Skip to content

Commit 8e14416

Browse files
committed
Port application client spec from jumpstart
1 parent db641c1 commit 8e14416

File tree

4 files changed

+296
-1
lines changed

4 files changed

+296
-1
lines changed

app/clients/application_client.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def self.inherited(client)
4747
response.const_set(:PARSER, Response::PARSER.dup)
4848
end
4949

50+
def self.base_uri(uri)
51+
const_set(:BASE_URI, uri)
52+
end
53+
5054
# Initializes an API client
5155
#
5256
# To provide authentication credentials, you can supply either `auth` or `token`.

app/clients/plausible_client.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
# --data '{"name":"pageview","url":"http://dummy.site","domain":"dummy.site"}'
1010

1111
class PlausibleClient < ApplicationClient
12-
BASE_URI = "https://plausible.io/api"
12+
base_uri "https://plausible.io/api"
13+
1314
DOMAIN = "joyofrails.com"
1415

1516
def post_event(name:, url:, referrer: nil, props: nil, headers: {})
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
require "rails_helper"
2+
3+
RSpec.describe ApplicationClient do
4+
subject(:client) { described_class.new(token: "test") }
5+
6+
it "authorization header" do
7+
stub_request(:get, "https://example.org/").with(headers: {"Authorization" => "Bearer test"})
8+
assert_nothing_raised do
9+
client.send(:get, "/")
10+
end
11+
end
12+
13+
it "basic auth" do
14+
stub_request(:get, "https://example.org/")
15+
client = ApplicationClient.new(basic_auth: {username: "user", password: "pass"})
16+
client.send(:get, "/")
17+
assert_requested(:get, "https://example.org/", headers: {"Authorization" => "Basic #{Base64.strict_encode64("user:pass")}"})
18+
end
19+
20+
it "get" do
21+
stub_request(:get, "https://example.org/test")
22+
assert_nothing_raised do
23+
client.send(:get, "/test")
24+
end
25+
end
26+
27+
it "get with query params" do
28+
stub_request(:get, "https://example.org/test").with(query: {"foo" => "bar"})
29+
assert_nothing_raised do
30+
client.send(:get, "/test", query: {foo: "bar"})
31+
end
32+
end
33+
34+
it "get with query params as a string" do
35+
stub_request(:get, "https://example.org/test").with(query: {"foo" => "bar"})
36+
assert_nothing_raised do
37+
client.send(:get, "/test", query: "foo=bar")
38+
end
39+
end
40+
41+
it "override BASE_URI by passing in full url" do
42+
stub_request(:get, "https://other.org/test")
43+
assert_nothing_raised do
44+
client.send(:get, "https://other.org/test")
45+
end
46+
end
47+
48+
it "post" do
49+
stub_request(:post, "https://example.org/test").with(body: {"foo" => {"bar" => "baz"}}.to_json)
50+
assert_nothing_raised do
51+
client.send(:post, "/test", body: {foo: {bar: "baz"}})
52+
end
53+
end
54+
55+
it "post with string body" do
56+
stub_request(:post, "https://example.org/test").with(body: "foo")
57+
assert_nothing_raised do
58+
client.send(:post, "/test", body: "foo")
59+
end
60+
end
61+
62+
it "post with custom content-type" do
63+
headers = {"Content-Type" => "application/x-www-form-urlencoded"}
64+
stub_request(:post, "https://example.org/test").with(body: {"foo" => "bar"}.to_json, headers: headers)
65+
assert_nothing_raised do
66+
client.send(:post, "/test", body: {foo: "bar"}, headers: headers)
67+
end
68+
end
69+
70+
it "multipart form data with file_fixture" do
71+
file = file_fixture("avatar.jpg")
72+
form_data = {
73+
"field1" => "value1",
74+
"file" => File.open(file)
75+
}
76+
77+
stub_request(:post, "https://example.org/upload").to_return(status: 200)
78+
assert_nothing_raised do
79+
client.send(:post, "/upload", form_data: form_data)
80+
end
81+
end
82+
83+
it "patch" do
84+
stub_request(:patch, "https://example.org/test").with(body: {"foo" => "bar"}.to_json)
85+
assert_nothing_raised do
86+
client.send(:patch, "/test", body: {foo: "bar"})
87+
end
88+
end
89+
90+
it "multipart form data with file_fixture and patch" do
91+
file = file_fixture("avatar.jpg")
92+
93+
form_data = {
94+
"field1" => "value1",
95+
"file" => File.open(file)
96+
}
97+
98+
stub_request(:patch, "https://example.org/update").to_return(status: 200)
99+
100+
assert_nothing_raised do
101+
client.send(:patch, "/update", form_data: form_data)
102+
end
103+
end
104+
105+
it "put" do
106+
stub_request(:put, "https://example.org/test").with(body: {"foo" => "bar"}.to_json)
107+
assert_nothing_raised do
108+
client.send(:put, "/test", body: {foo: "bar"})
109+
end
110+
end
111+
112+
it "multipart form data with file_fixture and put" do
113+
file = file_fixture("avatar.jpg")
114+
115+
form_data = {
116+
"field1" => "value1",
117+
"file" => File.open(file)
118+
}
119+
120+
stub_request(:put, "https://example.org/update").to_return(status: 200)
121+
122+
assert_nothing_raised do
123+
client.send(:put, "/update", form_data: form_data)
124+
end
125+
end
126+
127+
it "delete" do
128+
stub_request(:delete, "https://example.org/test")
129+
assert_nothing_raised do
130+
client.send(:delete, "/test")
131+
end
132+
end
133+
134+
it "response object parses json" do
135+
stub_request(:get, "https://example.org/test").to_return(body: {"foo" => "bar"}.to_json, headers: {content_type: "application/json"})
136+
result = client.send(:get, "/test")
137+
assert_equal "200", result.code
138+
assert_equal "application/json", result.content_type
139+
assert_equal "bar", result.foo
140+
end
141+
142+
it "response object parses xml" do
143+
stub_request(:get, "https://example.org/test").to_return(body: {"foo" => "bar"}.to_xml, headers: {content_type: "application/xml"})
144+
result = client.send(:get, "/test")
145+
assert_equal "200", result.code
146+
assert_equal "application/xml", result.content_type
147+
assert_equal "bar", result.xpath("//foo").children.first.to_s
148+
end
149+
150+
it "unauthorized" do
151+
stub_request(:get, "https://example.org/test").to_return(status: 401)
152+
assert_raises ApplicationClient::Unauthorized do
153+
client.send(:get, "/test")
154+
end
155+
end
156+
157+
it "forbidden" do
158+
stub_request(:get, "https://example.org/test").to_return(status: 403)
159+
assert_raises ApplicationClient::Forbidden do
160+
client.send(:get, "/test")
161+
end
162+
end
163+
164+
it "not found" do
165+
stub_request(:get, "https://example.org/test").to_return(status: 404)
166+
assert_raises ApplicationClient::NotFound do
167+
client.send(:get, "/test")
168+
end
169+
end
170+
171+
it "rate limit" do
172+
stub_request(:get, "https://example.org/test").to_return(status: 429)
173+
assert_raises ApplicationClient::RateLimit do
174+
client.send(:get, "/test")
175+
end
176+
end
177+
178+
it "internal error" do
179+
stub_request(:get, "https://example.org/test").to_return(status: 500)
180+
assert_raises ApplicationClient::InternalError do
181+
client.send(:get, "/test")
182+
end
183+
end
184+
185+
it "other error" do
186+
stub_request(:get, "https://example.org/test").to_return(status: 418)
187+
assert_raises ApplicationClient::Error do
188+
client.send(:get, "/test")
189+
end
190+
end
191+
192+
it "parses link header" do
193+
stub_request(:get, "https://example.org/pages").to_return(headers: {"Link" => "<https://example.org/pages?page=2>; rel=\"next\", <https://example.org/pages?page=1>; rel=\"prev\""})
194+
response = client.send(:get, "/pages")
195+
assert_equal "https://example.org/pages?page=2", response.link_header[:next]
196+
assert_equal "https://example.org/pages?page=1", response.link_header[:prev]
197+
end
198+
199+
it "handles missing link header" do
200+
stub_request(:get, "https://example.org/pages")
201+
response = client.send(:get, "/pages")
202+
assert_empty(response.link_header)
203+
end
204+
205+
describe "with basic auth" do
206+
subject(:client) { basic_auth_class.new }
207+
208+
let(:basic_auth_class) do
209+
Class.new(ApplicationClient) do
210+
base_uri "https://example.org"
211+
212+
def basic_auth
213+
{username: "user", password: "pass"}
214+
end
215+
end
216+
end
217+
218+
it "uses basic auth" do
219+
stub_request(:get, "https://example.org/")
220+
client.send :get, "/"
221+
assert_requested(:get, "https://example.org/", headers: {"Authorization" => "Basic #{Base64.strict_encode64("user:pass")}"})
222+
end
223+
end
224+
225+
describe "with pagination" do
226+
let(:paginated_client_class) do
227+
Class.new(ApplicationClient) do
228+
base_uri "https://test.example.org"
229+
230+
def root
231+
get "/"
232+
end
233+
234+
def content_type
235+
"application/xml"
236+
end
237+
238+
def all_pages
239+
with_pagination("/pages", query: {per_page: 100}) do |response|
240+
response.link_header[:next]
241+
end
242+
end
243+
244+
def all_projects
245+
with_pagination("/projects", query: {per_page: 100}) do |response|
246+
next_page = response.parsed_body.pagination.next_page
247+
{page: next_page} if next_page
248+
end
249+
end
250+
end
251+
end
252+
253+
it "with_pagination and url" do
254+
stub_request(:get, "https://test.example.org/pages?per_page=100").to_return(headers: {"Link" => "<https://test.example.org/pages?page=2>; rel=\"next\""})
255+
stub_request(:get, "https://test.example.org/pages?per_page=100&page=2")
256+
assert_nothing_raised do
257+
paginated_client_class.new(token: "test").all_pages
258+
end
259+
end
260+
261+
it "with_pagination with query hash" do
262+
stub_request(:get, "https://test.example.org/projects?per_page=100").to_return(body: {pagination: {next_page: 2}}.to_json, headers: {content_type: "application/json"})
263+
stub_request(:get, "https://test.example.org/projects?per_page=100&page=2").to_return(body: {pagination: {prev_page: 1}}.to_json, headers: {content_type: "application/json"})
264+
assert_nothing_raised do
265+
paginated_client_class.new(token: "test").all_projects
266+
end
267+
end
268+
269+
it "get" do
270+
stub_request(:get, "https://test.example.org/")
271+
assert_nothing_raised do
272+
paginated_client_class.new(token: "test").root
273+
end
274+
end
275+
276+
it "content type" do
277+
stub_request(:get, "https://test.example.org/").with(headers: {"Accept" => "application/xml"})
278+
assert_nothing_raised do
279+
paginated_client_class.new(token: "test").root
280+
end
281+
end
282+
283+
it "other error" do
284+
stub_request(:get, "https://test.example.org/").to_return(status: 418)
285+
assert_raises paginated_client_class::Error do
286+
paginated_client_class.new(token: "test").root
287+
end
288+
end
289+
end
290+
end

spec/fixtures/files/avatar.jpg

4.1 KB
Loading

0 commit comments

Comments
 (0)