add sign in page

This commit is contained in:
yoyuzh
2026-03-18 11:50:03 +08:00
parent 7518dc158f
commit 8b0f77fa21
14 changed files with 1408 additions and 130 deletions

View File

@@ -1,7 +1,7 @@
import assert from 'node:assert/strict';
import { afterEach, beforeEach, test } from 'node:test';
import { apiRequest } from './api';
import { apiRequest, shouldRetryRequest, toNetworkApiError } from './api';
import { clearStoredSession, saveStoredSession } from './session';
class MemoryStorage implements Storage {
@@ -109,3 +109,33 @@ test('apiRequest throws backend message on business error', async () => {
await assert.rejects(() => apiRequest('/user/profile'), /login required/);
});
test('network login failures are retried a limited number of times for auth login', () => {
const error = new TypeError('Failed to fetch');
assert.equal(shouldRetryRequest('/auth/login', {method: 'POST'}, error, 0), true);
assert.equal(shouldRetryRequest('/auth/login', {method: 'POST'}, error, 1), true);
assert.equal(shouldRetryRequest('/auth/login', {method: 'POST'}, error, 2), false);
});
test('network register failures are not retried automatically', () => {
const error = new TypeError('Failed to fetch');
assert.equal(shouldRetryRequest('/auth/register', {method: 'POST'}, error, 0), false);
});
test('network get failures are retried up to two times after the first attempt', () => {
const error = new TypeError('Failed to fetch');
assert.equal(shouldRetryRequest('/files/list', {method: 'GET'}, error, 0), true);
assert.equal(shouldRetryRequest('/files/list', {method: 'GET'}, error, 1), true);
assert.equal(shouldRetryRequest('/files/list', {method: 'GET'}, error, 2), true);
assert.equal(shouldRetryRequest('/files/list', {method: 'GET'}, error, 3), false);
});
test('network fetch failures are converted to readable api errors', () => {
const apiError = toNetworkApiError(new TypeError('Failed to fetch'));
assert.equal(apiError.status, 0);
assert.match(apiError.message, /网络连接异常|Failed to fetch/);
});