Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/$1"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
Expand Down
102 changes: 102 additions & 0 deletions apps/backend/src/test/factories/account.factory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { createTestAccount, createTestAccounts } from './account.factory';

describe('Account Factory', () => {
describe('createTestAccount', () => {
it('should create account with default values', () => {
const account = createTestAccount();

expect(account.id).toBeDefined();
expect(account.name).toMatch(/^Test Account [a-f0-9-]+$/);
expect(account.description).toBe('Test account description');
});

it('should accept custom id', () => {
const account = createTestAccount({ id: 'custom-account-id' });

expect(account.id).toBe('custom-account-id');
});

it('should accept custom name', () => {
const account = createTestAccount({ name: 'My Custom Account' });

expect(account.name).toBe('My Custom Account');
});

it('should accept custom description', () => {
const account = createTestAccount({ description: 'Custom description' });

expect(account.description).toBe('Custom description');
});

it('should accept all options at once', () => {
const account = createTestAccount({
id: 'acc-123',
name: 'Full Account',
description: 'Full description',
});

expect(account.id).toBe('acc-123');
expect(account.name).toBe('Full Account');
expect(account.description).toBe('Full description');
});

it('should create unique IDs for multiple accounts', () => {
const account1 = createTestAccount();
const account2 = createTestAccount();

expect(account1.id).not.toBe(account2.id);
});

it('should create unique names for multiple accounts', () => {
const account1 = createTestAccount();
const account2 = createTestAccount();

expect(account1.name).not.toBe(account2.name);
});
});

describe('createTestAccounts', () => {
it('should create specified number of accounts', () => {
const accounts = createTestAccounts(5);

expect(accounts).toHaveLength(5);
});

it('should create zero accounts when count is 0', () => {
const accounts = createTestAccounts(0);

expect(accounts).toHaveLength(0);
});

it('should create accounts with sequential names', () => {
const accounts = createTestAccounts(3);

expect(accounts[0].name).toBe('Test Account 1');
expect(accounts[1].name).toBe('Test Account 2');
expect(accounts[2].name).toBe('Test Account 3');
});

it('should create accounts with unique IDs', () => {
const accounts = createTestAccounts(3);
const ids = accounts.map((a) => a.id);
const uniqueIds = new Set(ids);

expect(uniqueIds.size).toBe(3);
});

it('should create accounts with default description', () => {
const accounts = createTestAccounts(2);

accounts.forEach((account) => {
expect(account.description).toBe('Test account description');
});
});

it('should handle large count', () => {
const accounts = createTestAccounts(100);

expect(accounts).toHaveLength(100);
expect(accounts[99].name).toBe('Test Account 100');
});
});
});
34 changes: 34 additions & 0 deletions apps/backend/src/test/factories/account.factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Account } from '../../entities/account.entity';
import { v4 as uuid } from 'uuid';

export interface CreateTestAccountOptions {
id?: string;
name?: string;
description?: string;
}

/**
* Factory for creating test Account entities.
*/
export function createTestAccount(
options: CreateTestAccountOptions = {},
): Account {
const account = new Account();

account.id = options.id ?? uuid();
account.name = options.name ?? `Test Account ${uuid().slice(0, 8)}`;
account.description = options.description ?? 'Test account description';

return account;
}

/**
* Create multiple test accounts
*/
export function createTestAccounts(count: number): Account[] {
return Array.from({ length: count }, (_, index) =>
createTestAccount({
name: `Test Account ${index + 1}`,
}),
);
}
2 changes: 2 additions & 0 deletions apps/backend/src/test/factories/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './user.factory';
export * from './account.factory';
210 changes: 210 additions & 0 deletions apps/backend/src/test/factories/user.factory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import {
createTestUser,
createTestUserWithProvider,
createTestSuperAdmin,
createTestInvitedUser,
CreateTestUserOptions,
} from './user.factory';

