Skip to content

Commit

Permalink
draft-api/article-api: Add disclaimer field
Browse files Browse the repository at this point in the history
  • Loading branch information
katrinewi committed Dec 13, 2024
1 parent 3502cf9 commit 199b023
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 42 deletions.
15 changes: 10 additions & 5 deletions article-api/src/test/scala/no/ndla/articleapi/TestData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ trait TestData {
availability = Availability.everyone,
relatedContent = Seq.empty,
revisionDate = Some(NDLADate.now().withNano(0)),
slug = None
slug = None,
disclaimer = Seq.empty
)

val sampleDomainArticle: Article = Article(
Expand All @@ -177,7 +178,8 @@ trait TestData {
availability = Availability.everyone,
relatedContent = Seq.empty,
revisionDate = None,
slug = None
slug = None,
disclaimer = Seq.empty
)

val sampleDomainArticle2: Article = Article(
Expand All @@ -202,7 +204,8 @@ trait TestData {
availability = Availability.everyone,
relatedContent = Seq.empty,
revisionDate = None,
slug = None
slug = None,
disclaimer = Seq.empty
)

val sampleArticleWithByNcSa: Article = sampleArticleWithPublicDomain.copy(copyright = byNcSaCopyright)
Expand Down Expand Up @@ -239,7 +242,8 @@ trait TestData {
availability = Availability.everyone,
relatedContent = Seq.empty,
revisionDate = None,
slug = None
slug = None,
disclaimer = Seq.empty
)

val apiArticleWithHtmlFaultV2: api.ArticleV2DTO = api.ArticleV2DTO(
Expand Down Expand Up @@ -308,7 +312,8 @@ trait TestData {
availability = Availability.everyone,
relatedContent = Seq.empty,
revisionDate = None,
slug = None
slug = None,
disclaimer = Seq.empty
)
}

Expand Down
22 changes: 22 additions & 0 deletions common/src/main/scala/no/ndla/common/model/domain/Disclaimer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Part of NDLA common
* Copyright (C) 2024 NDLA
*
* See LICENSE
*/

package no.ndla.common.model.domain

import io.circe.{Decoder, Encoder}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import no.ndla.language.model.LanguageField

case class Disclaimer(disclaimer: String, language: String) extends LanguageField[String] {
override def value: String = disclaimer
override def isEmpty: Boolean = disclaimer.isEmpty
}

object Disclaimer {
implicit def encoder: Encoder[Disclaimer] = deriveEncoder[Disclaimer]
implicit def decoder: Decoder[Disclaimer] = deriveDecoder[Disclaimer]
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ case class Article(
availability: Availability,
relatedContent: Seq[RelatedContent],
revisionDate: Option[NDLADate],
slug: Option[String]
slug: Option[String],
disclaimer: Seq[Disclaimer]
) extends Content

object Article {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ case class Draft(
comments: Seq[Comment],
priority: Priority,
started: Boolean,
qualityEvaluation: Option[QualityEvaluation]
qualityEvaluation: Option[QualityEvaluation],
disclaimer: Seq[Disclaimer]
) extends Content {

def supportedLanguages: Seq[String] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ case class ArticleDTO(
@description("If the article should be prioritized. Possible values are prioritized, on-hold, unspecified") priority: String,
@description("If the article has been edited after last status or responsible change") started: Boolean,
@description("The quality evaluation of the article. Consist of a score from 1 to 5 and a comment.") qualityEvaluation : Option[QualityEvaluationDTO],
@description("The disclaimer of the article") disclaimer: Option[DisclaimerDTO]
)

object ArticleDTO {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package no.ndla.draftapi.model.api

/*
* Part of NDLA common
* Copyright (C) 2024 NDLA
*
* See LICENSE
*
*/

import io.circe.{Decoder, Encoder}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import sttp.tapir.Schema.annotations.description

case class DisclaimerDTO(
@description("The freetext content of the disclaimer") disclaimer: String,
@description("The freetext html content of the disclaimer") htmlDisclaimer: String,
@description("ISO 639-1 code that represents the language used in the disclaimer") language: String
)

object DisclaimerDTO {
implicit def encoder: Encoder[DisclaimerDTO] = deriveEncoder
implicit def decoder: Decoder[DisclaimerDTO] = deriveDecoder
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ case class NewArticleDTO(
@description("If the article should be prioritized") prioritized: Option[Boolean],
@description("If the article should be prioritized. Possible values are prioritized, on-hold, unspecified") priority: Option[String],
@description("The quality evaluation of the article. Consist of a score from 1 to 5 and a comment.") qualityEvaluation : Option[QualityEvaluationDTO],
@description("The disclaimer of the article") disclaimer: Option[String]
)
// format: on

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ case class UpdatedArticleDTO(
@description("If the article should be prioritized") prioritized: Option[Boolean],
@description("If the article should be prioritized. Possible values are prioritized, on-hold, unspecified") priority: Option[String],
@description("The quality evaluation of the article. Consist of a score from 1 to 5 and a comment.") qualityEvaluation : Option[QualityEvaluationDTO],
)
@description("The disclaimer of the article") disclaimer: Option[String]

)
// format: on

object UpdatedArticleDTO {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ trait ConverterService {
val domainContent = newArticle.content
.map(content => common.ArticleContent(removeUnknownEmbedTagAttribute(content), newArticle.language))
.toSeq
val domainDisclaimer = Seq(common.Disclaimer(newArticle.disclaimer.getOrElse(""), newArticle.language))

val status = externalIds match {
case Nil => common.Status(PLANNED, Set.empty)
Expand Down Expand Up @@ -124,7 +125,8 @@ trait ConverterService {
comments = newCommentToDomain(newArticle.comments.getOrElse(List.empty)),
priority = priority,
started = false,
qualityEvaluation = qualityEvaluationToDomain(newArticle.qualityEvaluation)
qualityEvaluation = qualityEvaluationToDomain(newArticle.qualityEvaluation),
disclaimer = domainDisclaimer
)
)
}
Expand Down Expand Up @@ -257,6 +259,9 @@ trait ConverterService {
private def toDomainTitle(articleTitle: api.ArticleTitleDTO): common.Title =
common.Title(articleTitle.title, articleTitle.language)

private def toDomainDisclaimer(articleDisclaimer: api.DisclaimerDTO): common.Disclaimer =
common.Disclaimer(articleDisclaimer.disclaimer, articleDisclaimer.language)

private def toDomainContent(articleContent: api.ArticleContentDTO): common.ArticleContent = {
common.ArticleContent(removeUnknownEmbedTagAttribute(articleContent.content), articleContent.language)
}
Expand Down Expand Up @@ -386,6 +391,7 @@ trait ConverterService {
val metaImage = findByLanguageOrBestEffort(article.metaImage, language).map(toApiArticleMetaImage)
val revisionMetas = article.revisionMeta.map(toApiRevisionMeta)
val responsible = article.responsible.map(toApiResponsible)
val disclaimer = findByLanguageOrBestEffort((article.disclaimer), language).map(toApiArticleDisclaimer)

Success(
api.ArticleDTO(
Expand Down Expand Up @@ -421,7 +427,8 @@ trait ConverterService {
prioritized = article.priority == Priority.Prioritized,
priority = article.priority.entryName,
started = article.started,
qualityEvaluation = toApiQualityEvaluation(article.qualityEvaluation)
qualityEvaluation = toApiQualityEvaluation(article.qualityEvaluation),
disclaimer = disclaimer
)
)
} else {
Expand Down Expand Up @@ -453,6 +460,13 @@ trait ConverterService {
def toApiArticleTitle(title: common.Title): api.ArticleTitleDTO =
api.ArticleTitleDTO(Jsoup.parseBodyFragment(title.title).body().text(), title.title, title.language)

def toApiArticleDisclaimer(disclaimer: common.Disclaimer): api.DisclaimerDTO =
api.DisclaimerDTO(
Jsoup.parseBodyFragment(disclaimer.disclaimer).body().text(),
disclaimer.disclaimer,
disclaimer.language
)

private def toApiArticleContent(content: common.ArticleContent): api.ArticleContentDTO =
api.ArticleContentDTO(content.content, content.language)

Expand Down Expand Up @@ -620,7 +634,8 @@ trait ConverterService {
availability = draft.availability,
relatedContent = draft.relatedContent,
revisionDate = getNextRevision(draft.revisionMeta).map(_.revisionDate),
slug = draft.slug
slug = draft.slug,
disclaimer = draft.disclaimer
)
)
}
Expand Down Expand Up @@ -781,6 +796,14 @@ trait ConverterService {
.traverse(lang => articleWithNewContent.title.toSeq.map(t => toDomainTitle(api.ArticleTitleDTO(t, t, lang))))
.flatten
)
val updatedDisclaimer = mergeLanguageFields(
toMergeInto.disclaimer,
maybeLang
.traverse(lang =>
articleWithNewContent.disclaimer.toSeq.map(d => toDomainDisclaimer(api.DisclaimerDTO(d, d, lang)))
)
.flatten
)
val updatedContents = mergeLanguageFields(
toMergeInto.content,
maybeLang
Expand Down Expand Up @@ -845,7 +868,8 @@ trait ConverterService {
comments = updatedComments,
priority = priority,
started = toMergeInto.started,
qualityEvaluation = qualityEvaluationToDomain(article.qualityEvaluation)
qualityEvaluation = qualityEvaluationToDomain(article.qualityEvaluation),
disclaimer = updatedDisclaimer
)

Success(converted)
Expand All @@ -858,7 +882,7 @@ trait ConverterService {
user: TokenUser,
oldNdlaCreatedDate: Option[NDLADate],
oldNdlaUpdatedDate: Option[NDLADate]
): Try[Draft] = article.language match {
): Try[Draft] = (article.language match {
case None =>
val error = ValidationMessage("language", "This field must be specified when updating language fields")
Failure(new ValidationException(errors = Seq(error)))
Expand Down Expand Up @@ -933,9 +957,10 @@ trait ConverterService {
comments = comments,
priority = priority,
started = false,
qualityEvaluation = qualityEvaluationToDomain(article.qualityEvaluation)
qualityEvaluation = qualityEvaluationToDomain(article.qualityEvaluation),
disclaimer = article.disclaimer.map(d => common.Disclaimer(d, lang)).toSeq
)
}
})

private[service] def buildTransitionsMap(user: TokenUser, article: Option[Draft]): Map[String, List[String]] =
StateTransitionRules.StateTransitions.groupBy(_.from).map { case (from, to) =>
Expand Down
24 changes: 17 additions & 7 deletions draft-api/src/test/scala/no/ndla/draftapi/TestData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ object TestData {
priority = Priority.Unspecified.entryName,
started = false,
prioritized = false,
qualityEvaluation = None
qualityEvaluation = None,
disclaimer = None
)

val blankUpdatedArticle: UpdatedArticleDTO = api.UpdatedArticleDTO(
Expand Down Expand Up @@ -142,7 +143,8 @@ object TestData {
comments = None,
prioritized = None,
priority = None,
qualityEvaluation = None
qualityEvaluation = None,
disclaimer = None
)

val sampleApiUpdateArticle: UpdatedArticleDTO = blankUpdatedArticle.copy(
Expand Down Expand Up @@ -230,6 +232,7 @@ object TestData {
false,
Priority.Unspecified.entryName,
false,
None,
None
)

Expand Down Expand Up @@ -283,6 +286,7 @@ object TestData {
false,
Priority.Unspecified.entryName,
false,
None,
None
)

Expand Down Expand Up @@ -317,7 +321,8 @@ object TestData {
Seq.empty,
Priority.Unspecified,
false,
None
None,
Seq.empty
)

val sampleArticleWithPublicDomain: Draft = Draft(
Expand Down Expand Up @@ -351,7 +356,8 @@ object TestData {
Seq.empty,
Priority.Unspecified,
false,
None
None,
Seq.empty
)

val sampleDomainArticle: Draft = Draft(
Expand Down Expand Up @@ -387,7 +393,8 @@ object TestData {
Seq.empty,
Priority.Unspecified,
false,
None
None,
Seq.empty
)

val newArticle: NewArticleDTO = api.NewArticleDTO(
Expand Down Expand Up @@ -426,6 +433,7 @@ object TestData {
None,
None,
None,
None,
None
)

Expand Down Expand Up @@ -476,7 +484,8 @@ object TestData {
comments = Seq.empty,
priority = Priority.Unspecified,
started = false,
qualityEvaluation = None
qualityEvaluation = None,
disclaimer = Seq.empty
)

val apiArticleWithHtmlFaultV2: api.ArticleDTO = api.ArticleDTO(
Expand Down Expand Up @@ -532,7 +541,8 @@ object TestData {
prioritized = false,
priority = Priority.Unspecified.entryName,
started = false,
qualityEvaluation = None
qualityEvaluation = None,
disclaimer = None
)

val (nodeId, nodeId2) = ("1234", "4321")
Expand Down
Loading

0 comments on commit 199b023

Please sign in to comment.