1 /**
2  * Tests all Network implementations.
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <vladimir@thecybershadow.net>
12  */
13 
14 module ae.sys.net.test;
15 
16 import std.array;
17 import std.file;
18 import std.process : environment;
19 
20 import ae.net.http.common;
21 import ae.sys.data;
22 
23 static import ae.sys.net.ae;
24 static import ae.sys.net.curl;
25 version(Windows)
26 static import ae.sys.net.wininet;
27 static import ae.sys.net.cachedcurl;
28 
29 debug static import std.stdio;
30 
31 // Server-side test scripts are here:
32 // https://gist.github.com/58df32ed1dbe64fffd0545f87d9321ad
33 string testBaseURL = "http://thecybershadow.net/d/nettest/"; // should be HTTP
34 
35 void test(string moduleName, string className)()
36 {
37 	debug std.stdio.stderr.writeln("Testing " ~ className);
38 
39 	mixin("import ae.sys.net." ~ moduleName ~ ";");
40 	mixin("alias Net = " ~ className ~ ";");
41 	auto net = new Net();
42 
43 	debug std.stdio.stderr.writeln(" - getFile");
44 	{
45 		assert(net.getFile(testBaseURL ~ "testUrl1") == "Hello world\n");
46 	}
47 
48 	debug std.stdio.stderr.writeln(" - downloadFile");
49 	{
50 		enum fn = "test.txt";
51 		if (fn.exists) fn.remove();
52 		scope(exit) if (fn.exists) fn.remove();
53 
54 		net.downloadFile(testBaseURL ~ "testUrl1", fn);
55 		assert(fn.readText() == "Hello world\n");
56 	}
57 
58 	debug std.stdio.stderr.writeln(" - urlOK");
59 	{
60 		assert( net.urlOK(testBaseURL ~ "testUrl1"));
61 		assert(!net.urlOK(testBaseURL ~ "testUrlNX"));
62 		static if (moduleName == "wininet")
63 			assert( net.urlOK(testBaseURL.replace("http://", "https://") ~  "testUrl1"));
64 	}
65 
66 	debug std.stdio.stderr.writeln(" - resolveRedirect");
67 	{
68 		auto result = net.resolveRedirect(testBaseURL ~ "testUrl3");
69 		assert(result == testBaseURL ~ "testUrl2", result);
70 	}
71 
72 	debug std.stdio.stderr.writeln(" - post");
73 	{
74 		auto result = cast(string)net.post(testBaseURL ~ "testUrl4", "Hello world\n");
75 		assert(result == "Hello world\n", result);
76 	}
77 
78 	debug std.stdio.stderr.writeln(" - httpRequest");
79 	{
80 		auto request = new HttpRequest(testBaseURL ~ "testUrl5");
81 		request.method = "PUT";
82 		request.headers.add("Test-Request-Header", "foo");
83 		request.data = [Data("bar")];
84 		auto response = net.httpRequest(request);
85 		assert(response.status == HttpStatusCode.Accepted);
86 		assert(response.statusMessage == "Custom Message");
87 		assert(response.data.joinToHeap == "PUT foo bar");
88 		assert(response.headers["Test-Response-Header"] == "baz");
89 	}
90 }
91 
92 unittest
93 {
94 	// Don't do network requests on the project tester.
95 	// See:
96 	// - https://github.com/CyberShadow/ae/issues/30
97 	// - https://github.com/dlang/dmd/pull/9618#issuecomment-483214780
98 	if (environment.get("BUILDKITE_AGENT_NAME"))
99 		return;
100 
101 	test!("ae", "AENetwork");
102 	test!("curl", "CurlNetwork");
103 	version(Windows)
104 	test!("wininet", "WinINetNetwork");
105 
106 	import ae.utils.meta : classInit;
107 	auto cacheDir = classInit!(ae.sys.net.cachedcurl.CachedCurlNetwork).cacheDir;
108 	if (cacheDir.exists) cacheDir.rmdirRecurse();
109 	scope(exit) if (cacheDir.exists) cacheDir.rmdirRecurse();
110 	test!("cachedcurl", "CachedCurlNetwork");
111 }