diff --git a/cypress/apiRequests/Channels.js b/cypress/apiRequests/Channels.js index cb21f81c7..27bdca4e4 100644 --- a/cypress/apiRequests/Channels.js +++ b/cypress/apiRequests/Channels.js @@ -54,3 +54,15 @@ export function deleteChannel(channelId, targetChannelId) { }`; return cy.sendRequestWithQuery(deleteChannelMutation); } + +export function activateChannel(channelId) { + const mutation = `mutation{ + channelActivate(id:"${channelId}"){ + errors{ + field + message + } + } + }`; + return cy.sendRequestWithQuery(mutation); +} diff --git a/cypress/apiRequests/ShippingMethod.js b/cypress/apiRequests/ShippingMethod.js index f41720d97..0e6ab0a65 100644 --- a/cypress/apiRequests/ShippingMethod.js +++ b/cypress/apiRequests/ShippingMethod.js @@ -1,3 +1,5 @@ +import { getValueWithDefault } from "./utils/Utils"; + export function createShippingRate(name, shippingZone) { const mutation = `mutation{ shippingPriceCreate(input:{ @@ -14,16 +16,24 @@ export function createShippingRate(name, shippingZone) { } export function createShippingZone(name, country, channelId) { + const channelsLines = getValueWithDefault( + channelId, + `addChannels:["${channelId}"]` + ); const mutation = `mutation{ shippingZoneCreate(input:{ name: "${name}" countries: "${country}" - addChannels:["${channelId}"] + ${channelsLines} }){ shippingZone{ id name } + errors{ + message + field + } } }`; return cy @@ -77,17 +87,33 @@ export function deleteShippingZone(shippingZoneId) { export function getShippingZones() { const query = `query{ - shippingZones(first:100){ - edges{ - node{ - name - id - } - } - } + shippingZones(first:100){ + edges{ + node{ + name + id } - `; + } + } + } + `; return cy .sendRequestWithQuery(query) .then(resp => resp.body.data.shippingZones.edges); } + +export function getShippingZone(shippingZoneId) { + const query = `query{ + shippingZone(id:"${shippingZoneId}"){ + id + name + channels{ + name + id + } + } + } `; + return cy + .sendRequestWithQuery(query) + .then(resp => resp.body.data.shippingZone); +} diff --git a/cypress/elements/channels/add-channel-form-selectors.js b/cypress/elements/channels/add-channel-form-selectors.js index c6364df78..fda52da8f 100644 --- a/cypress/elements/channels/add-channel-form-selectors.js +++ b/cypress/elements/channels/add-channel-form-selectors.js @@ -8,5 +8,7 @@ export const ADD_CHANNEL_FORM_SELECTORS = { currencyValidationMessage: "[data-testid='currency-text-input-helper-text']", slugValidationMessage: "[data-testid='slug-text-input-helper-text']", currencyAutocompleteDropdown: - "[data-test='singleautocomplete-select-option'][data-test-type='custom']" + "[data-test='singleautocomplete-select-option'][data-test-type='custom']", + addShippingZoneButton: '[data-test-id="add-shipping-zone-button"]', + shippingAutocompleteSelect: "[data-test-id='shippingAutoCompleteSelect']" }; diff --git a/cypress/integration/allEnv/configuration/channels.js b/cypress/integration/allEnv/configuration/channels.js index f12d1c448..f1d03dc79 100644 --- a/cypress/integration/allEnv/configuration/channels.js +++ b/cypress/integration/allEnv/configuration/channels.js @@ -2,29 +2,37 @@ import faker from "faker"; import { createChannel } from "../../../apiRequests/Channels"; +import { + createShippingZone, + getShippingZone +} from "../../../apiRequests/ShippingMethod"; import { ONE_PERMISSION_USERS } from "../../../Data/users"; import { PRODUCTS_LIST } from "../../../elements/catalog/products/products-list"; import { ADD_CHANNEL_FORM_SELECTORS } from "../../../elements/channels/add-channel-form-selectors"; import { AVAILABLE_CHANNELS_FORM } from "../../../elements/channels/available-channels-form"; -import { CHANNEL_FORM_SELECTORS } from "../../../elements/channels/channel-form-selectors"; import { CHANNELS_SELECTORS } from "../../../elements/channels/channels-selectors"; import { SELECT_CHANNELS_TO_ASSIGN } from "../../../elements/channels/select-channels-to-assign"; import { HEADER_SELECTORS } from "../../../elements/header/header-selectors"; -import { DRAFT_ORDER_SELECTORS } from "../../../elements/orders/draft-order-selectors"; -import { ORDERS_SELECTORS } from "../../../elements/orders/orders-selectors"; import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors"; import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements"; import { createChannelByView } from "../../../steps/channelsSteps"; import { urlList } from "../../../url/urlList"; import { deleteChannelsStartsWith } from "../../../utils/channelsUtils"; +import { deleteShippingStartsWith } from "../../../utils/shippingUtils"; describe("Channels", () => { - const channelStartsWith = `CyChannels:`; + const channelStartsWith = `CyChannels`; + const randomName = `${channelStartsWith} ${faker.datatype.number()}`; const currency = "PLN"; + let shippingZone; before(() => { cy.clearSessionData().loginUserViaRequest(); deleteChannelsStartsWith(channelStartsWith); + deleteShippingStartsWith(channelStartsWith); + createShippingZone(randomName, "US").then(shippingZoneResp => { + shippingZone = shippingZoneResp; + }); }); beforeEach(() => { @@ -39,11 +47,11 @@ describe("Channels", () => { cy.addAliasToGraphRequest("Channels"); cy.visit(urlList.channels); cy.wait("@Channels"); - cy.addAliasToGraphRequest("Channel"); - createChannelByView(randomChannel, currency); + createChannelByView({ name: randomChannel, currency }); + cy.wait("@Channel"); + // New channel should be visible in channels list - cy.wait("@Channel") - .get(ADD_CHANNEL_FORM_SELECTORS.backToChannelsList) + cy.get(ADD_CHANNEL_FORM_SELECTORS.backToChannelsList) .click() .get(CHANNELS_SELECTORS.channelsTable) .contains(randomChannel); @@ -72,6 +80,28 @@ describe("Channels", () => { .contains(randomChannel); }); + it("should create channel with shippingZone", () => { + // remove login after fixing SALEOR-3162 + cy.clearSessionData().loginUserViaRequest(); + + const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`; + cy.addAliasToGraphRequest("Channels"); + cy.visit(urlList.channels); + cy.wait("@Channels"); + createChannelByView({ + name: randomChannel, + currency, + shippingZone: shippingZone.name + }); + cy.wait("@Channel"); + getShippingZone(shippingZone.id).then(shippingZoneResp => { + const assignedChannel = shippingZoneResp.channels.find( + channel => channel.name === randomChannel + ); + expect(assignedChannel).to.be.ok; + }); + }); + it("should validate slug name", () => { const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`; createChannel({ @@ -81,7 +111,7 @@ describe("Channels", () => { currencyCode: currency }); cy.visit(urlList.channels); - createChannelByView(randomChannel, currency); + createChannelByView({ name: randomChannel, currency }); cy.get(ADD_CHANNEL_FORM_SELECTORS.slugValidationMessage).should( "be.visible" ); @@ -90,7 +120,10 @@ describe("Channels", () => { it("should validate duplicated currency", () => { const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`; cy.visit(urlList.channels); - createChannelByView(randomChannel, "notExistingCurrency"); + createChannelByView({ + name: randomChannel, + currency: "notExistingCurrency" + }); cy.get(ADD_CHANNEL_FORM_SELECTORS.currencyValidationMessage).should( "be.visible" ); @@ -119,32 +152,4 @@ describe("Channels", () => { .contains(randomChannelToDelete) .should("not.exist"); }); - - it("should not be possible to add products to order with inactive channel", () => { - const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`; - createChannel({ - isActive: false, - name: randomChannel, - slug: randomChannel, - currencyCode: currency - }); - cy.clearSessionData().loginUserViaRequest(); - cy.visit(urlList.orders) - .get(ORDERS_SELECTORS.createOrder) - .click() - .get(CHANNEL_FORM_SELECTORS.channelSelect) - .click() - .get(CHANNEL_FORM_SELECTORS.channelOption) - .contains(randomChannel) - .click() - .get(CHANNEL_FORM_SELECTORS.confirmButton) - .click(); - cy.location() - .should(loc => { - const urlRegex = new RegExp(`${urlList.orders}.+`, "g"); - expect(loc.pathname).to.match(urlRegex); - }) - .get(DRAFT_ORDER_SELECTORS.addProducts) - .should("not.exist"); - }); }); diff --git a/cypress/integration/allEnv/configuration/inactiveChannel.js b/cypress/integration/allEnv/configuration/inactiveChannel.js new file mode 100644 index 000000000..38816cadd --- /dev/null +++ b/cypress/integration/allEnv/configuration/inactiveChannel.js @@ -0,0 +1,148 @@ +// +import faker from "faker"; + +import { activateChannel, createChannel } from "../../../apiRequests/Channels"; +import { createCheckout } from "../../../apiRequests/Checkout"; +import { getProductDetails } from "../../../apiRequests/storeFront/ProductDetails"; +import { CHANNEL_FORM_SELECTORS } from "../../../elements/channels/channel-form-selectors"; +import { DRAFT_ORDER_SELECTORS } from "../../../elements/orders/draft-order-selectors"; +import { ORDERS_SELECTORS } from "../../../elements/orders/orders-selectors"; +import { urlList } from "../../../url/urlList"; +import { + deleteChannelsStartsWith, + getDefaultChannel +} from "../../../utils/channelsUtils"; +import { + createProductInChannel, + createTypeAttributeAndCategoryForProduct, + deleteProductsStartsWith +} from "../../../utils/products/productsUtils"; +import { isProductVisible } from "../../../utils/storeFront/storeFrontProductUtils"; + +describe("Tests on inactive channel", () => { + const channelStartsWith = `InactiveChannel`; + const randomName = `${channelStartsWith}${faker.datatype.number()}`; + const currency = "PLN"; + + let address; + let defaultChannel; + let newChannel; + + before(() => { + cy.clearSessionData().loginUserViaRequest(); + deleteChannelsStartsWith(channelStartsWith); + deleteProductsStartsWith(channelStartsWith); + cy.fixture("addresses").then(({ plAddress }) => { + address = plAddress; + }); + getDefaultChannel().then(channel => (defaultChannel = channel)); + createChannel({ + isActive: false, + name: randomName, + slug: randomName, + currencyCode: currency + }).then(channel => { + newChannel = channel; + }); + }); + + beforeEach(() => { + cy.clearSessionData().loginUserViaRequest(); + }); + + it("should not be possible to add products to order with inactive channel", () => { + cy.visit(urlList.orders) + .get(ORDERS_SELECTORS.createOrder) + .click() + .get(CHANNEL_FORM_SELECTORS.channelSelect) + .click() + .get(CHANNEL_FORM_SELECTORS.channelOption) + .contains(newChannel.name) + .click() + .get(CHANNEL_FORM_SELECTORS.confirmButton) + .click(); + cy.location() + .should(loc => { + const urlRegex = new RegExp(`${urlList.orders}.+`, "g"); + expect(loc.pathname).to.match(urlRegex); + }) + .get(DRAFT_ORDER_SELECTORS.addProducts) + .should("not.exist"); + }); + + it("should not be possible to create checkout with inactive channel", () => { + const randomChannel = `${channelStartsWith}${faker.datatype.number()}`; + createTypeAttributeAndCategoryForProduct(randomChannel) + .then(({ productType, attribute, category }) => { + createProductInChannel({ + name: randomChannel, + channelId: defaultChannel.id, + productTypeId: productType.id, + attributeId: attribute.id, + categoryId: category.id + }); + }) + .then(({ variantsList }) => { + createCheckout({ + channelSlug: newChannel.slug, + email: "example@example.com", + variantsList, + address + }); + }) + .then(({ errors }) => { + expect( + errors[0], + "checkout shouldn't be created with error in field channel" + ).to.have.property("field", "channel"); + }); + }); + + it("products in inactive channel should not be displayed", () => { + const randomChannel = `${channelStartsWith}${faker.datatype.number()}`; + let channel; + let product; + + createChannel({ + isActive: false, + name: randomChannel, + slug: randomChannel, + currencyCode: currency + }) + .then(channelResp => { + channel = channelResp; + createTypeAttributeAndCategoryForProduct(randomChannel); + }) + .then(({ productType, attribute, category }) => { + createProductInChannel({ + name: randomChannel, + channelId: channel.id, + productTypeId: productType.id, + attributeId: attribute.id, + categoryId: category.id + }); + }) + .then(({ product: productResp }) => { + product = productResp; + getProductDetails(product.id, channel.slug); + }) + .then(resp => { + const isVisible = isProductVisible(resp, randomChannel); + expect( + isVisible, + "product with inactive channel shouldn't be visible" + ).to.be.eq(false); + activateChannel(channel.id); + }) + .then(() => { + getProductDetails(product.id, channel.slug); + }) + .then(resp => { + const isVisible = isProductVisible(resp, randomChannel); + expect( + isVisible, + "product with active channel should be visible" + ).to.be.eq(true); + }); + }); +}); diff --git a/cypress/integration/allEnv/products/productsVariants.js b/cypress/integration/allEnv/products/productsVariants.js index 3961c0feb..4ce1e868b 100644 --- a/cypress/integration/allEnv/products/productsVariants.js +++ b/cypress/integration/allEnv/products/productsVariants.js @@ -160,16 +160,12 @@ describe("Creating variants", () => { const name = `${startsWith}${faker.datatype.number()}`; const variantsPrice = 10; let createdProduct; - // createChannel({ isActive: true, name, currencyCode: "PLN" }) - // .then(resp => { - // newChannel = resp; createProduct({ attributeId: attribute.id, name, productTypeId: productType.id, categoryId: category.id }) - // }) .then(productResp => { createdProduct = productResp; updateChannelInProduct({ diff --git a/cypress/steps/channelsSteps.js b/cypress/steps/channelsSteps.js index 13090fa57..286caf875 100644 --- a/cypress/steps/channelsSteps.js +++ b/cypress/steps/channelsSteps.js @@ -5,9 +5,16 @@ import { CHANNELS_SELECTORS } from "../elements/channels/channels-selectors"; import { SELECT_CHANNELS_TO_ASSIGN } from "../elements/channels/select-channels-to-assign"; import { HEADER_SELECTORS } from "../elements/header/header-selectors"; import { BUTTON_SELECTORS } from "../elements/shared/button-selectors"; +import { fillAutocompleteSelect } from "./shared/autocompleteSelect"; -export function createChannelByView(name, currency, slug = name) { - cy.get(CHANNELS_SELECTORS.createChannelButton) +export function createChannelByView({ + name, + currency, + slug = name, + shippingZone +}) { + cy.addAliasToGraphRequest("Channel") + .get(CHANNELS_SELECTORS.createChannelButton) .click() .get(ADD_CHANNEL_FORM_SELECTORS.channelName) .type(name) @@ -23,8 +30,23 @@ export function createChannelByView(name, currency, slug = name) { cy.get(ADD_CHANNEL_FORM_SELECTORS.currencyAutocompleteDropdown).click(); } }); + if (shippingZone) { + addShippingZone(shippingZone); + } cy.get(ADD_CHANNEL_FORM_SELECTORS.saveButton).click(); } + +export function addShippingZone(shippingZone) { + cy.get(BUTTON_SELECTORS.expandIcon) + .click() + .get(ADD_CHANNEL_FORM_SELECTORS.addShippingZoneButton) + .click(); + fillAutocompleteSelect( + ADD_CHANNEL_FORM_SELECTORS.shippingAutocompleteSelect, + shippingZone + ); +} + export function selectChannelInPicker(channelName) { cy.get(CHANNEL_FORM_SELECTORS.channelSelect).click(); cy.contains(CHANNEL_FORM_SELECTORS.channelOption, channelName) @@ -32,6 +54,7 @@ export function selectChannelInPicker(channelName) { .get(CHANNEL_FORM_SELECTORS.confirmButton) .click(); } + export function selectChannelInHeader(channelName) { cy.get(HEADER_SELECTORS.channelSelect) .click() @@ -39,6 +62,7 @@ export function selectChannelInHeader(channelName) { .contains(channelName) .click(); } + export function selectChannelInDetailsPages(channelName) { cy.get(AVAILABLE_CHANNELS_FORM.menageChannelsButton) .click() @@ -58,6 +82,7 @@ export function selectChannelInDetailsPages(channelName) { .find(BUTTON_SELECTORS.submit) .click(); } + export function selectChannelVariantInDetailsPage(channelName, attributeName) { cy.get(AVAILABLE_CHANNELS_FORM.menageChannelsButton).click(); cy.contains(SELECT_CHANNELS_TO_ASSIGN.expandChannelRow, channelName) diff --git a/src/channels/components/ShippingZonesCard/ShippingZonesCardListFooter.tsx b/src/channels/components/ShippingZonesCard/ShippingZonesCardListFooter.tsx index 90ca63ace..1755fbcbe 100644 --- a/src/channels/components/ShippingZonesCard/ShippingZonesCardListFooter.tsx +++ b/src/channels/components/ShippingZonesCard/ShippingZonesCardListFooter.tsx @@ -51,6 +51,7 @@ const ShippingZonesCardListFooter: React.FC =