Skip to content
Open
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
9 changes: 5 additions & 4 deletions app/services/integrations/aggregator/base_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Aggregator
class BaseService < BaseService
BASE_URL = "https://api.nango.dev/"
REQUEST_LIMIT_ERROR_CODE = "SSS_REQUEST_LIMIT_EXCEEDED"
BAD_REQUEST_ERROR = "502 Bad Gateway"
BAD_GATEWAY_ERROR = "502 Bad Gateway"

def initialize(integration:, options: {})
@integration = integration
Expand Down Expand Up @@ -162,14 +162,15 @@ def request_limit_error?(http_error)
end

def bad_gateway_error?(http_error)
http_error.error_body.include?(BAD_REQUEST_ERROR)
http_error.error_code.to_s == "502" ||
http_error.error_body.include?(BAD_GATEWAY_ERROR)
end

def parse_response(response)
JSON.parse(response.body)
rescue JSON::ParserError
if response.body.include?(BAD_REQUEST_ERROR)
# NOTE: Sometimes, Anrock is responding with an HTTP 200 with a payload containing a 502 error...
if response.body.include?(BAD_GATEWAY_ERROR)
# NOTE: Sometimes, Anrok is responding with an HTTP 200 with a payload containing a 502 error...
raise(Integrations::Aggregator::BadGatewayError.new(response.body, http_client.uri))
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def call
result
rescue LagoHttpClient::HttpError => e
raise RequestLimitError(e) if request_limit_error?(e)
raise e if bad_gateway_error?(e)
raise Integrations::Aggregator::BadGatewayError.new(e.error_body, e.uri) if bad_gateway_error?(e)

code = code(e)
message = message(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def call
result
rescue LagoHttpClient::HttpError => e
raise Integrations::Aggregator::RequestLimitError(e) if request_limit_error?(e)
raise e if bad_gateway_error?(e)
raise Integrations::Aggregator::BadGatewayError.new(e.error_body, e.uri) if bad_gateway_error?(e)

code = code(e)
message = message(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
let(:integration_customer) { create(:anrok_customer, integration:, customer:) }
let(:customer) { create(:customer, :with_shipping_address, organization:) }
let(:organization) { create(:organization) }
let(:lago_client) { instance_double(LagoHttpClient::Client) }
let(:endpoint) { "https://api.nango.dev/v1/anrok/draft_invoices" }
let(:add_on) { create(:add_on, organization:) }
let(:add_on_two) { create(:add_on, organization:) }
Expand Down Expand Up @@ -64,6 +63,7 @@
"Provider-Config-Key" => "anrok"
}
end
let(:response_status) { 200 }

let(:params) do
[
Expand Down Expand Up @@ -99,32 +99,24 @@
end

before do
allow(LagoHttpClient::Client).to receive(:new)
.with(endpoint, retries_on: [OpenSSL::SSL::SSLError])
.and_return(lago_client)

integration_customer
integration_collection_mapping1
integration_mapping_add_on
fee_add_on
fee_add_on_two

stub_request(:post, endpoint).with(body: params.to_json, headers:)
.and_return(status: response_status, body:)
end

describe "#call" do
context "when service call is successful" do
let(:response) { instance_double(Net::HTTPOK) }

before do
allow(lago_client).to receive(:post_with_response).with(kind_of(Array), headers).and_return(response)
allow(response).to receive(:body).and_return(body)
allow(lago_client).to receive(:uri).and_return(endpoint)
end

context "when taxes are successfully fetched" do
let(:body) do
let(:base_body) do
path = Rails.root.join("spec/fixtures/integration_aggregator/taxes/invoices/success_response.json")
File.read(path)
end
let(:body) { base_body }

it "returns fees" do
result = service_call
Expand All @@ -140,16 +132,16 @@
end

context "when special rules applied" do
before do
parsed_body = JSON.parse(body)
let(:body) do
parsed_body = JSON.parse(base_body)
parsed_body["succeededInvoices"].first["fees"].first["tax_amount_cents"] = 0
parsed_body["succeededInvoices"].first["fees"].first["tax_breakdown"] = [
{
reason: "",
type: rule
}
]
allow(response).to receive(:body).and_return(parsed_body.to_json)
parsed_body.to_json
end

special_rules =
Expand Down Expand Up @@ -242,6 +234,8 @@

before do
params.first["fees"].each { |fee| fee["item_code"] = nil }
stub_request(:post, endpoint).with(body: params.to_json, headers:)
.and_return(status: response_status, body:)
end

it "sends request to anrok with empty link to fallback item" do
Expand Down Expand Up @@ -275,14 +269,29 @@
File.read(path)
end

let(:http_error) { LagoHttpClient::HttpError.new(error_code, body, nil) }
context "when the body contains a bad gateway error" do
let(:response_status) { 200 }
let(:body) do
path = Rails.root.join("spec/fixtures/integration_aggregator/bad_gateway_error.html")
File.read(path)
end

it "raises an HTTP error" do
expect { service_call }.to raise_error(Integrations::Aggregator::BadGatewayError)
end
end

before do
allow(lago_client).to receive(:post_with_response).with(params, headers).and_raise(http_error)
context "when the error code is 502" do
let(:response_status) { 502 }
let(:body) { "" }

it "raises an HTTP error" do
expect { service_call }.to raise_error(Integrations::Aggregator::BadGatewayError)
end
end

context "when it is a server error" do
let(:error_code) { Faker::Number.between(from: 500, to: 599) }
context "when it is another server error" do
let(:response_status) { Faker::Number.between(from: 500, to: 599) }

it "returns an error" do
result = service_call
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
let(:integration_customer) { create(:anrok_customer, integration:, customer:, external_customer_id: nil) }
let(:customer) { create(:customer, organization:) }
let(:organization) { create(:organization) }
let(:lago_client) { instance_double(LagoHttpClient::Client) }
let(:endpoint) { "https://api.nango.dev/v1/anrok/finalized_invoices" }
let(:add_on) { create(:add_on, organization:) }
let(:add_on_two) { create(:add_on, organization:) }
Expand Down Expand Up @@ -64,12 +63,12 @@
"Provider-Config-Key" => "anrok"
}
end
let(:response_status) { 200 }

let(:params) do
[
{
"id" => invoice.id,
"issuing_date" => invoice.issuing_date,
"issuing_date" => invoice.issuing_date.to_s,
"currency" => invoice.currency,
"contact" => {
"external_id" => customer.external_id,
Expand All @@ -94,33 +93,25 @@
"item_code" => "1",
"amount_cents" => 200
}
]
],
"id" => invoice.id
}
]
end

