diff --git a/src/webassets_test.cpp b/src/webassets_test.cpp
new file mode 100644
index 0000000..2157f03
--- /dev/null
+++ b/src/webassets_test.cpp
@@ -0,0 +1,207 @@
+#include <crow/app.h>
+#include <gmock/gmock.h>
+#include <zlib.h>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/iostreams/copy.hpp>
+#include <boost/iostreams/filter/gzip.hpp>
+#include <boost/iostreams/filtering_streambuf.hpp>
+#include <boost/lexical_cast.hpp>
+#include <sstream>
+#include <webassets.hpp>
+#include "gtest/gtest.h"
+using namespace crow;
+using namespace std;
+using namespace testing;
+
+bool gzipInflate(const std::string& compressedBytes,
+                 std::string& uncompressedBytes) {
+  if (compressedBytes.size() == 0) {
+    uncompressedBytes = compressedBytes;
+    return true;
+  }
+
+  uncompressedBytes.clear();
+
+  unsigned full_length = compressedBytes.size();
+  unsigned half_length = compressedBytes.size() / 2;
+
+  unsigned uncompLength = full_length;
+  char* uncomp = (char*)calloc(sizeof(char), uncompLength);
+
+  z_stream strm;
+  strm.next_in = (Bytef*)compressedBytes.c_str();
+  strm.avail_in = compressedBytes.size();
+  strm.total_out = 0;
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+
+  bool done = false;
+
+  if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
+    free(uncomp);
+    return false;
+  }
+
+  while (!done) {
+    // If our output buffer is too small
+    if (strm.total_out >= uncompLength) {
+      // Increase size of output buffer
+      char* uncomp2 = (char*)calloc(sizeof(char), uncompLength + half_length);
+      memcpy(uncomp2, uncomp, uncompLength);
+      uncompLength += half_length;
+      free(uncomp);
+      uncomp = uncomp2;
+    }
+
+    strm.next_out = (Bytef*)(uncomp + strm.total_out);
+    strm.avail_out = uncompLength - strm.total_out;
+
+    // Inflate another chunk.
+    int err = inflate(&strm, Z_SYNC_FLUSH);
+    if (err == Z_STREAM_END)
+      done = true;
+    else if (err != Z_OK) {
+      break;
+    }
+  }
+
+  if (inflateEnd(&strm) != Z_OK) {
+    free(uncomp);
+    return false;
+  }
+
+  for (size_t i = 0; i < strm.total_out; ++i) {
+    uncompressedBytes += uncomp[i];
+  }
+  free(uncomp);
+  return true;
+}
+
+
+
+
+// Tests static files are loaded correctly
+TEST(Webassets, StaticFilesFixedRoutes) {
+  std::array<char, 2048> buf;
+  SimpleApp app;
+  webassets::request_routes(app);
+  Server<SimpleApp> server(&app, "127.0.0.1", 45451);
+  auto _ = async(launch::async, [&] { server.run(); });
+
+  // Get the homepage
+  std::string sendmsg = "GET /\r\n\r\n";
+
+  asio::io_service is;
+
+  asio::ip::tcp::socket c(is);
+  c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"),
+                                    45451));
+
+  c.send(asio::buffer(sendmsg));
+
+  c.receive(asio::buffer(buf, 2048));
+  c.close();
+
+  std::string response(std::begin(buf), std::end(buf));
+  // This is a routine to split strings until a newline is hit
+  // TODO(ed) this should really use the HTTP parser
+  std::vector<std::string> headers;
+  std::string::size_type pos = 0;
+  std::string::size_type prev = 0;
+  int content_length = 0;
+  std::string content_encoding("");
+  while ((pos = response.find("\r\n", prev)) != std::string::npos) {
+    auto this_string = response.substr(prev, pos - prev);
+    if (this_string == "") {
+      prev = pos + 2;
+      break;
+    }
+
+    if (boost::starts_with(this_string, "Content-Length: ")) {
+      content_length = boost::lexical_cast<int>(this_string.substr(16));
+      // TODO(ed) This is an unfortunate test, but it's all we have at this
+      // point
+      // Realistically, the index.html will be more than 500 bytes.  This
+      // test will need to be improved at some point
+      EXPECT_GT(content_length, 500);
+    }
+    if (boost::starts_with(this_string, "Content-Encoding: ")) {
+      content_encoding = this_string.substr(18);
+    }
+
+    headers.push_back(this_string);
+    prev = pos + 2;
+  }
+
+  auto http_content = response.substr(prev);
+  // TODO(ed) ideally the server should support non-compressed gzip assets.
+  // Once this
+  // occurs, this line will be obsolete
+  std::string ungziped_content = http_content;
+  if (content_encoding == "gzip") {
+    EXPECT_TRUE(gzipInflate(http_content, ungziped_content));
+  }
+
+  EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
+  EXPECT_THAT(headers,
+              ::testing::Contains("Content-Type: text/html;charset=UTF-8"));
+
+  EXPECT_EQ(ungziped_content.substr(0, 21), "<!DOCTYPE html>\n<html");
+
+  server.stop();
+}
+
+
+
+// Tests static files are loaded correctly
+TEST(Webassets, EtagIsSane) {
+  std::array<char, 2048> buf;
+  SimpleApp app;
+  webassets::request_routes(app);
+  Server<SimpleApp> server(&app, "127.0.0.1", 45451);
+  auto _ = async(launch::async, [&] { server.run(); });
+
+  // Get the homepage
+  std::string sendmsg = "GET /\r\n\r\n";
+
+  asio::io_service is;
+
+  asio::ip::tcp::socket c(is);
+  c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"),
+                                    45451));
+
+  c.send(asio::buffer(sendmsg));
+
+  c.receive(asio::buffer(buf, 2048));
+  c.close();
+
+  std::string response(std::begin(buf), std::end(buf));
+  // This is a routine to split strings until a newline is hit
+  // TODO(ed) this should really use the HTTP parser
+  std::vector<std::string> headers;
+  std::string::size_type pos = 0;
+  std::string::size_type prev = 0;
+  int content_length = 0;
+  std::string content_encoding("");
+  while ((pos = response.find("\r\n", prev)) != std::string::npos) {
+    auto this_string = response.substr(prev, pos - prev);
+    if (this_string == "") {
+      prev = pos + 2;
+      break;
+    }
+
+    if (boost::starts_with(this_string, "ETag: ")) {
+      auto etag = this_string.substr(6);
+      // ETAG should not be blank
+      EXPECT_NE(etag, "");
+      // SHa1 is 20 characters long
+      EXPECT_EQ(etag.size(), 40);
+      EXPECT_THAT(etag, MatchesRegex("^[a-f0-9]+$"));
+    }
+
+    headers.push_back(this_string);
+    prev = pos + 2;
+  }
+
+  server.stop();
+}
\ No newline at end of file
