Skip to content

Commit

Permalink
Add validation of webhook_url by doing actual POST
Browse files Browse the repository at this point in the history
  • Loading branch information
mlandauer committed Aug 25, 2020
1 parent bfb12a6 commit 8a28cd2
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 1 deletion.
18 changes: 17 additions & 1 deletion app/models/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class App < ActiveRecord::Base
}
validate :custom_tracking_domain_points_to_correct_place
validate :validate_dkim_settings
validate :webhook_url_works
# Validating booleans so that they can't have nil values.
# See https://stackoverflow.com/questions/34759092/to-validate-or-not-to-validate-boolean-field
validates :open_tracking_enabled, inclusion: { in: [true, false] }
Expand All @@ -21,7 +22,7 @@ class App < ActiveRecord::Base
validates :legacy_dkim_selector, inclusion: { in: [true, false] }

before_create :set_smtp_password
before_create :set_webhook_key
before_validation :set_webhook_key
after_create :set_smtp_username

def self.cuttlefish
Expand Down Expand Up @@ -144,6 +145,21 @@ def custom_tracking_domain_points_to_correct_place
)
end

def webhook_url_works
return if webhook_url.nil?

RestClient.post(
webhook_url,
{ key: webhook_key, test_event: {} }.to_json,
{ content_type: :json }
)
rescue RestClient::ExceptionWithResponse => e
errors.add(
:webhook_url,
"returned #{e.response.code} code when doing POST to #{webhook_url}"
)
end

def set_smtp_password
# Only set if it hasn't been set already
# This makes testing a little more straightforward
Expand Down
50 changes: 50 additions & 0 deletions spec/fixtures/vcr_cassettes/webhook.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions spec/models/app_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,38 @@
# ).to be_nil
# end
# end

describe "#webhook_url" do
it "should validate if the url returns 200 code from POST" do
url = "https://www.planningalerts.org.au/deliveries"
key = "abc123"
# Expect a POST to be done succesfully
expect(RestClient).to receive(:post).with(
url,
{ key: key, test_event: {} }.to_json,
{ content_type: :json }
)
app = build(:app, webhook_url: url, webhook_key: key)
expect(app).to be_valid
end

it "should validate with nil and not try to do a POST" do
expect(RestClient).to_not receive(:post)
app = build(:app, webhook_url: nil)
expect(app).to be_valid
end

it "should not validate if the url returns a 404" do
VCR.use_cassette("webhook") do
app = build(
:app,
webhook_url: "https://www.planningalerts.org.au/deliveries"
)
expect(app).to_not be_valid
expect(app.errors[:webhook_url]).to eq(
["returned 404 code when doing POST to https://www.planningalerts.org.au/deliveries"]
)
end
end
end
end

0 comments on commit 8a28cd2

Please sign in to comment.