Skip to content

Display registered stubs with NetConnectNotAllowedError exception #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 119 additions & 5 deletions spec/webmock_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe WebMock do
it "stubs and calls block for response" do
WebMock.wrap do
WebMock.stub(:post, "www.example.com").with(body: "Hello!").to_return do |request|
headers = HTTP::Headers.new.merge!({ "Content-length" => "6" })
headers = HTTP::Headers.new.merge!({"Content-length" => "6"})
HTTP::Client::Response.new(418, body: request.body.to_s.reverse, headers: headers)
end

Expand Down Expand Up @@ -329,6 +329,120 @@ describe WebMock do
end
end

it "contains registered stubs on failure" do
WebMock.wrap do
WebMock.stub(:get, "https://test.example.com")
begin
HTTP::Client.get("https://www.example.com/")
rescue ex : WebMock::NetConnectNotAllowedError
ex.message.not_nil!.strip.should eq(
<<-MSG
Real HTTP connections are disabled. Unregistered request: GET https://www.example.com/ with headers {"Connection" => "close", "Host" => "www.example.com"}

You can stub this request with the following snippet:

WebMock.stub(:get, "https://www.example.com/").
to_return(body: "")

Registered request stubs:

stub(:get, "https://test.example.com")
MSG
)
end
end
end

it "contains registered stubs on failure (with headers)" do
WebMock.wrap do
WebMock.stub(:post, "https://test.example.com").with(headers: {"Content-Type" => "application/json"})
begin
HTTP::Client.get("https://www.example.com/")
rescue ex : WebMock::NetConnectNotAllowedError
ex.message.not_nil!.strip.should eq(
<<-MSG
Real HTTP connections are disabled. Unregistered request: GET https://www.example.com/ with headers {"Connection" => "close", "Host" => "www.example.com"}

You can stub this request with the following snippet:

WebMock.stub(:get, "https://www.example.com/").
to_return(body: "")

Registered request stubs:

stub(:post, "https://test.example.com").
with(
headers: {
"Content-Type" => "application/json"
}
)
)
MSG
)
end
end
end

it "contains registered stubs on failure (with body)" do
WebMock.wrap do
WebMock.stub(:post, "https://test.example.com").with(body: "line1\nline2")
begin
HTTP::Client.get("https://www.example.com/")
rescue ex : WebMock::NetConnectNotAllowedError
ex.message.not_nil!.strip.should eq(
<<-MSG
Real HTTP connections are disabled. Unregistered request: GET https://www.example.com/ with headers {"Connection" => "close", "Host" => "www.example.com"}

You can stub this request with the following snippet:

WebMock.stub(:get, "https://www.example.com/").
to_return(body: "")

Registered request stubs:

stub(:post, "https://test.example.com").
with(
body: "line1\\nline2"
)
)
MSG
)
end
end
end

it "contains registered stubs on failure (with headers and body)" do
WebMock.wrap do
WebMock.stub(:post, "https://test.example.com").with(body: "line1\nline2", headers: {"Content-Type" => "application/json", "Accept" => "*/*"})
begin
HTTP::Client.get("https://www.example.com/")
rescue ex : WebMock::NetConnectNotAllowedError
ex.message.not_nil!.strip.should eq(
<<-MSG
Real HTTP connections are disabled. Unregistered request: GET https://www.example.com/ with headers {"Connection" => "close", "Host" => "www.example.com"}

You can stub this request with the following snippet:

WebMock.stub(:get, "https://www.example.com/").
to_return(body: "")

Registered request stubs:

stub(:post, "https://test.example.com").
with(
body: "line1\\nline2",
headers: {
"Content-Type" => "application/json",
"Accept" => "*/*"
}
)
)
MSG
)
end
end
end

it "works with request callbacks" do
WebMock.wrap do
WebMock.stub(:get, "http://www.example.com").with(query: {"foo" => "bar"})
Expand Down Expand Up @@ -388,7 +502,7 @@ describe WebMock do
end

# Commented so that specs run fast, but uncomment to try it (it works)
#it "calls callback after live request" do
# it "calls callback after live request" do
# WebMock.wrap do
# WebMock.callbacks.add do
# after_live_request do |request, response|
Expand All @@ -398,15 +512,15 @@ describe WebMock do
# WebMock.allow_net_connect = true
# HTTP::Client.get("http://www.example.net")
# end
#end
# end

#it "doesn't error if callback is not set" do
# it "doesn't error if callback is not set" do
# WebMock.wrap do
# WebMock.allow_net_connect = true
# client = HTTP::Client.get("http://www.example.net")
# client.status_code.should eq 200
# end
#end
# end

# it "allows net connect" do
# WebMock.wrap do
Expand Down
4 changes: 4 additions & 0 deletions src/webmock.cr
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ module WebMock
@@registry.find_stub(request)
end

def stubs
@@registry.stubs
end

def callbacks
@@callbacks
end
Expand Down
9 changes: 9 additions & 0 deletions src/webmock/net_connect_not_allowed_error.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class WebMock::NetConnectNotAllowedError < Exception
io << "\n\n"
stubbing_instructions(request, io)
io << "\n\n"
registered_requests(io)
end
end

Expand Down Expand Up @@ -61,6 +62,14 @@ class WebMock::NetConnectNotAllowedError < Exception
io << %[ to_return(body: "")]
end

private def registered_requests(io)
return if WebMock.stubs.empty?
io << "Registered request stubs:"
io << "\n\n"
WebMock.stubs.each { |stub| io << StubSnippet.new(stub).to_s }
io << "\n\n"
end

private def request_uri_to_s(request, io)
io << request.scheme
io << "://"
Expand Down
2 changes: 2 additions & 0 deletions src/webmock/stub.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class WebMock::Stub
getter :method, :uri, :expected_headers, :expected_body, :expected_query

@method : String
@uri : URI
@expected_headers : HTTP::Headers?
Expand Down
2 changes: 2 additions & 0 deletions src/webmock/stub_registry.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
struct WebMock::StubRegistry
getter :stubs

def initialize
@stubs = [] of Stub
end
Expand Down
35 changes: 35 additions & 0 deletions src/webmock/stub_snippet.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
struct WebMock::StubSnippet
def initialize(stub : Stub)
@stub = stub
end

def to_s
String.build do |io|
io << "stub(:#{@stub.method.downcase}, \"#{@stub.uri}\""
if body || headers
io << ").\n with(\n"
if body
io << " body: \"#{body.to_s.gsub("\n", "\\n")}\""
io << ",\n" if headers
end
if headers
io << " headers: {\n "
io << headers.not_nil!.map { |key, values| "\"#{key}\" => \"#{values.join(", ")}\"" }.join(",\n ")
io << "\n }\n"
else
io << "\n"
end
io << " )\n"
end
io << ")\n"
end
end

private def body
@stub.expected_body
end

private def headers
@stub.expected_headers
end
end