velody/backend/src/modules/users/owner-context.service.spec.ts
2026-06-24 07:36:57 +02:00

143 lines
4.1 KiB
TypeScript

import { randomUUID } from 'node:crypto';
import { RequestContextService } from '../../infrastructure/request-context/request-context.service';
import { BootstrapOwnerContextService } from './owner-context.service';
describe('BootstrapOwnerContextService', () => {
it('resolves the bootstrap default owner today', async () => {
const defaultUser = {
id: randomUUID(),
slug: 'default-owner',
displayName: 'Default Owner',
isDefault: true,
};
const defaultUserService = {
getOrCreateDefaultUser: jest.fn().mockResolvedValue(defaultUser),
} as any;
const service = new BootstrapOwnerContextService(
defaultUserService,
new RequestContextService(),
{
device: {
findUnique: jest.fn(),
},
} as any,
);
await expect(service.resolve()).resolves.toEqual({
userId: defaultUser.id,
});
expect(defaultUserService.getOrCreateDefaultUser).toHaveBeenCalledTimes(1);
});
it('prefers the authenticated device owner when present', async () => {
const requestContext = new RequestContextService();
const defaultUserService = {
getOrCreateDefaultUser: jest.fn(),
} as any;
const legacyOwnerId = randomUUID();
const prismaService = {
device: {
findUnique: jest.fn().mockResolvedValue({
userId: legacyOwnerId,
}),
},
} as any;
const service = new BootstrapOwnerContextService(
defaultUserService,
requestContext,
prismaService,
);
const authenticatedOwnerId = randomUUID();
await requestContext.run(async () => {
requestContext.setLegacyDeviceId(randomUUID());
requestContext.setAuthenticatedDevice({
deviceId: randomUUID(),
userId: authenticatedOwnerId,
});
await expect(service.resolve()).resolves.toEqual({
userId: authenticatedOwnerId,
});
});
expect(defaultUserService.getOrCreateDefaultUser).not.toHaveBeenCalled();
expect(prismaService.device.findUnique).not.toHaveBeenCalled();
});
it('falls back to the legacy device owner before the bootstrap default owner', async () => {
const requestContext = new RequestContextService();
const defaultUserService = {
getOrCreateDefaultUser: jest.fn(),
} as any;
const legacyDeviceId = randomUUID();
const legacyOwnerId = randomUUID();
const prismaService = {
device: {
findUnique: jest.fn().mockResolvedValue({
userId: legacyOwnerId,
}),
},
} as any;
const service = new BootstrapOwnerContextService(
defaultUserService,
requestContext,
prismaService,
);
await requestContext.run(async () => {
requestContext.setLegacyDeviceId(legacyDeviceId);
await expect(service.resolve()).resolves.toEqual({
userId: legacyOwnerId,
});
});
expect(prismaService.device.findUnique).toHaveBeenCalledWith({
where: {
id: legacyDeviceId,
},
select: {
userId: true,
},
});
expect(defaultUserService.getOrCreateDefaultUser).not.toHaveBeenCalled();
});
it('uses the bootstrap default owner when legacy device fallback is disabled', async () => {
const requestContext = new RequestContextService();
const defaultUser = {
id: randomUUID(),
slug: 'default-owner',
displayName: 'Default Owner',
isDefault: true,
};
const defaultUserService = {
getOrCreateDefaultUser: jest.fn().mockResolvedValue(defaultUser),
} as any;
const prismaService = {
device: {
findUnique: jest.fn(),
},
} as any;
const service = new BootstrapOwnerContextService(
defaultUserService,
requestContext,
prismaService,
);
await requestContext.run(async () => {
requestContext.setLegacyDeviceId(randomUUID());
await expect(
service.resolve({ allowLegacyDeviceFallback: false }),
).resolves.toEqual({
userId: defaultUser.id,
});
});
expect(prismaService.device.findUnique).not.toHaveBeenCalled();
expect(defaultUserService.getOrCreateDefaultUser).toHaveBeenCalledTimes(1);
});
});