Skip to content

Commit

Permalink
update specs
Browse files Browse the repository at this point in the history
  • Loading branch information
lovrocolic committed Dec 27, 2024
1 parent 0eace7c commit 64d8697
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 671 deletions.
33 changes: 1 addition & 32 deletions spec/graphql/mutations/invoices/retry_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,6 @@
amount_cents: 2_000
)
end

let(:integration) { create(:anrok_integration, organization:) }
let(:integration_customer) { create(:anrok_customer, integration:, customer:) }
let(:response) { instance_double(Net::HTTPOK) }
let(:lago_client) { instance_double(LagoHttpClient::Client) }
let(:endpoint) { 'https://api.nango.dev/v1/anrok/finalized_invoices' }
let(:body) do
path = Rails.root.join('spec/fixtures/integration_aggregator/taxes/invoices/success_response.json')
json = File.read(path)

# setting item_id based on the test example
response = JSON.parse(json)
response['succeededInvoices'].first['fees'].first['item_id'] = fee_subscription.id

response.to_json
end
let(:integration_collection_mapping) do
create(
:netsuite_collection_mapping,
integration:,
mapping_type: :fallback_item,
settings: {external_id: '1', external_account_code: '11', external_name: ''}
)
end
let(:mutation) do
<<-GQL
mutation($input: RetryInvoiceInput!) {
Expand All @@ -77,14 +53,7 @@
end

before do
integration_collection_mapping
fee_subscription

integration_customer

allow(LagoHttpClient::Client).to receive(:new).with(endpoint).and_return(lago_client)
allow(lago_client).to receive(:post_with_response).and_return(response)
allow(response).to receive(:body).and_return(body)
end

it_behaves_like 'requires current user'
Expand All @@ -106,7 +75,7 @@
data = result['data']['retryInvoice']

expect(data['id']).to eq(invoice.id)
expect(data['status']).to eq('finalized')
expect(data['status']).to eq('pending')
end
end
end
12 changes: 0 additions & 12 deletions spec/jobs/bill_subscription_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,6 @@
expect(Invoices::SubscriptionService).to have_received(:call)
end

context 'when there is tax error' do
let(:result) do
BaseService::Result.new.validation_failure!(errors: {tax_error: ['invalidMapping']})
end

it 'does not throw an error' do
expect do
described_class.perform_now(subscriptions, timestamp, invoicing_reason:)
end.not_to raise_error
end
end

context 'with a previously created invoice' do
let(:invoice) { create(:invoice, :generating) }

Expand Down
138 changes: 27 additions & 111 deletions spec/services/invoices/calculate_fees_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,101 +160,24 @@
context 'when there is tax provider integration' do
let(:integration) { create(:anrok_integration, organization:) }
let(:integration_customer) { create(:anrok_customer, integration:, customer:) }
let(:response) { instance_double(Net::HTTPOK) }
let(:lago_client) { instance_double(LagoHttpClient::Client) }
let(:endpoint) { 'https://api.nango.dev/v1/anrok/finalized_invoices' }
let(:body) do
p = Rails.root.join('spec/fixtures/integration_aggregator/taxes/invoices/success_response_multiple_fees.json')
File.read(p)
end
let(:integration_collection_mapping) do
create(
:netsuite_collection_mapping,
integration:,
mapping_type: :fallback_item,
settings: {external_id: '1', external_account_code: '11', external_name: ''}
)
end

before do
integration_collection_mapping
integration_customer

allow(LagoHttpClient::Client).to receive(:new).with(endpoint).and_return(lago_client)
allow(lago_client).to receive(:post_with_response).and_return(response)
allow(response).to receive(:body).and_return(body)
allow(Integrations::Aggregator::Taxes::Invoices::CreateDraftService).to receive(:call).and_call_original
allow(Integrations::Aggregator::Taxes::Invoices::CreateService).to receive(:call).and_call_original
allow_any_instance_of(Fee).to receive(:id).and_wrap_original do |m, *args| # rubocop:disable RSpec/AnyInstance
fee = m.receiver
if fee.charge_id == charge.id
'charge_fee_id-12345'
elsif fee.subscription_id == subscription.id
'sub_fee_id-12345'
else
m.call(*args)
end
end
end

it 'creates fees' do
it 'returns tax unknown error and puts invoice in valid status' do
result = invoice_service.call

aggregate_failures do
expect(result).to be_success

expect(result.invoice.fees_amount_cents).to eq(100)
expect(result.invoice.taxes_amount_cents).to eq(10)
expect(result).not_to be_success
expect(result.error.code).to eq('tax_error')
expect(result.error.error_message).to eq('unknown taxes')

expect(result.invoice.reload.error_details.count).to eq(0)
end
end

it 'fetches taxes using finalized invoices service' do
invoice_service.call
expect(Integrations::Aggregator::Taxes::Invoices::CreateService).to have_received(:call)
end

context 'when there is error received from the provider' do
let(:body) do
p = Rails.root.join('spec/fixtures/integration_aggregator/taxes/invoices/failure_response.json')
File.read(p)
end

it 'returns tax error' do
result = invoice_service.call

aggregate_failures do
expect(result).not_to be_success
expect(result.error.code).to eq('tax_error')
expect(result.error.error_message).to eq('taxDateTooFarInFuture')

expect(invoice.reload.status).to eq('failed')
expect(invoice.reload.error_details.count).to eq(1)
expect(invoice.reload.error_details.first.details['tax_error']).to eq('taxDateTooFarInFuture')
end
end

context 'with api limit error' do
let(:body) do
p = Rails.root.join('spec/fixtures/integration_aggregator/taxes/invoices/api_limit_response.json')
File.read(p)
end

it 'returns and store proper error details' do
result = invoice_service.call

aggregate_failures do
expect(result).not_to be_success
expect(result.error.code).to eq('tax_error')
expect(result.error.error_message).to eq('validationError')

expect(invoice.reload.error_details.count).to eq(1)
expect(invoice.reload.error_details.first.details['tax_error']).to eq('validationError')
expect(invoice.reload.error_details.first.details['tax_error_message'])
.to eq("You've exceeded your API limit of 10 per second")
end
end
expect(invoice.reload.status).to eq('pending')
expect(invoice.reload.tax_status).to eq('pending')
expect(invoice.reload.fees_amount_cents).to eq(100)
expect(invoice.reload.taxes_amount_cents).to eq(0)
expect(invoice.reload.error_details.count).to eq(0)
end
end

Expand All @@ -271,48 +194,41 @@
end

context 'when no context is passed' do
let(:endpoint) { 'https://api.nango.dev/v1/anrok/draft_invoices' }

it 'creates fees' do
it 'returns tax unknown error and puts invoice in valid status' do
result = invoice_service.call

aggregate_failures do
expect(result).to be_success

expect(result.invoice.fees_amount_cents).to eq(100)
expect(result.invoice.taxes_amount_cents).to eq(10)
expect(result).not_to be_success
expect(result.error.code).to eq('tax_error')
expect(result.error.error_message).to eq('unknown taxes')

expect(result.invoice.reload.error_details.count).to eq(0)
expect(invoice.reload.status).to eq('draft')
expect(invoice.reload.tax_status).to eq('pending')
expect(invoice.reload.fees_amount_cents).to eq(100)
expect(invoice.reload.taxes_amount_cents).to eq(0)
expect(invoice.reload.error_details.count).to eq(0)
end
end

it 'fetches taxes using draft invoices service' do
invoice_service.call
expect(Integrations::Aggregator::Taxes::Invoices::CreateDraftService).to have_received(:call)
end
end

context 'when context is :finalize' do
let(:endpoint) { 'https://api.nango.dev/v1/anrok/finalized_invoices' }
let(:context) { :finalize }

it 'creates fees' do
it 'returns tax unknown error and puts invoice in valid status' do
result = invoice_service.call

aggregate_failures do
expect(result).to be_success

expect(result.invoice.fees_amount_cents).to eq(100)
expect(result.invoice.taxes_amount_cents).to eq(10)
expect(result).not_to be_success
expect(result.error.code).to eq('tax_error')
expect(result.error.error_message).to eq('unknown taxes')

expect(result.invoice.reload.error_details.count).to eq(0)
expect(invoice.reload.status).to eq('pending')
expect(invoice.reload.tax_status).to eq('pending')
expect(invoice.reload.fees_amount_cents).to eq(100)
expect(invoice.reload.taxes_amount_cents).to eq(0)
expect(invoice.reload.error_details.count).to eq(0)
end
end

it 'fetches taxes using finalized invoices service' do
invoice_service.call
expect(Integrations::Aggregator::Taxes::Invoices::CreateService).to have_received(:call)
end
end
end
end
Expand Down
123 changes: 123 additions & 0 deletions spec/services/invoices/compute_taxes_and_totals_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Invoices::ComputeTaxesAndTotalsService, type: :service do
subject(:totals_service) { described_class.new(invoice:) }

describe '#call' do
let(:organization) { create(:organization) }
let(:customer) { create(:customer, organization:) }

let(:invoice) do
create(
:invoice,
:finalized,
customer:,
organization:,
subscriptions: [subscription],
currency: 'EUR',
issuing_date: Time.zone.at(timestamp).to_date
)
end

let(:subscription) do
create(
:subscription,
plan:,
subscription_at: started_at,
started_at:,
created_at: started_at
)
end

let(:timestamp) { Time.zone.now - 1.year }
let(:started_at) { Time.zone.now - 2.years }
let(:plan) { create(:plan, organization:, interval: 'monthly') }
let(:billable_metric) { create(:billable_metric, aggregation_type: 'count_agg') }
let(:charge) { create(:standard_charge, plan: subscription.plan, charge_model: 'standard', billable_metric:) }

let(:fee_subscription) do
create(
:fee,
invoice:,
subscription:,
fee_type: :subscription,
amount_cents: 2_000
)
end
let(:fee_charge) do
create(
:fee,
invoice:,
charge:,
fee_type: :charge,
total_aggregated_units: 100,
amount_cents: 1_000
)
end

before do
fee_subscription
fee_charge
end

context 'when invoice does not exist' do
it 'returns an error' do
result = described_class.new(invoice: nil).call

expect(result).not_to be_success
expect(result.error.error_code).to eq('invoice_not_found')
end
end

context 'when there is tax provider' do
let(:integration) { create(:anrok_integration, organization:) }
let(:integration_customer) { create(:anrok_customer, integration:, customer:) }

before do
integration_customer
end

it 'enqueues a Invoices::ProviderTaxes::PullTaxesAndApplyJob' do
expect do
totals_service.call
end.to have_enqueued_job(Invoices::ProviderTaxes::PullTaxesAndApplyJob).with(invoice:)
end

it 'sets correct statuses on invoice' do
totals_service.call

expect(invoice.reload.status).to eq('pending')
expect(invoice.reload.tax_status).to eq('pending')
end

context 'when invoice is draft' do
before { invoice.update!(status: :draft) }

it 'sets only tax status' do
described_class.new(invoice:, finalizing: false).call

expect(invoice.reload.status).to eq('draft')
expect(invoice.reload.tax_status).to eq('pending')
end
end
end

context 'when there is NO tax provider' do
let(:result) { BaseService::Result.new }

before do
allow(Invoices::ComputeAmountsFromFees).to receive(:call)
.with(invoice:)
.and_return(result)
end

it 'calls the add on create service' do
totals_service.call

expect(Invoices::ComputeAmountsFromFees).to have_received(:call)
end
end
end
end
Loading

0 comments on commit 64d8697

Please sign in to comment.