fix: Allow filtering products by variant options in store (#7784)
This commit is contained in:
@@ -51,499 +51,6 @@ describe("/store/products", () => {
|
||||
medusaProcess.kill()
|
||||
})
|
||||
|
||||
describe("GET /store/products", () => {
|
||||
beforeEach(async () => {
|
||||
const defaultSalesChannel = await simpleSalesChannelFactory(
|
||||
dbConnection,
|
||||
{
|
||||
id: "sales-channel",
|
||||
is_default: true,
|
||||
}
|
||||
)
|
||||
await productSeeder(dbConnection, defaultSalesChannel)
|
||||
await adminSeeder(dbConnection)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
await db.teardown()
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by id ASC", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get("/store/products?order=id")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(5)
|
||||
expect(response.data.products[0].id).toEqual(giftCardId)
|
||||
expect(response.data.products[1].id).toEqual(testProductId)
|
||||
expect(response.data.products[2].id).toEqual(testProductId1)
|
||||
expect(response.data.products[3].id).toEqual(testProductFilteringId1)
|
||||
expect(response.data.products[4].id).toEqual(testProductFilteringId2)
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by id DESC", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get("/store/products?order=-id")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(5)
|
||||
expect(response.data.products[0].id).toEqual(testProductFilteringId2)
|
||||
expect(response.data.products[1].id).toEqual(testProductFilteringId1)
|
||||
expect(response.data.products[2].id).toEqual(testProductId1)
|
||||
expect(response.data.products[3].id).toEqual(testProductId)
|
||||
expect(response.data.products[4].id).toEqual(giftCardId)
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by variants title DESC", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get("/store/products?order=-variants.title")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(5)
|
||||
|
||||
const testProductIndex = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId)
|
||||
)
|
||||
const testProduct1Index = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId1)
|
||||
)
|
||||
|
||||
// Since they have the same variant titles for rank 2, the order is not guaranteed
|
||||
expect([3, 4]).toContain(testProductIndex)
|
||||
expect([3, 4]).toContain(testProduct1Index)
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by variants title ASC", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get("/store/products?order=variants.title")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(5)
|
||||
|
||||
const testProductIndex = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId)
|
||||
)
|
||||
const testProduct1Index = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId1)
|
||||
)
|
||||
|
||||
expect(testProductIndex).toBe(0)
|
||||
expect(testProduct1Index).toBe(1)
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by variants prices DESC", async () => {
|
||||
const api = useApi()
|
||||
|
||||
await simpleProductFactory(dbConnection, {
|
||||
id: testProductId2,
|
||||
status: "published",
|
||||
variants: [
|
||||
{
|
||||
id: "test_variant_5",
|
||||
prices: [
|
||||
{
|
||||
currency: "usd",
|
||||
amount: 200,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
let response = await api.get(
|
||||
"/store/products?order=-variants.prices.amount"
|
||||
)
|
||||
|
||||
// Update amount to unsure order, same amount will add randomness in the result with the same amounts
|
||||
const productToUpdate = response.data.products.find(
|
||||
(p) => p.id === testProductId
|
||||
)
|
||||
const priceToUpdate = productToUpdate.variants[0].prices[0]
|
||||
const priceData = {
|
||||
id: priceToUpdate.id,
|
||||
currency_code: priceToUpdate.currency_code,
|
||||
amount: 120,
|
||||
}
|
||||
|
||||
await api.post(
|
||||
`/admin/products/${testProductId}/variants/${productToUpdate.variants[0].id}`,
|
||||
{ prices: [priceData] },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
response = await api.get("/store/products?order=-variants.prices.amount")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(6)
|
||||
|
||||
const testProductIndex = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId)
|
||||
)
|
||||
const testProduct1Index = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId1)
|
||||
)
|
||||
const testProduct2Index = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId2)
|
||||
)
|
||||
|
||||
expect(testProduct2Index).toBe(3) // 200
|
||||
expect(testProductIndex).toBe(4) // 120
|
||||
expect(testProduct1Index).toBe(5) // 100
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by variants prices ASC", async () => {
|
||||
const api = useApi()
|
||||
|
||||
await simpleProductFactory(dbConnection, {
|
||||
id: testProductId2,
|
||||
status: "published",
|
||||
variants: [
|
||||
{
|
||||
id: "test_variant_5",
|
||||
prices: [
|
||||
{
|
||||
currency: "usd",
|
||||
amount: 200,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
let response = await api.get(
|
||||
"/store/products?order=variants.prices.amount"
|
||||
)
|
||||
|
||||
// Update amount to unsure order, same amount will add randomness in the result with the same amounts
|
||||
const productToUpdate = response.data.products.find(
|
||||
(p) => p.id === testProductId1
|
||||
)
|
||||
const priceToUpdate = productToUpdate.variants[0].prices[0]
|
||||
const priceData = {
|
||||
id: priceToUpdate.id,
|
||||
currency_code: priceToUpdate.currency_code,
|
||||
amount: 120,
|
||||
}
|
||||
|
||||
await api.post(
|
||||
`/admin/products/${testProductId1}/variants/${productToUpdate.variants[0].id}`,
|
||||
{ prices: [priceData] },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
response = await api.get("/store/products?order=variants.prices.amount")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(6)
|
||||
|
||||
const testProductIndex = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId)
|
||||
)
|
||||
const testProduct1Index = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === testProductId1)
|
||||
)
|
||||
const testProduct2Index = response.data.products.indexOf(
|
||||
response.data.products.find((p) => p.id === "test-product2")
|
||||
)
|
||||
|
||||
expect(testProductIndex).toBe(0) // 100
|
||||
expect(testProduct1Index).toBe(1) // 120
|
||||
expect(testProduct2Index).toBe(2) // 200
|
||||
})
|
||||
|
||||
it("products contain only fields defined with `fields` param", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get("/store/products?fields=handle")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
|
||||
expect(Object.keys(response.data.products[0])).toHaveLength(10)
|
||||
expect(Object.keys(response.data.products[0])).toEqual(
|
||||
expect.arrayContaining([
|
||||
"id",
|
||||
"created_at",
|
||||
|
||||
// fields
|
||||
"handle",
|
||||
// relations
|
||||
"variants",
|
||||
"options",
|
||||
"images",
|
||||
"tags",
|
||||
"collection",
|
||||
"type",
|
||||
"profiles",
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by id ASC and filtered with free text search", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get("/store/products?q=filtering&order=id")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(2)
|
||||
|
||||
expect(response.data.products).toEqual([
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId1,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId2,
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("returns a list of ordered products by id DESC and filtered with free text search", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get("/store/products?q=filtering&order=-id")
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(2)
|
||||
|
||||
expect(response.data.products).toEqual([
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId2,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId1,
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("returns a list of products in collection", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const notExpected = [
|
||||
expect.objectContaining({ collection_id: "test-collection" }),
|
||||
expect.objectContaining({ collection_id: "test-collection1" }),
|
||||
]
|
||||
|
||||
const response = await api
|
||||
.get("/store/products?collection_id[]=test-collection2")
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(1)
|
||||
expect(response.data.products).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId2,
|
||||
collection_id: "test-collection2",
|
||||
}),
|
||||
])
|
||||
)
|
||||
|
||||
for (const notExpect of notExpected) {
|
||||
expect(response.data.products).toEqual(
|
||||
expect.not.arrayContaining([notExpect])
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("returns a list of products with a given tag", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const notExpected = [expect.objectContaining({ id: "tag4" })]
|
||||
|
||||
const response = await api
|
||||
.get("/store/products?tags[]=tag3")
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(1)
|
||||
expect(response.data.products).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId1,
|
||||
collection_id: "test-collection1",
|
||||
}),
|
||||
])
|
||||
)
|
||||
|
||||
for (const notExpect of notExpected) {
|
||||
expect(response.data.products).toEqual(
|
||||
expect.not.arrayContaining([notExpect])
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("returns gift card product", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api
|
||||
.get("/store/products?is_giftcard=true")
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products.length).toEqual(1)
|
||||
expect(response.data.products).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: giftCardId,
|
||||
is_giftcard: true,
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("returns non gift card products", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api
|
||||
.get("/store/products?is_giftcard=false")
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
|
||||
expect(response.data.products).toEqual(
|
||||
expect.not.arrayContaining([
|
||||
expect.objectContaining({ is_giftcard: true }),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("returns product with tag", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const notExpected = [expect.objectContaining({ id: "tag4" })]
|
||||
|
||||
const response = await api
|
||||
.get("/store/products?tags[]=tag3")
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(1)
|
||||
expect(response.data.products).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId1,
|
||||
collection_id: "test-collection1",
|
||||
}),
|
||||
])
|
||||
)
|
||||
|
||||
for (const notExpect of notExpected) {
|
||||
expect(response.data.products).toEqual(
|
||||
expect.not.arrayContaining([notExpect])
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("returns a list of products in with a given handle", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const notExpected = [
|
||||
expect.objectContaining({ handle: testProductFilteringId1 }),
|
||||
]
|
||||
|
||||
const response = await api
|
||||
.get("/store/products?handle=test-product_filtering_2")
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(1)
|
||||
expect(response.data.products).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId2,
|
||||
handle: testProductFilteringId2,
|
||||
}),
|
||||
])
|
||||
)
|
||||
|
||||
for (const notExpect of notExpected) {
|
||||
expect(response.data.products).toEqual(
|
||||
expect.not.arrayContaining([notExpect])
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("works when filtering by type_id", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get(
|
||||
`/store/products?type_id[]=test-type&fields=id,title,type_id`
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products).toHaveLength(5)
|
||||
expect(response.data.products).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
type_id: "test-type",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("returns only published products", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const notExpected = [
|
||||
expect.objectContaining({ status: "proposed" }),
|
||||
expect.objectContaining({ status: "draft" }),
|
||||
expect.objectContaining({ status: "rejected" }),
|
||||
]
|
||||
|
||||
const response = await api.get("/store/products").catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.products.length).toEqual(5)
|
||||
expect(response.data.products).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: testProductId1,
|
||||
collection_id: "test-collection",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: testProductId,
|
||||
collection_id: "test-collection",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId2,
|
||||
collection_id: "test-collection2",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: testProductFilteringId1,
|
||||
collection_id: "test-collection1",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: giftCardId,
|
||||
}),
|
||||
])
|
||||
)
|
||||
|
||||
for (const notExpect of notExpected) {
|
||||
expect(response.data.products).toEqual(
|
||||
expect.not.arrayContaining([notExpect])
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("list params", () => {
|
||||
beforeEach(async () => {
|
||||
await productSeeder(dbConnection)
|
||||
|
||||
Reference in New Issue
Block a user