feat: adds discount code search functionality (#155)
This commit is contained in:
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" },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -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.
|
||||||
|
|||||||
Reference in new issue
Block a user