blob: 1d02171e8424e4f37413ba5a2512908552f08f02 [file] [log] [blame]
Ed Tanousb4a7bfa2017-04-04 17:23:00 -07001#include <crow/app.h>
2#include <gmock/gmock.h>
Ed Tanous9140a672017-04-24 17:01:32 -07003
4#include <test_utils.hpp>
5#include <webassets.hpp>
6#include <sstream>
Ed Tanousb4a7bfa2017-04-04 17:23:00 -07007#include <boost/algorithm/string/predicate.hpp>
8#include <boost/iostreams/copy.hpp>
9#include <boost/iostreams/filter/gzip.hpp>
10#include <boost/iostreams/filtering_streambuf.hpp>
11#include <boost/lexical_cast.hpp>
Ed Tanousb4a7bfa2017-04-04 17:23:00 -070012#include "gtest/gtest.h"
Ed Tanous9140a672017-04-24 17:01:32 -070013
Ed Tanousb4a7bfa2017-04-04 17:23:00 -070014using namespace crow;
15using namespace std;
16using namespace testing;
17
Ed Tanousb4a7bfa2017-04-04 17:23:00 -070018// Tests static files are loaded correctly
19TEST(Webassets, StaticFilesFixedRoutes) {
20 std::array<char, 2048> buf;
21 SimpleApp app;
22 webassets::request_routes(app);
23 Server<SimpleApp> server(&app, "127.0.0.1", 45451);
24 auto _ = async(launch::async, [&] { server.run(); });
25
26 // Get the homepage
27 std::string sendmsg = "GET /\r\n\r\n";
28
29 asio::io_service is;
30
31 asio::ip::tcp::socket c(is);
32 c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"),
33 45451));
34
35 c.send(asio::buffer(sendmsg));
36
37 c.receive(asio::buffer(buf, 2048));
38 c.close();
39
40 std::string response(std::begin(buf), std::end(buf));
41 // This is a routine to split strings until a newline is hit
42 // TODO(ed) this should really use the HTTP parser
43 std::vector<std::string> headers;
44 std::string::size_type pos = 0;
45 std::string::size_type prev = 0;
46 int content_length = 0;
47 std::string content_encoding("");
48 while ((pos = response.find("\r\n", prev)) != std::string::npos) {
49 auto this_string = response.substr(prev, pos - prev);
50 if (this_string == "") {
51 prev = pos + 2;
52 break;
53 }
54
55 if (boost::starts_with(this_string, "Content-Length: ")) {
56 content_length = boost::lexical_cast<int>(this_string.substr(16));
57 // TODO(ed) This is an unfortunate test, but it's all we have at this
58 // point
59 // Realistically, the index.html will be more than 500 bytes. This
60 // test will need to be improved at some point
61 EXPECT_GT(content_length, 500);
62 }
63 if (boost::starts_with(this_string, "Content-Encoding: ")) {
64 content_encoding = this_string.substr(18);
65 }
66
67 headers.push_back(this_string);
68 prev = pos + 2;
69 }
70
71 auto http_content = response.substr(prev);
72 // TODO(ed) ideally the server should support non-compressed gzip assets.
73 // Once this
74 // occurs, this line will be obsolete
75 std::string ungziped_content = http_content;
76 if (content_encoding == "gzip") {
77 EXPECT_TRUE(gzipInflate(http_content, ungziped_content));
78 }
79
80 EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
81 EXPECT_THAT(headers,
82 ::testing::Contains("Content-Type: text/html;charset=UTF-8"));
83
84 EXPECT_EQ(ungziped_content.substr(0, 21), "<!DOCTYPE html>\n<html");
85
86 server.stop();
87}
88
Ed Tanousb4a7bfa2017-04-04 17:23:00 -070089// Tests static files are loaded correctly
90TEST(Webassets, EtagIsSane) {
91 std::array<char, 2048> buf;
92 SimpleApp app;
93 webassets::request_routes(app);
94 Server<SimpleApp> server(&app, "127.0.0.1", 45451);
95 auto _ = async(launch::async, [&] { server.run(); });
96
97 // Get the homepage
98 std::string sendmsg = "GET /\r\n\r\n";
99
100 asio::io_service is;
101
102 asio::ip::tcp::socket c(is);
103 c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"),
104 45451));
105
106 c.send(asio::buffer(sendmsg));
107
108 c.receive(asio::buffer(buf, 2048));
109 c.close();
110
111 std::string response(std::begin(buf), std::end(buf));
112 // This is a routine to split strings until a newline is hit
113 // TODO(ed) this should really use the HTTP parser
114 std::vector<std::string> headers;
115 std::string::size_type pos = 0;
116 std::string::size_type prev = 0;
117 int content_length = 0;
118 std::string content_encoding("");
119 while ((pos = response.find("\r\n", prev)) != std::string::npos) {
120 auto this_string = response.substr(prev, pos - prev);
121 if (this_string == "") {
Ed Tanousb4a7bfa2017-04-04 17:23:00 -0700122 break;
123 }
124
125 if (boost::starts_with(this_string, "ETag: ")) {
126 auto etag = this_string.substr(6);
127 // ETAG should not be blank
128 EXPECT_NE(etag, "");
129 // SHa1 is 20 characters long
130 EXPECT_EQ(etag.size(), 40);
131 EXPECT_THAT(etag, MatchesRegex("^[a-f0-9]+$"));
132 }
133
134 headers.push_back(this_string);
135 prev = pos + 2;
136 }
137
138 server.stop();
139}