package net.thucydides.core.reports.html;
import com.google.common.collect.ImmutableList;
import net.thucydides.core.issues.IssueTracking;
import net.thucydides.core.model.NumericalFormatter;
import net.thucydides.core.util.EnvironmentVariables;
import net.thucydides.core.util.MockEnvironmentVariables;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
import java.util.Locale;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class WhenFormattingForHTML {
private Locale currentLocale;
@Mock
IssueTracking issueTracking;
@Before
public void prepareFormatter() {
MockitoAnnotations.initMocks(this);
currentLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
}
@After
public void after() {
Locale.setDefault(currentLocale);
}
@Test
public void should_include_issue_tracking_link_using_a_shortened_url() {
when(issueTracking.getIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MY-PROJECT/browse/{0}");
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MY-PROJECT/browse/ISSUE-{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("Fixes issue #123");
assertThat(formattedValue, is("Fixes issue <a target=\"_blank\" href=\"http://my.issue.tracker/MY-PROJECT/browse/ISSUE-123\">#123</a>"));
}
@Test
public void should_include_issue_tracking_link_using_a_full_url() {
when(issueTracking.getIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MY-PROJECT/browse/{0}");
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MY-PROJECT/browse/ISSUE-{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("Fixes issue ISSUE-123");
assertThat(formattedValue, is("Fixes issue <a target=\"_blank\" href=\"http://my.issue.tracker/MY-PROJECT/browse/ISSUE-123\">ISSUE-123</a>"));
}
@Test
public void should_include_issue_tracking_link_for_both_full_and_shortened_ids() {
when(issueTracking.getIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MY-PROJECT/browse/{0}");
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MY-PROJECT/browse/MYPROJECT-{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("Fixes issue #1 and MYPROJECT-2");
assertThat(formattedValue, is("Fixes issue <a target=\"_blank\" href=\"http://my.issue.tracker/MY-PROJECT/browse/MYPROJECT-1\">#1</a> and <a target=\"_blank\" href=\"http://my.issue.tracker/MY-PROJECT/browse/MYPROJECT-2\">MYPROJECT-2</a>"));
}
@Test
public void should_include_multiple_issue_tracking_links() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MY-PROJECT/browse/ISSUE-{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("A scenario with about issues #123 and #456");
assertThat(formattedValue, is("A scenario with about issues <a target=\"_blank\" href=\"http://my.issue.tracker/MY-PROJECT/browse/ISSUE-123\">#123</a> and <a target=\"_blank\" href=\"http://my.issue.tracker/MY-PROJECT/browse/ISSUE-456\">#456</a>"));
}
@Test
public void should_allow_letters_and_numbers_in_issue_number() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MYPROJECT/browse/{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("A big story (#MYPROJECT-123,#MYPROJECT-456)");
assertThat(formattedValue, is("A big story (<a target=\"_blank\" href=\"http://my.issue.tracker/MYPROJECT/browse/MYPROJECT-123\">#MYPROJECT-123</a>,<a target=\"_blank\" href=\"http://my.issue.tracker/MYPROJECT/browse/MYPROJECT-456\">#MYPROJECT-456</a>)"));
}
@Test
public void should_allow_overlapping_issue_number() {
IssueTracking issueTracking = mock(IssueTracking.class);
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MYPROJECT/browse/{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("A big story (#MYPROJECT-12,#MYPROJECT-123,#MYPROJECT-1)");
assertThat(formattedValue, containsString("http://my.issue.tracker/MYPROJECT/browse/MYPROJECT-1"));
assertThat(formattedValue, containsString("http://my.issue.tracker/MYPROJECT/browse/MYPROJECT-12"));
assertThat(formattedValue, containsString("http://my.issue.tracker/MYPROJECT/browse/MYPROJECT-123"));
}
@Test
public void should_allow_dashes_in_issue_number() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MYPROJECT/browse/{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("A big story (#MY-PROJECT-123,#MY-PROJECT-456)");
assertThat(formattedValue, is("A big story (<a target=\"_blank\" href=\"http://my.issue.tracker/MYPROJECT/browse/MY-PROJECT-123\">#MY-PROJECT-123</a>,<a target=\"_blank\" href=\"http://my.issue.tracker/MYPROJECT/browse/MY-PROJECT-456\">#MY-PROJECT-456</a>)"));
}
@Test
public void should_allow_underscores_in_issue_number() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn("http://my.issue.tracker/MYPROJECT/browse/{0}");
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("A big story (#MY_PROJECT_123,#MY_PROJECT_456)");
assertThat(formattedValue, is("A big story (<a target=\"_blank\" href=\"http://my.issue.tracker/MYPROJECT/browse/MY_PROJECT_123\">#MY_PROJECT_123</a>,<a target=\"_blank\" href=\"http://my.issue.tracker/MYPROJECT/browse/MY_PROJECT_456\">#MY_PROJECT_456</a>)"));
}
@Test
public void formatter_should_render_asciidoc() {
Formatter formatter = new Formatter(issueTracking);
String formatted = formatter.renderAsciidoc("a quick *brown* fox");
assertThat(formatted, is("a quick <strong>brown</strong> fox"));
}
@Test
public void formatter_should_render_multiline_asciidoc() {
Formatter formatter = new Formatter(issueTracking);
String formatted = formatter.renderAsciidoc("a quick *brown* fox\njumped over a log");
assertThat(formatted, is("a quick <strong>brown</strong> fox<br>jumped over a log"));
}
@Test
public void formatter_should_render_asciidoc_if_configured() {
EnvironmentVariables environmentVariables = new MockEnvironmentVariables();
environmentVariables.setProperty("narrative.format","asciidoc");
Formatter formatter = new Formatter(issueTracking, environmentVariables);
String formatted = formatter.renderDescription("a quick *brown* fox\njumped over a log");
assertThat(formatted, is("a quick <strong>brown</strong> fox<br>jumped over a log"));
}
@Test
public void formatter_should_not_render_asciidoc_not_if_configured() {
EnvironmentVariables environmentVariables = new MockEnvironmentVariables();
Formatter formatter = new Formatter(issueTracking, environmentVariables);
String formatted = formatter.renderDescription("a quick *brown* fox\njumped over a log");
assertThat(formatted, is("a quick *brown* fox<br>jumped over a log"));
}
private final String htmlDescription = "<h2><a name=\"ScenarioDosometests\"></a>Scenario Do some tests</h2>\n"+
"<p><b>Given</b> we want to test some stuff<br/>\n"+
"<b>When</b> we do some tests<br/>\n"+
"<b>Then</b> the stuff should be tested<br/>\n"+
"<b>Examples</b></p>\n"+
"<table class='confluenceTable'><tbody>\n"+
"<tr>\n"+
"<td class='confluenceTd'> test </td>\n"+
"<td class='confluenceTd'> expected </td>\n"+
"</tr>\n"+
"<tr>\n"+
"<td class='confluenceTd'> Test 1 </td>\n"+
"<td class='confluenceTd'> success </td>\n"+
"</tr>\n"+
"<tr>\n"+
"<td class='confluenceTd'> Test 2 </td>\n"+
"<td class='confluenceTd'> failure </td>\n"+
"</tr>\n"+
"</tbody></table>\n";
@Test
public void formatter_should_leave_rendered_html_as_is() {
EnvironmentVariables environmentVariables = new MockEnvironmentVariables();
Formatter formatter = new Formatter(issueTracking, environmentVariables);
String formatted = formatter.renderDescription(htmlDescription);
assertThat(formatted, is(htmlDescription));
}
@Test
public void should_identify_issues_in_a_text() {
List<String> issues = Formatter.shortenedIssuesIn("A scenario about issue #123");
assertThat(issues, hasItem("#123"));
}
@Test
public void should_identify_multiple_issues_in_a_text() {
List<String> issues = Formatter.shortenedIssuesIn("A scenario about issue #123,#456, #789");
assertThat(issues, hasItems("#123", "#456", "#789"));
}
@Test
public void should_not_format_issues_if_no_issue_manage_url_is_provided() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("A scenario with about issues #123 and #456");
assertThat(formattedValue, is("A scenario with about issues #123 and #456"));
}
@Test
public void should_not_format_issues_if_the_issue_manage_url_is_empty() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.addLinks("A scenario with about issues #123 and #456");
assertThat(formattedValue, is("A scenario with about issues #123 and #456"));
}
@Test
public void should_insert_line_breaks_into_text_values() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.htmlCompatible("Line one\nLine two\nLine three");
assertThat(formattedValue, is("Line one<br>Line two<br>Line three"));
}
@Test
public void should_convert_text_tables_into_html_tables() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.convertAnyTables("| name | age |\n|Bill|20|");
assertThat(formattedValue, is("<table class='embedded'><thead><th>name</th><th>age</th></thead><tbody><tr><td>Bill</td><td>20</td></tr></tbody></table>"));
}
@Test
public void should_convert_embedded_text_tables_into_html_tables() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.convertAnyTables("A table:\n| name | age |\n|Bill|20|");
assertThat(formattedValue, is("A table:<br><table class='embedded'><thead><th>name</th><th>age</th></thead><tbody><tr><td>Bill</td><td>20</td></tr></tbody></table>"));
}
@Test
public void should_convert_embedded_text_tables__with_square_brackets_into_html_tables() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.convertAnyTables("A table:\n[| name | age |\n|Bill|20|]");
assertThat(formattedValue, is("A table:<br><table class='embedded'><thead><th>name</th><th>age</th></thead><tbody><tr><td>Bill</td><td>20</td></tr></tbody></table>"));
}
@Test
public void should_ignore_isolated_pipes() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.convertAnyTables("Not a table: | that was a pipe");
assertThat(formattedValue, is("Not a table: | that was a pipe"));
}
@Test
public void should_return_empty_string_when_inserting_line_breaks_into_a_null_value() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.htmlCompatible(null);
assertThat(formattedValue, is(""));
}
@Test
public void should_insert_line_breaks_into_text_values_with_windows_line_breaks() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.htmlCompatible("Line one\r\nLine two\r\nLine three");
assertThat(formattedValue, is("Line one<br>Line two<br>Line three"));
}
@Test
public void should_not_escape_html_tags() {
when(issueTracking.getShortenedIssueTrackerUrl()).thenReturn(null);
Formatter formatter = new Formatter(issueTracking);
String formattedValue = formatter.htmlCompatible("<ul style='margin-left:5%'><li>Line one</li><li>Line two</li><li>Line three</li></ul>");
assertThat(formattedValue, is("<ul style='margin-left:5%'><li>Line one</li><li>Line two</li><li>Line three</li></ul>"));
}
@Test
public void should_escape_table_fields() {
Formatter formatter = new Formatter(issueTracking);
List<String> fields = ImmutableList.of("name","age");
String formattedValue = formatter.formatWithFields("Given a person named <name>\nand aged <age>", fields);
assertThat(formattedValue, is("Given a person named <name><br>and aged <age>"));
}
@Test
public void formatter_should_round_doubles_to_a_given_precision() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.rounded(1.234,1), is("1.2"));
}
@Test
public void formatter_should_round_doubles_to_zero_precision_if_required() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.rounded(1.234,0), is("1"));
}
@Test
public void formatter_should_round_doubles_up_to_zero_precision_if_required() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.rounded(1.634,0), is("2"));
}
@Test
public void formatter_should_round_doubles_up() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.rounded(1.678,1), is("1.7"));
}
@Test
public void formatter_should_drop_training_zeros() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.rounded(1.0,2), is("1"));
}
@Test
public void formatter_should_round_percentages_to_a_given_precision() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.percentage(0.1234,1), is("12.3%"));
}
@Test
public void formatter_should_round_percentages_to_zero_precision_if_required() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.percentage(0.1234,0), is("12%"));
}
@Test
public void formatter_should_round_percentages_up_to_zero_precision_if_required() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.percentage(0.1254,0), is("13%"));
}
@Test
public void formatter_should_round_percentages_up() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.percentage(0.16789, 1), is("16.8%"));
}
@Test
public void formatter_should_drop_training_zeros_for_percentages() {
NumericalFormatter formatter = new NumericalFormatter();
assertThat(formatter.percentage(0.5, 1), is("50%"));
}
}