delete
This commit is contained in:
@@ -17,12 +17,14 @@ describe('ListsService', () => {
|
||||
const originalApiKey = process.env.MISTRAL_API_KEY;
|
||||
const originalAgentId = process.env.MISTRAL_AGENT_ID;
|
||||
let service: ListsService;
|
||||
let listsRepository: InMemoryRepository<UserListEntity>;
|
||||
let usersRepository: InMemoryRepository<UserEntity>;
|
||||
|
||||
beforeEach(() => {
|
||||
listsRepository = new InMemoryRepository<UserListEntity>();
|
||||
usersRepository = new InMemoryRepository<UserEntity>();
|
||||
service = new ListsService(
|
||||
new InMemoryRepository<UserListEntity>() as never,
|
||||
listsRepository as never,
|
||||
new InMemoryRepository<UserListItemEntity>() as never,
|
||||
new InMemoryRepository<UserListShareEntity>() as never,
|
||||
usersRepository as never,
|
||||
@@ -67,6 +69,16 @@ describe('ListsService', () => {
|
||||
expect(updatedList.description).toBe('Fokusliste');
|
||||
expect(deleteResponse.message).toBe('List deleted.');
|
||||
await expect(service.listLists('user-1')).resolves.toHaveLength(0);
|
||||
await expect(service.getList('user-1', list.id)).rejects.toThrow(
|
||||
NotFoundException,
|
||||
);
|
||||
await expect(
|
||||
service.updateList('user-1', list.id, { name: 'Wieder da' }),
|
||||
).rejects.toThrow(NotFoundException);
|
||||
expect(
|
||||
(await listsRepository.find()).find((storedList) => storedList.id === list.id)
|
||||
?.deletedAt,
|
||||
).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
it('publishes realtime snapshots and deletions for the owning user', async () => {
|
||||
@@ -155,6 +167,12 @@ describe('ListsService', () => {
|
||||
await expect(service.deleteList('user-2', list.id)).rejects.toThrow(
|
||||
ForbiddenException,
|
||||
);
|
||||
|
||||
await service.deleteList('user-1', list.id);
|
||||
await expect(service.listLists('user-2')).resolves.toHaveLength(0);
|
||||
await expect(service.getList('user-2', list.id)).rejects.toThrow(
|
||||
NotFoundException,
|
||||
);
|
||||
});
|
||||
|
||||
it('adds, updates, checks and deletes list items', async () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { Repository } from 'typeorm';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { AuditLogService } from '../audit/audit-log.service';
|
||||
import {
|
||||
ListTemplate,
|
||||
@@ -78,6 +78,7 @@ export class ListsService {
|
||||
name: this.requireName(createDto.name),
|
||||
description: this.normalizeOptionalText(createDto.description),
|
||||
kind: this.normalizeKind(createDto.kind),
|
||||
deletedAt: null,
|
||||
items: [],
|
||||
});
|
||||
|
||||
@@ -119,6 +120,7 @@ export class ListsService {
|
||||
? this.normalizeOptionalText(createDto.description)
|
||||
: template.description,
|
||||
kind: template.kind,
|
||||
deletedAt: null,
|
||||
items: template.items.map((item) =>
|
||||
this.listItemsRepository.create({
|
||||
id: randomUUID(),
|
||||
@@ -157,7 +159,7 @@ export class ListsService {
|
||||
|
||||
async listLists(ownerId: string): Promise<UserList[]> {
|
||||
const ownedLists = await this.listsRepository.find({
|
||||
where: { ownerId },
|
||||
where: { ownerId, deletedAt: IsNull() },
|
||||
relations: { items: true, owner: true, shares: { user: true } },
|
||||
order: { name: 'ASC', items: { position: 'ASC' } },
|
||||
});
|
||||
@@ -176,12 +178,12 @@ export class ListsService {
|
||||
const sharedList =
|
||||
share.list ??
|
||||
(await this.listsRepository.findOne({
|
||||
where: { id: share.listId },
|
||||
where: { id: share.listId, deletedAt: IsNull() },
|
||||
relations: { items: true, owner: true, shares: { user: true } },
|
||||
order: { items: { position: 'ASC' } },
|
||||
}));
|
||||
|
||||
if (sharedList) {
|
||||
if (sharedList && !sharedList.deletedAt) {
|
||||
await this.hydrateListAccessRelations(sharedList);
|
||||
listsById.set(sharedList.id, sharedList);
|
||||
}
|
||||
@@ -245,7 +247,8 @@ export class ListsService {
|
||||
kind: list.kind,
|
||||
itemCount: list.items.length,
|
||||
};
|
||||
await this.listsRepository.remove(list);
|
||||
list.deletedAt = new Date();
|
||||
await this.listsRepository.save(list);
|
||||
|
||||
await this.auditLogService?.record({
|
||||
actorUserId: ownerId,
|
||||
@@ -503,7 +506,7 @@ export class ListsService {
|
||||
listId: string,
|
||||
): Promise<UserListEntity> {
|
||||
const list = await this.listsRepository.findOne({
|
||||
where: { id: listId },
|
||||
where: { id: listId, deletedAt: IsNull() },
|
||||
relations: { items: true, owner: true, shares: { user: true } },
|
||||
order: { items: { position: 'ASC' } },
|
||||
});
|
||||
@@ -693,7 +696,7 @@ export class ListsService {
|
||||
}
|
||||
|
||||
const list = await this.listsRepository.findOne({
|
||||
where: { id: listId },
|
||||
where: { id: listId, deletedAt: IsNull() },
|
||||
relations: { items: true, owner: true, shares: { user: true } },
|
||||
order: { items: { position: 'ASC' } },
|
||||
});
|
||||
|
||||
@@ -50,6 +50,10 @@ export class UserListEntity {
|
||||
})
|
||||
updatedAt!: Date;
|
||||
|
||||
@Index('IDX_user_lists_deleted_at')
|
||||
@Column({ type: 'datetime', precision: 3, nullable: true })
|
||||
deletedAt?: Date | null;
|
||||
|
||||
@ManyToOne(() => UserEntity, (user) => user.lists, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user