Skip to content

Commit

Permalink
Refactor Hanami specs to use Transaction#to_h
Browse files Browse the repository at this point in the history
Don't assert method calls but check what the extension receives for
transaction data.

Part of #252

[skip changeset]
  • Loading branch information
tombruijn committed Jun 24, 2024
1 parent ad3f1c8 commit 52b78f1
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 52 deletions.
8 changes: 7 additions & 1 deletion lib/appsignal/integrations/hanami.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ def self.init
Appsignal.start_logger
Appsignal.start

::Hanami::Action.prepend Appsignal::Integrations::HanamiIntegration if Appsignal.active?
return unless Appsignal.active?

::Hanami::Action.prepend Appsignal::Integrations::HanamiIntegration
end
end
end
Expand All @@ -41,11 +43,15 @@ def call(env)
begin
Appsignal.instrument("process_action.hanami") do
super.tap do |response|
# TODO: update to response_status or remove:
# https://github.com/appsignal/appsignal-ruby/issues/183
transaction.set_metadata("status", response.status.to_s)
end
end
rescue Exception => error # rubocop:disable Lint/RescueException
transaction.set_error(error)
# TODO: update to response_status or remove:
# https://github.com/appsignal/appsignal-ruby/issues/183
transaction.set_metadata("status", "500")
raise error
ensure
Expand Down
120 changes: 72 additions & 48 deletions spec/lib/appsignal/integrations/hanami_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,25 @@
describe "Hanami integration" do
require "appsignal/integrations/hanami"

before do
allow(Appsignal).to receive(:active?).and_return(true)
allow(Appsignal).to receive(:start).and_return(true)
allow(Appsignal).to receive(:start_logger).and_return(true)
end

describe Appsignal::Integrations::HanamiPlugin do
it "starts AppSignal on init" do
expect(Appsignal).to receive(:start)
end

it "starts the logger on init" do
expect(Appsignal).to receive(:start_logger)
Appsignal::Integrations::HanamiPlugin.init
end

it "prepends the integration to Hanami" do
expect(::Hanami::Action).to receive(:prepend)
.with(Appsignal::Integrations::HanamiIntegration)
allow(Appsignal).to receive(:active?).and_return(true)
Appsignal::Integrations::HanamiPlugin.init
expect(::Hanami::Action.included_modules)
.to include(Appsignal::Integrations::HanamiIntegration)
end

context "when not active" do
before { allow(Appsignal).to receive(:active?).and_return(false) }

it "does not prepend the integration" do
Appsignal::Integrations::HanamiPlugin.init
expect(::Hanami::Action).to_not receive(:prepend)
.with(Appsignal::Integrations::HanamiIntegration)
end
Expand All @@ -52,8 +47,6 @@
expect(Appsignal.config.env).to eq("test")
end
end

after { Appsignal::Integrations::HanamiPlugin.init }
end

describe "Hanami Actions" do
Expand All @@ -64,60 +57,91 @@
:method => "GET"
)
end
let(:router_params) { { "foo" => "bar", "baz" => "qux" } }
around { |example| keep_transactions { example.run } }
before :context do
start_agent
end
before do
allow(Appsignal).to receive(:active?).and_return(true)
Appsignal::Integrations::HanamiPlugin.init
end

let(:router_params) { { :foo => "bar", :baz => "qux" } }
def make_request(env, app: HanamiApp::Actions::Books::Index)
action = app.new
action.call(env)
end

describe "#call", :error => false do
describe "#call" do
it "sets params" do
expect_any_instance_of(Appsignal::Transaction).to receive(:params=).with(router_params)
make_request(env)

expect(last_transaction.to_h).to include(
"sample_data" => hash_including(
"params" => router_params
)
)
end

it "sets the action name" do
expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil)
.with("HanamiApp::Actions::Books::Index")
it "sets the namespace and action name" do
make_request(env)

expect(last_transaction.to_h).to include(
"namespace" => Appsignal::Transaction::HTTP_REQUEST,
"action" => "HanamiApp::Actions::Books::Index"
)
end

it "sets the metadata" do
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
.with("status", "200")
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
.with("path", "/books")
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
.with("method", "GET")
make_request(env)

expect(last_transaction.to_h).to include(
"metadata" => hash_including(
"status" => "200",
"path" => "/books",
"method" => "GET"
)
)
end

it "sets the queue start" do
expect_any_instance_of(Appsignal::Transaction)
.to receive(:set_http_or_background_queue_start)
context "with queue start header" do
let(:queue_start_time) { fixed_time * 1_000 }
before do
env["HTTP_X_REQUEST_START"] = "t=#{queue_start_time.to_i}" # in milliseconds
end

it "sets the queue start" do
make_request(env)

expect(last_transaction.ext.queue_start).to eq(queue_start_time)
end
end

context "with error", :error => true do
let(:error) { HanamiApp::ExampleError }
context "with error" do
before do
expect do
make_request(env, :app => HanamiApp::Actions::Books::Error)
end.to raise_error(ExampleException)
end

it "records the exception" do
expect_any_instance_of(Appsignal::Transaction).to receive(:set_error).with(error)
expect(last_transaction.to_h).to include(
"error" => {
"name" => "ExampleException",
"message" => "exception message",
"backtrace" => kind_of(String)
}
)
end

it "sets the status to 500" do
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
.with("status", "500")
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata).twice
expect(last_transaction.to_h).to include(
"metadata" => hash_including(
"status" => "500"
)
)
end
end

after(:error => false) do
Appsignal::Integrations::HanamiPlugin.init

action = HanamiApp::Actions::Books::Index.new
action.call(env)
end

after(:error => true) do
Appsignal::Integrations::HanamiPlugin.init

action = HanamiApp::Actions::Books::Error.new
expect { action.call(env) }.to raise_error(error)
end
end
end
end
Expand Down
4 changes: 1 addition & 3 deletions spec/support/hanami/hanami_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ def handle(_request, response)

class Error < Hanami::Action
def handle(_request, _response)
raise ExampleError
raise ExampleException, "exception message"
end
end
end
end

class ExampleError < StandardError; end
end

0 comments on commit 52b78f1

Please sign in to comment.