feat(editor): F4.6e the e-mail program and e-mail server on a computer's desktop
The oracle MailWindowRun uses Java's e-mail windows as a person does and answers their dialogs. The core sets and saves the program's account, deletes a mail, checks a form as Java's window does, and gives the server its domain, new and removed accounts and the window's own line; the room sends both programs' views and takes their actions; the editor has both windows. Better than Java: a name field for a new account, a user name the server has is refused, deleting hits the folder shown, a new domain goes into the accounts file at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
// The e-mail windows' lines and checks against Java's
|
||||
// (packages/sim/test/mailWindow.java.json, MailWindowRun): each kind of line
|
||||
// the server's window got there in Java's words, what it leaves out, a
|
||||
// failure's message, and the checks of a new account.
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { EmailServerLogEntry } from '@mdg-filius/core';
|
||||
import { accountNames, newAccountProblem } from '../src/desktop/EmailServerPanel.js';
|
||||
import { emailServerLine, mailFailureText } from '../src/desktop/mailLines.js';
|
||||
import { translate } from '../src/i18n/i18n.js';
|
||||
|
||||
const java = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../sim/test/mailWindow.java.json'), 'utf8')) as { steps: { step: string; log?: string }[] };
|
||||
const log = (step: string) => java.steps.find((each) => each.step === step)!.log!;
|
||||
const de = (key: string, values?: Readonly<Record<string, string | number>>) => translate('de', key, values);
|
||||
const en = (key: string, values?: Readonly<Record<string, string | number>>) => translate('en', key, values);
|
||||
|
||||
describe("the e-mail server window's lines", () => {
|
||||
it("are Java's, line by line", () => {
|
||||
const after = log('server:after mails');
|
||||
const entries: EmailServerLogEntry[] = [
|
||||
{ kind: 'connectionOpened' },
|
||||
{ kind: 'received', address: '192.168.0.20', text: 'MAIL FROM: <anna@schule.de>' },
|
||||
{ kind: 'sent', address: '192.168.0.20', text: '250 Sender OK' },
|
||||
{ kind: 'stored', username: 'anna' },
|
||||
];
|
||||
for (const entry of entries) expect(after, entry.kind).toContain(`${emailServerLine(entry, de)}\n`);
|
||||
expect(log('server:start')).toBe(`${emailServerLine({ kind: 'switched', active: true }, de)}\n`);
|
||||
expect(log('server:stop').endsWith(`\n${emailServerLine({ kind: 'switched', active: false }, de)}\n`)).toBe(true);
|
||||
});
|
||||
|
||||
it("write the SMTP client's lines, and leave out its failures as Java's window does", () => {
|
||||
expect(emailServerLine({ kind: 'connectionStarting' }, de)).toBe('----');
|
||||
expect(emailServerLine({ kind: 'smtpConnected', address: '1.2.3.4', port: 25 }, de)).toBe('Verbindung zu 1.2.3.4:25 hergestellt');
|
||||
expect(emailServerLine({ kind: 'smtpDisconnected', address: '1.2.3.4', port: 25 }, en)).toBe('Connection to 1.2.3.4:25 disconnected');
|
||||
expect(emailServerLine({ kind: 'mailSent', recipients: 'a@b.de' }, de)).toBe('Mail versendet an a@b.de');
|
||||
expect(emailServerLine({ kind: 'sendFailed', address: '1.2.3.4' }, de)).toBe('Fehler beim Senden an 1.2.3.4');
|
||||
expect(emailServerLine({ kind: 'failed', failure: { kind: 'receiveFailed' } }, de)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("show a failure's message as Java's dialog does", () => {
|
||||
expect(mailFailureText({ kind: 'answer', text: '-ERR wrong password' }, de)).toBe('-ERR wrong password');
|
||||
expect(mailFailureText({ kind: 'connect', failure: 'unresolved' }, de)).toBe('Ziel konnte nicht bestimmt werden!');
|
||||
expect(mailFailureText({ kind: 'connect', failure: 'timedOut' }, en)).toBe('Timeout while connecting');
|
||||
expect(mailFailureText({ kind: 'connect', failure: 'failed' }, de)).toBe('Aktives Öffnen des Sockets fehlgeschlagen');
|
||||
expect(mailFailureText({ kind: 'receiveFailed' }, de)).toBe('Verbindung nicht aufgebaut!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('a new account', () => {
|
||||
it("is checked as Java's window checks it, and refused where the server has the name", () => {
|
||||
const accounts = [{ username: 'anna' }];
|
||||
expect(newAccountProblem('', 'x', accounts)).toBe('missing');
|
||||
expect(newAccountProblem('bob', '', accounts)).toBe('missing');
|
||||
for (const name of ['carl os', 'a\tb', 'a\nb']) expect(newAccountProblem(name, 'x', accounts), name).toBe('whiteSpace');
|
||||
expect(newAccountProblem('ANNA', 'x', accounts)).toBe('exists');
|
||||
expect(newAccountProblem('bob', 'x', accounts)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("takes the name typed, and Java's placeholders without one", () => {
|
||||
expect(accountNames('Neue Nutzerin', de)).toEqual({ firstName: 'Neue', lastName: 'Nutzerin' });
|
||||
expect(accountNames('Anna', de)).toEqual({ firstName: 'Anna', lastName: '' });
|
||||
expect(accountNames(' ', de)).toEqual({ firstName: 'Vorname', lastName: 'Nachname' });
|
||||
expect(accountNames('', en)).toEqual({ firstName: 'First name', lastName: 'Last name' });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user