Skip to content

commercetools testing

The helpers this package ships for your tests, by the path you import them from. How the test layers fit together is in the testing guide.

@evolve-framework/commercetools/testing

A mocked commercetools project, test clients and tokens, the custom types and payment states a test project needs, and describePaymentAdapterContract, the scenarios every payment adapter meets.

configureTestClientFactory
import { configureTestClientFactory } from "@evolve-framework/commercetools/testing";
function configureTestClientFactory(config: ClientConfig): Promise<void>
OptionTypeDescription
CTP_PROJECT_KEYstring
CTP_API_URLstring
CTP_AUTH_URLstring
CTP_CLIENT_ID?string
CTP_CLIENT_SECRET?string
CTP_SCOPES?string[]

Returns Promise<void>

createAnonymousToken
import { createAnonymousToken } from "@evolve-framework/commercetools/testing";
function createAnonymousToken(
anonymousId?: string,
): Promise<FederatedToken>

Returns Promise<FederatedToken>

createCustomerToken
import { createCustomerToken } from "@evolve-framework/commercetools/testing";
function createCustomerToken(
customer: Customer,
businessUnit?: BusinessUnit,
): FederatedToken
OptionTypeDescription
unitType"Company"

Type of the Business Unit indicating its position in a hierarchy.

idstring

Unique identifier of the Business Unit.

versionnumber

Current version of the Business Unit.

createdAtstring

Date and time (UTC) the Business Unit was initially created.

lastModifiedAtstring

Date and time (UTC) the Business Unit was last updated.

keystring

User-defined unique and immutable identifier of the Business Unit.

statusBusinessUnitStatus

Indicates whether the Business Unit can be edited and used in Orders.

storeModeBusinessUnitStoreMode

The value of this field is always Explicit because a Company cannot have a parent Business Unit that Stores can be inherited from.

namestring

Name of the Business Unit.

addressesAddress[]

Addresses used by the Business Unit.

shippingAddressIdsstring[]

Unique identifiers of addresses used as shipping addresses.

billingAddressIdsstring[]

Unique identifiers of addresses used as billing addresses.

associateModeBusinessUnitAssociateMode

The value of this field is always Explicit because a Company cannot have a parent Business Unit that Associates can be inherited from.

associatesAssociate[]

Associates that are part of the Business Unit in specific roles.

topLevelUnitBusinessUnitKeyReference

Top-level unit of the Business Unit. The top-level unit is of unitType Company.

approvalRuleModeBusinessUnitApprovalRuleMode

The value of this field is always Explicit because a Company cannot have a parent Business Unit that Approval Rules can be inherited from.

lastModifiedBy?LastModifiedBy

IDs and references that last modified the BusinessUnit.

createdBy?CreatedBy

IDs and references that created the BusinessUnit.

stores?StoreKeyReference[]

References to Stores the Business Unit is associated with. Only present when storeMode is Explicit.

More

If the Business Unit has Stores defined, then all of its Carts, Orders, Recurring Orders, Quotes, Quote Requests, or Shopping Lists must belong to one of the Business Unit's Stores.

If the Business Unit has no Stores, then all of its Carts, Orders, Recurring Orders, Quotes, Quote Requests, or Shopping Lists must not belong to any Store.

inheritedStores?StoreKeyReference[]

Stores that are inherited from a parent Business Unit. The value of this field is eventually consistent and is only present when the storeMode is set to FromParent.

contactEmail?string

Email address of the Business Unit.

custom?CustomFields

Custom Fields of the Business Unit.

customerGroupAssignments?CustomerGroupAssignment[]

Customer Groups assigned to the Business Unit.

More

They are considered during line Item price selection, if provided (non-null).

defaultShippingAddressId?string

Unique identifier of the address used as the default shipping address.

defaultBillingAddressId?string

Unique identifier of the address used as the default billing address.

inheritedAssociates?InheritedAssociate[]

Associates that are inherited from a parent Business Unit. The value of this field is eventually consistent and is only present when the associateMode is set to ExplicitAndFromParent.

parentUnit?BusinessUnitKeyReference

Parent unit of the Business Unit. Only present when the unitType is Division.

Returns FederatedToken

createTestExtensionContextThe context an API extension is called with, for calling one directly from a test.
import { createTestExtensionContext } from "@evolve-framework/commercetools/testing";

Generic in the action type because the extensions are: one registered on the order resource takes an ApiExtensionContext<OrderUpdateAction>, so a test for it asks for createTestExtensionContext<OrderUpdateAction>().

