مراية لـ
https://github.com/postalserver/postal.git
تم المزامنة 2025-11-30 21:32:30 +00:00
121 أسطر
4.1 KiB
Ruby
121 أسطر
4.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
|
|
RSpec.describe WebhookDeliveryService do
|
|
let(:server) { create(:server) }
|
|
let(:webhook) { create(:webhook, server: server) }
|
|
let(:webhook_request) { create(:webhook_request, :locked, webhook: webhook) }
|
|
|
|
subject(:service) { described_class.new(webhook_request: webhook_request) }
|
|
|
|
let(:response_status) { 200 }
|
|
let(:response_body) { "OK" }
|
|
|
|
before do
|
|
stub_request(:post, webhook.url).to_return(status: response_status, body: response_body)
|
|
end
|
|
|
|
describe "#call" do
|
|
it "sends a request to the webhook's url" do
|
|
service.call
|
|
expect(WebMock).to have_requested(:post, webhook.url).with({
|
|
body: {
|
|
event: webhook_request.event,
|
|
timestamp: webhook_request.created_at.to_f,
|
|
payload: webhook_request.payload,
|
|
uuid: webhook_request.uuid
|
|
}.to_json,
|
|
headers: {
|
|
"Content-Type" => "application/json",
|
|
"X-Postal-Signature" => /\A[a-z0-9\/+]+=*\z/i,
|
|
"X-Postal-Signature-256" => /\A[a-z0-9\/+]+=*\z/i,
|
|
"X-Postal-Signature-KID" => /\A[a-f0-9\/+]{64}\z/i
|
|
}
|
|
})
|
|
end
|
|
|
|
context "when the endpoint returns a 200 OK" do
|
|
it "creates a webhook request for the server" do
|
|
service.call
|
|
expect(server.message_db.webhooks.list(1)[:total]).to eq(1)
|
|
webhook_request = server.message_db.webhooks.list(1)[:records].first
|
|
expect(webhook_request).to have_attributes(
|
|
event: webhook_request.event,
|
|
url: webhook_request.url,
|
|
status_code: 200,
|
|
body: "OK",
|
|
uuid: webhook_request.uuid,
|
|
will_retry?: false,
|
|
payload: webhook_request.payload,
|
|
attempt: 1,
|
|
timestamp: webhook_request.timestamp
|
|
)
|
|
end
|
|
|
|
it "deletes the webhook request" do
|
|
service.call
|
|
expect { webhook_request.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
end
|
|
|
|
it "updates the last used at time on the webhook" do
|
|
frozen_time = Time.current.change(usec: 0)
|
|
Timecop.freeze(frozen_time) do
|
|
service.call
|
|
expect(webhook.reload.last_used_at).to eq(frozen_time)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the request returns a 500 Internal Server Error for the first time" do
|
|
let(:response_status) { 500 }
|
|
let(:response_body) { "internal server error!" }
|
|
|
|
it "unlocks the webhook request if locked" do
|
|
expect { service.call }.to change { webhook_request.reload.locked? }.from(true).to(false)
|
|
end
|
|
|
|
it "updates the retry time and attempt counter" do
|
|
service.call
|
|
expect(webhook_request.reload.attempts).to eq(1)
|
|
expect(webhook_request.retry_after).to be_within(1.second).of(2.minutes.from_now)
|
|
end
|
|
end
|
|
|
|
context "when the request returns a 500 Internal Server Error for the second time" do
|
|
let(:webhook_request) { create(:webhook_request, :locked, webhook: webhook, attempts: 1) }
|
|
let(:response_status) { 500 }
|
|
let(:response_body) { "internal server error!" }
|
|
|
|
it "updates the retry time and attempt counter" do
|
|
service.call
|
|
expect(webhook_request.reload.attempts).to eq(2)
|
|
expect(webhook_request.retry_after).to be_within(1.second).of(3.minutes.from_now)
|
|
end
|
|
end
|
|
|
|
context "when the request returns a 500 Internal Server Error for the sixth time" do
|
|
let(:webhook_request) { create(:webhook_request, :locked, webhook: webhook, attempts: 5) }
|
|
let(:response_status) { 500 }
|
|
let(:response_body) { "internal server error!" }
|
|
|
|
it "creates a webhook request for the server" do
|
|
service.call
|
|
expect(server.message_db.webhooks.list(1)[:total]).to eq(1)
|
|
webhook_request = server.message_db.webhooks.list(1)[:records].first
|
|
expect(webhook_request).to have_attributes(
|
|
status_code: 500,
|
|
body: "internal server error!",
|
|
will_retry?: false,
|
|
attempt: 6
|
|
)
|
|
end
|
|
|
|
it "deletes the webhook request" do
|
|
service.call
|
|
expect { webhook_request.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
end
|
|
end
|
|
end
|
|
end
|