Skip to content

Commit f8a5666

Browse files
Change account webhook creation from after_create to after_commit
This ensures that CareerPlug webhooks are only created after the account transaction has been successfully committed to the database. This prevents orphaned webhook records if account creation fails or is rolled back. The change improves data consistency and follows Rails best practices for callbacks that create associated records or have external side effects. Includes tests to verify that: - Webhooks are created after successful account creation - Webhooks are not created if account creation fails/rolls back - Webhooks are not created when CAREERPLUG_WEBHOOK_SECRET is blank
1 parent 6981c65 commit f8a5666

2 files changed

Lines changed: 66 additions & 1 deletion

File tree

app/models/account.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Account < ApplicationRecord
5757

5858
validates :external_account_id, uniqueness: true, allow_nil: true
5959

60-
after_create :create_careerplug_webhook
60+
after_commit :create_careerplug_webhook, on: :create
6161

6262
scope :active, -> { where(archived_at: nil) }
6363

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe Account, '#create_careerplug_webhook' do
6+
around do |example|
7+
original_secret = ENV.fetch('CAREERPLUG_WEBHOOK_SECRET', nil)
8+
original_url = ENV.fetch('CAREERPLUG_WEBHOOK_URL', nil)
9+
10+
# Set required env vars for webhook creation
11+
ENV['CAREERPLUG_WEBHOOK_SECRET'] = 'test_secret'
12+
ENV['CAREERPLUG_WEBHOOK_URL'] = 'http://example.com/webhook'
13+
14+
example.run
15+
16+
# Restore original env vars
17+
ENV['CAREERPLUG_WEBHOOK_SECRET'] = original_secret
18+
ENV['CAREERPLUG_WEBHOOK_URL'] = original_url
19+
end
20+
21+
describe 'CareerPlug webhook creation' do
22+
it 'creates webhook after successful account creation' do
23+
account = build(:account)
24+
expect(account.webhook_urls).to be_empty
25+
26+
account.save!
27+
28+
expect(account.webhook_urls.count).to eq(1)
29+
webhook = account.webhook_urls.first
30+
expect(webhook.url).to eq('http://example.com/webhook')
31+
expect(webhook.events).to eq(['form.viewed', 'form.started', 'form.completed', 'form.declined'])
32+
expect(webhook.secret).to eq({ 'X-CareerPlug-Secret' => 'test_secret' })
33+
end
34+
35+
it 'does not create webhook if account creation fails' do
36+
# This test verifies that after_commit behavior works correctly
37+
# by simulating a transaction rollback
38+
39+
expect do
40+
described_class.transaction do
41+
create(:account)
42+
# Simulate some error that would cause rollback
43+
raise ActiveRecord::Rollback
44+
end
45+
end.not_to change(described_class, :count)
46+
47+
expect do
48+
described_class.transaction do
49+
create(:account)
50+
raise ActiveRecord::Rollback
51+
end
52+
end.not_to change(WebhookUrl, :count)
53+
end
54+
55+
it 'does not create webhook when CAREERPLUG_WEBHOOK_SECRET is blank' do
56+
original_secret = ENV.fetch('CAREERPLUG_WEBHOOK_SECRET', nil)
57+
ENV['CAREERPLUG_WEBHOOK_SECRET'] = ''
58+
59+
account = create(:account)
60+
expect(account.webhook_urls.count).to eq(0)
61+
62+
ENV['CAREERPLUG_WEBHOOK_SECRET'] = original_secret
63+
end
64+
end
65+
end

0 commit comments

Comments
 (0)