feat: adds discount code search functionality (#155)

This commit is contained in:
Oliver Windall Juhl authored and GitHub committed 2021-01-27 11:13:24 +01:00
1 parent 103749eb65
commit 7e14da1225
6 files changed
+160 -16

No files matched your search

@@ -7,6 +7,7 @@ export default ({
findOne, findOne,
findOneOrFail, findOneOrFail,
save, save,
findAndCount,
} = {}) => { } = {}) => {
return { return {
create: jest.fn().mockImplementation((...args) => { create: jest.fn().mockImplementation((...args) => {
@@ -63,5 +64,11 @@ export default ({
} }
return Promise.resolve(...args); return Promise.resolve(...args);
}), }),
findAndCount: jest.fn().mockImplementation((...args) => {
if (findAndCount) {
return findAndCount(...args);
}
return {};
}),
}; };
}; };
@@ -1,9 +1,10 @@
import { IdMap } from "medusa-test-utils" import { IdMap } from "medusa-test-utils"
import { defaultFields, defaultRelations } from ".."
import { request } from "../../../../../helpers/test-request" import { request } from "../../../../../helpers/test-request"
import { DiscountServiceMock } from "../../../../../services/__mocks__/discount" import { DiscountServiceMock } from "../../../../../services/__mocks__/discount"
describe("GET /admin/discounts", () => { describe("GET /admin/discounts", () => {
describe("successful retrieval", () => { describe("successful retrieval of discounts", () => {
let subject let subject
beforeAll(async () => { beforeAll(async () => {
@@ -21,31 +22,55 @@ describe("GET /admin/discounts", () => {
expect(subject.status).toEqual(200) expect(subject.status).toEqual(200)
}) })
it("calls service retrieve", () => { it("calls service retrieve with config", () => {
expect(DiscountServiceMock.list).toHaveBeenCalledTimes(1) expect(DiscountServiceMock.listAndCount).toHaveBeenCalledTimes(1)
expect(DiscountServiceMock.listAndCount).toHaveBeenCalledWith(
{},
{
select: defaultFields,
relations: defaultRelations,
skip: 0,
take: 20,
order: { created_at: "DESC" },
}
)
}) })
}) })
describe("expand region filter", () => { describe("successful retrieval of discounts with query config", () => {
let subject let subject
beforeAll(async () => { beforeAll(async () => {
jest.clearAllMocks() jest.clearAllMocks()
subject = await request("GET", `/admin/discounts?expand_fields=regions`, { subject = await request(
adminSession: { "GET",
jwt: { `/admin/discounts?q=OLI&limit=40&offset=20&is_dynamic=false`,
userId: IdMap.getId("admin_user"), {
adminSession: {
jwt: {
userId: IdMap.getId("admin_user"),
},
}, },
}, }
}) )
}) })
it("returns 200", () => { it("returns 200", () => {
expect(subject.status).toEqual(200) expect(subject.status).toEqual(200)
}) })
it("calls service retrieve", () => { it("calls service retrieve with config", () => {
expect(DiscountServiceMock.list).toHaveBeenCalledTimes(1) expect(DiscountServiceMock.listAndCount).toHaveBeenCalledTimes(1)
expect(DiscountServiceMock.listAndCount).toHaveBeenCalledWith(
{ q: "OLI", is_dynamic: false },
{
select: defaultFields,
relations: defaultRelations,
skip: 20,
take: 40,
order: { created_at: "DESC" },
}
)
}) })
}) })
}) })
@@ -2,23 +2,35 @@ import { defaultFields, defaultRelations } from "./"
export default async (req, res) => { export default async (req, res) => {
try { try {
const selector = {} const discountService = req.scope.resolve("discountService")
const limit = parseInt(req.query.limit) || 20 const limit = parseInt(req.query.limit) || 20
const offset = parseInt(req.query.offset) || 0 const offset = parseInt(req.query.offset) || 0
const discountService = req.scope.resolve("discountService") let selector = {}
if ("q" in req.query) {
selector.q = req.query.q
}
if ("is_dynamic" in req.query) {
selector.is_dynamic = req.query.is_dynamic === "true"
}
const listConfig = { const listConfig = {
select: defaultFields, select: defaultFields,
relations: defaultRelations, relations: defaultRelations,
skip: offset, skip: offset,
take: limit, take: limit,
order: { created_at: "DESC" },
} }
const discounts = await discountService.list(selector, listConfig) const [discounts, count] = await discountService.listAndCount(
selector,
listConfig
)
res.status(200).json({ discounts }) res.status(200).json({ discounts, count, offset, limit })
} catch (err) { } catch (err) {
throw err throw err
} }
@@ -165,6 +165,9 @@ export const DiscountServiceMock = {
list: jest.fn().mockImplementation(data => { list: jest.fn().mockImplementation(data => {
return Promise.resolve([{}]) return Promise.resolve([{}])
}), }),
listAndCount: jest.fn().mockImplementation(data => {
return Promise.resolve([{}])
}),
addRegion: jest.fn().mockReturnValue(Promise.resolve()), addRegion: jest.fn().mockReturnValue(Promise.resolve()),
removeRegion: jest.fn().mockReturnValue(Promise.resolve()), removeRegion: jest.fn().mockReturnValue(Promise.resolve()),
addValidProduct: jest.fn().mockReturnValue(Promise.resolve()), addValidProduct: jest.fn().mockReturnValue(Promise.resolve()),
@@ -468,4 +468,55 @@ describe("DiscountService", () => {
expect(discountRepository.save).toHaveBeenCalledTimes(0) expect(discountRepository.save).toHaveBeenCalledTimes(0)
}) })
}) })
describe("listAndCount", () => {
const discountRepository = MockRepository({
findAndCount: () =>
Promise.resolve([
{
id: IdMap.getId("total10"),
code: "OLITEST",
},
]),
})
const discountService = new DiscountService({
manager: MockManager,
discountRepository,
})
beforeEach(() => {
jest.clearAllMocks()
})
it("calls repository function with query and default config", async () => {
await discountService.listAndCount({ q: "OLI" })
expect(discountRepository.findAndCount).toHaveBeenCalledTimes(1)
expect(discountRepository.findAndCount).toHaveBeenCalledWith({
join: {
alias: "discount",
},
where: expect.anything(),
skip: 0,
take: 50,
order: { created_at: "DESC" },
})
})
it("calls repository function specified query", async () => {
await discountService.listAndCount(
{},
{ skip: 50, take: 50, order: { created_at: "ASC" } }
)
expect(discountRepository.findAndCount).toHaveBeenCalledTimes(1)
expect(discountRepository.findAndCount).toHaveBeenCalledWith({
where: {},
skip: 50,
take: 50,
order: { created_at: "ASC" },
})
})
})
}) })
+46
View File
@@ -2,6 +2,7 @@ import _ from "lodash"
import randomize from "randomatic" import randomize from "randomatic"
import { BaseService } from "medusa-interfaces" import { BaseService } from "medusa-interfaces"
import { Validator, MedusaError } from "medusa-core-utils" import { Validator, MedusaError } from "medusa-core-utils"
import { Brackets } from "typeorm"
/** /**
* Provides layer to manipulate discounts. * Provides layer to manipulate discounts.
@@ -115,6 +116,51 @@ class DiscountService extends BaseService {
return discountRepo.find(query) return discountRepo.find(query)
} }
/**
* @param {Object} selector - the query object for find
* @return {Promise} the result of the find operation
*/
async listAndCount(
selector = {},
config = { skip: 0, take: 50, order: { created_at: "DESC" } }
) {
const discountRepo = this.manager_.getCustomRepository(
this.discountRepository_
)
let q
if ("q" in selector) {
q = selector.q
delete selector.q
}
const query = this.buildQuery_(selector, config)
if (q) {
const where = query.where
delete where.code
query.join = {
alias: "discount",
}
query.where = qb => {
qb.where(where)
qb.andWhere(
new Brackets(qb => {
qb.where(`discount.code ILIKE :q`, { q: `%${q}%` })
})
)
}
}
const [discounts, count] = await discountRepo.findAndCount(query)
return [discounts, count]
}
/** /**
* Creates a discount with provided data given that the data is validated. * Creates a discount with provided data given that the data is validated.
* Normalizes discount code to uppercase. * Normalizes discount code to uppercase.