diff --git a/article-api/src/main/scala/no/ndla/articleapi/validation/ContentValidator.scala b/article-api/src/main/scala/no/ndla/articleapi/validation/ContentValidator.scala
index 4b556f08d..90fc36721 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/validation/ContentValidator.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/validation/ContentValidator.scala
@@ -50,6 +50,7 @@ trait ContentValidator {
def validateArticle(article: Article, isImported: Boolean): Try[Article] = {
val validationErrors = validateArticleContent(article.content) ++
article.introduction.flatMap(i => validateIntroduction(i)) ++
+ validateArticleDisclaimer(article.disclaimer.getOrElse(Seq.empty)) ++
validateMetaDescription(article.metaDescription, isImported) ++
validateTitle(article.title) ++
validateCopyright(article.copyright) ++
@@ -89,6 +90,14 @@ trait ContentValidator {
}) ++ validateNonEmpty("content", contents)
}
+ private def validateArticleDisclaimer(disclaimers: Seq[Disclaimer]): Seq[ValidationMessage] = {
+ disclaimers.flatMap(disclaimer => {
+ val field = s"disclaimer.${disclaimer.language}"
+ TextValidator.validate(field, disclaimer.disclaimer, allLegalTags).toList ++
+ validateLanguage("content.language", disclaimer.language)
+ })
+ }
+
private def rootElementContainsOnlySectionBlocks(field: String, html: String): Option[ValidationMessage] = {
val legalTopLevelTag = "section"
val topLevelTags = stringToJsoupDocument(html).children().asScala.map(_.tagName())
diff --git a/article-api/src/test/scala/no/ndla/articleapi/validation/ContentValidatorTest.scala b/article-api/src/test/scala/no/ndla/articleapi/validation/ContentValidatorTest.scala
index c4f191bed..f8b4a626b 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/validation/ContentValidatorTest.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/validation/ContentValidatorTest.scala
@@ -15,6 +15,7 @@ import no.ndla.common.model.domain.{
ArticleMetaImage,
Author,
Description,
+ Disclaimer,
Introduction,
RequiredLibrary,
Tag,
@@ -30,6 +31,8 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
val validDocument = """"""
val validIntroduction = """
heisann heia
hopp
"""
val invalidDocument = """"""
+ val validDisclaimer =
+ """hallo!test
"""
test("validateArticle does not throw an exception on a valid document") {
val article = TestData.sampleArticleWithByNcSa.copy(content = Seq(ArticleContent(validDocument, "nb")))
@@ -77,6 +80,41 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
contentValidator.validateArticle(article, false).isSuccess should be(true)
}
+ test("validateArticle should throw an error if disclaimer contains illegal HTML tags") {
+ val article = TestData.sampleArticleWithByNcSa.copy(
+ content = Seq(ArticleContent(validDocument, "nb")),
+ disclaimer = Some(Seq(Disclaimer("hei
", "nb")))
+ )
+ val result = contentValidator.validateArticle(article, false)
+ result.failed.get.asInstanceOf[ValidationException].errors.length should be(1)
+ result.failed.get.asInstanceOf[ValidationException].errors.head.message should be(
+ "The content contains illegal tags and/or attributes. Allowed HTML tags are: h3, msgroup, a, article, sub, sup, mtext, msrow, tbody, mtd, pre, thead, figcaption, mover, msup, semantics, ol, span, mroot, munder, h4, mscarries, dt, nav, mtr, ndlaembed, li, br, mrow, merror, mphantom, u, audio, ul, maligngroup, mfenced, annotation, div, strong, section, i, mspace, malignmark, mfrac, code, h2, td, aside, em, mstack, button, dl, th, tfoot, math, tr, b, blockquote, msline, col, annotation-xml, mstyle, caption, mpadded, mo, mlongdiv, msubsup, p, munderover, maction, menclose, h1, details, mmultiscripts, msqrt, mscarry, mstac, mi, mglyph, mlabeledtr, mtable, mprescripts, summary, mn, msub, ms, table, colgroup, dd"
+ )
+ }
+
+ test("validateArticle should not throw an error if disclaimer contains legal HTML tags") {
+ val article = TestData.sampleArticleWithByNcSa.copy(
+ content = Seq(ArticleContent(validDocument, "nb")),
+ disclaimer = Some(
+ Seq(
+ Disclaimer(
+ validDisclaimer,
+ "nb"
+ )
+ )
+ )
+ )
+ contentValidator.validateArticle(article, false).isSuccess should be(true)
+ }
+
+ test("validateArticle should not throw an error if disclaimer contains plain text") {
+ val article = TestData.sampleArticleWithByNcSa.copy(
+ content = Seq(ArticleContent(validDocument, "nb")),
+ disclaimer = Some(Seq(Disclaimer("disclaimer", "nb")))
+ )
+ contentValidator.validateArticle(article, false).isSuccess should be(true)
+ }
+
test("validateArticle should throw an error if metaDescription contains HTML tags") {
val article = TestData.sampleArticleWithByNcSa.copy(
content = Seq(ArticleContent(validDocument, "nb")),
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/validation/ContentValidator.scala b/draft-api/src/main/scala/no/ndla/draftapi/validation/ContentValidator.scala
index d1bd62e04..c9ff0c12b 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/validation/ContentValidator.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/validation/ContentValidator.scala
@@ -84,6 +84,7 @@ trait ContentValidator {
if (shouldValidateEntireArticle)
article.content.flatMap(c => validateArticleContent(c)) ++
article.introduction.flatMap(i => validateIntroduction(i)) ++
+ validateArticleDisclaimer(article.disclaimer.getOrElse(Seq.empty)) ++
article.metaDescription.flatMap(m => validateMetaDescription(m)) ++
validateTitles(article.title) ++
article.copyright.map(x => validateCopyright(x)).toSeq.flatten ++
@@ -164,6 +165,13 @@ trait ContentValidator {
validateLanguage("content.language", content.language)
}
+ private def validateArticleDisclaimer(disclaimers: Seq[Disclaimer]): Seq[ValidationMessage] = {
+ disclaimers.flatMap(disclaimer => {
+ TextValidator.validate("disclaimer", disclaimer.disclaimer, allLegalTags).toList ++
+ validateLanguage("disclaimer.language", disclaimer.language)
+ })
+ }
+
private def rootElementContainsOnlySectionBlocks(field: String, html: String): Option[ValidationMessage] = {
val legalTopLevelTag = "section"
val topLevelTags = stringToJsoupDocument(html).children().asScala.map(_.tagName())
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/validation/ContentValidatorTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/validation/ContentValidatorTest.scala
index 9d626f17c..413498b69 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/validation/ContentValidatorTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/validation/ContentValidatorTest.scala
@@ -21,6 +21,8 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
override val converterService: ConverterService = new ConverterService
val validDocument = """"""
val invalidDocument = """"""
+ val validDisclaimer =
+ """hallo!test
"""
val articleToValidate: Draft =
TestData.sampleArticleWithByNcSa.copy(responsible = Some(Responsible("hei", TestData.today)))
@@ -58,7 +60,36 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
contentValidator.validateArticle(article).isSuccess should be(true)
}
+ test("validateArticle should throw an error if disclaimer contains illegal HTML tags") {
+ val article = articleToValidate.copy(
+ content = Seq(ArticleContent(validDocument, "nb")),
+ disclaimer = Some(Seq(Disclaimer("hei
", "nb")))
+ )
+ val result = contentValidator.validateArticle(article)
+ result.failed.get.asInstanceOf[ValidationException].errors.length should be(1)
+ result.failed.get.asInstanceOf[ValidationException].errors.head.message should be(
+ "The content contains illegal tags and/or attributes. Allowed HTML tags are: h3, msgroup, a, article, sub, sup, mtext, msrow, tbody, mtd, pre, thead, figcaption, mover, msup, semantics, ol, span, mroot, munder, h4, mscarries, dt, nav, mtr, ndlaembed, li, br, mrow, merror, mphantom, u, audio, ul, maligngroup, mfenced, annotation, div, strong, section, i, mspace, malignmark, mfrac, code, h2, td, aside, em, mstack, button, dl, th, tfoot, math, tr, b, blockquote, msline, col, annotation-xml, mstyle, caption, mpadded, mo, mlongdiv, msubsup, p, munderover, maction, menclose, h1, details, mmultiscripts, msqrt, mscarry, mstac, mi, mglyph, mlabeledtr, mtable, mprescripts, summary, mn, msub, ms, table, colgroup, dd"
+ )
+ }
+
+ test("validateArticle should not throw an error if disclaimer contains legal HTML tags") {
+ val article = articleToValidate.copy(
+ content = Seq(ArticleContent(validDocument, "nb")),
+ disclaimer = Some(Seq(Disclaimer(validDisclaimer, "nb")))
+ )
+ contentValidator.validateArticle(article).isSuccess should be(true)
+
+ }
+
test("validateArticle should throw an error if metaDescription contains HTML tags") {
+ val article = articleToValidate.copy(
+ content = Seq(ArticleContent(validDocument, "nb")),
+ metaDescription = Seq(Description(validDisclaimer, "nb"))
+ )
+ contentValidator.validateArticle(article).isFailure should be(true)
+ }
+
+ test("validateArticle should throw an error if metaDescription contains plain text") {
val article = articleToValidate.copy(
content = Seq(ArticleContent(validDocument, "nb")),
metaDescription = Seq(Description(validDocument, "nb"))