Merge branch 'develop' into feat/draft-orders
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
node_modules
|
||||
*yarn-error.log
|
||||
.DS_Store
|
||||
lerna-debug.log
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
let ignore = [`**/dist`];
|
||||
|
||||
// Jest needs to compile this code, but generally we don't want this copied
|
||||
// to output folders
|
||||
if (process.env.NODE_ENV !== `test`) {
|
||||
ignore.push(`**/__tests__`);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sourceMaps: true,
|
||||
presets: ["babel-preset-medusa-package"],
|
||||
ignore,
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
dist/
|
||||
node_modules
|
||||
*yarn-error.log
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
const productSeeder = require("../../helpers/product-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/admin/collections", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /admin/products", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a product", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const payload = {
|
||||
title: "Summer Collection",
|
||||
handle: "summer-collection",
|
||||
};
|
||||
|
||||
const response = await api
|
||||
.post("/admin/collections", payload, {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("product_collection", response.data.collection);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
const path = require("path");
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const { Customer, Address } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/admin/customers", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("GET /admin/customers", () => {
|
||||
let id;
|
||||
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection);
|
||||
const manager = dbConnection.manager;
|
||||
|
||||
const created = manager.create(Customer, {
|
||||
email: "test1@email.com",
|
||||
});
|
||||
|
||||
const newly = await manager.save(created);
|
||||
|
||||
id = newly.id;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "address"`);
|
||||
await manager.query(`DELETE FROM "customer"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("lists customers and query count", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.get(`/admin/customers/${id}`, {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("customer", response.data.customer);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,82 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const { Region } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/discounts", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /store/carts", () => {
|
||||
let regId;
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection);
|
||||
const manager = dbConnection.manager;
|
||||
const created = manager.create(Region, {
|
||||
id: "region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
const newReg = await manager.save(created);
|
||||
regId = newReg.id;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "discount"`);
|
||||
await manager.query(`DELETE FROM "discount_rule"`);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a cart", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const getRes = await api.post(
|
||||
`/admin/discounts`,
|
||||
{
|
||||
code: "10DISC",
|
||||
rule: {
|
||||
description: "10 Percent",
|
||||
type: "percentage",
|
||||
allocation: "total",
|
||||
value: 10,
|
||||
},
|
||||
regions: [regId],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(getRes.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("discount", getRes.data.discount);
|
||||
fixtureWriter.addFixture("discount_rule", getRes.data.discount.rule);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const { Region } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/discounts", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /admin/gift-cards", () => {
|
||||
let regId;
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection);
|
||||
const manager = dbConnection.manager;
|
||||
const created = manager.create(Region, {
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
const newReg = await manager.save(created);
|
||||
regId = newReg.id;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "discount"`);
|
||||
await manager.query(`DELETE FROM "discount_rule"`);
|
||||
await manager.query(`DELETE FROM "gift_card"`);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a cart", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const getRes = await api.post(
|
||||
`/admin/gift-cards`,
|
||||
{
|
||||
value: 1000,
|
||||
region_id: regId,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(getRes.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("gift_card", getRes.data.gift_card);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,73 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const { Notification } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const orderSeeder = require("../../helpers/order-seeder");
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/admin/orders", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("GET /notifications", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection);
|
||||
const manager = dbConnection.manager;
|
||||
|
||||
const noti = manager.create(Notification, {
|
||||
event_name: "order.placed",
|
||||
resource_type: "order",
|
||||
resource_id: "order_01F0BF66ZBXNJ98WDQ9SCWH8Y7",
|
||||
provider_id: "test-not",
|
||||
data: {},
|
||||
to: "test@email.com",
|
||||
});
|
||||
await manager.save(noti);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "notification"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a claim", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get(`/admin/notifications`, {
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("notification", response.data.notifications[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,164 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const orderSeeder = require("../../helpers/order-seeder");
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/admin/orders", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("GET /admin/orders/:id", () => {
|
||||
let id;
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection);
|
||||
const order = await orderSeeder(dbConnection);
|
||||
id = order.id;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "cart"`);
|
||||
await manager.query(`DELETE FROM "fulfillment_item"`);
|
||||
await manager.query(`DELETE FROM "fulfillment"`);
|
||||
await manager.query(`DELETE FROM "swap"`);
|
||||
await manager.query(`DELETE FROM "return"`);
|
||||
await manager.query(`DELETE FROM "claim_image"`);
|
||||
await manager.query(`DELETE FROM "claim_tag"`);
|
||||
await manager.query(`DELETE FROM "claim_item"`);
|
||||
await manager.query(`DELETE FROM "shipping_method"`);
|
||||
await manager.query(`DELETE FROM "line_item"`);
|
||||
await manager.query(`DELETE FROM "claim_order"`);
|
||||
await manager.query(`DELETE FROM "money_amount"`);
|
||||
await manager.query(`DELETE FROM "product_option_value"`);
|
||||
await manager.query(`DELETE FROM "product_option"`);
|
||||
await manager.query(`DELETE FROM "product_variant"`);
|
||||
await manager.query(`DELETE FROM "product"`);
|
||||
await manager.query(`DELETE FROM "shipping_option"`);
|
||||
await manager.query(`DELETE FROM "discount"`);
|
||||
await manager.query(`DELETE FROM "payment"`);
|
||||
await manager.query(`DELETE FROM "order"`);
|
||||
await manager.query(`DELETE FROM "customer"`);
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
|
||||
);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a claim", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get(`/admin/orders/${id}`, {
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("order", response.data.order);
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /admin/orders/:id/returns", () => {
|
||||
let id;
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection);
|
||||
const order = await orderSeeder(dbConnection);
|
||||
id = order.id;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "cart"`);
|
||||
await manager.query(`DELETE FROM "fulfillment_item"`);
|
||||
await manager.query(`DELETE FROM "fulfillment"`);
|
||||
await manager.query(`DELETE FROM "swap"`);
|
||||
await manager.query(`DELETE FROM "return_item"`);
|
||||
await manager.query(`DELETE FROM "return"`);
|
||||
await manager.query(`DELETE FROM "claim_image"`);
|
||||
await manager.query(`DELETE FROM "claim_tag"`);
|
||||
await manager.query(`DELETE FROM "claim_item"`);
|
||||
await manager.query(`DELETE FROM "shipping_method"`);
|
||||
await manager.query(`DELETE FROM "line_item"`);
|
||||
await manager.query(`DELETE FROM "claim_order"`);
|
||||
await manager.query(`DELETE FROM "money_amount"`);
|
||||
await manager.query(`DELETE FROM "product_option_value"`);
|
||||
await manager.query(`DELETE FROM "product_option"`);
|
||||
await manager.query(`DELETE FROM "product_variant"`);
|
||||
await manager.query(`DELETE FROM "product"`);
|
||||
await manager.query(`DELETE FROM "shipping_option"`);
|
||||
await manager.query(`DELETE FROM "discount"`);
|
||||
await manager.query(`DELETE FROM "payment"`);
|
||||
await manager.query(`DELETE FROM "order"`);
|
||||
await manager.query(`DELETE FROM "customer"`);
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
|
||||
);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a return", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const { data } = await api.get(`/admin/orders/${id}`, {
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
});
|
||||
const order = data.order;
|
||||
|
||||
const response = await api.post(
|
||||
`/admin/orders/${id}/return`,
|
||||
{
|
||||
items: [
|
||||
{
|
||||
item_id: order.items[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("return", response.data.order.returns[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
const productSeeder = require("../../helpers/product-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/admin/products", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /admin/products", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await productSeeder(dbConnection);
|
||||
await adminSeeder(dbConnection);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "product_option_value"`);
|
||||
await manager.query(`DELETE FROM "product_option"`);
|
||||
await manager.query(`DELETE FROM "money_amount"`);
|
||||
await manager.query(`DELETE FROM "product_variant"`);
|
||||
await manager.query(`DELETE FROM "product"`);
|
||||
await manager.query(`DELETE FROM "product_collection"`);
|
||||
await manager.query(`DELETE FROM "product_tag"`);
|
||||
await manager.query(`DELETE FROM "product_type"`);
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
|
||||
);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a product", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const payload = {
|
||||
title: "Test product",
|
||||
description: "test-product-description",
|
||||
type: { value: "test-type" },
|
||||
collection_id: "test-collection",
|
||||
tags: [{ value: "123" }, { value: "456" }],
|
||||
options: [{ title: "size" }, { title: "color" }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
inventory_quantity: 10,
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: [{ value: "large" }, { value: "green" }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const response = await api
|
||||
.post("/admin/products", payload, {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("product", response.data.product);
|
||||
fixtureWriter.addFixture(
|
||||
"product_variant",
|
||||
response.data.product.variants[0]
|
||||
);
|
||||
fixtureWriter.addFixture(
|
||||
"product_option",
|
||||
response.data.product.options[0]
|
||||
);
|
||||
fixtureWriter.addFixture(
|
||||
"product_option_value",
|
||||
response.data.product.variants[0].options[0]
|
||||
);
|
||||
fixtureWriter.addFixture(
|
||||
"money_amount",
|
||||
response.data.product.variants[0].prices[0]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const { Region } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/shipping-options", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /admin/shipping-options", () => {
|
||||
let regId;
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection);
|
||||
const manager = dbConnection.manager;
|
||||
const created = manager.create(Region, {
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
fulfillment_providers: [
|
||||
{
|
||||
id: "test-ful",
|
||||
},
|
||||
],
|
||||
});
|
||||
const newReg = await manager.save(created);
|
||||
regId = newReg.id;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "shipping_option"`);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a cart", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const getRes = await api.post(
|
||||
`/admin/shipping-options`,
|
||||
{
|
||||
name: "Free Shipping",
|
||||
region_id: regId,
|
||||
provider_id: "test-ful",
|
||||
data: {},
|
||||
price_type: "flat_rate",
|
||||
amount: 100,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(getRes.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("region", getRes.data.shipping_option.region);
|
||||
fixtureWriter.addFixture("shipping_option", getRes.data.shipping_option);
|
||||
fixtureWriter.addFixture(
|
||||
"shipping_profile",
|
||||
getRes.data.shipping_option.shipping_profile
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const { Region } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
const cartSeeder = require("../../helpers/cart-seeder");
|
||||
|
||||
const fixtureWriter = require("../../utils/write-fixture").default;
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/store/carts", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /store/carts", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.insert(Region, {
|
||||
id: "region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id='region' WHERE iso_2 = 'us'`
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "cart"`);
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
|
||||
);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
});
|
||||
|
||||
it("creates a cart", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.post("/store/carts");
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
const getRes = await api.post(`/store/carts/${response.data.cart.id}`);
|
||||
expect(getRes.status).toEqual(200);
|
||||
|
||||
fixtureWriter.addFixture("cart", getRes.data.cart);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
const Scrypt = require("scrypt-kdf");
|
||||
const { User } = require("@medusajs/medusa");
|
||||
|
||||
module.exports = async (connection, data = {}) => {
|
||||
const manager = connection.manager;
|
||||
|
||||
const buf = await Scrypt.kdf("secret_password", { logN: 1, r: 1, p: 1 });
|
||||
const password_hash = buf.toString("base64");
|
||||
|
||||
await manager.insert(User, {
|
||||
id: "admin_user",
|
||||
email: "admin@medusa.js",
|
||||
api_token: "test_token",
|
||||
password_hash,
|
||||
...data,
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
const { Customer, Region, Cart } = require("@medusajs/medusa");
|
||||
|
||||
module.exports = async (connection, data = {}) => {
|
||||
const manager = connection.manager;
|
||||
|
||||
await manager.insert(Region, {
|
||||
id: "test-region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id='test-region' WHERE iso_2 = 'us'`
|
||||
);
|
||||
|
||||
await manager.insert(Customer, {
|
||||
id: "test-customer",
|
||||
email: "test@email.com",
|
||||
});
|
||||
|
||||
await manager.insert(Customer, {
|
||||
id: "test-customer-2",
|
||||
email: "test-2@email.com",
|
||||
});
|
||||
|
||||
await manager.insert(Customer, {
|
||||
id: "some-customer",
|
||||
email: "some-customer@email.com",
|
||||
});
|
||||
|
||||
const cart = manager.create(Cart, {
|
||||
id: "test-cart",
|
||||
customer_id: "some-customer",
|
||||
email: "some-customer@email.com",
|
||||
shipping_address: {
|
||||
id: "test-shipping-address",
|
||||
first_name: "lebron",
|
||||
country_code: "us",
|
||||
},
|
||||
region_id: "test-region",
|
||||
currency_code: "usd",
|
||||
items: [],
|
||||
});
|
||||
|
||||
await manager.save(cart);
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
const { Customer, Address } = require("@medusajs/medusa");
|
||||
|
||||
module.exports = async (connection, data = {}) => {
|
||||
const manager = connection.manager;
|
||||
|
||||
await manager.insert(Customer, {
|
||||
id: "test-customer-1",
|
||||
email: "test1@email.com",
|
||||
});
|
||||
|
||||
await manager.insert(Customer, {
|
||||
id: "test-customer-2",
|
||||
email: "test2@email.com",
|
||||
});
|
||||
|
||||
await manager.insert(Customer, {
|
||||
id: "test-customer-3",
|
||||
email: "test3@email.com",
|
||||
});
|
||||
|
||||
await manager.insert(Address, {
|
||||
id: "test-address",
|
||||
first_name: "Lebron",
|
||||
last_name: "James",
|
||||
customer_id: "test-customer-1",
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
const {
|
||||
ShippingProfile,
|
||||
Customer,
|
||||
MoneyAmount,
|
||||
LineItem,
|
||||
Country,
|
||||
ShippingOption,
|
||||
ShippingMethod,
|
||||
Product,
|
||||
ProductOption,
|
||||
ProductVariant,
|
||||
Region,
|
||||
Order,
|
||||
} = require("@medusajs/medusa");
|
||||
|
||||
module.exports = async (connection, data = {}) => {
|
||||
const manager = connection.manager;
|
||||
|
||||
const defaultProfile = await manager.findOne(ShippingProfile, {
|
||||
type: "default",
|
||||
});
|
||||
|
||||
const prodOption = manager.create(ProductOption, {
|
||||
title: "Size",
|
||||
});
|
||||
const newProdOption = await manager.save(prodOption);
|
||||
|
||||
const prod = manager.create(Product, {
|
||||
title: "test product",
|
||||
profile_id: defaultProfile.id,
|
||||
options: [newProdOption],
|
||||
});
|
||||
const newProd = await manager.save(prod);
|
||||
|
||||
const prodVar = manager.create(ProductVariant, {
|
||||
title: "test variant",
|
||||
product_id: newProd.id,
|
||||
inventory_quantity: 1,
|
||||
options: [
|
||||
{
|
||||
option_id: newProdOption.id,
|
||||
value: "Size",
|
||||
},
|
||||
],
|
||||
});
|
||||
const newProdVar = manager.save(prodVar);
|
||||
|
||||
const ma = manager.create(MoneyAmount, {
|
||||
variant_id: newProdVar.id,
|
||||
currency_code: "usd",
|
||||
amount: 8000,
|
||||
});
|
||||
await manager.save(ma);
|
||||
|
||||
const region = manager.create(Region, {
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
const newReg = await manager.save(region);
|
||||
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id='${newReg.id}' WHERE iso_2 = 'us'`
|
||||
);
|
||||
|
||||
const customer = manager.create(Customer, {
|
||||
email: "test@email.com",
|
||||
});
|
||||
const newCustomer = await manager.save(customer);
|
||||
|
||||
const shipOpt = manager.create(ShippingOption, {
|
||||
name: "test-option",
|
||||
provider_id: "test-ful",
|
||||
region_id: newReg.id,
|
||||
profile_id: defaultProfile.id,
|
||||
price_type: "flat_rate",
|
||||
amount: 1000,
|
||||
data: {},
|
||||
});
|
||||
const newShipOpt = await manager.save(shipOpt);
|
||||
|
||||
const order = manager.create(Order, {
|
||||
customer_id: newCustomer.id,
|
||||
email: "test@email.com",
|
||||
billing_address: {
|
||||
first_name: "lebron",
|
||||
},
|
||||
shipping_address: {
|
||||
first_name: "lebron",
|
||||
country_code: "us",
|
||||
},
|
||||
region_id: newReg.id,
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
discounts: [
|
||||
{
|
||||
id: "test-discount",
|
||||
code: "TEST134",
|
||||
is_dynamic: false,
|
||||
rule: {
|
||||
id: "test-rule",
|
||||
description: "Test Discount",
|
||||
type: "percentage",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
},
|
||||
is_disabled: false,
|
||||
regions: [
|
||||
{
|
||||
id: newReg.id,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
payments: [
|
||||
{
|
||||
id: "test-payment",
|
||||
amount: 10000,
|
||||
currency_code: "usd",
|
||||
amount_refunded: 0,
|
||||
provider_id: "test",
|
||||
data: {},
|
||||
},
|
||||
],
|
||||
items: [
|
||||
{
|
||||
id: "test-item",
|
||||
fulfilled_quantity: 1,
|
||||
title: "Line Item",
|
||||
description: "Line Item Desc",
|
||||
thumbnail: "https://test.js/1234",
|
||||
unit_price: 8000,
|
||||
quantity: 1,
|
||||
variant_id: newProdVar.id,
|
||||
},
|
||||
],
|
||||
...data,
|
||||
});
|
||||
|
||||
const newOrder = await manager.save(order);
|
||||
|
||||
const shipMeth = manager.create(ShippingMethod, {
|
||||
order_id: newOrder.id,
|
||||
shipping_option_id: newShipOpt.id,
|
||||
price: 1000,
|
||||
data: {},
|
||||
});
|
||||
|
||||
await manager.save(shipMeth);
|
||||
|
||||
return newOrder;
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
const {
|
||||
ProductCollection,
|
||||
ProductTag,
|
||||
ProductType,
|
||||
Region,
|
||||
Product,
|
||||
ShippingProfile,
|
||||
ProductVariant,
|
||||
} = require("@medusajs/medusa");
|
||||
|
||||
module.exports = async (connection, data = {}) => {
|
||||
const manager = connection.manager;
|
||||
|
||||
const defaultProfile = await manager.findOne(ShippingProfile, {
|
||||
type: "default",
|
||||
});
|
||||
|
||||
const coll = manager.create(ProductCollection, {
|
||||
id: "test-collection",
|
||||
title: "Test collection",
|
||||
});
|
||||
|
||||
await manager.save(coll);
|
||||
|
||||
const tag = manager.create(ProductTag, {
|
||||
id: "tag1",
|
||||
value: "123",
|
||||
});
|
||||
|
||||
await manager.save(tag);
|
||||
|
||||
const type = manager.create(ProductType, {
|
||||
id: "test-type",
|
||||
value: "test-type",
|
||||
});
|
||||
|
||||
await manager.save(type);
|
||||
|
||||
await manager.insert(Region, {
|
||||
id: "test-region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
|
||||
await manager.insert(Product, {
|
||||
id: "test-product",
|
||||
title: "Test product",
|
||||
profile_id: defaultProfile.id,
|
||||
description: "test-product-description",
|
||||
collection_id: "test-collection",
|
||||
type: { id: "test-type", value: "test-type" },
|
||||
tags: [
|
||||
{ id: "tag1", value: "123" },
|
||||
{ tag: "tag2", value: "456" },
|
||||
],
|
||||
options: [{ id: "test-option", title: "Default value" }],
|
||||
});
|
||||
|
||||
await manager.insert(ProductVariant, {
|
||||
id: "test-variant",
|
||||
inventory_quantity: 10,
|
||||
title: "Test variant",
|
||||
product_id: "test-product",
|
||||
prices: [{ id: "test-price", currency_code: "usd", amount: 100 }],
|
||||
options: [{ id: "test-variant-option", value: "Default variant" }],
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
plugins: [],
|
||||
projectConfig: {
|
||||
// redis_url: REDIS_URL,
|
||||
database_url: "postgres://localhost/medusa-fixtures",
|
||||
database_type: "postgres",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "babel src -d dist --extensions \".ts,.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@medusajs/medusa": "^1.1.3",
|
||||
"medusa-interfaces": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.12.10",
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/node": "^7.12.10",
|
||||
"babel-preset-medusa-package": "^1.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
const fixtureWriter = require("./utils/write-fixture").default;
|
||||
const { dropDatabase } = require("pg-god");
|
||||
|
||||
beforeAll(() => {
|
||||
console.log(fixtureWriter);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
console.log(fixtureWriter);
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
await fixtureWriter.execute();
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { FulfillmentService } from "medusa-interfaces";
|
||||
|
||||
class TestFulService extends FulfillmentService {
|
||||
static identifier = "test-ful";
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
getFulfillmentOptions() {
|
||||
return [
|
||||
{
|
||||
id: "manual-fulfillment",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
validateFulfillmentData(data, cart) {
|
||||
return data;
|
||||
}
|
||||
|
||||
validateOption(data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
canCalculate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
calculatePrice() {
|
||||
throw Error("Manual Fulfillment service cannot calculatePrice");
|
||||
}
|
||||
|
||||
createOrder() {
|
||||
// No data is being sent anywhere
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
createFulfillment() {
|
||||
// No data is being sent anywhere
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
cancelFulfillment() {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
}
|
||||
|
||||
export default TestFulService;
|
||||
@@ -0,0 +1,19 @@
|
||||
import { NotificationService } from "medusa-interfaces";
|
||||
|
||||
class TestNotiService extends NotificationService {
|
||||
static identifier = "test-not";
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async sendNotification() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async resendNotification() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
export default TestNotiService;
|
||||
@@ -0,0 +1,59 @@
|
||||
import { PaymentService } from "medusa-interfaces";
|
||||
|
||||
class TestPayService extends PaymentService {
|
||||
static identifier = "test-pay";
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async getStatus(paymentData) {
|
||||
return "authorized";
|
||||
}
|
||||
|
||||
async retrieveSavedMethods(customer) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
async createPayment() {
|
||||
return {};
|
||||
}
|
||||
|
||||
async retrievePayment(data) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async getPaymentData(sessionData) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async authorizePayment(sessionData, context = {}) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async updatePaymentData(sessionData, update) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async updatePayment(sessionData, cart) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async deletePayment(payment) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async capturePayment(payment) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async refundPayment(payment, amountToRefund) {
|
||||
return {};
|
||||
}
|
||||
|
||||
async cancelPayment(payment) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export default TestPayService;
|
||||
@@ -0,0 +1,30 @@
|
||||
const fs = require("fs").promises;
|
||||
const path = require("path");
|
||||
|
||||
class FixtureWriter {
|
||||
constructor() {
|
||||
const resolvedPath = path.resolve("./docs/api/fixtures.json");
|
||||
const existing = require(resolvedPath);
|
||||
|
||||
this.toWrite_ = existing.resources;
|
||||
this.resolvedPath_ = resolvedPath;
|
||||
}
|
||||
|
||||
addFixture(key, data) {
|
||||
this.toWrite_ = {
|
||||
...this.toWrite_,
|
||||
[key]: data,
|
||||
};
|
||||
}
|
||||
|
||||
async execute() {
|
||||
const toSet = {
|
||||
resources: this.toWrite_,
|
||||
};
|
||||
const s = JSON.stringify(toSet, null, 2);
|
||||
return await fs.writeFile(this.resolvedPath_, s);
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new FixtureWriter();
|
||||
export default instance;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
const path = require("path");
|
||||
const { spawn } = require("child_process");
|
||||
|
||||
const { setPort } = require("./use-api");
|
||||
|
||||
module.exports = ({ cwd }) => {
|
||||
const serverPath = path.join(__dirname, "test-server.js");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const medusaProcess = spawn("node", [path.resolve(serverPath)], {
|
||||
cwd,
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_ENV: "development",
|
||||
JWT_SECRET: "test",
|
||||
COOKIE_SECRET: "test",
|
||||
},
|
||||
stdio: ["ignore", "ignore", "inherit", "ipc"],
|
||||
});
|
||||
|
||||
medusaProcess.on("uncaughtException", (err) => {
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
medusaProcess.on("message", (port) => {
|
||||
setPort(port);
|
||||
resolve(medusaProcess);
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
const path = require("path");
|
||||
const express = require("express");
|
||||
const getPort = require("get-port");
|
||||
|
||||
const loaders = require("@medusajs/medusa/dist/loaders").default;
|
||||
|
||||
const initialize = async () => {
|
||||
const app = express();
|
||||
|
||||
const { dbConnection } = await loaders({
|
||||
directory: path.resolve(process.cwd()),
|
||||
expressApp: app,
|
||||
});
|
||||
|
||||
const PORT = await getPort();
|
||||
|
||||
return {
|
||||
db: dbConnection,
|
||||
app,
|
||||
port: PORT,
|
||||
};
|
||||
};
|
||||
|
||||
const setup = async () => {
|
||||
const { app, port } = await initialize();
|
||||
|
||||
app.listen(port, (err) => {
|
||||
process.send(port);
|
||||
});
|
||||
};
|
||||
|
||||
setup();
|
||||
@@ -0,0 +1,21 @@
|
||||
const axios = require("axios").default;
|
||||
|
||||
const ServerTestUtil = {
|
||||
port_: null,
|
||||
client_: null,
|
||||
|
||||
setPort: function (port) {
|
||||
this.client_ = axios.create({ baseURL: `http://localhost:${port}` });
|
||||
},
|
||||
};
|
||||
|
||||
const instance = ServerTestUtil;
|
||||
|
||||
module.exports = {
|
||||
setPort: function (port) {
|
||||
instance.setPort(port);
|
||||
},
|
||||
useApi: function () {
|
||||
return instance.client_;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
const { dropDatabase, createDatabase } = require("pg-god");
|
||||
const { createConnection } = require("typeorm");
|
||||
|
||||
const path = require("path");
|
||||
|
||||
const DbTestUtil = {
|
||||
db_: null,
|
||||
|
||||
setDb: function (connection) {
|
||||
this.db_ = connection;
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
return this.db_.synchronize(true);
|
||||
},
|
||||
|
||||
shutdown: async function () {
|
||||
await this.db_.close();
|
||||
return dropDatabase({ databaseName });
|
||||
},
|
||||
};
|
||||
|
||||
const instance = DbTestUtil;
|
||||
|
||||
module.exports = {
|
||||
initDb: async function ({ cwd }) {
|
||||
const migrationDir = path.resolve(
|
||||
path.join(
|
||||
cwd,
|
||||
`node_modules`,
|
||||
`@medusajs`,
|
||||
`medusa`,
|
||||
`dist`,
|
||||
`migrations`
|
||||
)
|
||||
);
|
||||
|
||||
const databaseName = "medusa-fixtures";
|
||||
await createDatabase({ databaseName });
|
||||
|
||||
const connection = await createConnection({
|
||||
type: "postgres",
|
||||
url: "postgres://localhost/medusa-fixtures",
|
||||
migrations: [`${migrationDir}/*.js`],
|
||||
});
|
||||
|
||||
await connection.runMigrations();
|
||||
await connection.close();
|
||||
|
||||
const modelsLoader = require(path.join(
|
||||
cwd,
|
||||
`node_modules`,
|
||||
`@medusajs`,
|
||||
`medusa`,
|
||||
`dist`,
|
||||
`loaders`,
|
||||
`models`
|
||||
)).default;
|
||||
|
||||
const entities = modelsLoader({}, { register: false });
|
||||
const dbConnection = await createConnection({
|
||||
type: "postgres",
|
||||
url: "postgres://localhost/medusa-fixtures",
|
||||
entities,
|
||||
});
|
||||
|
||||
instance.setDb(dbConnection);
|
||||
return dbConnection;
|
||||
},
|
||||
useDb: function () {
|
||||
return instance;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
const ServerTestUtil = {
|
||||
server_: null,
|
||||
app_: null,
|
||||
|
||||
setApp: function (app) {
|
||||
this.app_ = app;
|
||||
},
|
||||
|
||||
start: async function () {
|
||||
this.server_ = await new Promise((resolve, reject) => {
|
||||
const s = this.app_.listen(PORT, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
resolve(s);
|
||||
});
|
||||
},
|
||||
|
||||
kill: function () {
|
||||
return new Promise((resolve, _) => {
|
||||
if (this.server_) {
|
||||
this.server_.close(() => resolve());
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const instance = ServerTestUtil;
|
||||
|
||||
module.exports = {
|
||||
setApp: function (app) {
|
||||
instance.setApp(app);
|
||||
return instance;
|
||||
},
|
||||
|
||||
useServer: function () {
|
||||
return instance;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
const glob = require(`glob`);
|
||||
|
||||
const pkgs = glob
|
||||
.sync(`${__dirname}/*/`)
|
||||
.map((p) => p.replace(__dirname, `<rootDir>/docs-util`));
|
||||
|
||||
module.exports = {
|
||||
testEnvironment: `node`,
|
||||
rootDir: `../`,
|
||||
roots: pkgs,
|
||||
testPathIgnorePatterns: [
|
||||
`/examples/`,
|
||||
`/www/`,
|
||||
`/dist/`,
|
||||
`/node_modules/`,
|
||||
`__tests__/fixtures`,
|
||||
`__testfixtures__`,
|
||||
`.cache`,
|
||||
],
|
||||
transform: { "^.+\\.[jt]s$": `<rootDir>/jest-transformer.js` },
|
||||
setupFilesAfterEnv: ["<rootDir>/docs-util/setup.js"],
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
const fixtureWriter = require("./fixture-gen/utils/write-fixture").default;
|
||||
const { dropDatabase } = require("pg-god");
|
||||
|
||||
afterAll(async () => {
|
||||
await dropDatabase({ databaseName: "medusa-fixtures" });
|
||||
await fixtureWriter.execute();
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "Medusa Admin API",
|
||||
"license": {
|
||||
"name": "MIT"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Auth",
|
||||
"description": "Auth endpoints allows authorization of admin Users and manages their sessions."
|
||||
},
|
||||
{
|
||||
"name": "Collection",
|
||||
"x-resourceId": "product_collection"
|
||||
},
|
||||
{
|
||||
"name": "Customer",
|
||||
"x-resourceId": "customer"
|
||||
},
|
||||
{
|
||||
"name": "Discount",
|
||||
"x-resourceId": "discount"
|
||||
},
|
||||
{
|
||||
"name": "Gift Card",
|
||||
"x-resourceId": "gift_card"
|
||||
},
|
||||
{
|
||||
"name": "Notification",
|
||||
"x-resourceId": "notification"
|
||||
},
|
||||
{
|
||||
"name": "Order",
|
||||
"x-resourceId": "order"
|
||||
},
|
||||
{
|
||||
"name": "Product",
|
||||
"x-resourceId": "product"
|
||||
},
|
||||
{
|
||||
"name": "Region",
|
||||
"x-resourceId": "region"
|
||||
},
|
||||
{
|
||||
"name": "Return",
|
||||
"x-resourceId": "return"
|
||||
},
|
||||
{
|
||||
"name": "Shipping Option",
|
||||
"x-resourceId": "shipping_option"
|
||||
},
|
||||
{
|
||||
"name": "Shipping Profile",
|
||||
"x-resourceId": "shipping_profile"
|
||||
},
|
||||
{
|
||||
"name": "Swap",
|
||||
"x-resourceId": "swap"
|
||||
},
|
||||
{
|
||||
"name": "Product Variant",
|
||||
"x-resourceId": "product_variant"
|
||||
}
|
||||
],
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://api.medusa-commerce.com/admin"
|
||||
}
|
||||
],
|
||||
"paths": {}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,735 @@
|
||||
{
|
||||
"resources": {
|
||||
"customer": {
|
||||
"id": "cus_01F0BGFY6ANPB473KJ5H8V889M",
|
||||
"email": "test1@email.com",
|
||||
"first_name": null,
|
||||
"last_name": null,
|
||||
"billing_address_id": null,
|
||||
"password_hash": null,
|
||||
"phone": null,
|
||||
"has_account": false,
|
||||
"orders": [],
|
||||
"created_at": "2021-03-09T12:48:21.706Z",
|
||||
"updated_at": "2021-03-09T12:48:21.706Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"order": {
|
||||
"id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
|
||||
"status": "pending",
|
||||
"fulfillment_status": "not_fulfilled",
|
||||
"payment_status": "not_paid",
|
||||
"display_id": 1,
|
||||
"cart_id": null,
|
||||
"customer_id": "cus_01F0BGFG280DRD18VXM1F9GJXA",
|
||||
"customer": {
|
||||
"id": "cus_01F0BGFG280DRD18VXM1F9GJXA",
|
||||
"email": "test@email.com",
|
||||
"first_name": null,
|
||||
"last_name": null,
|
||||
"billing_address_id": null,
|
||||
"password_hash": null,
|
||||
"phone": null,
|
||||
"has_account": false,
|
||||
"created_at": "2021-03-09T12:48:07.240Z",
|
||||
"updated_at": "2021-03-09T12:48:07.240Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"email": "test@email.com",
|
||||
"billing_address": {
|
||||
"id": "addr_01F0BGFG30PG1NP6V0EDJDF6PW",
|
||||
"customer_id": null,
|
||||
"company": null,
|
||||
"first_name": "lebron",
|
||||
"last_name": null,
|
||||
"address_1": null,
|
||||
"address_2": null,
|
||||
"city": null,
|
||||
"country_code": null,
|
||||
"province": null,
|
||||
"postal_code": null,
|
||||
"phone": null,
|
||||
"created_at": "2021-03-09T12:48:07.263Z",
|
||||
"updated_at": "2021-03-09T12:48:07.263Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"shipping_address": {
|
||||
"id": "addr_01F0BGFG30EBKX6C89N35YB2PX",
|
||||
"customer_id": null,
|
||||
"company": null,
|
||||
"first_name": "lebron",
|
||||
"last_name": null,
|
||||
"address_1": null,
|
||||
"address_2": null,
|
||||
"city": null,
|
||||
"country_code": "us",
|
||||
"province": null,
|
||||
"postal_code": null,
|
||||
"phone": null,
|
||||
"created_at": "2021-03-09T12:48:07.263Z",
|
||||
"updated_at": "2021-03-09T12:48:07.263Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"region_id": "reg_01F0BGFG21NC3VQ662FYNF3P4Z",
|
||||
"region": {
|
||||
"id": "reg_01F0BGFG21NC3VQ662FYNF3P4Z",
|
||||
"name": "Test Region",
|
||||
"currency_code": "usd",
|
||||
"tax_rate": "0",
|
||||
"tax_code": null,
|
||||
"payment_providers": [],
|
||||
"fulfillment_providers": [],
|
||||
"created_at": "2021-03-09T12:48:07.233Z",
|
||||
"updated_at": "2021-03-09T12:48:07.233Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"currency_code": "usd",
|
||||
"tax_rate": 0,
|
||||
"discounts": [
|
||||
{
|
||||
"id": "test-discount",
|
||||
"code": "TEST134",
|
||||
"is_dynamic": false,
|
||||
"rule_id": "dru_01F0BGFG30S3FSBE67PKDCTT0Y",
|
||||
"rule": {
|
||||
"id": "dru_01F0BGFG30S3FSBE67PKDCTT0Y",
|
||||
"description": "Test Discount",
|
||||
"type": "percentage",
|
||||
"value": 10,
|
||||
"allocation": "total",
|
||||
"usage_limit": null,
|
||||
"created_at": "2021-03-09T12:48:07.263Z",
|
||||
"updated_at": "2021-03-09T12:48:07.263Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"is_disabled": false,
|
||||
"parent_discount_id": null,
|
||||
"starts_at": "2021-03-09T12:48:07.263Z",
|
||||
"ends_at": null,
|
||||
"created_at": "2021-03-09T12:48:07.263Z",
|
||||
"updated_at": "2021-03-09T12:48:07.263Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
}
|
||||
],
|
||||
"gift_cards": [],
|
||||
"shipping_methods": [
|
||||
{
|
||||
"id": "sm_01F0BGFG3SQZC01D8JP4REY0RF",
|
||||
"shipping_option_id": "so_01F0BGFG2DV0GR6VD87AQ7XAB2",
|
||||
"order_id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
|
||||
"claim_order_id": null,
|
||||
"cart_id": null,
|
||||
"swap_id": null,
|
||||
"return_id": null,
|
||||
"shipping_option": {
|
||||
"id": "so_01F0BGFG2DV0GR6VD87AQ7XAB2",
|
||||
"name": "test-option",
|
||||
"region_id": "reg_01F0BGFG21NC3VQ662FYNF3P4Z",
|
||||
"profile_id": "sp_01F0BGFG04GKTA9FTYWBT19NKJ",
|
||||
"provider_id": "test-ful",
|
||||
"price_type": "flat_rate",
|
||||
"amount": 1000,
|
||||
"is_return": false,
|
||||
"data": {},
|
||||
"created_at": "2021-03-09T12:48:07.245Z",
|
||||
"updated_at": "2021-03-09T12:48:07.245Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"price": 1000,
|
||||
"data": {}
|
||||
}
|
||||
],
|
||||
"payments": [
|
||||
{
|
||||
"id": "test-payment",
|
||||
"swap_id": null,
|
||||
"cart_id": null,
|
||||
"order_id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
|
||||
"amount": 10000,
|
||||
"currency_code": "usd",
|
||||
"amount_refunded": 0,
|
||||
"provider_id": "test",
|
||||
"data": {},
|
||||
"captured_at": null,
|
||||
"canceled_at": null,
|
||||
"created_at": "2021-03-09T12:48:07.263Z",
|
||||
"updated_at": "2021-03-09T12:48:07.263Z",
|
||||
"metadata": null,
|
||||
"idempotency_key": null
|
||||
}
|
||||
],
|
||||
"fulfillments": [],
|
||||
"returns": [],
|
||||
"claims": [],
|
||||
"refunds": [],
|
||||
"swaps": [],
|
||||
"items": [
|
||||
{
|
||||
"id": "test-item",
|
||||
"cart_id": null,
|
||||
"order_id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
|
||||
"swap_id": null,
|
||||
"claim_order_id": null,
|
||||
"title": "Line Item",
|
||||
"description": "Line Item Desc",
|
||||
"thumbnail": "https://test.js/1234",
|
||||
"is_giftcard": false,
|
||||
"should_merge": true,
|
||||
"allow_discounts": true,
|
||||
"has_shipping": null,
|
||||
"unit_price": 8000,
|
||||
"variant_id": null,
|
||||
"variant": null,
|
||||
"quantity": 1,
|
||||
"fulfilled_quantity": 1,
|
||||
"returned_quantity": null,
|
||||
"shipped_quantity": null,
|
||||
"created_at": "2021-03-09T12:48:07.263Z",
|
||||
"updated_at": "2021-03-09T12:48:07.263Z",
|
||||
"metadata": null,
|
||||
"refundable": 7200
|
||||
}
|
||||
],
|
||||
"gift_card_transactions": [],
|
||||
"canceled_at": null,
|
||||
"created_at": "2021-03-09T12:48:07.263Z",
|
||||
"updated_at": "2021-03-09T12:48:07.263Z",
|
||||
"metadata": null,
|
||||
"shipping_total": 1000,
|
||||
"gift_card_total": 0,
|
||||
"discount_total": 800,
|
||||
"tax_total": 0,
|
||||
"subtotal": 8000,
|
||||
"total": 8200,
|
||||
"refunded_total": 0,
|
||||
"refundable_amount": 8200
|
||||
},
|
||||
"product": {
|
||||
"id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"title": "Test product",
|
||||
"subtitle": null,
|
||||
"description": "test-product-description",
|
||||
"handle": "test-product",
|
||||
"is_giftcard": false,
|
||||
"images": [],
|
||||
"thumbnail": null,
|
||||
"options": [
|
||||
{
|
||||
"id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
|
||||
"title": "size",
|
||||
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
{
|
||||
"id": "opt_01F0BGG4N3Q09ME0BEZG6XZGFQ",
|
||||
"title": "color",
|
||||
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
}
|
||||
],
|
||||
"variants": [
|
||||
{
|
||||
"id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"title": "Test variant",
|
||||
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"product": {
|
||||
"id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"title": "Test product",
|
||||
"subtitle": null,
|
||||
"description": "test-product-description",
|
||||
"handle": "test-product",
|
||||
"is_giftcard": false,
|
||||
"thumbnail": null,
|
||||
"profile_id": "sp_01F0BGG4J2RGH25WZVP8S6VNGW",
|
||||
"weight": null,
|
||||
"length": null,
|
||||
"height": null,
|
||||
"width": null,
|
||||
"hs_code": null,
|
||||
"origin_country": null,
|
||||
"mid_code": null,
|
||||
"material": null,
|
||||
"collection_id": "test-collection",
|
||||
"type_id": "test-type",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"prices": [
|
||||
{
|
||||
"id": "ma_01F0BGG4P5K0TCMD72MJFS0M65",
|
||||
"currency_code": "usd",
|
||||
"amount": 100,
|
||||
"sale_amount": null,
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"region_id": null,
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null
|
||||
}
|
||||
],
|
||||
"sku": null,
|
||||
"barcode": null,
|
||||
"ean": null,
|
||||
"upc": null,
|
||||
"inventory_quantity": 10,
|
||||
"allow_backorder": false,
|
||||
"manage_inventory": true,
|
||||
"hs_code": null,
|
||||
"origin_country": null,
|
||||
"mid_code": null,
|
||||
"material": null,
|
||||
"weight": null,
|
||||
"length": null,
|
||||
"height": null,
|
||||
"width": null,
|
||||
"options": [
|
||||
{
|
||||
"id": "optval_01F0BGG4NY1PRPV3FXQ3J66GQH",
|
||||
"value": "large",
|
||||
"option_id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
{
|
||||
"id": "optval_01F0BGG4NYTMFH5EXJ4C7QAKSK",
|
||||
"value": "green",
|
||||
"option_id": "opt_01F0BGG4N3Q09ME0BEZG6XZGFQ",
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
}
|
||||
],
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
}
|
||||
],
|
||||
"profile_id": "sp_01F0BGG4J2RGH25WZVP8S6VNGW",
|
||||
"weight": null,
|
||||
"length": null,
|
||||
"height": null,
|
||||
"width": null,
|
||||
"hs_code": null,
|
||||
"origin_country": null,
|
||||
"mid_code": null,
|
||||
"material": null,
|
||||
"collection_id": "test-collection",
|
||||
"collection": {
|
||||
"id": "test-collection",
|
||||
"title": "Test collection",
|
||||
"handle": null,
|
||||
"created_at": "2021-03-09T12:48:28.250Z",
|
||||
"updated_at": "2021-03-09T12:48:28.250Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"type_id": "test-type",
|
||||
"type": {
|
||||
"id": "test-type",
|
||||
"value": "test-type",
|
||||
"created_at": "2021-03-09T12:48:28.260Z",
|
||||
"updated_at": "2021-03-09T12:48:28.260Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"id": "tag1",
|
||||
"value": "123",
|
||||
"created_at": "2021-03-09T12:48:28.257Z",
|
||||
"updated_at": "2021-03-09T12:48:28.257Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
{
|
||||
"id": "ptag_01F0BGG4MRHZSMYN9Q1YQZHPWT",
|
||||
"value": "456",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
}
|
||||
],
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"metadata": null
|
||||
},
|
||||
"cart": {
|
||||
"id": "cart_01F0BGFQA6ETNHS7QGEZD9VTF2",
|
||||
"email": null,
|
||||
"billing_address_id": null,
|
||||
"billing_address": null,
|
||||
"shipping_address_id": "addr_01F0BGFQA6YF81V6CREDHNCZMZ",
|
||||
"shipping_address": {
|
||||
"id": "addr_01F0BGFQA6YF81V6CREDHNCZMZ",
|
||||
"customer_id": null,
|
||||
"company": null,
|
||||
"first_name": null,
|
||||
"last_name": null,
|
||||
"address_1": null,
|
||||
"address_2": null,
|
||||
"city": null,
|
||||
"country_code": "us",
|
||||
"province": null,
|
||||
"postal_code": null,
|
||||
"phone": null,
|
||||
"created_at": "2021-03-09T12:48:14.638Z",
|
||||
"updated_at": "2021-03-09T12:48:14.638Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"items": [],
|
||||
"region_id": "region",
|
||||
"region": {
|
||||
"id": "region",
|
||||
"name": "Test Region",
|
||||
"currency_code": "usd",
|
||||
"tax_rate": "0",
|
||||
"tax_code": null,
|
||||
"countries": [
|
||||
{
|
||||
"id": 236,
|
||||
"iso_2": "us",
|
||||
"iso_3": "usa",
|
||||
"num_code": 840,
|
||||
"name": "UNITED STATES",
|
||||
"display_name": "United States",
|
||||
"region_id": "region"
|
||||
}
|
||||
],
|
||||
"payment_providers": [],
|
||||
"fulfillment_providers": [],
|
||||
"created_at": "2021-03-09T12:48:14.601Z",
|
||||
"updated_at": "2021-03-09T12:48:14.601Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"discounts": [],
|
||||
"gift_cards": [],
|
||||
"customer_id": null,
|
||||
"payment_sessions": [],
|
||||
"payment_id": null,
|
||||
"payment": null,
|
||||
"shipping_methods": [],
|
||||
"type": "default",
|
||||
"completed_at": null,
|
||||
"created_at": "2021-03-09T12:48:14.638Z",
|
||||
"updated_at": "2021-03-09T12:48:14.777Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null,
|
||||
"idempotency_key": null,
|
||||
"shipping_total": 0,
|
||||
"discount_total": 0,
|
||||
"tax_total": 0,
|
||||
"gift_card_total": 0,
|
||||
"subtotal": 0,
|
||||
"total": 0
|
||||
},
|
||||
"product_collection": {
|
||||
"id": "pcol_01F0BGG81W0FERCAHMR79J72G8",
|
||||
"title": "Summer Collection",
|
||||
"handle": "summer-collection",
|
||||
"created_at": "2021-03-09T12:48:31.804Z",
|
||||
"updated_at": "2021-03-09T12:48:31.804Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"discount": {
|
||||
"id": "disc_01F0BGG1BJH91HJ7J9Q0NR0BR6",
|
||||
"code": "10DISC",
|
||||
"is_dynamic": false,
|
||||
"rule_id": "dru_01F0BGG1B3BCZ292BSRRK72JGS",
|
||||
"rule": {
|
||||
"id": "dru_01F0BGG1B3BCZ292BSRRK72JGS",
|
||||
"description": "10 Percent",
|
||||
"type": "percentage",
|
||||
"value": 10,
|
||||
"allocation": "total",
|
||||
"usage_limit": null,
|
||||
"created_at": "2021-03-09T12:48:24.921Z",
|
||||
"updated_at": "2021-03-09T12:48:24.921Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"is_disabled": false,
|
||||
"parent_discount_id": null,
|
||||
"starts_at": "2021-03-09T12:48:24.921Z",
|
||||
"ends_at": null,
|
||||
"created_at": "2021-03-09T12:48:24.921Z",
|
||||
"updated_at": "2021-03-09T12:48:24.921Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"product_variant": {
|
||||
"id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"title": "Test variant",
|
||||
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"product": {
|
||||
"id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"title": "Test product",
|
||||
"subtitle": null,
|
||||
"description": "test-product-description",
|
||||
"handle": "test-product",
|
||||
"is_giftcard": false,
|
||||
"thumbnail": null,
|
||||
"profile_id": "sp_01F0BGG4J2RGH25WZVP8S6VNGW",
|
||||
"weight": null,
|
||||
"length": null,
|
||||
"height": null,
|
||||
"width": null,
|
||||
"hs_code": null,
|
||||
"origin_country": null,
|
||||
"mid_code": null,
|
||||
"material": null,
|
||||
"collection_id": "test-collection",
|
||||
"type_id": "test-type",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"prices": [
|
||||
{
|
||||
"id": "ma_01F0BGG4P5K0TCMD72MJFS0M65",
|
||||
"currency_code": "usd",
|
||||
"amount": 100,
|
||||
"sale_amount": null,
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"region_id": null,
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null
|
||||
}
|
||||
],
|
||||
"sku": null,
|
||||
"barcode": null,
|
||||
"ean": null,
|
||||
"upc": null,
|
||||
"inventory_quantity": 10,
|
||||
"allow_backorder": false,
|
||||
"manage_inventory": true,
|
||||
"hs_code": null,
|
||||
"origin_country": null,
|
||||
"mid_code": null,
|
||||
"material": null,
|
||||
"weight": null,
|
||||
"length": null,
|
||||
"height": null,
|
||||
"width": null,
|
||||
"options": [
|
||||
{
|
||||
"id": "optval_01F0BGG4NY1PRPV3FXQ3J66GQH",
|
||||
"value": "large",
|
||||
"option_id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
{
|
||||
"id": "optval_01F0BGG4NYTMFH5EXJ4C7QAKSK",
|
||||
"value": "green",
|
||||
"option_id": "opt_01F0BGG4N3Q09ME0BEZG6XZGFQ",
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
}
|
||||
],
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"product_option": {
|
||||
"id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
|
||||
"title": "size",
|
||||
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"product_option_value": {
|
||||
"id": "optval_01F0BGG4NY1PRPV3FXQ3J66GQH",
|
||||
"value": "large",
|
||||
"option_id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"money_amount": {
|
||||
"id": "ma_01F0BGG4P5K0TCMD72MJFS0M65",
|
||||
"currency_code": "usd",
|
||||
"amount": 100,
|
||||
"sale_amount": null,
|
||||
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
|
||||
"region_id": null,
|
||||
"created_at": "2021-03-09T12:48:28.304Z",
|
||||
"updated_at": "2021-03-09T12:48:28.304Z",
|
||||
"deleted_at": null
|
||||
},
|
||||
"gift_card": {
|
||||
"id": "gift_01F0BF6H3XHRT2SF4Y05AM95B9",
|
||||
"code": "HRYB-SMX4-XXQN-2SRL",
|
||||
"value": 1000,
|
||||
"balance": 1000,
|
||||
"region_id": "reg_01F0BF6H2MZ06R2G2ZGZCAX3NS",
|
||||
"region": {
|
||||
"id": "reg_01F0BF6H2MZ06R2G2ZGZCAX3NS",
|
||||
"name": "Test Region",
|
||||
"currency_code": "usd",
|
||||
"tax_rate": "0",
|
||||
"tax_code": null,
|
||||
"payment_providers": [],
|
||||
"fulfillment_providers": [],
|
||||
"created_at": "2021-03-09T12:25:44.788Z",
|
||||
"updated_at": "2021-03-09T12:25:44.788Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"is_disabled": false,
|
||||
"ends_at": null,
|
||||
"created_at": "2021-03-09T12:25:44.818Z",
|
||||
"updated_at": "2021-03-09T12:25:44.818Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"shipping_option": {
|
||||
"id": "so_01F0BGFTXZ6V3GAJHBKHNTR54H",
|
||||
"name": "Free Shipping",
|
||||
"region_id": "reg_01F0BGFTW7J0DGWKJJP3X7AWP9",
|
||||
"region": {
|
||||
"id": "reg_01F0BGFTW7J0DGWKJJP3X7AWP9",
|
||||
"name": "Test Region",
|
||||
"currency_code": "usd",
|
||||
"tax_rate": "0",
|
||||
"tax_code": null,
|
||||
"payment_providers": [],
|
||||
"fulfillment_providers": [
|
||||
{
|
||||
"id": "test-ful",
|
||||
"is_installed": true
|
||||
}
|
||||
],
|
||||
"created_at": "2021-03-09T12:48:18.311Z",
|
||||
"updated_at": "2021-03-09T12:48:18.311Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"profile_id": "sp_01F0BGFTVGXRBATSDBZN5SK2JP",
|
||||
"profile": {
|
||||
"id": "sp_01F0BGFTVGXRBATSDBZN5SK2JP",
|
||||
"name": "Default Shipping Profile",
|
||||
"type": "default",
|
||||
"created_at": "2021-03-09T12:48:18.240Z",
|
||||
"updated_at": "2021-03-09T12:48:18.240Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"provider_id": "test-ful",
|
||||
"price_type": "flat_rate",
|
||||
"amount": 100,
|
||||
"is_return": false,
|
||||
"requirements": [],
|
||||
"data": {},
|
||||
"created_at": "2021-03-09T12:48:18.354Z",
|
||||
"updated_at": "2021-03-09T12:48:18.354Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"region": {
|
||||
"id": "reg_01F0BGFTW7J0DGWKJJP3X7AWP9",
|
||||
"name": "Test Region",
|
||||
"currency_code": "usd",
|
||||
"tax_rate": "0",
|
||||
"tax_code": null,
|
||||
"payment_providers": [],
|
||||
"fulfillment_providers": [
|
||||
{
|
||||
"id": "test-ful",
|
||||
"is_installed": true
|
||||
}
|
||||
],
|
||||
"created_at": "2021-03-09T12:48:18.311Z",
|
||||
"updated_at": "2021-03-09T12:48:18.311Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
},
|
||||
"return": {
|
||||
"id": "ret_01F0BGFGGVWNV93E789K1DB2QK",
|
||||
"status": "requested",
|
||||
"items": [
|
||||
{
|
||||
"return_id": "ret_01F0BGFGGVWNV93E789K1DB2QK",
|
||||
"item_id": "test-item",
|
||||
"quantity": 1,
|
||||
"is_requested": true,
|
||||
"requested_quantity": 1,
|
||||
"received_quantity": null,
|
||||
"metadata": null
|
||||
}
|
||||
],
|
||||
"swap_id": null,
|
||||
"claim_order_id": null,
|
||||
"order_id": "order_01F0BGFGBMCTXE6CD7KCTZG5D1",
|
||||
"shipping_method": null,
|
||||
"shipping_data": null,
|
||||
"refund_amount": 7200,
|
||||
"received_at": null,
|
||||
"created_at": "2021-03-09T12:48:07.680Z",
|
||||
"updated_at": "2021-03-09T12:48:07.680Z",
|
||||
"metadata": null,
|
||||
"idempotency_key": "abb55222-1d22-4852-9714-9b63baec3633"
|
||||
},
|
||||
"notification": {
|
||||
"id": "noti_01F0BGFKZ7P3NC5V1PG10S75N0",
|
||||
"resource_type": "order",
|
||||
"resource_id": "order_01F0BF66ZBXNJ98WDQ9SCWH8Y7",
|
||||
"event_name": "order.placed",
|
||||
"to": "test@email.com",
|
||||
"provider_id": "test-not",
|
||||
"created_at": "2021-03-09T12:48:11.238Z",
|
||||
"updated_at": "2021-03-09T12:48:11.238Z",
|
||||
"resends": []
|
||||
},
|
||||
"discount_rule": {
|
||||
"id": "dru_01F0BGG1B3BCZ292BSRRK72JGS",
|
||||
"description": "10 Percent",
|
||||
"type": "percentage",
|
||||
"value": 10,
|
||||
"allocation": "total",
|
||||
"usage_limit": null,
|
||||
"created_at": "2021-03-09T12:48:24.921Z",
|
||||
"updated_at": "2021-03-09T12:48:24.921Z",
|
||||
"deleted_at": null,
|
||||
"metadata": null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "Medusa Storefront API",
|
||||
"license": {
|
||||
"name": "MIT"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Auth",
|
||||
"description": "Auth endpoints allows authorization of admin Users and manages their sessions."
|
||||
},
|
||||
{
|
||||
"name": "Cart",
|
||||
"x-resourceId": "cart"
|
||||
},
|
||||
{
|
||||
"name": "Collection",
|
||||
"x-resourceId": "product_collection"
|
||||
},
|
||||
{
|
||||
"name": "Customer",
|
||||
"x-resourceId": "customer"
|
||||
},
|
||||
{
|
||||
"name": "Discount",
|
||||
"x-resourceId": "discount"
|
||||
},
|
||||
{
|
||||
"name": "Gift Card",
|
||||
"x-resourceId": "gift_card"
|
||||
},
|
||||
{
|
||||
"name": "Notification",
|
||||
"x-resourceId": "notification"
|
||||
},
|
||||
{
|
||||
"name": "Order",
|
||||
"x-resourceId": "order"
|
||||
},
|
||||
{
|
||||
"name": "Product",
|
||||
"x-resourceId": "product"
|
||||
},
|
||||
{
|
||||
"name": "Region",
|
||||
"x-resourceId": "region"
|
||||
},
|
||||
{
|
||||
"name": "Return",
|
||||
"x-resourceId": "return"
|
||||
},
|
||||
{
|
||||
"name": "Shipping Option",
|
||||
"x-resourceId": "shipping_option"
|
||||
},
|
||||
{
|
||||
"name": "Shipping Profile",
|
||||
"x-resourceId": "shipping_profile"
|
||||
},
|
||||
{
|
||||
"name": "Swap",
|
||||
"x-resourceId": "swap"
|
||||
},
|
||||
{
|
||||
"name": "Product Variant",
|
||||
"x-resourceId": "product_variant"
|
||||
}
|
||||
],
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://api.medusa-commerce.com/store"
|
||||
}
|
||||
],
|
||||
"paths": {}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,79 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const { Region } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
const adminSeeder = require("../../helpers/admin-seeder");
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/admin/gift-cards", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-integration" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /admin/gift-cards", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
try {
|
||||
await adminSeeder(dbConnection);
|
||||
await manager.insert(Region, {
|
||||
id: "region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "gift_card"`);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("creates a gift card", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.post(
|
||||
"/admin/gift-cards",
|
||||
{
|
||||
value: 1000,
|
||||
region_id: "region",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.gift_card.value).toEqual(1000);
|
||||
expect(response.data.gift_card.balance).toEqual(1000);
|
||||
expect(response.data.gift_card.region_id).toEqual("region");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -151,30 +151,29 @@ describe("/admin/orders", () => {
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
expect(response.data.order.claims[0].claim_items).toEqual([
|
||||
expect.objectContaining({
|
||||
item_id: "test-item",
|
||||
quantity: 1,
|
||||
reason: "production_failure",
|
||||
images: [
|
||||
expect.objectContaining({
|
||||
url: "https://test.image.com",
|
||||
}),
|
||||
],
|
||||
tags: [
|
||||
expect.objectContaining({
|
||||
value: "fluff",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
]);
|
||||
expect(response.data.order.claims[0].claim_items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
item_id: "test-item",
|
||||
quantity: 1,
|
||||
reason: "production_failure",
|
||||
images: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
url: "https://test.image.com",
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
expect(response.data.order.claims[0].additional_items).toEqual([
|
||||
expect.objectContaining({
|
||||
variant_id: "test-variant",
|
||||
quantity: 1,
|
||||
}),
|
||||
]);
|
||||
expect(response.data.order.claims[0].additional_items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
variant_id: "test-variant",
|
||||
quantity: 1,
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it("updates a claim", async () => {
|
||||
@@ -296,26 +295,28 @@ describe("/admin/orders", () => {
|
||||
claim = updateData.order.claims[0];
|
||||
|
||||
expect(claim.claim_items.length).toEqual(1);
|
||||
expect(claim.claim_items).toEqual([
|
||||
expect.objectContaining({
|
||||
id: claim.claim_items[0].id,
|
||||
reason: "production_failure",
|
||||
note: "Something new",
|
||||
images: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
url: "https://test.image.com",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
url: "https://new.com/image",
|
||||
}),
|
||||
]),
|
||||
tags: expect.arrayContaining([
|
||||
expect.objectContaining({ value: "completely" }),
|
||||
expect.objectContaining({ value: "new" }),
|
||||
expect.objectContaining({ value: "tags" }),
|
||||
]),
|
||||
}),
|
||||
]);
|
||||
expect(claim.claim_items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: claim.claim_items[0].id,
|
||||
reason: "production_failure",
|
||||
note: "Something new",
|
||||
images: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
url: "https://test.image.com",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
url: "https://new.com/image",
|
||||
}),
|
||||
]),
|
||||
// tags: expect.arrayContaining([
|
||||
// expect.objectContaining({ value: "completely" }),
|
||||
// expect.objectContaining({ value: "new" }),
|
||||
// expect.objectContaining({ value: "tags" }),
|
||||
// ]),
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it("updates claim items - removes image", async () => {
|
||||
@@ -384,11 +385,11 @@ describe("/admin/orders", () => {
|
||||
reason: "production_failure",
|
||||
note: "Something new",
|
||||
images: [],
|
||||
tags: expect.arrayContaining([
|
||||
expect.objectContaining({ value: "completely" }),
|
||||
expect.objectContaining({ value: "new" }),
|
||||
expect.objectContaining({ value: "tags" }),
|
||||
]),
|
||||
// tags: expect.arrayContaining([
|
||||
// expect.objectContaining({ value: "completely" }),
|
||||
// expect.objectContaining({ value: "new" }),
|
||||
// expect.objectContaining({ value: "tags" }),
|
||||
// ]),
|
||||
}),
|
||||
]);
|
||||
});
|
||||
@@ -466,4 +467,157 @@ describe("/admin/orders", () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /admin/orders", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection);
|
||||
// Manually insert date for filtering
|
||||
const createdAt = new Date("26 January 1997 12:00 UTC");
|
||||
await orderSeeder(dbConnection, {
|
||||
created_at: createdAt.toISOString(),
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "cart"`);
|
||||
await manager.query(`DELETE FROM "fulfillment_item"`);
|
||||
await manager.query(`DELETE FROM "fulfillment"`);
|
||||
await manager.query(`DELETE FROM "swap"`);
|
||||
await manager.query(`DELETE FROM "return"`);
|
||||
await manager.query(`DELETE FROM "claim_image"`);
|
||||
await manager.query(`DELETE FROM "claim_tag"`);
|
||||
await manager.query(`DELETE FROM "claim_item"`);
|
||||
await manager.query(`DELETE FROM "shipping_method"`);
|
||||
await manager.query(`DELETE FROM "line_item"`);
|
||||
await manager.query(`DELETE FROM "claim_order"`);
|
||||
await manager.query(`DELETE FROM "money_amount"`);
|
||||
await manager.query(`DELETE FROM "product_variant"`);
|
||||
await manager.query(`DELETE FROM "product"`);
|
||||
await manager.query(`DELETE FROM "shipping_option"`);
|
||||
await manager.query(`DELETE FROM "discount"`);
|
||||
await manager.query(`DELETE FROM "payment"`);
|
||||
await manager.query(`DELETE FROM "order"`);
|
||||
await manager.query(`DELETE FROM "customer"`);
|
||||
await manager.query(
|
||||
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
|
||||
);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
await manager.query(`DELETE FROM "user"`);
|
||||
});
|
||||
|
||||
it("lists all orders", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get("/admin/orders?fields=id", {
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.orders).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "test-order",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("successfully lists orders with greater than", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get(
|
||||
"/admin/orders?fields=id&created_at[gt]=01-26-1990",
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.orders).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "test-order",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("successfully lists no orders with greater than", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get(
|
||||
"/admin/orders?fields=id&created_at[gt]=01-26-2000",
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.orders).toEqual([]);
|
||||
});
|
||||
|
||||
it("successfully lists orders with less than", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get(
|
||||
"/admin/orders?fields=id&created_at[lt]=01-26-2000",
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.orders).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "test-order",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("successfully lists no orders with less than", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get(
|
||||
"/admin/orders?fields=id&created_at[lt]=01-26-1990",
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.orders).toEqual([]);
|
||||
});
|
||||
|
||||
it("successfully lists orders using unix (greater than)", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get(
|
||||
"/admin/orders?fields=id&created_at[gt]=633351600",
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.orders).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "test-order",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ describe("/store/carts", () => {
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
dropDatabase({ databaseName: "medusa-integration" });
|
||||
await dropDatabase({ databaseName: "medusa-integration" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const { Region, GiftCard } = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/store/gift-cards", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-integration" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("GET /store/gift-cards/:code", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.insert(Region, {
|
||||
id: "region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
await manager.insert(GiftCard, {
|
||||
id: "gift_test",
|
||||
code: "GC_TEST",
|
||||
value: 200,
|
||||
balance: 120,
|
||||
region_id: "region",
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "gift_card"`);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
});
|
||||
|
||||
it("retrieves a gift card", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api.get("/store/gift-cards/GC_TEST");
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.gift_card).toEqual({
|
||||
id: "gift_test",
|
||||
code: "GC_TEST",
|
||||
value: 200,
|
||||
balance: 120,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,160 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const {
|
||||
Region,
|
||||
Order,
|
||||
Customer,
|
||||
ShippingProfile,
|
||||
Product,
|
||||
ProductVariant,
|
||||
MoneyAmount,
|
||||
LineItem,
|
||||
} = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/store/carts", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-integration" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("GET /store/orders", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(
|
||||
`ALTER SEQUENCE order_display_id_seq RESTART WITH 111`
|
||||
);
|
||||
await manager.insert(Region, {
|
||||
id: "region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
await manager.insert(Customer, {
|
||||
id: "cus_1234",
|
||||
email: "test@email.com",
|
||||
});
|
||||
await manager.insert(Order, {
|
||||
id: "order_test",
|
||||
email: "test@email.com",
|
||||
display_id: 111,
|
||||
customer_id: "cus_1234",
|
||||
region_id: "region",
|
||||
tax_rate: 0,
|
||||
currency_code: "usd",
|
||||
});
|
||||
|
||||
const defaultProfile = await manager.findOne(ShippingProfile, {
|
||||
type: "default",
|
||||
});
|
||||
await manager.insert(Product, {
|
||||
id: "test-product",
|
||||
title: "test product",
|
||||
profile_id: defaultProfile.id,
|
||||
options: [{ id: "test-option", title: "Size" }],
|
||||
});
|
||||
|
||||
await manager.insert(ProductVariant, {
|
||||
id: "test-variant",
|
||||
title: "test variant",
|
||||
product_id: "test-product",
|
||||
inventory_quantity: 1,
|
||||
options: [
|
||||
{
|
||||
option_id: "test-option",
|
||||
value: "Size",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await manager.insert(LineItem, {
|
||||
id: "test-item",
|
||||
fulfilled_quantity: 1,
|
||||
title: "Line Item",
|
||||
description: "Line Item Desc",
|
||||
thumbnail: "https://test.js/1234",
|
||||
unit_price: 8000,
|
||||
quantity: 1,
|
||||
variant_id: "test-variant",
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "line_item"`);
|
||||
|
||||
await manager.query(`DELETE FROM "order"`);
|
||||
await manager.query(`DELETE FROM "customer"`);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
|
||||
await manager.query(`DELETE FROM "product_option_value"`);
|
||||
await manager.query(`DELETE FROM "product_option"`);
|
||||
await manager.query(`DELETE FROM "money_amount"`);
|
||||
await manager.query(`DELETE FROM "product_variant"`);
|
||||
await manager.query(`DELETE FROM "product"`);
|
||||
});
|
||||
|
||||
it("looks up order", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.get("/store/orders?display_id=111&email=test@email.com")
|
||||
.catch((err) => {
|
||||
return err.response;
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.data.order.display_id).toEqual(111);
|
||||
expect(response.data.order.email).toEqual("test@email.com");
|
||||
});
|
||||
|
||||
it("fails if display_id + email not provided", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.get("/store/orders?display_id=111")
|
||||
.catch((err) => {
|
||||
return err.response;
|
||||
});
|
||||
expect(response.status).toEqual(400);
|
||||
});
|
||||
|
||||
it("fails if display_id + email not provided", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.get("/store/orders?email=test@email.com")
|
||||
.catch((err) => {
|
||||
return err.response;
|
||||
});
|
||||
expect(response.status).toEqual(400);
|
||||
});
|
||||
|
||||
it("fails if email not correct", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.get("/store/orders?display_id=111&email=test1@email.com")
|
||||
.catch((err) => {
|
||||
return err.response;
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(404);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,178 @@
|
||||
const { dropDatabase } = require("pg-god");
|
||||
const path = require("path");
|
||||
const {
|
||||
Region,
|
||||
Order,
|
||||
Customer,
|
||||
ShippingProfile,
|
||||
Product,
|
||||
ProductVariant,
|
||||
ShippingOption,
|
||||
LineItem,
|
||||
} = require("@medusajs/medusa");
|
||||
|
||||
const setupServer = require("../../../helpers/setup-server");
|
||||
const { useApi } = require("../../../helpers/use-api");
|
||||
const { initDb } = require("../../../helpers/use-db");
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
describe("/store/carts", () => {
|
||||
let medusaProcess;
|
||||
let dbConnection;
|
||||
|
||||
beforeAll(async () => {
|
||||
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||
dbConnection = await initDb({ cwd });
|
||||
medusaProcess = await setupServer({ cwd });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
dbConnection.close();
|
||||
await dropDatabase({ databaseName: "medusa-integration" });
|
||||
|
||||
medusaProcess.kill();
|
||||
});
|
||||
|
||||
describe("POST /store/returns", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(
|
||||
`ALTER SEQUENCE order_display_id_seq RESTART WITH 111`
|
||||
);
|
||||
|
||||
await manager.insert(Region, {
|
||||
id: "region",
|
||||
name: "Test Region",
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
});
|
||||
|
||||
await manager.insert(Customer, {
|
||||
id: "cus_1234",
|
||||
email: "test@email.com",
|
||||
});
|
||||
|
||||
await manager.insert(Order, {
|
||||
id: "order_test",
|
||||
email: "test@email.com",
|
||||
display_id: 111,
|
||||
customer_id: "cus_1234",
|
||||
region_id: "region",
|
||||
tax_rate: 0,
|
||||
currency_code: "usd",
|
||||
});
|
||||
|
||||
const defaultProfile = await manager.findOne(ShippingProfile, {
|
||||
type: "default",
|
||||
});
|
||||
|
||||
await manager.insert(Product, {
|
||||
id: "test-product",
|
||||
title: "test product",
|
||||
profile_id: defaultProfile.id,
|
||||
options: [{ id: "test-option", title: "Size" }],
|
||||
});
|
||||
|
||||
await manager.insert(ProductVariant, {
|
||||
id: "test-variant",
|
||||
title: "test variant",
|
||||
product_id: "test-product",
|
||||
inventory_quantity: 1,
|
||||
options: [
|
||||
{
|
||||
option_id: "test-option",
|
||||
value: "Size",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await manager.insert(LineItem, {
|
||||
id: "test-item",
|
||||
order_id: "order_test",
|
||||
fulfilled_quantity: 1,
|
||||
title: "Line Item",
|
||||
description: "Line Item Desc",
|
||||
thumbnail: "https://test.js/1234",
|
||||
unit_price: 8000,
|
||||
quantity: 1,
|
||||
variant_id: "test-variant",
|
||||
});
|
||||
|
||||
await manager.insert(ShippingOption, {
|
||||
id: "test-option",
|
||||
name: "Test ret",
|
||||
profile_id: defaultProfile.id,
|
||||
region_id: "region",
|
||||
provider_id: "test-ful",
|
||||
data: {},
|
||||
price_type: "flat_rate",
|
||||
amount: 1000,
|
||||
is_return: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const manager = dbConnection.manager;
|
||||
await manager.query(`DELETE FROM "shipping_method"`);
|
||||
await manager.query(`DELETE FROM "shipping_option"`);
|
||||
await manager.query(`DELETE FROM "return_item"`);
|
||||
await manager.query(`DELETE FROM "return"`);
|
||||
await manager.query(`DELETE FROM "line_item"`);
|
||||
await manager.query(`DELETE FROM "order"`);
|
||||
await manager.query(`DELETE FROM "customer"`);
|
||||
await manager.query(`DELETE FROM "region"`);
|
||||
|
||||
await manager.query(`DELETE FROM "product_option_value"`);
|
||||
await manager.query(`DELETE FROM "product_option"`);
|
||||
await manager.query(`DELETE FROM "money_amount"`);
|
||||
await manager.query(`DELETE FROM "product_variant"`);
|
||||
await manager.query(`DELETE FROM "product"`);
|
||||
});
|
||||
|
||||
it("creates a return", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.post("/store/returns", {
|
||||
order_id: "order_test",
|
||||
items: [
|
||||
{
|
||||
item_id: "test-item",
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((err) => {
|
||||
return err.response;
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
expect(response.data.return.refund_amount).toEqual(8000);
|
||||
});
|
||||
|
||||
it("creates a return with shipping method", async () => {
|
||||
const api = useApi();
|
||||
|
||||
const response = await api
|
||||
.post("/store/returns", {
|
||||
order_id: "order_test",
|
||||
return_shipping: {
|
||||
option_id: "test-option",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
item_id: "test-item",
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((err) => {
|
||||
return err.response;
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
expect(response.data.return.refund_amount).toEqual(7000);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@medusajs/medusa": "^1.1.3",
|
||||
"medusa-interfaces": "^1.1.0"
|
||||
"medusa-interfaces": "^1.1.0",
|
||||
"typeorm": "^0.2.31"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.12.10",
|
||||
@@ -16,4 +17,4 @@
|
||||
"@babel/node": "^7.12.10",
|
||||
"babel-preset-medusa-package": "^1.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,10 @@ class TestFulService extends FulfillmentService {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
createReturn() {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
createFulfillment() {
|
||||
// No data is being sent anywhere
|
||||
return Promise.resolve({});
|
||||
|
||||
@@ -4064,6 +4064,28 @@ typeorm@^0.2.29:
|
||||
yargonaut "^1.1.2"
|
||||
yargs "^16.0.3"
|
||||
|
||||
typeorm@^0.2.31:
|
||||
version "0.2.31"
|
||||
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.31.tgz#82b8a1b233224f81c738f53b0380386ccf360917"
|
||||
integrity sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==
|
||||
dependencies:
|
||||
"@sqltools/formatter" "1.2.2"
|
||||
app-root-path "^3.0.0"
|
||||
buffer "^5.5.0"
|
||||
chalk "^4.1.0"
|
||||
cli-highlight "^2.1.10"
|
||||
debug "^4.1.1"
|
||||
dotenv "^8.2.0"
|
||||
glob "^7.1.6"
|
||||
js-yaml "^3.14.0"
|
||||
mkdirp "^1.0.4"
|
||||
reflect-metadata "^0.1.13"
|
||||
sha.js "^2.4.11"
|
||||
tslib "^1.13.0"
|
||||
xml2js "^0.4.23"
|
||||
yargonaut "^1.1.2"
|
||||
yargs "^16.0.3"
|
||||
|
||||
uid-safe@~2.1.5:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
0 silly argv { _: [ 'bootstrap' ],
|
||||
0 silly argv lernaVersion: '3.22.1',
|
||||
0 silly argv '$0': '/usr/local/bin/lerna' }
|
||||
1 notice cli v3.22.1
|
||||
2 verbose rootPath /Users/srindom/Developer/medusa-js
|
||||
3 info versioning independent
|
||||
4 error JSONError: Unexpected token < in JSON at position 34 while parsing near '...edusa-file-spaces",<<<<<<< HEAD "vers...' in packages/medusa-file-spaces/package.json
|
||||
4 error at module.exports (/Users/srindom/Developer/medusa-js/node_modules/parse-json/index.js:26:19)
|
||||
4 error at parse (/Users/srindom/Developer/medusa-js/node_modules/load-json-file/index.js:15:9)
|
||||
+6
-1
@@ -31,6 +31,11 @@
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"jest": "jest",
|
||||
"test": "jest",
|
||||
"test:integration": "jest --config=integration-tests/jest.config.js --runInBand"
|
||||
"test:integration": "jest --config=integration-tests/jest.config.js --runInBand",
|
||||
"test:fixtures": "jest --config=docs-util/jest.config.js --runInBand"
|
||||
},
|
||||
"dependencies": {
|
||||
"oas-normalize": "^2.3.1",
|
||||
"swagger-inline": "^3.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,73 @@ Joi.address = () => {
|
||||
})
|
||||
}
|
||||
|
||||
Joi.dateFilter = () => {
|
||||
return Joi.object({
|
||||
lt: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
|
||||
gt: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
|
||||
gte: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
|
||||
lte: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
|
||||
})
|
||||
}
|
||||
|
||||
Joi.orderFilter = () => {
|
||||
return Joi.object().keys({
|
||||
id: Joi.string(),
|
||||
q: Joi.string(),
|
||||
status: Joi.array()
|
||||
.items(
|
||||
Joi.string().valid(
|
||||
"pending",
|
||||
"completed",
|
||||
"archived",
|
||||
"canceled",
|
||||
"requires_action"
|
||||
)
|
||||
)
|
||||
.single(),
|
||||
fulfillment_status: Joi.array()
|
||||
.items(
|
||||
Joi.string().valid(
|
||||
"not_fulfilled",
|
||||
"fulfilled",
|
||||
"partially_fulfilled",
|
||||
"shipped",
|
||||
"partially_shipped",
|
||||
"canceled",
|
||||
"returned",
|
||||
"partially_returned",
|
||||
"requires_action"
|
||||
)
|
||||
)
|
||||
.single(),
|
||||
payment_status: Joi.array()
|
||||
.items(
|
||||
Joi.string().valid(
|
||||
"captured",
|
||||
"awaiting",
|
||||
"not_paid",
|
||||
"refunded",
|
||||
"partially_refunded",
|
||||
"canceled",
|
||||
"requires_action"
|
||||
)
|
||||
)
|
||||
.single(),
|
||||
display_id: Joi.string(),
|
||||
cart_id: Joi.string(),
|
||||
offset: Joi.string(),
|
||||
limit: Joi.string(),
|
||||
expand: Joi.string(),
|
||||
fields: Joi.string(),
|
||||
customer_id: Joi.string(),
|
||||
email: Joi.string(),
|
||||
region_id: Joi.string(),
|
||||
currency_code: Joi.string(),
|
||||
tax_rate: Joi.string(),
|
||||
canceled_at: Joi.dateFilter(),
|
||||
created_at: Joi.dateFilter(),
|
||||
updated_at: Joi.dateFilter(),
|
||||
})
|
||||
}
|
||||
|
||||
export default Joi
|
||||
|
||||
@@ -11,9 +11,6 @@ describe("BaseService", () => {
|
||||
id: "1234",
|
||||
test1: ["123", "12", "1"],
|
||||
test2: Not("this"),
|
||||
rec: {
|
||||
first: ["1", "2", "3"],
|
||||
},
|
||||
},
|
||||
{
|
||||
relations: ["1234"],
|
||||
@@ -25,9 +22,6 @@ describe("BaseService", () => {
|
||||
id: "1234",
|
||||
test1: In(["123", "12", "1"]),
|
||||
test2: Not("this"),
|
||||
rec: {
|
||||
first: In(["1", "2", "3"]),
|
||||
},
|
||||
},
|
||||
relations: ["1234"],
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { In, FindOperator, getManager } from "typeorm"
|
||||
import { In, FindOperator, Raw } from "typeorm"
|
||||
|
||||
/**
|
||||
* Common functionality for Services
|
||||
@@ -29,7 +29,32 @@ class BaseService {
|
||||
acc[key] = In([...value])
|
||||
break
|
||||
case value !== null && typeof value === "object":
|
||||
acc[key] = build(value)
|
||||
const subquery = []
|
||||
|
||||
Object.entries(value).map(([modifier, val]) => {
|
||||
switch (modifier) {
|
||||
case "lt":
|
||||
subquery.push({ operator: "<", value: val })
|
||||
break
|
||||
case "gt":
|
||||
subquery.push({ operator: ">", value: val })
|
||||
break
|
||||
case "lte":
|
||||
subquery.push({ operator: "<=", value: val })
|
||||
break
|
||||
case "gte":
|
||||
subquery.push({ operator: ">=", value: val })
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
acc[key] = Raw(
|
||||
a =>
|
||||
subquery
|
||||
.map((s, index) => `${a} ${s.operator} :${index}`)
|
||||
.join(" AND "),
|
||||
subquery.map(s => s.value)
|
||||
)
|
||||
break
|
||||
default:
|
||||
acc[key] = value
|
||||
|
||||
@@ -47,8 +47,63 @@ const order = {
|
||||
email: "test@example.com",
|
||||
}
|
||||
|
||||
const roundingOrder = {
|
||||
region: {
|
||||
tax_code: "1234",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: "rounding-item",
|
||||
title: "Test",
|
||||
allow_discounts: true,
|
||||
variant: {
|
||||
sku: "TEST",
|
||||
},
|
||||
unit_price: 31600,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
shipping_total: 0,
|
||||
shipping_methods: [
|
||||
{
|
||||
name: "standard",
|
||||
price: 0,
|
||||
},
|
||||
],
|
||||
discounts: [
|
||||
{
|
||||
code: "testdiscount",
|
||||
rule: {
|
||||
type: "percentage",
|
||||
allocation: "total",
|
||||
value: 50,
|
||||
},
|
||||
},
|
||||
],
|
||||
payment_method: {
|
||||
id: "123",
|
||||
},
|
||||
tax_rate: 25,
|
||||
currency_code: "DKK",
|
||||
display_id: "1234",
|
||||
id: "rounding",
|
||||
shipping_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Testson",
|
||||
address_1: "Test",
|
||||
address_2: "TEst",
|
||||
postal_code: "1234",
|
||||
country_code: "DK",
|
||||
phone: "12345678",
|
||||
},
|
||||
email: "test@example.com",
|
||||
}
|
||||
|
||||
const OrderService = {
|
||||
retrieve: () => {
|
||||
retrieve: (id) => {
|
||||
if (id === "rounding") {
|
||||
return Promise.resolve(roundingOrder)
|
||||
}
|
||||
return Promise.resolve(order)
|
||||
},
|
||||
update: () => {
|
||||
@@ -60,17 +115,29 @@ const TotalsService = {
|
||||
getTotal: () => {
|
||||
return Promise.resolve(123)
|
||||
},
|
||||
getLineDiscounts: () => {
|
||||
return Promise.resolve([])
|
||||
getLineDiscounts: (o) => {
|
||||
if (o.id === "rounding") {
|
||||
return [
|
||||
{
|
||||
item: { id: "rounding-item", quantity: 1 },
|
||||
amount: 15800,
|
||||
},
|
||||
]
|
||||
}
|
||||
return []
|
||||
},
|
||||
getShippingTotal: () => {
|
||||
getShippingTotal: (o) => {
|
||||
if (o.id === "rounding") {
|
||||
return 0
|
||||
}
|
||||
return 12399
|
||||
},
|
||||
rounded: (value) => {
|
||||
const decimalPlaces = 4
|
||||
return Number(
|
||||
Math.round(parseFloat(value + "e" + decimalPlaces)) + "e-" + decimalPlaces
|
||||
)
|
||||
return Math.round(value)
|
||||
// const decimalPlaces = 4
|
||||
// return Number(
|
||||
// Math.round(parseFloat(value + "e" + decimalPlaces)) + "e-" + decimalPlaces
|
||||
// )
|
||||
},
|
||||
}
|
||||
|
||||
@@ -146,6 +213,8 @@ describe("BrightpearlService", () => {
|
||||
)
|
||||
|
||||
it("successfully builds sales order", async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
await bpService.createSalesOrder(order)
|
||||
|
||||
expect(mockCreateOrder).toHaveBeenCalledWith({
|
||||
@@ -201,4 +270,132 @@ describe("BrightpearlService", () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("rounding", () => {
|
||||
const bpService = new BrightpearlService(
|
||||
{
|
||||
orderService: OrderService,
|
||||
totalsService: TotalsService,
|
||||
oauthService: OAuthService,
|
||||
regionService: RegionService,
|
||||
},
|
||||
{ account: "test" }
|
||||
)
|
||||
|
||||
it("rounds correctly", async () => {
|
||||
jest.clearAllMocks()
|
||||
await bpService.createSalesOrder("rounding")
|
||||
|
||||
expect(mockCreateOrder).toHaveBeenCalledTimes(1)
|
||||
expect(mockCreateOrder).toHaveBeenCalledWith({
|
||||
currency: { code: "DKK" },
|
||||
ref: "1234",
|
||||
externalRef: "rounding",
|
||||
channelId: "1",
|
||||
installedIntegrationInstanceId: undefined,
|
||||
statusId: "3",
|
||||
customer: {
|
||||
id: "12345",
|
||||
address: {
|
||||
addressFullName: "Test Testson",
|
||||
addressLine1: "Test",
|
||||
addressLine2: "TEst",
|
||||
postalCode: "1234",
|
||||
countryIsoCode: "DK",
|
||||
telephone: "12345678",
|
||||
email: "test@example.com",
|
||||
},
|
||||
},
|
||||
delivery: {
|
||||
shippingMethodId: 0,
|
||||
address: {
|
||||
addressFullName: "Test Testson",
|
||||
addressLine1: "Test",
|
||||
addressLine2: "TEst",
|
||||
postalCode: "1234",
|
||||
countryIsoCode: "DK",
|
||||
telephone: "12345678",
|
||||
email: "test@example.com",
|
||||
},
|
||||
},
|
||||
rows: [
|
||||
{
|
||||
name: "Test",
|
||||
net: 158,
|
||||
tax: 39.5,
|
||||
quantity: 1,
|
||||
taxCode: "1234",
|
||||
externalRef: "rounding-item",
|
||||
nominalCode: "4000",
|
||||
},
|
||||
{
|
||||
name: "Shipping: standard",
|
||||
quantity: 1,
|
||||
net: 0,
|
||||
tax: 0,
|
||||
taxCode: "1234",
|
||||
nominalCode: "4040",
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
|
||||
it("rounds correctly", async () => {
|
||||
jest.clearAllMocks()
|
||||
await bpService.createSalesOrder("rounding")
|
||||
|
||||
expect(mockCreateOrder).toHaveBeenCalledTimes(1)
|
||||
expect(mockCreateOrder).toHaveBeenCalledWith({
|
||||
currency: { code: "DKK" },
|
||||
ref: "1234",
|
||||
externalRef: "rounding",
|
||||
channelId: "1",
|
||||
installedIntegrationInstanceId: undefined,
|
||||
statusId: "3",
|
||||
customer: {
|
||||
id: "12345",
|
||||
address: {
|
||||
addressFullName: "Test Testson",
|
||||
addressLine1: "Test",
|
||||
addressLine2: "TEst",
|
||||
postalCode: "1234",
|
||||
countryIsoCode: "DK",
|
||||
telephone: "12345678",
|
||||
email: "test@example.com",
|
||||
},
|
||||
},
|
||||
delivery: {
|
||||
shippingMethodId: 0,
|
||||
address: {
|
||||
addressFullName: "Test Testson",
|
||||
addressLine1: "Test",
|
||||
addressLine2: "TEst",
|
||||
postalCode: "1234",
|
||||
countryIsoCode: "DK",
|
||||
telephone: "12345678",
|
||||
email: "test@example.com",
|
||||
},
|
||||
},
|
||||
rows: [
|
||||
{
|
||||
name: "Test",
|
||||
net: 158,
|
||||
tax: 39.5,
|
||||
quantity: 1,
|
||||
taxCode: "1234",
|
||||
externalRef: "rounding-item",
|
||||
nominalCode: "4000",
|
||||
},
|
||||
{
|
||||
name: "Shipping: standard",
|
||||
quantity: 1,
|
||||
net: 0,
|
||||
tax: 0,
|
||||
taxCode: "1234",
|
||||
nominalCode: "4040",
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -355,10 +355,10 @@ class BrightpearlService extends BaseService {
|
||||
return row.externalRef === i.item_id
|
||||
})
|
||||
return {
|
||||
net: this.totalsService_.rounded(
|
||||
net: this.bpround_(
|
||||
(parentRow.net / parentRow.quantity) * i.quantity
|
||||
),
|
||||
tax: this.totalsService_.rounded(
|
||||
tax: this.bpround_(
|
||||
(parentRow.tax / parentRow.quantity) * i.quantity
|
||||
),
|
||||
productId: parentRow.productId,
|
||||
@@ -697,10 +697,10 @@ class BrightpearlService extends BaseService {
|
||||
return row.externalRef === i.item_id
|
||||
})
|
||||
return {
|
||||
net: this.totalsService_.rounded(
|
||||
net: this.bpround_(
|
||||
(parentRow.net / parentRow.quantity) * i.quantity
|
||||
),
|
||||
tax: this.totalsService_.rounded(
|
||||
tax: this.bpround_(
|
||||
(parentRow.tax / parentRow.quantity) * i.quantity
|
||||
),
|
||||
productId: parentRow.productId,
|
||||
@@ -1096,9 +1096,16 @@ class BrightpearlService extends BaseService {
|
||||
return { contactId: customer }
|
||||
}
|
||||
|
||||
bpround_(n) {
|
||||
const decimalPlaces = 4
|
||||
return Number(
|
||||
Math.round(parseFloat(n + "e" + decimalPlaces)) + "e-" + decimalPlaces
|
||||
)
|
||||
}
|
||||
|
||||
bpnum_(number, taxRate = 100) {
|
||||
const bpNumber = number / 100
|
||||
return this.totalsService_.rounded(bpNumber * (taxRate / 100))
|
||||
return this.bpround_(bpNumber * (taxRate / 100))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -381,6 +381,10 @@ class SendGridService extends NotificationService {
|
||||
relations: ["region", "order"],
|
||||
})
|
||||
|
||||
if (!giftCard.order) {
|
||||
return
|
||||
}
|
||||
|
||||
const taxRate = giftCard.region.tax_rate / 100
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { default as authenticateCustomer } from "./authenticate-customer"
|
||||
import { default as authenticate } from "./authenticate"
|
||||
import { default as normalizeQuery } from "./normalized-query"
|
||||
import { default as wrap } from "./await-middleware"
|
||||
|
||||
export default {
|
||||
authenticate,
|
||||
authenticateCustomer,
|
||||
normalizeQuery,
|
||||
wrap,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
export default () => {
|
||||
return (req, res, next) => {
|
||||
const clean = Object.entries(req.query).reduce((acc, [key, val]) => {
|
||||
if (Array.isArray(val) && val.length === 1) {
|
||||
acc[key] = val[0].split(",")
|
||||
} else {
|
||||
acc[key] = val
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
req.query = clean
|
||||
|
||||
next()
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,26 @@ import jwt from "jsonwebtoken"
|
||||
import { Validator } from "medusa-core-utils"
|
||||
import config from "../../../../config"
|
||||
|
||||
/**
|
||||
* @oas [post] /auth
|
||||
* operationId: "PostAuth"
|
||||
* summary: "Authenticate a User"
|
||||
* description: "Logs a User in and authorizes them to manage Store settings."
|
||||
* parameters:
|
||||
* - (body) email=* {string} The User's email.
|
||||
* - (body) password=* {string} The User's password.
|
||||
* tags:
|
||||
* - Auth
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* customer:
|
||||
* $ref: "#/components/schemas/user"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { body } = req
|
||||
const schema = Validator.object().keys({
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
import passport from "passport"
|
||||
|
||||
/**
|
||||
* @oas [get] /auth
|
||||
* operationId: "GetAuth"
|
||||
* summary: "Get Session"
|
||||
* description: "Gets the currently logged in User."
|
||||
* tags:
|
||||
* - Auth
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* customer:
|
||||
* $ref: "#/components/schemas/user"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const userService = req.scope.resolve("userService")
|
||||
const user = await userService.retrieve(req.user.userId)
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* @oas [post] /collections
|
||||
* operationId: "PostCollections"
|
||||
* summary: "Create a Product Collection"
|
||||
* description: "Creates a Product Collection."
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* required:
|
||||
* - title
|
||||
* properties:
|
||||
* title:
|
||||
* type: string
|
||||
* description: The title to identify the Collection by.
|
||||
* handle:
|
||||
* type: string
|
||||
* description: An optional handle to be used in slugs, if none is provided we will kebab-case the title.
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Collection
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* collection:
|
||||
* $ref: "#/components/schemas/product_collection"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const schema = Validator.object().keys({
|
||||
title: Validator.string().required(),
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
/**
|
||||
* @oas [delete] /collections/{id}
|
||||
* operationId: "DeleteCollectionsCollection"
|
||||
* summary: "Delete a Product Collection"
|
||||
* description: "Deletes a Product Collection."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Collection.
|
||||
* tags:
|
||||
* - Collection
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* id:
|
||||
* type: string
|
||||
* description: The id of the deleted Collection
|
||||
* object:
|
||||
* type: string
|
||||
* description: The type of the object that was deleted.
|
||||
* deleted:
|
||||
* type: boolean
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/**
|
||||
* @oas [get] /collections/{id}
|
||||
* operationId: "GetCollectionsCollection"
|
||||
* summary: "Retrieve a Product Collection"
|
||||
* description: "Retrieves a Product Collection."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Product Collection
|
||||
* tags:
|
||||
* - Collection
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* collection:
|
||||
* $ref: "#/components/schemas/product_collection"
|
||||
*/
|
||||
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
import { defaultFields, defaultRelations } from "."
|
||||
|
||||
/**
|
||||
* @oas [get] /collections
|
||||
* operationId: "GetCollections"
|
||||
* summary: "List Product Collections"
|
||||
* description: "Retrieve a list of Product Collection."
|
||||
* tags:
|
||||
* - Collection
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* collection:
|
||||
* $ref: "#/components/schemas/product_collection"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
const selector = {}
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* @oas [post] /collections/{id}
|
||||
* operationId: "PostCollectionsCollection"
|
||||
* summary: "Update a Product Collection"
|
||||
* description: "Updates a Product Collection."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Collection.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* title:
|
||||
* type: string
|
||||
* description: The title to identify the Collection by.
|
||||
* handle:
|
||||
* type: string
|
||||
* description: An optional handle to be used in slugs, if none is provided we will kebab-case the title.
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Collection
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* collection:
|
||||
* $ref: "#/components/schemas/product_collection"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
import { Validator, MedusaError } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* @oas [post] /customers
|
||||
* operationId: "PostCustomers"
|
||||
* summary: "Create a Customer"
|
||||
* description: "Creates a Customer."
|
||||
* parameters:
|
||||
* - (body) email=* {string} The Customer's email address.
|
||||
* - (body) first_name=* {string} The Customer's first name.
|
||||
* - (body) last_name=* {string} The Customer's last name.
|
||||
* - (body) phone {string} The Customer's phone number.
|
||||
* tags:
|
||||
* - Customer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* customer:
|
||||
* $ref: "#/components/schemas/customer"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const schema = Validator.object().keys({
|
||||
email: Validator.string()
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/**
|
||||
* @oas [get] /customers/{id}
|
||||
* operationId: "GetCustomersCustomer"
|
||||
* summary: "Retrieve a Customer"
|
||||
* description: "Retrieves a Customer."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Customer.
|
||||
* tags:
|
||||
* - Customer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* customer:
|
||||
* $ref: "#/components/schemas/customer"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
try {
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/**
|
||||
* @oas [get] /customers
|
||||
* operationId: "GetCustomers"
|
||||
* summary: "List Customers"
|
||||
* description: "Retrieves a list of Customers."
|
||||
* tags:
|
||||
* - Customer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* customer:
|
||||
* $ref: "#/components/schemas/customer"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
const customerService = req.scope.resolve("customerService")
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
import { Validator, MedusaError } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* @oas [post] /customers/{id}
|
||||
* operationId: "PostCustomersCustomer"
|
||||
* summary: "Update a Customer"
|
||||
* description: "Updates a Customer."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Customer.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* first_name:
|
||||
* type: string
|
||||
* description: The Customer's first name.
|
||||
* last_name:
|
||||
* type: string
|
||||
* description: The Customer's last name.
|
||||
* phone:
|
||||
* description: The Customer's phone number.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Customer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* customer:
|
||||
* $ref: "#/components/schemas/customer"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /discounts/{id}/regions/{region_id}
|
||||
* operationId: "PostDiscountsDiscountRegionsRegion"
|
||||
* summary: "Adds Region availability"
|
||||
* description: "Adds a Region to the list of Regions that a Discount can be used in."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount.
|
||||
* - (path) region_id=* {string} The id of the Region.
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id, region_id } = req.params
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /discounts/{id}/products/{product_id}
|
||||
* operationId: "PostDiscountsDiscountProductsProduct"
|
||||
* summary: "Adds Product availability"
|
||||
* description: "Adds a Product to the list of Products that a Discount can be used for."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount.
|
||||
* - (path) product_id=* {string} The id of the Product.
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id, variant_id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,56 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* @oas [post] /discounts
|
||||
* operationId: "PostDiscounts"
|
||||
* summary: "Creates a Discount"
|
||||
* description: "Creates a Discount with a given set of rules that define how the Discount behaves."
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* code:
|
||||
* type: string
|
||||
* description: A unique code that will be used to redeem the Discount
|
||||
* is_dynamic:
|
||||
* type: string
|
||||
* description: Whether the Discount should have multiple instances of itself, each with a different code. This can be useful for automatically generated codes that all have to follow a common set of rules.
|
||||
* rule:
|
||||
* description: The Discount Rule that defines how Discounts are calculated
|
||||
* oneOf:
|
||||
* - $ref: "#/components/schemas/discount_rule"
|
||||
* is_disabled:
|
||||
* type: boolean
|
||||
* description: Whether the Discount code is disabled on creation. You will have to enable it later to make it available to Customers.
|
||||
* starts_at:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: The time at which the Discount should be available.
|
||||
* ends_at:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: The time at which the Discount should no longer be available.
|
||||
* regions:
|
||||
* description: A list of Region ids representing the Regions in which the Discount can be used.
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const schema = Validator.object().keys({
|
||||
code: Validator.string().required(),
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* @oas [post] /discounts/{id}/dynamic-codes
|
||||
* operationId: "PostDiscountsDiscountDynamicCodes"
|
||||
* summary: "Create a dynamic Discount code"
|
||||
* description: "Creates a unique code that can map to a parent Discount. This is useful if you want to automatically generate codes with the same behaviour."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount to create the dynamic code from."
|
||||
* - (body) code=* {string} The unique code that will be used to redeem the Discount.
|
||||
* - (body) metadata {object} An optional set of key-value paris to hold additional information.
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id } = req.params
|
||||
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
/**
|
||||
* @oas [delete] /discounts/{id}
|
||||
* operationId: "DeleteDiscountsDiscount"
|
||||
* summary: "Delete a Discount"
|
||||
* description: "Deletes a Discount."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* id:
|
||||
* type: string
|
||||
* description: The id of the deleted Discount
|
||||
* object:
|
||||
* type: string
|
||||
* description: The type of the object that was deleted.
|
||||
* deleted:
|
||||
* type: boolean
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id } = req.params
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/**
|
||||
* @oas [delete] /discounts/{id}/dynamic-codes/{code}
|
||||
* operationId: "DeleteDiscountsDiscountDynamicCodesCode"
|
||||
* summary: "Delete a dynamic code"
|
||||
* description: "Deletes a dynamic code from a Discount."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount
|
||||
* - (path) code=* {string} The id of the Discount
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id, code } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [get] /discounts/{id}
|
||||
* operationId: "GetDiscountsDiscount"
|
||||
* summary: "Retrieve a Discount"
|
||||
* description: "Retrieves a Discount"
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id } = req.params
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [get] /discounts
|
||||
* operationId: "GetDiscounts"
|
||||
* summary: "List Discounts"
|
||||
* description: "Retrieves a list of Discounts"
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
const discountService = req.scope.resolve("discountService")
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [delete] /discounts/{id}/regions/{region_id}
|
||||
* operationId: "DeleteDiscountsDiscountRegionsRegion"
|
||||
* summary: "Remove Region availability"
|
||||
* description: "Removes a Region from the list of Regions that a Discount can be used in."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount.
|
||||
* - (path) region_id=* {string} The id of the Region.
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id, region_id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /discounts/{id}/products/{product_id}
|
||||
* operationId: "DeleteDiscountsDiscountProductsProduct"
|
||||
* summary: "Remove Product availability"
|
||||
* description: "Removes a Product from the list of Products that a Discount can be used for."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount.
|
||||
* - (path) product_id=* {string} The id of the Product.
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id, variant_id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,56 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /discounts/{id}
|
||||
* operationId: "PostDiscountsDiscount"
|
||||
* summary: "Update a Discount"
|
||||
* description: "Updates a Discount with a given set of rules that define how the Discount behaves."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Discount.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* code:
|
||||
* type: string
|
||||
* description: A unique code that will be used to redeem the Discount
|
||||
* is_dynamic:
|
||||
* type: string
|
||||
* description: Whether the Discount should have multiple instances of itself, each with a different code. This can be useful for automatically generated codes that all have to follow a common set of rules.
|
||||
* rule:
|
||||
* description: The Discount Rule that defines how Discounts are calculated
|
||||
* oneOf:
|
||||
* - $ref: "#/components/schemas/discount_rule"
|
||||
* is_disabled:
|
||||
* type: boolean
|
||||
* description: Whether the Discount code is disabled on creation. You will have to enable it later to make it available to Customers.
|
||||
* starts_at:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: The time at which the Discount should be available.
|
||||
* ends_at:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: The time at which the Discount should no longer be available.
|
||||
* regions:
|
||||
* description: A list of Region ids representing the Regions in which the Discount can be used.
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* tags:
|
||||
* - Discount
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* discount:
|
||||
* $ref: "#/components/schemas/discount"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { discount_id } = req.params
|
||||
const schema = Validator.object().keys({
|
||||
|
||||
@@ -1,6 +1,46 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /gift-cards
|
||||
* operationId: "PostGiftCards"
|
||||
* summary: "Create a Gift Card"
|
||||
* description: "Creates a Gift Card that can redeemed by its unique code. The Gift Card is only valid within 1 region."
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* value:
|
||||
* type: integer
|
||||
* description: The value (excluding VAT) that the Gift Card should represent.
|
||||
* is_disabled:
|
||||
* type: boolean
|
||||
* description: Whether the Gift Card is disabled on creation. You will have to enable it later to make it available to Customers.
|
||||
* ends_at:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: The time at which the Gift Card should no longer be available.
|
||||
* region_id:
|
||||
* description: The id of the Region in which the Gift Card can be used.
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Gift Card
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* gift_card:
|
||||
* $ref: "#/components/schemas/gift_card"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const schema = Validator.object().keys({
|
||||
value: Validator.number()
|
||||
@@ -20,9 +60,12 @@ export default async (req, res) => {
|
||||
try {
|
||||
const giftCardService = req.scope.resolve("giftCardService")
|
||||
|
||||
await giftCardService.create(value)
|
||||
const newly = await giftCardService.create({
|
||||
...value,
|
||||
balance: value.value,
|
||||
})
|
||||
|
||||
const giftCard = await giftCardService.retrieve(id, {
|
||||
const giftCard = await giftCardService.retrieve(newly.id, {
|
||||
select: defaultFields,
|
||||
relations: defaultRelations,
|
||||
})
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
/**
|
||||
* @oas [delete] /gift-cards/{id}
|
||||
* operationId: "DeleteGiftCardsGiftCard"
|
||||
* summary: "Delete a Gift Card"
|
||||
* description: "Deletes a Gift Card"
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Gift Card to delete.
|
||||
* tags:
|
||||
* - Gift Card
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* id:
|
||||
* type: string
|
||||
* description: The id of the deleted Gift Card
|
||||
* object:
|
||||
* type: string
|
||||
* description: The type of the object that was deleted.
|
||||
* deleted:
|
||||
* type: boolean
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [get] /gift-cards/{id}
|
||||
* operationId: "GetGiftCardsGiftCard"
|
||||
* summary: "Retrieve a Gift Card"
|
||||
* description: "Retrieves a Gift Card."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Gift Card.
|
||||
* tags:
|
||||
* - Gift Card
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* gift_card:
|
||||
* $ref: "#/components/schemas/gift_card"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [get] /gift-cards
|
||||
* operationId: "GetGiftCards"
|
||||
* summary: "List Gift Cards"
|
||||
* description: "Retrieves a list of Gift Cards."
|
||||
* tags:
|
||||
* - Gift Card
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* gift_cards:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: "#/components/schemas/gift_card"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
const selector = {}
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* @oas [post] /gift-cards/{id}
|
||||
* operationId: "PostGiftCardsGiftCard"
|
||||
* summary: "Create a Gift Card"
|
||||
* description: "Creates a Gift Card that can redeemed by its unique code. The Gift Card is only valid within 1 region."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Gift Card.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* balance:
|
||||
* type: integer
|
||||
* description: The value (excluding VAT) that the Gift Card should represent.
|
||||
* is_disabled:
|
||||
* type: boolean
|
||||
* description: Whether the Gift Card is disabled on creation. You will have to enable it later to make it available to Customers.
|
||||
* ends_at:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: The time at which the Gift Card should no longer be available.
|
||||
* region_id:
|
||||
* description: The id of the Region in which the Gift Card can be used.
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Gift Card
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* gift_card:
|
||||
* $ref: "#/components/schemas/gift_card"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
import _ from "lodash"
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [get] /notifications
|
||||
* operationId: "GetNotifications"
|
||||
* summary: "List Notifications"
|
||||
* description: "Retrieves a list of Notifications."
|
||||
* tags:
|
||||
* - Notification
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* notifications:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: "#/components/schemas/notification"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
const notificationService = req.scope.resolve("notificationService")
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /notifications/{id}/resend
|
||||
* operationId: "PostNotificationsNotificationResend"
|
||||
* summary: "Resend Notification"
|
||||
* description: "Resends a previously sent notifications, with the same data but optionally to a different address"
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Notification
|
||||
* tags:
|
||||
* - Notification
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* notification:
|
||||
* $ref: "#/components/schemas/notification"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -2,6 +2,28 @@ import _ from "lodash"
|
||||
import { Validator, MedusaError } from "medusa-core-utils"
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/shipping-methods
|
||||
* operationId: "PostOrdersOrderShippingMethods"
|
||||
* summary: "Add a Shipping Method"
|
||||
* description: "Adds a Shipping Method to an Order. If another Shipping Method exists with the same Shipping Profile, the previous Shipping Method will be replaced."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* - (body) price=* {integer} The price (excluding VAT) that should be charged for the Shipping Method
|
||||
* - (body) option_id=* {string} The id of the Shipping Option to create the Shipping Method from.
|
||||
* - (body) data=* {object} The data required for the Shipping Option to create a Shipping Method. This will depend on the Fulfillment Provider.
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/**
|
||||
* @oas [post] /orders/{id}/cancel
|
||||
* operationId: "PostOrdersOrderCancel"
|
||||
* summary: "Cancel an Order"
|
||||
* description: "Registers an Order as canceled. This triggers a flow that will cancel any created Fulfillments and Payments, may fail if the Payment or Fulfillment Provider is unable to cancel the Payment/Fulfillment."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/capture
|
||||
* operationId: "PostOrdersOrderCapture"
|
||||
* summary: "Capture an Order"
|
||||
* description: "Captures all the Payments associated with an Order."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,39 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/claims/{claim_id}/shipments
|
||||
* operationId: "PostOrdersOrderClaimsClaimShipments"
|
||||
* summary: "Create Claim Shipment"
|
||||
* description: "Registers a Claim Fulfillment as shipped."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* - (path) claim_id=* {string} The id of the Claim.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* fulfillment_id:
|
||||
* description: The id of the Fulfillment.
|
||||
* type: string
|
||||
* tracking_numbers:
|
||||
* description: The tracking numbers for the shipment.
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id, claim_id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,108 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /order/{id}/claims
|
||||
* operationId: "PostOrdersOrderClaims"
|
||||
* summary: "Create a Claim"
|
||||
* description: "Creates a Claim."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* type:
|
||||
* description: "The type of the Claim. This will determine how the Claim is treated: `replace` Claims will result in a Fulfillment with new items being created, while a `refund` Claim will refund the amount paid for the claimed items."
|
||||
* type: string
|
||||
* enum:
|
||||
* - replace
|
||||
* - refund
|
||||
* claim_items:
|
||||
* description: The Claim Items that the Claim will consist of.
|
||||
* type: array
|
||||
* items:
|
||||
* properties:
|
||||
* item_id:
|
||||
* description: The id of the Line Item that will be claimed.
|
||||
* type: string
|
||||
* quantity:
|
||||
* description: The number of items that will be returned
|
||||
* type: integer
|
||||
* note:
|
||||
* description: Short text describing the Claim Item in further detail.
|
||||
* type: string
|
||||
* reason:
|
||||
* description: The reason for the Claim
|
||||
* type: string
|
||||
* enum:
|
||||
* - missing_item
|
||||
* - wrong_item
|
||||
* - production_failure
|
||||
* - other
|
||||
* tags:
|
||||
* description: A list o tags to add to the Claim Item
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* images:
|
||||
* description: A list of image URL's that will be associated with the Claim
|
||||
* items:
|
||||
* type: string
|
||||
* return_shipping:
|
||||
* description: Optional details for the Return Shipping Method, if the items are to be sent back.
|
||||
* type: object
|
||||
* properties:
|
||||
* option_id:
|
||||
* type: string
|
||||
* description: The id of the Shipping Option to create the Shipping Method from.
|
||||
* price:
|
||||
* type: integer
|
||||
* description: The price to charge for the Shipping Method.
|
||||
* additional_items:
|
||||
* description: The new items to send to the Customer when the Claim type is Replace.
|
||||
* type: array
|
||||
* items:
|
||||
* properties:
|
||||
* variant_id:
|
||||
* description: The id of the Product Variant to ship.
|
||||
* type: string
|
||||
* quantity:
|
||||
* description: The quantity of the Product Variant to ship.
|
||||
* type: integer
|
||||
* shipping_methods:
|
||||
* description: The Shipping Methods to send the additional Line Items with.
|
||||
* type: array
|
||||
* items:
|
||||
* properties:
|
||||
* id:
|
||||
* description: The id of an existing Shipping Method
|
||||
* type: string
|
||||
* option_id:
|
||||
* description: The id of the Shipping Option to create a Shipping Method from
|
||||
* type: string
|
||||
* price:
|
||||
* description: The price to charge for the Shipping Method
|
||||
* type: integer
|
||||
* refund_amount:
|
||||
* description: The amount to refund the Customer when the Claim type is `refund`.
|
||||
* type: integer
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,44 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/fulfillments
|
||||
* operationId: "PostOrdersOrderFulfillments"
|
||||
* summary: "Create a Fulfillment"
|
||||
* description: "Creates a Fulfillment of an Order - will notify Fulfillment Providers to prepare a shipment."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* items:
|
||||
* description: The Line Items to include in the Fulfillment.
|
||||
* type: array
|
||||
* items:
|
||||
* properties:
|
||||
* item_id:
|
||||
* description: The id of Line Item to fulfill.
|
||||
* type: string
|
||||
* quantity:
|
||||
* description: The quantity of the Line Item to fulfill.
|
||||
* type: integer
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,38 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/shipment
|
||||
* operationId: "PostOrdersOrderShipment"
|
||||
* summary: "Create a Shipment"
|
||||
* description: "Registers a Fulfillment as shipped."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* fulfillment_id:
|
||||
* description: The id of the Fulfillment.
|
||||
* type: string
|
||||
* tracking_numbers:
|
||||
* description: The tracking numbers for the shipment.
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,39 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/swaps/{swap_id}/shipments
|
||||
* operationId: "PostOrdersOrderSwapsSwapShipments"
|
||||
* summary: "Create Swap Shipment"
|
||||
* description: "Registers a Swap Fulfillment as shipped."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* - (path) swap_id=* {string} The id of the Swap.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* fulfillment_id:
|
||||
* description: The id of the Fulfillment.
|
||||
* type: string
|
||||
* tracking_numbers:
|
||||
* description: The tracking numbers for the shipment.
|
||||
* type: array
|
||||
* items:
|
||||
* type: string
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id, swap_id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,62 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultFields, defaultRelations } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /order/{id}/swaps
|
||||
* operationId: "PostOrdersOrderSwaps"
|
||||
* summary: "Create a Swap"
|
||||
* description: "Creates a Swap. Swaps are used to handle Return of previously purchased goods and Fulfillment of replacements simultaneously."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Swap.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* return_items:
|
||||
* description: The Line Items to return as part of the Swap.
|
||||
* type: array
|
||||
* items:
|
||||
* properties:
|
||||
* item_id:
|
||||
* description: The id of the Line Item that will be claimed.
|
||||
* type: string
|
||||
* quantity:
|
||||
* description: The number of items that will be returned
|
||||
* type: integer
|
||||
* return_shipping:
|
||||
* description: How the Swap will be returned.
|
||||
* type: object
|
||||
* properties:
|
||||
* option_id:
|
||||
* type: string
|
||||
* description: The id of the Shipping Option to create the Shipping Method from.
|
||||
* price:
|
||||
* type: integer
|
||||
* description: The price to charge for the Shipping Method.
|
||||
* additional_items:
|
||||
* description: The new items to send to the Customer.
|
||||
* type: array
|
||||
* items:
|
||||
* properties:
|
||||
* variant_id:
|
||||
* description: The id of the Product Variant to ship.
|
||||
* type: string
|
||||
* quantity:
|
||||
* description: The quantity of the Product Variant to ship.
|
||||
* type: integer
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/**
|
||||
* @oas [delete] /order/{id}/metadata/{key}
|
||||
* operationId: "DeleteOrdersOrderMetadataKey"
|
||||
* summary: "Delete Metadata"
|
||||
* description: "Deletes a metadata key."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* - (path) key=* {string} The metadata key.
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id, key } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/claims/{claim_id}/fulfillments
|
||||
* operationId: "PostOrdersOrderClaimsClaimFulfillments"
|
||||
* summary: "Create a Claim Fulfillment"
|
||||
* description: "Creates a Fulfillment for a Claim."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* - (path) claim_id=* {string} The id of the Claim.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id, claim_id } = req.params
|
||||
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
import { MedusaError, Validator } from "medusa-core-utils"
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [post] /orders/{id}/swaps/{swap_id}/fulfillments
|
||||
* operationId: "PostOrdersOrderSwapsSwapFulfillments"
|
||||
* summary: "Create a Swap Fulfillment"
|
||||
* description: "Creates a Fulfillment for a Swap."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* - (path) swap_id=* {string} The id of the Swap.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* metadata:
|
||||
* description: An optional set of key-value pairs to hold additional information.
|
||||
* type: object
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id, swap_id } = req.params
|
||||
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
import { defaultRelations, defaultFields } from "./"
|
||||
|
||||
/**
|
||||
* @oas [get] /orders/{id}
|
||||
* operationId: "GetOrdersOrder"
|
||||
* summary: "Retrieve an Order"
|
||||
* description: "Retrieves an Order"
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user