Skip to content

Commit

Permalink
Merge pull request #438 from NDLANO/comment-embed
Browse files Browse the repository at this point in the history
Add comment embed
  • Loading branch information
katrinewi authored Apr 9, 2024
2 parents c362616 + 8f249fd commit a3d8046
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

package no.ndla.draftapi.service

import cats.implicits._
import cats.implicits.*
import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.configuration.Constants.EmbedTagName
import no.ndla.common.errors.{ValidationException, ValidationMessage}
import no.ndla.common.model.api.{Delete, DraftCopyright, Missing, UpdateWith, draft}
import no.ndla.common.model.domain.{Priority, Responsible}
import no.ndla.common.model.domain.{ArticleContent, Priority, Responsible}
import no.ndla.common.model.domain.draft.DraftStatus.{IMPORTED, PLANNED}
import no.ndla.common.model.domain.draft.{Comment, Draft, DraftStatus}
import no.ndla.common.model.{NDLADate, RelatedContentLink, api => commonApi, domain => common}
import no.ndla.common.model.{NDLADate, RelatedContentLink, api as commonApi, domain as common}
import no.ndla.common.{Clock, UUIDUtil, model}
import no.ndla.draftapi.Props
import no.ndla.draftapi.integration.ArticleApiClient
Expand All @@ -25,13 +25,14 @@ import no.ndla.draftapi.repository.DraftRepository
import no.ndla.language.Language.{AllLanguages, UnknownLanguage, findByLanguageOrBestEffort, mergeLanguageFields}
import no.ndla.mapping.License.getLicense
import no.ndla.network.tapir.auth.TokenUser
import no.ndla.validation._
import no.ndla.validation.*
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import org.jsoup.nodes.Entities.EscapeMode
import scalikejdbc.{DBSession, ReadOnlyAutoSession}

import java.util.UUID
import scala.jdk.CollectionConverters._
import scala.jdk.CollectionConverters.*
import scala.util.{Failure, Success, Try}

trait ConverterService {
Expand Down Expand Up @@ -552,6 +553,24 @@ trait ConverterService {
def getNextRevision(revisions: Seq[common.draft.RevisionMeta]): Option[common.draft.RevisionMeta] =
revisions.filterNot(_.status == common.draft.RevisionStatus.Revised).sortBy(_.revisionDate).headOption

def filterComments(content: Seq[ArticleContent]): Seq[ArticleContent] = {
val contents = content.map(cont => {
val document = Jsoup.parseBodyFragment(cont.content)
document
.outputSettings()
.escapeMode(EscapeMode.xhtml)
.prettyPrint(false)
.indentAmount(0)

val commentEmbeds = document.select("[data-resource='comment']")
commentEmbeds.unwrap()

val newContentString = document.select("body").first().html()
cont.copy(content = newContentString)
})
contents
}

def toArticleApiArticle(draft: Draft): Try[common.article.Article] = {
draft.copyright match {
case None => Failure(ValidationException("copyright", "Copyright must be present when publishing an article"))
Expand All @@ -561,7 +580,7 @@ trait ConverterService {
id = draft.id,
revision = draft.revision,
title = draft.title,
content = draft.content,
content = filterComments(draft.content),
copyright = toArticleApiCopyright(copyright),
tags = draft.tags,
requiredLibraries = draft.requiredLibraries,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1211,4 +1211,48 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
service.updatedCommentToDomainNullDocument(updatedComments).isFailure should be(true)
}

test("filterComments should remove comments") {
val content =
Seq(
ArticleContent(
s"""<h1>hello</h1><$EmbedTagName ${TagAttribute.DataResource}="${ResourceType.Comment}" ${TagAttribute.DataText}="Dette er min kommentar" ${TagAttribute.DataType}="inline"><p>Litt tekst</p></$EmbedTagName>""",
"nb"
)
)
val expectedContent = Seq(ArticleContent(s"""<h1>hello</h1><p>Litt tekst</p>""", "nb"))

val blockContent =
Seq(
ArticleContent(
s"""<h1>hello</h1><$EmbedTagName ${TagAttribute.DataResource}="${ResourceType.Comment}" ${TagAttribute.DataText}="Dette er min kommentar" ${TagAttribute.DataType}="block"/>""",
"nb"
),
ArticleContent(
s"""<h1>hello</h1><$EmbedTagName ${TagAttribute.DataResource}="${ResourceType.Comment}" ${TagAttribute.DataText}="Dette er min kommentar" ${TagAttribute.DataType}="block"/>""",
"nn"
)
)

val expectedBlockContent =
Seq(
ArticleContent(
s"""<h1>hello</h1>""",
"nb"
),
ArticleContent(
s"""<h1>hello</h1>""",
"nn"
)
)

val expectedTime = TestData.today

when(clock.now()).thenReturn(expectedTime)

val result = service.filterComments(content)
val blockResult = service.filterComments(blockContent)
result should be(expectedContent)
blockResult should be(expectedBlockContent)
}

}
48 changes: 48 additions & 0 deletions validation/src/main/resources/embed-tag-rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,54 @@
]
}
},
"comment": {
"fields": [
{
"name": "data-resource",
"validation": {
"required": true
}
},
{
"name": "data-type",
"validation": {
"required": true
}
},
{
"name": "data-text",
"validation": {
"required": true
}
}
],
"children": {
"required": false,
"allowedChildren": [
"aside",
"b",
"br",
"details",
"div",
"em",
"h2",
"h3",
"h4",
"i",
"math",
"ndlaembed",
"ol",
"p",
"s",
"strong",
"sub",
"sup",
"table",
"u",
"ul"
]
}
},
"h5p": {
"fields": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ object ResourceType extends Enum[ResourceType] {
case object Brightcove extends ResourceType("brightcove")
case object CampaignBlock extends ResourceType("campaign-block")
case object CodeBlock extends ResourceType("code-block")
case object Comment extends ResourceType("comment")
case object Concept extends ResourceType("concept")
case object ConceptList extends ResourceType("concept-list")
case object ContactBlock extends ResourceType("contact-block")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ object TagAttribute extends Enum[TagAttribute] with CirceEnum[TagAttribute] {
case object DataSubjectId extends TagAttribute("data-subject-id")
case object DataSubtitle extends TagAttribute("data-subtitle")
case object DataTag extends TagAttribute("data-tag")
case object DataText extends TagAttribute("data-text")
case object DataTitle extends TagAttribute("data-title")
case object DataTitleLanguage extends TagAttribute("data-title-language")
case object DataType extends TagAttribute("data-type")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,21 @@ class EmbedTagValidatorTest extends UnitSuite {
res.size should be(0)
}

test("validate should return no validation errors if comment embed-tag is used correctly with html") {
val tag = generateTagWithAttrsAndChildren(
Map(
TagAttribute.DataResource -> ResourceType.Comment.toString,
TagAttribute.DataText -> "Min kommentar",
TagAttribute.DataType -> "inline"
),
"""
|<p>her</p>
|""".stripMargin
)
val res = TagValidator.validate("content", tag)
res.size should be(0)
}

test(
"validate should return validation error if embed tag does not contain required attributes for data-resource=error"
) {
Expand Down

0 comments on commit a3d8046

Please sign in to comment.