diff --git a/api/src/controllers/listing.controller.ts b/api/src/controllers/listing.controller.ts index 4ba337f50e..6cd48b428c 100644 --- a/api/src/controllers/listing.controller.ts +++ b/api/src/controllers/listing.controller.ts @@ -76,15 +76,16 @@ export class ListingController { private readonly listingCsvExportService: ListingCsvExporterService, ) {} - @Get() + @Post('list') @ApiOperation({ summary: 'Get a paginated set of listings', operationId: 'list', }) + @PermissionAction(permissionActions.read) @UsePipes(new ValidationPipe(defaultValidationPipeOptions)) @UseInterceptors(ClassSerializerInterceptor) @ApiOkResponse({ type: PaginatedListingDto }) - public async getPaginatedSet(@Query() queryParams: ListingsQueryParams) { + public async getPaginatedSet(@Body() queryParams: ListingsQueryParams) { return await this.listingService.list(queryParams); } diff --git a/api/test/integration/listing.e2e-spec.ts b/api/test/integration/listing.e2e-spec.ts index 916b9c075e..4886e1dbdc 100644 --- a/api/test/integration/listing.e2e-spec.ts +++ b/api/test/integration/listing.e2e-spec.ts @@ -427,9 +427,10 @@ describe('Listing Controller Tests', () => { const query = stringify(queryParams as any); const res = await request(app.getHttpServer()) - .get(`/listings?${query}`) + .post(`/listings/list`) + .send(query) .set({ passkey: process.env.API_PASS_KEY || '' }) - .expect(200); + .expect(201); expect(res.body).toEqual({ items: [], @@ -478,9 +479,10 @@ describe('Listing Controller Tests', () => { let query = stringify(queryParams as any); let res = await request(app.getHttpServer()) - .get(`/listings?${query}`) + .post(`/listings/list`) + .send(query) .set({ passkey: process.env.API_PASS_KEY || '' }) - .expect(200); + .expect(201); expect(res.body.meta).toEqual({ currentPage: 1, @@ -509,9 +511,10 @@ describe('Listing Controller Tests', () => { query = stringify(queryParams as any); res = await request(app.getHttpServer()) - .get(`/listings?${query}`) + .post(`/listings/list`) + .send(query) .set({ passkey: process.env.API_PASS_KEY || '' }) - .expect(200); + .expect(201); expect(res.body.meta).toEqual({ currentPage: 2, diff --git a/api/test/integration/permission-tests/permission-as-admin.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-admin.e2e-spec.ts index df3f7192b7..56587d28c4 100644 --- a/api/test/integration/permission-tests/permission-as-admin.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-admin.e2e-spec.ts @@ -1069,10 +1069,10 @@ describe('Testing Permissioning of endpoints as Admin User', () => { describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-juris-admin-correct-juris.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-juris-admin-correct-juris.e2e-spec.ts index 8482793949..5b8bd74da8 100644 --- a/api/test/integration/permission-tests/permission-as-juris-admin-correct-juris.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-juris-admin-correct-juris.e2e-spec.ts @@ -1044,10 +1044,10 @@ describe('Testing Permissioning of endpoints as Jurisdictional Admin in the corr describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-juris-admin-wrong-juris.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-juris-admin-wrong-juris.e2e-spec.ts index 65cd500f47..f9ab8931f3 100644 --- a/api/test/integration/permission-tests/permission-as-juris-admin-wrong-juris.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-juris-admin-wrong-juris.e2e-spec.ts @@ -1014,10 +1014,10 @@ describe('Testing Permissioning of endpoints as Jurisdictional Admin in the wron describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-limited-juris-admin-correct-juris.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-limited-juris-admin-correct-juris.e2e-spec.ts index dfc1d2b896..1af4d55d2a 100644 --- a/api/test/integration/permission-tests/permission-as-limited-juris-admin-correct-juris.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-limited-juris-admin-correct-juris.e2e-spec.ts @@ -987,10 +987,10 @@ describe('Testing Permissioning of endpoints as Limited Jurisdictional Admin in describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-limited-juris-admin-wrong-juris.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-limited-juris-admin-wrong-juris.e2e-spec.ts index da0959732c..717f22b3cd 100644 --- a/api/test/integration/permission-tests/permission-as-limited-juris-admin-wrong-juris.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-limited-juris-admin-wrong-juris.e2e-spec.ts @@ -989,10 +989,10 @@ describe('Testing Permissioning of endpoints as Limited Jurisdictional Admin in describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-no-user.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-no-user.e2e-spec.ts index 2e06e2a15e..d32081450b 100644 --- a/api/test/integration/permission-tests/permission-as-no-user.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-no-user.e2e-spec.ts @@ -931,10 +931,10 @@ describe('Testing Permissioning of endpoints as logged out user', () => { describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-partner-correct-listing.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-partner-correct-listing.e2e-spec.ts index f44756f829..95df0887cb 100644 --- a/api/test/integration/permission-tests/permission-as-partner-correct-listing.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-partner-correct-listing.e2e-spec.ts @@ -67,6 +67,8 @@ import { createSimpleApplication, } from './helpers'; import { ApplicationFlaggedSetService } from '../../../src/services/application-flagged-set.service'; +import { ListingsQueryParams } from '../../../src/dtos/listings/listings-query-params.dto'; +import { Compare } from '../../../src/dtos/shared/base-filter.dto'; const testEmailService = { confirmation: jest.fn(), @@ -87,6 +89,7 @@ describe('Testing Permissioning of endpoints as partner with correct listing', ( let applicationFlaggedSetService: ApplicationFlaggedSetService; let cookies = ''; let jurisId = ''; + let jurisId2 = ''; let userListingId = ''; let closedUserListingId = ''; let closedUserListingId2 = ''; @@ -115,6 +118,11 @@ describe('Testing Permissioning of endpoints as partner with correct listing', ( prisma, 'correct partner permission juris', ); + + jurisId2 = await generateJurisdiction( + prisma, + 'correct partner permission juris 2', + ); await reservedCommunityTypeFactoryAll(jurisId, prisma); await unitAccessibilityPriorityTypeFactoryAll(prisma); @@ -135,6 +143,7 @@ describe('Testing Permissioning of endpoints as partner with correct listing', ( multiselectQuestions: [msq], digitalApp: true, }); + const listing = await prisma.listings.create({ data: listingData, }); @@ -149,7 +158,7 @@ describe('Testing Permissioning of endpoints as partner with correct listing', ( }); closedUserListingId = closedListing.id; - const listingData2 = await listingFactory(jurisId, prisma, { + const listingData2 = await listingFactory(jurisId2, prisma, { multiselectQuestions: [msq], }); const listing2 = await prisma.listings.create({ @@ -1042,10 +1051,38 @@ describe('Testing Permissioning of endpoints as partner with correct listing', ( describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .send({} as ListingsQueryParams) + .expect(201); + }); + + it('should succeed for list endpoint filtered by jurisdiction', async () => { + const totalListings = await request(app.getHttpServer()) + .post(`/listings/list`) + .set({ passkey: process.env.API_PASS_KEY || '' }) + .set('Cookie', cookies) + .send({}) + .expect(201); + const jurisdiction2Listings = await request(app.getHttpServer()) + .post(`/listings/list`) + .set({ passkey: process.env.API_PASS_KEY || '' }) + .set('Cookie', cookies) + .send({ + filter: [ + { + $comparison: Compare.IN, + jurisdiction: jurisId2, + }, + ], + } as ListingsQueryParams) + .expect(201); + + expect(totalListings.body.items.length).toBeGreaterThan( + jurisdiction2Listings.body.items.length, + ); + expect(jurisdiction2Listings.body.items.length).toBeGreaterThan(0); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-partner-wrong-listing.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-partner-wrong-listing.e2e-spec.ts index 434a2d278f..386c5f842e 100644 --- a/api/test/integration/permission-tests/permission-as-partner-wrong-listing.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-partner-wrong-listing.e2e-spec.ts @@ -1009,10 +1009,10 @@ describe('Testing Permissioning of endpoints as partner with wrong listing', () describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/integration/permission-tests/permission-as-public.e2e-spec.ts b/api/test/integration/permission-tests/permission-as-public.e2e-spec.ts index bcd3ec6f59..3981a6a50f 100644 --- a/api/test/integration/permission-tests/permission-as-public.e2e-spec.ts +++ b/api/test/integration/permission-tests/permission-as-public.e2e-spec.ts @@ -1002,10 +1002,10 @@ describe('Testing Permissioning of endpoints as public user', () => { describe('Testing listing endpoints', () => { it('should succeed for list endpoint', async () => { await request(app.getHttpServer()) - .get(`/listings?`) + .post(`/listings/list`) .set({ passkey: process.env.API_PASS_KEY || '' }) .set('Cookie', cookies) - .expect(200); + .expect(201); }); it('should succeed for retrieveListings endpoint', async () => { diff --git a/api/test/unit/services/listing.service.spec.ts b/api/test/unit/services/listing.service.spec.ts index ec640c4734..f40ef985f4 100644 --- a/api/test/unit/services/listing.service.spec.ts +++ b/api/test/unit/services/listing.service.spec.ts @@ -539,6 +539,10 @@ describe('Testing listing service', () => { [ListingFilterKeys.bedrooms]: 2, $comparison: Compare['>='], }, + { + [ListingFilterKeys.jurisdiction]: 'Jurisdiction', + $comparison: Compare.IN, + }, ], }; @@ -578,6 +582,15 @@ describe('Testing listing service', () => { }, ], }, + { + OR: [ + { + jurisdictionId: { + in: ['jurisdiction'], + }, + }, + ], + }, { name: { contains: 'simple search', @@ -638,6 +651,15 @@ describe('Testing listing service', () => { }, ], }, + { + OR: [ + { + jurisdictionId: { + in: ['jurisdiction'], + }, + }, + ], + }, { name: { contains: 'simple search', diff --git a/shared-helpers/src/types/backend-swagger.ts b/shared-helpers/src/types/backend-swagger.ts index 4e17323325..6913f2c40e 100644 --- a/shared-helpers/src/types/backend-swagger.ts +++ b/shared-helpers/src/types/backend-swagger.ts @@ -154,97 +154,14 @@ export class ListingsService { * Get a paginated set of listings */ list( - params: { - /** */ - page?: number - /** */ - limit?: number | "all" - /** */ - $comparison: string - /** */ - name?: string - /** */ - status?: ListingsStatusEnum - /** */ - neighborhood?: string - /** */ - bedrooms?: number - /** */ - bathrooms?: number - /** */ - zipcode?: string - /** */ - leasingAgents?: string - /** */ - jurisdiction?: string - /** */ - isExternal?: boolean - /** */ - availability?: FilterAvailabilityEnum - /** */ - city?: string - /** */ - monthlyRent?: number - /** */ - counties?: [] - /** */ - ids?: [] - /** */ - view?: ListingViews - /** */ - orderBy?: ListingOrderByKeys[] - /** */ - orderDir?: OrderByEnum[] - /** */ - search?: string - } = {} as any, - options: IRequestOptions = {} - ): Promise { - return new Promise((resolve, reject) => { - let url = basePath + "/listings" - - const configs: IRequestConfig = getConfigs("get", "application/json", url, options) - configs.params = { - page: params["page"], - limit: params["limit"], - $comparison: params["$comparison"], - name: params["name"], - status: params["status"], - neighborhood: params["neighborhood"], - bedrooms: params["bedrooms"], - bathrooms: params["bathrooms"], - zipcode: params["zipcode"], - leasingAgents: params["leasingAgents"], - jurisdiction: params["jurisdiction"], - isExternal: params["isExternal"], - availability: params["availability"], - city: params["city"], - monthlyRent: params["monthlyRent"], - counties: params["counties"], - ids: params["ids"], - view: params["view"], - orderBy: params["orderBy"], - orderDir: params["orderDir"], - search: params["search"], - } - - /** 适配ios13,get请求不允许带body */ - - axios(configs, resolve, reject) - }) - } - /** - * Create listing - */ - create( params: { /** requestBody */ - body?: ListingCreate + body?: ListingsQueryParams } = {} as any, options: IRequestOptions = {} - ): Promise { + ): Promise { return new Promise((resolve, reject) => { - let url = basePath + "/listings" + let url = basePath + "/listings/list" const configs: IRequestConfig = getConfigs("post", "application/json", url, options) @@ -255,28 +172,6 @@ export class ListingsService { axios(configs, resolve, reject) }) } - /** - * Delete listing by id - */ - delete( - params: { - /** requestBody */ - body?: IdDTO - } = {} as any, - options: IRequestOptions = {} - ): Promise { - return new Promise((resolve, reject) => { - let url = basePath + "/listings" - - const configs: IRequestConfig = getConfigs("delete", "application/json", url, options) - - let data = params.body - - configs.data = data - - axios(configs, resolve, reject) - }) - } /** * List all local and external listings */ @@ -368,6 +263,50 @@ export class ListingsService { axios(configs, resolve, reject) }) } + /** + * Create listing + */ + create( + params: { + /** requestBody */ + body?: ListingCreate + } = {} as any, + options: IRequestOptions = {} + ): Promise { + return new Promise((resolve, reject) => { + let url = basePath + "/listings" + + const configs: IRequestConfig = getConfigs("post", "application/json", url, options) + + let data = params.body + + configs.data = data + + axios(configs, resolve, reject) + }) + } + /** + * Delete listing by id + */ + delete( + params: { + /** requestBody */ + body?: IdDTO + } = {} as any, + options: IRequestOptions = {} + ): Promise { + return new Promise((resolve, reject) => { + let url = basePath + "/listings" + + const configs: IRequestConfig = getConfigs("delete", "application/json", url, options) + + let data = params.body + + configs.data = data + + axios(configs, resolve, reject) + }) + } /** * Duplicate listing */ diff --git a/sites/partners/src/lib/hooks.ts b/sites/partners/src/lib/hooks.ts index 794b27dc73..b42cdf0b74 100644 --- a/sites/partners/src/lib/hooks.ts +++ b/sites/partners/src/lib/hooks.ts @@ -49,7 +49,7 @@ type UseListingsDataProps = PaginationProps & { search?: string sort?: ColumnOrder[] roles?: UserRole - userJurisidctionIds?: string[] + userJurisdictionIds?: string[] } export function useSingleListingData(listingId: string) { @@ -72,7 +72,7 @@ export function useListingsData({ search = "", sort, roles, - userJurisidctionIds, + userJurisdictionIds, }: UseListingsDataProps) { const params = { page, @@ -101,7 +101,7 @@ export function useListingsData({ } else if (roles?.isJurisdictionalAdmin || roles?.isLimitedJurisdictionalAdmin) { params.filter.push({ $comparison: EnumListingFilterParamsComparison.IN, - jurisdiction: userJurisidctionIds[0], + jurisdiction: userJurisdictionIds[0], }) } @@ -113,7 +113,7 @@ export function useListingsData({ const { listingsService } = useContext(AuthContext) - const fetcher = () => listingsService.list(params) + const fetcher = () => listingsService.list({ body: { ...params } }) const paramsString = qs.stringify(params) diff --git a/sites/partners/src/pages/index.tsx b/sites/partners/src/pages/index.tsx index f6bc835a75..f34841af62 100644 --- a/sites/partners/src/pages/index.tsx +++ b/sites/partners/src/pages/index.tsx @@ -158,7 +158,7 @@ export default function ListingsList() { userId: profile?.id, sort: tableOptions.sort.sortOptions, roles: profile?.userRoles, - userJurisidctionIds: profile?.jurisdictions?.map((jurisdiction) => jurisdiction.id), + userJurisdictionIds: profile?.jurisdictions?.map((jurisdiction) => jurisdiction.id), }) return (