Skip to content

Commit

Permalink
Merge pull request #769 from housingbayarea/release/4277-lottery-resu…
Browse files Browse the repository at this point in the history
…lt-upload-update

fix: saving listing with uploaded lottery (bloom-housing#4277)
  • Loading branch information
YazeedLoonat authored Oct 2, 2024
2 parents 10c7233 + 1bd3032 commit d02c46c
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 5 deletions.
50 changes: 48 additions & 2 deletions api/src/services/listing.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
LanguagesEnum,
ListingEventsTypeEnum,
ListingsStatusEnum,
LotteryStatusEnum,
Prisma,
ReviewOrderTypeEnum,
UserRoleEnum,
Expand All @@ -31,7 +30,6 @@ import { Listing } from '../dtos/listings/listing.dto';
import { ListingCreate } from '../dtos/listings/listing-create.dto';
import { ListingDuplicate } from '../dtos/listings/listing-duplicate.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 @@ -1162,6 +1160,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 @@ -1234,6 +1277,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 @@ -1319,6 +1364,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 @@ -2524,6 +2524,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 @@ -2658,6 +2667,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 @@ -3246,4 +3264,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 d02c46c

Please sign in to comment.