Clean up URI parsing code and tests
This commit is contained in:
parent
0d3d9aab32
commit
0f9bc4867a
8 changed files with 370 additions and 292 deletions
|
@ -5,9 +5,6 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses and "linkifies" bitcoin links.
|
|
||||||
*/
|
|
||||||
class BitcoinUriParser implements UriParser {
|
class BitcoinUriParser implements UriParser {
|
||||||
private static final Pattern BITCOIN_URI_PATTERN =
|
private static final Pattern BITCOIN_URI_PATTERN =
|
||||||
Pattern.compile("bitcoin:[1-9a-km-zA-HJ-NP-Z]{27,34}(\\?[a-zA-Z0-9$\\-_.+!*'(),%:@&=]*)?");
|
Pattern.compile("bitcoin:[1-9a-km-zA-HJ-NP-Z]{27,34}(\\?[a-zA-Z0-9$\\-_.+!*'(),%:@&=]*)?");
|
||||||
|
@ -16,7 +13,6 @@ class BitcoinUriParser implements UriParser {
|
||||||
public int linkifyUri(String text, int startPos, StringBuffer outputBuffer) {
|
public int linkifyUri(String text, int startPos, StringBuffer outputBuffer) {
|
||||||
Matcher matcher = BITCOIN_URI_PATTERN.matcher(text);
|
Matcher matcher = BITCOIN_URI_PATTERN.matcher(text);
|
||||||
|
|
||||||
// Skip not matching uris
|
|
||||||
if (!matcher.find(startPos) || matcher.start() != startPos) {
|
if (!matcher.find(startPos) || matcher.start() != startPos) {
|
||||||
return startPos;
|
return startPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,10 @@ import java.util.regex.Pattern;
|
||||||
/**
|
/**
|
||||||
* Parses and "linkifies" http links.
|
* Parses and "linkifies" http links.
|
||||||
* <p>
|
* <p>
|
||||||
* This class is in parts inspired by OkHttp's HttpUrl (https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/HttpUrl.java),s
|
* This class is in parts inspired by OkHttp's
|
||||||
* but leaving out much of the parsing part.
|
* <a href="https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/HttpUrl.java">HttpUrl</a>.
|
||||||
|
* But much of the parsing parts have been left out.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
class HttpUriParser implements UriParser {
|
class HttpUriParser implements UriParser {
|
||||||
// This string represent character group sub-delim as described in RFC 3986
|
// This string represent character group sub-delim as described in RFC 3986
|
||||||
|
@ -19,11 +21,12 @@ class HttpUriParser implements UriParser {
|
||||||
private static final Pattern IPv4_PATTERN =
|
private static final Pattern IPv4_PATTERN =
|
||||||
Pattern.compile("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})(:(\\d{0,5}))?");
|
Pattern.compile("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})(:(\\d{0,5}))?");
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int linkifyUri(String text, int startPos, StringBuffer outputBuffer) {
|
public int linkifyUri(String text, int startPos, StringBuffer outputBuffer) {
|
||||||
int currentPos = startPos;
|
int currentPos = startPos;
|
||||||
|
|
||||||
// Test scheme
|
// Scheme
|
||||||
String shortScheme = text.substring(currentPos, Math.min(currentPos + 7, text.length()));
|
String shortScheme = text.substring(currentPos, Math.min(currentPos + 7, text.length()));
|
||||||
String longScheme = text.substring(currentPos, Math.min(currentPos + 8, text.length()));
|
String longScheme = text.substring(currentPos, Math.min(currentPos + 8, text.length()));
|
||||||
if (shortScheme.equalsIgnoreCase("https://")) {
|
if (shortScheme.equalsIgnoreCase("https://")) {
|
||||||
|
@ -33,20 +36,17 @@ class HttpUriParser implements UriParser {
|
||||||
} else if (longScheme.equalsIgnoreCase("rtsp://")) {
|
} else if (longScheme.equalsIgnoreCase("rtsp://")) {
|
||||||
currentPos += "rtsp://".length();
|
currentPos += "rtsp://".length();
|
||||||
} else {
|
} else {
|
||||||
// Unsupported scheme
|
|
||||||
return startPos;
|
return startPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test authority
|
// Authority
|
||||||
int authorityEnd = text.indexOf('/', currentPos);
|
int authorityEnd = text.indexOf('/', currentPos);
|
||||||
if (authorityEnd == -1) {
|
if (authorityEnd == -1) {
|
||||||
authorityEnd = text.length();
|
authorityEnd = text.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authority: Take a look at user info if available
|
|
||||||
currentPos = matchUserInfoIfAvailable(text, currentPos, authorityEnd);
|
currentPos = matchUserInfoIfAvailable(text, currentPos, authorityEnd);
|
||||||
|
|
||||||
// Authority: Take a look at host
|
|
||||||
if (!tryMatchDomainName(text, currentPos, authorityEnd) &&
|
if (!tryMatchDomainName(text, currentPos, authorityEnd) &&
|
||||||
!tryMatchIpv4Address(text, currentPos, authorityEnd, true) &&
|
!tryMatchIpv4Address(text, currentPos, authorityEnd, true) &&
|
||||||
!tryMatchIpv6Address(text, currentPos, authorityEnd)) {
|
!tryMatchIpv6Address(text, currentPos, authorityEnd)) {
|
||||||
|
@ -54,24 +54,27 @@ class HttpUriParser implements UriParser {
|
||||||
}
|
}
|
||||||
currentPos = authorityEnd;
|
currentPos = authorityEnd;
|
||||||
|
|
||||||
// Test path
|
// Path
|
||||||
if (currentPos < text.length() && text.charAt(currentPos) == '/') {
|
if (currentPos < text.length() && text.charAt(currentPos) == '/') {
|
||||||
currentPos = matchUnreservedPCTEncodedSubDelimClassesGreedy(text, currentPos + 1, "/:@");
|
currentPos = matchUnreservedPCTEncodedSubDelimClassesGreedy(text, currentPos + 1, "/:@");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for query
|
// Query
|
||||||
if (currentPos < text.length() && text.charAt(currentPos) == '?') {
|
if (currentPos < text.length() && text.charAt(currentPos) == '?') {
|
||||||
currentPos = matchUnreservedPCTEncodedSubDelimClassesGreedy(text, currentPos + 1, ":@/?");
|
currentPos = matchUnreservedPCTEncodedSubDelimClassesGreedy(text, currentPos + 1, ":@/?");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for fragment.
|
// Fragment
|
||||||
if (currentPos < text.length() && text.charAt(currentPos) == '#') {
|
if (currentPos < text.length() && text.charAt(currentPos) == '#') {
|
||||||
currentPos = matchUnreservedPCTEncodedSubDelimClassesGreedy(text, currentPos + 1, ":@/?");
|
currentPos = matchUnreservedPCTEncodedSubDelimClassesGreedy(text, currentPos + 1, ":@/?");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final link generation
|
String httpUri = text.substring(startPos, currentPos);
|
||||||
String linkifiedUri = String.format("<a href=\"%1$s\">%1$s</a>", text.substring(startPos, currentPos));
|
outputBuffer.append("<a href=\"")
|
||||||
outputBuffer.append(linkifiedUri);
|
.append(httpUri)
|
||||||
|
.append("\">")
|
||||||
|
.append(httpUri)
|
||||||
|
.append("</a>");
|
||||||
|
|
||||||
return currentPos;
|
return currentPos;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +92,7 @@ class HttpUriParser implements UriParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean tryMatchDomainName(String text, int startPos, int authorityEnd) {
|
private boolean tryMatchDomainName(String text, int startPos, int authorityEnd) {
|
||||||
// Partly from OkHttp's HttpUrl (https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/HttpUrl.java)
|
// Partly from OkHttp's HttpUrl
|
||||||
try {
|
try {
|
||||||
// Check for port
|
// Check for port
|
||||||
int portPos = text.indexOf(':', startPos);
|
int portPos = text.indexOf(':', startPos);
|
||||||
|
@ -143,7 +146,6 @@ class HttpUriParser implements UriParser {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate segments
|
|
||||||
for (int i = 1; i <= 4; i++) {
|
for (int i = 1; i <= 4; i++) {
|
||||||
int segment = Integer.parseInt(matcher.group(1));
|
int segment = Integer.parseInt(matcher.group(1));
|
||||||
if (segment > 255) {
|
if (segment > 255) {
|
||||||
|
@ -151,12 +153,10 @@ class HttpUriParser implements UriParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure port does not exist if missing
|
|
||||||
if (!portAllowed && matcher.group(5) != null) {
|
if (!portAllowed && matcher.group(5) != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate optional port
|
|
||||||
String portString = matcher.group(6);
|
String portString = matcher.group(6);
|
||||||
if (portString != null && !portString.isEmpty()) {
|
if (portString != null && !portString.isEmpty()) {
|
||||||
int port = Integer.parseInt(portString);
|
int port = Integer.parseInt(portString);
|
||||||
|
@ -169,7 +169,6 @@ class HttpUriParser implements UriParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean tryMatchIpv6Address(String text, int startPos, int authorityEnd) {
|
private boolean tryMatchIpv6Address(String text, int startPos, int authorityEnd) {
|
||||||
// General validation
|
|
||||||
if (text.codePointAt(startPos) != '[') {
|
if (text.codePointAt(startPos) != '[') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.fsck.k9.message.html;
|
||||||
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -9,13 +10,7 @@ import java.util.regex.Pattern;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows conversion of link in text to html link.
|
|
||||||
*/
|
|
||||||
public class UriLinkifier {
|
public class UriLinkifier {
|
||||||
/**
|
|
||||||
* Regular expression pattern to match uri scheme and parsers for supported uris as defined in RFC 3987
|
|
||||||
*/
|
|
||||||
private static final Pattern URI_SCHEME;
|
private static final Pattern URI_SCHEME;
|
||||||
private static final Map<String, UriParser> SUPPORTED_URIS;
|
private static final Map<String, UriParser> SUPPORTED_URIS;
|
||||||
private static final String SCHEME_SEPARATOR = " (";
|
private static final String SCHEME_SEPARATOR = " (";
|
||||||
|
@ -32,16 +27,8 @@ public class UriLinkifier {
|
||||||
URI_SCHEME = Pattern.compile(allSchemes, Pattern.CASE_INSENSITIVE);
|
URI_SCHEME = Pattern.compile(allSchemes, Pattern.CASE_INSENSITIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches for link-like text in a string and turn it into a link. Append the result to
|
public static void linkifyText(String text, StringBuffer outputBuffer) {
|
||||||
* <tt>outputBuffer</tt>. <tt>text</tt> is not modified.
|
|
||||||
*
|
|
||||||
* @param text
|
|
||||||
* Plain text to be linkified.
|
|
||||||
* @param outputBuffer
|
|
||||||
* Buffer to append linked text to.
|
|
||||||
*/
|
|
||||||
public static void linkifyText(final String text, final StringBuffer outputBuffer) {
|
|
||||||
int currentPos = 0;
|
int currentPos = 0;
|
||||||
Matcher matcher = URI_SCHEME.matcher(text);
|
Matcher matcher = URI_SCHEME.matcher(text);
|
||||||
|
|
||||||
|
@ -51,31 +38,39 @@ public class UriLinkifier {
|
||||||
String textBeforeMatch = text.substring(currentPos, startPos);
|
String textBeforeMatch = text.substring(currentPos, startPos);
|
||||||
outputBuffer.append(textBeforeMatch);
|
outputBuffer.append(textBeforeMatch);
|
||||||
|
|
||||||
if (!textBeforeMatch.isEmpty() &&
|
if (!isPrecededByValidSeparator(textBeforeMatch)) {
|
||||||
!SCHEME_SEPARATOR.contains(textBeforeMatch.substring(textBeforeMatch.length() - 1))) {
|
|
||||||
outputBuffer.append(text.charAt(startPos));
|
outputBuffer.append(text.charAt(startPos));
|
||||||
currentPos = startPos + 1;
|
currentPos = startPos + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find responsible parser and let it do it's job
|
String scheme = matcher.group().toLowerCase(Locale.US);
|
||||||
String scheme = matcher.group();
|
UriParser parser = SUPPORTED_URIS.get(scheme);
|
||||||
UriParser parser = SUPPORTED_URIS.get(scheme.toLowerCase());
|
|
||||||
int newPos = parser.linkifyUri(text, startPos, outputBuffer);
|
int newPos = parser.linkifyUri(text, startPos, outputBuffer);
|
||||||
|
|
||||||
// Handle invalid uri, at least advance by one to prevent endless loop
|
boolean uriWasNotLinkified = newPos <= startPos;
|
||||||
if (newPos <= startPos) {
|
if (uriWasNotLinkified) {
|
||||||
outputBuffer.append(text.charAt(startPos));
|
outputBuffer.append(text.charAt(startPos));
|
||||||
currentPos++;
|
currentPos++;
|
||||||
} else {
|
} else {
|
||||||
currentPos = (newPos > currentPos) ? newPos : currentPos + 1;
|
currentPos = (newPos > currentPos) ? newPos : currentPos + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPos >= text.length()) {
|
if (currentPos >= text.length()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy rest
|
String textAfterLastMatch = text.substring(currentPos);
|
||||||
outputBuffer.append(text.substring(currentPos));
|
outputBuffer.append(textAfterLastMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isPrecededByValidSeparator(String textBeforeMatch) {
|
||||||
|
if (textBeforeMatch.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String characterBeforeMatch = textBeforeMatch.substring(textBeforeMatch.length() - 1);
|
||||||
|
return SCHEME_SEPARATOR.contains(characterBeforeMatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
package com.fsck.k9.message.html;
|
package com.fsck.k9.message.html;
|
||||||
|
|
||||||
/**
|
|
||||||
* General framework to handle uris when parsing. Allows different handling depending on the scheme identifier.
|
|
||||||
*/
|
|
||||||
public interface UriParser {
|
public interface UriParser {
|
||||||
/**
|
/**
|
||||||
* Parse and linkify scheme specific uri beginning from given position. The result will be written to given buffer.
|
* Parse and linkify scheme specific URI beginning from given position. The result will be written to given buffer.
|
||||||
* @param text String to parse uri from.
|
*
|
||||||
* @param startPos Position where uri starts (first letter of scheme).
|
* @param text
|
||||||
* @param outputBuffer Buffer where linkified variant of uri is written to.
|
* String to parse URI from.
|
||||||
* @return Index where parsed uri ends (first non-uri letter). Should be startPos or smaller if no valid uri was found.
|
* @param startPos
|
||||||
|
* Position where URI starts (first letter of scheme).
|
||||||
|
* @param outputBuffer
|
||||||
|
* Buffer where linkified variant of URI is written to.
|
||||||
|
*
|
||||||
|
* @return Index where parsed URI ends (first non-URI letter). Should be {@code startPos} or smaller if no valid
|
||||||
|
* URI was found.
|
||||||
*/
|
*/
|
||||||
int linkifyUri(String text, int startPos, StringBuffer outputBuffer);
|
int linkifyUri(String text, int startPos, StringBuffer outputBuffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.fsck.k9.message.html;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static com.fsck.k9.message.html.UriParserTestHelper.assertLinkOnly;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
public class BitcoinUriParserTest {
|
||||||
|
BitcoinUriParser parser = new BitcoinUriParser();
|
||||||
|
StringBuffer outputBuffer = new StringBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void basicBitcoinUri() throws Exception {
|
||||||
|
assertLinkify("bitcoin:19W6QZkx8SYPG7BBCS7odmWGRxqRph5jFU");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitcoinUriWithAmount() throws Exception {
|
||||||
|
assertLinkify("bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu?amount=1.2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitcoinUriWithQueryParameters() throws Exception {
|
||||||
|
assertLinkify("bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu?amount=1.2" +
|
||||||
|
"&message=Payment&label=Satoshi&extra=other-param");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriInMiddleOfInput() throws Exception {
|
||||||
|
String prefix = "prefix ";
|
||||||
|
String uri = "bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu?amount=1.2";
|
||||||
|
String text = prefix + uri;
|
||||||
|
|
||||||
|
parser.linkifyUri(text, prefix.length(), outputBuffer);
|
||||||
|
|
||||||
|
assertLinkOnly(uri, outputBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invalidScheme() throws Exception {
|
||||||
|
assertNotLinkify("bitcion:19W6QZkx8SYPG7BBCS7odmWGRxqRph5jFU");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invalidAddress() throws Exception {
|
||||||
|
assertNotLinkify("bitcoin:[invalid]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invalidBitcoinUri_shouldReturnStartingPosition() throws Exception {
|
||||||
|
String uri = "bitcoin:[invalid]";
|
||||||
|
|
||||||
|
int newPos = linkify(uri);
|
||||||
|
|
||||||
|
assertEquals(0, newPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invalidBitcoinUri_shouldNotWriteToOutputBuffer() throws Exception {
|
||||||
|
String uri = "bitcoin:[invalid]";
|
||||||
|
|
||||||
|
linkify(uri);
|
||||||
|
|
||||||
|
assertEquals(0, outputBuffer.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int linkify(String uri) {
|
||||||
|
return parser.linkifyUri(uri, 0, outputBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertLinkify(String uri) {
|
||||||
|
linkify(uri);
|
||||||
|
assertLinkOnly(uri, outputBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertNotLinkify(String text) {
|
||||||
|
int newPos = linkify(text);
|
||||||
|
assertEquals(0, newPos);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,216 +1,155 @@
|
||||||
package com.fsck.k9.message.html;
|
package com.fsck.k9.message.html;
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.K9RobolectricTestRunner;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
|
|
||||||
|
import static com.fsck.k9.message.html.UriParserTestHelper.assertLinkOnly;
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
@RunWith(K9RobolectricTestRunner.class)
|
|
||||||
@Config(manifest = Config.NONE)
|
|
||||||
public class HttpUriParserTest {
|
public class HttpUriParserTest {
|
||||||
private HttpUriParser parser;
|
private final HttpUriParser parser = new HttpUriParser();
|
||||||
private StringBuffer outputBuffer;
|
private final StringBuffer outputBuffer = new StringBuffer();
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
@Test
|
||||||
parser = new HttpUriParser();
|
public void simpleDomain() {
|
||||||
outputBuffer = new StringBuffer();
|
assertLinkify("http://www.google.com");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleDomain() {
|
public void domainWithTrailingSlash() {
|
||||||
String text = "http://www.google.com";
|
assertLinkify("http://www.google.com/");
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDomainWithTrailingSlash() {
|
public void domainWithoutWww() {
|
||||||
String text = "http://www.google.com/";
|
assertLinkify("http://google.com/");
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDomainWithoutWWW() {
|
public void query() {
|
||||||
String text = "http://google.com/";
|
assertLinkify("http://google.com/give/me/?q=mode&c=information");
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDomainWithTrailingSpace() {
|
public void fragment() {
|
||||||
|
assertLinkify("http://google.com/give/me#only-the-best");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryAndFragment() {
|
||||||
|
assertLinkify("http://google.com/give/me/?q=mode&c=information#only-the-best");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv4Address() {
|
||||||
|
assertLinkify("http://127.0.0.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv4AddressWithTrailingSlash() {
|
||||||
|
assertLinkify("http://127.0.0.1/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv4AddressWithEmptyPort() {
|
||||||
|
assertLinkify("http://127.0.0.1:");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv4AddressWithPort() {
|
||||||
|
assertLinkify("http://127.0.0.1:524/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6Address() {
|
||||||
|
assertLinkify("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6AddressWithPort() {
|
||||||
|
assertLinkify("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6AddressWithTrailingSlash() {
|
||||||
|
assertLinkify("http://[1080:0:0:0:8:800:200C:417A]/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6AddressWithEndCompression() {
|
||||||
|
assertLinkify("http://[3ffe:2a00:100:7031::1]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6AddressWithBeginCompression() {
|
||||||
|
assertLinkify("http://[1080::8:800:200C:417A]/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6AddressWithCompressionPort() {
|
||||||
|
assertLinkify("http://[::FFFF:129.144.52.38]:80/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6AddressWithPrependedCompression() {
|
||||||
|
assertLinkify("http://[::192.9.5.5]/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6AddressWithTrailingIp4AndPort() {
|
||||||
|
assertLinkify("http://[::192.9.5.5]:80/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void domainWithTrailingSpace() {
|
||||||
String text = "http://google.com/ ";
|
String text = "http://google.com/ ";
|
||||||
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
||||||
assertEquals("<a href=\"http://google.com/\">http://google.com/</a>", outputBuffer.toString());
|
|
||||||
|
assertLinkOnly("http://google.com/", outputBuffer);
|
||||||
assertEquals(text.length() - 1, endPos);
|
assertEquals(text.length() - 1, endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDomainWithTrailingSpaceNewline() {
|
public void domainWithTrailingNewline() {
|
||||||
String text = "http://google.com/ \n";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals("<a href=\"http://google.com/\">http://google.com/</a>", outputBuffer.toString());
|
|
||||||
assertEquals(text.length() - 2, endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDomainWithTrailingNewline() {
|
|
||||||
String text = "http://google.com/\n";
|
String text = "http://google.com/\n";
|
||||||
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
||||||
assertEquals("<a href=\"http://google.com/\">http://google.com/</a>", outputBuffer.toString());
|
|
||||||
|
assertLinkOnly("http://google.com/", outputBuffer);
|
||||||
assertEquals(text.length() - 1, endPos);
|
assertEquals(text.length() - 1, endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDomainsWithQueryAndFragment() {
|
public void domainWithTrailingAngleBracket() {
|
||||||
String text = "http://google.com/give/me/?q=mode&c=information#only-the-best";
|
String text = "<http://google.com/>";
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(
|
|
||||||
"<a href=\"http://google.com/give/me/?q=mode&c=information#only-the-best\">http://google.com/give/me/?q=mode&c=information#only-the-best</a>",
|
|
||||||
outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
int endPos = parser.linkifyUri(text, 1, outputBuffer);
|
||||||
public void testDomainsWithQuery() {
|
|
||||||
String text = "http://google.com/give/me/?q=mode&c=information";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(
|
|
||||||
"<a href=\"http://google.com/give/me/?q=mode&c=information\">http://google.com/give/me/?q=mode&c=information</a>",
|
|
||||||
outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
assertLinkOnly("http://google.com/", outputBuffer);
|
||||||
public void testDomainsWithFragment() {
|
|
||||||
String text = "http://google.com/give/me#only-the-best";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(
|
|
||||||
"<a href=\"http://google.com/give/me#only-the-best\">http://google.com/give/me#only-the-best</a>",
|
|
||||||
outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDomainsWithQueryAndFragmentWithoutWWWW() {
|
|
||||||
String text = "http://google.com/give/me/?q=mode+c=information#only-the-best\n";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(
|
|
||||||
"<a href=\"http://google.com/give/me/?q=mode+c=information#only-the-best\">http://google.com/give/me/?q=mode+c=information#only-the-best</a>",
|
|
||||||
outputBuffer.toString());
|
|
||||||
assertEquals(text.length() - 1, endPos);
|
assertEquals(text.length() - 1, endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIpv4Address() {
|
public void uriInMiddleOfInput() throws Exception {
|
||||||
String text = "http://127.0.0.1";
|
String prefix = "prefix ";
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
String uri = "http://google.com/";
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
String text = prefix + uri;
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
|
parser.linkifyUri(text, prefix.length(), outputBuffer);
|
||||||
|
|
||||||
|
assertLinkOnly(uri, outputBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv4AddressWithTrailingSlash() {
|
int linkify(String uri) {
|
||||||
String text = "http://127.0.0.1/";
|
return parser.linkifyUri(uri, 0, outputBuffer);
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
void assertLinkify(String uri) {
|
||||||
public void testIpv4AddressWithEmptyPort() {
|
linkify(uri);
|
||||||
String text = "http://127.0.0.1:";
|
assertLinkOnly(uri, outputBuffer);
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv4AddressWithPort() {
|
|
||||||
String text = "http://127.0.0.1:524/";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6Address() {
|
|
||||||
String text = "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressWithPort() {
|
|
||||||
String text = "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressShort() {
|
|
||||||
String text = "http://[1080:0:0:0:8:800:200C:417A]/";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressWithEndCompression() {
|
|
||||||
String text = "http://[3ffe:2a00:100:7031::1]";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressWithBeginCompression() {
|
|
||||||
String text = "http://[1080::8:800:200C:417A]/";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressWithPrependedCompression() {
|
|
||||||
String text = "http://[::192.9.5.5]/";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressWithCompressionPort() {
|
|
||||||
String text = "http://[::FFFF:129.144.52.38]:80/";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressWithTrailingIp4() {
|
|
||||||
String text = "http://[::192.9.5.5]/";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6AddressWithTrailingIp4AndPort() {
|
|
||||||
String text = "http://[::192.9.5.5]:80/";
|
|
||||||
int endPos = parser.linkifyUri(text, 0, outputBuffer);
|
|
||||||
assertEquals(String.format("<a href=\"%1$s\">%1$s</a>", text), outputBuffer.toString());
|
|
||||||
assertEquals(text.length(), endPos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,90 +6,113 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static com.fsck.k9.message.html.UriParserTestHelper.assertLinkOnly;
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
@RunWith(K9RobolectricTestRunner.class)
|
@RunWith(K9RobolectricTestRunner.class)
|
||||||
@Config(manifest = Config.NONE)
|
@Config(manifest = Config.NONE)
|
||||||
public class UriLinkifierTest {
|
public class UriLinkifierTest {
|
||||||
@Test
|
private StringBuffer outputBuffer = new StringBuffer();
|
||||||
public void testLinkifyBitcoinAndHttpUri() {
|
|
||||||
String text = "bitcoin:19W6QZkx8SYPG7BBCS7odmWGRxqRph5jFU http://example.com/";
|
|
||||||
|
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
|
||||||
|
|
||||||
assertEquals("<a href=\"bitcoin:19W6QZkx8SYPG7BBCS7odmWGRxqRph5jFU\">" +
|
|
||||||
"bitcoin:19W6QZkx8SYPG7BBCS7odmWGRxqRph5jFU" +
|
|
||||||
"</a> " +
|
|
||||||
"<a href=\"http://example.com/\">" +
|
|
||||||
"http://example.com/" +
|
|
||||||
"</a>", outputBuffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleHttpUri() {
|
public void emptyText() {
|
||||||
String text = "http://www.google.com";
|
String text = "";
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
|
||||||
assertEquals("<a href=\"http://www.google.com\">http://www.google.com</a>", outputBuffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHttpUriWithTrailingSlash() {
|
|
||||||
String text = "http://www.google.com/";
|
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
UriLinkifier.linkifyText(text, outputBuffer);
|
||||||
assertEquals("<a href=\"http://www.google.com/\">http://www.google.com/</a>",
|
|
||||||
outputBuffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHttpUriWithoutWWW() {
|
|
||||||
String text = "http://google.com/";
|
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
|
||||||
assertEquals("<a href=\"http://google.com/\">http://google.com/</a>", outputBuffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHttpUriWithTrailingSpace() {
|
|
||||||
String text = "http://google.com/ ";
|
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
|
||||||
assertEquals("<a href=\"http://google.com/\">http://google.com/</a> ", outputBuffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHttpUriWithTrailingSpaceNewline() {
|
|
||||||
String text = "http://google.com/ \n";
|
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
|
||||||
assertEquals("<a href=\"http://google.com/\">http://google.com/</a> \n",
|
|
||||||
outputBuffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHttpUriWithTrailingNewline() {
|
|
||||||
String text = "http://google.com/\n";
|
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
|
||||||
assertEquals("<a href=\"http://google.com/\">http://google.com/</a>\n", outputBuffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIgnorePartialHttpUriScheme() {
|
|
||||||
String text = "myhttp://example.org";
|
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
|
||||||
assertEquals(text, outputBuffer.toString());
|
assertEquals(text, outputBuffer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPartialHttpUriSchemeWithSeparator() {
|
public void textWithoutUri_shouldBeCopiedToOutputBuffer() {
|
||||||
String text = "(http://example.org";
|
String text = "some text here";
|
||||||
StringBuffer outputBuffer = new StringBuffer();
|
|
||||||
UriLinkifier.linkifyText(text, outputBuffer);
|
UriLinkifier.linkifyText(text, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals(text, outputBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleUri() {
|
||||||
|
String uri = "http://example.org";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(uri, outputBuffer);
|
||||||
|
|
||||||
|
assertLinkOnly(uri, outputBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriPrecededBySpace() {
|
||||||
|
String text = " http://example.org";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(text, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals(" <a href=\"http://example.org\">http://example.org</a>", outputBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriPrecededByOpeningParenthesis() {
|
||||||
|
String text = "(http://example.org";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(text, outputBuffer);
|
||||||
|
|
||||||
assertEquals("(<a href=\"http://example.org\">http://example.org</a>", outputBuffer.toString());
|
assertEquals("(<a href=\"http://example.org\">http://example.org</a>", outputBuffer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriPrecededBySomeText() {
|
||||||
|
String uri = "Check out my fantastic URI: http://example.org";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(uri, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals("Check out my fantastic URI: <a href=\"http://example.org\">http://example.org</a>",
|
||||||
|
outputBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriWithTrailingText() {
|
||||||
|
String uri = "http://example.org/ is the best";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(uri, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals("<a href=\"http://example.org/\">http://example.org/</a> is the best", outputBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriEmbeddedInText() {
|
||||||
|
String uri = "prefix http://example.org/ suffix";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(uri, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals("prefix <a href=\"http://example.org/\">http://example.org/</a> suffix", outputBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriWithUppercaseScheme() {
|
||||||
|
String uri = "HTTP://example.org/";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(uri, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals("<a href=\"HTTP://example.org/\">HTTP://example.org/</a>", outputBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriNotPrecededByValidSeparator_shouldNotBeLinkified() {
|
||||||
|
String text = "myhttp://example.org";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(text, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals(text, outputBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriNotPrecededByValidSeparatorFollowedByValidUri() {
|
||||||
|
String text = "myhttp: http://example.org";
|
||||||
|
|
||||||
|
UriLinkifier.linkifyText(text, outputBuffer);
|
||||||
|
|
||||||
|
assertEquals("myhttp: <a href=\"http://example.org\">http://example.org</a>", outputBuffer.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.fsck.k9.message.html;
|
||||||
|
|
||||||
|
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
public class UriParserTestHelper {
|
||||||
|
public static void assertContainsLink(String expected, StringBuffer actual) {
|
||||||
|
String linkifiedUri = actual.toString();
|
||||||
|
Document document = Jsoup.parseBodyFragment(linkifiedUri);
|
||||||
|
Element anchorElement = document.select("a").first();
|
||||||
|
assertNotNull("No <a> element found", anchorElement);
|
||||||
|
assertEquals(expected, anchorElement.text());
|
||||||
|
assertEquals(expected, anchorElement.attr("href"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertLinkOnly(String expected, StringBuffer actual) {
|
||||||
|
String linkifiedUri = actual.toString();
|
||||||
|
Document document = Jsoup.parseBodyFragment(linkifiedUri);
|
||||||
|
Element anchorElement = document.select("a").first();
|
||||||
|
assertNotNull("No <a> element found", anchorElement);
|
||||||
|
assertEquals(expected, anchorElement.text());
|
||||||
|
assertEquals(expected, anchorElement.attr("href"));
|
||||||
|
|
||||||
|
assertAnchorElementIsSoleContent(document, anchorElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertAnchorElementIsSoleContent(Document document, Element anchorElement) {
|
||||||
|
assertEquals(document.body(), anchorElement.parent());
|
||||||
|
assertTrue("<a> element is surrounded by text", document.body().textNodes().isEmpty());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue