chore: refactor tests to improve clarity and reliability

- Removed unnecessary test.skip() calls in various test files, replacing them with comments for clarity.
- Enhanced retry logic in TestDataManager for API requests to handle rate limiting more gracefully.
- Updated security helper functions to include retry mechanisms for fetching security status and setting module states.
- Improved loading completion checks to handle page closure scenarios.
- Adjusted WebKit-specific tests to run in all browsers, removing the previous skip logic.
- General cleanup and refactoring across multiple test files to enhance readability and maintainability.
This commit is contained in:
GitHub Actions
2026-02-08 00:02:09 +00:00
parent 5054a334f2
commit aa85c911c0
71 changed files with 22475 additions and 3241 deletions

View File

@@ -130,9 +130,10 @@ describe('api client', () => {
expect(handler).toBeDefined()
// Call handler with auth endpoint error to verify it skips the auth error handler
if (handler) {
await handler(error)
}
const resultPromise = handler ? handler(error) : Promise.reject(new Error('handler missing'))
await expect(resultPromise).rejects.toBe(error)
expect(onAuthError).not.toHaveBeenCalled()
warnSpy.mockRestore()
})

View File

@@ -10,6 +10,9 @@ vi.mock('../client', () => ({
}));
describe('import API', () => {
const mockedGet = vi.mocked(client.get);
const mockedPost = vi.mocked(client.post);
beforeEach(() => {
vi.clearAllMocks();
});
@@ -17,7 +20,7 @@ describe('import API', () => {
it('uploadCaddyfile posts content', async () => {
const content = 'example.com';
const mockResponse = { preview: { hosts: [] } };
(client.post as any).mockResolvedValue({ data: mockResponse });
mockedPost.mockResolvedValue({ data: mockResponse });
const result = await uploadCaddyfile(content);
expect(client.post).toHaveBeenCalledWith('/import/upload', { content });
@@ -27,7 +30,7 @@ describe('import API', () => {
it('uploadCaddyfilesMulti posts files', async () => {
const files = [{ filename: 'Caddyfile', content: 'foo.com' }];
const mockResponse = { preview: { hosts: [] } };
(client.post as any).mockResolvedValue({ data: mockResponse });
mockedPost.mockResolvedValue({ data: mockResponse });
const result = await uploadCaddyfilesMulti(files);
expect(client.post).toHaveBeenCalledWith('/import/upload-multi', { files });
@@ -36,7 +39,7 @@ describe('import API', () => {
it('getImportPreview gets preview', async () => {
const mockResponse = { preview: { hosts: [] } };
(client.get as any).mockResolvedValue({ data: mockResponse });
mockedGet.mockResolvedValue({ data: mockResponse });
const result = await getImportPreview();
expect(client.get).toHaveBeenCalledWith('/import/preview');
@@ -49,7 +52,7 @@ describe('import API', () => {
const names = { 'foo.com': 'My Site' };
const mockResponse = { created: 1, updated: 0, skipped: 0, errors: [] };
(client.post as any).mockResolvedValue({ data: mockResponse });
mockedPost.mockResolvedValue({ data: mockResponse });
const result = await commitImport(sessionUUID, resolutions, names);
expect(client.post).toHaveBeenCalledWith('/import/commit', {
@@ -61,7 +64,7 @@ describe('import API', () => {
});
it('cancelImport posts cancel', async () => {
(client.post as any).mockResolvedValue({});
mockedPost.mockResolvedValue({});
await cancelImport();
expect(client.post).toHaveBeenCalledWith('/import/cancel');
@@ -69,7 +72,7 @@ describe('import API', () => {
it('getImportStatus gets status', async () => {
const mockResponse = { has_pending: true };
(client.get as any).mockResolvedValue({ data: mockResponse });
mockedGet.mockResolvedValue({ data: mockResponse });
const result = await getImportStatus();
expect(client.get).toHaveBeenCalledWith('/import/status');
@@ -77,7 +80,7 @@ describe('import API', () => {
});
it('getImportStatus handles error', async () => {
(client.get as any).mockRejectedValue(new Error('Failed'));
mockedGet.mockRejectedValue(new Error('Failed'));
const result = await getImportStatus();
expect(result).toEqual({ has_pending: false });

View File

@@ -54,8 +54,7 @@ describe('logs API - connectLiveLogs', () => {
beforeEach(() => {
// Mock global WebSocket
mockWebSocket = new MockWebSocket('');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).WebSocket = class MockedWebSocket extends MockWebSocket {
(globalThis as typeof globalThis & { WebSocket: typeof WebSocket }).WebSocket = class MockedWebSocket extends MockWebSocket {
constructor(url: string) {
super(url);
// eslint-disable-next-line @typescript-eslint/no-this-alias

View File

@@ -12,13 +12,18 @@ vi.mock('../client', () => ({
}));
describe('securityHeadersApi', () => {
const mockedGet = vi.mocked(client.get);
const mockedPost = vi.mocked(client.post);
const mockedPut = vi.mocked(client.put);
const mockedDelete = vi.mocked(client.delete);
beforeEach(() => {
vi.clearAllMocks();
});
it('listProfiles returns profiles', async () => {
const mockProfiles = [{ id: 1, name: 'Profile 1' }];
(client.get as any).mockResolvedValue({ data: { profiles: mockProfiles } });
mockedGet.mockResolvedValue({ data: { profiles: mockProfiles } });
const result = await securityHeadersApi.listProfiles();
expect(client.get).toHaveBeenCalledWith('/security/headers/profiles');
@@ -27,7 +32,7 @@ describe('securityHeadersApi', () => {
it('getProfile returns a profile', async () => {
const mockProfile = { id: 1, name: 'Profile 1' };
(client.get as any).mockResolvedValue({ data: { profile: mockProfile } });
mockedGet.mockResolvedValue({ data: { profile: mockProfile } });
const result = await securityHeadersApi.getProfile(1);
expect(client.get).toHaveBeenCalledWith('/security/headers/profiles/1');
@@ -37,7 +42,7 @@ describe('securityHeadersApi', () => {
it('createProfile creates a profile', async () => {
const newProfile = { name: 'New Profile' };
const mockResponse = { id: 1, ...newProfile };
(client.post as any).mockResolvedValue({ data: { profile: mockResponse } });
mockedPost.mockResolvedValue({ data: { profile: mockResponse } });
const result = await securityHeadersApi.createProfile(newProfile);
expect(client.post).toHaveBeenCalledWith('/security/headers/profiles', newProfile);
@@ -47,7 +52,7 @@ describe('securityHeadersApi', () => {
it('updateProfile updates a profile', async () => {
const updates = { name: 'Updated Profile' };
const mockResponse = { id: 1, ...updates };
(client.put as any).mockResolvedValue({ data: { profile: mockResponse } });
mockedPut.mockResolvedValue({ data: { profile: mockResponse } });
const result = await securityHeadersApi.updateProfile(1, updates);
expect(client.put).toHaveBeenCalledWith('/security/headers/profiles/1', updates);
@@ -55,7 +60,7 @@ describe('securityHeadersApi', () => {
});
it('deleteProfile deletes a profile', async () => {
(client.delete as any).mockResolvedValue({});
mockedDelete.mockResolvedValue({});
await securityHeadersApi.deleteProfile(1);
expect(client.delete).toHaveBeenCalledWith('/security/headers/profiles/1');
@@ -63,7 +68,7 @@ describe('securityHeadersApi', () => {
it('getPresets returns presets', async () => {
const mockPresets = [{ name: 'Basic' }];
(client.get as any).mockResolvedValue({ data: { presets: mockPresets } });
mockedGet.mockResolvedValue({ data: { presets: mockPresets } });
const result = await securityHeadersApi.getPresets();
expect(client.get).toHaveBeenCalledWith('/security/headers/presets');
@@ -73,7 +78,7 @@ describe('securityHeadersApi', () => {
it('applyPreset applies a preset', async () => {
const request = { preset_type: 'basic', name: 'My Preset' };
const mockResponse = { id: 1, ...request };
(client.post as any).mockResolvedValue({ data: { profile: mockResponse } });
mockedPost.mockResolvedValue({ data: { profile: mockResponse } });
const result = await securityHeadersApi.applyPreset(request);
expect(client.post).toHaveBeenCalledWith('/security/headers/presets/apply', request);
@@ -83,7 +88,7 @@ describe('securityHeadersApi', () => {
it('calculateScore calculates score', async () => {
const config = { hsts_enabled: true };
const mockResponse = { score: 90 };
(client.post as any).mockResolvedValue({ data: mockResponse });
mockedPost.mockResolvedValue({ data: mockResponse });
const result = await securityHeadersApi.calculateScore(config);
expect(client.post).toHaveBeenCalledWith('/security/headers/score', config);
@@ -93,7 +98,7 @@ describe('securityHeadersApi', () => {
it('validateCSP validates CSP', async () => {
const csp = "default-src 'self'";
const mockResponse = { valid: true, errors: [] };
(client.post as any).mockResolvedValue({ data: mockResponse });
mockedPost.mockResolvedValue({ data: mockResponse });
const result = await securityHeadersApi.validateCSP(csp);
expect(client.post).toHaveBeenCalledWith('/security/headers/csp/validate', { csp });
@@ -103,7 +108,7 @@ describe('securityHeadersApi', () => {
it('buildCSP builds CSP', async () => {
const directives = [{ directive: 'default-src', values: ["'self'"] }];
const mockResponse = { csp: "default-src 'self'" };
(client.post as any).mockResolvedValue({ data: mockResponse });
mockedPost.mockResolvedValue({ data: mockResponse });
const result = await securityHeadersApi.buildCSP(directives);
expect(client.post).toHaveBeenCalledWith('/security/headers/csp/build', { directives });