245 lines
7.4 KiB
TypeScript
245 lines
7.4 KiB
TypeScript
import { SessionClaims } from '@/lib/feature/user/clerk.model';
|
|
import {
|
|
CreateUserModel,
|
|
UpdateUserModel,
|
|
} from '@/lib/feature/user/user.model';
|
|
import {
|
|
getUserByEmail,
|
|
saveUser,
|
|
syncUser,
|
|
updateUser,
|
|
} from '@/lib/feature/user/user.service';
|
|
import { clerkClient } from '@clerk/nextjs/server';
|
|
import { AbstractStartedContainer } from 'testcontainers';
|
|
import { startTestDB } from '~/tests/setup/setup-db';
|
|
|
|
jest.mock('@clerk/nextjs/server', () => ({
|
|
clerkClient: jest.fn(),
|
|
}));
|
|
|
|
describe('UserService', () => {
|
|
let container: AbstractStartedContainer;
|
|
|
|
beforeAll(async () => {
|
|
container = await startTestDB();
|
|
}, 1_000_000);
|
|
|
|
afterAll(async () => {
|
|
await container.stop();
|
|
}, 1_000_000);
|
|
|
|
test('can save user', async () => {
|
|
const userToSave: CreateUserModel = {
|
|
name: 'Test User',
|
|
email: 'test@email.com',
|
|
role: 'user',
|
|
};
|
|
|
|
const savedUser = await saveUser(userToSave);
|
|
|
|
expect(savedUser.id).toBeDefined();
|
|
expect(savedUser.name).toBe(userToSave.name);
|
|
expect(savedUser.email).toBe(userToSave.email);
|
|
expect(savedUser.role).toBe(userToSave.role);
|
|
expect(savedUser.role).toBe(userToSave.role);
|
|
expect(savedUser.externalId).toBeDefined(); // Default to true if not set
|
|
});
|
|
|
|
test('cannot save user with existing email', async () => {
|
|
const userToSave: CreateUserModel = {
|
|
name: 'Test User',
|
|
email: 'test@email.com',
|
|
role: 'user',
|
|
};
|
|
await expect(saveUser(userToSave)).rejects.toThrow(
|
|
`User with email ${userToSave.email} already exists`
|
|
);
|
|
});
|
|
|
|
test('can getUserByEmail', async () => {
|
|
const user = await getUserByEmail('test@email.com');
|
|
|
|
expect(user).toBeDefined();
|
|
expect(user?.email).toBe('test@email.com');
|
|
expect(user?.name).toBe('Test User');
|
|
expect(user?.role).toBe('user');
|
|
expect(user?.externalId).toBeDefined(); // Default to true if not set
|
|
});
|
|
|
|
test('cannot getUserByEmail with non-existing email', async () => {
|
|
await expect(getUserByEmail('missing@email.com')).resolves.toBeNull();
|
|
});
|
|
|
|
test('can update user', async () => {
|
|
const dataToUpdate: UpdateUserModel = {
|
|
name: 'Updated User',
|
|
role: 'admin',
|
|
};
|
|
|
|
const user = await getUserByEmail('test@email.com');
|
|
expect(user).toBeDefined();
|
|
|
|
const updatedUser = await updateUser(user!.id, dataToUpdate);
|
|
|
|
expect(updatedUser).toBeDefined();
|
|
expect(updatedUser.id).toBe(user!.id);
|
|
expect(updatedUser.name).toBe(dataToUpdate.name);
|
|
expect(updatedUser.role).toBe(dataToUpdate.role);
|
|
expect(updatedUser.email).toBe(user!.email);
|
|
expect(updatedUser.externalId).toBeDefined(); // Default to true if not set
|
|
});
|
|
|
|
test('cannot update non-existing user', async () => {
|
|
const dataToUpdate: UpdateUserModel = {
|
|
name: 'Updated User',
|
|
role: 'admin',
|
|
};
|
|
|
|
await expect(updateUser('9999', dataToUpdate)).rejects.toThrow(
|
|
`User with ID 9999 not found`
|
|
);
|
|
});
|
|
|
|
test('can sync admin user', async () => {
|
|
process.env.CLERK_ORG_ID = 'test-org-id';
|
|
|
|
const mockGetOrganizationMembershipList = jest.fn().mockResolvedValue({
|
|
data: [
|
|
{
|
|
organization: {
|
|
id: process.env.CLERK_ORG_ID,
|
|
},
|
|
role: 'org:admin',
|
|
},
|
|
],
|
|
});
|
|
|
|
(clerkClient as jest.Mock).mockResolvedValue({
|
|
users: {
|
|
getOrganizationMembershipList:
|
|
mockGetOrganizationMembershipList,
|
|
},
|
|
});
|
|
|
|
const sessionClaims = {
|
|
user: {
|
|
full_name: 'Updated Name',
|
|
email: 'test@email.com',
|
|
username: 'test',
|
|
public_metadata: {
|
|
role: 'admin',
|
|
},
|
|
},
|
|
} as SessionClaims;
|
|
const syncedUser = await syncUser(sessionClaims);
|
|
|
|
expect(syncedUser).toBeDefined();
|
|
expect(syncedUser.name).toBe('Updated Name');
|
|
expect(syncedUser.email).toBe('test@email.com');
|
|
expect(syncedUser.role).toBe('admin');
|
|
});
|
|
|
|
test('can sync internal user', async () => {
|
|
process.env.CLERK_ORG_ID = 'test-org-id';
|
|
|
|
const mockGetOrganizationMembershipList = jest.fn().mockResolvedValue({
|
|
data: [
|
|
{
|
|
organization: {
|
|
id: process.env.CLERK_ORG_ID,
|
|
},
|
|
role: 'org:member',
|
|
},
|
|
],
|
|
});
|
|
|
|
(clerkClient as jest.Mock).mockResolvedValue({
|
|
users: {
|
|
getOrganizationMembershipList:
|
|
mockGetOrganizationMembershipList,
|
|
},
|
|
});
|
|
|
|
const sessionClaims = {
|
|
user: {
|
|
full_name: 'Updated Name',
|
|
email: 'test@email.com',
|
|
username: 'test',
|
|
public_metadata: {
|
|
role: 'internal',
|
|
},
|
|
},
|
|
} as SessionClaims;
|
|
const syncedUser = await syncUser(sessionClaims);
|
|
|
|
expect(syncedUser).toBeDefined();
|
|
expect(syncedUser.name).toBe('Updated Name');
|
|
expect(syncedUser.email).toBe('test@email.com');
|
|
expect(syncedUser.role).toBe('internal');
|
|
});
|
|
|
|
test('can sync user', async () => {
|
|
process.env.CLERK_ORG_ID = 'test-org-id';
|
|
|
|
const mockGetOrganizationMembershipList = jest.fn().mockResolvedValue({
|
|
data: [],
|
|
});
|
|
|
|
(clerkClient as jest.Mock).mockResolvedValue({
|
|
users: {
|
|
getOrganizationMembershipList:
|
|
mockGetOrganizationMembershipList,
|
|
},
|
|
});
|
|
|
|
const sessionClaims = {
|
|
user: {
|
|
full_name: 'Updated Name',
|
|
email: 'test@email.com',
|
|
username: 'test',
|
|
public_metadata: {
|
|
role: 'user',
|
|
},
|
|
},
|
|
} as SessionClaims;
|
|
const syncedUser = await syncUser(sessionClaims);
|
|
|
|
expect(syncedUser).toBeDefined();
|
|
expect(syncedUser.name).toBe('Updated Name');
|
|
expect(syncedUser.email).toBe('test@email.com');
|
|
expect(syncedUser.role).toBe('user');
|
|
});
|
|
|
|
test('can sync saving new user', async () => {
|
|
process.env.CLERK_ORG_ID = 'test-org-id';
|
|
|
|
const mockGetOrganizationMembershipList = jest.fn().mockResolvedValue({
|
|
data: [],
|
|
});
|
|
|
|
(clerkClient as jest.Mock).mockResolvedValue({
|
|
users: {
|
|
getOrganizationMembershipList:
|
|
mockGetOrganizationMembershipList,
|
|
},
|
|
});
|
|
|
|
const sessionClaims = {
|
|
user: {
|
|
full_name: 'Updated Name',
|
|
email: 'new@email.com',
|
|
username: 'test',
|
|
public_metadata: {
|
|
role: 'user',
|
|
},
|
|
},
|
|
} as SessionClaims;
|
|
const syncedUser = await syncUser(sessionClaims);
|
|
|
|
expect(syncedUser).toBeDefined();
|
|
expect(syncedUser.name).toBe('Updated Name');
|
|
expect(syncedUser.email).toBe('new@email.com');
|
|
expect(syncedUser.role).toBe('user');
|
|
});
|
|
});
|