Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions src/test/java/org/takes/tk/TkHtmlEmptyTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2014-2025 Yegor Bugayenko
* SPDX-License-Identifier: MIT
*/
package org.takes.tk;

import org.cactoos.io.InputStreamOf;
import org.cactoos.text.Joined;
import org.hamcrest.MatcherAssert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.llorllale.cactoos.matchers.IsText;
import org.takes.rq.RqFake;
import org.takes.rs.RsPrint;

/**
* Test case for {@link TkHtml with empty body}.
* @since 0.10
*/
final class TkHtmlEmptyTest {

@Test
@DisplayName("Throw IllegalStateException when string body is null")
void failsOnNullInputString() {
final String body = null;
Assertions.assertThrows(
IllegalStateException.class,
() -> {
MatcherAssert.assertThat(
"Must reject null string body",
new RsPrint(new TkHtml(body).act(new RqFake())),
this.textMatcher(body)
);
}
);
}

@Test
@DisplayName("Create valid HTTP response with empty body from empty string")
void createsEmptyTextResponseFromEmptyString() throws Exception {
final String body = "";
MatcherAssert.assertThat(
"TkHtml must create valid HTTP response from empty string",
new RsPrint(new TkHtml(body).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Throw IllegalStateException when scalar supplier returns null")
void failsOnNullInputScalar() {
final String body = null;
Assertions.assertThrows(
IllegalStateException.class,
() -> {
MatcherAssert.assertThat(
"Must reject null scalar body",
new RsPrint(new TkHtml(() -> body).act(new RqFake())),
this.textMatcher(body)
);
}
);
}

@Test
@DisplayName("Create valid HTTP response with empty body from empty scalar supplier")
void createsEmptyResponseFromEmptyScalar() throws Exception {
final String body = "";
MatcherAssert.assertThat(
"TkHtml must create valid HTTP response from empty scalar",
new RsPrint(new TkHtml(() -> body).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Throw NullPointerException when byte array is null")
void failsOnNullInputByteArray() {
final String body = null;
Assertions.assertThrows(
NullPointerException.class,
() -> {
MatcherAssert.assertThat(
"Must reject null byte array body",
new RsPrint(new TkHtml(body.getBytes()).act(new RqFake())),
this.textMatcher(body)
);
}
);
}

@Test
@DisplayName("Create valid HTTP response with empty body from empty byte array")
void createsEmptyResponseFromEmptyByteArray() throws Exception {
final String body = "";
MatcherAssert.assertThat(
"TkHtml must handle empty byte arrays correctly",
new RsPrint(new TkHtml(body.getBytes()).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Throw NullPointerException when input stream is null")
void failsOnNullInputStream() {
final String body = null;
Assertions.assertThrows(
NullPointerException.class,
() -> {
MatcherAssert.assertThat(
"Must reject null input stream body",
new RsPrint(new TkHtml(new InputStreamOf(body)).act(new RqFake())),
this.textMatcher(body)
);
}
);
}

@Test
@DisplayName("Create valid HTTP response with empty body from empty input stream")
void createsEmptyResponseFromEmptyInputStream() throws Exception {
final String body = "";
MatcherAssert.assertThat(
"TkHtml must create valid HTTP response from empty input stream",
new RsPrint(new TkHtml(new InputStreamOf(body)).act(new RqFake())),
this.textMatcher(body)
);
}

/**
* Creates text matcher for HTML response.
* @param body Response body
* @return Text matcher
*/
private IsText textMatcher(final String body) {
return new IsText(
new Joined(
"\r\n",
"HTTP/1.1 200 OK",
String.format("Content-Length: %s", body.getBytes().length),
"Content-Type: text/html",
"",
body
)
);
}
}
137 changes: 87 additions & 50 deletions src/test/java/org/takes/tk/TkHtmlTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import org.cactoos.io.InputStreamOf;
import org.cactoos.text.Joined;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.llorllale.cactoos.matchers.HasString;
import org.llorllale.cactoos.matchers.IsText;
Expand All @@ -21,95 +23,130 @@
final class TkHtmlTest {

@Test
void createsTextResponse() throws Exception {
@DisplayName("Create proper HTML response with valid HTML content from string")
void createsTextResponseFromInputString() throws Exception {
final String body = "<html>hello, world!</html>";
MatcherAssert.assertThat(
"TkHtml must create proper HTML response from string",
new RsPrint(new TkHtml(body).act(new RqFake())),
new IsText(
new Joined(
"\r\n",
"HTTP/1.1 200 OK",
String.format("Content-Length: %s", body.length()),
"Content-Type: text/html",
"",
body
)
)
new RsPrint(new TkHtml(body).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Create proper HTML response from scalar supplier with valid content")
void createsTextResponseFromScalar() throws Exception {
final String body = "<html>hello, world!</html>";
MatcherAssert.assertThat(
"TkHtml must create proper HTML response from scalar supplier",
new RsPrint(new TkHtml(() -> body).act(new RqFake())),
new IsText(
new Joined(
"\r\n",
"HTTP/1.1 200 OK",
String.format("Content-Length: %s", body.length()),
"Content-Type: text/html",
"",
body
)
)
new RsPrint(new TkHtml(() -> body).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Create proper HTML response from byte array with valid content")
void createsTextResponseFromByteArray() throws Exception {
final String body = "<html>hello, world!</html>";
MatcherAssert.assertThat(
"TkHtml must create proper HTML response from byte array",
new RsPrint(new TkHtml(body.getBytes()).act(new RqFake())),
new IsText(
new Joined(
"\r\n",
"HTTP/1.1 200 OK",
String.format("Content-Length: %s", body.length()),
"Content-Type: text/html",
"",
body
)
)
"TkHtml must create valid HTTP response from empty byte array",
new RsPrint(new TkHtml(body.getBytes()).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Create proper HTML response from input stream with valid content")
void createsTextResponseFromInputStream() throws Exception {
final String body = "<html>hello, world!</html>";
MatcherAssert.assertThat(
"TkHtml must create proper HTML response from input stream",
new RsPrint(new TkHtml(new InputStreamOf(body)).act(new RqFake())),
new IsText(
new Joined(
"\r\n",
"HTTP/1.1 200 OK",
String.format("Content-Length: %s", body.length()),
"Content-Type: text/html",
"",
body
)
)
new RsPrint(new TkHtml(new InputStreamOf(body)).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Produce consistent responses when same instance is used multiple times")
void printsResourceMultipleTimes() throws Exception {
final String body = "<html>hello, dude!</html>";
final Take take = new TkHtml(body);
MatcherAssert.assertThat(
"First HTML response must contain the expected body text",
new RsPrint(take.act(new RqFake())),
new HasString(body)
new RsPrint(take.act(new RqFake())),
new HasString(body)
);
MatcherAssert.assertThat(
"Second HTML response must also contain the expected body text",
new RsPrint(take.act(new RqFake())),
new HasString(body)
new RsPrint(take.act(new RqFake())),
new HasString(body)
);
}

@Test
@DisplayName("Text HTML body starts with <html> tag")
void textResponseHtmlStartsWithHtmlTag() throws Exception {
final String body = "<html><body>Hello World</body></html>";
MatcherAssert.assertThat(
"HTML response must start with <html> tag",
new RsPrint(new TkHtml(body).act(new RqFake()))
.printBody().trim().startsWith("<html>"),
Matchers.is(true)
);
}

@Test
@DisplayName("Text HTML body ends with </html> tag")
void textResponseHtmlEndsWithHtmlTag() throws Exception {
final String body = "<html><body>Hello World</body></html>";
MatcherAssert.assertThat(
"HTML response must end with </html> tag",
new RsPrint(new TkHtml(body).act(new RqFake()))
.printBody().trim().endsWith("</html>"),
Matchers.is(true)
);
}

@Test
@DisplayName("Complete text HTML document with head and body")
void acceptsCompleteHtmlDocument() throws Exception {
final String body = "<html><head><title>Test</title></head><body>Content</body></html>";
MatcherAssert.assertThat(
"TkHtml must accept complete HTML document structure",
new RsPrint(new TkHtml(body).act(new RqFake())),
this.textMatcher(body)
);
}

@Test
@DisplayName("Text HTML structure with proper nesting")
void validatesHtmlStructureWithNesting() throws Exception {
final String body = "<html><body><div><p>Nested content</p></div></body></html>";
final String response = new RsPrint(new TkHtml(body).act(new RqFake())).printBody();
MatcherAssert.assertThat(
"HTML response must start with <html> tag",
response.indexOf("<html>") < response.indexOf("<body>")
&& response.indexOf("<body>") < response.indexOf("</body>")
&& response.indexOf("</body>") < response.indexOf("</html>"),
Matchers.is(true)
);
}

/**
* Creates text matcher for HTML response.
* @param body Response body
* @return Text matcher
*/
private IsText textMatcher(final String body) {
return new IsText(
new Joined(
"\r\n",
"HTTP/1.1 200 OK",
String.format("Content-Length: %s", body.getBytes().length),
"Content-Type: text/html",
"",
body
)
);
}
}
Loading