refactor: memory medium tests (#19568)

This commit is contained in:
Jason Rasmussen
2025-06-26 19:52:10 -04:00
committed by GitHub
parent 6fed223405
commit 6c6a32c63e
3 changed files with 206 additions and 202 deletions
@@ -0,0 +1,132 @@
import { MemoryController } from 'src/controllers/memory.controller';
import { MemoryService } from 'src/services/memory.service';
import request from 'supertest';
import { errorDto } from 'test/medium/responses';
import { factory } from 'test/small.factory';
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
describe(MemoryController.name, () => {
let ctx: ControllerContext;
const service = mockBaseService(MemoryService);
beforeAll(async () => {
ctx = await controllerSetup(MemoryController, [{ provide: MemoryService, useValue: service }]);
return () => ctx.close();
});
beforeEach(() => {
service.resetAllMocks();
ctx.reset();
});
describe('GET /memories', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).get('/memories');
expect(ctx.authenticate).toHaveBeenCalled();
});
});
describe('POST /memories', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).post('/memories');
expect(ctx.authenticate).toHaveBeenCalled();
});
it('should validate data when type is on this day', async () => {
const { status, body } = await request(ctx.getHttpServer())
.post('/memories')
.send({
type: 'on_this_day',
data: {},
memoryAt: new Date(2021).toISOString(),
});
expect(status).toBe(400);
expect(body).toEqual(
errorDto.badRequest(['data.year must be a positive number', 'data.year must be an integer number']),
);
});
});
describe('GET /memories/statistics', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).get('/memories/statistics');
expect(ctx.authenticate).toHaveBeenCalled();
});
});
describe('GET /memories/:id', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).get(`/memories/${factory.uuid()}`);
expect(ctx.authenticate).toHaveBeenCalled();
});
it('should require a valid id', async () => {
const { status, body } = await request(ctx.getHttpServer()).get(`/memories/invalid`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['id must be a UUID']));
});
});
describe('PUT /memories/:id', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).put(`/memories/${factory.uuid()}`);
expect(ctx.authenticate).toHaveBeenCalled();
});
it('should require a valid id', async () => {
const { status, body } = await request(ctx.getHttpServer()).put(`/memories/invalid`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['id must be a UUID']));
});
});
describe('DELETE /memories/:id', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).delete(`/memories/${factory.uuid()}`);
expect(ctx.authenticate).toHaveBeenCalled();
});
});
describe('PUT /memories/:id/assets', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).put(`/memories/${factory.uuid()}/assets`);
expect(ctx.authenticate).toHaveBeenCalled();
});
it('should require a valid id', async () => {
const { status, body } = await request(ctx.getHttpServer()).put(`/memories/invalid/assets`).send({ ids: [] });
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['id must be a UUID']));
});
it('should require a valid asset id', async () => {
const { status, body } = await request(ctx.getHttpServer())
.put(`/memories/${factory.uuid()}/assets`)
.send({ ids: ['invalid'] });
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['each value in ids must be a UUID']));
});
});
describe('DELETE /memories/:id/assets', () => {
it('should be an authenticated route', async () => {
await request(ctx.getHttpServer()).delete(`/memories/${factory.uuid()}/assets`);
expect(ctx.authenticate).toHaveBeenCalled();
});
it('should require a valid id', async () => {
const { status, body } = await request(ctx.getHttpServer()).delete(`/memories/invalid/assets`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['id must be a UUID']));
});
it('should require a valid asset id', async () => {
const { status, body } = await request(ctx.getHttpServer())
.delete(`/memories/${factory.uuid()}/assets`)
.send({ ids: ['invalid'] });
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['each value in ids must be a UUID']));
});
});
});
@@ -1,7 +1,8 @@
import { Kysely } from 'kysely';
import { DateTime } from 'luxon';
import { DB } from 'src/db';
import { AssetFileType } from 'src/enum';
import { AssetFileType, MemoryType } from 'src/enum';
import { AccessRepository } from 'src/repositories/access.repository';
import { AssetRepository } from 'src/repositories/asset.repository';
import { DatabaseRepository } from 'src/repositories/database.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
@@ -11,6 +12,7 @@ import { SystemMetadataRepository } from 'src/repositories/system-metadata.repos
import { UserRepository } from 'src/repositories/user.repository';
import { MemoryService } from 'src/services/memory.service';
import { newMediumService } from 'test/medium.factory';
import { factory } from 'test/small.factory';
import { getKyselyDB } from 'test/utils';
let defaultDatabase: Kysely<DB>;
@@ -19,6 +21,7 @@ const setup = (db?: Kysely<DB>) => {
return newMediumService(MemoryService, {
database: db || defaultDatabase,
real: [
AccessRepository,
AssetRepository,
DatabaseRepository,
MemoryRepository,
@@ -36,6 +39,74 @@ describe(MemoryService.name, () => {
defaultDatabase = await getKyselyDB();
});
describe('create', () => {
it('should create a new memory', async () => {
const { sut, ctx } = setup();
const { user } = await ctx.newUser();
const auth = factory.auth({ user });
const dto = {
type: MemoryType.ON_THIS_DAY,
data: { year: 2021 },
memoryAt: new Date(2021),
};
await expect(sut.create(auth, dto)).resolves.toEqual({
id: expect.any(String),
type: dto.type,
data: dto.data,
createdAt: expect.any(Date),
updatedAt: expect.any(Date),
isSaved: false,
memoryAt: dto.memoryAt,
ownerId: user.id,
assets: [],
});
});
it('should create a new memory (with assets)', async () => {
const { sut, ctx } = setup();
const { user } = await ctx.newUser();
const { asset: asset1 } = await ctx.newAsset({ ownerId: user.id });
const { asset: asset2 } = await ctx.newAsset({ ownerId: user.id });
const auth = factory.auth({ user });
const dto = {
type: MemoryType.ON_THIS_DAY,
data: { year: 2021 },
memoryAt: new Date(2021),
assetIds: [asset1.id, asset2.id],
};
await expect(sut.create(auth, dto)).resolves.toEqual(
expect.objectContaining({
id: expect.any(String),
assets: [expect.objectContaining({ id: asset1.id }), expect.objectContaining({ id: asset2.id })],
}),
);
});
it('should create a new memory and ignore assets the user does not have access to', async () => {
const { sut, ctx } = setup();
const { user: user1 } = await ctx.newUser();
const { user: user2 } = await ctx.newUser();
const { asset: asset1 } = await ctx.newAsset({ ownerId: user1.id });
const { asset: asset2 } = await ctx.newAsset({ ownerId: user2.id });
const auth = factory.auth({ user: user1 });
const dto = {
type: MemoryType.ON_THIS_DAY,
data: { year: 2021 },
memoryAt: new Date(2021),
assetIds: [asset1.id, asset2.id],
};
await expect(sut.create(auth, dto)).resolves.toEqual(
expect.objectContaining({
id: expect.any(String),
assets: [expect.objectContaining({ id: asset1.id })],
}),
);
});
});
describe('onMemoryCreate', () => {
it('should work on an empty database', async () => {
const { sut } = setup();