diff --git a/.changeset/weak-scissors-jam.md b/.changeset/weak-scissors-jam.md new file mode 100644 index 00000000..8be0f0f0 --- /dev/null +++ b/.changeset/weak-scissors-jam.md @@ -0,0 +1,5 @@ +--- +"@labdigital/commercetools-mock": minor +--- + +Add ability to set shipping and billing addresses when creating customer diff --git a/src/repositories/customer/index.ts b/src/repositories/customer/index.ts index 3203b37b..1e17559b 100644 --- a/src/repositories/customer/index.ts +++ b/src/repositories/customer/index.ts @@ -1,10 +1,12 @@ import type { + Address, Customer, CustomerCreatePasswordResetToken, CustomerDraft, CustomerResetPassword, CustomerToken, DuplicateFieldError, + InvalidInputError, MyCustomerResetPassword, ResourceNotFoundError, } from "@commercetools/platform-sdk"; @@ -53,20 +55,50 @@ export class CustomerRepository extends AbstractResourceRepository<"customer"> { }); } - const addresses = + const addresses: Address[] = draft.addresses?.map((address) => ({ ...address, id: generateRandomString(5), })) ?? []; - const defaultBillingAddressId = - addresses.length > 0 && draft.defaultBillingAddress !== undefined - ? addresses[draft.defaultBillingAddress].id - : undefined; - const defaultShippingAddressId = - addresses.length > 0 && draft.defaultShippingAddress !== undefined - ? addresses[draft.defaultShippingAddress].id - : undefined; + const lookupAdressId = ( + addresses: Address[], + addressId: number, + ): string => { + if (addressId < addresses.length) { + const id = addresses[addressId].id; + if (!id) { + throw new Error("Address ID is missing"); + } + return id; + } + throw new CommercetoolsError({ + code: "InvalidInput", + message: `Address with ID '${addressId}' not found.`, + errors: [ + { + code: "InvalidInput", + message: `Address with ID '${addressId}' not found.`, + field: "addressId", + }, + ], + }); + }; + + const defaultBillingAddressId = draft.defaultBillingAddress + ? lookupAdressId(addresses, draft.defaultBillingAddress) + : undefined; + const defaultShippingAddressId = draft.defaultShippingAddress + ? lookupAdressId(addresses, draft.defaultShippingAddress) + : undefined; + const shippingAddressIds = + draft.shippingAddresses?.map((addressId) => + lookupAdressId(addresses, addressId), + ) ?? []; + const billingAddressIds = + draft.billingAddresses?.map((addressId) => + lookupAdressId(addresses, addressId), + ) ?? []; const resource: Customer = { ...getBaseResourceProperties(), @@ -86,6 +118,8 @@ export class CustomerRepository extends AbstractResourceRepository<"customer"> { externalId: draft.externalId, defaultBillingAddressId: defaultBillingAddressId, defaultShippingAddressId: defaultShippingAddressId, + shippingAddressIds: shippingAddressIds, + billingAddressIds: billingAddressIds, custom: createCustomFields( draft.custom, context.projectKey, diff --git a/src/services/customer.test.ts b/src/services/customer.test.ts index a2d01bb6..1f935d15 100644 --- a/src/services/customer.test.ts +++ b/src/services/customer.test.ts @@ -1,4 +1,8 @@ -import { Customer, CustomerToken } from "@commercetools/platform-sdk"; +import { + Customer, + CustomerDraft, + CustomerToken, +} from "@commercetools/platform-sdk"; import assert from "assert"; import supertest from "supertest"; import { afterEach, beforeEach, describe, expect, test } from "vitest"; @@ -7,6 +11,46 @@ import { CommercetoolsMock, getBaseResourceProperties } from "../index"; const ctMock = new CommercetoolsMock(); +afterEach(() => { + ctMock.clear(); +}); + +describe("Customer create", () => { + test("create new customer", async () => { + const draft: CustomerDraft = { + email: "new-user@example.com", + password: "supersecret", + authenticationMode: "Password", + stores: [], + addresses: [ + { + key: "address-key", + firstName: "John", + lastName: "Doe", + streetName: "Main Street", + streetNumber: "1", + postalCode: "12345", + country: "DE", + }, + ], + billingAddresses: [0], + shippingAddresses: [0], + }; + + const response = await supertest(ctMock.app) + .post(`/dummy/customers`) + .send(draft); + + const customer = response.body.customer as Customer; + expect(response.status, JSON.stringify(customer)).toBe(201); + expect(customer.version).toBe(1); + expect(customer.defaultBillingAddressId).toBeUndefined(); + expect(customer.defaultShippingAddressId).toBeUndefined(); + expect(customer.billingAddressIds).toHaveLength(1); + expect(customer.shippingAddressIds).toHaveLength(1); + }); +}); + describe("Customer Update Actions", () => { let customer: Customer | undefined; @@ -25,10 +69,6 @@ describe("Customer Update Actions", () => { ctMock.project("dummy").add("customer", customer); }); - afterEach(() => { - ctMock.clear(); - }); - test("exists", async () => { assert(customer, "customer not created"); diff --git a/src/services/my-customer.test.ts b/src/services/my-customer.test.ts index 08f18836..f887ecac 100644 --- a/src/services/my-customer.test.ts +++ b/src/services/my-customer.test.ts @@ -35,6 +35,8 @@ describe("Me", () => { version: 1, isEmailVerified: false, addresses: [], + billingAddressIds: [], + shippingAddressIds: [], id: expect.anything(), createdAt: expect.anything(), lastModifiedAt: expect.anything(),