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 send
(method
, path
, headers
, body
) do
33 print path
# for debugging
35 assert has_response
(path
)
37 if update_responses_cache
then
38 var file
= response_file
(path
)
39 save_actual_response
(path
, file
)
42 var response
= response_string
(path
)
43 if response_is_error
(path
) then
44 last_error
= new GithubAPIError(
45 response
.parse_json
.as(JsonObject)["message"].as(String),
46 response_code
(path
).to_i
,
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?page=1&per_page=3"] = "repo_labels_nit"
61 map
["/repos/nitlang/nit/labels/ok_will_merge"] = "repo_labels_ok_will_merge"
62 map
["/repos/nitlang/nit/milestones?page=1&per_page=3"] = "repo_milestones_nit"
63 map
["/repos/nitlang/nit/milestones/4"] = "repo_milestones_4"
64 map
["/repos/nitlang/nit/branches?page=1&per_page=2"] = "repo_branches_nit"
65 map
["/repos/nitlang/nit/branches/master"] = "repo_branches_master"
66 map
["/repos/nitlang/nit/issues?page=1&per_page=3"] = "repo_issues_nit"
67 map
["/repos/nitlang/nit/issues/1000"] = "repo_issues_1000"
68 map
["/repos/nitlang/nit/issues/1000/comments?page=1&per_page=3"] = "repo_issues_comments_nit"
69 map
["/repos/nitlang/nit/issues/comments/6020149"] = "repo_issues_comments_6020149"
70 map
["/repos/nitlang/nit/issues/1000/events?page=1&per_page=3"] = "repo_issues_events_nit"
71 map
["/repos/nitlang/nit/issues/events/199674194"] = "repo_issues_events_199674194"
72 map
["/repos/nitlang/nit/pulls?page=1&per_page=3"] = "repo_pulls_nit"
73 map
["/repos/nitlang/nit/pulls/1000"] = "repo_pulls_1000"
74 map
["/repos/nitlang/nit/pulls/945/comments?page=1&per_page=3"] = "repo_pulls_945_comments"
75 map
["/repos/nitlang/nit/pulls/comments/21010363"] = "repo_pulls_comment_21010363"
76 map
["/repos/nitlang/nit/commits/64ce1f"] = "repo_commits_64ce1f"
77 map
["/repos/nitlang/nit/commits/4e3c688d/status"] = "repo_commits_4e3c68_status"
78 map
["/repos/nitlang/nit/comments/8982707"] = "repo_comments_8982707"
79 map
["/search/issues?q=foo repo:nitlang/nit&page=1&per_page=3"] = "repo_search_issues_nit"
80 map
["/repos/nitlang/nit/stats/contributors"] = "repo_nit_contributors"
82 map
["/users/not_found/not_found"] = "errors_404"
86 # Does `self` have a mock response for Github `path`?
87 fun has_response
(path
: String): Bool do
88 return test_responses
.has_key
(path
)
91 # Root responses cache directory
92 var responses_dir
: String is lazy
do
93 var path
= "NIT_TESTING_PATH".environ
.dirname
/ "mock"
98 # Returns the response file path for a Github `path`
99 fun response_file
(path
: String): String do
100 assert has_response
(path
)
101 return "{responses_dir / test_responses[path]}.res"
104 # Returns the response body string for a Github `path`
105 fun response_string
(path
: String): String do
106 var file
= response_file
(path
)
107 assert file
.file_exists
108 return file
.to_path
.read_all
111 # Is this response a simulated error?
112 fun response_is_error
(path
: String): Bool do
113 assert has_response
(path
)
114 return test_responses
[path
].has_prefix
("errors_")
117 # Status code of a simulated error
119 # See `response_is_error`.
120 fun response_code
(path
: String): String do
121 assert response_is_error
(path
)
122 return test_responses
[path
].split
("_").last
129 # Change this value to `true` then run nitunit to cache the responses
130 # from the Github API.
132 # Default is `false`.
133 var update_responses_cache
= false
135 # Save the actual Github API response body for `uri` to a `file`
136 private fun save_actual_response
(uri
, file
: String) do
137 assert update_responses_cache
139 var request
= new CurlHTTPRequest("{api_url}{sanitize_uri(uri)}")
140 request
.user_agent
= actual_api
.user_agent
141 request
.headers
= actual_api
.new_headers
142 var response
= request
.execute
144 if response
isa CurlResponseSuccess then
145 response
.body_str
.write_to_file
(file
)
146 else if response
isa CurlResponseFailed then
147 response
.error_msg
.write_to_file
(file
)
150 print
"Response to `{uri}` saved at `{file}`"
153 # Actual GithubCurl instance used for caching
154 private var actual_api
= new GithubAPI(get_github_oauth
, "nitunit")
160 fun api
: MockGithubAPI do return new MockGithubAPI("test", "test")
162 fun test_deserialize
is test
do
163 var response
= api
.response_string
("/users/Morriar")
164 var obj
= api
.deserialize
(response
)
166 assert obj
.login
== "Morriar"
169 fun test_sanitize_url
is test
do
171 assert api
.sanitize_uri
("/repos/Nit with spaces/") == "/repos/Nit%20with%20spaces/"
174 fun test_get
is test
do
176 var obj
= api
.get
("/users/Morriar")
177 assert not api
.was_error
178 assert api
.last_error
== null
180 assert obj
.login
== "Morriar"
183 fun test_get_404
is test
do
185 var res
= api
.get
("/users/not_found/not_found")
188 var err
= api
.last_error
189 assert err
isa GithubAPIError
190 assert err
.status_code
== 404
191 assert err
.message
== "Not Found"
194 # TODO test more error cases
196 fun test_get_auth_user
is test
do
197 var user
= api
.get_auth_user
199 assert user
.login
== "Morriar"
200 assert user
.avatar_url
== "https://avatars2.githubusercontent.com/u/583144?v=4"
201 assert user
.name
== "Alexandre Terrasa"
202 assert user
.email
== "alexandre@moz-code.org"
203 assert user
.blog
== "moz-code.org"
206 fun test_get_user
is test
do
207 var user
= api
.get_user
("Morriar")
209 assert user
.login
== "Morriar"
210 assert user
.avatar_url
== "https://avatars2.githubusercontent.com/u/583144?v=4"
211 assert user
.name
== "Alexandre Terrasa"
212 assert user
.email
== "alexandre@moz-code.org"
213 assert user
.blog
== "moz-code.org"
216 fun test_get_repo
is test
do
217 var repo
= api
.get_repo
("nitlang/nit")
219 assert repo
.full_name
== "nitlang/nit"
220 assert repo
.name
== "nit"
221 assert repo
.owner
.login
== "nitlang"
222 assert repo
.default_branch
== "master"
225 fun test_get_branches
is test
do
226 var branches
= api
.get_repo_branches
("nitlang/nit", 1, 2)
227 assert branches
.length
== 2
228 assert branches
.first
.name
== "master"
229 assert branches
.last
.name
== "next"
232 fun test_get_issues
is test
do
233 var issues
= api
.get_repo_issues
("nitlang/nit", 1, 3)
234 assert issues
.length
== 3
235 assert issues
.first
.title
== "nitrpg: Move `nitrpg` to its own repository"
236 assert issues
.last
.title
== "Mock Github API tests"
239 fun test_search_issues
is test
do
240 var results
= api
.search_repo_issues
("nitlang/nit", "foo", 1, 3)
241 assert results
isa SearchResults
242 assert results
.items
.length
== 3
243 assert results
.items
.first
.as(Issue).title
== "Introduction of contracts in Nit"
244 assert results
.items
.last
.as(Issue).title
== "Appel de méthodes abstraites non redéfinies"
247 fun test_get_labels
is test
do
248 var labels
= api
.get_repo_labels
("nitlang/nit", 1, 3)
249 assert labels
.length
== 3
250 assert labels
.first
.name
== "API"
251 assert labels
.last
.name
== "NEP"
254 fun test_get_milestones
is test
do
255 var milestones
= api
.get_repo_milestones
("nitlang/nit", 1, 3)
256 assert milestones
.length
== 3
257 assert milestones
.first
.title
== "v1.0prealpha"
258 assert milestones
.last
.title
== "nitdoc - Abstraction levels"
261 fun test_get_pulls
is test
do
262 var pulls
= api
.get_repo_pulls
("nitlang/nit", 1, 3)
263 assert pulls
.length
== 3
264 assert pulls
.first
.title
== "nitrpg: Move `nitrpg` to its own repository"
265 assert pulls
.last
.title
== "Mock Github API tests"
268 fun test_get_branch
is test
do
269 var branch
= api
.get_branch
("nitlang/nit", "master")
270 assert branch
isa Branch
271 assert branch
.name
== "master"
274 fun test_get_commit
is test
do
275 var commit
= api
.get_commit
("nitlang/nit", "64ce1f")
276 assert commit
isa Commit
277 assert commit
.sha
== "64ce1f587209024f5de46d06c70526a569ff537f"
281 fun test_get_commit_status
is test
do
282 var status
= api
.get_commit_status
("nitlang/nit", "4e3c688d")
283 assert status
isa CommitStatus
284 assert status
.state
== "failure"
285 assert status
.sha
== "4e3c688d2c4b875c00f206eb4c4b6f2c4f34c096"
286 assert status
.total_count
== 1
288 var sub
= status
.statuses
.first
289 assert sub
.state
== "failure"
290 assert sub
.description
== "Merged pipeline on gitlab: failed"
291 assert sub
.context
== "gitlab-ci"
293 var repo
= status
.repository
295 assert repo
.full_name
== "nitlang/nit"
298 fun test_get_issue
is test
do
299 var issue
= api
.get_issue
("nitlang/nit", 1000)
300 assert issue
isa Issue
301 assert issue
.number
== 1000
302 assert issue
.title
== "Raise nitc from the dead"
303 assert issue
.user
.as(User).login
== "privat"
304 assert issue
.comments
== 7
305 assert issue
.created_at
== "2014-12-11T02:55:09Z"
306 assert issue
.closed_at
== "2014-12-13T15:38:09Z"
307 assert issue
.closed_by
.as(User).login
== "privat"
308 assert issue
.body
== "Raise dead on `nitc`.\nIt's super effective...\n"
309 assert issue
.is_pull_request
312 fun test_get_issue_comments
is test
do
313 var comments
= api
.get_issue_comments
("nitlang/nit", 1000, 1, 3)
314 assert comments
.length
== 3
315 assert comments
.first
.user
.login
== "R4PaSs"
316 assert comments
.last
.user
.login
== "xymus"
319 fun test_get_issue_events
is test
do
320 var events
= api
.get_issue_events
("nitlang/nit", 1000, 1, 3)
321 assert events
.length
== 3
322 assert events
.first
.actor
.login
== "privat"
323 assert events
.last
.actor
.login
== "xymus"
326 fun test_get_pull
is test
do
327 var pull
= api
.get_pull
("nitlang/nit", 1000)
328 assert pull
isa PullRequest
329 assert pull
.number
== 1000
330 assert pull
.title
== "Raise nitc from the dead"
331 assert pull
.user
.as(User).login
== "privat"
332 assert pull
.comments
== 7
333 assert pull
.created_at
== "2014-12-11T02:55:09Z"
334 assert pull
.closed_at
== "2014-12-13T15:38:09Z"
335 assert pull
.merged_by
.as(User).login
== "privat"
336 assert pull
.body
== "Raise dead on `nitc`.\nIt's super effective...\n"
339 fun test_get_pull_comments
is test
do
340 var comments
= api
.get_pull_comments
("nitlang/nit", 945, 1, 3)
341 assert comments
.length
== 2
342 assert comments
.first
.path
== "src/modelize/modelize_property.nit"
345 fun test_get_pull_comment
is test
do
346 var comment
= api
.get_pull_comment
("nitlang/nit", 21010363)
347 assert comment
isa PullComment
348 assert comment
.path
== "src/modelize/modelize_property.nit"
349 assert comment
.original_position
== 26
350 assert comment
.pull_number
== 945
354 fun test_get_label
is test
do
355 var labl
= api
.get_label
("nitlang/nit", "ok_will_merge")
356 assert labl
isa Label
357 assert labl
.name
== "ok_will_merge"
360 fun test_get_milestone
is test
do
361 var milestone
= api
.get_milestone
("nitlang/nit", 4)
362 assert milestone
isa Milestone
363 assert milestone
.title
== "v1.0prealpha"
367 fun test_get_issue_event
is test
do
368 var event
= api
.get_issue_event
("nitlang/nit", 199674194)
369 assert event
isa IssueEvent
370 assert event
.actor
.login
== "privat"
371 assert event
.event
== "labeled"
372 assert event
.labl
.as(Label).name
== "need_review"
375 fun test_get_issue_comment
is test
do
376 var comment
= api
.get_issue_comment
("nitlang/nit", 6020149)
377 assert comment
isa IssueComment
378 assert comment
.user
.login
== "privat"
379 assert comment
.created_at
.to_s
== "2012-05-30T20:16:54Z"
380 assert comment
.issue_number
== 10
383 fun test_get_comment
is test
do
384 var comment
= api
.get_commit_comment
("nitlang/nit", 8982707)
385 assert comment
isa CommitComment
386 assert comment
.user
.login
== "Morriar"
387 assert comment
.body
== "For testing purposes...\n"
388 assert comment
.commit_id
== "7eacb86d1e24b7e72bc9ac869bf7182c0300ceca"
391 fun test_contributor_stats
is test
do
392 var stats
= api
.get_repo_contrib_stats
("nitlang/nit")
393 assert stats
.last
.author
.login
== "privat"
394 assert stats
.last
.total
== 4536
395 assert stats
.last
.weeks
.length
== 575