Skip to content

Commit

Permalink
BC-5521 - Implement of KNL Control Module (#4486)
Browse files Browse the repository at this point in the history
* first commit

* add some tests

* add test cases and services

* add usecases and test cases

* fix importing

* add type in uc

* fix import

* fix most of issue form review

* add some test,additional status, limit ...

* changing limit parameter and changing in useCases

* Update apps/server/src/modules/deletion/uc/deletion-request.uc.ts

Co-authored-by: Sergej Hoffmann <[email protected]>

* Update apps/server/src/modules/deletion/uc/deletion-request.uc.ts

Co-authored-by: Sergej Hoffmann <[email protected]>

* Update apps/server/src/modules/deletion/services/deletion-request.service.ts

Co-authored-by: Sergej Hoffmann <[email protected]>

* Update apps/server/src/modules/deletion/deletion.module.ts

Co-authored-by: Sergej Hoffmann <[email protected]>

* fixes after review

* small fixes

---------

Co-authored-by: Sergej Hoffmann <[email protected]>
  • Loading branch information
WojciechGrancow and SevenWaysDP authored Nov 7, 2023
1 parent cbf3940 commit 01065dc
Show file tree
Hide file tree
Showing 45 changed files with 2,808 additions and 0 deletions.
11 changes: 11 additions & 0 deletions apps/server/src/modules/deletion/deletion.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { LoggerModule } from '@src/core/logger';
import { DeletionRequestService } from './services/deletion-request.service';
import { DeletionRequestRepo } from './repo/deletion-request.repo';

@Module({
imports: [LoggerModule],
providers: [DeletionRequestService, DeletionRequestRepo],
exports: [DeletionRequestService],
})
export class DeletionModule {}
70 changes: 70 additions & 0 deletions apps/server/src/modules/deletion/domain/deletion-log.do.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { deletionLogFactory } from './testing/factory/deletion-log.factory';
import { DeletionLog } from './deletion-log.do';
import { DeletionOperationModel } from './types/deletion-operation-model.enum';
import { DeletionDomainModel } from './types/deletion-domain-model.enum';

describe(DeletionLog.name, () => {
describe('constructor', () => {
describe('When constructor is called', () => {
it('should create a deletionRequest by passing required properties', () => {
const domainObject: DeletionLog = deletionLogFactory.build();

expect(domainObject instanceof DeletionLog).toEqual(true);
});
});

describe('when passed a valid id', () => {
const setup = () => {
const domainObject: DeletionLog = deletionLogFactory.buildWithId();

return { domainObject };
};

it('should set the id', () => {
const { domainObject } = setup();

const deletionLogDomainObject: DeletionLog = new DeletionLog(domainObject);

expect(deletionLogDomainObject.id).toEqual(domainObject.id);
});
});
});

describe('getters', () => {
describe('When getters are used', () => {
const setup = () => {
const props = {
id: new ObjectId().toHexString(),
domain: DeletionDomainModel.USER,
operation: DeletionOperationModel.DELETE,
modifiedCount: 0,
deletedCount: 1,
deletionRequestId: new ObjectId().toHexString(),
createdAt: new Date(),
updatedAt: new Date(),
};

const deletionLogDo = new DeletionLog(props);

return { props, deletionLogDo };
};
it('getters should return proper values', () => {
const { props, deletionLogDo } = setup();

const gettersValues = {
id: deletionLogDo.id,
domain: deletionLogDo.domain,
operation: deletionLogDo.operation,
modifiedCount: deletionLogDo.modifiedCount,
deletedCount: deletionLogDo.deletedCount,
deletionRequestId: deletionLogDo.deletionRequestId,
createdAt: deletionLogDo.createdAt,
updatedAt: deletionLogDo.updatedAt,
};

expect(gettersValues).toEqual(props);
});
});
});
});
44 changes: 44 additions & 0 deletions apps/server/src/modules/deletion/domain/deletion-log.do.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { EntityId } from '@shared/domain/types';
import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object';
import { DeletionDomainModel } from './types/deletion-domain-model.enum';
import { DeletionOperationModel } from './types/deletion-operation-model.enum';

export interface DeletionLogProps extends AuthorizableObject {
createdAt?: Date;
updatedAt?: Date;
domain: DeletionDomainModel;
operation?: DeletionOperationModel;
modifiedCount?: number;
deletedCount?: number;
deletionRequestId?: EntityId;
}

export class DeletionLog extends DomainObject<DeletionLogProps> {
get createdAt(): Date | undefined {
return this.props.createdAt;
}

get updatedAt(): Date | undefined {
return this.props.updatedAt;
}

get domain(): DeletionDomainModel {
return this.props.domain;
}

get operation(): DeletionOperationModel | undefined {
return this.props.operation;
}

get modifiedCount(): number | undefined {
return this.props.modifiedCount;
}

get deletedCount(): number | undefined {
return this.props.deletedCount;
}

get deletionRequestId(): EntityId | undefined {
return this.props.deletionRequestId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { DeletionRequest } from './deletion-request.do';
import { DeletionDomainModel } from './types/deletion-domain-model.enum';
import { deletionRequestFactory } from './testing/factory/deletion-request.factory';
import { DeletionStatusModel } from './types/deletion-status-model.enum';

describe(DeletionRequest.name, () => {
describe('constructor', () => {
describe('When constructor is called', () => {
it('should create a deletionRequest by passing required properties', () => {
const domainObject: DeletionRequest = deletionRequestFactory.build();

expect(domainObject instanceof DeletionRequest).toEqual(true);
});
});

describe('when passed a valid id', () => {
const setup = () => {
const domainObject: DeletionRequest = deletionRequestFactory.buildWithId();

return { domainObject };
};

it('should set the id', () => {
const { domainObject } = setup();

const deletionRequestDomainObject: DeletionRequest = new DeletionRequest(domainObject);

expect(deletionRequestDomainObject.id).toEqual(domainObject.id);
});
});
});

describe('getters', () => {
describe('When getters are used', () => {
const setup = () => {
const props = {
id: new ObjectId().toHexString(),
targetRefDomain: DeletionDomainModel.USER,
deleteAfter: new Date(),
targetRefId: new ObjectId().toHexString(),
status: DeletionStatusModel.REGISTERED,
createdAt: new Date(),
updatedAt: new Date(),
};

const deletionRequestDo = new DeletionRequest(props);

return { props, deletionRequestDo };
};

it('getters should return proper values', () => {
const { props, deletionRequestDo } = setup();

const gettersValues = {
id: deletionRequestDo.id,
targetRefDomain: deletionRequestDo.targetRefDomain,
deleteAfter: deletionRequestDo.deleteAfter,
targetRefId: deletionRequestDo.targetRefId,
status: deletionRequestDo.status,
createdAt: deletionRequestDo.createdAt,
updatedAt: deletionRequestDo.updatedAt,
};

expect(gettersValues).toEqual(props);
});
});
});
});
39 changes: 39 additions & 0 deletions apps/server/src/modules/deletion/domain/deletion-request.do.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { EntityId } from '@shared/domain/types';
import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object';
import { DeletionDomainModel } from './types/deletion-domain-model.enum';
import { DeletionStatusModel } from './types/deletion-status-model.enum';

export interface DeletionRequestProps extends AuthorizableObject {
createdAt?: Date;
updatedAt?: Date;
targetRefDomain: DeletionDomainModel;
deleteAfter: Date;
targetRefId: EntityId;
status: DeletionStatusModel;
}

export class DeletionRequest extends DomainObject<DeletionRequestProps> {
get createdAt(): Date | undefined {
return this.props.createdAt;
}

get updatedAt(): Date | undefined {
return this.props.updatedAt;
}

get targetRefDomain(): DeletionDomainModel {
return this.props.targetRefDomain;
}

get deleteAfter(): Date {
return this.props.deleteAfter;
}

get targetRefId(): EntityId {
return this.props.targetRefId;
}

get status(): DeletionStatusModel {
return this.props.status;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { DoBaseFactory } from '@shared/testing';
import { ObjectId } from '@mikro-orm/mongodb';
import { DeletionLog, DeletionLogProps } from '../../deletion-log.do';
import { DeletionOperationModel } from '../../types/deletion-operation-model.enum';
import { DeletionDomainModel } from '../../types/deletion-domain-model.enum';

export const deletionLogFactory = DoBaseFactory.define<DeletionLog, DeletionLogProps>(DeletionLog, () => {
return {
id: new ObjectId().toHexString(),
domain: DeletionDomainModel.USER,
operation: DeletionOperationModel.DELETE,
modifiedCount: 0,
deletedCount: 1,
deletionRequestId: new ObjectId().toHexString(),
createdAt: new Date(),
updatedAt: new Date(),
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { DoBaseFactory } from '@shared/testing';
import { ObjectId } from '@mikro-orm/mongodb';
import { DeepPartial } from 'fishery';
import { DeletionRequest, DeletionRequestProps } from '../../deletion-request.do';
import { DeletionDomainModel } from '../../types/deletion-domain-model.enum';
import { DeletionStatusModel } from '../../types/deletion-status-model.enum';

class DeletionRequestFactory extends DoBaseFactory<DeletionRequest, DeletionRequestProps> {
withUserIds(id: string): this {
const params: DeepPartial<DeletionRequestProps> = {
targetRefId: id,
};

return this.params(params);
}
}

export const deletionRequestFactory = DeletionRequestFactory.define(DeletionRequest, () => {
return {
id: new ObjectId().toHexString(),
targetRefDomain: DeletionDomainModel.USER,
deleteAfter: new Date(),
targetRefId: new ObjectId().toHexString(),
status: DeletionStatusModel.REGISTERED,
createdAt: new Date(),
updatedAt: new Date(),
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const enum DeletionDomainModel {
ACCOUNT = 'account',
CLASS = 'class',
COURSEGROUP = 'courseGroup',
COURSE = 'course',
FILE = 'file',
LESSONS = 'lessons',
PSEUDONYMS = 'pseudonyms',
TEAMS = 'teams',
USER = 'user',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const enum DeletionOperationModel {
DELETE = 'delete',
UPDATE = 'update',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const enum DeletionStatusModel {
FAILED = 'failed',
REGISTERED = 'registered',
SUCCESS = 'success',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { setupEntities } from '@shared/testing';
import { ObjectId } from '@mikro-orm/mongodb';
import { DeletionLogEntity } from './deletion-log.entity';
import { DeletionOperationModel } from '../domain/types/deletion-operation-model.enum';
import { DeletionDomainModel } from '../domain/types/deletion-domain-model.enum';

describe(DeletionLogEntity.name, () => {
beforeAll(async () => {
await setupEntities();
});

describe('constructor', () => {
describe('When constructor is called', () => {
const setup = () => {
const props = {
id: new ObjectId().toHexString(),
domain: DeletionDomainModel.USER,
operation: DeletionOperationModel.DELETE,
modifiedCount: 0,
deletedCount: 1,
deletionRequestId: new ObjectId(),
createdAt: new Date(),
updatedAt: new Date(),
};

return { props };
};
it('should throw an error by empty constructor', () => {
// @ts-expect-error: Test case
const test = () => new DeletionLogEntity();
expect(test).toThrow();
});

it('should create a deletionLog by passing required properties', () => {
const { props } = setup();
const entity: DeletionLogEntity = new DeletionLogEntity(props);

expect(entity instanceof DeletionLogEntity).toEqual(true);
});

it(`should return a valid object with fields values set from the provided complete props object`, () => {
const { props } = setup();
const entity: DeletionLogEntity = new DeletionLogEntity(props);

const entityProps = {
id: entity.id,
domain: entity.domain,
operation: entity.operation,
modifiedCount: entity.modifiedCount,
deletedCount: entity.deletedCount,
deletionRequestId: entity.deletionRequestId,
createdAt: entity.createdAt,
updatedAt: entity.updatedAt,
};

expect(entityProps).toEqual(props);
});
});
});
});
Loading

0 comments on commit 01065dc

Please sign in to comment.