fix: allow updating billing address on customer

This commit is contained in:
Sebastian Rindom
2021-07-13 10:41:06 +02:00
parent ddf94ca5be
commit 5a1cbc68b7
8 changed files with 267 additions and 33 deletions
@@ -56,6 +56,98 @@ describe("POST /store/customers/:id", () => {
})
})
describe("successfully updates a customer with billing address id", () => {
let subject
beforeAll(async () => {
subject = await request(
"POST",
`/store/customers/${IdMap.getId("lebron")}`,
{
payload: {
billing_address: "test",
},
clientSession: {
jwt: {
customer_id: IdMap.getId("lebron"),
},
},
}
)
})
afterAll(() => {
jest.clearAllMocks()
})
it("calls CustomerService update", () => {
expect(CustomerServiceMock.update).toHaveBeenCalledTimes(1)
expect(CustomerServiceMock.update).toHaveBeenCalledWith(
IdMap.getId("lebron"),
{
billing_address: "test",
}
)
})
it("status code 200", () => {
expect(subject.status).toEqual(200)
})
})
describe("successfully updates a customer with billing address object", () => {
let subject
beforeAll(async () => {
subject = await request(
"POST",
`/store/customers/${IdMap.getId("lebron")}`,
{
payload: {
billing_address: {
first_name: "Olli",
last_name: "Juhl",
address_1: "Laksegade",
city: "Copenhagen",
country_code: "dk",
postal_code: "2100",
phone: "+1 (222) 333 4444",
},
},
clientSession: {
jwt: {
customer_id: IdMap.getId("lebron"),
},
},
}
)
})
afterAll(() => {
jest.clearAllMocks()
})
it("calls CustomerService update", () => {
expect(CustomerServiceMock.update).toHaveBeenCalledTimes(1)
expect(CustomerServiceMock.update).toHaveBeenCalledWith(
IdMap.getId("lebron"),
{
billing_address: {
first_name: "Olli",
last_name: "Juhl",
address_1: "Laksegade",
city: "Copenhagen",
country_code: "dk",
postal_code: "2100",
phone: "+1 (222) 333 4444",
},
}
)
})
it("status code 200", () => {
expect(subject.status).toEqual(200)
})
})
describe("fails if not authenticated", () => {
let subject
beforeAll(async () => {
@@ -58,7 +58,7 @@ export default (app, container) => {
return app
}
export const defaultRelations = ["shipping_addresses"]
export const defaultRelations = ["shipping_addresses", "billing_address"]
export const defaultFields = [
"id",
@@ -44,6 +44,7 @@ export default async (req, res) => {
const { id } = req.params
const schema = Validator.object().keys({
billing_address: Validator.address().optional(),
first_name: Validator.string().optional(),
last_name: Validator.string().optional(),
password: Validator.string().optional(),
@@ -168,8 +168,14 @@ describe("CustomerService", () => {
},
})
const addressRepository = MockRepository({
create: data => data,
save: data => Promise.resolve(data),
})
const customerService = new CustomerService({
manager: MockManager,
addressRepository,
customerRepository,
eventBusService,
})
@@ -233,7 +239,7 @@ describe("CustomerService", () => {
last_name: "Juhl",
address_1: "Laksegade",
city: "Copenhagen",
country_code: "DK",
country_code: "dk",
postal_code: "2100",
phone: "+1 (222) 333 4444",
},
+41 -2
View File
@@ -367,6 +367,7 @@ class CustomerService extends BaseService {
const customerRepository = manager.getCustomRepository(
this.customerRepository_
)
const addrRepo = manager.getCustomRepository(this.addressRepository_)
const customer = await this.retrieve(customerId)
@@ -375,6 +376,7 @@ class CustomerService extends BaseService {
password,
password_hash,
billing_address,
billing_address_id,
metadata,
...rest
} = update
@@ -387,8 +389,9 @@ class CustomerService extends BaseService {
customer.email = this.validateEmail_(email)
}
if (billing_address) {
customer.billing_address = this.validateBillingAddress_(billing_address)
if ("billing_address_id" in update || "billing_address" in update) {
const address = update.billing_address_id || update.billing_address
await this.updateBillingAddress_(customer, address, addrRepo)
}
for (const [key, value] of Object.entries(rest)) {
@@ -400,6 +403,7 @@ class CustomerService extends BaseService {
}
const updated = await customerRepository.save(customer)
await this.eventBus_
.withTransaction(manager)
.emit(CustomerService.Events.UPDATED, updated)
@@ -407,6 +411,41 @@ class CustomerService extends BaseService {
})
}
/**
* Updates the cart's billing address.
* @param {Customer} customer - the Customer to update
* @param {object} address - the value to set the billing address to
* @return {Promise} the result of the update operation
*/
async updateBillingAddress_(customer, addressOrId, addrRepo) {
if (typeof addressOrId === `string`) {
addressOrId = await addrRepo.findOne({
where: { id: addressOrId },
})
}
addressOrId.country_code = addressOrId.country_code.toLowerCase()
if (addressOrId.id) {
customer.billing_address_id = addressOrId.id
customer.billing_address = addressOrId
} else {
if (customer.billing_address_id) {
const addr = await addrRepo.findOne({
where: { id: customer.billing_address_id },
})
await addrRepo.save({ ...addr, ...addressOrId })
} else {
const created = addrRepo.create({
...addressOrId,
})
const saved = await addrRepo.save(created)
customer.billing_address = saved
}
}
}
async updateAddress(customerId, addressId, address) {
return this.atomicPhase_(async manager => {
const addressRepo = manager.getCustomRepository(this.addressRepository_)