1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 module test_api
is test
21 # To avoid test flakyness we test the GithubAPI against a mock of the real one.
22 # For each api request we return a cache file of the real API response body.
24 # Cache files can be automatically created and updated by setting
25 # `update_responses_cache` to `true` then running `nitunit`.
29 # Mock so it returns the response from a file
31 # See `update_responses_cache`.
32 redef fun get_and_parse
(uri
) do
33 print uri
# for debugging
35 var path
= uri
.replace
("https://api.github.com/", "/")
36 assert has_response
(path
)
38 if update_responses_cache
then
39 var file
= response_file
(path
)
40 save_actual_response
(uri
, file
)
43 var response
= response_string
(path
).parse_json
44 if response_is_error
(path
) then
45 var title
= "GithubAPIError"
46 var msg
= response
.as(JsonObject)["message"].as(String)
47 var err
= new GithubError(msg
, title
)
48 err
.json
["requested_uri"] = uri
49 err
.json
["status_code"] = response_code
(path
)
55 var test_responses
: Map[String, String] do
56 var map
= new HashMap[String, String]
57 map
["/user"] = "user_Morriar"
58 map
["/users/Morriar"] = "user_Morriar"
59 map
["/repos/nitlang/nit"] = "repo_nit"
60 map
["/repos/nitlang/nit/labels/ok_will_merge"] = "repo_labels_ok_will_merge"
61 map
["/repos/nitlang/nit/milestones/4"] = "repo_milestones_4"
62 map
["/repos/nitlang/nit/branches"] = "repo_branches_nit"
63 map
["/repos/nitlang/nit/branches/master"] = "repo_branches_master"
64 map
["/repos/nitlang/nit/issues/1000"] = "repo_issues_1000"
65 map
["/repos/nitlang/nit/issues/comments/6020149"] = "repo_issues_comments_6020149"
66 map
["/repos/nitlang/nit/issues/events/199674194"] = "repo_issues_events_199674194"
67 map
["/repos/nitlang/nit/pulls/1000"] = "repo_pulls_1000"
68 map
["/repos/nitlang/nit/commits/64ce1f"] = "repo_commits_64ce1f"
69 map
["/repos/nitlang/nit/comments/8982707"] = "repo_comments_8982707"
70 map
["/repos/nitlang/nit/pulls/comments/21010363"] = "repo_pulls_comment_21010363"
72 map
["/users/not_found/not_found"] = "errors_404"
76 # Does `self` have a mock response for Github `path`?
77 fun has_response
(path
: String): Bool do
78 return test_responses
.has_key
(path
)
81 # Root responses cache directory
82 var responses_dir
: String is lazy
do
83 var path
= "NIT_TESTING_PATH".environ
.dirname
/ "mock"
88 # Returns the response file path for a Github `path`
89 fun response_file
(path
: String): String do
90 assert has_response
(path
)
91 return "{responses_dir / test_responses[path]}.res"
94 # Returns the response body string for a Github `path`
95 fun response_string
(path
: String): String do
96 var file
= response_file
(path
)
97 assert file
.file_exists
98 return file
.to_path
.read_all
101 # Is this response a simulated error?
102 fun response_is_error
(path
: String): Bool do
103 assert has_response
(path
)
104 return test_responses
[path
].has_prefix
("errors_")
107 # Status code of a simulated error
109 # See `response_is_error`.
110 fun response_code
(path
: String): String do
111 assert response_is_error
(path
)
112 return test_responses
[path
].split
("_").last
119 # Change this value to `true` then run nitunit to cache the responses
120 # from the Github API.
122 # Default is `false`.
123 var update_responses_cache
= false
125 # Save the actual Github API response body for `uri` to a `file`
126 private fun save_actual_response
(uri
, file
: String) do
127 assert update_responses_cache
129 var request
= new CurlHTTPRequest(uri
)
130 request
.user_agent
= actual_curl
.user_agent
131 request
.headers
= actual_curl
.header
132 var response
= request
.execute
134 if response
isa CurlResponseSuccess then
135 response
.body_str
.write_to_file
(file
)
136 else if response
isa CurlResponseFailed then
137 response
.error_msg
.write_to_file
(file
)
140 print
"Response to `{uri}` saved at `{file}`"
143 # Actual GithubCurl instance used for caching
144 private var actual_curl
= new GithubCurl(get_github_oauth
, "nitunit")
150 var mock
= new MockGithubCurl("test", "test")
152 fun api
: GithubAPI do
153 var api
= new GithubAPI("test")
158 fun test_deserialize
is test
do
159 var response
= mock
.response_string
("/users/Morriar")
160 var obj
= api
.deserialize
(response
)
162 assert obj
.login
== "Morriar"
165 fun test_sanitize_url
is test
do
167 assert api
.sanitize_uri
("/repos/Nit with spaces/") == "/repos/Nit%20with%20spaces/"
170 fun test_get
is test
do
172 var obj
= api
.get
("/users/Morriar")
173 assert not api
.was_error
174 assert api
.last_error
== null
175 assert obj
isa JsonObject
176 assert obj
["login"] == "Morriar"
179 fun test_get_404
is test
do
181 var res
= api
.get
("/users/not_found/not_found")
184 var err
= api
.last_error
185 assert err
isa GithubError
186 assert err
.name
== "GithubAPIError"
187 assert err
.message
== "Not Found"
190 fun test_load_from_github
is test
do
192 var obj
= api
.load_from_github
("/users/Morriar")
193 assert not api
.was_error
194 assert api
.last_error
== null
196 assert obj
.login
== "Morriar"
199 fun test_load_from_github_404
is test
do
201 var res
= api
.load_from_github
("/users/not_found/not_found")
204 var err
= api
.last_error
205 assert err
isa GithubError
206 assert err
.name
== "GithubAPIError"
207 assert err
.message
== "Not Found"
210 # TODO test more error cases
212 fun test_get_auth_user
is test
do
213 var user
= api
.load_auth_user
215 assert user
.login
== "Morriar"
216 assert user
.avatar_url
== "https://avatars2.githubusercontent.com/u/583144?v=4"
217 assert user
.name
== "Alexandre Terrasa"
218 assert user
.email
== "alexandre@moz-code.org"
219 assert user
.blog
== "moz-code.org"
222 fun test_get_user
is test
do
223 var user
= api
.load_user
("Morriar")
225 assert user
.login
== "Morriar"
226 assert user
.avatar_url
== "https://avatars2.githubusercontent.com/u/583144?v=4"
227 assert user
.name
== "Alexandre Terrasa"
228 assert user
.email
== "alexandre@moz-code.org"
229 assert user
.blog
== "moz-code.org"
232 fun test_get_repo
is test
do
233 var repo
= api
.load_repo
("nitlang/nit")
235 assert repo
.full_name
== "nitlang/nit"
236 assert repo
.name
== "nit"
237 assert repo
.owner
.login
== "nitlang"
238 assert repo
.default_branch
== "master"
241 private var repo
: Repo is lazy
do return api
.load_repo
("nitlang/nit").as(not null)
243 fun test_get_branches
is test
do
244 var branches
= api
.load_repo_branches
(repo
)
245 assert branches
.length
== 2
246 assert branches
.first
.name
== "master"
247 assert branches
.last
.name
== "next"
251 # TODO repo_last_issue
257 fun test_get_branch
is test
do
258 var branch
= api
.load_branch
(repo
, "master")
259 assert branch
isa Branch
260 assert branch
.name
== "master"
263 # TODO branch commits
265 fun test_get_commit
is test
do
266 var commit
= api
.load_commit
(repo
, "64ce1f")
267 assert commit
isa Commit
268 assert commit
.sha
== "64ce1f587209024f5de46d06c70526a569ff537f"
272 fun test_get_issue
is test
do
273 var issue
= api
.load_issue
(repo
, 1000)
274 assert issue
isa Issue
275 assert issue
.number
== 1000
276 assert issue
.title
== "Raise nitc from the dead"
277 assert issue
.user
.as(User).login
== "privat"
278 assert issue
.comments
== 7
279 assert issue
.created_at
== "2014-12-11T02:55:09Z"
280 assert issue
.closed_at
== "2014-12-13T15:38:09Z"
281 assert issue
.closed_by
.as(User).login
== "privat"
282 assert issue
.body
== "Raise dead on `nitc`.\nIt's super effective...\n"
283 assert issue
.is_pull_request
286 # TODO issue comments
289 fun test_get_pull
is test
do
290 var pull
= api
.load_pull
(repo
, 1000)
291 assert pull
isa Issue
292 assert pull
.number
== 1000
293 assert pull
.title
== "Raise nitc from the dead"
294 assert pull
.user
.as(User).login
== "privat"
295 assert pull
.comments
== 7
296 assert pull
.created_at
== "2014-12-11T02:55:09Z"
297 assert pull
.closed_at
== "2014-12-13T15:38:09Z"
298 assert pull
.merged_by
.as(User).login
== "privat"
299 assert pull
.body
== "Raise dead on `nitc`.\nIt's super effective...\n"
302 fun test_get_label
is test
do
303 var labl
= api
.load_label
(repo
, "ok_will_merge")
304 assert labl
isa Label
305 assert labl
.name
== "ok_will_merge"
308 fun test_get_milestone
is test
do
309 var milestone
= api
.load_milestone
(repo
, 4)
310 assert milestone
isa Milestone
311 assert milestone
.title
== "v1.0prealpha"
315 fun test_get_issue_event
is test
do
316 var event
= api
.load_issue_event
(repo
, 199674194)
317 assert event
isa IssueEvent
318 assert event
.actor
.login
== "privat"
319 assert event
.event
== "labeled"
320 assert event
.labl
.as(Label).name
== "need_review"
323 fun test_get_issue_comment
is test
do
324 var comment
= api
.load_issue_comment
(repo
, 6020149)
325 assert comment
isa IssueComment
326 assert comment
.user
.login
== "privat"
327 assert comment
.created_at
.to_s
== "2012-05-30T20:16:54Z"
328 assert comment
.issue_number
== 10
331 fun test_get_comment
is test
do
332 var comment
= api
.load_commit_comment
(repo
, 8982707)
333 assert comment
isa CommitComment
334 assert comment
.user
.login
== "Morriar"
335 assert comment
.body
== "For testing purposes...\n"
336 assert comment
.commit_id
== "7eacb86d1e24b7e72bc9ac869bf7182c0300ceca"
339 fun test_get_review_comments
is test
do
340 var comment
= api
.load_review_comment
(repo
, 21010363)
341 assert comment
isa ReviewComment
342 assert comment
.path
== "src/modelize/modelize_property.nit"
343 assert comment
.original_position
== 26
344 assert comment
.pull_number
== 945