Merge pull request #725 from kiwix/safer_testing_of_html_responses

Safer testing of HTML responses
This commit is contained in:
Kelson 2022-03-18 07:03:02 +01:00 committed by GitHub
commit a5baafd09f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 75 additions and 35 deletions

View File

@ -322,26 +322,63 @@ TEST_F(ServerTest, 404)
EXPECT_EQ(404, zfs1_->GET(url)->status) << "url: " << url; EXPECT_EQ(404, zfs1_->GET(url)->status) << "url: " << url;
} }
class TestContentIn404HtmlResponse namespace TestingOfHtmlResponses
{
struct ExpectedResponseData
{
const std::string bookName, bookTitle, expectedBody;
};
enum ExpectedResponseDataType
{
book_name,
book_title,
expected_body
};
// Operator overloading is used as a means of defining a mini-DSL for
// defining test data in a concise way (see usage in
// TEST_F(ServerTest, 404WithBodyTesting))
ExpectedResponseData operator==(ExpectedResponseDataType t, std::string s)
{
switch (t)
{
case book_name: return ExpectedResponseData{s, "", ""};
case book_title: return ExpectedResponseData{"", s, ""};
case expected_body: return ExpectedResponseData{"", "", s};
default: assert(false); return ExpectedResponseData{};
}
}
std::string selectNonEmpty(const std::string& a, const std::string& b)
{
if ( a.empty() ) return b;
assert(b.empty());
return a;
}
ExpectedResponseData operator&&(const ExpectedResponseData& a,
const ExpectedResponseData& b)
{
return ExpectedResponseData{
selectNonEmpty(a.bookName, b.bookName),
selectNonEmpty(a.bookTitle, b.bookTitle),
selectNonEmpty(a.expectedBody, b.expectedBody)
};
}
class TestContentIn404HtmlResponse : public ExpectedResponseData
{ {
public: public:
TestContentIn404HtmlResponse(const std::string& url, TestContentIn404HtmlResponse(const std::string& url,
const std::string& expectedBody) const ExpectedResponseData& erd)
: url(url) : ExpectedResponseData(erd)
, expectedBody(expectedBody) , url(url)
{} {}
TestContentIn404HtmlResponse(const std::string& url, const std::string url;
const std::string& bookName,
const std::string& bookTitle,
const std::string& expectedBody)
: url(url)
, bookName(bookName)
, bookTitle(bookTitle)
, expectedBody(expectedBody)
{}
const std::string url, bookName, bookTitle, expectedBody;
std::string expectedResponse() const; std::string expectedResponse() const;
@ -445,11 +482,14 @@ std::string TestContentIn404HtmlResponse::taskbarLinks() const
+ R"("><button>&#x1F3B2;</button></a>)"; + R"("><button>&#x1F3B2;</button></a>)";
} }
} // namespace TestingOfHtmlResponses
TEST_F(ServerTest, 404WithBodyTesting) TEST_F(ServerTest, 404WithBodyTesting)
{ {
using namespace TestingOfHtmlResponses;
const std::vector<TestContentIn404HtmlResponse> testData{ const std::vector<TestContentIn404HtmlResponse> testData{
{ /* url */ "/ROOT/random?content=non-existent-book", { /* url */ "/ROOT/random?content=non-existent-book",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
//EOLWHITESPACEMARKER //EOLWHITESPACEMARKER
<p> <p>
@ -458,7 +498,7 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/suggest?content=no-such-book&term=whatever", { /* url */ "/ROOT/suggest?content=no-such-book&term=whatever",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
//EOLWHITESPACEMARKER //EOLWHITESPACEMARKER
<p> <p>
@ -467,7 +507,7 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/catalog/", { /* url */ "/ROOT/catalog/",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/catalog/" was not found on this server. The requested URL "/ROOT/catalog/" was not found on this server.
@ -478,7 +518,7 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/catalog/invalid_endpoint", { /* url */ "/ROOT/catalog/invalid_endpoint",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/catalog/invalid_endpoint" was not found on this server. The requested URL "/ROOT/catalog/invalid_endpoint" was not found on this server.
@ -489,7 +529,7 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/invalid-book/whatever", { /* url */ "/ROOT/invalid-book/whatever",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/invalid-book/whatever" was not found on this server. The requested URL "/ROOT/invalid-book/whatever" was not found on this server.
@ -500,9 +540,9 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/zimfile/invalid-article", { /* url */ "/ROOT/zimfile/invalid-article",
/* book name */ "zimfile", book_name=="zimfile" &&
/* book title */ "Ray Charles", book_title=="Ray Charles" &&
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/zimfile/invalid-article" was not found on this server. The requested URL "/ROOT/zimfile/invalid-article" was not found on this server.
@ -513,7 +553,7 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ R"(/ROOT/"><svg onload=alert(1)>)", { /* url */ R"(/ROOT/"><svg onload=alert(1)>)",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/&quot;&gt;&lt;svg onload=alert(1)&gt;" was not found on this server. The requested URL "/ROOT/&quot;&gt;&lt;svg onload=alert(1)&gt;" was not found on this server.
@ -524,9 +564,9 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ R"(/ROOT/zimfile/"><svg onload=alert(1)>)", { /* url */ R"(/ROOT/zimfile/"><svg onload=alert(1)>)",
/* book name */ "zimfile", book_name=="zimfile" &&
/* book title */ "Ray Charles", book_title=="Ray Charles" &&
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/zimfile/&quot;&gt;&lt;svg onload=alert(1)&gt;" was not found on this server. The requested URL "/ROOT/zimfile/&quot;&gt;&lt;svg onload=alert(1)&gt;" was not found on this server.
@ -537,7 +577,7 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/raw/no-such-book/meta/Title", { /* url */ "/ROOT/raw/no-such-book/meta/Title",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/raw/no-such-book/meta/Title" was not found on this server. The requested URL "/ROOT/raw/no-such-book/meta/Title" was not found on this server.
@ -548,7 +588,7 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/raw/zimfile/XYZ", { /* url */ "/ROOT/raw/zimfile/XYZ",
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/raw/zimfile/XYZ" was not found on this server. The requested URL "/ROOT/raw/zimfile/XYZ" was not found on this server.
@ -559,9 +599,9 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/raw/zimfile/meta/invalid-metadata", { /* url */ "/ROOT/raw/zimfile/meta/invalid-metadata",
/* book name */ "zimfile", book_name=="zimfile" &&
/* book title */ "Ray Charles", book_title=="Ray Charles" &&
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/raw/zimfile/meta/invalid-metadata" was not found on this server. The requested URL "/ROOT/raw/zimfile/meta/invalid-metadata" was not found on this server.
@ -572,9 +612,9 @@ TEST_F(ServerTest, 404WithBodyTesting)
)" }, )" },
{ /* url */ "/ROOT/raw/zimfile/content/invalid-article", { /* url */ "/ROOT/raw/zimfile/content/invalid-article",
/* book name */ "zimfile", book_name=="zimfile" &&
/* book title */ "Ray Charles", book_title=="Ray Charles" &&
/* expected body */ R"( expected_body==R"(
<h1>Not Found</h1> <h1>Not Found</h1>
<p> <p>
The requested URL "/ROOT/raw/zimfile/content/invalid-article" was not found on this server. The requested URL "/ROOT/raw/zimfile/content/invalid-article" was not found on this server.