- Introduced SKILL.md outlining the principles and processes for effective interface design. - Added critique.md for evaluating design outputs and ensuring craft over correctness. - Created example.md to illustrate the application of subtle layering principles in design decisions. - Developed principles.md detailing core craft principles for consistent design quality. - Implemented validation.md for memory management and pattern reuse in the design system. - Established system.md for the Playzer design system, defining direction, domain concepts, and design decisions. - Added StatusBadge component for displaying booking statuses with appropriate styles and labels. - Updated skills-lock.json to include the new interface-design skill.
123 lines
3.2 KiB
TypeScript
123 lines
3.2 KiB
TypeScript
import { beforeEach, expect, mock, test } from 'bun:test';
|
|
|
|
import { createInviteComplexUserHandler } from '@/modules/complex/handlers/invite-complex-user.handler';
|
|
import type { InviteComplexUserResponse } from '@repo/api-contract';
|
|
|
|
const inviteComplexUserMock = mock(async () => undefined as unknown as InviteComplexUserResponse);
|
|
|
|
class MockComplexMembersError extends Error {
|
|
status: 400 | 403 | 404 | 409;
|
|
|
|
constructor(message: string, status: 400 | 403 | 404 | 409 = 400) {
|
|
super(message);
|
|
this.name = 'ComplexMembersError';
|
|
this.status = status;
|
|
}
|
|
}
|
|
|
|
const inviteComplexUserHandler = createInviteComplexUserHandler({
|
|
inviteComplexUser: inviteComplexUserMock,
|
|
ComplexMembersError: MockComplexMembersError,
|
|
});
|
|
|
|
type HandlerContext = {
|
|
get: (key: 'user' | 'session') => { id: string } | undefined;
|
|
req: {
|
|
param: () => Record<string, string>;
|
|
valid: () => unknown;
|
|
};
|
|
json: ReturnType<typeof mock>;
|
|
};
|
|
|
|
function createContext(input: {
|
|
userId: string;
|
|
params: Record<string, string>;
|
|
body: unknown;
|
|
}) {
|
|
const json = mock((payload: unknown, init?: unknown) => ({
|
|
payload,
|
|
init,
|
|
}));
|
|
|
|
const c = {
|
|
get: (key: 'user' | 'session') => {
|
|
if (key === 'user') {
|
|
return { id: input.userId };
|
|
}
|
|
|
|
return undefined;
|
|
},
|
|
req: {
|
|
param: () => input.params,
|
|
valid: () => input.body,
|
|
},
|
|
json,
|
|
} as unknown as HandlerContext;
|
|
|
|
return { c, json };
|
|
}
|
|
|
|
beforeEach(() => {
|
|
inviteComplexUserMock.mockReset();
|
|
mock.clearAllMocks();
|
|
});
|
|
|
|
test('returns 201 with the service result', async () => {
|
|
const serviceResult = {
|
|
invitation: {
|
|
id: 'inv-1',
|
|
complexId: 'complex-1',
|
|
email: 'new.member@example.com',
|
|
status: 'PENDING',
|
|
createdAt: '2026-04-22T00:00:00.000Z',
|
|
expiresAt: '2026-04-29T00:00:00.000Z',
|
|
acceptedAt: null,
|
|
revokedAt: null,
|
|
},
|
|
} as const;
|
|
|
|
inviteComplexUserMock.mockResolvedValue(serviceResult);
|
|
|
|
const { c, json } = createContext({
|
|
userId: 'admin-1',
|
|
params: { id: '11111111-1111-4111-8111-111111111111' },
|
|
body: { email: 'new.member@example.com' },
|
|
});
|
|
|
|
const response = await inviteComplexUserHandler(c as never);
|
|
|
|
expect(inviteComplexUserMock).toHaveBeenCalledWith(
|
|
'admin-1',
|
|
'11111111-1111-4111-8111-111111111111',
|
|
{ email: 'new.member@example.com' }
|
|
);
|
|
expect(json.mock.calls[0]?.[0]).toEqual(serviceResult);
|
|
expect(json.mock.calls[0]?.[1]).toBe(201);
|
|
expect(response).toBeDefined();
|
|
});
|
|
|
|
test('maps ComplexMembersError to an error response', async () => {
|
|
inviteComplexUserMock.mockRejectedValue(
|
|
new MockComplexMembersError('Solo un ADMIN puede administrar usuarios.', 403)
|
|
);
|
|
|
|
const { c, json } = createContext({
|
|
userId: 'employee-1',
|
|
params: { id: '11111111-1111-4111-8111-111111111111' },
|
|
body: { email: 'new.member@example.com' },
|
|
});
|
|
|
|
const response = await inviteComplexUserHandler(c as never);
|
|
|
|
expect(inviteComplexUserMock).toHaveBeenCalledWith(
|
|
'employee-1',
|
|
'11111111-1111-4111-8111-111111111111',
|
|
{ email: 'new.member@example.com' }
|
|
);
|
|
expect(json.mock.calls[0]?.[0]).toEqual({
|
|
message: 'Solo un ADMIN puede administrar usuarios.',
|
|
});
|
|
expect(json.mock.calls[0]?.[1]).toEqual({ status: 403 });
|
|
expect(response).toBeDefined();
|
|
});
|