Files
trips/src/lib/server/users.test.ts
AI Agent e11fcb56a2
All checks were successful
Build and Push Image / docker-build-and-push (push) Successful in 2m28s
admin) allow local login user management (#39)
Co-authored-by: Shaun Campbell <shaun@campbellwireless.net>
Reviewed-on: #39
Co-authored-by: AI Agent <ai-agent@campbellwireless.net>
Co-committed-by: AI Agent <ai-agent@campbellwireless.net>
2026-02-22 20:07:46 +00:00

152 lines
4.4 KiB
TypeScript

import { beforeEach, afterEach, describe, expect, it } from 'vitest';
import { setupTestDb } from '../../tests/helpers.js';
import type { Database } from './db/types.js';
import {
createLocalUser,
deleteUser,
listUsers,
setLocalPasswordForUser,
updateUser,
upsertUserFromAuth,
upsertUserProfile
} from './users.js';
let database: Database;
beforeEach(() => {
database = setupTestDb();
});
afterEach(() => {
database.close();
});
describe('upsertUserFromAuth', () => {
it('creates a new user with profile data', () => {
const created = upsertUserFromAuth({
id: 'u1',
username: 'jdoe',
fullName: 'Jane Doe',
email: 'jane@example.com',
authSource: 'OIDC - Synology'
});
expect(created.id).toBe('u1');
expect(created.username).toBe('jdoe');
expect(created.full_name).toBe('Jane Doe');
expect(created.email).toBe('jane@example.com');
expect(created.auth_source).toBe('OIDC - Synology');
expect(listUsers()).toHaveLength(1);
});
it('updates existing users with new auth data', () => {
upsertUserFromAuth({
id: 'u1',
username: 'jdoe',
fullName: 'Jane Doe',
email: 'jane@example.com',
authSource: 'OIDC - Synology'
});
const updated = upsertUserFromAuth({
id: 'u1',
username: 'janed',
email: 'jane.doe@example.com'
});
expect(updated.username).toBe('janed');
expect(updated.email).toBe('jane.doe@example.com');
});
});
describe('upsertUserProfile', () => {
it('creates a user from profile details', () => {
const created = upsertUserProfile('u2', 'Sam Sample', 'sam@example.com');
expect(created.id).toBe('u2');
expect(created.full_name).toBe('Sam Sample');
expect(created.email).toBe('sam@example.com');
});
});
describe('updateUser', () => {
it('updates user fields and syncs self profile when present', () => {
upsertUserFromAuth({
id: 'u3',
username: 'sarah',
fullName: 'Sarah Lee',
email: 'sarah@example.com'
});
database.run(
`INSERT INTO people (id, user_id, first_name, last_name, email, is_self)
VALUES (?, ?, ?, ?, ?, 1)`,
['p1', 'u3', 'Sarah', 'Lee', 'sarah@example.com']
);
updateUser({ id: 'u3', username: 'slee', fullName: 'Sarah Smith', email: 'ss@example.com' });
const user = listUsers().find((item) => item.id === 'u3');
expect(user?.username).toBe('slee');
expect(user?.full_name).toBe('Sarah Smith');
expect(user?.email).toBe('ss@example.com');
const profile = database.get<{ first_name: string; last_name: string; email: string | null }>(
'SELECT first_name, last_name, email FROM people WHERE user_id = ? AND is_self = 1',
['u3']
);
expect(profile?.first_name).toBe('Sarah');
expect(profile?.last_name).toBe('Smith');
expect(profile?.email).toBe('ss@example.com');
});
});
describe('deleteUser', () => {
it('removes the user record', () => {
upsertUserFromAuth({ id: 'u4', username: 'delete-me', fullName: 'Delete Me' });
deleteUser('u4');
expect(listUsers().find((item) => item.id === 'u4')).toBeUndefined();
});
});
describe('createLocalUser', () => {
it('creates a local user with credentials', async () => {
const created = await createLocalUser({
username: 'local-user',
fullName: 'Local User',
email: 'local@example.com',
password: 'averysecurepassword'
});
expect(created.username).toBe('local-user');
expect(created.auth_source).toBe('Local');
const row = database.get<{ user_id: string; password_hash: string }>(
'SELECT user_id, password_hash FROM local_credentials WHERE user_id = ?',
[created.id]
);
expect(row?.user_id).toBe(created.id);
expect(row?.password_hash).toBeTruthy();
});
it('rejects duplicate usernames', async () => {
await createLocalUser({
username: 'dup-user',
fullName: 'Dup User',
password: 'averysecurepassword'
});
await expect(
createLocalUser({
username: 'dup-user',
fullName: 'Dup User Two',
password: 'averysecurepassword'
})
).rejects.toThrow('Username already exists');
});
});
describe('setLocalPasswordForUser', () => {
it('sets local credentials for an existing user', async () => {
upsertUserFromAuth({ id: 'u5', username: 'sarah', fullName: 'Sarah Lee' });
await setLocalPasswordForUser('u5', 'averysecurepassword');
const row = database.get<{ user_id: string; password_hash: string }>(
'SELECT user_id, password_hash FROM local_credentials WHERE user_id = ?',
['u5']
);
expect(row?.user_id).toBe('u5');
expect(row?.password_hash).toBeTruthy();
});
});