fulfillment_order_test.rb 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. # frozen_string_literal: true
  2. require 'test_helper'
  3. require 'fulfillment_order_test_helper'
  4. class FulFillmentOrderTest < Test::Unit::TestCase
  5. include FulfillmentOrderTestHelper
  6. def setup
  7. super
  8. @url_prefix = url_prefix_for_activated_session_for('2020-01')
  9. fake(
  10. 'fulfillment_orders',
  11. url: "#{@url_prefix}/fulfillment_orders/519788021.json",
  12. method: :get,
  13. body: load_fixture('fulfillment_order')
  14. )
  15. end
  16. context "FulfillmentOrder" do
  17. context ".new" do
  18. should "raise NotImplementedError when api_version is older than 2020-01" do
  19. url_prefix_for_activated_session_for('2019-10')
  20. fulfillment_order = load_fixture('fulfillment_order')
  21. exception = assert_raises(NotImplementedError) do
  22. ShopifyAPI::FulfillmentOrder.new(ActiveSupport::JSON.decode(fulfillment_order))
  23. end
  24. assert_equal(
  25. "The minimum supported version is 2020-01.",
  26. exception.message
  27. )
  28. end
  29. end
  30. context ".find and .all" do
  31. should "raise NotImplementedError when api_version is older than 2020-01" do
  32. @url_prefix = url_prefix_for_activated_session_for('2019-10')
  33. fake(
  34. 'fulfillment_orders',
  35. url: "#{@url_prefix}/fulfillment_orders/519788021.json",
  36. method: :get,
  37. body: load_fixture('fulfillment_order')
  38. )
  39. exception = assert_raises(NotImplementedError) do
  40. ShopifyAPI::FulfillmentOrder.find(519788021)
  41. end
  42. assert_equal(
  43. "The minimum supported version is 2020-01.",
  44. exception.message
  45. )
  46. assert_raises(NotImplementedError) do
  47. ShopifyAPI::FulfillmentOrder.all(params: { order_id: 450789469 })
  48. end
  49. end
  50. end
  51. context "#find" do
  52. should "be able to find fulfillment order" do
  53. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  54. assert(fulfillment_order.is_a?(ShopifyAPI::FulfillmentOrder))
  55. assert_equal(519788021, fulfillment_order.id)
  56. assert_equal(450789469, fulfillment_order.order_id)
  57. end
  58. end
  59. context "#all" do
  60. should "be able to list fulfillment orders for an order" do
  61. fake(
  62. 'orders',
  63. url: "#{@url_prefix}/orders/450789469/fulfillment_orders.json",
  64. method: :get,
  65. body: load_fixture('fulfillment_orders')
  66. )
  67. fulfillment_orders = ShopifyAPI::FulfillmentOrder.all(
  68. params: { order_id: 450789469 }
  69. )
  70. assert_equal([519788021, 519788022], fulfillment_orders.map(&:id).sort)
  71. fulfillment_orders.each do |fulfillment_order|
  72. assert(fulfillment_order.is_a?(ShopifyAPI::FulfillmentOrder))
  73. assert_equal(450789469, fulfillment_order.order_id)
  74. end
  75. end
  76. should "require order_id" do
  77. assert_raises(ShopifyAPI::ValidationException) do
  78. ShopifyAPI::FulfillmentOrder.all
  79. end
  80. end
  81. end
  82. context "#fulfillments" do
  83. should "be able to list fulfillments for a fulfillment order" do
  84. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  85. fake(
  86. 'fulfillment_orders',
  87. url: "#{@url_prefix}/fulfillment_orders/#{fulfillment_order.id}/fulfillments.json",
  88. method: :get,
  89. body: load_fixture('fulfillments')
  90. )
  91. fulfillments = fulfillment_order.fulfillments
  92. assert_equal(1, fulfillments.count)
  93. fulfillment = fulfillments.first
  94. assert(fulfillment.is_a?(ShopifyAPI::Fulfillment))
  95. assert_equal(450789469, fulfillment.order_id)
  96. end
  97. end
  98. context "#locations_for_move" do
  99. should "be able to list locations for a fulfillment order" do
  100. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  101. fake(
  102. 'fulfillment_orders',
  103. url: "#{@url_prefix}/fulfillment_orders/#{fulfillment_order.id}/locations_for_move.json",
  104. method: :get,
  105. body: load_fixture('fulfillment_order_locations_for_move')
  106. )
  107. locations_for_move = fulfillment_order.locations_for_move
  108. assert_equal(2, locations_for_move.count)
  109. location_for_move = locations_for_move.first
  110. assert(location_for_move.is_a?(ShopifyAPI::FulfillmentOrderLocationsForMove))
  111. location = location_for_move.location
  112. assert(location.is_a?(ShopifyAPI::Location))
  113. assert_equal(1059367776, location.id)
  114. end
  115. end
  116. context "#move" do
  117. should "move a fulfillment order to a new_location_id" do
  118. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  119. new_location_id = 5
  120. fake_original_fulfillment_order = fulfillment_order.clone
  121. fake_original_fulfillment_order.status = 'closed'
  122. fake_moved_fulfillment_order = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  123. fake_moved_fulfillment_order['assigned_location_id'] = new_location_id
  124. request_body = { fulfillment_order: { new_location_id: 5 } }
  125. body = {
  126. original_fulfillment_order: fake_original_fulfillment_order,
  127. moved_fulfillment_order: fake_moved_fulfillment_order,
  128. remaining_fulfillment_order: nil,
  129. }
  130. fake(
  131. 'fulfillment_orders',
  132. url: "#{@url_prefix}/fulfillment_orders/519788021/move.json",
  133. method: :post,
  134. request_body: ActiveSupport::JSON.encode(request_body),
  135. body: ActiveSupport::JSON.encode(body)
  136. )
  137. response_fulfillment_orders = fulfillment_order.move(new_location_id: new_location_id)
  138. assert_equal('closed', fulfillment_order.status)
  139. assert_equal(3, response_fulfillment_orders.count)
  140. original_fulfillment_order = response_fulfillment_orders['original_fulfillment_order']
  141. refute_nil original_fulfillment_order
  142. assert(original_fulfillment_order.is_a?(ShopifyAPI::FulfillmentOrder))
  143. assert_equal('closed', original_fulfillment_order.status)
  144. moved_fulfillment_order = response_fulfillment_orders['moved_fulfillment_order']
  145. refute_nil moved_fulfillment_order
  146. assert(moved_fulfillment_order.is_a?(ShopifyAPI::FulfillmentOrder))
  147. assert_equal('open', moved_fulfillment_order.status)
  148. assert_equal(new_location_id, moved_fulfillment_order.assigned_location_id)
  149. remaining_fulfillment_order = response_fulfillment_orders['remaining_fulfillment_order']
  150. assert_nil(remaining_fulfillment_order)
  151. end
  152. end
  153. context "#cancel" do
  154. should "cancel a fulfillment order" do
  155. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  156. assert_equal('open', fulfillment_order.status)
  157. cancelled = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  158. cancelled['status'] = 'cancelled'
  159. body = {
  160. fulfillment_order: cancelled,
  161. replacement_fulfillment_order: fulfillment_order,
  162. }
  163. fake(
  164. 'fulfillment_orders',
  165. url: "#{@url_prefix}/fulfillment_orders/519788021/cancel.json",
  166. method: :post,
  167. body: ActiveSupport::JSON.encode(body)
  168. )
  169. response_fulfillment_orders = fulfillment_order.cancel
  170. assert_equal('cancelled', fulfillment_order.status)
  171. assert_equal(2, response_fulfillment_orders.count)
  172. fulfillment_order = response_fulfillment_orders['fulfillment_order']
  173. assert_equal('cancelled', fulfillment_order.status)
  174. replacement_fulfillment_order = response_fulfillment_orders['replacement_fulfillment_order']
  175. assert_equal('open', replacement_fulfillment_order.status)
  176. end
  177. end
  178. context "#close" do
  179. should "be able to close fulfillment order" do
  180. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  181. fulfillment_order.status = 'in_progress'
  182. closed = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  183. closed['status'] = 'incomplete'
  184. request_body = {
  185. fulfillment_order: {
  186. message: "Test close message.",
  187. },
  188. }
  189. fake(
  190. 'fulfillment_orders',
  191. url: "#{@url_prefix}/fulfillment_orders/519788021/close.json",
  192. method: :post,
  193. request_body: ActiveSupport::JSON.encode(request_body),
  194. body: ActiveSupport::JSON.encode(closed)
  195. )
  196. assert(fulfillment_order.close(message: "Test close message."))
  197. assert_equal('incomplete', fulfillment_order.status)
  198. end
  199. end
  200. context "#open" do
  201. should "be able to open fulfillment order" do
  202. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  203. fulfillment_order.status = 'scheduled'
  204. opened = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  205. opened['status'] = 'open'
  206. body = {
  207. fulfillment_order: opened,
  208. }
  209. fake(
  210. 'fulfillment_orders',
  211. url: "#{@url_prefix}/fulfillment_orders/519788021/open.json",
  212. method: :post,
  213. body: ActiveSupport::JSON.encode(body)
  214. )
  215. assert(fulfillment_order.open)
  216. assert_equal('open', fulfillment_order.status)
  217. end
  218. end
  219. context "#reschedule" do
  220. should "be able to rescheduled fulfillment order" do
  221. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  222. fulfillment_order.status = 'scheduled'
  223. new_fulfill_at = "2021-11-29"
  224. rescheduled = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  225. rescheduled['status'] = 'scheduled'
  226. rescheduled['fulfill_at'] = new_fulfill_at
  227. body = {
  228. fulfillment_order: rescheduled,
  229. }
  230. request_body = { fulfillment_order: { new_fulfill_at: new_fulfill_at } }
  231. fake(
  232. 'fulfillment_orders',
  233. url: "#{@url_prefix}/fulfillment_orders/519788021/reschedule.json",
  234. method: :post,
  235. request_body: ActiveSupport::JSON.encode(request_body),
  236. body: ActiveSupport::JSON.encode(body)
  237. )
  238. assert(fulfillment_order.reschedule(new_fulfill_at: new_fulfill_at))
  239. assert_equal('scheduled', fulfillment_order.status)
  240. assert_equal(new_fulfill_at, fulfillment_order.fulfill_at)
  241. end
  242. end
  243. context "#request_fulfillment" do
  244. should "make a fulfillment request for a fulfillment order including unsubmitted" do
  245. fake_original_fulfillment_order = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  246. fake_original_fulfillment_order['status'] = 'closed'
  247. fake_submitted_fulfillment_order = fake_original_fulfillment_order.clone
  248. fake_submitted_fulfillment_order['id'] = 2
  249. fake_submitted_fulfillment_order['status'] = 'open'
  250. fake_submitted_fulfillment_order['request_status'] = 'submitted'
  251. fake_unsubmitted_fulfillment_order = fake_original_fulfillment_order.clone
  252. fake_unsubmitted_fulfillment_order['id'] = 3
  253. fake_unsubmitted_fulfillment_order['status'] = 'open'
  254. fake_unsubmitted_fulfillment_order['request_status'] = 'unsubmitted'
  255. body = {
  256. original_fulfillment_order: fake_original_fulfillment_order,
  257. submitted_fulfillment_order: fake_submitted_fulfillment_order,
  258. unsubmitted_fulfillment_order: fake_unsubmitted_fulfillment_order,
  259. }
  260. request_body = {
  261. fulfillment_request: {
  262. fulfillment_order_line_items: [
  263. { id: 1, quantity: 1 },
  264. ],
  265. message: 'Fulfill this FO, please.',
  266. },
  267. }
  268. fake(
  269. 'fulfillment_orders',
  270. url: "#{@url_prefix}/fulfillment_orders/519788021/fulfillment_request.json",
  271. method: :post,
  272. request_body: ActiveSupport::JSON.encode(request_body),
  273. body: ActiveSupport::JSON.encode(body)
  274. )
  275. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  276. params = {
  277. fulfillment_order_line_items: [{ id: 1, quantity: 1 }],
  278. message: "Fulfill this FO, please.",
  279. }
  280. response_fulfillment_orders = fulfillment_order.request_fulfillment(**params)
  281. assert_equal('closed', fulfillment_order.status)
  282. assert_equal(3, response_fulfillment_orders.size)
  283. original_fulfillment_order = response_fulfillment_orders['original_fulfillment_order']
  284. assert_equal(519788021, original_fulfillment_order.id)
  285. assert_equal('closed', original_fulfillment_order.status)
  286. submitted_fulfillment_order = response_fulfillment_orders['submitted_fulfillment_order']
  287. assert_equal(2, submitted_fulfillment_order.id)
  288. assert_equal('open', submitted_fulfillment_order.status)
  289. assert_equal('submitted', submitted_fulfillment_order.request_status)
  290. unsubmitted_fulfillment_order = response_fulfillment_orders['unsubmitted_fulfillment_order']
  291. assert_equal(3, unsubmitted_fulfillment_order.id)
  292. assert_equal('open', unsubmitted_fulfillment_order.status)
  293. assert_equal('unsubmitted', unsubmitted_fulfillment_order.request_status)
  294. end
  295. should "make a fulfillment request for a fulfillment order excluding unsubmitted" do
  296. fake_original_fulfillment_order = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  297. fake_original_fulfillment_order['status'] = 'closed'
  298. fake_submitted_fulfillment_order = fake_original_fulfillment_order.clone
  299. fake_submitted_fulfillment_order['id'] = 2
  300. fake_submitted_fulfillment_order['status'] = 'open'
  301. fake_submitted_fulfillment_order['request_status'] = 'submitted'
  302. body = {
  303. original_fulfillment_order: fake_original_fulfillment_order,
  304. submitted_fulfillment_order: fake_submitted_fulfillment_order,
  305. unsubmitted_fulfillment_order: nil,
  306. }
  307. request_body = {
  308. fulfillment_request: {
  309. fulfillment_order_line_items: [
  310. { id: 1, quantity: 1 },
  311. ],
  312. message: 'Fulfill this FO, please.',
  313. },
  314. }
  315. fake(
  316. 'fulfillment_orders',
  317. url: "#{@url_prefix}/fulfillment_orders/519788021/fulfillment_request.json",
  318. method: :post,
  319. request_body: ActiveSupport::JSON.encode(request_body),
  320. body: ActiveSupport::JSON.encode(body)
  321. )
  322. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  323. params = {
  324. fulfillment_order_line_items: [{ id: 1, quantity: 1 }],
  325. message: "Fulfill this FO, please.",
  326. }
  327. response_fulfillment_orders = fulfillment_order.request_fulfillment(**params)
  328. assert_equal('closed', fulfillment_order.status)
  329. assert_equal(3, response_fulfillment_orders.size)
  330. original_fulfillment_order = response_fulfillment_orders['original_fulfillment_order']
  331. assert_equal(519788021, original_fulfillment_order.id)
  332. assert_equal('closed', original_fulfillment_order.status)
  333. submitted_fulfillment_order = response_fulfillment_orders['submitted_fulfillment_order']
  334. assert_equal(2, submitted_fulfillment_order.id)
  335. assert_equal('open', submitted_fulfillment_order.status)
  336. assert_equal('submitted', submitted_fulfillment_order.request_status)
  337. assert_nil(response_fulfillment_orders['unsubmitted_fulfillment_order'])
  338. end
  339. end
  340. context "#accept_fulfillment_request" do
  341. should "accept a fulfillment request for a fulfillment order" do
  342. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  343. message = "LGTM. Accept this FO fulfillment request"
  344. request_body = {
  345. 'fulfillment_request' => {
  346. 'message' => message,
  347. },
  348. }
  349. fake_response = {
  350. fulfillment_order: fulfillment_order.attributes.merge(status: 'in_progress', request_status: 'accepted'),
  351. }
  352. fake(
  353. 'fulfillment_orders',
  354. url: "#{@url_prefix}/fulfillment_orders/519788021/fulfillment_request/accept.json",
  355. method: :post,
  356. request_body: ActiveSupport::JSON.encode(request_body),
  357. body: ActiveSupport::JSON.encode(fake_response)
  358. )
  359. accepted = fulfillment_order.accept_fulfillment_request(message: message)
  360. assert_equal(true, accepted)
  361. assert_equal('in_progress', fulfillment_order.status)
  362. assert_equal('accepted', fulfillment_order.request_status)
  363. end
  364. end
  365. context "#reject_fulfillment_request" do
  366. should "reject a fulfillment request for a fulfillment order" do
  367. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  368. message = "LBTM. Reject this FO fulfillment request"
  369. request_body = {
  370. 'fulfillment_request' => {
  371. 'message' => message,
  372. },
  373. }
  374. fake_response = {
  375. fulfillment_order: fulfillment_order.attributes.merge(status: 'open', request_status: 'rejected'),
  376. }
  377. fake(
  378. 'fulfillment_orders',
  379. url: "#{@url_prefix}/fulfillment_orders/519788021/fulfillment_request/reject.json",
  380. method: :post,
  381. request_body: ActiveSupport::JSON.encode(request_body),
  382. body: ActiveSupport::JSON.encode(fake_response)
  383. )
  384. rejected = fulfillment_order.reject_fulfillment_request(message: message)
  385. assert_equal(true, rejected)
  386. assert_equal('open', fulfillment_order.status)
  387. assert_equal('rejected', fulfillment_order.request_status)
  388. end
  389. end
  390. context "#request_cancellation" do
  391. should "make a cancellation request for a fulfillment order" do
  392. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  393. message = "Cancelling this please."
  394. request_body = {
  395. 'cancellation_request' => {
  396. 'message' => message,
  397. },
  398. }
  399. cancelling = ActiveSupport::JSON.decode(load_fixture('fulfillment_order'))
  400. cancelling['status'] = 'in_progress'
  401. cancelling['request_status'] = 'cancellation_requested'
  402. fake(
  403. 'fulfillment_orders',
  404. url: "#{@url_prefix}/fulfillment_orders/519788021/cancellation_request.json",
  405. method: :post,
  406. request_body: ActiveSupport::JSON.encode(request_body),
  407. body: ActiveSupport::JSON.encode({ fulfillment_order: cancelling })
  408. )
  409. cancelled = fulfillment_order.request_cancellation(message: "Cancelling this please.")
  410. assert_equal(true, cancelled)
  411. assert_equal('in_progress', fulfillment_order.status)
  412. assert_equal('cancellation_requested', fulfillment_order.request_status)
  413. end
  414. end
  415. context "#accept_cancellation_request" do
  416. should "accept a cancellation request for a fulfillment order" do
  417. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  418. message = 'Already in-progress. Reject this FO cancellation request'
  419. request_body = {
  420. 'cancellation_request' => {
  421. 'message' => message,
  422. },
  423. }
  424. fake_response = {
  425. fulfillment_order: fulfillment_order.attributes.merge(status: 'cancelled',
  426. request_status: 'cancellation_accepted'),
  427. }
  428. fake(
  429. 'fulfillment_orders',
  430. url: "#{@url_prefix}/fulfillment_orders/519788021/cancellation_request/accept.json",
  431. method: :post,
  432. request_body: ActiveSupport::JSON.encode(request_body),
  433. body: ActiveSupport::JSON.encode(fake_response)
  434. )
  435. accepted = fulfillment_order.accept_cancellation_request(message: message)
  436. assert_equal(true, accepted)
  437. assert_equal('cancelled', fulfillment_order.status)
  438. assert_equal('cancellation_accepted', fulfillment_order.request_status)
  439. end
  440. end
  441. context "#reject_cancellation_request" do
  442. should "reject a cancellation request for a fulfillment order" do
  443. fulfillment_order = ShopifyAPI::FulfillmentOrder.find(519788021)
  444. message = "Already in-progress. Reject this FO cancellation request"
  445. request_body = {
  446. 'cancellation_request' => {
  447. 'message' => message,
  448. },
  449. }
  450. fake_response = {
  451. fulfillment_order: fulfillment_order.attributes.merge(status: 'in_progress',
  452. request_status: 'cancellation_rejected'),
  453. }
  454. fake(
  455. 'fulfillment_orders',
  456. url: "#{@url_prefix}/fulfillment_orders/519788021/cancellation_request/reject.json",
  457. method: :post,
  458. request_body: request_body,
  459. body: ActiveSupport::JSON.encode(fake_response)
  460. )
  461. rejected = fulfillment_order.reject_cancellation_request(message: message)
  462. assert_equal(true, rejected)
  463. assert_equal('in_progress', fulfillment_order.status)
  464. assert_equal('cancellation_rejected', fulfillment_order.request_status)
  465. end
  466. end
  467. end
  468. end