Skip to content

Commit

Permalink
CC-34716: Added tests for order-amendment.
Browse files Browse the repository at this point in the history
  • Loading branch information
dmiseev committed Nov 26, 2024
1 parent c5118c8 commit e4b4bd9
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 71 deletions.
9 changes: 9 additions & 0 deletions helpers/cart-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ export class CartHelper {
}
}

deleteCart(customerEmail, cartId) {
this.http.sendDeleteRequest(
this.http.url`${this.getCartsUrl()}/${cartId}`,
null,
this.getParamsWithAuthorization(customerEmail),
false
)
}

addItemToCart(cartId, quantity, params, sku) {
const addItemToCartResponse = this.http.sendPostRequest(
this.http.url`${this.getCartsUrl()}/${cartId}/items`,
Expand Down
107 changes: 76 additions & 31 deletions helpers/dynamic-fixtures-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export class DynamicFixturesHelper {
this.http = http;
}

haveCustomerWithQuoteAndItems(quoteCount, itemCount, defaultItemPrice = 100) {
haveCustomersWithQuotes(customerCount, quoteCount = 1, itemCount = 10, defaultItemPrice = 5000) {
const defaultParams = {
headers: {
'Content-Type': 'application/vnd.api+json',
Expand All @@ -13,23 +13,61 @@ export class DynamicFixturesHelper {

const dynamicFixturesResponse = this.http.sendPostRequest(
this.http.url`${this.backendApiUrl}/dynamic-fixtures`,
JSON.stringify(this._getCustomerWithItemsInQuoteAttributes(quoteCount, itemCount, defaultItemPrice)),
JSON.stringify(this._getCustomersWithQuotesAttributes(customerCount, quoteCount, itemCount, defaultItemPrice)),
defaultParams,
false
);

const dynamicFixturesResponseJson = JSON.parse(dynamicFixturesResponse.body);
const customerData = dynamicFixturesResponseJson.data.filter(item => /^customer\d+$/.test(item.attributes.key));

const customerData = dynamicFixturesResponseJson.data.find(item => item.attributes.key === 'customer');
const quoteData = dynamicFixturesResponseJson.data.filter(item => item.attributes.key.startsWith('quote'));
return customerData.map(customer => {
const associatedCustomerQuotes = dynamicFixturesResponseJson.data
.filter(item => item.attributes.key.startsWith(`${customer.attributes.key}Quote`))
.map(quote => quote.attributes.data.uuid);

return {
customerEmail: customer.attributes.data.email,
quoteIds: associatedCustomerQuotes
};
});
}

haveConsoleCommands(commands) {
const params = {
headers: {
'Content-Type': 'application/vnd.api+json',
},
timeout: 20000,
};

this.http.sendPostRequest(
this.http.url`${this.backendApiUrl}/dynamic-fixtures`,
JSON.stringify(this._getConsoleCommandsAttributes(commands)),
params,
false
);
}

_getConsoleCommandsAttributes(commands) {
const operations = commands.map((command) => {
return {
type: 'cli-command',
name: command,
};
});

return {
customerEmail: customerData.attributes.data.email,
quoteIds: quoteData.map(item => item.attributes.data.uuid),
data: {
type: 'dynamic-fixtures',
attributes: {
operations: operations,
},
},
};
}

_getCustomerWithItemsInQuoteAttributes(quoteCount = 1, itemCount = 10, defaultItemPrice = 100) {
_getCustomersWithQuotesAttributes(customerCount = 1, quoteCount = 1, itemCount = 10, defaultItemPrice = 100) {
const baseOperations = [
{
type: 'transfer',
Expand All @@ -48,18 +86,6 @@ export class DynamicFixturesHelper {
name: 'haveCountry',
key: 'country'
},
{
type: 'helper',
name: 'haveCustomer',
key: 'customer',
arguments: [{ locale: '#locale', password: 'change123' }]
},
{
type: 'helper',
name: 'confirmCustomer',
key: 'confirmedCustomer',
arguments: ['#customer']
},
{
type: 'transfer',
name: 'ProductImageTransfer',
Expand Down Expand Up @@ -122,27 +148,46 @@ export class DynamicFixturesHelper {
}));
};

// Generate quotes dynamically
const quotes = Array.from({ length: quoteCount }, (_, i) => ({
type: 'helper',
name: 'havePersistentQuote',
key: `quote${i + 1}`,
arguments: [
// Generate customers dynamically
const customers = Array.from({ length: customerCount }, (_, customerIndex) => {
const customerKey = `customer${customerIndex + 1}`;
return [
{
customer: '#customer',
items: generateItems()
}
]
}));
type: 'helper',
name: 'haveCustomer',
key: customerKey,
arguments: [{ locale: '#locale', password: 'change123' }]
},
{
type: 'helper',
name: 'confirmCustomer',
key: `confirmed${customerKey}`,
arguments: [`#${customerKey}`]
},
// Generate quotes for each customer
...Array.from({ length: quoteCount }, (_, quoteIndex) => ({
type: 'helper',
name: 'havePersistentQuote',
key: `${customerKey}Quote${quoteIndex + 1}`,
arguments: [
{
customer: `#${customerKey}`,
items: generateItems()
}
]
}))
];
}).flat();

return {
data: {
type: 'dynamic-fixtures',
attributes: {
synchronize: true,
operations: [...baseOperations, ...products, ...quotes]
operations: [...baseOperations, ...products, ...customers]
}
}
};
}

}
2 changes: 2 additions & 0 deletions tests/abstract-scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import CustomerHelper from '../helpers/customer-helper.js';
import { AssertionsHelper } from '../helpers/assertions-helper.js';
import { BapiHelper } from '../helpers/bapi-helper.js';
import AdminHelper from '../helpers/admin-helper.js';
import { DynamicFixturesHelper } from '../helpers/dynamic-fixtures-helper.js';

export class AbstractScenario {
// eslint-disable-next-line no-unused-vars
Expand All @@ -33,6 +34,7 @@ export class AbstractScenario {
this.bapiHelper = new BapiHelper(this.urlHelper, this.http, this.adminHelper, this.assertionsHelper);
this.storefrontHelper = new StorefrontHelper(this.urlHelper, this.http, this.customerHelper, this.assertionsHelper);
this.browserHelper = new BrowserHelper(this.urlHelper, this.customerHelper, this.assertionsHelper);
this.dynamicFixturesHelper = new DynamicFixturesHelper(this.getBackendApiUrl(), this.http);
}

createTrendMetric(name) {
Expand Down
4 changes: 2 additions & 2 deletions tests/b2b/sapi/scenarios/checkout/checkout-scenario.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SharedCheckoutScenario } from '../../../../cross-product/sapi/scenarios/checkout/shared-checkout-scenario.js';

export class CheckoutScenario extends SharedCheckoutScenario {
_getPaymentProviderName() {
return 'DummyPayment';
_getPaymentProviderName(isMpPaymentProvider = true) {
return isMpPaymentProvider ? 'DummyPayment' : 'DummyPayment';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,30 @@ import { group } from 'k6';
export class SharedCartReorderScenario extends AbstractScenario {
execute(customerEmail, orderId) {
let self = this;

group('Cart Reorder', function () {
const cartReorderResponse = self.http.sendPostRequest(
self.http.url`${self.getStorefrontApiBaseUrl()}/cart-reorder`,
JSON.stringify(self._getCartReorderAttributes(orderId)),
self.cartHelper.getParamsWithAuthorization(customerEmail),
false
);

self.assertionsHelper.assertResponseStatus(cartReorderResponse, 201);
self.haveReorder(customerEmail, orderId);
});
}

haveReorder(customerEmail, orderId) {
const cartReorderResponse = this.http.sendPostRequest(
this.http.url`${this.getStorefrontApiBaseUrl()}/cart-reorder`,
JSON.stringify(this._getCartReorderAttributes(orderId)),
this.cartHelper.getParamsWithAuthorization(customerEmail),
false
);

this.assertionsHelper.assertResponseStatus(cartReorderResponse, 201);

return JSON.parse(cartReorderResponse.body);
}

_getCartReorderAttributes(orderId) {
return {
data: {
type: 'cart-reorder',
attributes: {
orderReference: orderId,
orderReference: orderId
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,15 @@ export class SharedCheckoutScenario extends AbstractScenario {
});
}

placeOrder(customerEmail, cartId) {
console.log(`Executing checkout for customer: ${customerEmail}, cartId: ${cartId}`);

let self = this;
const requestParams = self.cartHelper.getParamsWithAuthorization(customerEmail);

const checkoutResponse = self.http.sendPostRequest(
self.http.url`${self.getStorefrontApiBaseUrl()}/checkout?include=orders`,
JSON.stringify(self._getCheckoutData(cartId, customerEmail, false)),
requestParams,
haveOrder(customerEmail, cartId, isMpPaymentProvider = true) {
const checkoutResponse = this.http.sendPostRequest(
this.http.url`${this.getStorefrontApiBaseUrl()}/checkout?include=orders`,
JSON.stringify(this._getCheckoutData(cartId, customerEmail, isMpPaymentProvider)),
this.cartHelper.getParamsWithAuthorization(customerEmail),
false
);

self.assertionsHelper.assertResponseStatus(checkoutResponse, 201);
this.assertionsHelper.assertResponseStatus(checkoutResponse, 201);

return JSON.parse(checkoutResponse.body);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { AbstractScenario } from '../../../../abstract-scenario.js';
import { group } from 'k6';

export class SharedOrderAmendmentScenario extends AbstractScenario {
execute(customerEmail, orderId) {
let self = this;
group('Order Amendment', function () {
self.haveOrderAmendment(customerEmail, orderId);
});
}

haveOrderAmendment(customerEmail, orderId) {
this._ensureOrderStateState(customerEmail, orderId, 'payment pending');

const cartReorderResponse = this.http.sendPostRequest(
this.http.url`${this.getStorefrontApiBaseUrl()}/cart-reorder`,
JSON.stringify(this._getCartReorderAttributes(orderId)),
this.cartHelper.getParamsWithAuthorization(customerEmail),
false
);

this.assertionsHelper.assertResponseStatus(cartReorderResponse, 201);

return JSON.parse(cartReorderResponse.body);
}

_ensureOrderStateState(customerEmail, orderId, state, maxRetries = 5) {
let retries = 0;
let order;

do {
order = this._getOrder(customerEmail, orderId);
if (order.data.attributes.itemStates[0] !== state) {
this.dynamicFixturesHelper.haveConsoleCommands(['console oms:check-condition', 'console oms:check-timeout']);
}
retries++;
} while (order.data.attributes.itemStates[0] !== state && retries < maxRetries);

if (retries === maxRetries) {
throw new Error(`Order state is not ${state} after ${maxRetries} retries`);
}
}

_getOrder(customerEmail, orderId) {
let self = this;
const orderResponse = self.http.sendGetRequest(
self.http.url`${self.getStorefrontApiBaseUrl()}/orders/${orderId}`,
self.cartHelper.getParamsWithAuthorization(customerEmail),
false
);
self.assertionsHelper.assertResponseStatus(orderResponse, 200);

return JSON.parse(orderResponse.body);
}

_getCartReorderAttributes(orderId) {
return {
data: {
type: 'cart-reorder',
attributes: {
orderReference: orderId,
isAmendment: true
}
}
}
}
}
27 changes: 10 additions & 17 deletions tests/suite/sapi/tests/cart-reorder/SUITE-TEST_ID-cart-reorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
SharedCartReorderScenario
} from '../../../../cross-product/sapi/scenarios/cart-reorder/shared-cart-reorder-scenario.js';
import { SharedCheckoutScenario } from '../../../../cross-product/sapi/scenarios/checkout/shared-checkout-scenario.js';
import { DynamicFixturesHelper } from '../../../../../helpers/dynamic-fixtures-helper.js';
import { Http } from '../../../../../lib/http.js';
export { handleSummary } from '../../../../../helpers/summary-helper.js';

const iterations = 10;
Expand All @@ -15,7 +13,7 @@ const sharedCartReorderScenario = new SharedCartReorderScenario(environment);
export const options = loadDefaultOptions();
options.scenarios = {
TEST_ID_Cart_Reorder: {
exec: 'executeCartReorderScenario',
exec: 'execute',
executor: 'shared-iterations',
tags: {
testId: 'TEST_ID',
Expand All @@ -24,24 +22,19 @@ options.scenarios = {
iterations: iterations
},
};
options.thresholds[`http_req_duration{url:${sharedCartReorderScenario.getStorefrontApiBaseUrl()}/cart-reorder}`] = ['avg<327'];
options.thresholds[`http_req_duration{url:${sharedCartReorderScenario.getStorefrontApiBaseUrl()}/cart-reorder}`] = ['avg<409'];

export function setup() {
const dynamicFixturesHelper = new DynamicFixturesHelper(
'http://glue-backend.eu.spryker.local', // TODO: replace with the actual Glue URL
new Http()
);

return dynamicFixturesHelper.haveCustomerWithQuoteAndItems(iterations, 10, 5000);
return sharedCheckoutScenario.dynamicFixturesHelper.haveCustomersWithQuotes(iterations);
}

export function executeCartReorderScenario(data) {
const customerEmail = data.customerEmail;
const quoteIds = data.quoteIds;
const quoteId = quoteIds[__ITER % quoteIds.length];
export function execute(data) {
const customerIndex = __ITER % data.length;
const { customerEmail, quoteIds } = data[customerIndex];

const checkoutResponseJson = sharedCheckoutScenario.placeOrder(customerEmail, quoteId);
const orderId = checkoutResponseJson.data.relationships.orders.data[0].id;
// Place an order
const checkoutResponseJson = sharedCheckoutScenario.haveOrder(customerEmail, quoteIds[0], false);

sharedCartReorderScenario.execute(customerEmail, orderId);
// Reorder
sharedCartReorderScenario.execute(customerEmail, checkoutResponseJson.data.relationships.orders.data[0].id);
}
Loading

0 comments on commit e4b4bd9

Please sign in to comment.