fix: enforce 1 shipping method per profile (#322)

prevents the scenario where multiple concurrent calls to insert a shipping method may lead to an inconsistent cart state with more than 1 shipping method per profile.
This commit is contained in:
Zakaria El Asri
2021-07-23 11:26:20 +01:00
committed by GitHub
parent 8c26a5fd88
commit b378a4f8bc
3 changed files with 71 additions and 1 deletions

View File

@@ -206,6 +206,65 @@ describe("/store/carts", () => {
});
});
describe("POST /store/carts/:id/shipping-methods", () => {
beforeEach(async () => {
await cartSeeder(dbConnection);
});
afterEach(async () => {
const manager = dbConnection.manager;
await doAfterEach(manager);
});
it("adds a shipping method to cart", async () => {
const api = useApi();
const cartWithShippingMethod = await api.post(
"/store/carts/test-cart/shipping-methods",
{
option_id: "test-option",
},
{ withCredentials: true }
);
expect(cartWithShippingMethod.data.cart.shipping_methods).toContainEqual(
expect.objectContaining({ shipping_option_id: "test-option" })
);
expect(cartWithShippingMethod.status).toEqual(200);
});
it("adds no more than 1 shipping method per shipping profile", async () => {
const api = useApi();
const addShippingMethod = async (option_id) => {
return await api.post(
"/store/carts/test-cart/shipping-methods",
{
option_id,
},
{ withCredentials: true }
);
};
await addShippingMethod("test-option");
const cartWithAnotherShippingMethod = await addShippingMethod(
"test-option-2"
);
expect(
cartWithAnotherShippingMethod.data.cart.shipping_methods.length
).toEqual(1);
expect(
cartWithAnotherShippingMethod.data.cart.shipping_methods
).toContainEqual(
expect.objectContaining({
shipping_option_id: "test-option-2",
price: 500,
})
);
expect(cartWithAnotherShippingMethod.status).toEqual(200);
});
});
describe("DELETE /store/carts/:id/discounts/:code", () => {
beforeEach(async () => {
try {

View File

@@ -100,6 +100,17 @@ module.exports = async (connection, data = {}) => {
data: {},
});
await manager.insert(ShippingOption, {
id: "test-option-2",
name: "test-option-2",
provider_id: "test-ful",
region_id: "test-region",
profile_id: defaultProfile.id,
price_type: "flat_rate",
amount: 500,
data: {},
});
const cart = manager.create(Cart, {
id: "test-cart",
customer_id: "some-customer",

View File

@@ -1365,7 +1365,7 @@ class CartService extends BaseService {
.withTransaction(manager)
.emit(CartService.Events.UPDATED, result)
return result
})
}, "SERIALIZABLE")
}
/**