Building a RESTful Web Service :: Learn how to create a RESTful web service with Spring. :: spring-boot http://spring.io/guides/gs/rest-service/

FakeZincControllerUnitTest.java 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Copyright 2016 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package fr.sayasoft.fake.zinc;
  17. import com.google.common.collect.Lists;
  18. import com.google.gson.Gson;
  19. import fr.sayasoft.zinc.sdk.domain.OrderRequest;
  20. import fr.sayasoft.zinc.sdk.domain.PaymentMethod;
  21. import fr.sayasoft.zinc.sdk.domain.Product;
  22. import fr.sayasoft.zinc.sdk.domain.RetailerCredentials;
  23. import fr.sayasoft.zinc.sdk.domain.ZincAddress;
  24. import fr.sayasoft.zinc.sdk.enums.ShippingMethod;
  25. import fr.sayasoft.zinc.sdk.enums.ZincErrorCode;
  26. import org.junit.Test;
  27. import org.junit.runner.RunWith;
  28. import org.springframework.beans.factory.annotation.Autowired;
  29. import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
  30. import org.springframework.boot.test.context.SpringBootTest;
  31. import org.springframework.http.MediaType;
  32. import org.springframework.test.context.junit4.SpringRunner;
  33. import org.springframework.test.web.servlet.MockMvc;
  34. import java.nio.charset.Charset;
  35. import static fr.sayasoft.fake.zinc.FakeZincController.POST_ORDER_RESPONSE;
  36. import static fr.sayasoft.fake.zinc.FakeZincController.POST_ORDER_RESPONSE_TO_BE_REPLACED;
  37. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
  38. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
  39. import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
  40. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
  41. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
  42. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
  43. @RunWith(SpringRunner.class)
  44. @SpringBootTest
  45. @AutoConfigureMockMvc
  46. public class FakeZincControllerUnitTest {
  47. private final OrderRequest orderRequest = OrderRequest.builder()
  48. .retailer("amazon")
  49. .products(Lists.newArrayList(new Product("0923568964")))
  50. .shippingAddress(
  51. ZincAddress.builder()
  52. .firstName("John Hannibal")
  53. .lastName("Smith")
  54. .addressLine1("1234 Main Street")
  55. .addressLine2("above the bar")
  56. .zipCode("11907")
  57. .city("Brooklyn")
  58. .state("NY")
  59. .country("US")
  60. .phoneNumber("123-123-1234")
  61. .build()
  62. ).shippingMethod(ShippingMethod.cheapest) // TODO
  63. .billingAddress( // TODO parametrize
  64. ZincAddress.builder()
  65. .firstName("John Hannibal")
  66. .lastName("Smith")
  67. .addressLine1("1234 Main Street")
  68. .addressLine2("above the bar")
  69. .zipCode("11907")
  70. .city("Brooklyn")
  71. .state("NY")
  72. .country("US")
  73. .phoneNumber("123-123-1234")
  74. .build()
  75. )
  76. .paymentMethod(
  77. PaymentMethod.builder()
  78. .nameOnCard("Hello World")
  79. .number("0000000000000000")
  80. .securityCode("000")
  81. .expirationMonth(12)
  82. .expirationYear(2020)
  83. .useGift(false)
  84. .build()
  85. )
  86. .retailerCredentials(new RetailerCredentials("test@test.fr", "password")) // TODO
  87. .maxPrice(0) // TODO
  88. .giftMessage("Here is your package") // TODO
  89. .isGift(true)
  90. .build();
  91. private final MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
  92. MediaType.APPLICATION_JSON.getSubtype(),
  93. Charset.forName("utf8"));
  94. public static final String POST_ORDER_REQUEST = "{\n" +
  95. " \"client_token\": \"public\",\n" +
  96. " \"idempotency_key\": \"XXX\", \n" +
  97. " \"retailer\": \"amazon\",\n" +
  98. " \"products\": [{\"product_id\": \"0923568964\", \"quantity\": 1}],\n" +
  99. " \"max_price\": 2300,\n" +
  100. " \"shipping_address\": {\n" +
  101. " \"first_name\": \"Tim\",\n" +
  102. " \"last_name\": \"Beaver\",\n" +
  103. " \"address_line1\": \"77 Massachusetts Avenue\",\n" +
  104. " \"address_line2\": \"\",\n" +
  105. " \"zip_code\": \"02139\",\n" +
  106. " \"city\": \"Cambridge\", \n" +
  107. " \"state\": \"MA\",\n" +
  108. " \"country\": \"US\",\n" +
  109. " \"phone_number\": \"5551230101\"\n" +
  110. " },\n" +
  111. " \"is_gift\": true,\n" +
  112. " \"gift_message\": \"Here's your package, Tim! Enjoy!\",\n" +
  113. " \"shipping_method\": \"cheapest\",\n" +
  114. " \"payment_method\": {\n" +
  115. " \"name_on_card\": \"Ben Bitdiddle\",\n" +
  116. " \"number\": \"5555555555554444\",\n" +
  117. " \"security_code\": \"123\",\n" +
  118. " \"expiration_month\": 1,\n" +
  119. " \"expiration_year\": 2015,\n" +
  120. " \"use_gift\": false\n" +
  121. " },\n" +
  122. " \"billing_address\": {\n" +
  123. " \"first_name\": \"William\", \n" +
  124. " \"last_name\": \"Rogers\",\n" +
  125. " \"address_line1\": \"84 Massachusetts Ave\",\n" +
  126. " \"address_line2\": \"\",\n" +
  127. " \"zip_code\": \"02139\",\n" +
  128. " \"city\": \"Cambridge\", \n" +
  129. " \"state\": \"MA\",\n" +
  130. " \"country\": \"US\",\n" +
  131. " \"phone_number\": \"5551234567\"\n" +
  132. " },\n" +
  133. " \"retailer_credentials\": {\n" +
  134. " \"email\": \"timbeaver@gmail.com\",\n" +
  135. " \"password\": \"myAmazonPassword\"\n" +
  136. " },\n" +
  137. " \"webhooks\": {\n" +
  138. " \"order_placed\": \"http://mywebsite.com/zinc/order_placed\",\n" +
  139. " \"order_failed\": \"http://mywebsite.com/zinc/order_failed\",\n" +
  140. " \"tracking_obtained\": \"http://mywebsite.com/zinc/tracking_obtained\"\n" +
  141. " },\n" +
  142. " \"client_notes\": {\n" +
  143. " \"our_internal_order_id\": \"abc123\"\n" +
  144. " }\n" +
  145. "}";
  146. @Autowired
  147. private MockMvc mockMvc;
  148. @Test
  149. public void noParamGreetingShouldReturnDefaultMessage() throws Exception {
  150. this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
  151. .andExpect(jsonPath("$.content").value("Hello, World!"));
  152. }
  153. @Test
  154. public void paramGreetingShouldReturnTailoredMessage() throws Exception {
  155. this.mockMvc.perform(get("/greeting").param("name", "Spring Community"))
  156. .andDo(print()).andExpect(status().isOk())
  157. .andExpect(jsonPath("$.content").value("Hello, Spring Community!"));
  158. }
  159. @Test
  160. public void getOrder() throws Exception {
  161. this.mockMvc.perform(get("/v1/orders/1234546"))
  162. .andDo(print()).andExpect(status().isOk())
  163. .andExpect(content().string(FakeZincController.GET_ORDER_RESPONSE));
  164. }
  165. @Test
  166. public void postOrder_withString() throws Exception {
  167. this.mockMvc.perform(post("/v1/orders")
  168. .contentType(contentType)
  169. .content(POST_ORDER_REQUEST))
  170. .andDo(print())
  171. .andExpect(status().isCreated())
  172. .andExpect(content().string(POST_ORDER_RESPONSE));
  173. }
  174. @Test
  175. public void postOrder_withObject() throws Exception {
  176. final String idempotencyKey = "Carina-β-Carinae-Miaplacidus";
  177. orderRequest.setIdempotencyKey(idempotencyKey);
  178. this.mockMvc.perform(post("/v1/orders")
  179. .contentType(contentType)
  180. .content(new Gson().toJson(orderRequest)))
  181. .andDo(print())
  182. .andExpect(status().isCreated())
  183. .andExpect(content().string(POST_ORDER_RESPONSE.replace(POST_ORDER_RESPONSE_TO_BE_REPLACED, idempotencyKey)));
  184. }
  185. @Test
  186. public void postOrder_KO() throws Exception {
  187. final String idempotencyKey = "Ursa-Major-γ-Ursae-Majoris-Phecda";
  188. final String clientNotes = ZincErrorCode.invalid_quantity.name();
  189. orderRequest.setIdempotencyKey(idempotencyKey);
  190. orderRequest.setClientNotes(clientNotes);
  191. final MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
  192. MediaType.APPLICATION_JSON.getSubtype(),
  193. Charset.forName("utf8"));
  194. this.mockMvc.perform(post("/v1/orders")
  195. .contentType(contentType)
  196. .content(new Gson().toJson(orderRequest)))
  197. .andDo(print())
  198. .andExpect(status().is2xxSuccessful())
  199. .andExpect(content().string("{\"code\":\"invalid_quantity\"," +
  200. "\"message\":\"The quantity for one of the products does not match the one available on the retailer.\"," +
  201. "\"data\":\"Ursa-Major-γ-Ursae-Majoris-Phecda\"" +
  202. "}"));
  203. }
  204. }