describe('User Factory', () => {
describe('createTestUser', () => {
it('should create user with default values', () => {
const user = createTestUser();

expect(user.id).toBeDefined();
expect(user.email).toMatch(/^test-[a-f0-9-]+@example\.com$/);
expect(user.name).toBe('Test User');
expect(user.status).toBe('accepted');
expect(user.providerIds).toEqual([]);
expect(user.isSuperAdmin).toBe(false);
expect(user.profileImage).toBeNull();
});

it('should accept custom id', () => {
const user = createTestUser({ id: 'custom-id-123' });

expect(user.id).toBe('custom-id-123');
});

it('should accept custom email', () => {
const user = createTestUser({ email: 'custom@example.com' });

expect(user.email).toBe('custom@example.com');
});

it('should use default email when null is passed (nullish coalescing behavior)', () => {
const user = createTestUser({ email: null });

// Note: nullish coalescing (??) returns default for null
expect(user.email).toMatch(/^test-[a-f0-9-]+@example\.com$/);
});

it('should accept custom name', () => {
const user = createTestUser({ name: 'John Doe' });

expect(user.name).toBe('John Doe');
});

it('should accept custom status', () => {
const user = createTestUser({ status: 'pending' });

expect(user.status).toBe('pending');
});

it('should accept custom providerIds', () => {
const providerIds = ['google|123', 'auth0|456'];
const user = createTestUser({ providerIds });

expect(user.providerIds).toEqual(providerIds);
});

it('should accept isSuperAdmin flag', () => {
const user = createTestUser({ isSuperAdmin: true });

expect(user.isSuperAdmin).toBe(true);
});

it('should accept custom profileImage', () => {
const user = createTestUser({ profileImage: 'https://example.com/photo.jpg' });

expect(user.profileImage).toBe('https://example.com/photo.jpg');
});

it('should accept multiple options at once', () => {
const options: CreateTestUserOptions = {
id: 'user-123',
email: 'test@test.com',
name: 'Full Name',
status: 'invited',
providerIds: ['google|abc'],
isSuperAdmin: true,
profileImage: 'image.jpg',
};

const user = createTestUser(options);

expect(user.id).toBe('user-123');
expect(user.email).toBe('test@test.com');
expect(user.name).toBe('Full Name');
expect(user.status).toBe('invited');
expect(user.providerIds).toEqual(['google|abc']);
expect(user.isSuperAdmin).toBe(true);
expect(user.profileImage).toBe('image.jpg');
});

it('should create unique IDs for multiple users', () => {
const user1 = createTestUser();
const user2 = createTestUser();

expect(user1.id).not.toBe(user2.id);
});

it('should create unique emails for multiple users', () => {
const user1 = createTestUser();
const user2 = createTestUser();

expect(user1.email).not.toBe(user2.email);
});
});

describe('createTestUserWithProvider', () => {
it('should create user with google provider', () => {
const user = createTestUserWithProvider('google', '123456789');

expect(user.providerIds).toContain('google|123456789');
});

it('should create user with auth0 provider', () => {
const user = createTestUserWithProvider('auth0', 'user_abc');

expect(user.providerIds).toContain('auth0|user_abc');
});

it('should preserve additional options', () => {
const user = createTestUserWithProvider('google', '123', {
name: 'Custom Name',
isSuperAdmin: true,
});

expect(user.providerIds).toContain('google|123');
expect(user.name).toBe('Custom Name');
expect(user.isSuperAdmin).toBe(true);
});

it('should prepend new provider to existing providerIds', () => {
const user = createTestUserWithProvider('google', 'new-id', {
providerIds: ['auth0|existing'],
});

expect(user.providerIds).toHaveLength(2);
expect(user.providerIds[0]).toBe('google|new-id');
expect(user.providerIds[1]).toBe('auth0|existing');
});
});

describe('createTestSuperAdmin', () => {
it('should create user with isSuperAdmin true', () => {
const admin = createTestSuperAdmin();

expect(admin.isSuperAdmin).toBe(true);
});

it('should use admin@example.com as default email', () => {
const admin = createTestSuperAdmin();

expect(admin.email).toBe('admin@example.com');
});

it('should use Super Admin as default name', () => {
const admin = createTestSuperAdmin();

expect(admin.name).toBe('Super Admin');
});

it('should allow overriding email', () => {
const admin = createTestSuperAdmin({ email: 'custom-admin@example.com' });

expect(admin.email).toBe('custom-admin@example.com');
});

it('should allow overriding name', () => {
const admin = createTestSuperAdmin({ name: 'Custom Admin' });

expect(admin.name).toBe('Custom Admin');
});

it('should preserve other default values', () => {
const admin = createTestSuperAdmin();

expect(admin.status).toBe('accepted');
expect(admin.providerIds).toEqual([]);
expect(admin.profileImage).toBeNull();
});
});

describe('createTestInvitedUser', () => {
it('should create user with status invited', () => {
const user = createTestInvitedUser();

expect(user.status).toBe('invited');
});

it('should use default values for other fields', () => {
const user = createTestInvitedUser();

expect(user.name).toBe('Test User');
expect(user.isSuperAdmin).toBe(false);
});

it('should allow overriding other options', () => {
const user = createTestInvitedUser({
name: 'Pending User',
email: 'pending@example.com',
});

expect(user.status).toBe('invited');
expect(user.name).toBe('Pending User');
expect(user.email).toBe('pending@example.com');
});
});
});
Loading