Saleor 1745 tests for discounts sales (#998)

* test plan for sales - discounts

* create sale

* passing tests for sales

* tests for collections

* remove eslint diable in sales tests

* remove eslint-disable

* move shared selectors

* move shared selectors

* fix indentation in requests

* add formatDate function

* remove moment

* remove moment
This commit is contained in:
Karolina 2021-03-12 15:57:02 +01:00 committed by GitHub
parent fc597a7a7f
commit 746ce8b95f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 864 additions and 522 deletions

View file

@ -1,39 +1,39 @@
export function createAttribute(name, attributeValues = ["value"]) { export function createAttribute(name, attributeValues = ["value"]) {
const values = attributeValues.map(element => `{name:"${element}"}`); const values = attributeValues.map(element => `{name:"${element}"}`);
const mutation = `mutation{ const mutation = `mutation{
attributeCreate(input:{ attributeCreate(input:{
name:"${name}" name:"${name}"
valueRequired:false valueRequired:false
type:PRODUCT_TYPE type:PRODUCT_TYPE
values: [${values}] values: [${values}]
}){ }){
attribute{ attribute{
id id
name name
values{name} values{name}
} }
attributeErrors{ attributeErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function getAttributes(first, search) { export function getAttributes(first, search) {
const mutation = `query{ const mutation = `query{
attributes(first:${first}, filter:{ attributes(first:${first}, filter:{
search:"${search}" search:"${search}"
}){ }){
edges{ edges{
node{ node{
id id
name name
} }
} }
} }
}`; }`;
return cy return cy
.sendRequestWithQuery(mutation) .sendRequestWithQuery(mutation)
.then(resp => resp.body.data.attributes.edges); .then(resp => resp.body.data.attributes.edges);
@ -41,12 +41,12 @@ export function getAttributes(first, search) {
export function deleteAttribute(attributeId) { export function deleteAttribute(attributeId) {
const mutation = `mutation{ const mutation = `mutation{
attributeDelete(id:"${attributeId}"){ attributeDelete(id:"${attributeId}"){
attributeErrors{ attributeErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -1,42 +1,42 @@
export function createCategory(name, slug = name) { export function createCategory(name, slug = name) {
const mutation = `mutation{ const mutation = `mutation{
categoryCreate(input:{name:"${name}", slug: "${slug}"}){ categoryCreate(input:{name:"${name}", slug: "${slug}"}){
productErrors{ productErrors{
field field
message message
} }
category{ category{
id id
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function getCategories(first, search) { export function getCategories(first, search) {
const mutation = `query{ const mutation = `query{
categories(first:${first}, filter:{ categories(first:${first}, filter:{
search:"${search}" search:"${search}"
}){ }){
edges{ edges{
node{ node{
id id
name name
} }
} }
} }
}`; }`;
return cy return cy
.sendRequestWithQuery(mutation) .sendRequestWithQuery(mutation)
.then(resp => resp.body.data.categories.edges); .then(resp => resp.body.data.categories.edges);
} }
export function deleteCategory(categoryId) { export function deleteCategory(categoryId) {
const mutation = `mutation{ const mutation = `mutation{
categoryDelete(id:"${categoryId}"){ categoryDelete(id:"${categoryId}"){
productErrors{ productErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -1,50 +1,49 @@
export function createChannel(isActive, name, slug, currencyCode) { export function createChannel(isActive, name, slug, currencyCode) {
const createChannelMutation = `mutation{ const createChannelMutation = `mutation{
channelCreate(input: { channelCreate(input: {
isActive: ${isActive} isActive: ${isActive}
name: "${name}" name: "${name}"
slug: "${slug}" slug: "${slug}"
currencyCode: "${currencyCode}" currencyCode: "${currencyCode}"
}){ }){
channel{ channel{
id id
name name
slug slug
} }
channelErrors{ channelErrors{
code code
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(createChannelMutation); return cy.sendRequestWithQuery(createChannelMutation);
} }
export function getChannels() { export function getChannels() {
const getChannelsInfoQuery = `query{ const getChannelsInfoQuery = `query{
channels{ channels{
name name
id id
isActive isActive
slug slug
currencyCode currencyCode
}
} }
`; }`;
return cy.sendRequestWithQuery(getChannelsInfoQuery); return cy.sendRequestWithQuery(getChannelsInfoQuery);
} }
export function deleteChannel(channelId, targetChannelId) { export function deleteChannel(channelId, targetChannelId) {
const deleteChannelMutation = `mutation{ const deleteChannelMutation = `mutation{
channelDelete(id: "${channelId}", input:{ channelDelete(id: "${channelId}", input:{
targetChannel: "${targetChannelId}" targetChannel: "${targetChannelId}"
}){ }){
channel{ channel{
name name
} }
channelErrors{ channelErrors{
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(deleteChannelMutation); return cy.sendRequestWithQuery(deleteChannelMutation);
} }

View file

@ -9,63 +9,63 @@ export function createCheckout(
variantId:"${variant.id}"}` variantId:"${variant.id}"}`
); );
const mutation = `mutation{ const mutation = `mutation{
checkoutCreate(input:{ checkoutCreate(input:{
channel:"${channelSlug}" channel:"${channelSlug}"
email:"${email}" email:"${email}"
lines: [${lines.join()}] lines: [${lines.join()}]
}){ }){
checkoutErrors{ checkoutErrors{
field field
message message
} }
created created
checkout{ checkout{
id id
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function addShippingMethod(checkoutId, shippingMethodId) { export function addShippingMethod(checkoutId, shippingMethodId) {
const mutation = `mutation{ const mutation = `mutation{
checkoutShippingMethodUpdate(checkoutId:"${checkoutId}", checkoutShippingMethodUpdate(checkoutId:"${checkoutId}",
shippingMethodId:"${shippingMethodId}"){ shippingMethodId:"${shippingMethodId}"){
checkoutErrors{ checkoutErrors{
message message
field field
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function addPayment(checkoutId, gateway, token) { export function addPayment(checkoutId, gateway, token) {
const mutation = `mutation{ const mutation = `mutation{
checkoutPaymentCreate(checkoutId:"${checkoutId}", checkoutPaymentCreate(checkoutId:"${checkoutId}",
input:{ input:{
gateway: "${gateway}" gateway: "${gateway}"
token:"${token}" token:"${token}"
}){ }){
paymentErrors{ paymentErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function completeCheckout(checkoutId) { export function completeCheckout(checkoutId) {
const mutation = `mutation{ const mutation = `mutation{
checkoutComplete(checkoutId:"${checkoutId}"){ checkoutComplete(checkoutId:"${checkoutId}"){
order{ order{
id id
} }
confirmationNeeded confirmationNeeded
confirmationData confirmationData
checkoutErrors{ checkoutErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -5,30 +5,30 @@ export function getCollections(search) {
}` }`
: ""; : "";
const query = `query{ const query = `query{
collections(first:100 ${filter}){ collections(first:100 ${filter}){
edges{ edges{
node{ node{
id id
name name
}
}
} }
}`; }
}
}`;
return cy return cy
.sendRequestWithQuery(query) .sendRequestWithQuery(query)
.then(resp => resp.body.data.collections.edges); .then(resp => resp.body.data.collections.edges);
} }
export function deleteCollection(collectionId) { export function deleteCollection(collectionId) {
const mutation = `mutation{ const mutation = `mutation{
collectionDelete(id:"${collectionId}"){ collectionDelete(id:"${collectionId}"){
collection{ collection{
id id
} }
collectionErrors{ collectionErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -1,41 +1,40 @@
export function createCustomer(email, customerName, address, isActive = false) { export function createCustomer(email, customerName, address, isActive = false) {
const mutation = ` const mutation = `
mutation{ mutation{
customerCreate(input:{ customerCreate(input:{
firstName: "${customerName}" firstName: "${customerName}"
lastName: "${customerName}" lastName: "${customerName}"
email: "${email}" email: "${email}"
isActive: ${isActive} isActive: ${isActive}
defaultBillingAddress: { defaultBillingAddress: {
companyName: "${address.companyName}" companyName: "${address.companyName}"
streetAddress1: "${address.streetAddress1}" streetAddress1: "${address.streetAddress1}"
streetAddress2: "${address.streetAddress2}" streetAddress2: "${address.streetAddress2}"
city: "${address.city}" city: "${address.city}"
postalCode: "${address.postalCode}" postalCode: "${address.postalCode}"
country: ${address.country} country: ${address.country}
phone: "${address.phone}" phone: "${address.phone}"
} }
defaultShippingAddress: { defaultShippingAddress: {
companyName: "${address.companyName}" companyName: "${address.companyName}"
streetAddress1: "${address.streetAddress1}" streetAddress1: "${address.streetAddress1}"
streetAddress2: "${address.streetAddress2}" streetAddress2: "${address.streetAddress2}"
city: "${address.city}" city: "${address.city}"
postalCode: "${address.postalCode}" postalCode: "${address.postalCode}"
country: ${address.country} country: ${address.country}
phone: "${address.phone}" phone: "${address.phone}"
} }
}){ }){
user{ user{
id id
email email
} }
accountErrors{ accountErrors{
code code
message message
} }
}
} }
`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
@ -54,29 +53,28 @@ export function deleteCustomers(startsWith) {
export function deleteCustomer(customerId) { export function deleteCustomer(customerId) {
const mutation = `mutation{ const mutation = `mutation{
customerDelete(id:"${customerId}"){ customerDelete(id:"${customerId}"){
accountErrors{ accountErrors{
code code
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function getCustomers(startsWith) { export function getCustomers(startsWith) {
const query = `query{ const query = `query{
customers(first:100, filter: { customers(first:100, filter: {
search: "${startsWith}" search: "${startsWith}"
}){ }){
edges{ edges{
node{ node{
id id
email email
} }
} }
} }
} }`;
`;
return cy.sendRequestWithQuery(query); return cy.sendRequestWithQuery(query);
} }

View file

@ -1,34 +1,34 @@
export function getSalesForChannel(channelSlug, period) { export function getSalesForChannel(channelSlug, period) {
const query = `query{ const query = `query{
ordersTotal(period: ${period}, channel:"${channelSlug}"){ ordersTotal(period: ${period}, channel:"${channelSlug}"){
gross{ gross{
amount amount
} }
} }
}`; }`;
return cy.sendRequestWithQuery(query); return cy.sendRequestWithQuery(query);
} }
export function getOrdersForChannel(channelSlug, created) { export function getOrdersForChannel(channelSlug, created) {
const query = `query{ const query = `query{
orders(created: ${created}, channel:"${channelSlug}"){ orders(created: ${created}, channel:"${channelSlug}"){
totalCount totalCount
} }
}`; }`;
return cy.sendRequestWithQuery(query); return cy.sendRequestWithQuery(query);
} }
export function getOrdersWithStatus(status, channelSlug) { export function getOrdersWithStatus(status, channelSlug) {
const query = `query{ const query = `query{
orders(status: ${status}, channel:"${channelSlug}"){ orders(status: ${status}, channel:"${channelSlug}"){
totalCount totalCount
} }
}`; }`;
return cy.sendRequestWithQuery(query); return cy.sendRequestWithQuery(query);
} }
export function getProductsOutOfStock(channelSlug) { export function getProductsOutOfStock(channelSlug) {
const query = `query{ const query = `query{
products(stockAvailability: OUT_OF_STOCK, channel:"${channelSlug}"){ products(stockAvailability: OUT_OF_STOCK, channel:"${channelSlug}"){
totalCount totalCount
} }
}`; }`;
return cy.sendRequestWithQuery(query); return cy.sendRequestWithQuery(query);
} }

View file

@ -1,57 +1,55 @@
export function markOrderAsPaid(orderId) { export function markOrderAsPaid(orderId) {
const mutation = `mutation{ const mutation = `mutation{
orderMarkAsPaid(id:"${orderId}"){ orderMarkAsPaid(id:"${orderId}"){
orderErrors{ orderErrors{
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function addProductToOrder(orderId, variantId, quantity = 1) { export function addProductToOrder(orderId, variantId, quantity = 1) {
const mutation = `mutation{ const mutation = `mutation{
draftOrderLinesCreate(id:"${orderId}", input:{ draftOrderLinesCreate(id:"${orderId}", input:{
quantity:${quantity} quantity:${quantity}
variantId: "${variantId}" variantId: "${variantId}"
}){ }){
orderErrors{ orderErrors{
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function createDraftOrder(customerId, shippingMethodId, channelId) { export function createDraftOrder(customerId, shippingMethodId, channelId) {
const mutation = ` const mutation = `mutation{
mutation{ draftOrderCreate(input:{
draftOrderCreate(input:{ user:"${customerId}"
user:"${customerId}" shippingMethod:"${shippingMethodId}"
shippingMethod:"${shippingMethodId}" channel: "${channelId}"
channel: "${channelId}" }){
}){ orderErrors{
orderErrors{ message
message }
} order{
order{ id
id }
} }
} }`;
}
`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function completeOrder(orderId) { export function completeOrder(orderId) {
const mutation = `mutation{ const mutation = `mutation{
draftOrderComplete(id:"${orderId}"){ draftOrderComplete(id:"${orderId}"){
order{ order{
id id
} }
orderErrors{ orderErrors{
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -7,18 +7,17 @@ export function getFirstProducts(first, search) {
}` }`
: ""; : "";
const query = `query{ const query = `query{
products(first:${first}${filter}){ products(first:${first}${filter}){
edges{ edges{
node{ node{
id id
name name
variants{ variants{
id id
} }
} }
} }
} }`;
`;
return cy return cy
.sendRequestWithQuery(query) .sendRequestWithQuery(query)
.then(resp => resp.body.data.products.edges); .then(resp => resp.body.data.products.edges);
@ -32,57 +31,58 @@ export function updateChannelInProduct({
visibleInListings = true visibleInListings = true
}) { }) {
const mutation = `mutation{ const mutation = `mutation{
productChannelListingUpdate(id:"${productId}", productChannelListingUpdate(id:"${productId}",
input:{ input:{
addChannels:{ addChannels:{
channelId:"${channelId}" channelId:"${channelId}"
isPublished:${isPublished} isPublished:${isPublished}
isAvailableForPurchase:${isAvailableForPurchase} isAvailableForPurchase:${isAvailableForPurchase}
visibleInListings:${visibleInListings} visibleInListings:${visibleInListings}
} }
}){ }){
product{ product{
id id
name name
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function updateChannelPriceInVariant(variantId, channelId) { export function updateChannelPriceInVariant(variantId, channelId) {
const mutation = `mutation{ const mutation = `mutation{
productVariantChannelListingUpdate(id: "${variantId}", input: { productVariantChannelListingUpdate(id: "${variantId}", input: {
channelId: "${channelId}" channelId: "${channelId}"
price: 10 price: 10
costPrice: 10 costPrice: 10
}){ }){
productChannelListingErrors{ productChannelListingErrors{
message message
}
} }
} } `;
} `;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function createProduct(attributeId, name, productType, category) { export function createProduct(attributeId, name, productType, category) {
const mutation = `mutation{ const mutation = `mutation{
productCreate(input:{ productCreate(input:{
attributes:[{ attributes:[{
id:"${attributeId}" id:"${attributeId}"
}] }]
name:"${name}" name:"${name}"
productType:"${productType}" productType:"${productType}"
category:"${category}" category:"${category}"
}){ }){
product{ product{
id id
} name
productErrors{
field
message
}
} }
}`; productErrors{
field
message
}
}
}`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
@ -113,71 +113,71 @@ export function createVariant({
); );
const mutation = `mutation{ const mutation = `mutation{
productVariantBulkCreate(product: "${productId}", variants: { productVariantBulkCreate(product: "${productId}", variants: {
attributes: [] attributes: []
sku: "${sku}" sku: "${sku}"
${channelListings} ${channelListings}
${stocks} ${stocks}
}) { }) {
productVariants{ productVariants{
id id
name name
} }
bulkProductErrors{ bulkProductErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function createTypeProduct(name, attributeId, slug = name) { export function createTypeProduct(name, attributeId, slug = name) {
const mutation = `mutation{ const mutation = `mutation{
productTypeCreate(input: { productTypeCreate(input: {
name: "${name}" name: "${name}"
slug: "${slug}" slug: "${slug}"
isShippingRequired: true isShippingRequired: true
productAttributes: "${attributeId}" productAttributes: "${attributeId}"
variantAttributes: "${attributeId}" variantAttributes: "${attributeId}"
}){ }){
productErrors{ productErrors{
field field
message message
}
productType{
id
}
} }
productType{ } `;
id
}
}
} `;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function deleteProduct(productId) { export function deleteProduct(productId) {
const mutation = `mutation{ const mutation = `mutation{
productDelete(id: "${productId}"){ productDelete(id: "${productId}"){
productErrors{ productErrors{
field field
message message
}
} }
} } `;
} `;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function getProductTypes(first, search) { export function getProductTypes(first, search) {
const query = `query{ const query = `query{
productTypes(first:${first}, filter:{ productTypes(first:${first}, filter:{
search:"${search}" search:"${search}"
}){ }){
edges{ edges{
node{ node{
id id
name name
}
} }
} }
}`; }
}`;
return cy return cy
.sendRequestWithQuery(query) .sendRequestWithQuery(query)
.then(resp => resp.body.data.productTypes.edges); .then(resp => resp.body.data.productTypes.edges);
@ -185,12 +185,12 @@ export function getProductTypes(first, search) {
export function deleteProductType(productTypeId) { export function deleteProductType(productTypeId) {
const mutation = `mutation{ const mutation = `mutation{
productTypeDelete(id:"${productTypeId}"){ productTypeDelete(id:"${productTypeId}"){
productErrors{ productErrors{
field field
message message
}
} }
}`; }
}`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -0,0 +1,35 @@
import { getValueWithDefault } from "./utils/Utils";
export function getSales(first, searchQuery) {
const filter = getValueWithDefault(
searchQuery,
`, filter:{
search:"${searchQuery}"
}`
);
const query = `query{
sales(first:
${first} ${filter}){
edges{
node{
id
name
}
}
}
}`;
return cy
.sendRequestWithQuery(query)
.then(resp => resp.body.data.sales.edges);
}
export function deleteSale(saleId) {
const mutation = `mutation{
saleDelete(id:"${saleId}"){
discountErrors{
field
message
}
}
}`;
return cy.sendRequestWithQuery(mutation);
}

View file

@ -1,55 +1,49 @@
export function createShippingRate(name, shippingZone) { export function createShippingRate(name, shippingZone) {
const mutation = ` const mutation = `mutation{
mutation{ shippingPriceCreate(input:{
shippingPriceCreate(input:{ name: "${name}"
name: "${name}" shippingZone: "${shippingZone}"
shippingZone: "${shippingZone}" type: PRICE
type: PRICE }){
}){ shippingMethod{
shippingMethod{ id
id }
} }
} }`;
}
`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function createShippingZone(name, country) { export function createShippingZone(name, country) {
const mutation = ` const mutation = `mutation{
mutation{ shippingZoneCreate(input:{
shippingZoneCreate(input:{ name: "${name}"
name: "${name}" countries: "${country}"
countries: "${country}" }){
}){ shippingZone{
shippingZone{ id
id }
} }
} }`;
}
`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function addChannelToShippingMethod(shippingRateId, channelId, price) { export function addChannelToShippingMethod(shippingRateId, channelId, price) {
const mutation = ` const mutation = `mutation{
mutation{ shippingMethodChannelListingUpdate(id:"${shippingRateId}", input:{
shippingMethodChannelListingUpdate(id:"${shippingRateId}", input:{ addChannels: {
addChannels: { channelId:"${channelId}"
channelId:"${channelId}" price: ${price}
price: ${price} }
} }){
}){ shippingMethod{
shippingMethod{ id
id }
} shippingErrors{
shippingErrors{ code
code message
message }
} }
} }`;
}
`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -1,55 +1,55 @@
export function createWarehouse(name, shippingZone, address, slug = name) { export function createWarehouse(name, shippingZone, address, slug = name) {
const mutation = `mutation{ const mutation = `mutation{
createWarehouse(input:{ createWarehouse(input:{
name:"${name}" name:"${name}"
slug:"${slug}" slug:"${slug}"
shippingZones:"${shippingZone}" shippingZones:"${shippingZone}"
address:{ address:{
streetAddress1: "${address.streetAddress1}" streetAddress1: "${address.streetAddress1}"
streetAddress2: "${address.streetAddress2}" streetAddress2: "${address.streetAddress2}"
city: "${address.city}" city: "${address.city}"
postalCode: "${address.postalCode}" postalCode: "${address.postalCode}"
country: ${address.country} country: ${address.country}
phone: "${address.phone}" phone: "${address.phone}"
} }
}){ }){
warehouseErrors{ warehouseErrors{
field field
message message
} }
warehouse{ warehouse{
id id
name name
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }
export function getWarehouses(first, search) { export function getWarehouses(first, search) {
const query = `query{ const query = `query{
warehouses(first:${first}, filter:{ warehouses(first:${first}, filter:{
search:"${search}" search:"${search}"
}){ }){
edges{ edges{
node{ node{
id id
name name
} }
} }
} }
}`; }`;
return cy return cy
.sendRequestWithQuery(query) .sendRequestWithQuery(query)
.then(resp => resp.body.data.warehouses.edges); .then(resp => resp.body.data.warehouses.edges);
} }
export function deleteWarehouse(warehouseId) { export function deleteWarehouse(warehouseId) {
const mutation = `mutation{ const mutation = `mutation{
deleteWarehouse(id:"${warehouseId}"){ deleteWarehouse(id:"${warehouseId}"){
warehouseErrors{ warehouseErrors{
field field
message message
} }
} }
}`; }`;
return cy.sendRequestWithQuery(mutation); return cy.sendRequestWithQuery(mutation);
} }

View file

@ -1,19 +1,19 @@
export function getCollection(collectionId, channelSlug) { export function getCollection(collectionId, channelSlug) {
const query = `query Collection{ const query = `query Collection{
collection(id: "${collectionId}", channel: "${channelSlug}") { collection(id: "${collectionId}", channel: "${channelSlug}") {
id id
slug slug
name name
products(first:100){ products(first:100){
totalCount totalCount
edges{ edges{
node{ node{
id id
name name
}
}
} }
} }
}`; }
}
}`;
return cy.sendRequestWithQuery(query, "token"); return cy.sendRequestWithQuery(query, "token");
} }

View file

@ -1,37 +1,37 @@
export function getProductDetails(productId, channelId) { export function getProductDetails(productId, channelId) {
const query = `fragment BasicProductFields on Product { const query = `fragment BasicProductFields on Product {
id id
name name
}
fragment Price on TaxedMoney {
gross {
amount
currency
} }
}
fragment Price on TaxedMoney {
gross { fragment ProductVariantFields on ProductVariant {
amount id
currency sku
name
pricing {
price {
...Price
} }
} }
}
fragment ProductVariantFields on ProductVariant {
id query ProductDetails{
sku product(id: "${productId}", channel: "${channelId}") {
name ...BasicProductFields
pricing { variants {
price { ...ProductVariantFields
...Price
}
} }
isAvailable
isAvailableForPurchase
availableForPurchase
} }
}`;
query ProductDetails{
product(id: "${productId}", channel: "${channelId}") {
...BasicProductFields
variants {
...ProductVariantFields
}
isAvailable
isAvailableForPurchase
availableForPurchase
}
}`;
return cy.sendRequestWithQuery(query, "token"); return cy.sendRequestWithQuery(query, "token");
} }

View file

@ -1,17 +1,17 @@
export function searchInShop(searchQuery) { export function searchInShop(searchQuery) {
const query = `query SearchProducts { const query = `query SearchProducts {
products(channel: "default-channel", filter:{ products(channel: "default-channel", filter:{
search: "${searchQuery}" search: "${searchQuery}"
}, first:10){ },
totalCount first:10){
edges{ totalCount
node{ edges{
id node{
name id
} name
}
} }
}`; }
}
}`;
return cy.sendRequestWithQuery(query, "token"); return cy.sendRequestWithQuery(query, "token");
} }

View file

@ -0,0 +1,4 @@
export const ASSIGN_PRODUCTS_SELECTORS = {
searchInput: "[name='query']",
tableRow: "[data-test-id='assign-product-table-row']"
};

View file

@ -0,0 +1,16 @@
export const MENAGE_CHANNEL_AVAILABILITY = {
availableManageButton:
"[data-test-id='channels-availiability-manage-button']",
channelsAvailabilityForm:
"[data-test-id='manage-products-channels-availiability-list']",
channelAvailabilityColumn:
"[data-test='availability'][data-test-availability='true']",
channelAvailabilityList: "ul[role='menu']",
assignedChannels: "[data-test='channel-availability-item']",
publishedRadioButtons: "[name*='isPublished']",
availableForPurchaseRadioButtons: "[name*='isAvailableForPurchase']",
radioButtonsValueTrue: "[value='true']",
radioButtonsValueFalse: "[value='false']",
visibleInListingsButton: "[name*='visibleInListings']",
allChannelsInput: "[name='allChannels']"
};

View file

@ -0,0 +1,11 @@
export const SALES_SELECTORS = {
createSaleButton: "[data-test-id='create-sale']",
nameInput: "[name='name']",
percentageOption: "[value='PERCENTAGE']",
fixedOption: "[value='FIXED']",
discountValue: "[name='value']",
startDateInput: "[name='startDate']",
saveButton: "[data-test='button-bar-confirm']",
productsTab: "[data-test-id='products-tab']",
assignProducts: "[data-test-id='assign-products']"
};

View file

@ -1,4 +1,5 @@
export const BUTTON_SELECTORS = { export const BUTTON_SELECTORS = {
back: '[data-test="back"]', back: '[data-test="back"]',
submit: '[data-test="submit"]' submit: '[data-test="submit"]',
checkbox: "[type='checkbox']"
}; };

View file

@ -0,0 +1,179 @@
// <reference types="cypress" />
import faker from "faker";
import { updateChannelInProduct } from "../../apiRequests/Product";
import {
assignProducts,
createSale,
discountOptions
} from "../../steps/salesSteps";
import { urlList } from "../../url/urlList";
import * as channelsUtils from "../../utils/channelsUtils";
import * as productsUtils from "../../utils/productsUtils";
import { deleteSalesStartsWith } from "../../utils/salesUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
import { getProductPrice } from "../../utils/storeFront/storeFrontProductUtils";
describe("Sales discounts", () => {
const startsWith = "Cy-";
let productType;
let attribute;
let category;
let defaultChannel;
let warehouse;
before(() => {
cy.clearSessionData().loginUserViaRequest();
channelsUtils.deleteChannelsStartsWith(startsWith);
deleteSalesStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
const name = `${startsWith}${faker.random.number()}`;
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
channelsUtils.getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addresses => {
createShipping({
channelId: defaultChannel.id,
name,
address: addresses.plAddress,
price: 100
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create percentage discount", () => {
const saleName = `${startsWith}${faker.random.number()}`;
const discountValue = 50;
const productPrice = 100;
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
cy.visit(urlList.sales);
const product = productResp;
createSale({
saleName,
channelName: defaultChannel.name,
discountValue,
discountOption: discountOptions.PERCENTAGE
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => {
const expectedPrice = (productPrice * discountValue) / 100;
expect(expectedPrice).to.be.eq(price);
});
});
it("should create fixed price discount", () => {
const saleName = `${startsWith}${faker.random.number()}`;
const discountValue = 50;
const productPrice = 100;
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
cy.visit(urlList.sales);
const product = productResp;
createSale({
saleName,
channelName: defaultChannel.name,
discountValue,
discountOption: discountOptions.FIXED
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => {
const expectedPrice = productPrice - discountValue;
expect(expectedPrice).to.be.eq(price);
});
});
it("should not displayed discount not assign to channel", () => {
const saleName = `${startsWith}${faker.random.number()}`;
let channel;
let product;
const discountValue = 50;
const productPrice = 100;
channelsUtils
.createChannel({ name: saleName })
.then(channelResp => (channel = channelResp));
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
product = productResp;
updateChannelInProduct({
productId: product.id,
channelId: channel.id
});
})
.then(() => {
cy.visit(urlList.sales);
createSale({
saleName,
channelName: channel.name,
discountValue
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => expect(price).to.equal(productPrice));
});
});

View file

@ -0,0 +1,57 @@
import { ASSIGN_PRODUCTS_SELECTORS } from "../elements/catalog/assign-products";
import { MENAGE_CHANNEL_AVAILABILITY } from "../elements/channels/menage-channel-availability";
import { SALES_SELECTORS } from "../elements/discounts/sales";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
import { formatDate } from "../support/formatDate";
export const discountOptions = {
PERCENTAGE: SALES_SELECTORS.percentageOption,
FIXED: SALES_SELECTORS.fixedOption
};
export function createSale({
saleName,
channelName,
discountValue = 10,
discountOption = discountOptions.PERCENTAGE
}) {
const todaysDate = formatDate(new Date());
cy.get(SALES_SELECTORS.createSaleButton)
.click()
.get(SALES_SELECTORS.nameInput)
.type(saleName)
.get(discountOption)
.click()
.get(MENAGE_CHANNEL_AVAILABILITY.availableManageButton)
.click()
.get(MENAGE_CHANNEL_AVAILABILITY.allChannelsInput)
.click()
.get(MENAGE_CHANNEL_AVAILABILITY.channelsAvailabilityForm)
.contains(channelName)
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.get(SALES_SELECTORS.discountValue)
.type(discountValue)
.get(SALES_SELECTORS.startDateInput)
.type(todaysDate);
cy.addAliasToGraphRequest("SaleCreate");
cy.get(SALES_SELECTORS.saveButton).click();
cy.wait("@SaleCreate");
}
export function assignProducts(productName) {
cy.get(SALES_SELECTORS.productsTab)
.click()
.get(SALES_SELECTORS.assignProducts)
.click()
.get(ASSIGN_PRODUCTS_SELECTORS.searchInput)
.type(productName);
cy.contains(ASSIGN_PRODUCTS_SELECTORS.tableRow, productName)
.find(BUTTON_SELECTORS.checkbox)
.click();
cy.addAliasToGraphRequest("SaleCataloguesAdd");
cy.get(BUTTON_SELECTORS.submit).click();
cy.wait("@SaleCataloguesAdd");
}

View file

@ -0,0 +1,12 @@
export function formatDate(date) {
const day = getPeriodValue(date, { day: "2-digit" });
const month = getPeriodValue(date, { month: "2-digit" });
const year = getPeriodValue(date, { year: "numeric" });
return new Array(year, month, day).join("-");
}
function getPeriodValue(date, option) {
const formatter = new Intl.DateTimeFormat("en-us", option);
return formatter.format(date);
}

View file

@ -6,6 +6,7 @@ export const urlList = {
orders: "orders/", orders: "orders/",
products: "products/", products: "products/",
warehouses: "warehouses/", warehouses: "warehouses/",
sales: "discounts/sales/",
collections: "collections/" collections: "collections/"
}; };
export const productDetailsUrl = productId => `${urlList.products}${productId}`; export const productDetailsUrl = productId => `${urlList.products}${productId}`;

View file

@ -0,0 +1,5 @@
import { deleteSale, getSales } from "../apiRequests/Sales";
export function deleteSalesStartsWith(startsWith) {
cy.deleteElementsStartsWith(deleteSale, getSales, startsWith, "sales");
}

View file

@ -18,7 +18,7 @@ export const isProductVisibleInSearchResult = (resp, productName) => {
); );
}; };
export const getProductVariants = (productId, channelSlug) => export const getProductVariants = (productId, channelSlug) => {
getProductDetails(productId, channelSlug).then(resp => { getProductDetails(productId, channelSlug).then(resp => {
const variantsList = resp.body.data.product.variants; const variantsList = resp.body.data.product.variants;
return variantsList.map(element => ({ return variantsList.map(element => ({
@ -26,3 +26,9 @@ export const getProductVariants = (productId, channelSlug) =>
price: element.pricing.price.gross.amount price: element.pricing.price.gross.amount
})); }));
}); });
};
export const getProductPrice = (productId, channelSlug) =>
getProductDetails(productId, channelSlug).then(
resp => resp.body.data.product.variants[0].pricing.price.gross.amount
);

View file

@ -165,7 +165,10 @@ const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
); );
return ( return (
<TableRow key={product.id}> <TableRow
key={product.id}
data-test-id="assign-product-table-row"
>
<TableCellAvatar <TableCellAvatar
className={classes.avatar} className={classes.avatar}
thumbnail={maybe(() => product.thumbnail.url)} thumbnail={maybe(() => product.thumbnail.url)}
@ -202,6 +205,7 @@ const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
<FormattedMessage {...buttonMessages.back} /> <FormattedMessage {...buttonMessages.back} />
</Button> </Button>
<ConfirmButton <ConfirmButton
data-test="submit"
transitionState={confirmButtonState} transitionState={confirmButtonState}
color="primary" color="primary"
variant="contained" variant="contained"

View file

@ -38,17 +38,19 @@ interface TabProps<T> {
children?: React.ReactNode; children?: React.ReactNode;
isActive: boolean; isActive: boolean;
changeTab: (index: T) => void; changeTab: (index: T) => void;
testId?: string;
} }
export function Tab<T>(value: T) { export function Tab<T>(value: T) {
const Component: React.FC<TabProps<T>> = props => { const Component: React.FC<TabProps<T>> = props => {
const { children, isActive, changeTab } = props; const { children, isActive, changeTab, testId } = props;
const classes = useStyles(props); const classes = useStyles(props);
return ( return (
<Typography <Typography
component="span" component="span"
data-test-id={testId}
className={classNames({ className={classNames({
[classes.root]: true, [classes.root]: true,
[classes.active]: isActive [classes.active]: isActive

View file

@ -98,7 +98,11 @@ const DiscountProducts: React.FC<SaleProductsProps> = props => {
description: "section header" description: "section header"
})} })}
toolbar={ toolbar={
<Button color="primary" onClick={onProductAssign}> <Button
color="primary"
onClick={onProductAssign}
data-test-id="assign-products"
>
<FormattedMessage <FormattedMessage
defaultMessage="Assign products" defaultMessage="Assign products"
description="button" description="button"

View file

@ -208,6 +208,7 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
)} )}
</CollectionsTab> </CollectionsTab>
<ProductsTab <ProductsTab
testId="products-tab"
isActive={activeTab === SaleDetailsPageTab.products} isActive={activeTab === SaleDetailsPageTab.products}
changeTab={onTabClick} changeTab={onTabClick}
> >

View file

@ -54,7 +54,12 @@ const SaleListPage: React.FC<SaleListPageProps> = ({
return ( return (
<Container> <Container>
<PageHeader title={intl.formatMessage(sectionNames.sales)}> <PageHeader title={intl.formatMessage(sectionNames.sales)}>
<Button onClick={onAdd} variant="contained" color="primary"> <Button
onClick={onAdd}
variant="contained"
color="primary"
data-test-id="create-sale"
>
<FormattedMessage defaultMessage="Create Sale" description="button" /> <FormattedMessage defaultMessage="Create Sale" description="button" />
</Button> </Button>
</PageHeader> </PageHeader>

View file

@ -73441,6 +73441,7 @@ exports[`Storyshots Views / Discounts / Sale details collections 1`] = `
</span> </span>
<span <span
class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id" class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id"
data-test-id="products-tab"
> >
Products (4) Products (4)
</span> </span>
@ -74796,6 +74797,7 @@ exports[`Storyshots Views / Discounts / Sale details default 1`] = `
</span> </span>
<span <span
class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id" class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id"
data-test-id="products-tab"
> >
Products (4) Products (4)
</span> </span>
@ -76156,6 +76158,7 @@ exports[`Storyshots Views / Discounts / Sale details form errors 1`] = `
</span> </span>
<span <span
class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id" class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id"
data-test-id="products-tab"
> >
Products (4) Products (4)
</span> </span>
@ -77538,6 +77541,7 @@ exports[`Storyshots Views / Discounts / Sale details loading 1`] = `
</span> </span>
<span <span
class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id" class="MuiTypography-root-id Tab-root-id MuiTypography-body1-id"
data-test-id="products-tab"
> >
Products (…) Products (…)
</span> </span>
@ -78925,6 +78929,7 @@ exports[`Storyshots Views / Discounts / Sale details products 1`] = `
</span> </span>
<span <span
class="MuiTypography-root-id Tab-root-id Tab-active-id MuiTypography-body1-id" class="MuiTypography-root-id Tab-root-id Tab-active-id MuiTypography-body1-id"
data-test-id="products-tab"
> >
Products (4) Products (4)
</span> </span>
@ -78948,6 +78953,7 @@ exports[`Storyshots Views / Discounts / Sale details products 1`] = `
> >
<button <button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id" class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
data-test-id="assign-products"
tabindex="0" tabindex="0"
type="button" type="button"
> >
@ -79968,6 +79974,7 @@ exports[`Storyshots Views / Discounts / Sale list default 1`] = `
> >
<button <button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id" class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="create-sale"
tabindex="0" tabindex="0"
type="button" type="button"
> >
@ -80658,6 +80665,7 @@ exports[`Storyshots Views / Discounts / Sale list loading 1`] = `
> >
<button <button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id" class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="create-sale"
tabindex="0" tabindex="0"
type="button" type="button"
> >
@ -81102,6 +81110,7 @@ exports[`Storyshots Views / Discounts / Sale list no channels 1`] = `
> >
<button <button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id" class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="create-sale"
tabindex="0" tabindex="0"
type="button" type="button"
> >
@ -81792,6 +81801,7 @@ exports[`Storyshots Views / Discounts / Sale list no data 1`] = `
> >
<button <button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id" class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="create-sale"
tabindex="0" tabindex="0"
type="button" type="button"
> >