Add unit tests for models and services
- Implemented unit tests for the Package model, covering methods such as generateId, findById, findByName, and version management. - Created unit tests for the Repository model, including repository creation, name validation, and retrieval methods. - Added tests for the Session model, focusing on session creation, validation, and invalidation. - Developed unit tests for the User model, ensuring user creation, password hashing, and retrieval methods function correctly. - Implemented AuthService tests, validating login, token refresh, and session management. - Added TokenService tests, covering token creation, validation, and revocation processes.
This commit is contained in:
268
test/helpers/factory.helper.ts
Normal file
268
test/helpers/factory.helper.ts
Normal file
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* Factory helper - creates test entities with sensible defaults
|
||||
*/
|
||||
|
||||
import { Organization } from '../../ts/models/organization.ts';
|
||||
import { OrganizationMember } from '../../ts/models/organization.member.ts';
|
||||
import { Repository } from '../../ts/models/repository.ts';
|
||||
import { Team } from '../../ts/models/team.ts';
|
||||
import { TeamMember } from '../../ts/models/team.member.ts';
|
||||
import { Package } from '../../ts/models/package.ts';
|
||||
import { RepositoryPermission } from '../../ts/models/repository.permission.ts';
|
||||
import type {
|
||||
TOrganizationRole,
|
||||
TTeamRole,
|
||||
TRepositoryRole,
|
||||
TRepositoryVisibility,
|
||||
TRegistryProtocol,
|
||||
} from '../../ts/interfaces/auth.interfaces.ts';
|
||||
|
||||
export interface ICreateTestOrganizationOptions {
|
||||
createdById: string;
|
||||
name?: string;
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
isPublic?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create test organization
|
||||
*/
|
||||
export async function createTestOrganization(
|
||||
options: ICreateTestOrganizationOptions
|
||||
): Promise<Organization> {
|
||||
const uniqueId = crypto.randomUUID().slice(0, 8);
|
||||
|
||||
const org = await Organization.createOrganization({
|
||||
name: options.name || `test-org-${uniqueId}`,
|
||||
displayName: options.displayName || `Test Org ${uniqueId}`,
|
||||
description: options.description || 'Test organization',
|
||||
createdById: options.createdById,
|
||||
});
|
||||
|
||||
if (options.isPublic !== undefined) {
|
||||
org.isPublic = options.isPublic;
|
||||
await org.save();
|
||||
}
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create organization with owner membership
|
||||
*/
|
||||
export async function createOrgWithOwner(
|
||||
ownerId: string,
|
||||
orgOptions?: Partial<ICreateTestOrganizationOptions>
|
||||
): Promise<{
|
||||
organization: Organization;
|
||||
membership: OrganizationMember;
|
||||
}> {
|
||||
const organization = await createTestOrganization({
|
||||
createdById: ownerId,
|
||||
...orgOptions,
|
||||
});
|
||||
|
||||
const membership = await OrganizationMember.addMember({
|
||||
organizationId: organization.id,
|
||||
userId: ownerId,
|
||||
role: 'owner',
|
||||
});
|
||||
|
||||
organization.memberCount = 1;
|
||||
await organization.save();
|
||||
|
||||
return { organization, membership };
|
||||
}
|
||||
|
||||
/**
|
||||
* Add member to organization
|
||||
*/
|
||||
export async function addOrgMember(
|
||||
organizationId: string,
|
||||
userId: string,
|
||||
role: TOrganizationRole = 'member',
|
||||
invitedBy?: string
|
||||
): Promise<OrganizationMember> {
|
||||
const membership = await OrganizationMember.addMember({
|
||||
organizationId,
|
||||
userId,
|
||||
role,
|
||||
invitedBy,
|
||||
});
|
||||
|
||||
const org = await Organization.findById(organizationId);
|
||||
if (org) {
|
||||
org.memberCount += 1;
|
||||
await org.save();
|
||||
}
|
||||
|
||||
return membership;
|
||||
}
|
||||
|
||||
export interface ICreateTestRepositoryOptions {
|
||||
organizationId: string;
|
||||
createdById: string;
|
||||
name?: string;
|
||||
protocol?: TRegistryProtocol;
|
||||
visibility?: TRepositoryVisibility;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create test repository
|
||||
*/
|
||||
export async function createTestRepository(
|
||||
options: ICreateTestRepositoryOptions
|
||||
): Promise<Repository> {
|
||||
const uniqueId = crypto.randomUUID().slice(0, 8);
|
||||
|
||||
return Repository.createRepository({
|
||||
organizationId: options.organizationId,
|
||||
name: options.name || `test-repo-${uniqueId}`,
|
||||
protocol: options.protocol || 'npm',
|
||||
visibility: options.visibility || 'private',
|
||||
description: options.description || 'Test repository',
|
||||
createdById: options.createdById,
|
||||
});
|
||||
}
|
||||
|
||||
export interface ICreateTestTeamOptions {
|
||||
organizationId: string;
|
||||
name?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create test team
|
||||
*/
|
||||
export async function createTestTeam(options: ICreateTestTeamOptions): Promise<Team> {
|
||||
const uniqueId = crypto.randomUUID().slice(0, 8);
|
||||
|
||||
return Team.createTeam({
|
||||
organizationId: options.organizationId,
|
||||
name: options.name || `test-team-${uniqueId}`,
|
||||
description: options.description || 'Test team',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add member to team
|
||||
*/
|
||||
export async function addTeamMember(
|
||||
teamId: string,
|
||||
userId: string,
|
||||
role: TTeamRole = 'member'
|
||||
): Promise<TeamMember> {
|
||||
const member = new TeamMember();
|
||||
member.id = await TeamMember.getNewId();
|
||||
member.teamId = teamId;
|
||||
member.userId = userId;
|
||||
member.role = role;
|
||||
member.createdAt = new Date();
|
||||
await member.save();
|
||||
return member;
|
||||
}
|
||||
|
||||
export interface IGrantRepoPermissionOptions {
|
||||
repositoryId: string;
|
||||
userId?: string;
|
||||
teamId?: string;
|
||||
role: TRepositoryRole;
|
||||
grantedById: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant repository permission
|
||||
*/
|
||||
export async function grantRepoPermission(
|
||||
options: IGrantRepoPermissionOptions
|
||||
): Promise<RepositoryPermission> {
|
||||
const perm = new RepositoryPermission();
|
||||
perm.id = await RepositoryPermission.getNewId();
|
||||
perm.repositoryId = options.repositoryId;
|
||||
perm.userId = options.userId;
|
||||
perm.teamId = options.teamId;
|
||||
perm.role = options.role;
|
||||
perm.grantedById = options.grantedById;
|
||||
perm.createdAt = new Date();
|
||||
await perm.save();
|
||||
return perm;
|
||||
}
|
||||
|
||||
export interface ICreateTestPackageOptions {
|
||||
organizationId: string;
|
||||
repositoryId: string;
|
||||
createdById: string;
|
||||
name?: string;
|
||||
protocol?: TRegistryProtocol;
|
||||
versions?: string[];
|
||||
isPrivate?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create test package
|
||||
*/
|
||||
export async function createTestPackage(options: ICreateTestPackageOptions): Promise<Package> {
|
||||
const uniqueId = crypto.randomUUID().slice(0, 8);
|
||||
const protocol = options.protocol || 'npm';
|
||||
const name = options.name || `test-package-${uniqueId}`;
|
||||
|
||||
const pkg = new Package();
|
||||
pkg.id = Package.generateId(protocol, options.organizationId, name);
|
||||
pkg.organizationId = options.organizationId;
|
||||
pkg.repositoryId = options.repositoryId;
|
||||
pkg.protocol = protocol;
|
||||
pkg.name = name;
|
||||
pkg.isPrivate = options.isPrivate ?? true;
|
||||
pkg.createdById = options.createdById;
|
||||
pkg.createdAt = new Date();
|
||||
pkg.updatedAt = new Date();
|
||||
|
||||
const versions = options.versions || ['1.0.0'];
|
||||
for (const version of versions) {
|
||||
pkg.addVersion({
|
||||
version,
|
||||
publishedAt: new Date(),
|
||||
publishedById: options.createdById,
|
||||
size: 1024,
|
||||
digest: `sha256:${crypto.randomUUID().replace(/-/g, '')}`,
|
||||
downloads: 0,
|
||||
metadata: {},
|
||||
});
|
||||
}
|
||||
|
||||
pkg.distTags['latest'] = versions[versions.length - 1];
|
||||
await pkg.save();
|
||||
return pkg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create complete test scenario with org, repo, team, and package
|
||||
*/
|
||||
export async function createFullTestScenario(ownerId: string): Promise<{
|
||||
organization: Organization;
|
||||
repository: Repository;
|
||||
team: Team;
|
||||
package: Package;
|
||||
}> {
|
||||
const { organization } = await createOrgWithOwner(ownerId);
|
||||
|
||||
const repository = await createTestRepository({
|
||||
organizationId: organization.id,
|
||||
createdById: ownerId,
|
||||
protocol: 'npm',
|
||||
});
|
||||
|
||||
const team = await createTestTeam({
|
||||
organizationId: organization.id,
|
||||
});
|
||||
|
||||
const pkg = await createTestPackage({
|
||||
organizationId: organization.id,
|
||||
repositoryId: repository.id,
|
||||
createdById: ownerId,
|
||||
});
|
||||
|
||||
return { organization, repository, team, package: pkg };
|
||||
}
|
||||
Reference in New Issue
Block a user