refactor
[m6w6/seekat] / tests / api.php
1 <?php
2
3 use seekat\API;
4 use React\Promise\PromiseInterface;
5 use seekat\API\Links\ {
6 function first, function last, function next, function prev
7 };
8
9 describe("API", function() {
10
11 describe("Interface", function() {
12 it("should return API on property access", function() {
13 expect($this->api->users)->to->be->instanceof(API::class);
14 });
15
16 it("should return a clone on property access", function() {
17 expect($this->api->users)->to->not->equal($this->api);
18 });
19
20 it("should return PromiseInterface on function call", function() {
21 expect($this->api->users->m6w6())->to->be->instanceof(PromiseInterface::class);
22 });
23 });
24
25 describe("Requests", function() {
26
27 it("should successfully request /users/m6w6", function() {
28 $this->api->users->m6w6()->then(function($json) use(&$m6w6) {
29 $m6w6 = $json;
30 }, function($error) use(&$errors) {
31 $errors[] = (string) $error;
32 });
33
34 $this->api->send();
35
36 expect($errors)->to->be->empty;
37 expect($m6w6->login)->to->loosely->equal("m6w6");
38 });
39
40 it("should export an array of data, url, type, links and headers", function() {
41 $this->api->users->m6w6()->then(function($json) use(&$m6w6) {
42 $m6w6 = $json;
43 }, function($error) use(&$errors) {
44 $errors[] = (string) $error;
45 });
46
47 $this->api->send();
48
49 expect($errors)->to->be->empty();
50 expect($m6w6->export())->to->be->an("array")->and->contain->keys([
51 "data", "url", "type", "links", "headers"
52 ]);
53 });
54
55 it("should return the count of followers when accessing /users/m6w6->followers", function() {
56 $this->api->users->m6w6()->then(function($m6w6) use(&$followers) {
57 $followers = $m6w6->followers;
58 }, function($error) use(&$errors) {
59 $errors[] = (string) $error;
60 });
61
62 $this->api->send();
63
64 expect($errors)->to->be->empty();
65 expect($followers->export()["data"])->to->be->an("integer");
66 });
67
68 it("should fetch followers_url when accessing /users/m6w6->followers_url", function() {
69 $this->api->users->m6w6()->then(function($m6w6) use(&$followers, &$errors) {
70 $m6w6->followers_url()->then(function($json) use(&$followers) {
71 $followers = $json;
72 }, function($error) use(&$errors) {
73 $errors[] = (string) $error;
74 });
75 }, function($error) use(&$errors) {
76 $errors[] = (string) $error;
77 });
78
79 $this->api->send();
80
81 expect($errors)->to->be->empty;
82 expect($followers->export()["data"])->to->be->an("array");
83 expect(count($followers))->to->be->above(0);
84 });
85
86 it("should provide access to array indices", function() {
87 $this->api->users->m6w6()->then(function($m6w6) use(&$followers, &$errors) {
88 $m6w6->followers_url()->then(function($json) use(&$followers) {
89 $followers = $json;
90 }, function($error) use(&$errors) {
91 $errors[] = (string) $error;
92 });
93 }, function($error) use(&$errors) {
94 $errors[] = (string) $error;
95 });
96
97 $this->api->send();
98
99 expect($errors)->to->be->empty;
100 expect($followers->{0})->to->be->an("object");
101 expect($followers->export()["data"][0])->to->be->an("object");
102 });
103
104 it("should handle a few requests in parallel", function() {
105 $this->api->users->m6w6()->then(function($m6w6) use(&$count, &$errors) {
106 foreach ($m6w6 as $key => $val) {
107 switch ($key) {
108 case "html_url":
109 case "avatar_url":
110 break;
111 default:
112 if (substr($key, -4) === "_url") {
113 $val->get()->then(function() use(&$count) {
114 ++$count;
115 }, function($error) use(&$errors) {
116 $errors[] = (string) $error;
117 });
118 }
119 }
120 }
121 }, function($error) use(&$errors) {
122 $errors[] = (string) $error;
123 });
124
125 $this->api->send();
126
127 expect($errors)->to->be->empty;
128 expect($count)->to->be->above(2);
129 });
130
131 });
132
133 describe("Cache", function() {
134 it("should cache successive calls", function() {
135 $cache = new API\Call\Cache\Service\Hollow();
136 $this->api->users->m6w6(null, null, $cache)->then(function($json) use(&$m6w6) {
137 $m6w6 = $json;
138 }, function($error) use(&$errors) {
139 $errors[] = (string) $error;
140 });
141
142 $this->api->send();
143
144 $data = $cache->getStorage();
145 $this->api->users->m6w6(null, null, $cache)->then(function($json) use(&$m6w6_) {
146 $m6w6_ = $json;
147 }, function($error) use(&$errors) {
148 $errors[] = (string) $error;
149 });
150
151 $this->api->send();
152
153 expect($errors)->to->be->empty;
154 expect($m6w6->login)->to->loosely->equal("m6w6");
155 expect($m6w6_->login)->to->loosely->equal("m6w6");
156 expect($data)->to->equal($cache->getStorage());
157 expect(count($cache->getStorage()))->to->equal(1);
158 });
159 xit("should refresh stale cache entries");
160 });
161
162 describe("Generators", function() {
163 it("should iterate over a generator of promises", function() {
164 ($this->api)(function($api) use(&$gists_count, &$files_count) {
165 $gists = yield $api->users->m6w6->gists();
166 $gists_count = count($gists);
167 foreach ($gists as $gist) {
168 $files_count += count($gist->files);
169 }
170 });
171 expect($gists_count)->to->be->above(0);
172 expect($files_count)->to->be->at->least($gists_count);
173 });
174 it("should iterate over a generator of promises with links", function() {
175 ($this->api)(function($api) use(&$repos, &$first, &$next, &$last, &$prev) {
176 $repos = yield $api->users->m6w6->repos(["per_page" => 1]);
177 $last = yield last($repos);
178 $prev = yield prev($last);
179 $next = yield next($prev);
180 $first = yield first($prev);
181 return -123;
182 })->done(function($value) use(&$result) {
183 $result = $value;
184 });
185
186 expect($result)->to->equal(-123);
187 expect($repos->export()["data"])->to->loosely->equal($first->export()["data"]);
188 expect($last->export()["data"])->to->loosely->equal($next->export()["data"]);
189 });
190 });
191
192 describe("Errors", function() {
193 it("should handle cancellation gracefully", function() {
194 $this->api->users->m6w6()->then(function($value) use(&$result) {
195 $result = $value;
196 }, function($error) use(&$message) {
197 $message = \seekat\Exception\message($error);
198 })->cancel();
199 expect($result)->to->be->empty();
200 expect($message)->to->equal("Cancelled");
201 });
202
203 it("should handle request errors gracefully", function() {
204 $this->api->generate->a404()->then(function($value) use(&$result) {
205 $result = $value;
206 }, function($error) use(&$message) {
207 $message = \seekat\Exception\message($error);
208 });
209 $this->api->send();
210 expect($result)->to->be->empty();
211 expect($message)->to->equal("Not Found");
212 });
213 });
214 });