From 2ad2b4c5baf0f01ef93063926e05e13a1b4f5380 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Fri, 14 Aug 2020 02:43:57 +0300 Subject: [PATCH] vweb: add more tests. Fix missing Content-Length: header bug on 404. --- vlib/vweb/tests/vweb_test.v | 74 +++++++++++++++++++++++++++++- vlib/vweb/tests/vweb_test_server.v | 36 ++++++++++++++- vlib/vweb/vweb.v | 2 +- 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/vlib/vweb/tests/vweb_test.v b/vlib/vweb/tests/vweb_test.v index 83dc58c3bc..e08877751c 100644 --- a/vlib/vweb/tests/vweb_test.v +++ b/vlib/vweb/tests/vweb_test.v @@ -1,11 +1,12 @@ import os import time +import json import net import net.http const ( sport = 12380 - exit_after_time = 1000 // milliseconds + exit_after_time = 5000 // milliseconds vexe = os.getenv('VEXE') vroot = os.dir(vexe) serverexe = os.join_path(os.cache_dir(), 'vweb_test_server.exe') @@ -108,6 +109,20 @@ fn test_http_client_index() { assert x.text == 'Welcome to VWeb' } +fn test_http_client_404() { + url_404_list := [ + 'http://127.0.0.1:$sport/zxcnbnm', + 'http://127.0.0.1:$sport/JHKAJA', + 'http://127.0.0.1:$sport/unknown', + ] + for url in url_404_list { + res := http.get(url) or { + panic(err) + } + assert res.status_code == 404 + } +} + fn test_http_client_simple() { x := http.get('http://127.0.0.1:$sport/simple') or { panic(err) @@ -132,6 +147,7 @@ fn test_http_client_settings_page() { } assert_common_http_headers(x) assert x.text == 'username: bilbo' + // y := http.get('http://127.0.0.1:$sport/kent/settings') or { panic(err) } @@ -145,11 +161,67 @@ fn test_http_client_user_repo_settings_page() { } assert_common_http_headers(x) assert x.text == 'username: bilbo | repository: gostamp' + // y := http.get('http://127.0.0.1:$sport/kent/golang/settings') or { panic(err) } assert_common_http_headers(y) assert y.text == 'username: kent | repository: golang' + // + z := http.get('http://127.0.0.1:$sport/missing/golang/settings') or { + panic(err) + } + assert z.status_code == 404 +} + +struct User { + name string + age int +} + +fn test_http_client_json_post() { + ouser := User{ + name: 'Bilbo' + age: 123 + } + json_for_ouser := json.encode(ouser) + x := http.post_json('http://127.0.0.1:$sport/json_echo', json_for_ouser) or { + panic(err) + } + $if debug_net_socket_client ? { + eprintln('json response: $x') + } + assert x.headers['Content-Type'] == 'application/json' + assert x.text == json_for_ouser + nuser := json.decode(User, x.text) or { + User{} + } + assert '$ouser' == '$nuser' +} + +fn test_http_client_shutdown_does_not_work_without_a_cookie() { + x := http.get('http://127.0.0.1:$sport/shutdown') or { + assert err == '' + return + } + assert x.status_code == 404 + assert x.text == '404 Not Found' +} + +fn testsuite_end() { + // This test is guaranteed to be called last. + // It sends a request to the server to shutdown. + x := http.fetch('http://127.0.0.1:$sport/shutdown', { + method: .get + cookies: { + 'skey': 'superman' + } + }) or { + assert err == '' + return + } + assert x.status_code == 200 + assert x.text == 'good bye' } // utility code: diff --git a/vlib/vweb/tests/vweb_test_server.v b/vlib/vweb/tests/vweb_test_server.v index f4508095f8..a6db6a70c6 100644 --- a/vlib/vweb/tests/vweb_test_server.v +++ b/vlib/vweb/tests/vweb_test_server.v @@ -4,6 +4,10 @@ import os import vweb import time +const ( + known_users = ['bilbo', 'kent'] +) + struct App { port int timeout int @@ -38,7 +42,7 @@ pub fn (mut app App) init() { } pub fn (mut app App) init_once() { - eprintln('Started webserver on http://127.0.0.1:$app.port/ , with maximum runtime of $app.timeout milliseconds.') + eprintln('>> webserver: started on http://127.0.0.1:$app.port/ , with maximum runtime of $app.timeout milliseconds.') } pub fn (mut app App) index() { @@ -58,12 +62,42 @@ pub fn (mut app App) html_page() vweb.Result { // the following serve custom routes ['/:user/settings'] pub fn (mut app App) settings(username string) vweb.Result { + if username !in known_users { + return app.vweb.not_found() + } app.vweb.html('username: $username') return vweb.Result{} } ['/:user/:repo/settings'] pub fn (mut app App) user_repo_settings(username, repository string) vweb.Result { + if username !in known_users { + return app.vweb.not_found() + } app.vweb.html('username: $username | repository: $repository') return vweb.Result{} } + +[post] +['/json_echo'] +pub fn (mut app App) json() vweb.Result { + app.vweb.set_content_type(app.vweb.req.headers['Content-Type']) + return app.vweb.ok(app.vweb.req.data) +} + +pub fn (mut app App) shutdown() vweb.Result { + session_key := app.vweb.get_cookie('skey') or { + return app.vweb.not_found() + } + if session_key != 'superman' { + return app.vweb.not_found() + } + go app.gracefull_exit() + return app.vweb.ok('good bye') +} + +fn (mut app App) gracefull_exit() { + eprintln('>> webserver: gracefull_exit') + time.sleep_ms(100) + exit(0) +} diff --git a/vlib/vweb/vweb.v b/vlib/vweb/vweb.v index 9e41f0aee9..c8392aeb73 100644 --- a/vlib/vweb/vweb.v +++ b/vlib/vweb/vweb.v @@ -16,7 +16,7 @@ pub const ( header_server = 'Server: VWeb\r\n' header_connection_close = 'Connection: close\r\n' headers_close = '${header_server}${header_connection_close}\r\n' - http_404 = 'HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\n${headers_close}404 Not Found' + http_404 = 'HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: 13\r\n${headers_close}404 Not Found' http_500 = 'HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/plain\r\n${headers_close}500 Internal Server Error' mime_types = { '.css': 'text/css; charset=utf-8',