Keep account validation and persistence inside one guarded submission. Recheck modal identity before committing, persist a copied hoster candidate, and publish renderer state only after saveConfig succeeds.
129 lines
3.4 KiB
JavaScript
129 lines
3.4 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { submitValidatedAccount } = require('../renderer/account-submit');
|
|
|
|
test('ok validates and commits exactly once in one submission', async () => {
|
|
let validations = 0;
|
|
let commits = 0;
|
|
const result = await submitValidatedAccount({
|
|
validate: async () => {
|
|
validations++;
|
|
return { status: 'ok', message: 'Login erfolgreich' };
|
|
},
|
|
commit: async () => {
|
|
commits++;
|
|
},
|
|
isCurrent: () => true
|
|
});
|
|
|
|
assert.equal(result.status, 'committed');
|
|
assert.equal(validations, 1);
|
|
assert.equal(commits, 1);
|
|
});
|
|
|
|
test('warn validates and commits exactly once in one submission', async () => {
|
|
let commits = 0;
|
|
const validation = { status: 'warn', message: 'Login mit Warnung' };
|
|
const result = await submitValidatedAccount({
|
|
validate: async () => validation,
|
|
commit: async (received) => {
|
|
commits++;
|
|
assert.equal(received, validation);
|
|
},
|
|
isCurrent: () => true
|
|
});
|
|
|
|
assert.equal(result.status, 'committed');
|
|
assert.equal(result.validation, validation);
|
|
assert.equal(commits, 1);
|
|
});
|
|
|
|
for (const status of ['error', 'skipped']) {
|
|
test(`${status} rejects without committing`, async () => {
|
|
let commits = 0;
|
|
const validation = { status, message: `${status} result` };
|
|
const result = await submitValidatedAccount({
|
|
validate: async () => validation,
|
|
commit: async () => {
|
|
commits++;
|
|
},
|
|
isCurrent: () => true
|
|
});
|
|
|
|
assert.equal(result.status, 'rejected');
|
|
assert.equal(result.validation, validation);
|
|
assert.equal(commits, 0);
|
|
});
|
|
}
|
|
|
|
test('validate throw returns error without committing', async () => {
|
|
const expected = new Error('validation failed');
|
|
let commits = 0;
|
|
const result = await submitValidatedAccount({
|
|
validate: async () => {
|
|
throw expected;
|
|
},
|
|
commit: async () => {
|
|
commits++;
|
|
},
|
|
isCurrent: () => true
|
|
});
|
|
|
|
assert.equal(result.status, 'error');
|
|
assert.equal(result.error, expected);
|
|
assert.equal(commits, 0);
|
|
});
|
|
|
|
test('otp_required returns challenge without committing', async () => {
|
|
let commits = 0;
|
|
const validation = { status: 'otp_required', message: 'OTP gesendet' };
|
|
const result = await submitValidatedAccount({
|
|
validate: async () => validation,
|
|
commit: async () => {
|
|
commits++;
|
|
},
|
|
isCurrent: () => true
|
|
});
|
|
|
|
assert.equal(result.status, 'otp_required');
|
|
assert.equal(result.validation, validation);
|
|
assert.equal(commits, 0);
|
|
});
|
|
|
|
test('stale submission is rejected immediately before commit', async () => {
|
|
let current = true;
|
|
let commits = 0;
|
|
const validation = { status: 'ok' };
|
|
const result = await submitValidatedAccount({
|
|
validate: async () => {
|
|
current = false;
|
|
return validation;
|
|
},
|
|
commit: async () => {
|
|
commits++;
|
|
},
|
|
isCurrent: () => current
|
|
});
|
|
|
|
assert.equal(result.status, 'stale');
|
|
assert.equal(result.validation, validation);
|
|
assert.equal(commits, 0);
|
|
});
|
|
|
|
test('save failure returns error after one commit attempt', async () => {
|
|
const expected = new Error('save failed');
|
|
let commits = 0;
|
|
const result = await submitValidatedAccount({
|
|
validate: async () => ({ status: 'ok' }),
|
|
commit: async () => {
|
|
commits++;
|
|
throw expected;
|
|
},
|
|
isCurrent: () => true
|
|
});
|
|
|
|
assert.equal(result.status, 'error');
|
|
assert.equal(result.error, expected);
|
|
assert.equal(commits, 1);
|
|
});
|