diff --git a/cypress/elements/siteSettings/site-settings-details.js b/cypress/elements/siteSettings/site-settings-details.js
index 8272239f8..4cb90a3e9 100644
--- a/cypress/elements/siteSettings/site-settings-details.js
+++ b/cypress/elements/siteSettings/site-settings-details.js
@@ -1,4 +1,8 @@
export const SITE_SETTINGS_DETAILS = {
nameInput: '[name="name"]',
- descriptionInput: '[name="description"]'
+ descriptionInput: '[name="description"]',
+ stockReservationAuthenticatedUserInput:
+ '[name="reserveStockDurationAuthenticatedUser"]',
+ stockReservationAnonymousUserInput:
+ '[name="reserveStockDurationAnonymousUser"]'
};
diff --git a/cypress/integration/orders/manageStockReservation.js b/cypress/integration/orders/manageStockReservation.js
new file mode 100644
index 000000000..86809884e
--- /dev/null
+++ b/cypress/integration/orders/manageStockReservation.js
@@ -0,0 +1,180 @@
+///
+///
+
+import faker from "faker";
+
+import { createCheckout } from "../../support/api/requests/Checkout";
+import { updateStockReservation } from "../../support/api/requests/ShopSettings";
+import { getDefaultChannel } from "../../support/api/utils/channelsUtils";
+import {
+ createProductInChannel,
+ createTypeAttributeAndCategoryForProduct,
+ deleteProductsStartsWith
+} from "../../support/api/utils/products/productsUtils";
+import {
+ createShipping,
+ deleteShippingStartsWith
+} from "../../support/api/utils/shippingUtils";
+import filterTests from "../../support/filterTests";
+import {
+ enterSiteSettingAndSetStockReservation,
+ userType
+} from "../../support/pages/siteSettings";
+
+filterTests({ definedTags: ["all"], version: "3.1.0" }, () => {
+ describe("As an admin I want to manage stock reservation", () => {
+ const startsWith = "manageStocks";
+ const name = `${startsWith}${faker.datatype.number()}`;
+ const productQuantity = 10;
+ const customerType = {
+ authenticated: "auth",
+ anonymous: "token"
+ };
+
+ let defaultChannel;
+ let address;
+ let warehouse;
+ let attribute;
+ let category;
+ let productType;
+ let dataForCheckout;
+
+ before(() => {
+ cy.clearSessionData().loginUserViaRequest();
+ deleteProductsStartsWith(startsWith);
+ deleteShippingStartsWith(startsWith);
+ cy.fixture("addresses")
+ .then(addresses => {
+ address = addresses.usAddress;
+ getDefaultChannel();
+ })
+ .then(channel => {
+ defaultChannel = channel;
+ createShipping({
+ channelId: defaultChannel.id,
+ name,
+ address
+ });
+ })
+ .then(({ warehouse: warehouseResp }) => {
+ warehouse = warehouseResp;
+ createTypeAttributeAndCategoryForProduct({ name });
+ })
+ .then(
+ ({
+ attribute: attributeResp,
+ category: categoryResp,
+ productType: productTypeResp
+ }) => {
+ attribute = attributeResp;
+ category = categoryResp;
+ productType = productTypeResp;
+ }
+ );
+ });
+
+ beforeEach(() => {
+ const productName = `${startsWith}${faker.datatype.number()}`;
+
+ cy.clearSessionData().loginUserViaRequest();
+
+ createProductInChannel({
+ attributeId: attribute.id,
+ categoryId: category.id,
+ channelId: defaultChannel.id,
+ name: productName,
+ productTypeId: productType.id,
+ warehouseId: warehouse.id,
+ quantityInWarehouse: productQuantity
+ }).then(({ variantsList }) => {
+ dataForCheckout = {
+ email: "example@example.pl",
+ address,
+ channelSlug: defaultChannel.slug,
+ variantsList,
+ productQuantity
+ };
+ });
+ });
+
+ it("should be able to set stock reservation for authenticated customer in checkout. TC: SALEOR_0415", () => {
+ dataForCheckout.auth = customerType.authenticated;
+
+ updateStockReservation({})
+ .then(() => {
+ enterSiteSettingAndSetStockReservation(userType.authenticated, 10);
+ createCheckout(dataForCheckout);
+ })
+ .then(({ checkout }) => {
+ expect(checkout).to.be.ok;
+ createCheckout(dataForCheckout);
+ })
+ .then(resp => {
+ expect(resp.errors, "there should be errors in response").to.not.be
+ .empty;
+ expect(
+ resp.errors[0].field,
+ "error should be on field quantity"
+ ).to.be.eq("quantity");
+ });
+ });
+
+ it("should be able to set stock reservation for anonymous customer in checkout. TC: SALEOR_0416", () => {
+ dataForCheckout.auth = customerType.anonymous;
+
+ updateStockReservation({})
+ .then(() => {
+ enterSiteSettingAndSetStockReservation(userType.anonymous, 10);
+ createCheckout(dataForCheckout);
+ })
+ .then(({ checkout }) => {
+ expect(checkout).to.be.ok;
+ createCheckout(dataForCheckout);
+ })
+ .then(resp => {
+ expect(resp.errors, "there should be errors in response").to.not.be
+ .empty;
+ expect(
+ resp.errors[0].field,
+ "error should be on field quantity"
+ ).to.be.eq("quantity");
+ });
+ });
+
+ it("should be able to leave empty stock reservation for authenticated customer in checkout. TC: SALEOR_0417", () => {
+ dataForCheckout.auth = customerType.authenticated;
+
+ updateStockReservation({ authenticatedUserStock: 10 })
+ .then(() => {
+ enterSiteSettingAndSetStockReservation(userType.authenticated);
+ createCheckout(dataForCheckout);
+ })
+ .then(({ checkout }) => {
+ expect(checkout).to.be.ok;
+ createCheckout(dataForCheckout);
+ })
+ .then(resp => {
+ expect(resp.errors, "there should be no errors in response").to.be
+ .empty;
+ });
+ });
+
+ it("should be able to leave empty stock reservation for anonymous customer in checkout. TC: SALEOR_0418", () => {
+ dataForCheckout.auth = customerType.anonymous;
+
+ updateStockReservation({ anonymousUserStock: 10 })
+ .then(() => {
+ enterSiteSettingAndSetStockReservation(userType.anonymous);
+ createCheckout(dataForCheckout);
+ })
+ .then(({ checkout }) => {
+ expect(checkout).to.be.ok;
+ createCheckout(dataForCheckout);
+ })
+ .then(resp => {
+ expect(resp.errors, "there should be no errors in response").to.be
+ .empty;
+ });
+ });
+ });
+});
diff --git a/cypress/support/api/requests/Checkout.js b/cypress/support/api/requests/Checkout.js
index 598a77f7a..e9866a5ce 100644
--- a/cypress/support/api/requests/Checkout.js
+++ b/cypress/support/api/requests/Checkout.js
@@ -32,10 +32,12 @@ export function createCheckout({
}`
);
+ const emailLine = getValueWithDefault(email, `email: "${email}"`);
+
const mutation = `mutation{
checkoutCreate(input:{
channel:"${channelSlug}"
- email:"${email}"
+ ${emailLine}
lines: [${lines.join()}]
${shippingAddress}
${billingAddressLines}
diff --git a/cypress/support/api/requests/ShopSettings.js b/cypress/support/api/requests/ShopSettings.js
index 8e9aaa606..035c6b21f 100644
--- a/cypress/support/api/requests/ShopSettings.js
+++ b/cypress/support/api/requests/ShopSettings.js
@@ -20,6 +20,28 @@ export function updateShopWeightUnit(weightUnit) {
.its("body.data.shopSettingsUpdate");
}
+export function updateStockReservation({
+ authenticatedUserStock = 0,
+ anonymousUserStock = 0
+}) {
+ const mutation = `mutation{
+ shopSettingsUpdate(input:{
+ reserveStockDurationAnonymousUser: ${anonymousUserStock},
+ reserveStockDurationAuthenticatedUser: ${authenticatedUserStock}
+ }){
+ errors{
+ field
+ message
+ }
+ shop{
+ reserveStockDurationAnonymousUser,
+ reserveStockDurationAuthenticatedUser
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation).its("body.data.shopSettingsUpdate");
+}
+
export function updateShopAddress(address) {
const input = getDefaultAddress(address, "input");
const mutation = `mutation{
diff --git a/cypress/support/pages/siteSettings.js b/cypress/support/pages/siteSettings.js
new file mode 100644
index 000000000..e32eb84fd
--- /dev/null
+++ b/cypress/support/pages/siteSettings.js
@@ -0,0 +1,21 @@
+import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
+import { SITE_SETTINGS_DETAILS } from "../../elements/siteSettings/site-settings-details";
+import { urlList } from "../../fixtures/urlList";
+
+export function enterSiteSettingAndSetStockReservation(userType, stockAmount) {
+ cy.visitAndWaitForProgressBarToDisappear(urlList.siteSettings);
+ if (stockAmount) {
+ cy.get(userType).clearAndType(stockAmount);
+ } else {
+ cy.get(userType).clear();
+ }
+ cy.addAliasToGraphRequest("ShopSettingsUpdate")
+ .get(BUTTON_SELECTORS.confirm)
+ .click()
+ .waitForRequestAndCheckIfNoErrors("@ShopSettingsUpdate");
+}
+
+export const userType = {
+ anonymous: SITE_SETTINGS_DETAILS.stockReservationAnonymousUserInput,
+ authenticated: SITE_SETTINGS_DETAILS.stockReservationAuthenticatedUserInput
+};