Skip to content
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

Improve BaseHTTPClient #875

Merged
merged 1 commit into from
Aug 24, 2019
Merged

Improve BaseHTTPClient #875

merged 1 commit into from
Aug 24, 2019

Conversation

paulcsmith
Copy link
Member

@paulcsmith paulcsmith commented Aug 23, 2019

This can be used for request specs. This will be used for the default auth specs when generating an API app with Auth.

I imagine this could be used for other HTTP Clients as well, but for now the main purpose is for testing Lucky apps

@paulcsmith paulcsmith force-pushed the pcs/add-base-http-client branch from 06c54c1 to c1a3f40 Compare August 23, 2019 23:39
Copy link
Member

@edwardloveall edwardloveall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be really nice to use in tests. I had some code nitpicks, but other than that I think it's great.

# Set headers for requests
#
# ```
# # `content_type` will be normalized to `content-type`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're trying to say:

Suggested change
# # `content_type` will be normalized to `content-type`
# # `content_type` will be normalized to `Content-Type`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I can't find this anywhere. Where does this happen? I see that headers have upcase called on them but I don't understand how _ -> -.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Headers are case insensitive! https://stackoverflow.com/questions/5258977/are-http-headers-case-sensitive So technically it does not capitalize them, but it does change the underscore to a hyphen. That's done by Crystal :D

Should I add a note that headers are case insensitive to the docs?

Copy link
Member Author

@paulcsmith paulcsmith Aug 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However it doesn't appear to change the underscore to a hyphen when setting (it does when getting the header value or the test would fail):

HTTP::Headers{"Foo" => "bar",
 "accept" => "text/csv",
 "accept-encoding" => "gzip, deflate",
 "content-length" => "2",
 "content_type" => "application/json",
 "host" => "localhost:6226",
 "user-agent" => "Crystal"}

I think most implementations of header parsers convert underscore to hyphen (like Crystal's does) but I think we should do it before setting just in case :)

https://github.com/crystal-lang/crystal/blob/5e6a1b672a8b06d2a819210b9905b806ec3d7c71/src/http/headers.cr#L3-L4

request = server.last_request
request.path.should eq "/hello"
request.method.should eq("POST")
request.body.not_nil!.gets_to_end.should eq(NamedTuple.new.to_json)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caught my eye. As far as I can tell we're not sending anything as the post body. Is an empty post body somehow initialized to the json of a NamedTuple?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I see it down in the code with **params. Maybe it would be worth giving that param a type or a default so we didn't have to call not_nil! on it. It'd be cool if we could get rid of gets_to_end also, but I don't think that's as simple. Thoughts also on changing NamedTuple.new.to_json to "{}"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The request is an HTTP::Request from Crystal so I can't easily change that without monkey patching it. Since end users won't be checking the request body I don't think it is worth monkey patching it.

I do like the idea about just using a string! That's a lot clearer

{% end %}
end

private def with_fake_server(path : String, response_body : String)
TestServer.route(path: path, response_body: response_body)
Lucky::Server.temp_config(host: "localhost", port: 6226) do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason behind the 6226 port? Could we name it in a constant? Does it need to be configurable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted a private method. It's the port of the test server

Copy link
Member Author

@paulcsmith paulcsmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reviews! I think I addressed everything

request = server.last_request
request.path.should eq "/hello"
request.method.should eq("POST")
request.body.not_nil!.gets_to_end.should eq(NamedTuple.new.to_json)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The request is an HTTP::Request from Crystal so I can't easily change that without monkey patching it. Since end users won't be checking the request body I don't think it is worth monkey patching it.

I do like the idea about just using a string! That's a lot clearer

{% end %}
end

private def with_fake_server(path : String, response_body : String)
TestServer.route(path: path, response_body: response_body)
Lucky::Server.temp_config(host: "localhost", port: 6226) do
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted a private method. It's the port of the test server

# Set headers for requests
#
# ```
# # `content_type` will be normalized to `content-type`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Headers are case insensitive! https://stackoverflow.com/questions/5258977/are-http-headers-case-sensitive So technically it does not capitalize them, but it does change the underscore to a hyphen. That's done by Crystal :D

Should I add a note that headers are case insensitive to the docs?

# Set headers for requests
#
# ```
# # `content_type` will be normalized to `content-type`
Copy link
Member Author

@paulcsmith paulcsmith Aug 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However it doesn't appear to change the underscore to a hyphen when setting (it does when getting the header value or the test would fail):

HTTP::Headers{"Foo" => "bar",
 "accept" => "text/csv",
 "accept-encoding" => "gzip, deflate",
 "content-length" => "2",
 "content_type" => "application/json",
 "host" => "localhost:6226",
 "user-agent" => "Crystal"}

I think most implementations of header parsers convert underscore to hyphen (like Crystal's does) but I think we should do it before setting just in case :)

https://github.com/crystal-lang/crystal/blob/5e6a1b672a8b06d2a819210b9905b806ec3d7c71/src/http/headers.cr#L3-L4

@client.before_request do |request|
header_values = header_values
.to_h
.transform_keys(&.gsub("_", "_"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean

Suggested change
.transform_keys(&.gsub("_", "_"))
.transform_keys(&.gsub("_", "-"))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah :D And I had to tweak this a bit because there was a compile error

@paulcsmith paulcsmith force-pushed the pcs/add-base-http-client branch from c611181 to 7e6185c Compare August 24, 2019 14:53
@paulcsmith
Copy link
Member Author

Now I think it's good to go 🤣

@paulcsmith paulcsmith merged commit 0356c38 into master Aug 24, 2019
@paulcsmith paulcsmith deleted the pcs/add-base-http-client branch August 24, 2019 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants