feat: expand store product filtering (#973)

This commit is contained in:
Philip Korsholm
2022-01-11 16:06:16 +01:00
committed by GitHub
parent 6dbd8d318d
commit f61eaeec12
4 changed files with 590 additions and 22 deletions
@@ -1,3 +1,4 @@
import { IdMap } from "medusa-test-utils"
import { request } from "../../../../../helpers/test-request"
import { InviteServiceMock } from "../../../../../services/__mocks__/invite"
import { UserRole } from "../../../../../types/user"
@@ -9,9 +10,9 @@ describe("POST /invites", () => {
beforeAll(async () => {
subject = await request("POST", `/admin/invites`, {
payload: {
role: "",
role: "admin",
},
session: {
adminSession: {
jwt: {
userId: "test_user",
},
@@ -25,6 +26,10 @@ describe("POST /invites", () => {
it("throws when role is empty", () => {
expect(subject.error).toBeTruthy()
expect(subject.error.text).toEqual(
`{"type":"invalid_data","message":"user must be an email"}`
)
expect(subject.error.status).toEqual(400)
})
})
@@ -37,9 +42,9 @@ describe("POST /invites", () => {
role: "admin",
user: "lebron@james.com",
},
session: {
adminSession: {
jwt: {
userId: "test_user",
userId: IdMap.getId("admin_user"),
},
},
})
@@ -1,14 +1,40 @@
import { Type } from "class-transformer"
import { IsBoolean, IsInt, IsNumber, IsOptional } from "class-validator"
import { Transform, Type } from "class-transformer"
import {
IsArray,
IsBoolean,
IsNumber,
IsOptional,
IsString,
ValidateNested,
} from "class-validator"
import { omit, pickBy, identity } from "lodash"
import { MedusaError } from "medusa-core-utils"
import { defaultStoreProductsRelations } from "."
import { ProductService } from "../../../../services"
import { DateComparisonOperator } from "../../../../types/common"
import { validator } from "../../../../utils/validator"
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
/**
* @oas [get] /products
* operationId: GetProducts
* summary: List Products
* description: "Retrieves a list of Products."
* parameters:
* - (query) q {string} Query used for searching products.
* - (query) id {string} Id of the product to search for.
* - (query) collection_id {string[]} Collection ids to search for.
* - (query) tags {string[]} Tags to search for.
* - (query) title {string} to search for.
* - (query) description {string} to search for.
* - (query) handle {string} to search for.
* - (query) is_giftcard {string} Search for giftcards using is_giftcard=true.
* - (query) type {string} to search for.
* - (query) created_at {DateComparisonOperator} Date comparison for when resulting products was created, i.e. less than, greater than etc.
* - (query) updated_at {DateComparisonOperator} Date comparison for when resulting products was updated, i.e. less than, greater than etc.
* - (query) deleted_at {DateComparisonOperator} Date comparison for when resulting products was deleted, i.e. less than, greater than etc.
* - (query) offset {string} How many products to skip in the result.
* - (query) limit {string} Limit the number of products returned.
* tags:
* - Product
* responses:
@@ -37,13 +63,13 @@ export default async (req, res) => {
const validated = await validator(StoreGetProductsParams, req.query)
const selector = {}
const filterableFields: StoreGetProductsParams = omit(validated, [
"limit",
"offset",
])
if (validated.is_giftcard && validated.is_giftcard === true) {
selector["is_giftcard"] = validated.is_giftcard
}
selector["status"] = ["published"]
// get only published products for store endpoint
filterableFields["status"] = ["published"]
const listConfig = {
relations: defaultStoreProductsRelations,
@@ -52,7 +78,7 @@ export default async (req, res) => {
}
const [products, count] = await productService.listAndCount(
selector,
pickBy(filterableFields, (val) => typeof val !== "undefined"),
listConfig
)
@@ -64,17 +90,68 @@ export default async (req, res) => {
})
}
export class StoreGetProductsParams {
@IsInt()
export class StoreGetProductsPaginationParams {
@IsNumber()
@IsOptional()
@Type(() => Number)
limit = 100
offset?: number = 0
@IsInt()
@IsNumber()
@IsOptional()
@Type(() => Number)
offset = 0
limit?: number = 100
}
export class StoreGetProductsParams extends StoreGetProductsPaginationParams {
@IsString()
@IsOptional()
id?: string
@IsString()
@IsOptional()
q?: string
@IsArray()
@IsOptional()
collection_id?: string[]
@IsArray()
@IsOptional()
tags?: string[]
@IsString()
@IsOptional()
title?: string
@IsString()
@IsOptional()
description?: string
@IsString()
@IsOptional()
handle?: string
@IsBoolean()
@IsOptional()
@Transform(({ value }) => optionalBooleanMapper.get(value.toLowerCase()))
is_giftcard?: boolean
@IsString()
@IsOptional()
type?: string
@IsOptional()
@IsBoolean()
@Type(() => Boolean)
is_giftcard?: boolean
@ValidateNested()
@Type(() => DateComparisonOperator)
created_at?: DateComparisonOperator
@IsOptional()
@ValidateNested()
@Type(() => DateComparisonOperator)
updated_at?: DateComparisonOperator
@ValidateNested()
@IsOptional()
@Type(() => DateComparisonOperator)
deleted_at?: DateComparisonOperator
}