From ff2a5072db6cebc9383c446fbdb33ce1ff11f69d Mon Sep 17 00:00:00 2001 From: Rohan Likhite Date: Mon, 25 Mar 2024 10:57:28 -0400 Subject: [PATCH 1/3] WIP get patch working --- lib/intelligent_foods/api_client.rb | 9 +++- lib/intelligent_foods/errors.rb | 2 + lib/intelligent_foods/resources/order.rb | 18 ++++++++ spec/intelligent_foods/api_client_spec.rb | 10 +++++ .../intelligent_foods/resources/order_spec.rb | 41 +++++++++++++++++++ spec/support/helpers/api_helper.rb | 13 ++++++ 6 files changed, 91 insertions(+), 2 deletions(-) diff --git a/lib/intelligent_foods/api_client.rb b/lib/intelligent_foods/api_client.rb index 5b8e625..d3b1f6b 100644 --- a/lib/intelligent_foods/api_client.rb +++ b/lib/intelligent_foods/api_client.rb @@ -34,8 +34,13 @@ def execute_request(request:, uri:, body: nil, end end - def build_request_with_body(uri:, body:) - request = Net::HTTP::Post.new(uri) + def build_patch_request(uri:, body:) + build_request_with_body(uri: uri, body: body, + http_method: Net::HTTP::Patch) + end + + def build_request_with_body(uri:, body:, http_method: Net::HTTP::Post) + request = http_method.new(uri) request.body = body.to_json request["content-type"] = "application/json" request diff --git a/lib/intelligent_foods/errors.rb b/lib/intelligent_foods/errors.rb index 7648540..8511dcb 100644 --- a/lib/intelligent_foods/errors.rb +++ b/lib/intelligent_foods/errors.rb @@ -8,4 +8,6 @@ class OrderNotCancelledError < ApiError; end class OrderNotCreatedError < ApiError; end class AuthenticationError < ApiError; end + + class OrderNotUpdatedError < ApiError; end end diff --git a/lib/intelligent_foods/resources/order.rb b/lib/intelligent_foods/resources/order.rb index f3ff679..4758cf9 100644 --- a/lib/intelligent_foods/resources/order.rb +++ b/lib/intelligent_foods/resources/order.rb @@ -45,6 +45,18 @@ def cancel! end end + def update! + uri = URI("#{IntelligentFoods.base_url}/order/#{id}") + request = client.build_patch_request(uri: uri, body: update_request_body) + response = client.execute_request(request: request, uri: uri) + if response.success? + Order::build_from_response(response.data) + else + mark_as_invalid + raise_error(OrderNotUpdatedError, response) + end + end + def request_body @request_body ||= { menu_id: menu.id, @@ -55,6 +67,12 @@ def request_body } end + def update_request_body + @update_request_body ||= { + ship_to: ship_to, + } + end + def cancelled? status.downcase == CANCELLED end diff --git a/spec/intelligent_foods/api_client_spec.rb b/spec/intelligent_foods/api_client_spec.rb index 6bf86aa..8422447 100644 --- a/spec/intelligent_foods/api_client_spec.rb +++ b/spec/intelligent_foods/api_client_spec.rb @@ -165,6 +165,16 @@ end end + describe "#build_patch_request" do + it "builds a request using the Patch HTTP method" do + client = IntelligentFoods::ApiClient.new(id: "id", secret: "secret") + + result = client.build_patch_request(uri: "test.com", body: {}) + + expect(result.method).to eq("PATCH") + end + end + describe "#authenticated?" do it "is not authenticated" do client = IntelligentFoods::ApiClient.new(id: "id", secret: "secret") diff --git a/spec/intelligent_foods/resources/order_spec.rb b/spec/intelligent_foods/resources/order_spec.rb index 64d4e50..722645d 100644 --- a/spec/intelligent_foods/resources/order_spec.rb +++ b/spec/intelligent_foods/resources/order_spec.rb @@ -142,4 +142,45 @@ end end end + + describe "#update!" do + it "updates the order" do + order = build_stubbed_order + body = build_order_response + response = build_response(body: body) + stub_api_response response: response + + result = order.update! + + expect(result).to be_accepted + end + + context "the response code is not 200" do + it "raises a OrderNotUpdatedError" do + order = build_stubbed_order + response = error_response(message: "Order Not Found", + http_status_code: 404) + stub_api_response response: response + + expect { + order.update! + }.to raise_error(IntelligentFoods::OrderNotUpdatedError) + end + + it "marks the order as not valid" do + order = build_stubbed_order + response = error_response(message: "Order Not Found", + http_status_code: 404) + stub_api_response response: response + + begin + order.update! + rescue IntelligentFoods::OrderNotUpdatedError + # noop + end + + expect(order).not_to be_valid + end + end + end end diff --git a/spec/support/helpers/api_helper.rb b/spec/support/helpers/api_helper.rb index 5098819..26685fc 100644 --- a/spec/support/helpers/api_helper.rb +++ b/spec/support/helpers/api_helper.rb @@ -44,6 +44,19 @@ def read_error_response parse_json_file(ERROR_API_RESPONSE) end + def build_stubbed_order + recipient = build(:recipient) + menu = build(:menu, id: "2023-01-01") + order_item = build(:order_item) + callback_url = "https://api.domain.com/callback" + IntelligentFoods::Order.new(menu: menu, + recipient: recipient, + delivery_date: "2023-01-07", + items: [order_item], + external_id: "1337", + callback_url: callback_url) + end + def read_menu_api_response parse_json_file(MENU_API_RESPONSE) end From 522a410f9b53bb0ca5557bf0709ae4ed92ba5631 Mon Sep 17 00:00:00 2001 From: Rohan Likhite Date: Wed, 27 Mar 2024 10:00:47 -0400 Subject: [PATCH 2/3] WIP PR comments --- lib/intelligent_foods/api_client.rb | 31 ++++++++++++++--------- lib/intelligent_foods/resources/order.rb | 6 ++--- spec/intelligent_foods/api_client_spec.rb | 10 ++++++++ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/intelligent_foods/api_client.rb b/lib/intelligent_foods/api_client.rb index d3b1f6b..f3841f0 100644 --- a/lib/intelligent_foods/api_client.rb +++ b/lib/intelligent_foods/api_client.rb @@ -24,28 +24,35 @@ def authenticate! self end - def execute_request(request:, uri:, body: nil, - authorization: default_authorization) - Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| - request["Authorization"] = authorization.header - assign_body request: request, body: body - response = http.request(request) - handle_response(response: response) - end + def build_patch_request(uri:, body: nil) + build_request_with_body(uri: uri, body: body, + http_method: Net::HTTP::Patch) end - def build_patch_request(uri:, body:) + def build_post_request(uri:, body: nil) build_request_with_body(uri: uri, body: body, - http_method: Net::HTTP::Patch) + http_method: Net::HTTP::Post) end - def build_request_with_body(uri:, body:, http_method: Net::HTTP::Post) + def build_request_with_body(uri:, body:, http_method:) request = http_method.new(uri) - request.body = body.to_json request["content-type"] = "application/json" + unless body.nil? + request.body = body.to_json + end request end + def execute_request(request:, uri:, body: nil, + authorization: default_authorization) + Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| + request["Authorization"] = authorization.header + assign_body request: request, body: body + response = http.request(request) + handle_response(response: response) + end + end + def authenticated? access_token.present? end diff --git a/lib/intelligent_foods/resources/order.rb b/lib/intelligent_foods/resources/order.rb index 4758cf9..24fd8a1 100644 --- a/lib/intelligent_foods/resources/order.rb +++ b/lib/intelligent_foods/resources/order.rb @@ -22,7 +22,7 @@ def self.build_from_response(data) def create! uri = URI("#{IntelligentFoods.base_url}/order") - request = client.build_request_with_body(uri: uri, body: request_body) + request = client.build_post_request(uri: uri, body: request_body) response = client.execute_request(request: request, uri: uri) if response.success? Order::build_from_response(response.data) @@ -53,7 +53,7 @@ def update! Order::build_from_response(response.data) else mark_as_invalid - raise_error(OrderNotUpdatedError, response) + raise OrderNotUpdatedError.build(response) end end @@ -68,7 +68,7 @@ def request_body end def update_request_body - @update_request_body ||= { + { ship_to: ship_to, } end diff --git a/spec/intelligent_foods/api_client_spec.rb b/spec/intelligent_foods/api_client_spec.rb index 8422447..ff88fda 100644 --- a/spec/intelligent_foods/api_client_spec.rb +++ b/spec/intelligent_foods/api_client_spec.rb @@ -175,6 +175,16 @@ end end + describe "#build_post_request" do + it "builds a request using the Post HTTP method" do + client = IntelligentFoods::ApiClient.new(id: "id", secret: "secret") + + result = client.build_post_request(uri: "test.com", body: {}) + + expect(result.method).to eq("POST") + end + end + describe "#authenticated?" do it "is not authenticated" do client = IntelligentFoods::ApiClient.new(id: "id", secret: "secret") From 249f1bddb57bdf9da44528eb90800d451ac956c3 Mon Sep 17 00:00:00 2001 From: Rohan Likhite Date: Thu, 30 May 2024 14:16:50 -0400 Subject: [PATCH 3/3] WIP pr comments --- spec/factories.rb | 11 +++++++++++ spec/intelligent_foods/resources/order_spec.rb | 6 +++--- spec/support/helpers/api_helper.rb | 13 ------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index 7cfeae7..2b6cd0d 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,4 +1,15 @@ FactoryBot.define do + factory :order, class: "IntelligentFoods::Order" do + menu + recipient + delivery_date { Date.today.to_s } + items { [build(:order_item)] } + sequence :external_id do |n| + "d89397e1bad49c3b855df4406e5bf0#{n}" + end + callback_url { "http://test.com/api/callback" } + end + factory :recipient, class: "IntelligentFoods::Recipient" do name { "First Name" } street1 { "123 Main Street" } diff --git a/spec/intelligent_foods/resources/order_spec.rb b/spec/intelligent_foods/resources/order_spec.rb index 722645d..603411a 100644 --- a/spec/intelligent_foods/resources/order_spec.rb +++ b/spec/intelligent_foods/resources/order_spec.rb @@ -145,7 +145,7 @@ describe "#update!" do it "updates the order" do - order = build_stubbed_order + order = build(:order) body = build_order_response response = build_response(body: body) stub_api_response response: response @@ -157,7 +157,7 @@ context "the response code is not 200" do it "raises a OrderNotUpdatedError" do - order = build_stubbed_order + order = build(:order) response = error_response(message: "Order Not Found", http_status_code: 404) stub_api_response response: response @@ -168,7 +168,7 @@ end it "marks the order as not valid" do - order = build_stubbed_order + order = build(:order) response = error_response(message: "Order Not Found", http_status_code: 404) stub_api_response response: response diff --git a/spec/support/helpers/api_helper.rb b/spec/support/helpers/api_helper.rb index 26685fc..5098819 100644 --- a/spec/support/helpers/api_helper.rb +++ b/spec/support/helpers/api_helper.rb @@ -44,19 +44,6 @@ def read_error_response parse_json_file(ERROR_API_RESPONSE) end - def build_stubbed_order - recipient = build(:recipient) - menu = build(:menu, id: "2023-01-01") - order_item = build(:order_item) - callback_url = "https://api.domain.com/callback" - IntelligentFoods::Order.new(menu: menu, - recipient: recipient, - delivery_date: "2023-01-07", - items: [order_item], - external_id: "1337", - callback_url: callback_url) - end - def read_menu_api_response parse_json_file(MENU_API_RESPONSE) end