function createTestExtensionContext<TAction>(
options?: TestExtensionContextOptions<TAction>,
): ApiExtensionContext<TAction>
OptionTypeDescription
clientFactory?ClientFactory
action?ApiExtensionAction
resource?keyof ReferenceTypeToResourceMap
actions?TAction[]

Actions an extension earlier in the list would have returned.

signal?AbortSignal

Returns ApiExtensionContext<TAction>

ctMockClient
import { ctMockClient } from "@evolve-framework/commercetools/testing";
function ctMockClient(): ByProjectKeyRequestBuilder

Returns RequestBuilder

describePaymentAdapterContractThe scenarios every payment adapter meets, run the way a remote checkout calls it: through PaymentProviderModule's routes, so requests and responses are validated against the schemas the checkout uses.
import { describePaymentAdapterContract } from "@evolve-framework/commercetools/testing";
function describePaymentAdapterContract(
name: string,
create: () => PaymentAdapterUnderTest | Promise<PaymentAdapterUnderTest>,
): void

Returns void

matchingLocationHandlerThe shipping-method match for a location, which @labdigital/commercetools-mock does not serve.
import { matchingLocationHandler } from "@evolve-framework/commercetools/testing";
function matchingLocationHandler(): HttpHandler

Returns import("msw").HttpHandler

mockGraphQLContext
import { mockGraphQLContext } from "@evolve-framework/commercetools/testing";
function mockGraphQLContext(
options: MockContextValueOptions,
): Promise<MockContextValue>
OptionTypeDescription
clientFactory() => ByProjectKeyRequestBuilder
customer?Customer
token?FederatedToken
businessUnit?BusinessUnit

Returns Promise<MockContextValue>

provisionCustomTypesProvision the custom types the test project holds, the way a deployment does.
import { provisionCustomTypes } from "@evolve-framework/commercetools/testing";
function provisionCustomTypes(): Promise<void>

Returns Promise<void>

provisionPaymentStatesProvision the payment states the framework expects, the way a deployment does.
import { provisionPaymentStates } from "@evolve-framework/commercetools/testing";

Added straight to the mock's store rather than over HTTP, so a test that installs its own request handlers is not competing with the setup.

function provisionPaymentStates(): Promise<void>

Returns Promise<void>

signInHandlerThe project's in-store /login, which @labdigital/commercetools-mock does not serve.
import { signInHandler } from "@evolve-framework/commercetools/testing";
function signInHandler(): HttpHandler

Returns import("msw").HttpHandler

signUpHandlerThe project's customer creation as commercetools documents it for an anonymousCart, which @labdigital/commercetools-mock ignores: the cart is assigned to the new customer and returned with it.
import { signUpHandler } from "@evolve-framework/commercetools/testing";
function signUpHandler(): HttpHandler

Returns import("msw").HttpHandler

clientTestFactory
import { clientTestFactory } from "@evolve-framework/commercetools/testing";
const clientTestFactory: ClientFactory
ctMock
import { ctMock } from "@evolve-framework/commercetools/testing";
const ctMock: CommercetoolsMock
TEST_CUSTOM_TYPESThe custom types the test project provisions, as a deployment does.
import { TEST_CUSTOM_TYPES } from "@evolve-framework/commercetools/testing";

A business-unit key is here although no module asks for one: the fixtures attach a type when they create a business unit, so the framework has something to read fields off.

Kept in a module of its own with no imports. Anything the test setup reaches for pulls its whole import graph in before a test can mock part of it, and a mock that arrives after the real module is no mock at all.

