From feac2d3621228bc054a5e03743b7e82bcd31bd6b Mon Sep 17 00:00:00 2001 From: Sairam Charan Date: Mon, 8 Apr 2024 23:28:10 +0530 Subject: [PATCH 1/7] feat(WEB-2070): WEB-2070 Wait for db write on whisp create --- src/whisp/whisp.resolver.ts | 5 +- src/whisp/whisp.service.ts | 4 +- tests/unit/whisp/whisp.service.spec.ts | 162 +++++++++++++++++-------- 3 files changed, 117 insertions(+), 54 deletions(-) diff --git a/src/whisp/whisp.resolver.ts b/src/whisp/whisp.resolver.ts index e96dfdd59..86e9fbb95 100644 --- a/src/whisp/whisp.resolver.ts +++ b/src/whisp/whisp.resolver.ts @@ -33,9 +33,7 @@ export class WhispResolver { @Inject('PUB_SUB') private pubSub: PubSubEngine, ) { this.distributionService.whispSubject.subscribe((whisp) => { - setTimeout(() => { - pubSub.publish('whispAdded', { whispAdded: whisp }); - }, 1000); + pubSub.publish('whispAdded', { whispAdded: whisp }); }); } @@ -128,7 +126,6 @@ export class WhispResolver { @ResolveField(() => [Tag]) async tags(@Root() whisp: Whisp): Promise { // eslint-disable-next-line no-underscore-dangle - this.logger.log(`Test logging whisp ${JSON.stringify(whisp)}`); return this.whispService.findTagsByWhispId(whisp._id); } } diff --git a/src/whisp/whisp.service.ts b/src/whisp/whisp.service.ts index c554a75b9..5c3a0da50 100644 --- a/src/whisp/whisp.service.ts +++ b/src/whisp/whisp.service.ts @@ -43,7 +43,8 @@ export class WhispService { const { timeToLiveSec, expirationDate } = WhispService.fillTTL(whispIn, now); whisp.timeToLiveSec = timeToLiveSec; whisp.expirationDate = expirationDate; - const createdWhisp = await this.whispModel.create(whisp); + const whispInstance = new this.whispModel(whisp); + const createdWhisp = await whispInstance.save(); await this.eventService.triggerEvent(new Event(EventNames.WHISP_CREATED, createdWhisp)); this.distributionService.distributeWhisp(createdWhisp); @@ -127,7 +128,6 @@ export class WhispService { } async findTagsByWhispId(whispId: string): Promise { - this.logger.log(`Test logging whispId ${whispId}`); const whisps = await this.whispModel.findById(whispId).populate('tags').exec(); return whisps.tags; } diff --git a/tests/unit/whisp/whisp.service.spec.ts b/tests/unit/whisp/whisp.service.spec.ts index 83bb12d3c..91a754f38 100644 --- a/tests/unit/whisp/whisp.service.spec.ts +++ b/tests/unit/whisp/whisp.service.spec.ts @@ -8,6 +8,7 @@ import { FileService } from '../../../src/file/file.service'; import { SequenceService } from '../../../src/sequence/sequence.service'; import { WhispService } from '../../../src/whisp/whisp.service'; import { DistributionService } from '../../../src/distribution/distribution.service'; +import { Whisp } from '../../../src/whisp/whisp.entity'; jest.mock('../../../src/distribution/distribution.service'); jest.mock('../../../src/event/event.service'); @@ -16,66 +17,64 @@ jest.mock('../../../src/sequence/sequence.service'); describe('WhispService', () => { let whispService: WhispService; - let whispModel: Model; + let whispModel; const OBJECT_ID = '56cb91bdc3464f14678934ca'; - beforeEach(async () => { - // function to retrieve input of the called function - const passThrough = (data) => - new Promise((resolve) => { - resolve(data); - }); - - const moduleRef = await Test.createTestingModule({ - providers: [ - { - provide: getModelToken('Whisp'), - useFactory: () => ({ - findOneAndUpdate: jest.fn().mockReturnThis(), - create: jest.fn().mockImplementation(passThrough), - update: jest.fn(), - aggregate: jest.fn().mockReturnThis(), - allowDiskUse: jest.fn().mockReturnThis(), - exec: jest.fn(), - }), - }, - WhispService, - Logger, - { - provide: DistributionService, - useFactory: () => ({ - distributeWhisp: jest.fn(() => true), - }), - }, - FileService, - SequenceService, - EventService, - ], - }).compile(); - whispService = moduleRef.get(WhispService); - whispModel = moduleRef.get>(getModelToken('Whisp')); - }); - + // function to retrieve input of the called function + const passThrough = (data) => + new Promise((resolve) => { + resolve(data); + }); + describe('create Whisp', () => { + let constructorData = {}; + beforeEach(async () => { + constructorData = {} + class mockModel { + constructor(public data?: any) { + constructorData = data; + this.data = data + + } + save = jest.fn().mockReturnValue(this.data); + } + + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: getModelToken('Whisp'), + useValue: mockModel, + }, + WhispService, + Logger, + { + provide: DistributionService, + useFactory: () => ({ + distributeWhisp: jest.fn(() => true), + }), + }, + FileService, + SequenceService, + EventService, + ], + }).compile(); + whispService = moduleRef.get(WhispService); + whispModel = moduleRef.get(getModelToken('Whisp')); + }); + it('should set Timestamp when no timestamp is provided', async () => { await whispService.create({}); - expect(whispModel.create).toBeCalledWith( - expect.objectContaining({ - timestamp: expect.any(Date), - }), - ); + expect(constructorData).toHaveProperty('timestamp'); + expect(constructorData['timestamp']).toBeDefined(); }); it('should keep custom timestamp when timestamp is provided', async () => { const timestamp = new Date(); await whispService.create({ timestamp }); - expect(whispModel.create).toBeCalledWith( - expect.objectContaining({ - timestamp, - }), - ); + expect(constructorData).toHaveProperty('timestamp'); + expect(constructorData['timestamp']).toBe(timestamp); }); it('when ttl is provided expirationDate should be generate and be equal to updated date plus ttl duration', async () => { @@ -106,6 +105,7 @@ describe('WhispService', () => { 'time to live must be positive number of seconds or a parsable time string like 2min,1hour', ); }); + it('expirationDate override ttl', async () => { const now = new Date(); now.setSeconds(now.getSeconds() + 2); @@ -118,6 +118,39 @@ describe('WhispService', () => { }); describe('Update Whisp', () => { + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: getModelToken('Whisp'), + useFactory: () => ({ + findOneAndUpdate: jest.fn().mockReturnThis(), + create: jest.fn().mockImplementation(passThrough), + save: jest.fn().mockImplementation(passThrough), + update: jest.fn(), + aggregate: jest.fn().mockReturnThis(), + allowDiskUse: jest.fn().mockReturnThis(), + exec: jest.fn(), + constructor: jest.fn(), + }), + }, + WhispService, + Logger, + { + provide: DistributionService, + useFactory: () => ({ + distributeWhisp: jest.fn(() => true), + }), + }, + FileService, + SequenceService, + EventService, + ], + }).compile(); + whispService = moduleRef.get(WhispService); + whispModel = moduleRef.get>(getModelToken('Whisp')); + }); + it('should update timestamp when it is provided', async () => { const timestamp = new Date(); timestamp.setHours(timestamp.getHours() + 1); @@ -145,6 +178,39 @@ describe('WhispService', () => { }); describe('Count Whisp', () => { + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: getModelToken('Whisp'), + useFactory: () => ({ + findOneAndUpdate: jest.fn().mockReturnThis(), + create: jest.fn().mockImplementation(passThrough), + save: jest.fn().mockImplementation(passThrough), + update: jest.fn(), + aggregate: jest.fn().mockReturnThis(), + allowDiskUse: jest.fn().mockReturnThis(), + exec: jest.fn(), + constructor: jest.fn(), + }), + }, + WhispService, + Logger, + { + provide: DistributionService, + useFactory: () => ({ + distributeWhisp: jest.fn(() => true), + }), + }, + FileService, + SequenceService, + EventService, + ], + }).compile(); + whispService = moduleRef.get(WhispService); + whispModel = moduleRef.get>(getModelToken('Whisp')); + }); + it('calls mongo aggregate with empty match and group when they are not passed as parameters', async () => { await whispService.countWhispsGroup(); const expectedMatch = { $match: {} }; From 31afac4c9cbd717da1684e0179ba03c1c5ea4083 Mon Sep 17 00:00:00 2001 From: Sairam Charan Date: Mon, 8 Apr 2024 23:33:19 +0530 Subject: [PATCH 2/7] feat(WEB-2070): WEB-2070 lint fixes --- src/whisp/whisp.service.ts | 3 ++- tests/unit/whisp/whisp.service.spec.ts | 15 ++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/whisp/whisp.service.ts b/src/whisp/whisp.service.ts index 5c3a0da50..f81c9c11c 100644 --- a/src/whisp/whisp.service.ts +++ b/src/whisp/whisp.service.ts @@ -43,7 +43,8 @@ export class WhispService { const { timeToLiveSec, expirationDate } = WhispService.fillTTL(whispIn, now); whisp.timeToLiveSec = timeToLiveSec; whisp.expirationDate = expirationDate; - const whispInstance = new this.whispModel(whisp); + const WhispDocModel = this.whispModel; + const whispInstance = new WhispDocModel(whisp); const createdWhisp = await whispInstance.save(); await this.eventService.triggerEvent(new Event(EventNames.WHISP_CREATED, createdWhisp)); this.distributionService.distributeWhisp(createdWhisp); diff --git a/tests/unit/whisp/whisp.service.spec.ts b/tests/unit/whisp/whisp.service.spec.ts index 91a754f38..b67b6d1be 100644 --- a/tests/unit/whisp/whisp.service.spec.ts +++ b/tests/unit/whisp/whisp.service.spec.ts @@ -8,7 +8,6 @@ import { FileService } from '../../../src/file/file.service'; import { SequenceService } from '../../../src/sequence/sequence.service'; import { WhispService } from '../../../src/whisp/whisp.service'; import { DistributionService } from '../../../src/distribution/distribution.service'; -import { Whisp } from '../../../src/whisp/whisp.entity'; jest.mock('../../../src/distribution/distribution.service'); jest.mock('../../../src/event/event.service'); @@ -25,20 +24,18 @@ describe('WhispService', () => { new Promise((resolve) => { resolve(data); }); - describe('create Whisp', () => { - let constructorData = {}; + let constructorData:any; beforeEach(async () => { - constructorData = {} + constructorData = {}; class mockModel { constructor(public data?: any) { constructorData = data; - this.data = data - + this.data = data; } + save = jest.fn().mockReturnValue(this.data); } - const moduleRef = await Test.createTestingModule({ providers: [ { @@ -66,7 +63,7 @@ describe('WhispService', () => { await whispService.create({}); expect(constructorData).toHaveProperty('timestamp'); - expect(constructorData['timestamp']).toBeDefined(); + expect(constructorData.timestamp).toBeDefined(); }); it('should keep custom timestamp when timestamp is provided', async () => { @@ -74,7 +71,7 @@ describe('WhispService', () => { await whispService.create({ timestamp }); expect(constructorData).toHaveProperty('timestamp'); - expect(constructorData['timestamp']).toBe(timestamp); + expect(constructorData.timestamp).toBe(timestamp); }); it('when ttl is provided expirationDate should be generate and be equal to updated date plus ttl duration', async () => { From e411b726582f256d3c751ca9674f4597c69c79fa Mon Sep 17 00:00:00 2001 From: Sairam Charan Date: Mon, 8 Apr 2024 23:41:43 +0530 Subject: [PATCH 3/7] feat(WEB-2070): reduced duplication --- tests/unit/whisp/whisp.service.spec.ts | 92 ++++++++++---------------- 1 file changed, 35 insertions(+), 57 deletions(-) diff --git a/tests/unit/whisp/whisp.service.spec.ts b/tests/unit/whisp/whisp.service.spec.ts index b67b6d1be..f52b39fc6 100644 --- a/tests/unit/whisp/whisp.service.spec.ts +++ b/tests/unit/whisp/whisp.service.spec.ts @@ -14,16 +14,44 @@ jest.mock('../../../src/event/event.service'); jest.mock('../../../src/file/file.service'); jest.mock('../../../src/sequence/sequence.service'); +// function to retrieve input of the called function +const passThrough = (data) => +new Promise((resolve) => { + resolve(data); +}); + +const commonProviders = [ + { + provide: getModelToken('Whisp'), + useFactory: () => ({ + findOneAndUpdate: jest.fn().mockReturnThis(), + create: jest.fn().mockImplementation(passThrough), + save: jest.fn().mockImplementation(passThrough), + update: jest.fn(), + aggregate: jest.fn().mockReturnThis(), + allowDiskUse: jest.fn().mockReturnThis(), + exec: jest.fn(), + constructor: jest.fn(), + }), + }, + WhispService, + Logger, + { + provide: DistributionService, + useFactory: () => ({ + distributeWhisp: jest.fn(() => true), + }), + }, + FileService, + SequenceService, + EventService, +]; describe('WhispService', () => { let whispService: WhispService; let whispModel; const OBJECT_ID = '56cb91bdc3464f14678934ca'; - // function to retrieve input of the called function - const passThrough = (data) => - new Promise((resolve) => { - resolve(data); - }); + describe('create Whisp', () => { let constructorData:any; beforeEach(async () => { @@ -117,32 +145,7 @@ describe('WhispService', () => { describe('Update Whisp', () => { beforeEach(async () => { const moduleRef = await Test.createTestingModule({ - providers: [ - { - provide: getModelToken('Whisp'), - useFactory: () => ({ - findOneAndUpdate: jest.fn().mockReturnThis(), - create: jest.fn().mockImplementation(passThrough), - save: jest.fn().mockImplementation(passThrough), - update: jest.fn(), - aggregate: jest.fn().mockReturnThis(), - allowDiskUse: jest.fn().mockReturnThis(), - exec: jest.fn(), - constructor: jest.fn(), - }), - }, - WhispService, - Logger, - { - provide: DistributionService, - useFactory: () => ({ - distributeWhisp: jest.fn(() => true), - }), - }, - FileService, - SequenceService, - EventService, - ], + providers: commonProviders }).compile(); whispService = moduleRef.get(WhispService); whispModel = moduleRef.get>(getModelToken('Whisp')); @@ -177,32 +180,7 @@ describe('WhispService', () => { describe('Count Whisp', () => { beforeEach(async () => { const moduleRef = await Test.createTestingModule({ - providers: [ - { - provide: getModelToken('Whisp'), - useFactory: () => ({ - findOneAndUpdate: jest.fn().mockReturnThis(), - create: jest.fn().mockImplementation(passThrough), - save: jest.fn().mockImplementation(passThrough), - update: jest.fn(), - aggregate: jest.fn().mockReturnThis(), - allowDiskUse: jest.fn().mockReturnThis(), - exec: jest.fn(), - constructor: jest.fn(), - }), - }, - WhispService, - Logger, - { - provide: DistributionService, - useFactory: () => ({ - distributeWhisp: jest.fn(() => true), - }), - }, - FileService, - SequenceService, - EventService, - ], + providers: commonProviders, }).compile(); whispService = moduleRef.get(WhispService); whispModel = moduleRef.get>(getModelToken('Whisp')); From 5cba2ac49b8278860df2b883e71f0a956c99ea5c Mon Sep 17 00:00:00 2001 From: Sairam Charan Date: Mon, 8 Apr 2024 23:43:01 +0530 Subject: [PATCH 4/7] feat(WEB-2070): WEB-2070 lint fixes --- tests/unit/whisp/whisp.service.spec.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/unit/whisp/whisp.service.spec.ts b/tests/unit/whisp/whisp.service.spec.ts index f52b39fc6..188b9fd75 100644 --- a/tests/unit/whisp/whisp.service.spec.ts +++ b/tests/unit/whisp/whisp.service.spec.ts @@ -16,10 +16,9 @@ jest.mock('../../../src/sequence/sequence.service'); // function to retrieve input of the called function const passThrough = (data) => -new Promise((resolve) => { - resolve(data); -}); - + new Promise((resolve) => { + resolve(data); + }); const commonProviders = [ { provide: getModelToken('Whisp'), @@ -50,8 +49,6 @@ describe('WhispService', () => { let whispService: WhispService; let whispModel; const OBJECT_ID = '56cb91bdc3464f14678934ca'; - - describe('create Whisp', () => { let constructorData:any; beforeEach(async () => { @@ -145,7 +142,7 @@ describe('WhispService', () => { describe('Update Whisp', () => { beforeEach(async () => { const moduleRef = await Test.createTestingModule({ - providers: commonProviders + providers: commonProviders, }).compile(); whispService = moduleRef.get(WhispService); whispModel = moduleRef.get>(getModelToken('Whisp')); From 882923acd26e0f170a5b6139170d0f1061292032 Mon Sep 17 00:00:00 2001 From: Sairam Charan Date: Wed, 10 Apr 2024 11:27:27 +0530 Subject: [PATCH 5/7] feat(WEB-2070): WEB-2070 testing removing format --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f946b0178..8cddf543e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,9 +53,6 @@ jobs: - name: Lint run: npm run lint - - name: Format - run: npm run format:check - # We need execute the script manually because the code is mounted after the container is created - name: Create s3 bucket on localstack run: docker exec ${{job.services.localstack.id}} bash -c "`cat aws/bucket.sh`" From f78588340548c0ac046ac96869b3b9422f8e5c51 Mon Sep 17 00:00:00 2001 From: Sairam Charan Date: Wed, 10 Apr 2024 11:42:30 +0530 Subject: [PATCH 6/7] feat(WEB-2070): WEB-2070 undo testing removing format --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8cddf543e..f946b0178 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,9 @@ jobs: - name: Lint run: npm run lint + - name: Format + run: npm run format:check + # We need execute the script manually because the code is mounted after the container is created - name: Create s3 bucket on localstack run: docker exec ${{job.services.localstack.id}} bash -c "`cat aws/bucket.sh`" From 24df059e2ad892c29f0669ac1e9b64d5665f21a9 Mon Sep 17 00:00:00 2001 From: Sairam Charan Date: Wed, 10 Apr 2024 12:55:13 +0530 Subject: [PATCH 7/7] feat(WEB-2070): WEB-2070 lint fix --- tests/unit/whisp/whisp.service.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/whisp/whisp.service.spec.ts b/tests/unit/whisp/whisp.service.spec.ts index 188b9fd75..96af4927e 100644 --- a/tests/unit/whisp/whisp.service.spec.ts +++ b/tests/unit/whisp/whisp.service.spec.ts @@ -50,7 +50,7 @@ describe('WhispService', () => { let whispModel; const OBJECT_ID = '56cb91bdc3464f14678934ca'; describe('create Whisp', () => { - let constructorData:any; + let constructorData: any; beforeEach(async () => { constructorData = {}; class mockModel {