Skip to content

Commit

Permalink
fix: saving listing with uploaded lottery (#4277)
Browse files Browse the repository at this point in the history
* fix: saving listing with uploaded lottery

* fix: test update

* fix: update per pr notes
  • Loading branch information
YazeedLoonat authored Sep 6, 2024
1 parent 2fdd073 commit 6350344
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 7 deletions.
52 changes: 48 additions & 4 deletions api/src/services/listing.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {
BadRequestException,
ForbiddenException,
HttpException,
Inject,
Injectable,
Expand All @@ -14,7 +12,6 @@ import { SchedulerRegistry } from '@nestjs/schedule';
import {
LanguagesEnum,
ListingsStatusEnum,
LotteryStatusEnum,
Prisma,
ReviewOrderTypeEnum,
UserRoleEnum,
Expand All @@ -29,7 +26,6 @@ import { AmiChart } from '../dtos/ami-charts/ami-chart.dto';
import { Listing } from '../dtos/listings/listing.dto';
import { ListingCreate } from '../dtos/listings/listing-create.dto';
import { ListingFilterParams } from '../dtos/listings/listings-filter-params.dto';
import { ListingLotteryStatus } from '../dtos/listings/listing-lottery-status.dto';
import { ListingsQueryParams } from '../dtos/listings/listings-query-params.dto';
import { ListingUpdate } from '../dtos/listings/listing-update.dto';
import { IdDTO } from '../dtos/shared/id.dto';
Expand Down Expand Up @@ -1062,6 +1058,51 @@ export class ListingService implements OnModuleInit {
return undefined;
}

/**
* @param listingId the listing id we are operating on
* @description disconnects assets from listing events, then deletes those assets
*/
async updateListingEvents(listingId: string): Promise<void> {
const assetIds = await this.prisma.listingEvents.findMany({
select: {
id: true,
fileId: true,
},
where: {
listingId,
},
});
await Promise.all(
assetIds.map(async (assetData) => {
await this.prisma.listingEvents.update({
data: {
assets: {
disconnect: true,
},
},
where: {
id: assetData.id,
},
});
}),
);
const fileIds = assetIds.reduce((accum, curr) => {
if (curr.fileId) {
accum.push(curr.fileId);
}
return accum;
}, []);
if (fileIds.length) {
await this.prisma.assets.deleteMany({
where: {
id: {
in: fileIds,
},
},
});
}
}

/*
update a listing
*/
Expand Down Expand Up @@ -1134,6 +1175,8 @@ export class ListingService implements OnModuleInit {
dto,
'listingsBuildingAddress',
);
// Delete all assets tied to listing events before creating new ones
await this.updateListingEvents(dto.id);

// Wrap the deletion and update in one transaction so that units aren't lost if update fails
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down Expand Up @@ -1219,6 +1262,7 @@ export class ListingService implements OnModuleInit {
? {
create: {
...event.assets,
id: undefined,
},
}
: undefined,
Expand Down
3 changes: 0 additions & 3 deletions api/test/integration/listing.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ import { INestApplication } from '@nestjs/common';
import {
ApplicationAddressTypeEnum,
ApplicationMethodsTypeEnum,
ApplicationStatusEnum,
ApplicationSubmissionTypeEnum,
LanguagesEnum,
ListingEventsTypeEnum,
ListingsStatusEnum,
LotteryStatusEnum,
ReviewOrderTypeEnum,
UnitTypeEnum,
UserRoleEnum,
Expand Down
139 changes: 139 additions & 0 deletions api/test/unit/services/listing.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2256,6 +2256,15 @@ describe('Testing listing service', () => {
id: 'example id',
name: 'example name',
});
prisma.listingEvents.findMany = jest.fn().mockResolvedValue([]);
prisma.listingEvents.update = jest.fn().mockResolvedValue({
id: 'example id',
name: 'example name',
});
prisma.assets.delete = jest.fn().mockResolvedValue({
id: 'example id',
name: 'example name',
});
prisma.$transaction = jest
.fn()
.mockResolvedValue([{ id: 'example id', name: 'example name' }]);
Expand Down Expand Up @@ -2390,6 +2399,15 @@ describe('Testing listing service', () => {
id: 'example id',
name: 'example name',
});
prisma.listingEvents.findMany = jest.fn().mockResolvedValue([]);
prisma.listingEvents.update = jest.fn().mockResolvedValue({
id: 'example id',
name: 'example name',
});
prisma.assets.delete = jest.fn().mockResolvedValue({
id: 'example id',
name: 'example name',
});
const updateMock = jest
.fn()
.mockResolvedValue({ id: 'example id', name: 'example name' });
Expand Down Expand Up @@ -2978,4 +2996,125 @@ describe('Testing listing service', () => {
});
});
});

describe('Test updateListingEvents endpoint', () => {
it('should clear asset from listing events if they are present', async () => {
prisma.listingEvents.findMany = jest.fn().mockResolvedValue([
{
id: 'random asset id',
fileId: 'random file id',
},
]);
prisma.listingEvents.update = jest
.fn()
.mockResolvedValue({ success: true });
prisma.assets.deleteMany = jest.fn().mockResolvedValue({ success: true });

await service.updateListingEvents('random id');

expect(prisma.listingEvents.findMany).toHaveBeenCalledWith({
select: {
id: true,
fileId: true,
},
where: {
listingId: 'random id',
},
});
expect(prisma.listingEvents.update).toHaveBeenCalledWith({
data: {
assets: {
disconnect: true,
},
},
where: {
id: 'random asset id',
},
});
expect(prisma.assets.deleteMany).toHaveBeenCalledWith({
where: {
id: {
in: ['random file id'],
},
},
});
});

it('should clear multiple assets from listing events if they are present', async () => {
prisma.listingEvents.findMany = jest.fn().mockResolvedValue([
{
id: 'random asset id 1',
fileId: 'random file id 1',
},
{
id: 'random asset id 2',
},
]);
prisma.listingEvents.update = jest
.fn()
.mockResolvedValue({ success: true });
prisma.assets.deleteMany = jest.fn().mockResolvedValue({ success: true });

await service.updateListingEvents('random id');

expect(prisma.listingEvents.findMany).toHaveBeenCalledWith({
select: {
id: true,
fileId: true,
},
where: {
listingId: 'random id',
},
});
expect(prisma.listingEvents.update).toHaveBeenCalledWith({
data: {
assets: {
disconnect: true,
},
},
where: {
id: 'random asset id 1',
},
});
expect(prisma.listingEvents.update).toHaveBeenCalledWith({
data: {
assets: {
disconnect: true,
},
},
where: {
id: 'random asset id 2',
},
});
expect(prisma.assets.deleteMany).toHaveBeenCalledWith({
where: {
id: {
in: ['random file id 1'],
},
},
});
});

it('should do nothing if no listing events present', async () => {
prisma.listingEvents.findMany = jest.fn().mockResolvedValue([]);
prisma.listingEvents.update = jest
.fn()
.mockResolvedValue({ success: true });
prisma.assets.deleteMany = jest.fn().mockResolvedValue({ success: true });

await service.updateListingEvents('random id');

expect(prisma.listingEvents.findMany).toHaveBeenCalledWith({
select: {
id: true,
fileId: true,
},
where: {
listingId: 'random id',
},
});
expect(prisma.listingEvents.update).not.toHaveBeenCalled();
expect(prisma.assets.deleteMany).not.toHaveBeenCalled();
});
});
});

0 comments on commit 6350344

Please sign in to comment.