const TEST_CUSTOM_TYPES: { readonly order: "test-order"; readonly customer: "test-customer"; readonly "business-unit": "test-business-unit"; readonly payment: "test-payment"; readonly "…
PaymentAdapterUnderTestOne adapter under test, and how to make its provider answer.
import { type PaymentAdapterUnderTest } from "@evolve-framework/commercetools/testing";
export type PaymentAdapterUnderTest = {
adapter: BasePaymentAdapter;
server: {
use: (...handlers: RequestHandler[]) => void;
};
paymentMethod: string;
vendor: {
pending: () => RequestHandler[];
paid: () => RequestHandler[];
};
webhook: (interfaceId: string) => ProviderWebhook;
};
ProviderWebhookA provider's request announcing a payment's new state, as it is sent.
import { type ProviderWebhook } from "@evolve-framework/commercetools/testing";
export type ProviderWebhook = {
url: string;
payload: string | Record<string, unknown>;
headers?: Record<string, string>;
};

@evolve-framework/commercetools/factories

Factories that create carts, orders, customers, products and other resources in that mocked project.

rewindFactorySequencesRewind (reset) the sequence of all factories.
import { rewindFactorySequences } from "@evolve-framework/commercetools/factories";
function rewindFactorySequences(): void

Returns void

associateRoleDraftFactory
import { associateRoleDraftFactory } from "@evolve-framework/commercetools/factories";
const associateRoleDraftFactory: Factory<AssociateRoleDraft, AssociateRoleDraft, AssociateRole, DeepPartialObject<AssociateRoleDraft>>
businessUnitDraftFactory
import { businessUnitDraftFactory } from "@evolve-framework/commercetools/factories";
const businessUnitDraftFactory: Factory<BusinessUnitDraft, BusinessUnitDraft, BusinessUnit, DeepPartialObject<CompanyDraft> | DeepPartialObject<DivisionDraft>>
cartDiscountDraftFactory
import { cartDiscountDraftFactory } from "@evolve-framework/commercetools/factories";
const cartDiscountDraftFactory: Factory<CartDiscountDraft, Record<never, never>, CartDiscount, DeepPartialObject<CartDiscountDraft>>
cartDraftFactory
import { cartDraftFactory } from "@evolve-framework/commercetools/factories";
const cartDraftFactory: Factory<CartDraft, CartDraft, Cart, DeepPartialObject<CartDraft>>
categoryDraftFactory
import { categoryDraftFactory } from "@evolve-framework/commercetools/factories";
const categoryDraftFactory: Factory<CategoryDraft, CategoryDraft, Category, DeepPartialObject<CategoryDraft>>
channelDraftFactory
import { channelDraftFactory } from "@evolve-framework/commercetools/factories";
const channelDraftFactory: Factory<ChannelDraft, ChannelDraft, Channel, DeepPartialObject<ChannelDraft>>
customerDraftFactory
import { customerDraftFactory } from "@evolve-framework/commercetools/factories";
const customerDraftFactory: Factory<CustomerDraft, CustomerDraft, Customer, DeepPartialObject<CustomerDraft>>
discountCodeDraftFactory
import { discountCodeDraftFactory } from "@evolve-framework/commercetools/factories";
const discountCodeDraftFactory: Factory<DiscountCodeDraft, { cartDiscounts?: CartDiscountReference[] | undefined; }, DiscountCode, DeepPartialObject<DiscountCodeDraft>>
orderDraftFactory
import { orderDraftFactory } from "@evolve-framework/commercetools/factories";
const orderDraftFactory: Factory<OrderImportDraft, OrderImportDraft, Order, DeepPartialObject<OrderImportDraft>>
paymentDraftFactory
import { paymentDraftFactory } from "@evolve-framework/commercetools/factories";
const paymentDraftFactory: Factory<PaymentDraft, PaymentDraftTransientParams, Payment, DeepPartialObject<PaymentDraft>>
paymentStatusStateTransitionMessageFactory
import { paymentStatusStateTransitionMessageFactory } from "@evolve-framework/commercetools/factories";
const paymentStatusStateTransitionMessageFactory: Factory<PaymentStatusStateTransitionMessage, Record<never, never>, PaymentStatusStateTransitionMessage, DeepPartialObject<PaymentStatusStateTransitionMessage>>
productDiscountDraftFactory
import { productDiscountDraftFactory } from "@evolve-framework/commercetools/factories";
const productDiscountDraftFactory: Factory<ProductDiscountDraft, Record<never, never>, ProductDiscount, DeepPartialObject<ProductDiscountDraft>>
productDraftFactory
import { productDraftFactory } from "@evolve-framework/commercetools/factories";
const productDraftFactory: Factory<ProductDraft, ProductDraft, Product, DeepPartialObject<ProductDraft>>
productTypeDraftFactory
import { productTypeDraftFactory } from "@evolve-framework/commercetools/factories";
const productTypeDraftFactory: Factory<ProductTypeDraft, Record<never, never>, ProductType, DeepPartialObject<ProductTypeDraft>>
shippingMethodDraftFactory
import { shippingMethodDraftFactory } from "@evolve-framework/commercetools/factories";
const shippingMethodDraftFactory: Factory<ShippingMethodDraft, ShippingMethodDraft, ShippingMethod, DeepPartialObject<ShippingMethodDraft>>
shoppingListDraftFactory
import { shoppingListDraftFactory } from "@evolve-framework/commercetools/factories";
const shoppingListDraftFactory: Factory<ShoppingListDraft, ShoppingListDraft, ShoppingList, DeepPartialObject<ShoppingListDraft>>
standalonePriceDraft
import { standalonePriceDraft } from "@evolve-framework/commercetools/factories";
const standalonePriceDraft: Factory<StandalonePriceDraft, StandalonePriceDraft, StandalonePrice, DeepPartialObject<StandalonePriceDraft>>
stateDraftFactory
import { stateDraftFactory } from "@evolve-framework/commercetools/factories";
const stateDraftFactory: Factory<StateDraft, StateDraft, State, DeepPartialObject<StateDraft>>
storeDraftFactory
import { storeDraftFactory } from "@evolve-framework/commercetools/factories";
const storeDraftFactory: Factory<StoreDraft, StoreDraft, Store, DeepPartialObject<StoreDraft>>
taxCategoryDraftFactory
import { taxCategoryDraftFactory } from "@evolve-framework/commercetools/factories";
const taxCategoryDraftFactory: Factory<TaxCategoryDraft, TaxCategoryDraft, TaxCategory, DeepPartialObject<TaxCategoryDraft>>
transactionDraftFactory
import { transactionDraftFactory } from "@evolve-framework/commercetools/factories";
const transactionDraftFactory: Factory<TransactionDraft, TransactionDraft, Transaction, DeepPartialObject<TransactionDraft>>
zoneDraftFactory
import { zoneDraftFactory } from "@evolve-framework/commercetools/factories";
const zoneDraftFactory: Factory<ZoneDraft, ZoneDraft, Zone, DeepPartialObject<ZoneDraft>>

@evolve-framework/commercetools/simulation

Write what a back office would: confirm, ship and deliver orders, raise and pay invoices, and answer quote requests. Only for test environments.

answerRenegotiationAnswer a buyer's renegotiation request with a new offer.
import { answerRenegotiation } from "@evolve-framework/commercetools/simulation";
function answerRenegotiation(
ctApi: ByProjectKeyRequestBuilder,
quote: Quote,
options?: SendQuoteOptions,
): Promise<RenegotiationOutcome>
OptionTypeDescription
validTo?string

When the offer lapses. A moment in the past sends an expired quote.

prices?QuoteLinePrice[]

Per-line prices that replace the list price in the offer.

sellerComment?string

What the merchant tells the buyer about the offer.

quoteNumber?string

The seller's number for the quote, which becomes its key.

Returns Promise<RenegotiationOutcome>

assertSimulationEnabledThrows unless SIMULATION_ENABLED is "true", naming the project.
import { assertSimulationEnabled } from "@evolve-framework/commercetools/simulation";
function assertSimulationEnabled(projectKey: string): void

Returns void

cancelOrderAn order the merchant has called off, whatever its payment says.
import { cancelOrder } from "@evolve-framework/commercetools/simulation";
function cancelOrder(
ctApi: ByProjectKeyRequestBuilder,
order: Order,
): Promise<Order>

Returns Promise<Order>

confirmOrderAn order a merchant has accepted, which is what a back office confirms.
import { confirmOrder } from "@evolve-framework/commercetools/simulation";
function confirmOrder(
ctApi: ByProjectKeyRequestBuilder,
order: Order,
): Promise<Order>

Returns Promise<Order>

createBusinessUnitCreate a company under the given key or a generated one, billing to one address and shipping to the other.
import { createBusinessUnit } from "@evolve-framework/commercetools/simulation";
function createBusinessUnit(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
options: CreateBusinessUnitOptions,
): Promise<BusinessUnit>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

namestring
storestring

The key of the store the unit buys in.

billingAddressBaseAddress
shippingAddressBaseAddress
associates{ customerId: string; roleKeys: string[]; }[]
key?string

Starts with the test prefix; generated when left out.

custom?{ canPayOnAccount?: boolean | undefined; cocNumber?: string | undefined; vatNumber?: string | undefined; vatNumbers?: string[] | undefined; eoriNumber?: string …
typeKey?string

The project's business-unit type, which custom is written to.

Returns Promise<BusinessUnit>

declineQuoteRequestRefuse a quote request outright, without making an offer.
import { declineQuoteRequest } from "@evolve-framework/commercetools/simulation";
function declineQuoteRequest(
ctApi: ByProjectKeyRequestBuilder,
quoteRequest: QuoteRequest,
): Promise<QuoteRequest>

Returns Promise<QuoteRequest>

deliverOrderDeliver part or all of an order, and move the order to wherever that leaves it.
import { deliverOrder } from "@evolve-framework/commercetools/simulation";

The three writes belong together because the second two are answers to the first. Whether the shipment is Partial or Delivered is what is left over after this delivery, and an order whose last delivery has arrived is complete -- so a caller cannot get the delivery right and the state wrong, which is precisely what hand-editing custom fields in the Merchant Center gets wrong.

function deliverOrder(
ctApi: ByProjectKeyRequestBuilder,
order: Order,
options: DeliverOrderOptions,
): Promise<DeliveryOutcome>
OptionTypeDescription
items?DeliveryLine[]

Defaults to everything still undelivered, which is the usual dispatch.

trackingId?string
carrier?string

Returns Promise<DeliveryOutcome>

findOrderAn order by id or by order number, throwing when neither matches.
import { findOrder } from "@evolve-framework/commercetools/simulation";

Both are accepted because both are what a person has to hand: an order number is what the storefront shows and an id is what a log line carries. The id is tried first, since it is the one commercetools guarantees.

function findOrder(
ctApi: ByProjectKeyRequestBuilder,
reference: string,
): Promise<Order>

Returns Promise<Order>

findQuoteA quote by id, throwing when there is none.
import { findQuote } from "@evolve-framework/commercetools/simulation";
function findQuote(
ctApi: ByProjectKeyRequestBuilder,
id: string,
): Promise<Quote>

Returns Promise<Quote>

findQuoteRequestA quote request by id, throwing when there is none.
import { findQuoteRequest } from "@evolve-framework/commercetools/simulation";
function findQuoteRequest(
ctApi: ByProjectKeyRequestBuilder,
id: string,
): Promise<QuoteRequest>

Returns Promise<QuoteRequest>

findReviewA review by its id, or else by its key.
import { findReview } from "@evolve-framework/commercetools/simulation";
function findReview(
ctApi: ByProjectKeyRequestBuilder,
reference: string,
): Promise<Review>

Returns Promise<Review>

isSettableShipmentState
import { isSettableShipmentState } from "@evolve-framework/commercetools/simulation";
function isSettableShipmentState(
value: string,
): value is SettableShipmentState

Returns value is SettableShipmentState

moderateReviewMove a pending review to a moderator's verdict through its state transition, as a moderator does.
import { moderateReview } from "@evolve-framework/commercetools/simulation";
function moderateReview(
ctApi: ByProjectKeyRequestBuilder,
review: Review,
verdict: string,
states?: ReviewStateKeys,
): Promise<Review>
OptionTypeDescription
pendingstring

Where a new review waits. Defaults to ReviewPending.

approvedstring

Defaults to ReviewApproved.

rejectedstring

Defaults to ReviewRejected, the same default ProductReviewModule has.

Returns Promise<Review>

payInvoiceRecord money received against an invoice, outside the storefront.
import { payInvoice } from "@evolve-framework/commercetools/simulation";

One operation for a part payment and a settlement, because to the ledger they are the same event: money arrived. Which of the two it turns out to be is the balance's answer, and having the caller declare it would let them declare it wrong.

No interactionId is written. That field names the storefront payment that settled an invoice, and a bank transfer is not one -- claiming it would make the invoice point at a payment that does not exist.

function payInvoice(
ctApi: ByProjectKeyRequestBuilder,
invoiceId: string,
centAmount?: number,
): Promise<Payment>

Returns Promise<Payment>

payOrderAn order's payment succeeding, written as a provider's report is: the open transaction on the order's newest payment succeeds -- or, with none open, a successful charge for the planned amount is added -- the payment moves to PaymentSuccess and the order to Paid.
import { payOrder } from "@evolve-framework/commercetools/simulation";

Refuses an order without a payment, a cancelled order and one already paid, each of which no provider report would turn into a paid order.

function payOrder(
ctApi: ByProjectKeyRequestBuilder,
order: Order,
): Promise<PaymentOutcome>

Returns Promise<PaymentOutcome>

raiseCreditNoteRaise a credit note for an invoice: a document of its own, as a finance system issues one, rather than a mark on the invoice it corrects.
import { raiseCreditNote } from "@evolve-framework/commercetools/simulation";

It carries a negative total. That is what a credit note is -- money owed the other way -- and it is also what keeps the framework's arithmetic right: an outstanding balance is the total less what was collected, so a credit note raised for a positive amount would report the whole sum as still due and the storefront would offer to pay it.

Who it is billed to and which orders it covers are copied from the invoice being credited. A credit note reaching a different ledger than the invoice it corrects leaves a company's books not adding up.

function raiseCreditNote(
ctApi: ByProjectKeyRequestBuilder,
invoiceId: string,
options: CreditNoteOptions,
): Promise<Payment>
OptionTypeDescription
paymentTypeKeystring
creditNoteNumberstring

The credit note's own number, which is not the credited invoice's.

creditNoteDatestring
centAmount?number

How much is credited, as a positive amount.

reference?string
invoiceUrl?string

Returns Promise<Payment>

raiseInvoiceRaise an invoice, as a finance system would.
import { raiseInvoice } from "@evolve-framework/commercetools/simulation";

The status is written in a second call rather than guessed into the draft. A freshly raised invoice is always open, but saying so here would put a second answer next to the framework's, and the two would part company the day the rule changes.

function raiseInvoice(
ctApi: ByProjectKeyRequestBuilder,
options: RaiseInvoiceOptions,
): Promise<Payment>
OptionTypeDescription
paymentTypeKeystring

The project's payment custom type. An invoice is a payment carrying it.

amountAmount
invoiceNumberstring
invoiceDatestring
dueDatestring
orderNumbersstring[]

The orders this invoice bills. Empty for a standalone invoice.

reference?string
invoiceUrl?string

Link to the invoice document. Defaults to a sample PDF.

businessUnitId?string

Resolved from the key by the caller, since the field holds a reference.

customerId?string

Returns Promise<Payment>

remainingToDeliverWhat is on the order and not yet in a delivery.
import { remainingToDeliver } from "@evolve-framework/commercetools/simulation";

commercetools records deliveries but not what remains, so this is the sum every partial dispatch has to be measured against -- and it is what decides whether the order has been delivered in full.

function remainingToDeliver(order: Order): DeliveryLine[]

Returns DeliveryLine[]

repairInvoiceStatusesWrite the status of every invoice that has none, from its own ledger.
import { repairInvoiceStatuses } from "@evolve-framework/commercetools/simulation";

An invoice raised before the status field existed reads as open until this runs, whatever its transactions say. Running it again finds nothing to do.

function repairInvoiceStatuses(
ctApi: ByProjectKeyRequestBuilder,
options?: RepairInvoiceStatusesOptions,
): Promise<InvoiceStatusRepair[]>
OptionTypeDescription
dryRun?boolean

Report what would be written without writing it.

Returns Promise<InvoiceStatusRepair[]>

resolveDeliveryLinesTurn what a person typed into line items of this order.
import { resolveDeliveryLines } from "@evolve-framework/commercetools/simulation";

A SKU is accepted beside a line item id because a SKU is what somebody looking at a storefront has, and a line item id is what they would have to go and find. A reference matching neither is named rather than skipped: a dispatch that quietly left out a line is a partial delivery nobody asked for.

function resolveDeliveryLines(order: Order, specs: string[]): DeliveryLine[]

Returns DeliveryLine[]

sendQuoteAnswer a quote request with a quote the buyer can see, in the order the Merchant Center writes it: a staged quote that accepts the request, the offer priced in its quotation cart, then the quote sent from it.
import { sendQuote } from "@evolve-framework/commercetools/simulation";
function sendQuote(
ctApi: ByProjectKeyRequestBuilder,
quoteRequest: QuoteRequest,
options?: SendQuoteOptions,
): Promise<Quote>
OptionTypeDescription
validTo?string

When the offer lapses. A moment in the past sends an expired quote.

prices?QuoteLinePrice[]

Per-line prices that replace the list price in the offer.

sellerComment?string

What the merchant tells the buyer about the offer.

quoteNumber?string

The seller's number for the quote, which becomes its key.

Returns Promise<Quote>

setShipmentStateWhere the parcels are, as a warehouse reports it.
import { setShipmentState } from "@evolve-framework/commercetools/simulation";
function setShipmentState(
ctApi: ByProjectKeyRequestBuilder,
order: Order,
shipmentState: "Pending" | "Ready" | "Backorder" | "Canceled" | "Delayed" | "Shipped",
): Promise<Order>

Returns Promise<Order>

simulationClientA system client for the project the surrounding service is configured against, from the same variables that service reads.
import { simulationClient } from "@evolve-framework/commercetools/simulation";
function simulationClient(): Promise<SimulationClient>

Returns Promise<SimulationClient>

withdrawQuotePull a quote back before the buyer accepts it.
import { withdrawQuote } from "@evolve-framework/commercetools/simulation";
function withdrawQuote(
ctApi: ByProjectKeyRequestBuilder,
quote: Quote,
): Promise<Quote>

Returns Promise<Quote>

DEFAULT_REVIEW_STATES
import { DEFAULT_REVIEW_STATES } from "@evolve-framework/commercetools/simulation";
const DEFAULT_REVIEW_STATES: ReviewStateKeys
SAMPLE_INVOICE_PDF_URLThe document a simulated invoice links to when none is given, so an account page has a PDF to open.
import { SAMPLE_INVOICE_PDF_URL } from "@evolve-framework/commercetools/simulation";
const SAMPLE_INVOICE_PDF_URL: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
SETTABLE_SHIPMENT_STATESThe shipment states a warehouse sets on its own.
import { SETTABLE_SHIPMENT_STATES } from "@evolve-framework/commercetools/simulation";

Partial and Delivered are deliberately absent. Both are answers about what has actually been delivered, and deliverOrder is what can work that out -- offering them here would let a simulator produce an order claiming Delivered with nothing dispatched, which is the one kind of fixture worse than none.

const SETTABLE_SHIPMENT_STATES: readonly ["Pending", "Ready", "Shipped", "Delayed", "Backorder", "Canceled"]
TEST_BUSINESS_UNIT_KEY_PREFIXWhat every generated business-unit key starts with.
import { TEST_BUSINESS_UNIT_KEY_PREFIX } from "@evolve-framework/commercetools/simulation";
const TEST_BUSINESS_UNIT_KEY_PREFIX: "evolve-e2e-"
DeliveryLine
import { type DeliveryLine } from "@evolve-framework/commercetools/simulation";
export type DeliveryLine = {
lineItemId: string;
quantity: number;
};
DeliveryOutcome
import { type DeliveryOutcome } from "@evolve-framework/commercetools/simulation";
export type DeliveryOutcome = {
order: Order;
remaining: DeliveryLine[];
};
InvoiceStatusRepair
import { type InvoiceStatusRepair } from "@evolve-framework/commercetools/simulation";
export type InvoiceStatusRepair = {
invoiceId: string;
invoiceNumber: string;
status: string;
};
PaymentOutcome
import { type PaymentOutcome } from "@evolve-framework/commercetools/simulation";
export type PaymentOutcome = {
order: Order;
payment: Payment;
};
QuoteLinePriceA negotiated price for one line, named by its line item id or SKU.
import { type QuoteLinePrice } from "@evolve-framework/commercetools/simulation";
export type QuoteLinePrice = {
line: string;
centAmount: number;
};
RenegotiationOutcome
import { type RenegotiationOutcome } from "@evolve-framework/commercetools/simulation";
export type RenegotiationOutcome = {
quote: Quote;
superseded: Quote;
};
ReviewStateKeysThe review states a moderator moves a review between.
import { type ReviewStateKeys } from "@evolve-framework/commercetools/simulation";
export type ReviewStateKeys = {
pending: string;
approved: string;
rejected: string;
};
SettableShipmentState
import { type SettableShipmentState } from "@evolve-framework/commercetools/simulation";
export type SettableShipmentState = (typeof SETTABLE_SHIPMENT_STATES)[number];
SimulationClient
import { type SimulationClient } from "@evolve-framework/commercetools/simulation";
export type SimulationClient = {
ctApi: RequestBuilder;
projectKey: string;
};

@evolve-framework/commercetools/cleanup

Remove what an end-to-end run created: orders with their payments, carts, quote requests, generated business units, memberships and customers, refusing anything that is not test data.

deleteBackInStockSignUpsByEmailWithdraw every back-in-stock sign-up of a test identity's address, and answer how many there were.
import { deleteBackInStockSignUpsByEmail } from "@evolve-framework/commercetools/cleanup";
function deleteBackInStockSignUpsByEmail(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
email: string,
): Promise<number>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

Returns Promise<number>

deleteBusinessUnitDelete a business unit business-unit/create made, with its orders, quote requests (with quotes), carts, shopping lists and invoices.
import { deleteBusinessUnit } from "@evolve-framework/commercetools/cleanup";
function deleteBusinessUnit(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
key: string,
options?: CleanupOptions,
): Promise<boolean>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

quotes?boolean

Also remove quote requests; needs a client with the quote scopes.

Returns Promise<boolean>

deleteCartDelete a cart that is test data or nobody's: one whose customer or email is a test identity, or an anonymous cart with neither.
import { deleteCart } from "@evolve-framework/commercetools/cleanup";
function deleteCart(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
cartId: string,
): Promise<boolean>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

Returns Promise<boolean>

deleteCustomerDelete a test customer, and first its carts, the one an order was made from included, and its quote requests with the quotes that answer them: either outliving its customer stays on a shared business unit with nobody left to recognize it by.
import { deleteCustomer } from "@evolve-framework/commercetools/cleanup";
function deleteCustomer(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
customerId: string,
options?: CleanupOptions,
): Promise<boolean>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

quotes?boolean

Also remove quote requests; needs a client with the quote scopes.

Returns Promise<boolean>

deleteCustomersByEmailDelete every customer holding a test identity's address, and answer how many there were.
import { deleteCustomersByEmail } from "@evolve-framework/commercetools/cleanup";
function deleteCustomersByEmail(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
email: string,
options?: CleanupOptions,
): Promise<number>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

quotes?boolean

Also remove quote requests; needs a client with the quote scopes.

Returns Promise<number>

deleteOrderDelete an order whose customer is a test identity, with its payments, and put the stock it took back first, so a suite that keeps ordering does not sell a product out.
import { deleteOrder } from "@evolve-framework/commercetools/cleanup";

The payments go after the order, because commercetools refuses to delete one an order still references, and so does the cart the order was made from. They need no check of their own: the order proved they are test data, and once it is gone nothing else can.

function deleteOrder(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
orderId: string,
): Promise<boolean>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

Returns Promise<boolean>

deleteOrdersOfDelete every order a test customer placed, for an order the UI placed and whose id was not known when its rollback had to be enrolled.
import { deleteOrdersOf } from "@evolve-framework/commercetools/cleanup";
function deleteOrdersOf(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
customerId: string,
): Promise<number>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

Returns Promise<number>

deletePaymentDelete a payment, and so an invoice, that belongs to a test order, or whose customer or business unit is a test identity.
import { deletePayment } from "@evolve-framework/commercetools/cleanup";
function deletePayment(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
paymentId: string,
): Promise<boolean>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

Returns Promise<boolean>

deleteQuoteRequestDelete a test customer's quote request with the quotes and staged quote that answer it, the answers first so nothing is left pointing at a request that is gone.
import { deleteQuoteRequest } from "@evolve-framework/commercetools/cleanup";
function deleteQuoteRequest(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
quoteRequestId: string,
): Promise<boolean>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

Returns Promise<boolean>

removeAssociateTake a test customer out of a business unit, with the carts they hold in it, which nobody in the unit can open once they are gone.
import { removeAssociate } from "@evolve-framework/commercetools/cleanup";
function removeAssociate(
ctApi: ByProjectKeyRequestBuilder,
identity: TestIdentity,
businessUnitKey: string,
customerId: string,
): Promise<boolean>
OptionTypeDescription
domainstring

The reserved domain, e.g. test.example.com.

prefixstring

What every generated local part starts with, e.g. e2e-.

Returns Promise<boolean>

@evolve-framework/commercetools/test-support

The commercetools handlers for the test-support service in @evolve-framework/core/test-support.

commercetoolsTestSupportThe commercetools implementation of every test-support action, for createTestSupportModule.
import { commercetoolsTestSupport } from "@evolve-framework/commercetools/test-support";
function commercetoolsTestSupport(
options: CommercetoolsTestSupportOptions,
): CommercetoolsTestSupport
OptionTypeDescription
paymentTypeKeystring

The project's payment custom type, which every invoice carries.

businessUnitTypeKey?string

The project's business-unit custom type. Without it, business-unit/create refuses a request that sets custom fields.

quotes?boolean

Whether cleanup looks for quote requests. Leave it off for a project whose client has no quote scopes, which is refused the lookup.

client?(() => Promise<SimulationClient>)

Defaults to simulationClient, from the service's own configuration.

reviewStates?Partial<ReviewStateKeys>

The project's review state keys, where they differ from ReviewPending, ReviewApproved and ReviewRejected. The rejected key must match ProductReviewModule's rejectedStateKey, or a rejected review is read as not rejected.

Returns CommercetoolsTestSupport

CommercetoolsTestSupport
import { type CommercetoolsTestSupport } from "@evolve-framework/commercetools/test-support";
export type CommercetoolsTestSupport = {
simulate: SimulateHandlers;
cleanup: CleanupHandlers;
};

Commands

For data in a shared environment, the package also adds these commands:

  • evolve cleanup: Development only. Delete what end-to-end runs left behind
  • evolve simulate: Development only. Write what an ERP, a warehouse and a merchant would