fix: update tests

This commit is contained in:
Eli Bosley
2024-12-19 13:29:23 -05:00
parent d88b1e9660
commit b1ac0f9c83
4 changed files with 32 additions and 22 deletions

View File

@@ -58,15 +58,15 @@ test('getUrlForServer - field exists, ssl yes, port empty', () => {
expect(result).toMatchInlineSnapshot('"https://192.168.1.1/"');
});
test('getUrlForServer - field exists, ssl auto', () => {
test('getUrlForServer - field exists, ssl auto', async () => {
const getResult = async () => getUrlForServer({
nginx: { lanIp: '192.168.1.1', sslEnabled: true, sslMode: 'auto', httpPort: 123, httpsPort: 445 } as const as Nginx,
field: 'lanIp',
});
void expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Cannot get IP Based URL for field: "lanIp" SSL mode auto]`);
await expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Cannot get IP Based URL for field: "lanIp" SSL mode auto]`);
});
test('getUrlForServer - field does not exist, ssl disabled', () => {
test('getUrlForServer - field does not exist, ssl disabled', async () => {
const getResult = async () => getUrlForServer(
{
nginx: { lanIp: '192.168.1.1', sslEnabled: false, sslMode: 'no' } as const as Nginx,
@@ -76,7 +76,7 @@ test('getUrlForServer - field does not exist, ssl disabled', () => {
// @ts-expect-error Field doesn't exist
field: 'idontexist',
});
void expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: IP URL Resolver: Could not resolve any access URL for field: "idontexist", is FQDN?: false]`);
await expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: IP URL Resolver: Could not resolve any access URL for field: "idontexist", is FQDN?: false]`);
});
test('getUrlForServer - FQDN - field exists, port non-empty', () => {
@@ -104,13 +104,13 @@ test.each([
expect(result.toString()).toBe('https://my-fqdn.unraid.net/');
});
test('getUrlForServer - field does not exist, ssl disabled', () => {
test('getUrlForServer - field does not exist, ssl disabled', async () => {
const getResult = async () => getUrlForServer({ nginx:
{ lanFqdn: 'my-fqdn.unraid.net' } as const as Nginx,
ports: { portSsl: '', port: '', defaultUrl: new URL('https://my-default-url.unraid.net') },
// @ts-expect-error Field doesn't exist
field: 'idontexist' });
void expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: IP URL Resolver: Could not resolve any access URL for field: "idontexist", is FQDN?: false]`);
await expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: IP URL Resolver: Could not resolve any access URL for field: "idontexist", is FQDN?: false]`);
});
test('integration test, loading nginx ini and generating all URLs', async () => {

View File

@@ -1,7 +1,13 @@
import { expect, test } from 'vitest';
import { store } from '@app/store';
test('Before init returns default values for all fields', async () => {
const state = store.getState().config;
expect(state).toMatchInlineSnapshot(`
@@ -74,7 +80,7 @@ test('After init returns values from cfg file for all fields', async () => {
dynamicRemoteAccessType: 'DISABLED',
email: 'test@example.com',
idtoken: '',
localApiKey: '',
localApiKey: '426b62b4d51e441fa97a93dfa1259920390a6eb61bd8675db0caa18dd0e414e9',
refreshtoken: '',
regWizTime: '1611175408732_0951-1653-3509-FBA155FA23C0',
upnpEnabled: 'no',
@@ -127,7 +133,7 @@ test('updateUserConfig merges in changes to current state', async () => {
dynamicRemoteAccessType: 'DISABLED',
email: 'test@example.com',
idtoken: '',
localApiKey: '',
localApiKey: '426b62b4d51e441fa97a93dfa1259920390a6eb61bd8675db0caa18dd0e414e9',
refreshtoken: '',
regWizTime: '1611175408732_0951-1653-3509-FBA155FA23C0',
upnpEnabled: 'no',
@@ -141,4 +147,4 @@ test('updateUserConfig merges in changes to current state', async () => {
},
})
);
});
});

View File

@@ -2,17 +2,24 @@ import { Logger } from '@nestjs/common';
import { readdir, readFile, writeFile } from 'fs/promises';
import { join } from 'path';
import { ensureDir } from 'fs-extra';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { ZodError } from 'zod';
import type { ApiKey, ApiKeyWithSecret } from '@app/graphql/generated/api/types';
import { ApiKeySchema, ApiKeyWithSecretSchema } from '@app/graphql/generated/api/operations';
import { Role } from '@app/graphql/generated/api/types';
import { getters } from '@app/store';
import { ApiKeyService } from './api-key.service';
vi.mock('fs/promises', async () => ({
readdir: vi.fn(),
readFile: vi.fn(),
@@ -127,15 +134,14 @@ describe('ApiKeyService', () => {
it('should create ApiKeyWithSecret with generated key', async () => {
const saveSpy = vi.spyOn(apiKeyService, 'saveApiKey').mockResolvedValue();
const { key, id, description, roles } = mockApiKeyWithSecret;
const inputName = 'Test API Key';
const expectedName = 'TEST_API_KEY';
const name = 'Test API Key';
const result = await apiKeyService.create(inputName, description ?? '', roles);
const result = await apiKeyService.create(name, description ?? '', roles);
expect(result).toMatchObject({
id,
key,
name: expectedName,
name: name,
description,
roles,
createdAt: expect.any(String),
@@ -148,7 +154,7 @@ describe('ApiKeyService', () => {
const saveSpy = vi.spyOn(apiKeyService, 'saveApiKey');
await expect(apiKeyService.create('', 'desc', [Role.GUEST])).rejects.toThrow(
'API key name is required'
'API key name must be alphanumeric + spaces'
);
await expect(apiKeyService.create('name', 'desc', [])).rejects.toThrow(
@@ -300,13 +306,11 @@ describe('ApiKeyService', () => {
expect(readFile).toHaveBeenCalledTimes(2);
});
it('should throw authentication error when file read fails', async () => {
it('Should return null if an API key is invalid', async () => {
vi.mocked(readdir).mockResolvedValue(['key1.json'] as any);
vi.mocked(readFile).mockRejectedValue(new Error('Read error'));
await expect(apiKeyService.findByKey(mockApiKeyWithSecret.key)).rejects.toThrow(
'Authentication system error'
);
await expect(apiKeyService.findByKey(mockApiKeyWithSecret.key)).resolves.toBeNull();
});
it('should throw specific error for corrupted JSON', async () => {
@@ -465,4 +469,4 @@ describe('ApiKeyService', () => {
);
});
});
});
});

View File

@@ -55,7 +55,7 @@ export class ApiKeyService implements OnModuleInit {
if (/^[\p{L}\p{N} ]+$/u.test(name)) {
return name;
} else {
throw new GraphQLError('API key name must be alphanumeric and can only contain spaces');
throw new GraphQLError('API key name must be alphanumeric + spaces');
}
}
@@ -189,7 +189,7 @@ export class ApiKeyService implements OnModuleInit {
try {
const files = await readdir(this.basePath);
for (const file of files) {
for (const file of (files ?? [])) {
if (!file.endsWith('.json')) continue;
try {
@@ -233,7 +233,7 @@ export class ApiKeyService implements OnModuleInit {
}
this.logger.error(`Failed to read API key storage: ${error}`);
throw new GraphQLError('Authentication system unavailable');
throw new GraphQLError('Authentication system unavailable - please see logs');
}
}