@accounter/server
Version:
Accounter GraphQL server
97 lines • 4.64 kB
JavaScript
import { GraphQLError } from 'graphql';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { invitationsResolvers } from '../resolvers/invitations.resolver.js';
import { AcceptInvitationsProvider } from '../providers/accept-invitations.provider.js';
import { AuthContextProvider } from '../providers/auth-context.provider.js';
const acceptInvitation = invitationsResolvers.Mutation?.acceptInvitation;
const mockInfo = {};
describe('acceptInvitation resolver', () => {
let mockAuthProvider;
let mockAcceptInvitationsProvider;
beforeEach(() => {
mockAuthProvider = {
getAuthContext: vi.fn().mockResolvedValue({
authType: 'jwt',
user: {
userId: 'caller-user-id',
roleId: 'employee',
email: 'invitee@example.com',
permissions: [],
emailVerified: true,
permissionsVersion: 1,
auth0UserId: 'auth0|caller-123',
},
tenant: {
businessId: 'business-123',
roleId: 'employee',
},
}),
getJwtIdentity: vi.fn().mockResolvedValue(null),
};
mockAcceptInvitationsProvider = {
acceptInvitation: vi.fn().mockResolvedValue({
success: true,
businessId: 'business-abc',
roleId: 'employee',
}),
};
});
afterEach(() => {
vi.clearAllMocks();
});
function createContext() {
return {
injector: {
get(token) {
if (token === AuthContextProvider) {
return mockAuthProvider;
}
if (token === AcceptInvitationsProvider) {
return mockAcceptInvitationsProvider;
}
throw new Error(`Unexpected token requested: ${String(token)}`);
},
},
};
}
it('delegates to AcceptInvitationsProvider and returns payload', async () => {
const result = await acceptInvitation({}, { token: 'token-1' }, createContext(), mockInfo);
expect(result).toEqual({
success: true,
businessId: 'business-abc',
roleId: 'employee',
});
expect(mockAcceptInvitationsProvider.acceptInvitation).toHaveBeenCalledWith('token-1', 'auth0|caller-123', 'invitee@example.com');
});
it('trims token before delegation', async () => {
await acceptInvitation({}, { token: ' token-1 ' }, createContext(), mockInfo);
expect(mockAcceptInvitationsProvider.acceptInvitation).toHaveBeenCalledWith('token-1', 'auth0|caller-123', 'invitee@example.com');
});
it('empty token rejected with TOKEN_INVALID', async () => {
await expect(acceptInvitation({}, { token: ' ' }, createContext(), mockInfo)).rejects.toSatisfy(error => {
return error instanceof GraphQLError && error.extensions?.code === 'TOKEN_INVALID';
});
expect(mockAcceptInvitationsProvider.acceptInvitation).not.toHaveBeenCalled();
});
it('unauthenticated user delegates with null auth0UserId', async () => {
mockAuthProvider.getAuthContext.mockResolvedValueOnce(null);
mockAuthProvider.getJwtIdentity.mockResolvedValueOnce(null);
await acceptInvitation({}, { token: 'token-3' }, createContext(), mockInfo);
expect(mockAcceptInvitationsProvider.acceptInvitation).toHaveBeenCalledWith('token-3', null, null);
});
it('passes through GraphQLError from provider', async () => {
mockAcceptInvitationsProvider.acceptInvitation.mockRejectedValueOnce(new GraphQLError('Invitation token expired', {
extensions: { code: 'TOKEN_EXPIRED' },
}));
await expect(acceptInvitation({}, { token: 'expired-token' }, createContext(), mockInfo)).rejects.toSatisfy(error => {
return error instanceof GraphQLError && error.extensions?.code === 'TOKEN_EXPIRED';
});
});
it('wraps non-GraphQLError failures as INVITATION_ACCEPT_FAILED', async () => {
mockAcceptInvitationsProvider.acceptInvitation.mockRejectedValueOnce(new Error('boom'));
await expect(acceptInvitation({}, { token: 'token-rollback' }, createContext(), mockInfo)).rejects.toSatisfy(error => {
return error instanceof GraphQLError && error.extensions?.code === 'INVITATION_ACCEPT_FAILED';
});
});
});
//# sourceMappingURL=accept-invitation.test.js.map