add tests
This commit is contained in:
parent
1d9f3e8d5f
commit
1c5095eb93
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@apihub24/token-authentication",
|
||||
"version": "1.0.6",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@apihub24/token-authentication",
|
||||
"version": "1.0.6",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@apihub24/authentication": "2.0.0-alpha.0",
|
||||
|
||||
196
src/guards/token.guard.spec.ts
Normal file
196
src/guards/token.guard.spec.ts
Normal file
@ -0,0 +1,196 @@
|
||||
import { ExecutionContext } from "@nestjs/common";
|
||||
import { TokenGuard } from "./token.guard";
|
||||
import { Reflector } from "@nestjs/core";
|
||||
import {
|
||||
IAccount,
|
||||
IGroup,
|
||||
IOrganization,
|
||||
IRight,
|
||||
ITokenService,
|
||||
} from "@apihub24/authentication";
|
||||
import { RIGHTS_KEY } from "./rights.decorator";
|
||||
import { ROLES_KEY } from "./roles.decorator";
|
||||
import { ORGANIZATIONS_KEY } from "./organization.decorator";
|
||||
|
||||
describe("TokenGuard Tests", () => {
|
||||
let guard: TokenGuard;
|
||||
|
||||
const mockRight: IRight = { id: "r1", name: "read:users" };
|
||||
const mockOrganization: IOrganization = { id: "o1", name: "TestOrg" };
|
||||
const mockGroup: IGroup = {
|
||||
id: "g1",
|
||||
name: "admin",
|
||||
rights: [mockRight],
|
||||
organization: mockOrganization,
|
||||
};
|
||||
const mockAccount: IAccount = {
|
||||
id: "a1",
|
||||
accountName: "a1",
|
||||
email: "a1@example.de",
|
||||
passwordHash: "passwordhash",
|
||||
active: true,
|
||||
emailVerified: true,
|
||||
groups: [mockGroup],
|
||||
};
|
||||
const mockReflector = {
|
||||
getAllAndOverride: jest.fn(),
|
||||
};
|
||||
const mockTokenService = {
|
||||
getAccount: jest.fn(),
|
||||
};
|
||||
|
||||
const mockExecutionContext = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({
|
||||
headers: {},
|
||||
}),
|
||||
}),
|
||||
} as unknown as ExecutionContext;
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks();
|
||||
guard = new TokenGuard(
|
||||
mockReflector as unknown as Reflector,
|
||||
mockTokenService as unknown as ITokenService
|
||||
);
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(guard).toBeDefined();
|
||||
});
|
||||
|
||||
it("should return true if no metadata is required", async () => {
|
||||
mockReflector.getAllAndOverride.mockReturnValue(undefined);
|
||||
const result = await guard.canActivate(mockExecutionContext);
|
||||
expect(result).toBe(true);
|
||||
expect(mockTokenService.getAccount).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("Token Validation", () => {
|
||||
it("should return false if authorization header is missing", async () => {
|
||||
mockReflector.getAllAndOverride.mockReturnValue(["read:users"]);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({ getRequest: () => ({ headers: {} }) }),
|
||||
} as unknown as ExecutionContext;
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(false);
|
||||
expect(mockTokenService.getAccount).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should return false if token is invalid", async () => {
|
||||
mockReflector.getAllAndOverride.mockReturnValue(["read:users"]);
|
||||
mockTokenService.getAccount.mockResolvedValue(null);
|
||||
const result = await guard.canActivate(mockExecutionContext);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Successful Authorization", () => {
|
||||
it("should return true if account has required right", async () => {
|
||||
mockReflector.getAllAndOverride.mockImplementation((key: string) => {
|
||||
if (key === RIGHTS_KEY) return ["read:users"];
|
||||
return undefined;
|
||||
});
|
||||
mockTokenService.getAccount.mockResolvedValue(mockAccount);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ headers: { authorization: "Bearer bla" } }),
|
||||
}),
|
||||
} as unknown as ExecutionContext;
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true if account has required role", async () => {
|
||||
mockReflector.getAllAndOverride.mockImplementation((key: string) => {
|
||||
if (key === ROLES_KEY) return ["admin"];
|
||||
return undefined;
|
||||
});
|
||||
mockTokenService.getAccount.mockResolvedValue(mockAccount);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ headers: { authorization: "Bearer bla" } }),
|
||||
}),
|
||||
} as unknown as ExecutionContext;
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true if account belongs to the required organization", async () => {
|
||||
mockReflector.getAllAndOverride.mockImplementation((key: string) => {
|
||||
if (key === ORGANIZATIONS_KEY) return ["TestOrg"];
|
||||
return undefined;
|
||||
});
|
||||
mockTokenService.getAccount.mockResolvedValue(mockAccount);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ headers: { authorization: "Bearer bla" } }),
|
||||
}),
|
||||
} as unknown as ExecutionContext;
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true if all requirements are met", async () => {
|
||||
mockReflector.getAllAndOverride.mockImplementation((key: string) => {
|
||||
if (key === RIGHTS_KEY) return ["read:users"];
|
||||
if (key === ROLES_KEY) return ["admin"];
|
||||
if (key === ORGANIZATIONS_KEY) return ["TestOrg"];
|
||||
return undefined;
|
||||
});
|
||||
mockTokenService.getAccount.mockResolvedValue(mockAccount);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ headers: { authorization: "Bearer bla" } }),
|
||||
}),
|
||||
} as unknown as ExecutionContext;
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Failed Authorization", () => {
|
||||
it("should return false if a required right is missing", async () => {
|
||||
mockReflector.getAllAndOverride.mockImplementation((key: string) => {
|
||||
if (key === RIGHTS_KEY) return ["write:users"];
|
||||
return undefined;
|
||||
});
|
||||
mockTokenService.getAccount.mockResolvedValue(mockAccount);
|
||||
const result = await guard.canActivate(mockExecutionContext);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false if a required role is missing", async () => {
|
||||
mockReflector.getAllAndOverride.mockImplementation((key: string) => {
|
||||
if (key === ROLES_KEY) return ["user"];
|
||||
return undefined;
|
||||
});
|
||||
mockTokenService.getAccount.mockResolvedValue(mockAccount);
|
||||
const result = await guard.canActivate(mockExecutionContext);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false if a required organization is missing", async () => {
|
||||
mockReflector.getAllAndOverride.mockImplementation((key: string) => {
|
||||
if (key === ORGANIZATIONS_KEY) return ["AnotherOrg"];
|
||||
return undefined;
|
||||
});
|
||||
mockTokenService.getAccount.mockResolvedValue(mockAccount);
|
||||
const result = await guard.canActivate(mockExecutionContext);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
112
src/services/group.factory.service.spec.ts
Normal file
112
src/services/group.factory.service.spec.ts
Normal file
@ -0,0 +1,112 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import {
|
||||
GroupFactoryService,
|
||||
OrganizationService,
|
||||
RightService,
|
||||
TokenAuthenticationModule,
|
||||
} from "..";
|
||||
import { IOrganization, IRight } from "@apihub24/authentication";
|
||||
import * as validator from "class-validator";
|
||||
import { Group } from "../models/group";
|
||||
|
||||
describe("GroupFactoryService Tests", () => {
|
||||
let module: TestingModule;
|
||||
let service: GroupFactoryService;
|
||||
let rightService: RightService;
|
||||
let organizationService: OrganizationService;
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(GroupFactoryService);
|
||||
rightService = module.get(RightService);
|
||||
organizationService = module.get(OrganizationService);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
it("should create a group successfully", async () => {
|
||||
const rights: IRight[] = [
|
||||
{ id: "1", name: "read" },
|
||||
{ id: "2", name: "write" },
|
||||
];
|
||||
const organizations: IOrganization[] = [{ id: "org-1", name: "Test Org" }];
|
||||
const groupName = "Admins";
|
||||
const organizationId = "org-1";
|
||||
const rightIds = ["1", "2"];
|
||||
|
||||
jest.spyOn(rightService, "getBy").mockResolvedValue(rights);
|
||||
jest.spyOn(organizationService, "getBy").mockResolvedValue(organizations);
|
||||
jest.spyOn(validator, "validate").mockResolvedValue([]);
|
||||
|
||||
const result = await service.createGroup(
|
||||
groupName,
|
||||
organizationId,
|
||||
rightIds
|
||||
);
|
||||
|
||||
expect(rightService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(organizationService.getBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(result).toBeInstanceOf(Group);
|
||||
expect(result.name).toBe(groupName);
|
||||
expect(result.organization).toBe(organizations[0]);
|
||||
expect(result.rights).toBe(rights);
|
||||
});
|
||||
|
||||
it("should throw an error if the organization does not exist", async () => {
|
||||
const groupName = "Admins";
|
||||
const organizationId = "org-1";
|
||||
const rightIds = ["1", "2"];
|
||||
|
||||
jest.spyOn(rightService, "getBy").mockResolvedValue([]);
|
||||
jest.spyOn(organizationService, "getBy").mockResolvedValue([]);
|
||||
jest.spyOn(validator, "validate").mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
service.createGroup(groupName, organizationId, rightIds)
|
||||
).rejects.toThrow(`organization with id (${organizationId}) not exists`);
|
||||
});
|
||||
|
||||
it("should throw a validation error if the group data is invalid", async () => {
|
||||
const organizations: IOrganization[] = [{ id: "org-1", name: "Test Org" }];
|
||||
const validationError: validator.ValidationError[] = [
|
||||
{ toString: () => "name must not be empty" } as validator.ValidationError,
|
||||
];
|
||||
|
||||
jest.spyOn(rightService, "getBy").mockResolvedValue([]);
|
||||
jest.spyOn(organizationService, "getBy").mockResolvedValue(organizations);
|
||||
jest
|
||||
.spyOn(validator, "validate")
|
||||
.mockResolvedValue(Promise.resolve(validationError));
|
||||
|
||||
await expect(service.createGroup("Admins", "org-1", ["1"])).rejects.toThrow(
|
||||
"name must not be empty"
|
||||
);
|
||||
});
|
||||
});
|
||||
193
src/services/group.service.spec.ts
Normal file
193
src/services/group.service.spec.ts
Normal file
@ -0,0 +1,193 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { GroupService } from "./group.service";
|
||||
import { IRepository } from "@apihub24/repository";
|
||||
import {
|
||||
APIHUB24_GROUP_REPOSITORY,
|
||||
APIHUB24_RIGHT_REPOSITORY,
|
||||
IGroup,
|
||||
IRight,
|
||||
} from "@apihub24/authentication";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import { TokenAuthenticationModule } from "..";
|
||||
|
||||
describe("GroupService Tests", () => {
|
||||
let module: TestingModule;
|
||||
let service: GroupService;
|
||||
let groupRepository: IRepository<IGroup>;
|
||||
let rightRepository: IRepository<IRight>;
|
||||
|
||||
const mockGroup: IGroup = {
|
||||
id: "group1",
|
||||
name: "Admins",
|
||||
rights: [{ id: "right1", name: "read" }],
|
||||
organization: { id: "org1", name: "Test Org" },
|
||||
};
|
||||
|
||||
const mockRight: IRight = {
|
||||
id: "right2",
|
||||
name: "write",
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(GroupService);
|
||||
groupRepository = module.get(APIHUB24_GROUP_REPOSITORY);
|
||||
rightRepository = module.get(APIHUB24_RIGHT_REPOSITORY);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe("getBy", () => {
|
||||
it("should return groups matching the filter", async () => {
|
||||
jest.spyOn(groupRepository, "getBy").mockResolvedValue([mockGroup]);
|
||||
const result = await service.getBy((g) => g.id === "group1");
|
||||
expect(result).toEqual([mockGroup]);
|
||||
expect(groupRepository.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
});
|
||||
|
||||
it("should return an empty array if no groups match", async () => {
|
||||
jest.spyOn(groupRepository, "getBy").mockResolvedValue([]);
|
||||
const result = await service.getBy((g) => g.id === "non-existent");
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("save", () => {
|
||||
it("should save a single group and return it", async () => {
|
||||
jest.spyOn(groupRepository, "save").mockResolvedValue([mockGroup]);
|
||||
const result = await service.save(mockGroup);
|
||||
expect(result).toEqual(mockGroup);
|
||||
expect(groupRepository.save).toHaveBeenCalledWith([mockGroup]);
|
||||
});
|
||||
|
||||
it("should return null if save operation fails", async () => {
|
||||
jest.spyOn(groupRepository, "save").mockResolvedValue([]);
|
||||
const result = await service.save(mockGroup);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("delete", () => {
|
||||
it("should delete groups and return true on success", async () => {
|
||||
jest.spyOn(groupRepository, "deleteBy").mockResolvedValue(true);
|
||||
const result = await service.delete((g) => g.id === "group1");
|
||||
expect(result).toBe(true);
|
||||
expect(groupRepository.deleteBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("should return false on deletion failure", async () => {
|
||||
jest.spyOn(groupRepository, "deleteBy").mockResolvedValue(false);
|
||||
const result = await service.delete((g) => g.id === "non-existent");
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("addRightToGroup", () => {
|
||||
it("should add a right to a group and return the updated group", async () => {
|
||||
const updatedGroup = {
|
||||
...mockGroup,
|
||||
rights: [...mockGroup.rights, mockRight],
|
||||
};
|
||||
jest.spyOn(groupRepository, "getBy").mockResolvedValue([mockGroup]);
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([mockRight]);
|
||||
jest.spyOn(groupRepository, "save").mockResolvedValue([updatedGroup]);
|
||||
|
||||
const result = await service.addRightToGroup("group1", "right2");
|
||||
|
||||
expect(result).toEqual(updatedGroup);
|
||||
expect(groupRepository.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(rightRepository.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(groupRepository.save).toHaveBeenCalledWith([
|
||||
expect.objectContaining({
|
||||
rights: expect.arrayContaining([mockRight]),
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("should throw an error if the group is not found", async () => {
|
||||
jest.spyOn(groupRepository, "getBy").mockResolvedValue([]);
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([mockRight]);
|
||||
await expect(
|
||||
service.addRightToGroup("non-existent", "right2")
|
||||
).rejects.toThrow("group with id non-existent not found");
|
||||
});
|
||||
|
||||
it("should throw an error if the right is not found", async () => {
|
||||
jest.spyOn(groupRepository, "getBy").mockResolvedValue([mockGroup]);
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([]);
|
||||
await expect(
|
||||
service.addRightToGroup("group1", "non-existent")
|
||||
).rejects.toThrow("right with id non-existent not found");
|
||||
});
|
||||
|
||||
it("should throw an error if the updated group cannot be saved", async () => {
|
||||
jest.spyOn(groupRepository, "getBy").mockResolvedValue([mockGroup]);
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([mockRight]);
|
||||
jest.spyOn(groupRepository, "save").mockResolvedValue([]);
|
||||
await expect(service.addRightToGroup("group1", "right2")).rejects.toThrow(
|
||||
"group Admins can not be saved"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("removeRightFromGroup", () => {
|
||||
it("should remove a right from a group and return the updated group", async () => {
|
||||
const groupWithMultipleRights: IGroup = {
|
||||
...mockGroup,
|
||||
rights: [...mockGroup.rights, mockRight],
|
||||
};
|
||||
const updatedGroup = { ...groupWithMultipleRights, rights: [mockRight] };
|
||||
jest
|
||||
.spyOn(groupRepository, "getBy")
|
||||
.mockResolvedValue([groupWithMultipleRights]);
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([mockRight]);
|
||||
jest.spyOn(groupRepository, "save").mockResolvedValue([updatedGroup]);
|
||||
|
||||
const result = await service.removeRightFromGroup("group1", "right1");
|
||||
|
||||
expect(result).toEqual(updatedGroup);
|
||||
expect(groupRepository.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(rightRepository.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(groupRepository.save).toHaveBeenCalledWith([
|
||||
expect.objectContaining({
|
||||
rights: expect.not.arrayContaining([mockGroup.rights[0]]),
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("should throw an error if the group cannot be saved", async () => {
|
||||
jest.spyOn(groupRepository, "getBy").mockResolvedValue([mockGroup]);
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([mockRight]);
|
||||
jest.spyOn(groupRepository, "save").mockResolvedValue([]);
|
||||
await expect(
|
||||
service.removeRightFromGroup("group1", "right1")
|
||||
).rejects.toThrow("group Admins can not be saved");
|
||||
});
|
||||
});
|
||||
});
|
||||
150
src/services/login.service.spec.ts
Normal file
150
src/services/login.service.spec.ts
Normal file
@ -0,0 +1,150 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { LoginService } from "./login.service";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import { AccountService, TokenAuthenticationModule } from "..";
|
||||
import { Account } from "../models/account";
|
||||
import { Session } from "../models/session";
|
||||
import { SignIn } from "../models/sign.in";
|
||||
import {
|
||||
APIHUB24_PASSWORD_SERVICE,
|
||||
APIHUB24_SESSION_SERVICE,
|
||||
APIHUB24_TOKEN_SERVICE,
|
||||
IPasswordService,
|
||||
ISessionService,
|
||||
ITokenService,
|
||||
} from "@apihub24/authentication";
|
||||
|
||||
describe("LoginService Test", () => {
|
||||
let module: TestingModule;
|
||||
let service: LoginService;
|
||||
let accountService: AccountService;
|
||||
let passwordService: IPasswordService;
|
||||
let sessionService: ISessionService;
|
||||
let tokenService: ITokenService;
|
||||
|
||||
const mockAccount: Account = {
|
||||
id: "account1",
|
||||
accountName: "testuser",
|
||||
passwordHash: "hashedpassword",
|
||||
email: "testuser@example.de",
|
||||
emailVerified: true,
|
||||
active: true,
|
||||
groups: [],
|
||||
};
|
||||
const mockSession: Session = {
|
||||
id: "session1",
|
||||
account: mockAccount,
|
||||
metaData: {},
|
||||
};
|
||||
const mockSignIn: SignIn = {
|
||||
accountName: "testuser",
|
||||
password: "password123",
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(LoginService);
|
||||
accountService = module.get(AccountService);
|
||||
passwordService = module.get(APIHUB24_PASSWORD_SERVICE);
|
||||
sessionService = module.get(APIHUB24_SESSION_SERVICE);
|
||||
tokenService = module.get(APIHUB24_TOKEN_SERVICE);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe("signIn", () => {
|
||||
it("should return a token for a valid account", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([mockAccount]);
|
||||
jest.spyOn(passwordService, "verify").mockResolvedValue(true);
|
||||
jest.spyOn(sessionService, "create").mockResolvedValue(mockSession);
|
||||
jest.spyOn(tokenService, "generate").mockResolvedValue("jwt_token");
|
||||
|
||||
const result = await service.signIn(mockSignIn);
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(passwordService.verify).toHaveBeenCalledWith(
|
||||
mockSignIn.password,
|
||||
mockAccount.passwordHash
|
||||
);
|
||||
expect(sessionService.create).toHaveBeenCalledWith(mockAccount);
|
||||
expect(tokenService.generate).toHaveBeenCalledWith(
|
||||
mockSession,
|
||||
mockSignIn.accountName,
|
||||
"1h",
|
||||
"HS512"
|
||||
);
|
||||
expect(result).toBe("jwt_token");
|
||||
});
|
||||
|
||||
it("should return an empty string if account is not found", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([]);
|
||||
const result = await service.signIn(mockSignIn);
|
||||
expect(result).toBe("");
|
||||
});
|
||||
|
||||
it("should return an empty string if password verification fails", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([mockAccount]);
|
||||
jest.spyOn(passwordService, "verify").mockResolvedValue(false);
|
||||
const result = await service.signIn(mockSignIn);
|
||||
expect(result).toBe("");
|
||||
});
|
||||
|
||||
it("should return an empty string if the account has no password hash", async () => {
|
||||
const noPasswordHashAccount = { ...mockAccount, passwordHash: "" };
|
||||
jest
|
||||
.spyOn(accountService, "getBy")
|
||||
.mockResolvedValue([noPasswordHashAccount]);
|
||||
const result = await service.signIn(mockSignIn);
|
||||
expect(result).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("signOut", () => {
|
||||
it("should successfully remove a session", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([mockAccount]);
|
||||
jest.spyOn(sessionService, "getBy").mockResolvedValue([mockSession]);
|
||||
jest.spyOn(sessionService, "remove").mockResolvedValue();
|
||||
|
||||
await service.signOut("account1");
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(sessionService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(sessionService.remove).toHaveBeenCalledWith(mockSession.id);
|
||||
});
|
||||
|
||||
it("should do nothing if the account is not found", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([]);
|
||||
await service.signOut("non-existent-id");
|
||||
});
|
||||
|
||||
it("should do nothing if no session is found for the account", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([mockAccount]);
|
||||
jest.spyOn(sessionService, "getBy").mockResolvedValue([]);
|
||||
await service.signOut("account1");
|
||||
});
|
||||
});
|
||||
});
|
||||
49
src/services/organization.factory.service.spec.ts
Normal file
49
src/services/organization.factory.service.spec.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { OrganizationFactoryService } from "./organization.factory.service";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import { TokenAuthenticationModule } from "..";
|
||||
import { Organization } from "../models/organization";
|
||||
|
||||
describe("OrganizationFactoryService Tests", () => {
|
||||
let module: TestingModule;
|
||||
let service: OrganizationFactoryService;
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(OrganizationFactoryService);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
it("should create an organization with the correct name", () => {
|
||||
const orgName = "Test Organization";
|
||||
const result = service.createFromName(orgName);
|
||||
|
||||
expect(result).toBeInstanceOf(Organization);
|
||||
expect(result.name).toBe(orgName);
|
||||
});
|
||||
});
|
||||
130
src/services/organization.service.spec.ts
Normal file
130
src/services/organization.service.spec.ts
Normal file
@ -0,0 +1,130 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { OrganizationService } from "./organization.service";
|
||||
import { IRepository } from "@apihub24/repository";
|
||||
import {
|
||||
APIHUB24_ORGANIZATION_REPOSITORY,
|
||||
IOrganization,
|
||||
} from "@apihub24/authentication";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import { TokenAuthenticationModule } from "../token.authentication.module";
|
||||
|
||||
describe("OrganizationService Tests", () => {
|
||||
let module: TestingModule;
|
||||
let service: OrganizationService;
|
||||
let organizationRepository: IRepository<IOrganization>;
|
||||
|
||||
const mockOrganization: IOrganization = {
|
||||
id: "org1",
|
||||
name: "Test Organization",
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(OrganizationService);
|
||||
organizationRepository = module.get(APIHUB24_ORGANIZATION_REPOSITORY);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe("getBy", () => {
|
||||
it("should return organizations matching the filter", async () => {
|
||||
jest
|
||||
.spyOn(organizationRepository, "getBy")
|
||||
.mockResolvedValue([mockOrganization]);
|
||||
|
||||
const result = await service.getBy((org) => org.id === "org1");
|
||||
|
||||
expect(result).toEqual([mockOrganization]);
|
||||
expect(organizationRepository.getBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("should return an empty array if no organizations match", async () => {
|
||||
jest.spyOn(organizationRepository, "getBy").mockResolvedValue([]);
|
||||
|
||||
const result = await service.getBy((org) => org.id === "non-existent-id");
|
||||
|
||||
expect(result).toEqual([]);
|
||||
expect(organizationRepository.getBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("save", () => {
|
||||
it("should save a single organization and return it", async () => {
|
||||
jest
|
||||
.spyOn(organizationRepository, "save")
|
||||
.mockResolvedValue([mockOrganization]);
|
||||
|
||||
const result = await service.save(mockOrganization);
|
||||
|
||||
expect(result).toEqual(mockOrganization);
|
||||
expect(organizationRepository.save).toHaveBeenCalledWith([
|
||||
mockOrganization,
|
||||
]);
|
||||
});
|
||||
|
||||
it("should throw an error if the save operation fails", async () => {
|
||||
jest.spyOn(organizationRepository, "save").mockResolvedValue([]);
|
||||
|
||||
await expect(service.save(mockOrganization)).rejects.toThrow(
|
||||
`organization (${mockOrganization.name}) not saved`
|
||||
);
|
||||
expect(organizationRepository.save).toHaveBeenCalledWith([
|
||||
mockOrganization,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("deleteBy", () => {
|
||||
it("should delete organizations and return true on success", async () => {
|
||||
jest.spyOn(organizationRepository, "deleteBy").mockResolvedValue(true);
|
||||
|
||||
const result = await service.deleteBy((org) => org.id === "org1");
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(organizationRepository.deleteBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("should return false on deletion failure", async () => {
|
||||
jest.spyOn(organizationRepository, "deleteBy").mockResolvedValue(false);
|
||||
|
||||
const result = await service.deleteBy(
|
||||
(org) => org.id === "non-existent-id"
|
||||
);
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(organizationRepository.deleteBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
207
src/services/registration.service.spec.ts
Normal file
207
src/services/registration.service.spec.ts
Normal file
@ -0,0 +1,207 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { RegistrationService } from "./registration.service";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import {
|
||||
AccountFactoryService,
|
||||
AccountService,
|
||||
TokenAuthenticationModule,
|
||||
} from "..";
|
||||
import { Account } from "../models/account";
|
||||
import {
|
||||
APIHUB24_MAIL_SERVICE,
|
||||
IMailVerificationService,
|
||||
IRegistration,
|
||||
} from "@apihub24/authentication";
|
||||
|
||||
describe("RegistrationService Tests", () => {
|
||||
let module: TestingModule;
|
||||
let service: RegistrationService;
|
||||
let accountFactoryService: AccountFactoryService;
|
||||
let accountService: AccountService;
|
||||
let mailVerificationService: IMailVerificationService;
|
||||
|
||||
const mockRegistration: IRegistration = {
|
||||
accountName: "testuser",
|
||||
email: "test@example.com",
|
||||
password: "password123",
|
||||
passwordComparer: "password123",
|
||||
groupIds: [],
|
||||
};
|
||||
const mockAccount: Account = {
|
||||
id: "account1",
|
||||
accountName: "testuser",
|
||||
email: "test@example.com",
|
||||
emailVerified: false,
|
||||
active: false,
|
||||
passwordHash: "passwordhash",
|
||||
groups: [],
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(RegistrationService);
|
||||
accountFactoryService = module.get(AccountFactoryService);
|
||||
accountService = module.get(AccountService);
|
||||
mailVerificationService = module.get(APIHUB24_MAIL_SERVICE);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe("registerAccount", () => {
|
||||
it("should register a new account and return it", async () => {
|
||||
jest
|
||||
.spyOn(accountFactoryService, "createFromRegistration")
|
||||
.mockResolvedValue(mockAccount);
|
||||
jest.spyOn(accountService, "save").mockResolvedValue(mockAccount);
|
||||
|
||||
const result = await service.registerAccount(mockRegistration);
|
||||
|
||||
expect(accountFactoryService.createFromRegistration).toHaveBeenCalledWith(
|
||||
mockRegistration
|
||||
);
|
||||
expect(accountService.save).toHaveBeenCalledWith(mockAccount);
|
||||
expect(result).toEqual(mockAccount);
|
||||
});
|
||||
|
||||
it("should return null if account saving fails", async () => {
|
||||
jest
|
||||
.spyOn(accountFactoryService, "createFromRegistration")
|
||||
.mockResolvedValue(mockAccount);
|
||||
jest.spyOn(accountService, "save").mockResolvedValue(null);
|
||||
|
||||
const result = await service.registerAccount(mockRegistration);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("verify", () => {
|
||||
it("should verify an email and update unverified accounts", async () => {
|
||||
const unverifiedAccount = { ...mockAccount, emailVerified: false };
|
||||
const verifiedAccount = { ...mockAccount, emailVerified: true };
|
||||
jest.spyOn(mailVerificationService, "verify").mockResolvedValue(true);
|
||||
jest
|
||||
.spyOn(accountService, "getBy")
|
||||
.mockResolvedValue([unverifiedAccount]);
|
||||
jest.spyOn(accountService, "save").mockResolvedValue(verifiedAccount);
|
||||
|
||||
const result = await service.verify("test@example.com", "123456");
|
||||
|
||||
expect(mailVerificationService.verify).toHaveBeenCalledWith(
|
||||
"test@example.com",
|
||||
"123456"
|
||||
);
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(accountService.save).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ emailVerified: true })
|
||||
);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if verification code is invalid", async () => {
|
||||
jest.spyOn(mailVerificationService, "verify").mockResolvedValue(false);
|
||||
|
||||
const result = await service.verify("test@example.com", "invalid-code");
|
||||
|
||||
expect(mailVerificationService.verify).toHaveBeenCalledWith(
|
||||
"test@example.com",
|
||||
"invalid-code"
|
||||
);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("activateAccount", () => {
|
||||
it("should activate an account and return true", async () => {
|
||||
const activeAccount = { ...mockAccount, active: true };
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([mockAccount]);
|
||||
jest.spyOn(accountService, "save").mockResolvedValue(activeAccount);
|
||||
|
||||
const result = await service.activateAccount("account1");
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(accountService.save).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ active: true })
|
||||
);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if the account is not found", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([]);
|
||||
|
||||
const result = await service.activateAccount("non-existent-id");
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("deactivateAccount", () => {
|
||||
it("should deactivate an account and return true", async () => {
|
||||
const deactivatedAccount = { ...mockAccount, active: false };
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([mockAccount]);
|
||||
jest.spyOn(accountService, "save").mockResolvedValue(deactivatedAccount);
|
||||
|
||||
const result = await service.deactivateAccount("account1");
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(accountService.save).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ active: false })
|
||||
);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true if the account is not found", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([]);
|
||||
|
||||
const result = await service.deactivateAccount("non-existent-id");
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("unregisterAccount", () => {
|
||||
it("should delete an account if it exists", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([mockAccount]);
|
||||
jest.spyOn(accountService, "delete").mockResolvedValue(true);
|
||||
|
||||
await service.unregisterAccount("account1");
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
expect(accountService.delete).toHaveBeenCalledWith(expect.any(Function));
|
||||
});
|
||||
|
||||
it("should do nothing if the account is not found", async () => {
|
||||
jest.spyOn(accountService, "getBy").mockResolvedValue([]);
|
||||
|
||||
await service.unregisterAccount("non-existent-id");
|
||||
|
||||
expect(accountService.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
});
|
||||
});
|
||||
});
|
||||
70
src/services/right.factory.service.spec.ts
Normal file
70
src/services/right.factory.service.spec.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { RightFactoryService } from "./right.factory.service";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import { TokenAuthenticationModule } from "..";
|
||||
import * as validator from "class-validator";
|
||||
import { Right } from "../models/right";
|
||||
|
||||
describe("RightFactoryService Tests", () => {
|
||||
let module: TestingModule;
|
||||
let service: RightFactoryService;
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(RightFactoryService);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe("createRight", () => {
|
||||
it("should create a right successfully with a valid name", async () => {
|
||||
const rightName = "read:articles";
|
||||
jest.spyOn(validator, "validate").mockResolvedValue([]);
|
||||
|
||||
const result = await service.createRight(rightName);
|
||||
|
||||
expect(validator.validate).toHaveBeenCalled();
|
||||
expect(result).toBeInstanceOf(Right);
|
||||
expect(result.name).toBe(rightName);
|
||||
});
|
||||
|
||||
it("should throw an error if validation fails", async () => {
|
||||
const rightName = "";
|
||||
const validationError = [
|
||||
{
|
||||
toString: () => "name must not be empty",
|
||||
} as validator.ValidationError,
|
||||
];
|
||||
jest.spyOn(validator, "validate").mockResolvedValue(validationError);
|
||||
|
||||
await expect(service.createRight(rightName)).rejects.toThrow(
|
||||
"name must not be empty"
|
||||
);
|
||||
expect(validator.validate).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
113
src/services/right.service.spec.ts
Normal file
113
src/services/right.service.spec.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { RightService } from "./right.service";
|
||||
import { IRepository } from "@apihub24/repository";
|
||||
import { APIHUB24_RIGHT_REPOSITORY, IRight } from "@apihub24/authentication";
|
||||
import { MailServiceMockModule } from "../../test/mail.verification.service.mock";
|
||||
import { PasswordServiceMockModule } from "../../test/password.service.mock";
|
||||
import { SessionServiceMockModule } from "../../test/session.service.mock";
|
||||
import { TokenServiceMockModule } from "../../test/token.service.mock";
|
||||
import { AccountRepositoryMockModule } from "../../test/account.repository.mock";
|
||||
import { GroupRepositoryMockModule } from "../../test/group.repository.mock";
|
||||
import { RightRepositoryMockModule } from "../../test/right.repository.mock";
|
||||
import { OrganizationRepositoryMockModule } from "../../test/organization.repository.mock";
|
||||
import { TokenAuthenticationModule } from "..";
|
||||
|
||||
describe("RightService Tests", () => {
|
||||
let module: TestingModule;
|
||||
let service: RightService;
|
||||
let rightRepository: IRepository<IRight>;
|
||||
|
||||
const mockRight: IRight = {
|
||||
id: "right1",
|
||||
name: "read:users",
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
MailServiceMockModule.forRoot(),
|
||||
PasswordServiceMockModule.forRoot(),
|
||||
SessionServiceMockModule.forRoot(),
|
||||
TokenServiceMockModule.forRoot(),
|
||||
AccountRepositoryMockModule.forRoot(),
|
||||
GroupRepositoryMockModule.forRoot(),
|
||||
RightRepositoryMockModule.forRoot(),
|
||||
OrganizationRepositoryMockModule.forRoot(),
|
||||
TokenAuthenticationModule.forRoot(),
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get(RightService);
|
||||
rightRepository = module.get(APIHUB24_RIGHT_REPOSITORY);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe("getBy", () => {
|
||||
it("should return rights that match the filter", async () => {
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([mockRight]);
|
||||
|
||||
const result = await service.getBy((r) => r.id === "right1");
|
||||
|
||||
expect(result).toEqual([mockRight]);
|
||||
expect(rightRepository.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
});
|
||||
|
||||
it("should return an empty array if no rights match", async () => {
|
||||
jest.spyOn(rightRepository, "getBy").mockResolvedValue([]);
|
||||
|
||||
const result = await service.getBy((r) => r.id === "non-existent-id");
|
||||
|
||||
expect(result).toEqual([]);
|
||||
expect(rightRepository.getBy).toHaveBeenCalledWith(expect.any(Function));
|
||||
});
|
||||
});
|
||||
|
||||
describe("save", () => {
|
||||
it("should save a right and return it on success", async () => {
|
||||
jest.spyOn(rightRepository, "save").mockResolvedValue([mockRight]);
|
||||
|
||||
const result = await service.save(mockRight);
|
||||
|
||||
expect(result).toEqual(mockRight);
|
||||
expect(rightRepository.save).toHaveBeenCalledWith([mockRight]);
|
||||
});
|
||||
|
||||
it("should return null if the save operation fails", async () => {
|
||||
jest.spyOn(rightRepository, "save").mockResolvedValue([]);
|
||||
|
||||
const result = await service.save(mockRight);
|
||||
|
||||
expect(result).toBeNull();
|
||||
expect(rightRepository.save).toHaveBeenCalledWith([mockRight]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("delete", () => {
|
||||
it("should return true if the deletion is successful", async () => {
|
||||
jest.spyOn(rightRepository, "deleteBy").mockResolvedValue(true);
|
||||
|
||||
const result = await service.delete((r) => r.id === "right1");
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(rightRepository.deleteBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("should return false if the deletion fails", async () => {
|
||||
jest.spyOn(rightRepository, "deleteBy").mockResolvedValue(false);
|
||||
|
||||
const result = await service.delete((r) => r.id === "non-existent-id");
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(rightRepository.deleteBy).toHaveBeenCalledWith(
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user