-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(xero): Add integration services
- Loading branch information
1 parent
8503272
commit 3385169
Showing
10 changed files
with
321 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# frozen_string_literal: true | ||
|
||
module Integrations | ||
module Xero | ||
class CreateService < BaseService | ||
def call(**args) | ||
organization = Organization.find_by(id: args[:organization_id]) | ||
|
||
unless organization.premium_integrations.include?('xero') | ||
return result.not_allowed_failure!(code: 'premium_integration_missing') | ||
end | ||
|
||
integration = Integrations::XeroIntegration.new( | ||
organization:, | ||
name: args[:name], | ||
code: args[:code], | ||
connection_id: args[:connection_id] | ||
) | ||
|
||
integration.save! | ||
|
||
if integration.type == 'Integrations::XeroIntegration' | ||
Integrations::Aggregator::PerformSyncJob.set(wait: 2.seconds).perform_later(integration:) | ||
end | ||
|
||
result.integration = integration | ||
result | ||
rescue ActiveRecord::RecordInvalid => e | ||
result.record_validation_failure!(record: e.record) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# frozen_string_literal: true | ||
|
||
module Integrations | ||
module Xero | ||
class UpdateService < BaseService | ||
def initialize(integration:, params:) | ||
@integration = integration | ||
@params = params | ||
|
||
super | ||
end | ||
|
||
def call | ||
return result.not_found_failure!(resource: 'integration') unless integration | ||
|
||
unless integration.organization.premium_integrations.include?('xero') | ||
return result.not_allowed_failure!(code: 'premium_integration_missing') | ||
end | ||
|
||
integration.name = params[:name] if params.key?(:name) | ||
integration.code = params[:code] if params.key?(:code) | ||
|
||
integration.save! | ||
|
||
result.integration = integration | ||
result | ||
rescue ActiveRecord::RecordInvalid => e | ||
result.record_validation_failure!(record: e.record) | ||
end | ||
|
||
private | ||
|
||
attr_reader :integration, :params | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe Integrations::Xero::CreateService, type: :service do | ||
let(:service) { described_class.new(membership.user) } | ||
let(:membership) { create(:membership) } | ||
let(:organization) { membership.organization } | ||
|
||
describe '#call' do | ||
subject(:service_call) { service.call(**create_args) } | ||
|
||
let(:name) { 'Xero 1' } | ||
|
||
let(:create_args) do | ||
{ | ||
name:, | ||
code: 'xero1', | ||
organization_id: organization.id, | ||
connection_id: 'conn1' | ||
} | ||
end | ||
|
||
context 'without premium license' do | ||
it 'does not create an integration' do | ||
expect { service_call }.not_to change(Integrations::XeroIntegration, :count) | ||
end | ||
|
||
it 'returns an error' do | ||
result = service_call | ||
|
||
aggregate_failures do | ||
expect(result).not_to be_success | ||
expect(result.error).to be_a(BaseService::MethodNotAllowedFailure) | ||
end | ||
end | ||
end | ||
|
||
context 'with premium license' do | ||
around { |test| lago_premium!(&test) } | ||
|
||
context 'when xero premium integration is not present' do | ||
it 'returns an error' do | ||
result = service_call | ||
|
||
aggregate_failures do | ||
expect(result).not_to be_success | ||
expect(result.error).to be_a(BaseService::MethodNotAllowedFailure) | ||
end | ||
end | ||
end | ||
|
||
context 'when xero premium integration is present' do | ||
before do | ||
organization.update!(premium_integrations: ['xero']) | ||
end | ||
|
||
context 'without validation errors' do | ||
it 'creates an integration' do | ||
expect { service_call }.to change(Integrations::XeroIntegration, :count).by(1) | ||
|
||
integration = Integrations::XeroIntegration.order(:created_at).last | ||
expect(integration.name).to eq(name) | ||
end | ||
|
||
it 'returns an integration in result object' do | ||
result = service_call | ||
|
||
expect(result.integration).to be_a(Integrations::XeroIntegration) | ||
end | ||
|
||
it 'calls Integrations::Aggregator::PerformSyncJob' do | ||
expect { service_call }.to have_enqueued_job(Integrations::Aggregator::PerformSyncJob) | ||
end | ||
end | ||
|
||
context 'with validation error' do | ||
let(:name) { nil } | ||
|
||
it 'returns an error' do | ||
result = service_call | ||
|
||
aggregate_failures do | ||
expect(result).not_to be_success | ||
expect(result.error).to be_a(BaseService::ValidationFailure) | ||
expect(result.error.messages[:name]).to eq(['value_is_mandatory']) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe Integrations::Xero::UpdateService, type: :service do | ||
let(:integration) { create(:xero_integration, organization:) } | ||
let(:organization) { membership.organization } | ||
let(:membership) { create(:membership) } | ||
|
||
describe '#call' do | ||
subject(:service_call) { described_class.call(integration:, params: update_args) } | ||
|
||
before { integration } | ||
|
||
let(:name) { 'Xero 1' } | ||
|
||
let(:update_args) do | ||
{ | ||
name:, | ||
code: 'xero1' | ||
} | ||
end | ||
|
||
context 'without premium license' do | ||
it 'returns an error' do | ||
result = service_call | ||
|
||
aggregate_failures do | ||
expect(result).not_to be_success | ||
expect(result.error).to be_a(BaseService::MethodNotAllowedFailure) | ||
end | ||
end | ||
end | ||
|
||
context 'with premium license' do | ||
around { |test| lago_premium!(&test) } | ||
|
||
context 'when xero premium integration is not present' do | ||
it 'returns an error' do | ||
result = service_call | ||
|
||
aggregate_failures do | ||
expect(result).not_to be_success | ||
expect(result.error).to be_a(BaseService::MethodNotAllowedFailure) | ||
end | ||
end | ||
end | ||
|
||
context 'when xero premium integration is present' do | ||
before do | ||
organization.update!(premium_integrations: ['xero']) | ||
end | ||
|
||
context 'without validation errors' do | ||
it 'updates an integration' do | ||
service_call | ||
|
||
integration = Integrations::XeroIntegration.order(updated_at: :desc).first | ||
expect(integration.name).to eq(name) | ||
end | ||
|
||
it 'returns an integration in result object' do | ||
result = service_call | ||
|
||
expect(result.integration).to be_a(Integrations::XeroIntegration) | ||
end | ||
end | ||
|
||
context 'with validation error' do | ||
let(:name) { nil } | ||
|
||
it 'returns an error' do | ||
result = service_call | ||
|
||
aggregate_failures do | ||
expect(result).not_to be_success | ||
expect(result.error).to be_a(BaseService::ValidationFailure) | ||
expect(result.error.messages[:name]).to eq(['value_is_mandatory']) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |