Skip to content

Commit

Permalink
Merge pull request #216 from decentraland/feat/add-price-filters-rentals
Browse files Browse the repository at this point in the history
Feat/add price filters rentals
  • Loading branch information
juanmahidalgo committed Jan 16, 2023
2 parents 847503d + 2b85da9 commit 283bd4b
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 14 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"semi": false
},
"dependencies": {
"@dcl/schemas": "^6.3.0",
"@dcl/schemas": "^6.4.2",
"@well-known-components/env-config-provider": "^1.1.1",
"@well-known-components/http-server": "^1.1.6",
"@well-known-components/interfaces": "^1.1.3",
Expand Down
2 changes: 2 additions & 0 deletions src/controllers/handlers/rentals-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export async function getRentalsListingsHandler(
(getTypedStringQueryParameter(Object.values(Network), url.searchParams, "network") as Network) ?? undefined,
updatedAfter: url.searchParams.get("updatedAfter") ? Number(url.searchParams.get("updatedAfter")) : undefined,
target: url.searchParams.get("target") ?? ethers.constants.AddressZero,
minPricePerDay: url.searchParams.get("minPricePerDay") ?? undefined,
maxPricePerDay: url.searchParams.get("maxPricePerDay") ?? undefined,
}
const rentalListings = await rentals.getRentalsListings(
{
Expand Down
24 changes: 18 additions & 6 deletions src/ports/rentals/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,21 @@ export async function createRentalsComponent(
filterBy?.nftIds && filterBy.nftIds.length > 0 ? SQL`AND rentals.metadata_id = ANY(${filterBy.nftIds})\n` : ""
const filterByNetwork = filterBy?.network ? SQL`AND rentals.network = ${filterBy.network}\n` : ""

const filterByPrice = SQL``
if (filterBy?.minPricePerDay || filterBy?.maxPricePerDay) {
filterByPrice.append(`HAVING `)
if (filterBy?.minPricePerDay) {
filterByPrice.append(SQL`max(periods.price_per_day) >= ${filterBy.minPricePerDay}`)
if (filterBy?.maxPricePerDay) {
filterByPrice.append(` AND `)
}
}
if (filterBy?.maxPricePerDay) {
filterByPrice.append(SQL`min(periods.price_per_day) <= ${filterBy.maxPricePerDay}`)
}
filterByPrice.append(`\n`)
}

let sortByQuery: SQLStatement | string = `ORDER BY rentals.created_at ${sortDirectionParam}\n`
switch (sortByParam) {
case RentalsListingsSortBy.LAND_CREATION_DATE:
Expand Down Expand Up @@ -450,12 +465,9 @@ export async function createRentalsComponent(
query.append(filterByLessor)
query.append(filterByTenant)
query.append(filterByNftIds)
query.append(
SQL`
GROUP BY rentals.id, rentals_listings.id, periods.rental_id
ORDER BY rentals.metadata_id, rentals.created_at desc) as rentals\n
`
)
query.append(SQL`GROUP BY rentals.id, rentals_listings.id, periods.rental_id\n`)
query.append(filterByPrice)
query.append(SQL`ORDER BY rentals.metadata_id, rentals.created_at desc) as rentals\n`)
query.append("WHERE metadata.id = rentals.metadata_id\n")
query.append(filterByCategory)
query.append(filterBySearchText)
Expand Down
54 changes: 54 additions & 0 deletions test/unit/rentals-component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,60 @@ describe("when getting rental listings", () => {
})
})

describe("and the minPricePerDay filter is set", () => {
let minPricePerDay: string
beforeEach(() => {
minPricePerDay = "10000000"
dbGetRentalListings = []
dbQueryMock.mockResolvedValueOnce({ rows: dbGetRentalListings })
})

it("should have made the query to get the listings with the min price condition", async () => {
await expect(
rentalsComponent.getRentalsListings({
offset: 0,
limit: 10,
sortBy: null,
sortDirection: null,
filterBy: {
minPricePerDay,
},
})
).resolves.toEqual(dbGetRentalListings)
expect(dbQueryMock.mock.calls[0][0].text).toEqual(
expect.stringContaining(`HAVING max(periods.price_per_day) >= $1`)
)
expect(dbQueryMock.mock.calls[0][0].values).toEqual([minPricePerDay, 10, 0])
})
})

describe("and the maxPricePerDay filter is set", () => {
let maxPricePerDay: string
beforeEach(() => {
maxPricePerDay = "10000000"
dbGetRentalListings = []
dbQueryMock.mockResolvedValueOnce({ rows: dbGetRentalListings })
})

it("should have made the query to get the listings with the max price condition", async () => {
await expect(
rentalsComponent.getRentalsListings({
offset: 0,
limit: 10,
sortBy: null,
sortDirection: null,
filterBy: {
maxPricePerDay,
},
})
).resolves.toEqual(dbGetRentalListings)
expect(dbQueryMock.mock.calls[0][0].text).toEqual(
expect.stringContaining(`HAVING min(periods.price_per_day) <= $1`)
)
expect(dbQueryMock.mock.calls[0][0].values).toEqual([maxPricePerDay, 10, 0])
})
})

describe("and the category filter is set", () => {
beforeEach(() => {
dbGetRentalListings = []
Expand Down
58 changes: 58 additions & 0 deletions test/unit/rentals-handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,64 @@ describe("when getting rental listings", () => {
})
})

describe("and the process is done with the minPricePerDay parameter set", () => {
const minPricePerDay = "1"
beforeEach(() => {
url = new URL(`http://localhost/v1/rental-listing?minPricePerDay=${minPricePerDay}`)
})

it("should have retrieved the rental listings with the given target", async () => {
await getRentalsListingsHandler({ components, url })
expect(getRentalsListingsMock).toHaveBeenCalledWith(
expect.objectContaining({ filterBy: expect.objectContaining({ minPricePerDay }) }),
false
)
})
})

describe("and the process is done with the minPricePerDay parameter unset", () => {
beforeEach(() => {
url = new URL(`http://localhost/v1/rental-listing`)
})

it("should have retrieved the rental listings with the given target", async () => {
await getRentalsListingsHandler({ components, url })
expect(getRentalsListingsMock).toHaveBeenCalledWith(
expect.objectContaining({ filterBy: expect.not.objectContaining({ minPricePerDay: expect.anything() }) }),
false
)
})
})

describe("and the process is done with the maxPricePerDay parameter set", () => {
const maxPricePerDay = "100"
beforeEach(() => {
url = new URL(`http://localhost/v1/rental-listing?maxPricePerDay=${maxPricePerDay}`)
})

it("should have retrieved the rental listings with the given target", async () => {
await getRentalsListingsHandler({ components, url })
expect(getRentalsListingsMock).toHaveBeenCalledWith(
expect.objectContaining({ filterBy: expect.objectContaining({ maxPricePerDay }) }),
false
)
})
})

describe("and the process is done with the maxPricePerDay parameter unset", () => {
beforeEach(() => {
url = new URL(`http://localhost/v1/rental-listing`)
})

it("should have retrieved the rental listings with the given target", async () => {
await getRentalsListingsHandler({ components, url })
expect(getRentalsListingsMock).toHaveBeenCalledWith(
expect.objectContaining({ filterBy: expect.not.objectContaining({ maxPricePerDay: expect.anything() }) }),
false
)
})
})

describe("and the process is done with the target parameter set", () => {
const target = "0x1"
beforeEach(() => {
Expand Down

0 comments on commit 283bd4b

Please sign in to comment.