| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- import { CreateCustomerInput, SetCustomerForOrderResult } from '@vendure/common/lib/generated-shop-types';
- import {
- ChannelService,
- Customer,
- CustomerService,
- ErrorResultUnion,
- GuestCheckoutError,
- GuestCheckoutStrategy,
- Injector,
- Order,
- RequestContext,
- TransactionalConnection,
- } from '@vendure/core';
- import {
- createErrorResultGuard,
- createTestEnvironment,
- ErrorResultGuard,
- SimpleGraphQLClient,
- } from '@vendure/testing';
- import path from 'path';
- import { IsNull } from 'typeorm';
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
- import { initialData } from '../../../e2e-common/e2e-initial-data';
- import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
- import { AlreadyLoggedInError } from '../src/common/error/generated-graphql-shop-errors';
- import { testSuccessfulPaymentMethod } from './fixtures/test-payment-methods';
- import { ResultOf } from './graphql/graphql-admin';
- import { FragmentOf } from './graphql/graphql-shop';
- import { getCustomerListDocument } from './graphql/shared-definitions';
- import {
- activeOrderCustomerDocument,
- addItemToOrderDocument,
- setCustomerDocument,
- } from './graphql/shop-definitions';
- class TestGuestCheckoutStrategy implements GuestCheckoutStrategy {
- static allowGuestCheckout = true;
- static allowGuestCheckoutForRegisteredCustomers = true;
- static createNewCustomerOnEmailAddressConflict = false;
- private customerService: CustomerService;
- private connection: TransactionalConnection;
- private channelService: ChannelService;
- init(injector: Injector) {
- this.customerService = injector.get(CustomerService);
- this.connection = injector.get(TransactionalConnection);
- this.channelService = injector.get(ChannelService);
- }
- async setCustomerForOrder(
- ctx: RequestContext,
- order: Order,
- input: CreateCustomerInput,
- ): Promise<ErrorResultUnion<SetCustomerForOrderResult, Customer>> {
- if (TestGuestCheckoutStrategy.allowGuestCheckout === false) {
- return new GuestCheckoutError({ errorDetail: 'Guest orders are disabled' });
- }
- if (ctx.activeUserId) {
- return new AlreadyLoggedInError();
- }
- if (TestGuestCheckoutStrategy.createNewCustomerOnEmailAddressConflict === true) {
- const existing = await this.connection.getRepository(ctx, Customer).findOne({
- relations: ['channels'],
- where: {
- emailAddress: input.emailAddress,
- deletedAt: IsNull(),
- },
- });
- if (existing) {
- const newCustomer = await this.connection
- .getRepository(ctx, Customer)
- .save(new Customer(input));
- await this.channelService.assignToCurrentChannel(newCustomer, ctx);
- return newCustomer;
- }
- }
- const errorOnExistingUser = !TestGuestCheckoutStrategy.allowGuestCheckoutForRegisteredCustomers;
- const customer = await this.customerService.createOrUpdate(ctx, input, errorOnExistingUser);
- return customer;
- }
- }
- describe('Order taxes', () => {
- const { server, adminClient, shopClient } = createTestEnvironment({
- ...testConfig(),
- orderOptions: {
- guestCheckoutStrategy: new TestGuestCheckoutStrategy(),
- },
- paymentOptions: {
- paymentMethodHandlers: [testSuccessfulPaymentMethod],
- },
- });
- let customers: ResultOf<typeof getCustomerListDocument>['customers']['items'];
- const orderResultGuard: ErrorResultGuard<FragmentOf<typeof activeOrderCustomerDocument>> =
- createErrorResultGuard(input => !!input.lines);
- beforeAll(async () => {
- await server.init({
- initialData: {
- ...initialData,
- paymentMethods: [
- {
- name: testSuccessfulPaymentMethod.code,
- handler: { code: testSuccessfulPaymentMethod.code, arguments: [] },
- },
- ],
- },
- productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-full.csv'),
- customerCount: 2,
- });
- await adminClient.asSuperAdmin();
- const result = await adminClient.query(getCustomerListDocument);
- customers = result.customers.items;
- }, TEST_SETUP_TIMEOUT_MS);
- afterAll(async () => {
- await server.destroy();
- });
- it('with guest checkout disabled', async () => {
- TestGuestCheckoutStrategy.allowGuestCheckout = false;
- await shopClient.asAnonymousUser();
- await addItemToOrder(shopClient);
- const { setCustomerForOrder } = await shopClient.query(setCustomerDocument, {
- input: {
- emailAddress: 'guest@test.com',
- firstName: 'Guest',
- lastName: 'User',
- },
- });
- orderResultGuard.assertErrorResult(setCustomerForOrder);
- expect(setCustomerForOrder.errorCode).toBe('GUEST_CHECKOUT_ERROR');
- expect((setCustomerForOrder as any).errorDetail).toBe('Guest orders are disabled');
- });
- it('with guest checkout enabled', async () => {
- TestGuestCheckoutStrategy.allowGuestCheckout = true;
- await shopClient.asAnonymousUser();
- await addItemToOrder(shopClient);
- const { setCustomerForOrder } = await shopClient.query(setCustomerDocument, {
- input: {
- emailAddress: 'guest@test.com',
- firstName: 'Guest',
- lastName: 'User',
- },
- });
- orderResultGuard.assertSuccess(setCustomerForOrder);
- expect(setCustomerForOrder.customer?.emailAddress).toBe('guest@test.com');
- });
- it('with guest checkout for registered customers disabled', async () => {
- TestGuestCheckoutStrategy.allowGuestCheckoutForRegisteredCustomers = false;
- await shopClient.asAnonymousUser();
- await addItemToOrder(shopClient);
- const { setCustomerForOrder } = await shopClient.query(setCustomerDocument, {
- input: {
- emailAddress: customers[0].emailAddress,
- firstName: customers[0].firstName,
- lastName: customers[0].lastName,
- },
- });
- orderResultGuard.assertErrorResult(setCustomerForOrder);
- expect(setCustomerForOrder.errorCode).toBe('EMAIL_ADDRESS_CONFLICT_ERROR');
- });
- it('with guest checkout for registered customers enabled', async () => {
- TestGuestCheckoutStrategy.allowGuestCheckoutForRegisteredCustomers = true;
- await shopClient.asAnonymousUser();
- await addItemToOrder(shopClient);
- const { setCustomerForOrder } = await shopClient.query(setCustomerDocument, {
- input: {
- emailAddress: customers[0].emailAddress,
- firstName: customers[0].firstName,
- lastName: customers[0].lastName,
- },
- });
- orderResultGuard.assertSuccess(setCustomerForOrder);
- expect(setCustomerForOrder.customer?.emailAddress).toBe(customers[0].emailAddress);
- expect(setCustomerForOrder.customer?.id).toBe(customers[0].id);
- });
- it('create new customer on email address conflict', async () => {
- TestGuestCheckoutStrategy.createNewCustomerOnEmailAddressConflict = true;
- await shopClient.asAnonymousUser();
- await addItemToOrder(shopClient);
- const { setCustomerForOrder } = await shopClient.query(setCustomerDocument, {
- input: {
- emailAddress: customers[0].emailAddress,
- firstName: customers[0].firstName,
- lastName: customers[0].lastName,
- },
- });
- orderResultGuard.assertSuccess(setCustomerForOrder);
- expect(setCustomerForOrder.customer?.emailAddress).toBe(customers[0].emailAddress);
- expect(setCustomerForOrder.customer?.id).not.toBe(customers[0].id);
- });
- it('when already logged in', async () => {
- await shopClient.asUserWithCredentials(customers[0].emailAddress, 'test');
- await addItemToOrder(shopClient);
- const { setCustomerForOrder } = await shopClient.query(setCustomerDocument, {
- input: {
- emailAddress: customers[0].emailAddress,
- firstName: customers[0].firstName,
- lastName: customers[0].lastName,
- },
- });
- orderResultGuard.assertErrorResult(setCustomerForOrder);
- expect(setCustomerForOrder.errorCode).toBe('ALREADY_LOGGED_IN_ERROR');
- });
- });
- async function addItemToOrder(shopClient: SimpleGraphQLClient) {
- await shopClient.query(addItemToOrderDocument, {
- productVariantId: 'T_1',
- quantity: 1,
- });
- }
|