feat(medusa): Add endpoints specific to DiscountConditions (#1355)

This commit is contained in:
Oliver Windall Juhl
2022-05-13 12:42:23 +02:00
committed by GitHub
parent a69b52e031
commit 9ca45ea492
20 changed files with 1433 additions and 159 deletions

View File

@@ -14,3 +14,128 @@ Object {
"type": "duplicate_error",
}
`;
exports[`/admin/discounts POST /admin/discounts/:id/conditions fails if more than one condition type is provided: Only one of products, customer_groups is allowed, Only one of customer_groups, products is allowed 1`] = `"Request failed with status code 400"`;
exports[`/admin/discounts POST /admin/discounts/:id/conditions should create a condition 1`] = `
Object {
"code": "TEST",
"created_at": Any<String>,
"deleted_at": null,
"ends_at": null,
"id": "test-discount",
"is_disabled": false,
"is_dynamic": false,
"metadata": null,
"parent_discount": null,
"parent_discount_id": null,
"regions": Array [],
"rule": Object {
"allocation": "total",
"conditions": Array [
Object {
"created_at": Any<String>,
"deleted_at": null,
"discount_rule_id": Any<String>,
"id": Any<String>,
"metadata": null,
"operator": "in",
"type": "products",
"updated_at": Any<String>,
},
],
"created_at": Any<String>,
"deleted_at": null,
"description": null,
"id": Any<String>,
"metadata": null,
"type": "percentage",
"updated_at": Any<String>,
"value": 10,
},
"rule_id": Any<String>,
"starts_at": Any<String>,
"updated_at": Any<String>,
"usage_count": 0,
"usage_limit": null,
"valid_duration": null,
}
`;
exports[`/admin/discounts POST /admin/discounts/:id/conditions throws if discount does not exist: Discount with id does-not-exist was not found 1`] = `"Request failed with status code 404"`;
exports[`/admin/discounts POST /admin/discounts/:id/conditions/:condition_id should update a condition 1`] = `
Object {
"code": "TEST",
"created_at": Any<String>,
"deleted_at": null,
"ends_at": null,
"id": "test-discount",
"is_disabled": false,
"is_dynamic": false,
"metadata": null,
"parent_discount_id": null,
"rule": Object {
"allocation": "total",
"conditions": Array [
Object {
"created_at": Any<String>,
"deleted_at": null,
"discount_rule_id": Any<String>,
"id": Any<String>,
"metadata": null,
"operator": "in",
"products": Array [
Object {
"collection_id": null,
"created_at": Any<String>,
"deleted_at": null,
"description": null,
"discountable": true,
"external_id": null,
"handle": null,
"height": null,
"hs_code": null,
"id": "test-product",
"is_giftcard": false,
"length": null,
"material": null,
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile_id": Any<String>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
"title": "Practical Frozen Fish",
"type_id": Any<String>,
"updated_at": Any<String>,
"weight": null,
"width": null,
},
],
"type": "products",
"updated_at": Any<String>,
},
],
"created_at": Any<String>,
"deleted_at": null,
"description": null,
"id": Any<String>,
"metadata": null,
"type": "percentage",
"updated_at": Any<String>,
"value": 10,
},
"rule_id": Any<String>,
"starts_at": Any<String>,
"updated_at": Any<String>,
"usage_count": 0,
"usage_limit": null,
"valid_duration": null,
}
`;
exports[`/admin/discounts POST /admin/discounts/:id/conditions/:condition_id throws if condition does not exist: DiscountCondition with id does-not-exist was not found for Discount test-discount 1`] = `"Request failed with status code 404"`;
exports[`/admin/discounts POST /admin/discounts/:id/conditions/:condition_id throws if discount does not exist: Discount with id does-not-exist was not found 1`] = `"Request failed with status code 404"`;

View File

@@ -1,6 +1,5 @@
const path = require("path")
const {
Region,
DiscountRule,
Discount,
Customer,
@@ -12,7 +11,6 @@ const { useApi } = require("../../../helpers/use-api")
const { initDb, useDb } = require("../../../helpers/use-db")
const adminSeeder = require("../../helpers/admin-seeder")
const discountSeeder = require("../../helpers/discount-seeder")
const { exportAllDeclaration } = require("@babel/types")
const { simpleProductFactory } = require("../../factories")
const {
simpleDiscountFactory,
@@ -433,7 +431,6 @@ describe("/admin/discounts", () => {
await adminSeeder(dbConnection)
await discountSeeder(dbConnection)
} catch (err) {
console.log(err)
throw err
}
})
@@ -1468,41 +1465,37 @@ describe("/admin/discounts", () => {
describe("POST /admin/discounts/:discount_id/dynamic-codes", () => {
beforeEach(async () => {
const manager = dbConnection.manager
try {
await adminSeeder(dbConnection)
await manager.insert(DiscountRule, {
id: "test-discount-rule",
description: "Dynamic rule",
type: "percentage",
value: 10,
allocation: "total",
})
await manager.insert(Discount, {
id: "test-discount",
code: "DYNAMIC",
is_dynamic: true,
is_disabled: false,
rule_id: "test-discount-rule",
valid_duration: "P2Y",
})
await manager.insert(DiscountRule, {
id: "test-discount-rule1",
description: "Dynamic rule",
type: "percentage",
value: 10,
allocation: "total",
})
await manager.insert(Discount, {
id: "test-discount1",
code: "DYNAMICCode",
is_dynamic: true,
is_disabled: false,
rule_id: "test-discount-rule1",
})
} catch (err) {
console.log(err)
throw err
}
await adminSeeder(dbConnection)
await manager.insert(DiscountRule, {
id: "test-discount-rule",
description: "Dynamic rule",
type: "percentage",
value: 10,
allocation: "total",
})
await manager.insert(Discount, {
id: "test-discount",
code: "DYNAMIC",
is_dynamic: true,
is_disabled: false,
rule_id: "test-discount-rule",
valid_duration: "P2Y",
})
await manager.insert(DiscountRule, {
id: "test-discount-rule1",
description: "Dynamic rule",
type: "percentage",
value: 10,
allocation: "total",
})
await manager.insert(Discount, {
id: "test-discount1",
code: "DYNAMICCode",
is_dynamic: true,
is_disabled: false,
rule_id: "test-discount-rule1",
})
})
afterEach(async () => {
@@ -1554,7 +1547,7 @@ describe("/admin/discounts", () => {
}
)
.catch((err) => {
// console.log(err)
console.log(err)
})
expect(response.status).toEqual(200)
@@ -1566,4 +1559,477 @@ describe("/admin/discounts", () => {
)
})
})
describe("DELETE /admin/discounts/:id/conditions/:condition_id", () => {
beforeEach(async () => {
const manager = dbConnection.manager
await adminSeeder(dbConnection)
await manager.insert(DiscountRule, {
id: "test-discount-rule-fixed",
description: "Test discount rule",
type: "fixed",
value: 10,
allocation: "total",
})
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
await simpleDiscountFactory(dbConnection, {
id: "test-discount",
code: "TEST",
rule: {
type: "percentage",
value: "10",
allocation: "total",
conditions: [
{
type: "products",
operator: "in",
products: [prod.id],
},
],
},
})
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("should delete condition", async () => {
const api = useApi()
const group = await dbConnection.manager.insert(CustomerGroup, {
id: "customer-group-1",
name: "vip-customers",
})
await dbConnection.manager.insert(Customer, {
id: "cus_1234",
email: "oli@email.com",
groups: [group],
})
await simpleDiscountFactory(dbConnection, {
id: "test-discount",
code: "TEST",
rule: {
type: "percentage",
value: "10",
allocation: "total",
conditions: [
{
id: "test-condition",
type: "customer_groups",
operator: "in",
customer_groups: ["customer-group-1"],
},
],
},
})
const response = await api
.delete("/admin/discounts/test-discount/conditions/test-condition", {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err)
})
const disc = response.data
expect(response.status).toEqual(200)
expect(disc).toEqual(
expect.objectContaining({
id: "test-condition",
deleted: true,
object: "discount-condition",
})
)
})
it("should not fail if condition does not exist", async () => {
const api = useApi()
const response = await api
.delete("/admin/discounts/test-discount/conditions/test-condition", {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err)
})
const disc = response.data
expect(response.status).toEqual(200)
expect(disc).toEqual(
expect.objectContaining({
id: "test-condition",
deleted: true,
object: "discount-condition",
})
)
})
it("should fail if discount does not exist", async () => {
const api = useApi()
try {
await api.delete(
"/admin/discounts/not-exist/conditions/test-condition",
{
headers: {
Authorization: "Bearer test_token",
},
}
)
} catch (error) {
expect(error.message).toMatchSnapshot(
"Discount with id not-exist was not found"
)
}
})
})
describe("POST /admin/discounts/:id/conditions", () => {
beforeEach(async () => {
const manager = dbConnection.manager
await adminSeeder(dbConnection)
await manager.insert(DiscountRule, {
id: "test-discount-rule-fixed",
description: "Test discount rule",
type: "fixed",
value: 10,
allocation: "total",
})
await simpleDiscountFactory(dbConnection, {
id: "test-discount",
code: "TEST",
rule: {
type: "percentage",
value: "10",
allocation: "total",
},
})
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("should create a condition", async () => {
const api = useApi()
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
const response = await api
.post(
"/admin/discounts/test-discount/conditions",
{
operator: "in",
products: [prod.id],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err)
})
const disc = response.data.discount
expect(response.status).toEqual(200)
expect(disc).toMatchSnapshot({
id: "test-discount",
code: "TEST",
created_at: expect.any(String),
updated_at: expect.any(String),
rule_id: expect.any(String),
starts_at: expect.any(String),
rule: {
id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
conditions: [
{
id: expect.any(String),
discount_rule_id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
},
],
},
})
})
it("fails if more than one condition type is provided", async () => {
const api = useApi()
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
const group = await dbConnection.manager.insert(CustomerGroup, {
id: "customer-group-1",
name: "vip-customers",
})
await dbConnection.manager.insert(Customer, {
id: "cus_1234",
email: "oli@email.com",
groups: [group],
})
try {
await api.post(
"/admin/discounts/test-discount/conditions",
{
operator: "in",
products: [prod.id],
customer_groups: ["customer-group-1"],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
} catch (error) {
expect(error.message).toMatchSnapshot(
"Only one of products, customer_groups is allowed, Only one of customer_groups, products is allowed"
)
}
})
it("throws if discount does not exist", async () => {
expect.assertions(1)
const api = useApi()
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
try {
await api.post(
"/admin/discounts/does-not-exist/conditions/test-condition",
{
products: [prod2.id],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
} catch (error) {
expect(error.message).toMatchSnapshot(
"Discount with id does-not-exist was not found"
)
}
})
})
describe("POST /admin/discounts/:id/conditions/:condition_id", () => {
beforeEach(async () => {
const manager = dbConnection.manager
await adminSeeder(dbConnection)
await manager.insert(DiscountRule, {
id: "test-discount-rule-fixed",
description: "Test discount rule",
type: "fixed",
value: 10,
allocation: "total",
})
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
await simpleDiscountFactory(dbConnection, {
id: "test-discount",
code: "TEST",
rule: {
type: "percentage",
value: "10",
allocation: "total",
conditions: [
{
id: "test-condition",
type: "products",
operator: "in",
products: [prod.id],
},
],
},
})
await simpleDiscountFactory(dbConnection, {
id: "test-discount-2",
code: "TEST2",
rule: {
type: "percentage",
value: "10",
allocation: "total",
},
})
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("should update a condition", async () => {
const api = useApi()
const prod2 = await simpleProductFactory(dbConnection, {
id: "test-product",
type: "pants",
})
const discount = await api
.get("/admin/discounts/test-discount", {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err)
})
const cond = discount.data.discount.rule.conditions[0]
const response = await api
.post(
`/admin/discounts/test-discount/conditions/${cond.id}?expand=rule,rule.conditions,rule.conditions.products`,
{
products: [prod2.id],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err)
})
const disc = response.data.discount
expect(response.status).toEqual(200)
expect(disc).toMatchSnapshot({
id: "test-discount",
code: "TEST",
created_at: expect.any(String),
updated_at: expect.any(String),
rule_id: expect.any(String),
starts_at: expect.any(String),
rule: {
id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
conditions: [
{
id: expect.any(String),
discount_rule_id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
products: [
{
created_at: expect.any(String),
updated_at: expect.any(String),
profile_id: expect.any(String),
type_id: expect.any(String),
id: "test-product",
},
],
},
],
},
})
})
it("throws if condition does not exist", async () => {
const api = useApi()
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
try {
await api.post(
"/admin/discounts/test-discount/conditions/does-not-exist",
{
products: [prod2.id],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
} catch (error) {
expect(error.message).toMatchSnapshot(
"DiscountCondition with id does-not-exist was not found for Discount test-discount"
)
}
})
it("throws if discount does not exist", async () => {
expect.assertions(1)
const api = useApi()
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
try {
await api.post(
"/admin/discounts/does-not-exist/conditions/test-condition",
{
products: [prod2.id],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
} catch (error) {
expect(error.message).toMatchSnapshot(
"Discount with id does-not-exist was not found"
)
}
})
it("throws if condition does not belong to discount", async () => {
const api = useApi()
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
try {
await api.post(
"/admin/discounts/test-discount-2/conditions/test-condition",
{
products: [prod2.id],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
} catch (error) {
expect(error.message).toMatchSnapshot(
"DiscountCondition with id test-condition was not found for Discount test-discount-2"
)
}
})
})
})

View File

@@ -13,6 +13,7 @@ import faker from "faker"
import { Connection } from "typeorm"
export type DiscuntConditionFactoryData = {
id?: string
rule_id: string
type: DiscountConditionType
operator: DiscountConditionOperator
@@ -93,11 +94,17 @@ export const simpleDiscountConditionFactory = async (
resources = data.customer_groups
}
const condToSave = manager.create(DiscountCondition, {
const toCreate = {
type: data.type,
operator: data.operator,
discount_rule_id: data.rule_id,
})
}
if (data.id) {
toCreate["id"] = data.id
}
const condToSave = manager.create(DiscountCondition, toCreate)
const { conditionTable, resourceKey } = getJoinTableResourceIdentifiers(
data.type