import os import log import net.http import time import json import api import term const gitly_url = 'http://127.0.0.1:8080' const default_branch = 'main' const test_username = 'bob' const test_github_repo_url = 'https://github.com/vlang/pcre' const test_github_repo_primary_branch = 'master' fn main() { before()! test_index_page() ilog('Register the first user `${test_username}`') mut register_headers, token := register_user(test_username, '1234zxcv', 'bob@example.com') or { exit_with_message(err.str()) } ilog('Check all cookies that must be present') assert register_headers.contains(.set_cookie) ilog('Ensure the login token is present after registration') has_token := token != '' assert has_token test_user_page(test_username) test_login_with_token(test_username, token) test_static_served() test_oauth_page() test_create_repo(token, 'test1', '') assert get_repo_commit_count(token, test_username, 'test1', default_branch) == 0 assert get_repo_issue_count(token, test_username, 'test1') == 0 assert get_repo_branch_count(token, test_username, 'test1') == 0 repo_name := 'test2' test_create_repo(token, repo_name, test_github_repo_url) // wait while repo is cloning time.sleep(5 * time.second) // get repo assert get_repo_commit_count(token, test_username, repo_name, test_github_repo_primary_branch) > 0 assert get_repo_issue_count(token, test_username, repo_name) == 0 assert get_repo_branch_count(token, test_username, repo_name) > 0 test_repo_page(test_username, repo_name) test_branch_page(test_username, repo_name, test_github_repo_primary_branch) test_repos_page(test_username) test_repo_settings_page(test_username, repo_name) test_contributors_page(test_username, repo_name) // test_issues_page(test_username) test_stars_page(test_username) test_settings_page(test_username) test_commits_page(test_username, repo_name, test_github_repo_primary_branch) test_branches_page(test_username, repo_name) test_repo_tree(test_username, repo_name, test_github_repo_primary_branch, 'c') // this makes sure that the blob (and the tree?) is ready test_repo_tree(test_username, repo_name, test_github_repo_primary_branch, 'examples') test_blob_page(test_username, repo_name, test_github_repo_primary_branch, 'examples/hello.v') // test_refs_page(test_username, repo_name) // test_api_branches_count(test_username, repo_name) ilog('all tests passed!') after()! } fn before() ! { cd_executable_dir()! ilog('Make sure gitly is not running') kill_gitly_processes() remove_database_if_exists()! remove_repos_dir_if_exists()! compile_gitly() ilog('Start gitly in the background, then wait till gitly starts and is responding to requests') spawn run_gitly() wait_gitly() } fn after() ! { remove_database_if_exists()! remove_repos_dir_if_exists()! ilog('Ensure gitly is stopped') kill_gitly_processes() } fn run_gitly() { gitly_process := os.execute('./gitly.exe &') if gitly_process.exit_code != 0 { exit_with_message(gitly_process.str()) } } @[noreturn] fn exit_with_message(message string) { println(message) exit(1) } fn ilog(message string) { log.info(message) } fn cd_executable_dir() ! { executable_dir := os.dir(os.executable()) // Ensure that we are always running in the gitly folder, no matter what is the starting one: os.chdir(os.dir(executable_dir))! ilog('Testing first gitly run.') } fn kill_gitly_processes() { os.execute('pkill -9 gitly.exe') } fn remove_database_if_exists() ! { ilog('Remove old gitly DB') if os.exists('gitly.sqlite') { os.rm('gitly.sqlite')! } } fn remove_repos_dir_if_exists() ! { ilog('Remove repos directory') if os.exists('repos') { os.rmdir_all('repos')! } } fn compile_gitly() { ilog('Compile gitly') // Note that using `-d use_openssl` prevents tcc from working, so the compilation will be much slower: os.execute('v -d use_libbacktrace -cg -keepc -d use_openssl -o gitly.exe .') ilog('Compiled gitly.exe, size: ${os.file_size('gitly.exe')}') } fn wait_gitly() { for waiting_cycles := 0; waiting_cycles < 50; waiting_cycles++ { ilog('\twait: ${waiting_cycles}') time.sleep(100 * time.millisecond) http.get(prepare_url('')) or { continue } break } } fn prepare_url(path string) string { return '${gitly_url}/${path}' } fn test_index_page() { ilog("Ensure gitly's main page is up") index_page_result := http.get(prepare_url('')) or { exit_with_message(err.str()) } assert index_page_result.body.contains('') assert index_page_result.body.contains('') ilog('Ensure there is a welcome and register message') assert index_page_result.body.contains("Welcome to Gitly! Looks like you've just set it up, you'll need to register") ilog('Ensure there is a Register button') assert index_page_result.body.contains("") // Make sure no one's logged in assert index_page_result.body.contains("Log in") } // returns headers and token fn register_user(username string, password string, email string) !(http.Header, string) { response := http.post(prepare_url('register'), 'username=${username}&password=${password}&email=${email}&no_redirect=1') or { return err } mut token := '' for val in response.header.values(.set_cookie) { token = val.find_between('token=', ';') } return response.header, token } fn test_static_served() { ilog('Ensure that static css is served') css := http.get(prepare_url('css/gitly.css')) or { exit_with_message(err.str()) } assert css.status_code != 404 assert css.body.contains('body') assert css.body.contains('html') } fn test_user_page(username string) { ilog('Testing the new user /${username} page is up after registration') user_page_result := http.get(prepare_url(username)) or { exit_with_message(err.str()) } assert user_page_result.body.contains('

${username}

') } fn test_repo_page(username string, repo_name string) { ilog('Testing the new repo /${username}/${repo_name} page is up') repo_page_result := http.get(prepare_url('${username}/${repo_name}')) or { exit_with_message(err.str()) } assert repo_page_result.status_code == 200 } fn test_branch_page(username string, repo_name string, branch_name string) { ilog('Testing the new branch /${username}/${repo_name}/tree/${branch_name} page is up') branch_page_result := http.get(prepare_url('${username}/${repo_name}/tree/${branch_name}')) or { exit_with_message(err.str()) } assert branch_page_result.status_code == 200 } fn test_repos_page(username string) { ilog('Testing the new repos /${username}/repos page is up') repos_page_result := http.get(prepare_url('${username}/repos')) or { exit_with_message(err.str()) } assert repos_page_result.status_code == 200 } fn test_contributors_page(username string, repo_name string) { ilog('Testing the new contributors /${username}/${repo_name}/contributors page is up') contributors_page_result := http.get(prepare_url('${username}/${repo_name}/contributors')) or { exit_with_message(err.str()) } assert contributors_page_result.status_code == 200 } fn test_commits_page(username string, repo_name string, branch_name string) { ilog('Testing the new commits /${username}/${repo_name}/${branch_name}/commits/1 page is up') // Doesn't work with commits/[no 1] commits_page_result := http.get(prepare_url('${username}/${repo_name}/${branch_name}/commits/1')) or { exit_with_message(err.str()) } assert commits_page_result.status_code == 200 } fn test_branches_page(username string, repo_name string) { ilog('Testing the new branches /${username}/${repo_name}/branches page is up') branches_page_result := http.get(prepare_url('${username}/${repo_name}/branches')) or { exit_with_message(err.str()) } assert branches_page_result.status_code == 200 } fn test_api_branches_count(username string, repo_name string) { ilog('Testing if api/v1/${username}/${repo_name}/branches/count works') api_branches_count_result := http.get(prepare_url('api/v1/${username}/${repo_name}/branches/count')) or { exit_with_message(err.str()) } // api_branches_count_result := http.fetch( // method: .get // url: prepare_url("api/v1/${username}/${repo_name}/branches/count") // ) or { exit_with_message(err.str()) } assert api_branches_count_result.status_code == 200 response_json := json.decode[api.ApiBranchCount](api_branches_count_result.body) or { exit_with_message(err.str()) } assert response_json.result > 0 } fn test_refs_page(username string, repo_name string) { ilog('Testing the new refs /${username}/${repo_name}/info/refs page is up') refs_page_result := http.get(prepare_url('${username}/${repo_name}/info/refs')) or { exit_with_message(err.str()) } assert refs_page_result.status_code == 200 } fn test_oauth_page() { ilog('Testing the new oauth /oauth page is up') oauth_page_result := http.get(prepare_url('oauth')) or { exit_with_message(err.str()) } assert oauth_page_result.status_code == 200 } fn test_repo_tree(username string, repo_name string, branch_name string, path string) { ilog('Testing the new tree /${username}/${repo_name}/tree/${branch_name}/${path} page is up') repo_tree_result := http.get(prepare_url('${username}/${repo_name}/tree/${branch_name}/${path}')) or { exit_with_message(err.str()) } assert repo_tree_result.status_code == 200 } // fn test_issues_page(username string) { // test_endpoint_page("${username}/issues", 'issues') // } fn test_stars_page(username string) { ilog('Testing the new stars /${username}/stars page is up') stars_page_result := http.get(prepare_url('${username}/stars')) or { exit_with_message(err.str()) } assert stars_page_result.status_code == 200 } fn test_settings_page(username string) { ilog('Testing the new settings /${username}/settings page is up') settings_page_result := http.get(prepare_url('${username}/settings')) or { exit_with_message(err.str()) } assert settings_page_result.status_code == 200 } fn test_blob_page(username string, repo_name string, branch_name string, path string) { url := '${username}/${repo_name}/blob/${branch_name}/${path}' ilog('Testing the new blob /${url} page is up') blob_page_result := http.fetch( method: .get url: prepare_url(url) ) or { exit_with_message(err.str()) } assert blob_page_result.status_code == 200 assert blob_page_result.body.str().contains('m := r.match_str') } fn test_repo_settings_page(username string, repo_name string) { test_endpoint_page('${username}/${repo_name}/settings', 'settings') } fn test_endpoint_page(endpoint string, pagename string) { ilog('Testing the new ${pagename} /${endpoint} page is up') endpoint_result := http.get(prepare_url('${endpoint}')) or { exit_with_message(err.str()) } assert endpoint_result.status_code == 200 } fn test_login_with_token(username string, token string) { ilog('Try to login in with `${username}` user token') login_result := http.fetch( method: .get cookies: { 'token': token } url: prepare_url(username) ) or { exit_with_message(err.str()) } ilog('Ensure that after login, there is a signed in as `${username}` message') assert login_result.body.contains('Signed in as') assert login_result.body.contains("${username}") } fn test_create_repo(token string, name string, clone_url string) { description := 'test description' repo_visibility := 'public' response := http.fetch( method: .post cookies: { 'token': token } url: prepare_url('new') data: 'name=${name}&description=${description}&clone_url=${clone_url}&repo_visibility=${repo_visibility}&no_redirect=1' ) or { exit_with_message(err.str()) } assert response.status_code == 200 assert response.body == 'ok' } fn get_repo_commit_count(token string, username string, repo_name string, branch_name string) int { response := http.fetch( method: .get cookies: { 'token': token } url: prepare_url('api/v1/${username}/${repo_name}/${branch_name}/commits/count') ) or { exit_with_message(err.str()) } response_json := json.decode[api.ApiCommitCount](response.body) or { exit_with_message(err.str()) } dump(response_json.result) return response_json.result } fn get_repo_issue_count(token string, username string, repo_name string) int { response := http.fetch( method: .get cookies: { 'token': token } url: prepare_url('api/v1/${username}/${repo_name}/issues/count') ) or { exit_with_message(err.str()) } response_json := json.decode[api.ApiIssueCount](response.body) or { exit_with_message(err.str()) } return response_json.result } fn get_repo_branch_count(token string, username string, repo_name string) int { response := http.fetch( method: .get cookies: { 'token': token } url: prepare_url('api/v1/${username}/${repo_name}/branches/count') ) or { exit_with_message(err.str()) } response_json := json.decode[api.ApiBranchCount](response.body) or { exit_with_message(err.str()) } return response_json.result }