Introduce `getPublicUrl` in `S3Service` for generating public URLs. Replace custom file URL generation logic across services with the new method. Add media controller for file streaming and update related tests. Adjust frontend to display user roles instead of email in the sidebar. Update environment schema to include optional `API_URL`. Fix help page contact email.
132 lines
3.3 KiB
TypeScript
132 lines
3.3 KiB
TypeScript
jest.mock("uuid", () => ({
|
|
v4: jest.fn(() => "mocked-uuid"),
|
|
}));
|
|
|
|
jest.mock("@noble/post-quantum/ml-kem.js", () => ({
|
|
ml_kem768: {
|
|
keygen: jest.fn(),
|
|
encapsulate: jest.fn(),
|
|
decapsulate: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
jest.mock("jose", () => ({
|
|
SignJWT: jest.fn(),
|
|
jwtVerify: jest.fn(),
|
|
}));
|
|
|
|
import { CACHE_MANAGER } from "@nestjs/cache-manager";
|
|
import { ConfigService } from "@nestjs/config";
|
|
import { Test, TestingModule } from "@nestjs/testing";
|
|
import { RbacService } from "../auth/rbac.service";
|
|
import { MediaService } from "../media/media.service";
|
|
import { S3Service } from "../s3/s3.service";
|
|
import { UsersRepository } from "./repositories/users.repository";
|
|
import { UsersService } from "./users.service";
|
|
|
|
describe("UsersService", () => {
|
|
let service: UsersService;
|
|
let repository: UsersRepository;
|
|
|
|
const mockUsersRepository = {
|
|
create: jest.fn(),
|
|
findOne: jest.fn(),
|
|
findByEmailHash: jest.fn(),
|
|
findOneWithPrivateData: jest.fn(),
|
|
countAll: jest.fn(),
|
|
findAll: jest.fn(),
|
|
findByUsername: jest.fn(),
|
|
update: jest.fn(),
|
|
getTwoFactorSecret: jest.fn(),
|
|
getUserContents: jest.fn(),
|
|
getUserFavorites: jest.fn(),
|
|
softDeleteUserAndContents: jest.fn(),
|
|
};
|
|
|
|
const mockCacheManager = {
|
|
del: jest.fn(),
|
|
};
|
|
|
|
const mockRbacService = {
|
|
getUserRoles: jest.fn(),
|
|
};
|
|
|
|
const mockMediaService = {
|
|
scanFile: jest.fn(),
|
|
processImage: jest.fn(),
|
|
};
|
|
|
|
const mockS3Service = {
|
|
uploadFile: jest.fn(),
|
|
getPublicUrl: jest.fn(),
|
|
};
|
|
|
|
const mockConfigService = {
|
|
get: jest.fn(),
|
|
};
|
|
|
|
beforeEach(async () => {
|
|
jest.clearAllMocks();
|
|
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
providers: [
|
|
UsersService,
|
|
{ provide: UsersRepository, useValue: mockUsersRepository },
|
|
{ provide: CACHE_MANAGER, useValue: mockCacheManager },
|
|
{ provide: RbacService, useValue: mockRbacService },
|
|
{ provide: MediaService, useValue: mockMediaService },
|
|
{ provide: S3Service, useValue: mockS3Service },
|
|
{ provide: ConfigService, useValue: mockConfigService },
|
|
],
|
|
}).compile();
|
|
|
|
service = module.get<UsersService>(UsersService);
|
|
repository = module.get<UsersRepository>(UsersRepository);
|
|
});
|
|
|
|
it("should be defined", () => {
|
|
expect(service).toBeDefined();
|
|
});
|
|
|
|
describe("create", () => {
|
|
it("should create a user", async () => {
|
|
const data = {
|
|
username: "u1",
|
|
email: "e1",
|
|
passwordHash: "p1",
|
|
emailHash: "eh1",
|
|
};
|
|
mockUsersRepository.create.mockResolvedValue({ uuid: "uuid1", ...data });
|
|
|
|
const result = await service.create(data);
|
|
|
|
expect(result.uuid).toBe("uuid1");
|
|
expect(repository.create).toHaveBeenCalledWith(data);
|
|
});
|
|
});
|
|
|
|
describe("findOne", () => {
|
|
it("should find a user", async () => {
|
|
mockUsersRepository.findOne.mockResolvedValue({ uuid: "uuid1" });
|
|
const result = await service.findOne("uuid1");
|
|
expect(result.uuid).toBe("uuid1");
|
|
});
|
|
|
|
it("should return null if not found", async () => {
|
|
mockUsersRepository.findOne.mockResolvedValue(null);
|
|
const result = await service.findOne("uuid1");
|
|
expect(result).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("update", () => {
|
|
it("should update a user", async () => {
|
|
mockUsersRepository.update.mockResolvedValue([
|
|
{ uuid: "uuid1", displayName: "New" },
|
|
]);
|
|
const result = await service.update("uuid1", { displayName: "New" });
|
|
expect(result[0].displayName).toBe("New");
|
|
});
|
|
});
|
|
});
|