]> Dogcows Code - chaz/graphql-client/blob - t/http.t
rename class attribute to transport_class
[chaz/graphql-client] / t / http.t
1 #!/usr/bin/env perl
2
3 use warnings;
4 use strict;
5
6 use FindBin '$Bin';
7 use lib "$Bin/lib";
8
9 use Test::Deep;
10 use Test::Exception;
11 use Test::More;
12
13 use Future;
14 use GraphQL::Client::http;
15
16 HTTP::AnyUA->register_backend(MockUA => '+MockUA');
17
18 my $URL = 'http://localhost:4000/graphql';
19
20 subtest 'attributes' => sub {
21 my $http = GraphQL::Client::http->new;
22
23 is($http->method, 'POST', 'default method is POST');
24 is($http->url, undef, 'default url is undefined');
25
26 $http = GraphQL::Client::http->new(method => 'HEAD', url => $URL);
27
28 is($http->method, 'HEAD', 'method getter returns correctly');
29 is($http->url, $URL, 'url getter returns correctly');
30 };
31
32 subtest 'bad arguments to execute' => sub {
33 my $http = GraphQL::Client::http->new(ua => 'MockUA');
34 my $mock = $http->any_ua->backend;
35
36 throws_ok {
37 $http->execute('blah');
38 } qr/^Usage:/, 'first argument must be a hashref';
39
40 throws_ok {
41 $http->execute({});
42 } qr/^Request must have a query/, 'request must have a query';
43
44 throws_ok {
45 $http->execute({query => '{hello}'});
46 } qr/^URL must be provided/, 'request must have a URL';
47 };
48
49 subtest 'POST request' => sub {
50 my $http = GraphQL::Client::http->new(ua => 'MockUA', url => $URL);
51 my $mock = $http->any_ua->backend;
52
53 my $resp = $http->execute({
54 query => '{hello}',
55 });
56 my $req = ($mock->requests)[-1];
57
58 is($req->[0], 'POST', 'method is POST');
59 is($req->[2]{content}, '{"query":"{hello}"}', 'encoded body as JSON');
60 is($req->[2]{headers}{'content-type'}, 'application/json', 'set content-type to json');
61 };
62
63 subtest 'GET request' => sub {
64 my $http = GraphQL::Client::http->new(ua => 'MockUA', url => $URL);
65 my $mock = $http->any_ua->backend;
66
67 $http->execute({
68 query => '{hello}',
69 }, {
70 method => 'GET',
71 });
72 my $req = ($mock->requests)[-1];
73
74 is($req->[0], 'GET', 'method is GET');
75 is($req->[1], "$URL?query=%7Bhello%7D", 'encoded query in params');
76 is($req->[2]{content}, undef, 'no content');
77
78 $http->execute({
79 query => '{hello}',
80 }, {
81 method => 'GET',
82 url => "$URL?foo=bar",
83 });
84 $req = ($mock->requests)[-1];
85
86 is($req->[1], "$URL?foo=bar&query=%7Bhello%7D", 'encoded query in params with existing param');
87 };
88
89 subtest 'plain response' => sub {
90 my $http = GraphQL::Client::http->new(ua => 'MockUA', url => $URL);
91 my $mock = $http->any_ua->backend;
92
93 $mock->response({
94 content => '{"data":{"foo":"bar"}}',
95 reason => 'OK',
96 status => 200,
97 success => 1,
98 });
99 my $r = $http->execute({query => '{hello}'});
100 my $expected = {
101 response => {
102 data => {foo => 'bar'},
103 },
104 details => {
105 http_response => $mock->response,
106 },
107 };
108 is_deeply($r, $expected, 'success response') or diag explain $r;
109
110 $mock->response({
111 content => '{"data":{"foo":"bar"},"errors":[{"message":"uh oh"}]}',
112 reason => 'OK',
113 status => 200,
114 success => 1,
115 });
116 $r = $http->execute({query => '{hello}'});
117 $expected = {
118 response => {
119 data => {foo => 'bar'},
120 errors => [{message => 'uh oh'}],
121 },
122 details => {
123 http_response => $mock->response,
124 },
125 };
126 is_deeply($r, $expected, 'response with graphql errors') or diag explain $r;
127
128 $mock->response({
129 content => 'The agent failed',
130 reason => 'Internal Exception',
131 status => 599,
132 success => '',
133 });
134 my $resp = $http->execute({query => '{hello}'});
135 $expected = {
136 error => 'HTTP transport returned 599 (Internal Exception): The agent failed',
137 response => undef,
138 details => {
139 http_response => $mock->response,
140 },
141 };
142 is_deeply($resp, $expected, 'response with http error') or diag explain $resp;
143
144 $mock->response({
145 content => 'not json',
146 reason => 'OK',
147 status => 200,
148 success => 1,
149 });
150 $r = $http->execute({query => '{hello}'});
151 $expected = {
152 error => re('^HTTP transport failed to decode response:'),
153 response => undef,
154 details => {
155 http_response => $mock->response,
156 },
157 };
158 cmp_deeply($r, $expected, 'response with invalid response') or diag explain $r;
159 };
160
161 subtest 'future response' => sub {
162 my $http = GraphQL::Client::http->new(ua => 'MockUA', url => $URL);
163 my $mock = $http->any_ua->backend;
164
165 $mock->response(Future->done({
166 content => '{"data":{"foo":"bar"}}',
167 reason => 'OK',
168 status => 200,
169 success => 1,
170 }));
171 my $f = $http->execute({query => '{hello}'});
172 my $expected = {
173 response => {
174 data => {foo => 'bar'},
175 },
176 details => {
177 http_response => $mock->response->get,
178 },
179 };
180 is_deeply($f->get, $expected, 'success response') or diag explain $f->get;
181
182 $mock->response(Future->done({
183 content => '{"data":{"foo":"bar"},"errors":[{"message":"uh oh"}]}',
184 reason => 'OK',
185 status => 200,
186 success => 1,
187 }));
188 $f = $http->execute({query => '{hello}'});
189 $expected = {
190 response => {
191 data => {foo => 'bar'},
192 errors => [{message => 'uh oh'}],
193 },
194 details => {
195 http_response => $mock->response->get,
196 },
197 };
198 is_deeply($f->get, $expected, 'response with graphql errors') or diag explain $f->get;
199
200 $mock->response(Future->fail({
201 content => 'The agent failed',
202 reason => 'Internal Exception',
203 status => 599,
204 success => '',
205 }));
206 $expected = {
207 error => 'HTTP transport returned 599 (Internal Exception): The agent failed',
208 response => undef,
209 details => {
210 http_response => ($mock->response->failure)[0],
211 },
212 };
213 $f = $http->execute({query => '{hello}'});
214 is_deeply($f->get, $expected, 'response with http error') or diag explain $f->get;
215 };
216
217 done_testing;
This page took 0.048542 seconds and 4 git commands to generate.