Skip to content

Commit

Permalink
feat(hubspot): Add subscription jobs (#2746)
Browse files Browse the repository at this point in the history
## Roadmap Task

👉  https://getlago.canny.io/feature-requests/p/integration-with-hubspot

## Context

When creating or updating subscriptions in Lago, we must sync them to
Hubspot.

## Description

This PR implements jobs that handle syncing subscriptions to Hubspot.
  • Loading branch information
ivannovosad authored Oct 28, 2024
1 parent 21ad463 commit cfdd0ee
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 0 deletions.
1 change: 1 addition & 0 deletions Guardfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ guard :rspec, cmd: 'bundle exec rspec' do
end
watch('app/services/integrations/aggregator/base_service.rb') { 'spec/services/integrations/aggregator/' }
watch('app/services/base_service.rb') { 'spec/services/' }
watch('app/jobs/application_job.rb') { 'spec/jobs/' }
watch('app/models/application_record.rb') { 'spec/models/' }
watch('app/serializers/model_serializer.rb') { 'spec/serializers/' }
watch(%r{^spec/.+_spec\.rb$})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Integrations
module Aggregator
module Subscriptions
module Crm
class CreateCustomerAssociationJob < ApplicationJob
queue_as 'integrations'

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 10

def perform(subscription:)
result = Integrations::Aggregator::Subscriptions::Crm::CreateCustomerAssociationService.call(subscription:)
result.raise_if_error!
end
end
end
end
end
end
27 changes: 27 additions & 0 deletions app/jobs/integrations/aggregator/subscriptions/crm/create_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

module Integrations
module Aggregator
module Subscriptions
module Crm
class CreateJob < ApplicationJob
queue_as 'integrations'

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on Integrations::Aggregator::BasePayload::Failure, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 10

def perform(subscription:)
result = Integrations::Aggregator::Subscriptions::Crm::CreateService.call(subscription:)

if result.success?
Integrations::Aggregator::Subscriptions::Crm::CreateCustomerAssociationJob.perform_later(subscription:)
end

result.raise_if_error!
end
end
end
end
end
end
22 changes: 22 additions & 0 deletions app/jobs/integrations/aggregator/subscriptions/crm/update_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Integrations
module Aggregator
module Subscriptions
module Crm
class UpdateJob < ApplicationJob
queue_as 'integrations'

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on Integrations::Aggregator::BasePayload::Failure, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 10

def perform(subscription:)
result = Integrations::Aggregator::Subscriptions::Crm::UpdateService.call(subscription:)
result.raise_if_error!
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Integrations::Aggregator::Subscriptions::Crm::CreateCustomerAssociationJob, type: :job do
subject(:create_job) { described_class }

let(:service) { instance_double(Integrations::Aggregator::Subscriptions::Crm::CreateCustomerAssociationService) }
let(:subscription) { create(:subscription) }
let(:result) { BaseService::Result.new }

before do
allow(Integrations::Aggregator::Subscriptions::Crm::CreateCustomerAssociationService)
.to receive(:new).and_return(service)
allow(service).to receive(:call).and_return(result)
end

it 'calls the aggregator create subscription crm service' do
described_class.perform_now(subscription:)

aggregate_failures do
expect(Integrations::Aggregator::Subscriptions::Crm::CreateCustomerAssociationService).to have_received(:new)
expect(service).to have_received(:call)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Integrations::Aggregator::Subscriptions::Crm::CreateJob, type: :job do
subject(:create_job) { described_class }

let(:service) { instance_double(Integrations::Aggregator::Subscriptions::Crm::CreateService) }
let(:subscription) { create(:subscription) }
let(:result) { BaseService::Result.new }

before do
allow(Integrations::Aggregator::Subscriptions::Crm::CreateService).to receive(:new).and_return(service)
allow(service).to receive(:call).and_return(result)
end

context 'when the service call is not successful' do
before do
allow(result).to receive(:success?).and_return(false)
allow(result).to receive(:raise_if_error!).and_raise(StandardError)
end

it 'raises an error' do
expect { create_job.perform_now(subscription:) }.to raise_error(StandardError)
end
end

context 'when the service call is successful' do
it 'calls the aggregator create subscription crm service' do
described_class.perform_now(subscription:)

aggregate_failures do
expect(Integrations::Aggregator::Subscriptions::Crm::CreateService).to have_received(:new)
expect(service).to have_received(:call)
end
end

it 'enqueues the aggregator create customer association subscription job' do
expect do
described_class.perform_now(subscription:)
end.to have_enqueued_job(Integrations::Aggregator::Subscriptions::Crm::CreateCustomerAssociationJob).with(subscription:)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Integrations::Aggregator::Subscriptions::Crm::UpdateJob, type: :job do
subject(:create_job) { described_class }

let(:service) { instance_double(Integrations::Aggregator::Subscriptions::Crm::UpdateService) }
let(:subscription) { create(:subscription) }
let(:result) { BaseService::Result.new }

before do
allow(Integrations::Aggregator::Subscriptions::Crm::UpdateService).to receive(:new).and_return(service)
allow(service).to receive(:call).and_return(result)
end

it 'calls the aggregator create subscription crm service' do
described_class.perform_now(subscription:)

aggregate_failures do
expect(Integrations::Aggregator::Subscriptions::Crm::UpdateService).to have_received(:new)
expect(service).to have_received(:call)
end
end
end

0 comments on commit cfdd0ee

Please sign in to comment.