before do
allow(LagoHttpClient::Client).to receive(:new)
.with(endpoint, retries_on: [OpenSSL::SSL::SSLError])
.and_return(lago_client)

integration_customer
integration_collection_mapping1
integration_mapping_add_on
fee_add_on
fee_add_on_two

stub_request(:post, endpoint).with(body: params.to_json, headers:)
.and_return(status: response_status, body:)
end

describe "#call" do
context "when service call is successful" do
let(:response) { instance_double(Net::HTTPOK) }

before do
allow(lago_client).to receive(:post_with_response).with(array_including(params), headers).and_return(response)
allow(response).to receive(:body).and_return(body)
allow(lago_client).to receive(:uri).and_return(endpoint)
end

context "when taxes are successfully fetched for finalized invoice" do
let(:body) do
path = Rails.root.join("spec/fixtures/integration_aggregator/taxes/invoices/success_response.json")
Expand Down Expand Up @@ -158,8 +149,6 @@
let(:params) do
[
{
"id" => invoice.id,
"type" => "salesInvoice",
"issuing_date" => invoice.issuing_date,
"currency" => invoice.currency,
"contact" => {
Expand All @@ -185,17 +174,19 @@
"item_key" => fee_add_on.item_key,
"item_id" => fee_add_on.id,
"item_code" => "m1",
"unit" => 0.00,
"unit" => "0.0",
"amount" => "2.0"
},
{
"item_key" => fee_add_on_two.item_key,
"item_id" => fee_add_on_two.id,
"item_code" => "1",
"unit" => 0.00,
"unit" => "0.0",
"amount" => "2.0"
}
]
],
"id" => invoice.id,
"type" => "salesInvoice"
}
]
end
Expand Down Expand Up @@ -232,8 +223,6 @@
let(:params) do
[
{
"id" => invoice.id,
"type" => "returnInvoice",
"issuing_date" => invoice.issuing_date,
"currency" => invoice.currency,
"contact" => {
Expand All @@ -254,22 +243,24 @@
"region" => customer.billing_entity&.state,
"country" => customer.billing_entity&.country
},
"fees" => an_array_matching([
"fees" => [
{
"item_key" => fee_add_on.item_key,
"item_id" => fee_add_on.id,
"item_code" => "m1",
"unit" => 0.00,
"unit" => "0.0",
"amount" => "-2.0"
},
{
"item_key" => fee_add_on_two.item_key,
"item_id" => fee_add_on_two.id,
"item_code" => "1",
"unit" => 0.00,
"unit" => "0.0",
"amount" => "-2.0"
}
])
],
"id" => invoice.id,
"type" => "returnInvoice"
}
]
end
Expand Down Expand Up @@ -335,19 +326,21 @@
end

context "when service call is not successful" do
let(:body) do
path = Rails.root.join("spec/fixtures/integration_aggregator/error_response.json")
File.read(path)
end
context "when the error code is 502" do
let(:response_status) { 502 }
let(:body) { "" }

let(:http_error) { LagoHttpClient::HttpError.new(error_code, body, nil) }

before do
allow(lago_client).to receive(:post_with_response).with(params, headers).and_raise(http_error)
it "raises an HTTP error" do
expect { service_call }.to raise_error(Integrations::Aggregator::BadGatewayError)
end
end

context "when it is a server error" do
let(:error_code) { Faker::Number.between(from: 500, to: 599) }
let(:body) do
path = Rails.root.join("spec/fixtures/integration_aggregator/error_response.json")
File.read(path)
end
let(:response_status) { 500 }

it "returns an error" do
result = service_call
Expand Down
Loading