Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ Removes the shipping method from the cart.
+ Attributes (UpdateAddressPayload)
+ Response 200 (application/json)
+ Attributes (FullOrder)


### Create or update [PUT /v1/my/cart/shipping-address]

+ Request (application/json)
+ Attributes(CreateAddressPayload)
+ Response 200 (application/json)
+ Attributes (Address)

### Delete [DELETE]

Expand Down
5 changes: 5 additions & 0 deletions phoenix-scala/phoenix/app/phoenix/routes/Customer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ object Customer {
CartShippingAddressUpdater.updateShippingAddressFromPayload(auth.model, payload)
}
} ~
(put & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒
mutateOrFailures {
CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model, payload)
}
} ~
(delete & pathEnd) {
deleteOrFailures {
CartShippingAddressUpdater.removeShippingAddress(auth.model)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ object CartRoutes {
Some(refNum))
}
} ~
(put & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒
mutateOrFailures {
CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model,
payload,
Some(refNum))
}
} ~
(delete & pathEnd) {
mutateOrFailures {
CartShippingAddressUpdater.removeShippingAddress(auth.model, Some(refNum))
Expand Down
104 changes: 77 additions & 27 deletions phoenix-scala/phoenix/test/integration/AddressesIntegrationTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import phoenix.models.account._
import phoenix.models.cord.OrderShippingAddresses
import phoenix.models.location.{Address, Addresses, Country, Region}
import phoenix.payloads.AddressPayloads.CreateAddressPayload
import phoenix.responses.AddressResponse
import phoenix.payloads.CartPayloads.CreateCart
import phoenix.responses.{AddressResponse, TheResponse}
import phoenix.responses.PublicResponses.CountryWithRegions
import phoenix.responses.cord.CartResponse
import testutils._
import testutils.apis.{PhoenixAdminApi, PhoenixPublicApi}
import testutils.apis.{PhoenixAdminApi, PhoenixPublicApi, PhoenixStorefrontApi}
import testutils.fixtures.BakedFixtures
import testutils.fixtures.api.{randomAddress, ApiFixtureHelpers}

Expand All @@ -18,6 +20,7 @@ class AddressesIntegrationTest
with DefaultJwtAdminAuth
with ApiFixtureHelpers
with PhoenixAdminApi
with PhoenixStorefrontApi
with PhoenixPublicApi
with BakedFixtures {

Expand All @@ -31,15 +34,10 @@ class AddressesIntegrationTest
}

"POST /v1/customers/:customerId/addresses" - {
"creates an address" in new Customer_Seed {
val payload = CreateAddressPayload(name = "Home Office",
regionId = 1,
address1 = "3000 Coolio Dr",
city = "Seattle",
zip = "55555")
"creates an address" in new Customer_Seed with AddressFixture {
val newAddress =
customersApi(customer.accountId).addresses.create(payload).as[AddressResponse]
newAddress.name must === (payload.name)
customersApi(customer.accountId).addresses.create(addressPayload).as[AddressResponse]
newAddress.name must === (addressPayload.name)
newAddress.isDefault must === (Some(false))
}
}
Expand Down Expand Up @@ -74,31 +72,23 @@ class AddressesIntegrationTest
}

"PATCH /v1/customers/:customerId/addresses/:addressId" - {
"can be edited" in new CustomerAddress_Baked {
val payload = CreateAddressPayload(name = "Home Office",
regionId = 1,
address1 = "3000 Coolio Dr",
city = "Seattle",
zip = "55555")
(payload.name, payload.address1) must !==((address.name, address.address1))
"can be edited" in new CustomerAddress_Baked with AddressFixture {
(addressPayload.name, addressPayload.address1) must !==((address.name, address.address1))

val updated =
customersApi(customer.accountId).address(address.id).edit(payload).as[AddressResponse]
val updated = customersApi(customer.accountId)
.address(address.id)
.edit(addressPayload)
.as[AddressResponse]

(updated.name, updated.address1) must === ((payload.name, payload.address1))
(updated.name, updated.address1) must === ((addressPayload.name, addressPayload.address1))
}
}

"DELETE /v1/customers/:customerId/addresses/:addressId" - {
"can be deleted" in new CustomerAddress_Baked {
"can be deleted" in new CustomerAddress_Baked with AddressFixture {

//notice the payload is a default shipping address. Delete should make it not default.
val payload = CreateAddressPayload(name = "Delete Me",
regionId = 1,
address1 = "5000 Delete Dr",
city = "Deattle",
zip = "666",
isDefault = true)
val payload = addressPayload.copy(isDefault = true)

val newAddress: AddressResponse =
customersApi(customer.accountId).addresses.create(payload).as[AddressResponse]
Expand Down Expand Up @@ -144,6 +134,57 @@ class AddressesIntegrationTest
}
}

"Create /v1/my/addresses" - {
"POST shipping addresses into a cart adds it to customer details as well" in new AddressFixture {
withNewCustomerAuth(TestLoginData.random) { implicit auth ⇒
val cart = cartsApi.create(CreateCart(customerId = auth.customerId.some)).as[CartResponse]

storefrontCartsApi.shippingAddress.create(addressPayload).as[TheResponse[CartResponse]]

customersApi(auth.customerId).addresses.get
.as[Seq[AddressResponse]]
.onlyElement
.address1 must === (addressPayload.address1)

cartsApi(cart.referenceNumber)
.get()
.asTheResult[CartResponse]
.shippingAddress
.value
.address1 must === (addressPayload.address1)
}
}

"PUT for shipping addresses must be idempotent" in new AddressFixture {
pending // PR #2036
withNewCustomerAuth(TestLoginData.random) { implicit auth ⇒
val cart = cartsApi.create(CreateCart(customerId = auth.customerId.some)).as[CartResponse]

storefrontCartsApi.shippingAddress.createOrUpdate(addressPayload).mustBeOk()
storefrontCartsApi.shippingAddress.createOrUpdate(addressPayload).mustBeOk()
storefrontCartsApi.shippingAddress
.createOrUpdate(addressPayload.copy(address1 = "My New address"))
.mustBeOk()

val shippingAddress = cartsApi(cart.referenceNumber)
.get()
.asTheResult[CartResponse]
.shippingAddress
.value match {
case adr ⇒ (adr.address1, adr.city, adr.zip)
}

val customerAddress =
customersApi(auth.customerId).addresses.get.as[Seq[AddressResponse]].onlyElement match {
case adr ⇒ (adr.address1, adr.city, adr.zip)
}

shippingAddress must === (("My New address", addressPayload.city, addressPayload.zip))
customerAddress must === (("My New address", addressPayload.city, addressPayload.zip))
}
}
}

"GET /v1/my/addresses" - {
"retrieves a customer's addresses" in {
val (customer, loginData) = api_newCustomerWithLogin()
Expand Down Expand Up @@ -207,4 +248,13 @@ class AddressesIntegrationTest
trait NoDefaultAddressFixture extends CustomerAddress_Baked with EmptyCustomerCart_Baked {
val shippingAddress = OrderShippingAddresses.copyFromAddress(address, cart.refNum).gimme
}

trait AddressFixture {
val addressPayload = CreateAddressPayload(name = "Home Office",
regionId = 1,
address1 = "3000 Coolio Dr",
city = "Seattle",
zip = "55555")
}

}
14 changes: 14 additions & 0 deletions phoenix-scala/phoenix/test/integration/testutils/HttpSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ trait HttpSupport
dispatchRequest(request, jwtCookie)
}

def PUT(path: String, rawBody: String, jwtCookie: Option[Cookie]): HttpResponse = {
val request = HttpRequest(method = HttpMethods.PUT,
uri = pathToAbsoluteUrl(path),
entity = HttpEntity.Strict(
ContentTypes.`application/json`,
ByteString(rawBody)
))

dispatchRequest(request, jwtCookie)
}

def POST(path: String, jwtCookie: Option[Cookie]): HttpResponse =
dispatchRequest(HttpRequest(method = HttpMethods.POST, uri = pathToAbsoluteUrl(path)), jwtCookie)

Expand All @@ -141,6 +152,9 @@ trait HttpSupport
def POST[T <: AnyRef](path: String, payload: T, jwtCookie: Option[Cookie]): HttpResponse =
POST(path, writeJson(payload), jwtCookie)

def PUT[T <: AnyRef](path: String, payload: T, jwtCookie: Option[Cookie]): HttpResponse =
PUT(path, writeJson(payload), jwtCookie)

def PATCH[T <: AnyRef](path: String, payload: T, jwtCookie: Option[Cookie]): HttpResponse =
PATCH(path, writeJson(payload), jwtCookie)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package testutils.apis

import akka.http.scaladsl.model.HttpResponse
import cats.implicits._
import phoenix.payloads.AddressPayloads.CreateAddressPayload
import phoenix.payloads.CartPayloads.CheckoutCart
import phoenix.payloads.LineItemPayloads.UpdateLineItemsPayload
import phoenix.payloads.PaymentPayloads.{CreateApplePayPayment, CreateCreditCardFromTokenPayload}
Expand All @@ -11,6 +12,13 @@ trait PhoenixStorefrontApi extends HttpSupport { self: FoxSuite ⇒

val rootPrefix: String = "v1/my"

object accountApi {
val accountPath = s"$rootPrefix/account"

def getAccount()(implicit ca: TestCustomerAuth): HttpResponse =
GET(accountPath, ca.jwtCookie.some)
}

case class storefrontProductsApi(reference: String) {
val productPath = s"$rootPrefix/products/$reference/baked"

Expand Down Expand Up @@ -42,7 +50,16 @@ trait PhoenixStorefrontApi extends HttpSupport { self: FoxSuite ⇒

def searchByRegion(countryCode: String)(implicit aa: TestCustomerAuth): HttpResponse =
GET(s"$shippingMethods/$countryCode", aa.jwtCookie.some)
}

object shippingAddress {
val shippingAddress = s"$cartPath/shipping-address"

def create(payload: CreateAddressPayload)(implicit ca: TestCustomerAuth): HttpResponse =
POST(shippingAddress, payload, ca.jwtCookie.some)

def createOrUpdate(payload: CreateAddressPayload)(implicit ca: TestCustomerAuth): HttpResponse =
PUT(shippingAddress, payload, ca.jwtCookie.some)
}
}

Expand Down