Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-5695-RocketChat-user-deletion #4523

Merged
merged 31 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ca59c48
first commit
WojciechGrancow Oct 19, 2023
5838b81
add some tests
WojciechGrancow Oct 20, 2023
7df7c23
add test cases and services
WojciechGrancow Oct 27, 2023
a853ea7
add usecases and test cases
WojciechGrancow Nov 1, 2023
72c84b4
Merge branch 'main' into BC-5521-implementation-KNL-Module
WojciechGrancow Nov 1, 2023
c56ae3d
fix importing
WojciechGrancow Nov 1, 2023
cad4491
add type in uc
WojciechGrancow Nov 2, 2023
b80ff0e
fix import
WojciechGrancow Nov 2, 2023
44f1b43
implement entity, domain, mapper and repo for rocketChat
WojciechGrancow Nov 3, 2023
c226c6d
fix most of issue form review
WojciechGrancow Nov 3, 2023
7f2dd4f
add some test,additional status, limit ...
WojciechGrancow Nov 5, 2023
3ae845d
Merge branch 'main' into BC-5521-implementation-KNL-Module
WojciechGrancow Nov 5, 2023
2f9ad4b
Merge branch 'main' into BC-xxxx-RocketChat-user-deletion
WojciechGrancow Nov 5, 2023
aba10b4
implement rocketChat User deletion
WojciechGrancow Nov 6, 2023
65c7b5a
add service to module
WojciechGrancow Nov 6, 2023
972dffc
small fixes during review
WojciechGrancow Nov 6, 2023
9965b2a
Merge branch 'BC-5521-implementation-KNL-module' into BC-5695-RocketC…
WojciechGrancow Nov 6, 2023
550f16f
implement deletion rocketChat user in KNL deletion module
WojciechGrancow Nov 6, 2023
ef3941a
small fixes
WojciechGrancow Nov 6, 2023
a1ca155
changing limit parameter and changing in useCases
WojciechGrancow Nov 6, 2023
16a65cd
fix deletion rocketChatUser in KNL Deletion module
WojciechGrancow Nov 6, 2023
56f972d
fix from review
WojciechGrancow Nov 8, 2023
799d78f
Merge branch 'main' into BC-5695-RocketChat-user-deletion
WojciechGrancow Nov 8, 2023
051162a
delete 3 lines of code
WojciechGrancow Nov 8, 2023
2fef055
Merge branch 'main' into BC-5695-RocketChat-user-deletion
WojciechGrancow Nov 8, 2023
7842199
Update apps/server/src/modules/deletion/uc/deletion-request.uc.ts
WojciechGrancow Nov 8, 2023
4de1e5e
Update apps/server/src/modules/deletion/uc/deletion-request.uc.spec.ts
WojciechGrancow Nov 8, 2023
5d91b72
small fixes
WojciechGrancow Nov 8, 2023
29a5d4e
Update apps/server/src/modules/deletion/uc/deletion-request.uc.spec.ts
WojciechGrancow Nov 8, 2023
4736ee6
Merge branch 'main' into BC-5695-RocketChat-user-deletion
WojciechGrancow Nov 8, 2023
decb0fa
import fix
WojciechGrancow Nov 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions apps/server/src/modules/deletion/deletion.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { Logger } from '@src/core/logger';
import { DeletionRequestService } from './services/deletion-request.service';
import { DeletionRequestRepo } from './repo/deletion-request.repo';

@Module({
providers: [Logger, 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,12 @@
export const enum DeletionDomainModel {
ACCOUNT = 'account',
CLASS = 'class',
COURSEGROUP = 'courseGroup',
COURSE = 'course',
FILE = 'file',
LESSONS = 'lessons',
PSEUDONYMS = 'pseudonyms',
ROCKETCHATUSER = 'rocketChatUser',
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
Loading