mirror of
https://github.com/Athou/commafeed.git
synced 2026-09-22 03:54:11 +00:00
apply xml cleaning to opml files
This commit is contained in:
@@ -4,55 +4,55 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class FeedCleanerTest {
|
||||
class XMLCleanerTest {
|
||||
|
||||
FeedCleaner feedCleaner = new FeedCleaner();
|
||||
XMLCleaner xmlCleaner = new XMLCleaner();
|
||||
|
||||
@Nested
|
||||
class RemoveCharactersBeforeFirstXmlTag {
|
||||
@Test
|
||||
void removesWhitespaceBeforeXmlTag() {
|
||||
String xml = " \n\t<feed>content</feed>";
|
||||
Assertions.assertEquals("<feed>content</feed>", feedCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
Assertions.assertEquals("<feed>content</feed>", xmlCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesTextBeforeXmlTag() {
|
||||
String xml = "some text here<feed>content</feed>";
|
||||
Assertions.assertEquals("<feed>content</feed>", feedCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
Assertions.assertEquals("<feed>content</feed>", xmlCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsUnchangedWhenStartsWithXmlTag() {
|
||||
String xml = "<feed>content</feed>";
|
||||
Assertions.assertEquals("<feed>content</feed>", feedCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
Assertions.assertEquals("<feed>content</feed>", xmlCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenNoXmlTagFound() {
|
||||
String xml = "no xml tags here";
|
||||
Assertions.assertNull(feedCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
Assertions.assertNull(xmlCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsNull() {
|
||||
Assertions.assertNull(feedCleaner.removeCharactersBeforeFirstXmlTag(null));
|
||||
Assertions.assertNull(xmlCleaner.removeCharactersBeforeFirstXmlTag(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsEmpty() {
|
||||
Assertions.assertNull(feedCleaner.removeCharactersBeforeFirstXmlTag(""));
|
||||
Assertions.assertNull(xmlCleaner.removeCharactersBeforeFirstXmlTag(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsBlank() {
|
||||
Assertions.assertNull(feedCleaner.removeCharactersBeforeFirstXmlTag(" \n\t "));
|
||||
Assertions.assertNull(xmlCleaner.removeCharactersBeforeFirstXmlTag(" \n\t "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesMultipleXmlTags() {
|
||||
String xml = "garbage<feed><item>content</item></feed>";
|
||||
Assertions.assertEquals("<feed><item>content</item></feed>", feedCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
Assertions.assertEquals("<feed><item>content</item></feed>", xmlCleaner.removeCharactersBeforeFirstXmlTag(xml));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,58 +61,58 @@ class FeedCleanerTest {
|
||||
@Test
|
||||
void removesNullCharacter() {
|
||||
String xml = "<feed>content\u0000here</feed>";
|
||||
Assertions.assertEquals("<feed>contenthere</feed>", feedCleaner.removeInvalidXmlCharacters(xml));
|
||||
Assertions.assertEquals("<feed>contenthere</feed>", xmlCleaner.removeInvalidXmlCharacters(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesInvalidControlCharacters() {
|
||||
String xml = "<feed>content\u0001\u0002\u0003here</feed>";
|
||||
Assertions.assertEquals("<feed>contenthere</feed>", feedCleaner.removeInvalidXmlCharacters(xml));
|
||||
Assertions.assertEquals("<feed>contenthere</feed>", xmlCleaner.removeInvalidXmlCharacters(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesValidXmlCharacters() {
|
||||
String xml = "<feed>content with\ttab\nand newline</feed>";
|
||||
Assertions.assertEquals("<feed>content with\ttab\nand newline</feed>", feedCleaner.removeInvalidXmlCharacters(xml));
|
||||
Assertions.assertEquals("<feed>content with\ttab\nand newline</feed>", xmlCleaner.removeInvalidXmlCharacters(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesUnicodeCharacters() {
|
||||
String xml = "<feed>café résumé 中文 العربية</feed>";
|
||||
Assertions.assertEquals("<feed>café résumé 中文 العربية</feed>", feedCleaner.removeInvalidXmlCharacters(xml));
|
||||
Assertions.assertEquals("<feed>café résumé 中文 العربية</feed>", xmlCleaner.removeInvalidXmlCharacters(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesEmojiCharacters() {
|
||||
String xml = "<feed>🎮💪✅</feed>";
|
||||
Assertions.assertEquals("<feed>🎮💪✅</feed>", feedCleaner.removeInvalidXmlCharacters(xml));
|
||||
Assertions.assertEquals("<feed>🎮💪✅</feed>", xmlCleaner.removeInvalidXmlCharacters(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesMultipleInvalidCharacters() {
|
||||
String xml = "test\u0000test\u0001test\u0002test";
|
||||
Assertions.assertEquals("testtesttesttest", feedCleaner.removeInvalidXmlCharacters(xml));
|
||||
Assertions.assertEquals("testtesttesttest", xmlCleaner.removeInvalidXmlCharacters(xml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsNull() {
|
||||
Assertions.assertNull(feedCleaner.removeInvalidXmlCharacters(null));
|
||||
Assertions.assertNull(xmlCleaner.removeInvalidXmlCharacters(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsEmpty() {
|
||||
Assertions.assertNull(feedCleaner.removeInvalidXmlCharacters(""));
|
||||
Assertions.assertNull(xmlCleaner.removeInvalidXmlCharacters(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsBlank() {
|
||||
Assertions.assertNull(feedCleaner.removeInvalidXmlCharacters(" "));
|
||||
Assertions.assertNull(xmlCleaner.removeInvalidXmlCharacters(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesStringWithOnlyInvalidCharacters() {
|
||||
String xml = "\u0000\u0001\u0002";
|
||||
Assertions.assertEquals("", feedCleaner.removeInvalidXmlCharacters(xml));
|
||||
Assertions.assertEquals("", xmlCleaner.removeInvalidXmlCharacters(xml));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,71 +122,71 @@ class FeedCleanerTest {
|
||||
void testReplaceHtmlEntitiesWithNumericEntities() {
|
||||
String source = "<source>T´l´phone ′</source>";
|
||||
Assertions.assertEquals("<source>T´l´phone ′</source>",
|
||||
feedCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacesMultipleOccurrencesOfSameEntity() {
|
||||
String source = " ";
|
||||
Assertions.assertEquals("   ", feedCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
Assertions.assertEquals("   ", xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesTextWithoutEntities() {
|
||||
String source = "<feed>regular content</feed>";
|
||||
Assertions.assertEquals("<feed>regular content</feed>", feedCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
Assertions.assertEquals("<feed>regular content</feed>", xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesNumericEntities() {
|
||||
String source = "´′";
|
||||
Assertions.assertEquals("´′", feedCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
Assertions.assertEquals("´′", xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacesCommonHtmlEntities() {
|
||||
String source = "&"";
|
||||
Assertions.assertEquals("&"", feedCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
Assertions.assertEquals("&"", xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesPartialEntityMatches() {
|
||||
String source = "&lifier";
|
||||
String result = feedCleaner.replaceHtmlEntitiesWithNumericEntities(source);
|
||||
String result = xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source);
|
||||
Assertions.assertTrue(result.startsWith("&") || result.equals("&lifier"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsNull() {
|
||||
Assertions.assertNull(feedCleaner.replaceHtmlEntitiesWithNumericEntities(null));
|
||||
Assertions.assertNull(xmlCleaner.replaceHtmlEntitiesWithNumericEntities(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsEmpty() {
|
||||
Assertions.assertNull(feedCleaner.replaceHtmlEntitiesWithNumericEntities(""));
|
||||
Assertions.assertNull(xmlCleaner.replaceHtmlEntitiesWithNumericEntities(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsBlank() {
|
||||
Assertions.assertNull(feedCleaner.replaceHtmlEntitiesWithNumericEntities(" "));
|
||||
Assertions.assertNull(xmlCleaner.replaceHtmlEntitiesWithNumericEntities(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesEntityAtStartOfString() {
|
||||
String source = "&test";
|
||||
Assertions.assertEquals("&test", feedCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
Assertions.assertEquals("&test", xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesEntityAtEndOfString() {
|
||||
String source = "test&";
|
||||
Assertions.assertEquals("test&", feedCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
Assertions.assertEquals("test&", xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesMixedEntitiesAndText() {
|
||||
String source = "Hello World! Test.";
|
||||
String result = feedCleaner.replaceHtmlEntitiesWithNumericEntities(source);
|
||||
String result = xmlCleaner.replaceHtmlEntitiesWithNumericEntities(source);
|
||||
Assertions.assertTrue(result.contains("&#"));
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ class FeedCleanerTest {
|
||||
@Test
|
||||
void testRemoveDoctype() {
|
||||
String source = "<!DOCTYPE html><html><head></head><body></body></html>";
|
||||
Assertions.assertEquals("<html><head></head><body></body></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html><head></head><body></body></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -208,64 +208,64 @@ class FeedCleanerTest {
|
||||
<html><head></head><body></body></html>""";
|
||||
Assertions.assertEquals("""
|
||||
|
||||
<html><head></head><body></body></html>""", feedCleaner.removeDoctypeDeclarations(source));
|
||||
<html><head></head><body></body></html>""", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesComplexDoctypeWithSystemId() {
|
||||
String source = "<!DOCTYPE html SYSTEM \"about:legacy-compat\"><html><body></body></html>";
|
||||
Assertions.assertEquals("<html><body></body></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html><body></body></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesComplexDoctypeWithPublicId() {
|
||||
String source = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"><html></html>";
|
||||
Assertions.assertEquals("<html></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesCaseInsensitiveDoctype() {
|
||||
String source = "<!doctype html><html></html>";
|
||||
Assertions.assertEquals("<html></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesMixedCaseDoctype() {
|
||||
String source = "<!DoCtYpE html><html></html>";
|
||||
Assertions.assertEquals("<html></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removesMultipleDoctypeDeclarations() {
|
||||
String source = "<!DOCTYPE html><!DOCTYPE html><html></html>";
|
||||
Assertions.assertEquals("<html></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesContentWithoutDoctype() {
|
||||
String source = "<html><body>No doctype here</body></html>";
|
||||
Assertions.assertEquals("<html><body>No doctype here</body></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html><body>No doctype here</body></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsNull() {
|
||||
Assertions.assertNull(feedCleaner.removeDoctypeDeclarations(null));
|
||||
Assertions.assertNull(xmlCleaner.removeDoctypeDeclarations(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsEmpty() {
|
||||
Assertions.assertNull(feedCleaner.removeDoctypeDeclarations(""));
|
||||
Assertions.assertNull(xmlCleaner.removeDoctypeDeclarations(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullWhenInputIsBlank() {
|
||||
Assertions.assertNull(feedCleaner.removeDoctypeDeclarations(" "));
|
||||
Assertions.assertNull(xmlCleaner.removeDoctypeDeclarations(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesDoctypeWithExtraWhitespace() {
|
||||
String source = "<!DOCTYPE html ><html></html>";
|
||||
Assertions.assertEquals("<html></html>", feedCleaner.removeDoctypeDeclarations(source));
|
||||
Assertions.assertEquals("<html></html>", xmlCleaner.removeDoctypeDeclarations(source));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||
import com.commafeed.backend.feed.parser.XMLCleaner;
|
||||
import com.commafeed.backend.model.FeedCategory;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.service.FeedSubscriptionService;
|
||||
@@ -36,13 +37,15 @@ class OPMLImporterTest {
|
||||
}
|
||||
|
||||
private void testOpmlVersion(String fileName) throws IOException, IllegalArgumentException, FeedException {
|
||||
XMLCleaner xmlCleaner = Mockito.mock(XMLCleaner.class);
|
||||
FeedCategoryDAO feedCategoryDAO = Mockito.mock(FeedCategoryDAO.class);
|
||||
FeedSubscriptionService feedSubscriptionService = Mockito.mock(FeedSubscriptionService.class);
|
||||
User user = Mockito.mock(User.class);
|
||||
|
||||
Mockito.when(xmlCleaner.clean(Mockito.anyString())).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
String xml = IOUtils.toString(getClass().getResourceAsStream(fileName), StandardCharsets.UTF_8);
|
||||
|
||||
OPMLImporter importer = new OPMLImporter(feedCategoryDAO, feedSubscriptionService);
|
||||
OPMLImporter importer = new OPMLImporter(xmlCleaner, feedCategoryDAO, feedSubscriptionService);
|
||||
importer.importOpml(user, xml);
|
||||
|
||||
Mockito.verify(feedSubscriptionService)
|
||||
|
||||
Reference in New Issue
Block a user