plz / tests / first_run.v
432 lines · 341 sloc · 12.76 KB · c1be7a1408ed30cff2e8e359cf7e1ef69d66e988
Raw
1import os
2import log
3import net.http
4import time
5import json
6import api
7import term
8
9const gitly_url = 'http://127.0.0.1:8080'
10
11const default_branch = 'main'
12
13const test_username = 'bob'
14
15const test_github_repo_url = 'https://github.com/vlang/pcre'
16
17const test_github_repo_primary_branch = 'master'
18
19fn main() {
20 before()!
21
22 test_index_page()
23
24 ilog('Register the first user `${test_username}`')
25 mut register_headers, token := register_user(test_username, '1234zxcv', '[email protected]') or {
26 exit_with_message(err.str())
27 }
28
29 ilog('Check all cookies that must be present')
30 assert register_headers.contains(.set_cookie)
31
32 ilog('Ensure the login token is present after registration')
33 has_token := token != ''
34 assert has_token
35
36 test_user_page(test_username)
37 test_login_with_token(test_username, token)
38 test_static_served()
39 test_oauth_page()
40
41 test_create_repo(token, 'test1', '')
42 assert get_repo_commit_count(token, test_username, 'test1', default_branch) == 0
43 assert get_repo_issue_count(token, test_username, 'test1') == 0
44 assert get_repo_branch_count(token, test_username, 'test1') == 0
45
46 repo_name := 'test2'
47 test_create_repo(token, repo_name, test_github_repo_url)
48 // wait while repo is cloning
49 time.sleep(5 * time.second)
50 // get repo
51 assert get_repo_commit_count(token, test_username, repo_name, test_github_repo_primary_branch) > 0
52 assert get_repo_issue_count(token, test_username, repo_name) == 0
53 assert get_repo_branch_count(token, test_username, repo_name) > 0
54 test_repo_page(test_username, repo_name)
55 test_branch_page(test_username, repo_name, test_github_repo_primary_branch)
56 test_repos_page(test_username)
57 test_repo_settings_page(test_username, repo_name)
58 test_contributors_page(test_username, repo_name)
59 // test_issues_page(test_username)
60 test_stars_page(test_username)
61 test_settings_page(test_username)
62 test_commits_page(test_username, repo_name, test_github_repo_primary_branch)
63 test_branches_page(test_username, repo_name)
64 test_repo_tree(test_username, repo_name, test_github_repo_primary_branch, 'c')
65 // this makes sure that the blob (and the tree?) is ready
66 test_repo_tree(test_username, repo_name, test_github_repo_primary_branch, 'examples')
67 test_blob_page(test_username, repo_name, test_github_repo_primary_branch, 'examples/hello.v')
68 // test_refs_page(test_username, repo_name)
69 // test_api_branches_count(test_username, repo_name)
70 ilog('all tests passed!')
71
72 after()!
73}
74
75fn before() ! {
76 cd_executable_dir()!
77
78 ilog('Make sure gitly is not running')
79 kill_gitly_processes()
80
81 remove_database_if_exists()!
82 remove_repos_dir_if_exists()!
83 compile_gitly()
84
85 ilog('Start gitly in the background, then wait till gitly starts and is responding to requests')
86 spawn run_gitly()
87
88 wait_gitly()
89}
90
91fn after() ! {
92 remove_database_if_exists()!
93 remove_repos_dir_if_exists()!
94
95 ilog('Ensure gitly is stopped')
96 kill_gitly_processes()
97}
98
99fn run_gitly() {
100 gitly_process := os.execute('./gitly.exe &')
101 if gitly_process.exit_code != 0 {
102 exit_with_message(gitly_process.str())
103 }
104}
105
106@[noreturn]
107fn exit_with_message(message string) {
108 println(message)
109 exit(1)
110}
111
112fn ilog(message string) {
113 log.info(message)
114}
115
116fn cd_executable_dir() ! {
117 executable_dir := os.dir(os.executable())
118 // Ensure that we are always running in the gitly folder, no matter what is the starting one:
119 os.chdir(os.dir(executable_dir))!
120
121 ilog('Testing first gitly run.')
122}
123
124fn kill_gitly_processes() {
125 os.execute('pkill -9 gitly.exe')
126}
127
128fn remove_database_if_exists() ! {
129 ilog('Remove old gitly DB')
130
131 if os.exists('gitly.sqlite') {
132 os.rm('gitly.sqlite')!
133 }
134}
135
136fn remove_repos_dir_if_exists() ! {
137 ilog('Remove repos directory')
138
139 if os.exists('repos') {
140 os.rmdir_all('repos')!
141 }
142}
143
144fn compile_gitly() {
145 ilog('Compile gitly')
146 // Note that using `-d use_openssl` prevents tcc from working, so the compilation will be much slower:
147 os.execute('v -d use_libbacktrace -cg -keepc -d use_openssl -o gitly.exe .')
148 ilog('Compiled gitly.exe, size: ${os.file_size('gitly.exe')}')
149}
150
151fn wait_gitly() {
152 for waiting_cycles := 0; waiting_cycles < 50; waiting_cycles++ {
153 ilog('\twait: ${waiting_cycles}')
154 time.sleep(100 * time.millisecond)
155 http.get(prepare_url('')) or { continue }
156 break
157 }
158}
159
160fn prepare_url(path string) string {
161 return '${gitly_url}/${path}'
162}
163
164fn test_index_page() {
165 ilog("Ensure gitly's main page is up")
166 index_page_result := http.get(prepare_url('')) or { exit_with_message(err.str()) }
167 assert index_page_result.body.contains('<html>')
168 assert index_page_result.body.contains('</html>')
169
170 ilog('Ensure there is a welcome and register message')
171 assert index_page_result.body.contains("Welcome to Gitly! Looks like you've just set it up, you'll need to register")
172 ilog('Ensure there is a Register button')
173 assert index_page_result.body.contains("<input type='submit' value='Register'>")
174
175 // Make sure no one's logged in
176 assert index_page_result.body.contains("<a href='/login' class='login-button'>Log in</a>")
177}
178
179// returns headers and token
180fn register_user(username string, password string, email string) !(http.Header, string) {
181 response := http.post(prepare_url('register'),
182 'username=${username}&password=${password}&email=${email}&no_redirect=1') or { return err }
183
184 mut token := ''
185 for val in response.header.values(.set_cookie) {
186 token = val.find_between('token=', ';')
187 }
188
189 return response.header, token
190}
191
192fn test_static_served() {
193 ilog('Ensure that static css is served')
194 css := http.get(prepare_url('css/gitly.css')) or { exit_with_message(err.str()) }
195
196 assert css.status_code != 404
197 assert css.body.contains('body')
198 assert css.body.contains('html')
199}
200
201fn test_user_page(username string) {
202 ilog('Testing the new user /${username} page is up after registration')
203 user_page_result := http.get(prepare_url(username)) or { exit_with_message(err.str()) }
204
205 assert user_page_result.body.contains('<h3>${username}</h3>')
206}
207
208fn test_repo_page(username string, repo_name string) {
209 ilog('Testing the new repo /${username}/${repo_name} page is up')
210 repo_page_result := http.get(prepare_url('${username}/${repo_name}')) or {
211 exit_with_message(err.str())
212 }
213
214 assert repo_page_result.status_code == 200
215}
216
217fn test_branch_page(username string, repo_name string, branch_name string) {
218 ilog('Testing the new branch /${username}/${repo_name}/tree/${branch_name} page is up')
219 branch_page_result := http.get(prepare_url('${username}/${repo_name}/tree/${branch_name}')) or {
220 exit_with_message(err.str())
221 }
222
223 assert branch_page_result.status_code == 200
224}
225
226fn test_repos_page(username string) {
227 ilog('Testing the new repos /${username}/repos page is up')
228 repos_page_result := http.get(prepare_url('${username}/repos')) or {
229 exit_with_message(err.str())
230 }
231
232 assert repos_page_result.status_code == 200
233}
234
235fn test_contributors_page(username string, repo_name string) {
236 ilog('Testing the new contributors /${username}/${repo_name}/contributors page is up')
237 contributors_page_result := http.get(prepare_url('${username}/${repo_name}/contributors')) or {
238 exit_with_message(err.str())
239 }
240
241 assert contributors_page_result.status_code == 200
242}
243
244fn test_commits_page(username string, repo_name string, branch_name string) {
245 ilog('Testing the new commits /${username}/${repo_name}/${branch_name}/commits/1 page is up')
246 // Doesn't work with commits/[no 1]
247 commits_page_result := http.get(prepare_url('${username}/${repo_name}/${branch_name}/commits/1')) or {
248 exit_with_message(err.str())
249 }
250
251 assert commits_page_result.status_code == 200
252}
253
254fn test_branches_page(username string, repo_name string) {
255 ilog('Testing the new branches /${username}/${repo_name}/branches page is up')
256 branches_page_result := http.get(prepare_url('${username}/${repo_name}/branches')) or {
257 exit_with_message(err.str())
258 }
259
260 assert branches_page_result.status_code == 200
261}
262
263fn test_api_branches_count(username string, repo_name string) {
264 ilog('Testing if api/v1/${username}/${repo_name}/branches/count works')
265 api_branches_count_result := http.get(prepare_url('api/v1/${username}/${repo_name}/branches/count')) or {
266 exit_with_message(err.str())
267 }
268 // api_branches_count_result := http.fetch(
269 // method: .get
270 // url: prepare_url("api/v1/${username}/${repo_name}/branches/count")
271 // ) or { exit_with_message(err.str()) }
272
273 assert api_branches_count_result.status_code == 200
274
275 response_json := json.decode[api.ApiBranchCount](api_branches_count_result.body) or {
276 exit_with_message(err.str())
277 }
278 assert response_json.result > 0
279}
280
281fn test_refs_page(username string, repo_name string) {
282 ilog('Testing the new refs /${username}/${repo_name}/info/refs page is up')
283 refs_page_result := http.get(prepare_url('${username}/${repo_name}/info/refs')) or {
284 exit_with_message(err.str())
285 }
286
287 assert refs_page_result.status_code == 200
288}
289
290fn test_oauth_page() {
291 ilog('Testing the new oauth /oauth page is up')
292 oauth_page_result := http.get(prepare_url('oauth')) or { exit_with_message(err.str()) }
293
294 assert oauth_page_result.status_code == 200
295}
296
297fn test_repo_tree(username string, repo_name string, branch_name string, path string) {
298 ilog('Testing the new tree /${username}/${repo_name}/tree/${branch_name}/${path} page is up')
299 repo_tree_result := http.get(prepare_url('${username}/${repo_name}/tree/${branch_name}/${path}')) or {
300 exit_with_message(err.str())
301 }
302
303 assert repo_tree_result.status_code == 200
304}
305
306// fn test_issues_page(username string) {
307// test_endpoint_page("${username}/issues", 'issues')
308// }
309
310fn test_stars_page(username string) {
311 ilog('Testing the new stars /${username}/stars page is up')
312 stars_page_result := http.get(prepare_url('${username}/stars')) or {
313 exit_with_message(err.str())
314 }
315
316 assert stars_page_result.status_code == 200
317}
318
319fn test_settings_page(username string) {
320 ilog('Testing the new settings /${username}/settings page is up')
321 settings_page_result := http.get(prepare_url('${username}/settings')) or {
322 exit_with_message(err.str())
323 }
324
325 assert settings_page_result.status_code == 200
326}
327
328fn test_blob_page(username string, repo_name string, branch_name string, path string) {
329 url := '${username}/${repo_name}/blob/${branch_name}/${path}'
330 ilog('Testing the new blob /${url} page is up')
331 blob_page_result := http.fetch(
332 method: .get
333 url: prepare_url(url)
334 ) or { exit_with_message(err.str()) }
335
336 assert blob_page_result.status_code == 200
337 assert blob_page_result.body.str().contains('m := r.match_str')
338}
339
340fn test_repo_settings_page(username string, repo_name string) {
341 test_endpoint_page('${username}/${repo_name}/settings', 'settings')
342}
343
344fn test_endpoint_page(endpoint string, pagename string) {
345 ilog('Testing the new ${pagename} /${endpoint} page is up')
346 endpoint_result := http.get(prepare_url('${endpoint}')) or { exit_with_message(err.str()) }
347
348 assert endpoint_result.status_code == 200
349}
350
351fn test_login_with_token(username string, token string) {
352 ilog('Try to login in with `${username}` user token')
353
354 login_result := http.fetch(
355 method: .get
356 cookies: {
357 'token': token
358 }
359 url: prepare_url(username)
360 ) or { exit_with_message(err.str()) }
361
362 ilog('Ensure that after login, there is a signed in as `${username}` message')
363
364 assert login_result.body.contains('<span>Signed in as</span>')
365 assert login_result.body.contains("<a href='/${username}'>${username}</a>")
366}
367
368fn test_create_repo(token string, name string, clone_url string) {
369 description := 'test description'
370 repo_visibility := 'public'
371
372 response := http.fetch(
373 method: .post
374 cookies: {
375 'token': token
376 }
377 url: prepare_url('new')
378 data: 'name=${name}&description=${description}&clone_url=${clone_url}&repo_visibility=${repo_visibility}&no_redirect=1'
379 ) or { exit_with_message(err.str()) }
380
381 assert response.status_code == 200
382 assert response.body == 'ok'
383}
384
385fn get_repo_commit_count(token string, username string, repo_name string, branch_name string) int {
386 response := http.fetch(
387 method: .get
388 cookies: {
389 'token': token
390 }
391 url: prepare_url('api/v1/${username}/${repo_name}/${branch_name}/commits/count')
392 ) or { exit_with_message(err.str()) }
393
394 response_json := json.decode[api.ApiCommitCount](response.body) or {
395 exit_with_message(err.str())
396 }
397 dump(response_json.result)
398
399 return response_json.result
400}
401
402fn get_repo_issue_count(token string, username string, repo_name string) int {
403 response := http.fetch(
404 method: .get
405 cookies: {
406 'token': token
407 }
408 url: prepare_url('api/v1/${username}/${repo_name}/issues/count')
409 ) or { exit_with_message(err.str()) }
410
411 response_json := json.decode[api.ApiIssueCount](response.body) or {
412 exit_with_message(err.str())
413 }
414
415 return response_json.result
416}
417
418fn get_repo_branch_count(token string, username string, repo_name string) int {
419 response := http.fetch(
420 method: .get
421 cookies: {
422 'token': token
423 }
424 url: prepare_url('api/v1/${username}/${repo_name}/branches/count')
425 ) or { exit_with_message(err.str()) }
426
427 response_json := json.decode[api.ApiBranchCount](response.body) or {
428 exit_with_message(err.str())
429 }
430
431 return response_json.result
432}
433