diff --git a/.scalafmt.conf b/.scalafmt.conf
index ac77ca8d47..934a939d8b 100644
--- a/.scalafmt.conf
+++ b/.scalafmt.conf
@@ -1,5 +1,5 @@
version = 3.9.8
-runner.dialect = scala213source3
+runner.dialect = scala3
align.preset = more
maxColumn = 120
newlines.topLevelStatementsMinBreaks = 1
diff --git a/article-api/src/main/scala/no/ndla/articleapi/ArticleApiProperties.scala b/article-api/src/main/scala/no/ndla/articleapi/ArticleApiProperties.scala
index 53c865ff24..11e13cfdf4 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/ArticleApiProperties.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/ArticleApiProperties.scala
@@ -16,7 +16,7 @@ import no.ndla.validation.ResourceType
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: ArticleApiProperties
+ lazy val props: ArticleApiProperties
}
class ArticleApiProperties extends BaseProps with DatabaseProps {
diff --git a/article-api/src/main/scala/no/ndla/articleapi/ComponentRegistry.scala b/article-api/src/main/scala/no/ndla/articleapi/ComponentRegistry.scala
index 46182e9538..36ca856f91 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/ComponentRegistry.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/ComponentRegistry.scala
@@ -70,8 +70,8 @@ class ComponentRegistry(properties: ArticleApiProperties)
with FrontpageApiClient
with ImageApiClient
with V55__SetHideBylineForImagesNotCopyrighted {
- override val props: ArticleApiProperties = properties
- override val migrator: DBMigrator = DBMigrator(
+ override lazy val props: ArticleApiProperties = properties
+ override lazy val migrator: DBMigrator = DBMigrator(
new R__SetArticleLanguageFromTaxonomy(props),
new R__SetArticleTypeFromTaxonomy,
new V8__CopyrightFormatUpdated,
@@ -81,32 +81,32 @@ class ComponentRegistry(properties: ArticleApiProperties)
new V33__ConvertLanguageUnknown(props),
new V55__SetHideBylineForImagesNotCopyrighted
)
- override val DBUtil: DBUtility = new DBUtility
+ override lazy val DBUtil: DBUtility = new DBUtility
- lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
- lazy val internController = new InternController
- lazy val articleControllerV2 = new ArticleControllerV2
- lazy val healthController: TapirHealthController = new TapirHealthController
+ override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
+ override lazy val internController = new InternController
+ override lazy val articleControllerV2 = new ArticleControllerV2
+ override lazy val healthController: TapirHealthController = new TapirHealthController
- lazy val articleRepository = new ArticleRepository
- lazy val articleSearchService = new ArticleSearchService
- lazy val articleIndexService = new ArticleIndexService
+ override lazy val articleRepository = new ArticleRepository
+ override lazy val articleSearchService = new ArticleSearchService
+ override lazy val articleIndexService = new ArticleIndexService
- lazy val converterService = new ConverterService
- lazy val contentValidator = new ContentValidator()
+ override lazy val converterService = new ConverterService
+ override lazy val contentValidator = new ContentValidator()
- lazy val ndlaClient = new NdlaClient
- lazy val searchConverterService = new SearchConverterService
- lazy val readService = new ReadService
- lazy val writeService = new WriteService
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val readService = new ReadService
+ override lazy val writeService = new WriteService
- var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
- lazy val searchApiClient = new SearchApiClient
- lazy val feideApiClient = new FeideApiClient
- lazy val myndlaApiClient = new MyNDLAApiClient
- lazy val redisClient = new RedisClient(props.RedisHost, props.RedisPort)
- lazy val frontpageApiClient = new FrontpageApiClient
- lazy val imageApiClient = new ImageApiClient
+ var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
+ override lazy val searchApiClient = new SearchApiClient
+ override lazy val feideApiClient = new FeideApiClient
+ override lazy val myndlaApiClient = new MyNDLAApiClient
+ override lazy val redisClient = new RedisClient(props.RedisHost, props.RedisPort)
+ override lazy val frontpageApiClient = new FrontpageApiClient
+ override lazy val imageApiClient = new ImageApiClient
lazy val clock = new SystemClock
diff --git a/article-api/src/main/scala/no/ndla/articleapi/caching/Memoize.scala b/article-api/src/main/scala/no/ndla/articleapi/caching/Memoize.scala
index 6e42bbd1ba..be5cdeac5a 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/caching/Memoize.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/caching/Memoize.scala
@@ -17,7 +17,7 @@ class Memoize[R](maxCacheAgeMs: Long, f: () => R, autoRefreshCache: Boolean) ext
def isExpired: Boolean = lastUpdated + maxCacheAgeMs <= System.currentTimeMillis()
}
- private[this] var cache: Option[CacheValue] = None
+ private var cache: Option[CacheValue] = None
private def renewCache(): Unit = {
cache = Some(CacheValue(f(), System.currentTimeMillis()))
@@ -28,7 +28,7 @@ class Memoize[R](maxCacheAgeMs: Long, f: () => R, autoRefreshCache: Boolean) ext
val task = new Runnable {
def run(): Unit = renewCache()
}
- ex.scheduleAtFixedRate(task, 20, maxCacheAgeMs, TimeUnit.MILLISECONDS)
+ ex.scheduleAtFixedRate(task, 20, maxCacheAgeMs, TimeUnit.MILLISECONDS): Unit
}
def apply(): R = {
diff --git a/article-api/src/main/scala/no/ndla/articleapi/controller/ArticleControllerV2.scala b/article-api/src/main/scala/no/ndla/articleapi/controller/ArticleControllerV2.scala
index 95cb50db07..379460bcc5 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/controller/ArticleControllerV2.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/controller/ArticleControllerV2.scala
@@ -26,7 +26,6 @@ import no.ndla.network.tapir.Parameters.feideHeader
import no.ndla.network.tapir.{DynamicHeaders, TapirController}
import no.ndla.network.tapir.TapirUtil.errorOutputsFor
import sttp.model.{Header, MediaType}
-import sttp.tapir.EndpointIO.annotations.{header, jsonbody}
import sttp.tapir.*
import sttp.tapir.generic.auto.*
import sttp.tapir.server.ServerEndpoint
@@ -36,9 +35,7 @@ import scala.util.{Failure, Success, Try}
trait ArticleControllerV2 {
this: ReadService & WriteService & ArticleSearchService & SearchConverterService & ConverterService &
ContentValidator & Props & ErrorHandling & TapirController =>
- val articleControllerV2: ArticleControllerV2
-
- import props.*
+ lazy val articleControllerV2: ArticleControllerV2
class ArticleControllerV2 extends TapirController {
protected val applicationDescription = "Services for accessing articles from NDLA."
@@ -79,11 +76,11 @@ trait ArticleControllerV2 {
private val fallback =
query[Boolean]("fallback").description("Fallback to existing language if language is specified.").default(false)
protected val scrollId: EndpointInput.Query[Option[String]] = query[Option[String]]("search-context").description(
- s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${InitialScrollContextKeywords
+ s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${props.InitialScrollContextKeywords
.mkString("[", ",", "]")}.
|When scrolling, the parameters from the initial search is used, except in the case of '${this.language.name}' and '${this.fallback.name}'.
- |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after $ElasticSearchScrollKeepAlive).
- |If you are not paginating past $ElasticSearchIndexMaxResultWindow hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
+ |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after ${props.ElasticSearchScrollKeepAlive}).
+ |If you are not paginating past ${props.ElasticSearchIndexMaxResultWindow} hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
|""".stripMargin
)
private val grepCodes = listQuery[String]("grep-codes")
@@ -91,13 +88,6 @@ trait ArticleControllerV2 {
"A comma separated list of codes from GREP API the resources should be filtered by."
)
- private case class SummaryWithHeader(
- @jsonbody
- body: SearchResultV2DTO,
- @header("search-context")
- searchContext: Option[String]
- )
-
/** Does a scroll with [[ArticleSearchService]] If no scrollId is specified execute the function @orFunction in the
* second parameter list.
*
@@ -110,7 +100,7 @@ trait ArticleControllerV2 {
orFunction: => Try[(SearchResultV2DTO, DynamicHeaders)]
): Try[(SearchResultV2DTO, DynamicHeaders)] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
articleSearchService.scroll(scroll, language) match {
case Success(scrollResult) =>
val body = searchConverterService.asApiSearchResultV2(scrollResult)
@@ -134,8 +124,8 @@ trait ArticleControllerV2 {
.errorOut(errorOutputsFor())
.serverLogicPure { case (query, pageSize, pageNo, language) =>
val queryOrEmpty = query.getOrElse("")
- val parsedPageSize = pageSize.getOrElse(DefaultPageSize) match {
- case tooSmall if tooSmall < 1 => DefaultPageSize
+ val parsedPageSize = pageSize.getOrElse(props.DefaultPageSize) match {
+ case tooSmall if tooSmall < 1 => props.DefaultPageSize
case x => x
}
val parsedPageNo = pageNo.getOrElse(1) match {
@@ -228,9 +218,9 @@ trait ArticleControllerV2 {
) =>
scrollSearchOr(scrollId, language.code) {
val sort = Sort.valueOf(maybeSort.getOrElse(""))
- val pageSize = maybePageSize.getOrElse(DefaultPageSize)
+ val pageSize = maybePageSize.getOrElse(props.DefaultPageSize)
val page = maybePageNo.getOrElse(1)
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query,
@@ -301,12 +291,12 @@ trait ArticleControllerV2 {
val query = searchParams.query
val sort = searchParams.sort
val license = searchParams.license
- val pageSize = searchParams.pageSize.getOrElse(DefaultPageSize)
+ val pageSize = searchParams.pageSize.getOrElse(props.DefaultPageSize)
val page = searchParams.page.getOrElse(1)
val idList = searchParams.ids.getOrElse(List.empty)
val articleTypesFilter = searchParams.articleTypes.getOrElse(List.empty)
val grepCodes = searchParams.grepCodes.getOrElse(Seq.empty)
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query,
diff --git a/article-api/src/main/scala/no/ndla/articleapi/controller/InternController.scala b/article-api/src/main/scala/no/ndla/articleapi/controller/InternController.scala
index 20154a06bb..1667df0d8c 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/controller/InternController.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/controller/InternController.scala
@@ -38,7 +38,7 @@ import scala.util.{Failure, Success}
trait InternController {
this: ReadService & WriteService & ConverterService & ArticleRepository & IndexService & ArticleIndexService &
ContentValidator & Props & DBArticle & TapirController =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController with StrictLogging {
override val prefix: EndpointInput[Unit] = "intern"
diff --git a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V47__RenameAlignAttributeTable.scala b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V47__RenameAlignAttributeTable.scala
index 1e1fe8ddde..2410df9b93 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V47__RenameAlignAttributeTable.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V47__RenameAlignAttributeTable.scala
@@ -44,7 +44,7 @@ class V47__RenameAlignAttributeTable extends BaseJavaMigration {
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
- .withinTx { session => migrateRows(session) }
+ .withinTx { session => migrateRows(using session) }
private def migrateRows(implicit session: DBSession): Unit = {
val count = countAllRows.get
diff --git a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V48__ConvertSizeVariantToHideByline.scala b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V48__ConvertSizeVariantToHideByline.scala
index 2f25923a64..689009174c 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V48__ConvertSizeVariantToHideByline.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V48__ConvertSizeVariantToHideByline.scala
@@ -45,7 +45,7 @@ class V48__ConvertSizeVariantToHideByline extends BaseJavaMigration {
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
- .withinTx { session => migrateRows(session) }
+ .withinTx { session => migrateRows(using session) }
private def migrateRows(implicit session: DBSession): Unit = {
val count = countAllRows.get
diff --git a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V49__RemoveConceptListEmbeds.scala b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V49__RemoveConceptListEmbeds.scala
index 80f6f9fed5..163ccacbb7 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V49__RemoveConceptListEmbeds.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V49__RemoveConceptListEmbeds.scala
@@ -45,7 +45,7 @@ class V49__RemoveConceptListEmbeds extends BaseJavaMigration {
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
- .withinTx { session => migrateRows(session) }
+ .withinTx { session => migrateRows(using session) }
private def migrateRows(implicit session: DBSession): Unit = {
val count = countAllRows.get
diff --git a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V50__RemoveUnsupportedContactBlockAttributes.scala b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V50__RemoveUnsupportedContactBlockAttributes.scala
index a3fb7ff167..e51537742b 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V50__RemoveUnsupportedContactBlockAttributes.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V50__RemoveUnsupportedContactBlockAttributes.scala
@@ -45,7 +45,7 @@ class V50__RemoveUnsupportedContactBlockAttributes extends BaseJavaMigration {
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
- .withinTx { session => migrateRows(session) }
+ .withinTx { session => migrateRows(using session) }
private def migrateRows(implicit session: DBSession): Unit = {
val count = countAllRows.get
diff --git a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V54__RemoveStrongFromTitle.scala b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V54__RemoveStrongFromTitle.scala
index 4d23a9bc7a..362b70fb65 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/db/migration/V54__RemoveStrongFromTitle.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/db/migration/V54__RemoveStrongFromTitle.scala
@@ -45,7 +45,7 @@ class V54__RemoveStrongFromTitle extends BaseJavaMigration {
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
- .withinTx { session => migrateRows(session) }
+ .withinTx { session => migrateRows(using session) }
private def migrateRows(implicit session: DBSession): Unit = {
val count = countAllRows.get
diff --git a/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala b/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala
index f1c9f1be67..aa88673a3b 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala
@@ -16,8 +16,8 @@ class R__SetArticleLanguageFromTaxonomy(properties: ArticleApiProperties)
extends BaseJavaMigration
with Props
with DBArticle {
- override val props: ArticleApiProperties = properties
- override def getChecksum: Integer = 1 // Change this to something else if you want to repeat migration
+ override lazy val props: ArticleApiProperties = properties
+ override def getChecksum: Integer = 1 // Change this to something else if you want to repeat migration
override def migrate(context: Context): Unit = {}
}
diff --git a/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala b/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala
index b3716f1817..e93ca56877 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala
@@ -12,6 +12,6 @@ import no.ndla.articleapi.{ArticleApiProperties, Props}
import org.flywaydb.core.api.migration.{BaseJavaMigration, Context}
class V33__ConvertLanguageUnknown(properties: ArticleApiProperties) extends BaseJavaMigration with Props {
- override val props: ArticleApiProperties = properties
- override def migrate(context: Context): Unit = {}
+ override lazy val props: ArticleApiProperties = properties
+ override def migrate(context: Context): Unit = {}
}
diff --git a/article-api/src/main/scala/no/ndla/articleapi/integration/FrontpageApiClient.scala b/article-api/src/main/scala/no/ndla/articleapi/integration/FrontpageApiClient.scala
index 4a667ba99e..8c2ece9d18 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/integration/FrontpageApiClient.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/integration/FrontpageApiClient.scala
@@ -19,7 +19,7 @@ import scala.util.Try
trait FrontpageApiClient {
this: NdlaClient & ConverterService & Props =>
- val frontpageApiClient: FrontpageApiClient
+ lazy val frontpageApiClient: FrontpageApiClient
class FrontpageApiClient(FrontpageApiBaseUrl: String = props.FrontpageApiUrl) extends StrictLogging {
diff --git a/article-api/src/main/scala/no/ndla/articleapi/integration/ImageApiClient.scala b/article-api/src/main/scala/no/ndla/articleapi/integration/ImageApiClient.scala
index 490c88b6a5..1d4dbafa9f 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/integration/ImageApiClient.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/integration/ImageApiClient.scala
@@ -20,7 +20,7 @@ import scala.util.Try
trait ImageApiClient {
this: NdlaClient & ConverterService & Props =>
- val imageApiClient: ImageApiClient
+ lazy val imageApiClient: ImageApiClient
class ImageApiClient {
private val Endpoint = s"http://${props.ImageApiHost}/image-api/v3/images"
diff --git a/article-api/src/main/scala/no/ndla/articleapi/repository/ArticleRepository.scala b/article-api/src/main/scala/no/ndla/articleapi/repository/ArticleRepository.scala
index 47ff0828d6..5a0b6ce99d 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/repository/ArticleRepository.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/repository/ArticleRepository.scala
@@ -21,7 +21,7 @@ import scala.util.{Failure, Success, Try}
trait ArticleRepository {
this: DataSource & DBArticle =>
- val articleRepository: ArticleRepository
+ lazy val articleRepository: ArticleRepository
class ArticleRepository extends StrictLogging {
@@ -130,7 +130,7 @@ trait ArticleRepository {
ORDER BY revision DESC
LIMIT 1
"""
- )(session)
+ )(using session)
def withIdAndRevision(articleId: Long, revision: Int): Option[ArticleRow] = {
articleWhere(
@@ -188,8 +188,8 @@ trait ArticleRepository {
private def externalIdsFromResultSet(wrappedResultSet: WrappedResultSet): List[String] = {
Option(wrappedResultSet.array("external_id"))
- .map(_.getArray.asInstanceOf[Array[String]])
- .getOrElse(Array.empty)
+ .map(x => x.getArray.asInstanceOf[Array[String]])
+ .getOrElse(Array.empty[String])
.toList
}
diff --git a/article-api/src/main/scala/no/ndla/articleapi/service/ConverterService.scala b/article-api/src/main/scala/no/ndla/articleapi/service/ConverterService.scala
index a21dbbb24a..784a0d6ad9 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/service/ConverterService.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/service/ConverterService.scala
@@ -49,9 +49,7 @@ import scala.util.{Failure, Success, Try}
trait ConverterService {
this: Clock & ArticleRepository & Props =>
- val converterService: ConverterService
-
- import props.*
+ lazy val converterService: ConverterService
class ConverterService extends StrictLogging {
@@ -374,7 +372,7 @@ trait ConverterService {
private def toApiArticleMetaImage(metaImage: ArticleMetaImage): api.ArticleMetaImageDTO = {
api.ArticleMetaImageDTO(
- s"${externalApiUrls("raw-image")}/${metaImage.imageId}",
+ s"${props.externalApiUrls("raw-image")}/${metaImage.imageId}",
metaImage.altText,
metaImage.language
)
diff --git a/article-api/src/main/scala/no/ndla/articleapi/service/ReadService.scala b/article-api/src/main/scala/no/ndla/articleapi/service/ReadService.scala
index 5ee5aa66a7..391c18d1ae 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/service/ReadService.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/service/ReadService.scala
@@ -40,7 +40,7 @@ import scala.util.{Failure, Success, Try}
trait ReadService {
this: ArticleRepository & FeideApiClient & ConverterService & ArticleSearchService & SearchConverterService &
MemoizeHelpers & Props & ErrorHandling & FrontpageApiClient =>
- val readService: ReadService
+ lazy val readService: ReadService
class ReadService extends StrictLogging {
def getInternalIdByExternalId(externalId: String): Option[api.ArticleIdV2DTO] =
diff --git a/article-api/src/main/scala/no/ndla/articleapi/service/WriteService.scala b/article-api/src/main/scala/no/ndla/articleapi/service/WriteService.scala
index e1441c018b..8c415af167 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/service/WriteService.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/service/WriteService.scala
@@ -20,7 +20,6 @@ import no.ndla.database.DBUtility
import no.ndla.language.Language
import scalikejdbc.{AutoSession, DBSession}
import cats.implicits.*
-import no.ndla.common.implicits.TryQuestionMark
import no.ndla.network.clients.SearchApiClient
import java.util.concurrent.{ExecutorService, Executors}
@@ -30,7 +29,7 @@ import scala.util.{Failure, Success, Try}
trait WriteService {
this: ArticleRepository & ConverterService & ContentValidator & ArticleIndexService & ReadService & SearchApiClient &
DBUtility =>
- val writeService: WriteService
+ lazy val writeService: WriteService
class WriteService extends StrictLogging {
private val executor: ExecutorService = Executors.newSingleThreadExecutor
@@ -91,7 +90,7 @@ trait WriteService {
skipValidation: Boolean
)(session: DBSession = AutoSession): Try[Article] = for {
_ <- performArticleValidation(article, externalIds, useSoftValidation, skipValidation, useImportValidation)
- domainArticle <- articleRepository.updateArticleFromDraftApi(article, externalIds)(session)
+ domainArticle <- articleRepository.updateArticleFromDraftApi(article, externalIds)(using session)
_ <- articleIndexService.indexDocument(domainArticle)
_ <- Try(searchApiClient.indexDocument("article", domainArticle, None))
} yield domainArticle
@@ -107,7 +106,7 @@ trait WriteService {
case None => Failure(NotFoundException(s"Could not find article with id '$articleId' to partial publish"))
case Some(existingArticle) =>
val newArticle = converterService.updateArticleFields(existingArticle, partialArticle)
- val externalIds = articleRepository.getExternalIdsFromId(articleId)(session)
+ val externalIds = articleRepository.getExternalIdsFromId(articleId)(using session)
for {
insertedArticle <- updateArticle(
newArticle,
@@ -122,22 +121,24 @@ trait WriteService {
}
def partialUpdateBulk(bulkInput: PartialPublishArticlesBulkDTO): Try[Unit] = {
- DBUtil.rollbackOnFailure { session =>
- bulkInput.idTo.toList.traverse { case (id, ppa) =>
- val updateResult = partialUpdate(
- id,
- ppa,
- Language.AllLanguages,
- fallback = true,
- isInBulk = true
- )(session).unit
-
- updateResult.recoverWith { case _: NotFoundException =>
- logger.warn(s"Article with id '$id' was not found when bulk partial publishing")
- Success(())
+ DBUtil
+ .rollbackOnFailure { session =>
+ bulkInput.idTo.toList.traverse { case (id, ppa) =>
+ val updateResult = partialUpdate(
+ id,
+ ppa,
+ Language.AllLanguages,
+ fallback = true,
+ isInBulk = true
+ )(session).map(_ => ())
+
+ updateResult.recoverWith { case _: NotFoundException =>
+ logger.warn(s"Article with id '$id' was not found when bulk partial publishing")
+ Success(())
+ }
}
}
- }.unit
+ .map(_ => ())
}
def unpublishArticle(id: Long, revision: Option[Int]): Try[api.ArticleIdV2DTO] = {
diff --git a/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleIndexService.scala b/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleIndexService.scala
index 8c8615039d..2c2f87c451 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleIndexService.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleIndexService.scala
@@ -19,9 +19,9 @@ import no.ndla.common.model.domain.article.Article
trait ArticleIndexService {
this: SearchConverterService & IndexService & ArticleRepository & Props =>
- val articleIndexService: ArticleIndexService
+ lazy val articleIndexService: ArticleIndexService
- class ArticleIndexService extends StrictLogging with IndexService {
+ class ArticleIndexService extends IndexService with StrictLogging {
override val documentType: String = props.ArticleSearchDocument
override val searchIndex: String = props.ArticleSearchIndex
diff --git a/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleSearchService.scala b/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleSearchService.scala
index bba2c4ff76..026b5fc395 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleSearchService.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/service/search/ArticleSearchService.scala
@@ -30,14 +30,12 @@ import scala.util.{Failure, Success, Try}
trait ArticleSearchService {
this: Elastic4sClient & SearchConverterService & SearchService & ArticleIndexService & ConverterService & Props &
ErrorHandling =>
- val articleSearchService: ArticleSearchService
-
- import props.*
+ lazy val articleSearchService: ArticleSearchService
class ArticleSearchService extends StrictLogging with SearchService[api.ArticleSummaryV2DTO] {
private val noCopyright = boolQuery().not(termQuery("license", License.Copyrighted.toString))
- override val searchIndex: String = ArticleSearchIndex
+ override val searchIndex: String = props.ArticleSearchIndex
override def hitToApiModel(hit: String, language: String): api.ArticleSummaryV2DTO = {
converterService.hitAsArticleSummaryV2(hit, language)
@@ -114,9 +112,9 @@ trait ArticleSearchService {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.pageSize * settings.page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(ArticleErrorHelpers.ResultWindowTooLargeException())
} else {
@@ -132,7 +130,7 @@ trait ArticleSearchService {
// Only add scroll param if it is first page
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/article-api/src/main/scala/no/ndla/articleapi/service/search/IndexService.scala b/article-api/src/main/scala/no/ndla/articleapi/service/search/IndexService.scala
index 45363dfde0..4b90e2ee33 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/service/search/IndexService.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/service/search/IndexService.scala
@@ -24,7 +24,7 @@ import scala.util.{Failure, Success, Try}
trait IndexService {
this: Elastic4sClient & BaseIndexService & Props & ArticleRepository & SearchLanguage =>
- trait IndexService extends BaseIndexService with StrictLogging {
+ abstract class IndexService extends BaseIndexService with StrictLogging {
override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
def createIndexRequest(domainModel: Article, indexName: String): IndexRequest
diff --git a/article-api/src/main/scala/no/ndla/articleapi/service/search/SearchConverterService.scala b/article-api/src/main/scala/no/ndla/articleapi/service/search/SearchConverterService.scala
index 8450cb776c..65f015c3ee 100644
--- a/article-api/src/main/scala/no/ndla/articleapi/service/search/SearchConverterService.scala
+++ b/article-api/src/main/scala/no/ndla/articleapi/service/search/SearchConverterService.scala
@@ -19,7 +19,7 @@ import org.jsoup.Jsoup
trait SearchConverterService {
this: ConverterService & SearchLanguage =>
- val searchConverterService: SearchConverterService
+ lazy val searchConverterService: SearchConverterService
class SearchConverterService extends StrictLogging {
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 f57ccde539..b5d84ec6e3 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
@@ -26,7 +26,7 @@ import scala.util.{Failure, Success, Try}
trait ContentValidator {
this: ArticleRepository & Props =>
- val contentValidator: ContentValidator
+ lazy val contentValidator: ContentValidator
class ContentValidator {
private val inlineHtmlTags = props.InlineHtmlTags
diff --git a/article-api/src/test/scala/no/ndla/articleapi/TestData.scala b/article-api/src/test/scala/no/ndla/articleapi/TestData.scala
index 3fb81aaa76..104cb99a5c 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/TestData.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/TestData.scala
@@ -18,10 +18,10 @@ import no.ndla.common.model.domain.{article, *}
import no.ndla.common.model.domain.language.OptLanguageFields
import no.ndla.mapping.License
-trait TestData {
+trait TestDataT {
this: Props =>
- class TestData {
+ class TestDataClass {
private val publicDomainCopyright =
Copyright(License.PublicDomain.toString, None, List(), List(), List(), None, None, false)
private val byNcSaCopyright =
diff --git a/article-api/src/test/scala/no/ndla/articleapi/TestEnvironment.scala b/article-api/src/test/scala/no/ndla/articleapi/TestEnvironment.scala
index 45f3240737..8db6b96369 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/TestEnvironment.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/TestEnvironment.scala
@@ -54,46 +54,47 @@ trait TestEnvironment
with MemoizeHelpers
with DBArticle
with Props
- with TestData
+ with TestDataT
with DBMigrator
with SearchLanguage
with FrontpageApiClient
with ImageApiClient {
- lazy val props: ArticleApiProperties = new ArticleApiProperties {
+ override lazy val props: ArticleApiProperties = new ArticleApiProperties {
override def InlineHtmlTags: Set[String] = Set("code", "em", "span", "strong", "sub", "sup")
override def IntroductionHtmlTags: Set[String] = InlineHtmlTags ++ Set("br", "p")
}
- val TestData: TestData = new TestData
- val migrator: DBMigrator = mock[DBMigrator]
- val DBUtil: DBUtility = mock[DBUtility]
- val articleSearchService: ArticleSearchService = mock[ArticleSearchService]
- val articleIndexService: ArticleIndexService = mock[ArticleIndexService]
+ lazy val TestData: TestDataClass = new TestDataClass
+ override lazy val migrator: DBMigrator = mock[DBMigrator]
+ override lazy val DBUtil: DBUtility = mock[DBUtility]
- val internController: InternController = mock[InternController]
- val articleControllerV2: ArticleControllerV2 = mock[ArticleControllerV2]
+ override lazy val articleSearchService: ArticleSearchService = mock[ArticleSearchService]
+ override lazy val articleIndexService: ArticleIndexService = mock[ArticleIndexService]
- val healthController: TapirHealthController = mock[TapirHealthController]
+ override lazy val internController: InternController = mock[InternController]
+ override lazy val articleControllerV2: ArticleControllerV2 = mock[ArticleControllerV2]
- val dataSource: HikariDataSource = mock[HikariDataSource]
- val articleRepository: ArticleRepository = mock[ArticleRepository]
+ override lazy val healthController: TapirHealthController = mock[TapirHealthController]
- val converterService: ConverterService = mock[ConverterService]
- val readService: ReadService = mock[ReadService]
- val writeService: WriteService = mock[WriteService]
- val contentValidator: ContentValidator = mock[ContentValidator]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val articleRepository: ArticleRepository = mock[ArticleRepository]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val searchConverterService: SearchConverterService = mock[SearchConverterService]
- var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
- val searchApiClient: SearchApiClient = mock[SearchApiClient]
- val feideApiClient: FeideApiClient = mock[FeideApiClient]
- val redisClient: RedisClient = mock[RedisClient]
- val frontpageApiClient: FrontpageApiClient = mock[FrontpageApiClient]
- val imageApiClient: ImageApiClient = mock[ImageApiClient]
+ override lazy val converterService: ConverterService = mock[ConverterService]
+ override lazy val readService: ReadService = mock[ReadService]
+ override lazy val writeService: WriteService = mock[WriteService]
+ override lazy val contentValidator: ContentValidator = mock[ContentValidator]
- val clock: SystemClock = mock[SystemClock]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val searchConverterService: SearchConverterService = mock[SearchConverterService]
+ var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
+ override lazy val searchApiClient: SearchApiClient = mock[SearchApiClient]
+ override lazy val feideApiClient: FeideApiClient = mock[FeideApiClient]
+ override lazy val redisClient: RedisClient = mock[RedisClient]
+ override lazy val frontpageApiClient: FrontpageApiClient = mock[FrontpageApiClient]
+ override lazy val imageApiClient: ImageApiClient = mock[ImageApiClient]
+
+ override lazy val clock: SystemClock = mock[SystemClock]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/article-api/src/test/scala/no/ndla/articleapi/controller/ArticleControllerV2Test.scala b/article-api/src/test/scala/no/ndla/articleapi/controller/ArticleControllerV2Test.scala
index 9c5c66a90d..5f0cf5cafd 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/controller/ArticleControllerV2Test.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/controller/ArticleControllerV2Test.scala
@@ -38,7 +38,7 @@ class ArticleControllerV2Test extends UnitSuite with TestEnvironment with TapirC
val authHeaderWithWrongRole =
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9FSTFNVVU0T0RrNU56TTVNekkyTXpaRE9EazFOMFl3UXpkRE1EUXlPRFZDUXpRM1FUSTBNQSJ9.eyJodHRwczovL25kbGEubm8vY2xpZW50X2lkIjoieHh4eXl5IiwiaXNzIjoiaHR0cHM6Ly9uZGxhLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJ4eHh5eXlAY2xpZW50cyIsImF1ZCI6Im5kbGFfc3lzdGVtIiwiaWF0IjoxNTEwMzA1NzczLCJleHAiOjE1MTAzOTIxNzMsInNjb3BlIjoic29tZTpvdGhlciIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.Hbmh9KX19nx7yT3rEcP9pyzRO0uQJBRucfqH9QEZtLyXjYj_fAyOhsoicOVEbHSES7rtdiJK43-gijSpWWmGWOkE6Ym7nHGhB_nLdvp_25PDgdKHo-KawZdAyIcJFr5_t3CJ2Z2IPVbrXwUd99vuXEBaV0dMwkT0kDtkwHuS-8E"
- lazy val controller: ArticleControllerV2 = new ArticleControllerV2
+ override val controller: ArticleControllerV2 = new ArticleControllerV2
override def beforeEach(): Unit = {
reset(clock)
diff --git a/article-api/src/test/scala/no/ndla/articleapi/repository/ArticleRepositoryTest.scala b/article-api/src/test/scala/no/ndla/articleapi/repository/ArticleRepositoryTest.scala
index d156cd8de0..2ccc7f04c6 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/repository/ArticleRepositoryTest.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/repository/ArticleRepositoryTest.scala
@@ -16,14 +16,15 @@ import no.ndla.common.model.domain.Tag
import no.ndla.common.model.domain.article.Article
import no.ndla.scalatestsuite.DatabaseIntegrationSuite
import scalikejdbc.AutoSession
+import org.scalatest.EitherValues.convertEitherToValuable
import java.net.Socket
import scala.util.{Success, Try}
class ArticleRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with TestEnvironment {
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator = new DBMigrator
- var repository: ArticleRepository = _
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator = new DBMigrator
+ var repository: ArticleRepository = _
lazy val sampleArticle: Article = TestData.sampleArticleWithByNcSa
@@ -86,7 +87,7 @@ class ArticleRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with
val externalIds = List("123", "456")
val sampleArticle: Article =
TestData.sampleDomainArticle.copy(id = Some(5), revision = Some(42))
- val Success(res: Article) = repository.updateArticleFromDraftApi(sampleArticle, externalIds)
+ val res = repository.updateArticleFromDraftApi(sampleArticle, externalIds).get
res.id.isDefined should be(true)
repository.withId(res.id.get)(AutoSession).get.article.get should be(sampleArticle)
@@ -226,7 +227,7 @@ class ArticleRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with
List("6000", "10")
)
- val Right(relatedId) = repository.withId(1)(AutoSession).toArticle.get.relatedContent.head
+ val relatedId = repository.withId(1)(AutoSession).toArticle.get.relatedContent.head.value
relatedId should be(2L)
}
diff --git a/article-api/src/test/scala/no/ndla/articleapi/service/ReadServiceTest.scala b/article-api/src/test/scala/no/ndla/articleapi/service/ReadServiceTest.scala
index 0521ee1025..6a43845eb4 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/service/ReadServiceTest.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/service/ReadServiceTest.scala
@@ -56,8 +56,8 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
val articleContent2: ArticleContent = ArticleContent(content2, "und")
- override val readService = new ReadService
- override val converterService = new ConverterService
+ override lazy val readService = new ReadService
+ override lazy val converterService = new ConverterService
override def beforeEach(): Unit = {
reset(feideApiClient)
@@ -182,15 +182,17 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
.thenReturn(Seq(toArticleRow(article1), toArticleRow(article2), toArticleRow(article3)))
when(articleRepository.getExternalIdsFromId(any)(any)).thenReturn(List(""), List(""), List(""))
- val Success(result) =
- readService.getArticlesByIds(
- articleIds = ids,
- language = "nb",
- fallback = true,
- page = 1,
- pageSize = 10,
- feideAccessToken = None
- )
+ val result =
+ readService
+ .getArticlesByIds(
+ articleIds = ids,
+ language = "nb",
+ fallback = true,
+ page = 1,
+ pageSize = 10,
+ feideAccessToken = None
+ )
+ .get
result.length should be(3)
verify(feideApiClient, times(0)).getFeideExtendedUser(Some(feideId))
@@ -209,15 +211,17 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
.thenReturn(Seq(toArticleRow(article1), toArticleRow(article2), toArticleRow(article3)))
when(articleRepository.getExternalIdsFromId(any)(any)).thenReturn(List(""), List(""), List(""))
- val Success(result) =
- readService.getArticlesByIds(
- articleIds = ids,
- language = "nb",
- fallback = true,
- page = 1,
- pageSize = 10,
- feideAccessToken = Some(feideId)
- )
+ val result =
+ readService
+ .getArticlesByIds(
+ articleIds = ids,
+ language = "nb",
+ fallback = true,
+ page = 1,
+ pageSize = 10,
+ feideAccessToken = Some(feideId)
+ )
+ .get
result.length should be(3)
verify(feideApiClient, times(1)).getFeideExtendedUser(Some(feideId))
@@ -236,15 +240,17 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
.thenReturn(Seq(toArticleRow(article1), toArticleRow(article2), toArticleRow(article3)))
when(articleRepository.getExternalIdsFromId(any)(any)).thenReturn(List(""), List(""), List(""))
- val Success(result) =
- readService.getArticlesByIds(
- articleIds = ids,
- language = "nb",
- fallback = true,
- page = 1,
- pageSize = 10,
- feideAccessToken = Some(feideId)
- )
+ val result =
+ readService
+ .getArticlesByIds(
+ articleIds = ids,
+ language = "nb",
+ fallback = true,
+ page = 1,
+ pageSize = 10,
+ feideAccessToken = Some(feideId)
+ )
+ .get
result.length should be(2)
result.map(res => res.availability).contains("teacher") should be(false)
@@ -263,15 +269,17 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
when(articleRepository.getExternalIdsFromId(any)(any)).thenReturn(List(""), List(""), List(""))
when(feideApiClient.getFeideExtendedUser(any)).thenReturn(Failure(new RuntimeException))
- val Success(result) =
- readService.getArticlesByIds(
- articleIds = ids,
- language = "nb",
- fallback = true,
- page = 1,
- pageSize = 10,
- feideAccessToken = None
- )
+ val result =
+ readService
+ .getArticlesByIds(
+ articleIds = ids,
+ language = "nb",
+ fallback = true,
+ page = 1,
+ pageSize = 10,
+ feideAccessToken = None
+ )
+ .get
result.length should be(2)
result.map(res => res.availability).contains("teacher") should be(false)
@@ -280,16 +288,21 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
test("that getArticlesByIds fails if no ids were given") {
reset(articleRepository)
- val Failure(result: ValidationException) =
- readService.getArticlesByIds(
- articleIds = List.empty,
- language = "nb",
- fallback = true,
- page = 1,
- pageSize = 10,
- feideAccessToken = None
- )
- result.errors.head.message should be("Query parameter 'ids' is missing")
+ val result =
+ readService
+ .getArticlesByIds(
+ articleIds = List.empty,
+ language = "nb",
+ fallback = true,
+ page = 1,
+ pageSize = 10,
+ feideAccessToken = None
+ )
+ result.failed.get
+ .asInstanceOf[ValidationException]
+ .errors
+ .head
+ .message should be("Query parameter 'ids' is missing")
verify(articleRepository, times(0)).withIds(any, any, any)(any)
}
diff --git a/article-api/src/test/scala/no/ndla/articleapi/service/WriteServiceTest.scala b/article-api/src/test/scala/no/ndla/articleapi/service/WriteServiceTest.scala
index b85afd45f1..0670526748 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/service/WriteServiceTest.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/service/WriteServiceTest.scala
@@ -21,7 +21,7 @@ import scalikejdbc.DBSession
import scala.util.{Success, Try}
class WriteServiceTest extends UnitSuite with TestEnvironment {
- override val converterService = new ConverterService
+ override lazy val converterService = new ConverterService
val today: NDLADate = NDLADate.now()
val yesterday: NDLADate = NDLADate.now().minusDays(1)
diff --git a/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchConverterServiceTest.scala b/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchConverterServiceTest.scala
index f68bc6eea7..0f7113c9ff 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchConverterServiceTest.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchConverterServiceTest.scala
@@ -16,8 +16,8 @@ import no.ndla.search.model.{SearchableLanguageList, SearchableLanguageValues}
class ArticleSearchConverterServiceTest extends UnitSuite with TestEnvironment {
- override val searchConverterService = new SearchConverterService
- val sampleArticle: Article = TestData.sampleArticleWithPublicDomain.copy()
+ override lazy val searchConverterService = new SearchConverterService
+ val sampleArticle: Article = TestData.sampleArticleWithPublicDomain.copy()
val titles: List[Title] = List(
Title("Bokmål tittel", "nb"),
diff --git a/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchServiceTest.scala b/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchServiceTest.scala
index 5de1167b92..e3ec597031 100644
--- a/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchServiceTest.scala
+++ b/article-api/src/test/scala/no/ndla/articleapi/service/search/ArticleSearchServiceTest.scala
@@ -18,20 +18,15 @@ import no.ndla.language.Language
import no.ndla.mapping.License.{CC_BY_NC_SA, Copyrighted, PublicDomain}
import no.ndla.scalatestsuite.ElasticsearchIntegrationSuite
-import scala.util.Success
-
class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
- import TestData.testSettings
- import props.*
-
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val articleSearchService = new ArticleSearchService
- override val articleIndexService: ArticleIndexService = new ArticleIndexService {
+ override lazy val articleSearchService = new ArticleSearchService
+ override lazy val articleIndexService: ArticleIndexService = new ArticleIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val byNcSa: Copyright =
Copyright(
@@ -250,97 +245,101 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("That getStartAtAndNumResults returns SEARCH_MAX_PAGE_SIZE for value greater than SEARCH_MAX_PAGE_SIZE") {
- articleSearchService.getStartAtAndNumResults(0, 10001) should equal((0, MaxPageSize))
+ articleSearchService.getStartAtAndNumResults(0, 10001) should equal((0, props.MaxPageSize))
}
test(
"That getStartAtAndNumResults returns the correct calculated start at for page and page-size with default page-size"
) {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- articleSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal((expectedStartAt, DefaultPageSize))
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ articleSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
+ )
}
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
val page = 123
- val expectedStartAt = (page - 1) * DefaultPageSize
- articleSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal((expectedStartAt, DefaultPageSize))
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ articleSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
+ )
}
test("searching should return only articles of a given type if a type filter is specified") {
- val Success(results) =
- articleSearchService.matchingQuery(testSettings.copy(articleTypes = Seq(ArticleType.TopicArticle.entryName)))
+ val results = articleSearchService
+ .matchingQuery(TestData.testSettings.copy(articleTypes = Seq(ArticleType.TopicArticle.entryName)))
+ .get
results.totalCount should be(3)
- val Success(results2) = articleSearchService.matchingQuery(testSettings.copy(articleTypes = Seq.empty))
+ val results2 = articleSearchService.matchingQuery(TestData.testSettings.copy(articleTypes = Seq.empty)).get
results2.totalCount should be(10)
}
test("That searching without query returns all documents ordered by id ascending") {
- val Success(results) =
- articleSearchService.matchingQuery(testSettings.copy(query = None))
- val hits = results.results
+ val results = articleSearchService.matchingQuery(TestData.testSettings.copy(query = None)).get
+ val hits = results.results
results.totalCount should be(10)
hits.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 8, 9, 11, 13))
}
test("That searching returns all documents ordered by id descending") {
- val Success(results) = articleSearchService.matchingQuery(testSettings.copy(sort = Sort.ByIdDesc))
- val hits = results.results
+ val results = articleSearchService.matchingQuery(TestData.testSettings.copy(sort = Sort.ByIdDesc)).get
+ val hits = results.results
results.totalCount should be(10)
hits.map(_.id) should be(Seq(13, 11, 9, 8, 7, 6, 5, 3, 2, 1))
}
test("That searching returns all documents ordered by title ascending") {
- val Success(results) = articleSearchService.matchingQuery(testSettings.copy(sort = Sort.ByTitleAsc))
- val hits = results.results
+ val results = articleSearchService.matchingQuery(TestData.testSettings.copy(sort = Sort.ByTitleAsc)).get
+ val hits = results.results
results.totalCount should be(10)
hits.map(_.id) should be(Seq(8, 1, 3, 9, 5, 11, 6, 2, 7, 13))
}
test("That searching returns all documents ordered by title descending") {
- val Success(results) = articleSearchService.matchingQuery(testSettings.copy(sort = Sort.ByTitleDesc))
- val hits = results.results
+ val results = articleSearchService.matchingQuery(TestData.testSettings.copy(sort = Sort.ByTitleDesc)).get
+ val hits = results.results
results.totalCount should be(10)
hits.map(_.id) should be(Seq(13, 7, 2, 6, 11, 5, 9, 3, 1, 8))
}
test("That searching returns all documents ordered by lastUpdated descending") {
- val results = articleSearchService.matchingQuery(testSettings.copy(sort = Sort.ByLastUpdatedDesc))
+ val results = articleSearchService.matchingQuery(TestData.testSettings.copy(sort = Sort.ByLastUpdatedDesc))
val hits = results.get.results
results.get.totalCount should be(10)
hits.map(_.id) should be(Seq(3, 2, 1, 8, 9, 11, 13, 7, 6, 5))
}
test("That all returns all documents ordered by lastUpdated ascending") {
- val Success(results) = articleSearchService.matchingQuery(testSettings.copy(sort = Sort.ByLastUpdatedAsc))
- val hits = results.results
+ val results = articleSearchService.matchingQuery(TestData.testSettings.copy(sort = Sort.ByLastUpdatedAsc)).get
+ val hits = results.results
results.totalCount should be(10)
hits.map(_.id) should be(Seq(5, 6, 7, 8, 9, 11, 13, 1, 2, 3))
}
test("That all filtering on license only returns documents with given license") {
- val Success(results) = articleSearchService.matchingQuery(
- testSettings.copy(sort = Sort.ByTitleAsc, license = Some(PublicDomain.toString))
- )
+ val results = articleSearchService
+ .matchingQuery(TestData.testSettings.copy(sort = Sort.ByTitleAsc, license = Some(PublicDomain.toString)))
+ .get
val hits = results.results
results.totalCount should be(9)
hits.map(_.id) should be(Seq(8, 3, 9, 5, 11, 6, 2, 7, 13))
}
test("That all filtered by id only returns documents with the given ids") {
- val Success(results) = articleSearchService.matchingQuery(testSettings.copy(withIdIn = List(1, 3)))
- val hits = results.results
+ val results = articleSearchService.matchingQuery(TestData.testSettings.copy(withIdIn = List(1, 3))).get
+ val hits = results.results
results.totalCount should be(2)
hits.head.id should be(1)
hits.last.id should be(3)
}
test("That paging returns only hits on current page and not more than page-size") {
- val Success(page1) =
- articleSearchService.matchingQuery(testSettings.copy(sort = Sort.ByTitleAsc, page = 1, pageSize = 2))
- val Success(page2) =
- articleSearchService.matchingQuery(testSettings.copy(sort = Sort.ByTitleAsc, page = 2, pageSize = 2))
+ val page1 =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(sort = Sort.ByTitleAsc, page = 1, pageSize = 2)).get
+ val page2 =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(sort = Sort.ByTitleAsc, page = 2, pageSize = 2)).get
val hits1 = page1.results
val hits2 = page2.results
@@ -358,30 +357,32 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
test("matchingQuery should filter results based on an article type filter") {
val results = articleSearchService.matchingQuery(
- testSettings
+ TestData.testSettings
.copy(query = Some("bil"), sort = Sort.ByRelevanceDesc, articleTypes = Seq(ArticleType.TopicArticle.entryName))
)
results.get.totalCount should be(0)
val results2 = articleSearchService.matchingQuery(
- testSettings
+ TestData.testSettings
.copy(query = Some("bil"), sort = Sort.ByRelevanceDesc, articleTypes = Seq(ArticleType.Standard.entryName))
)
results2.get.totalCount should be(3)
}
test("That search matches title and html-content ordered by relevance descending") {
- val Success(results) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("bil"), sort = Sort.ByRelevanceDesc))
+ val results =
+ articleSearchService
+ .matchingQuery(TestData.testSettings.copy(query = Some("bil"), sort = Sort.ByRelevanceDesc))
+ .get
val hits = results.results
results.totalCount should be(3)
hits.map(_.id) should be(Seq(1, 5, 3))
}
test("That search combined with filter by id only returns documents matching the query with one of the given ids") {
- val Success(results) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("bil"), withIdIn = List(3), sort = Sort.ByRelevanceDesc)
- )
+ val results = articleSearchService
+ .matchingQuery(TestData.testSettings.copy(query = Some("bil"), withIdIn = List(3), sort = Sort.ByRelevanceDesc))
+ .get
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(3)
@@ -389,77 +390,104 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("That search matches title") {
- val Success(results) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("Pingvinen"), sort = Sort.ByTitleAsc))
+ val results =
+ articleSearchService
+ .matchingQuery(TestData.testSettings.copy(query = Some("Pingvinen"), sort = Sort.ByTitleAsc))
+ .get
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(2)
}
test("That search matches tags") {
- val Success(results) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("and"), sort = Sort.ByTitleAsc))
+ val results =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(query = Some("and"), sort = Sort.ByTitleAsc)).get
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(3)
}
test("That search does not return superman since it has license copyrighted and license is not specified") {
- val Success(results) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("supermann"), sort = Sort.ByTitleAsc))
+ val results =
+ articleSearchService
+ .matchingQuery(TestData.testSettings.copy(query = Some("supermann"), sort = Sort.ByTitleAsc))
+ .get
results.totalCount should be(0)
}
test("That search returns superman since license is specified as copyrighted") {
- val Success(results) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("supermann"), sort = Sort.ByTitleAsc, license = Some(Copyrighted.toString))
- )
+ val results = articleSearchService
+ .matchingQuery(
+ TestData.testSettings
+ .copy(query = Some("supermann"), sort = Sort.ByTitleAsc, license = Some(Copyrighted.toString))
+ )
+ .get
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(4)
}
test("Searching with logical AND only returns results with all terms") {
- val Success(search1) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("bilde + bil"), sort = Sort.ByTitleAsc))
+ val search1 =
+ articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("bilde + bil"), sort = Sort.ByTitleAsc)
+ )
+ .get
val hits1 = search1.results
hits1.map(_.id) should equal(Seq(1, 3, 5))
- val Success(search2) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("batmen + bil"), sort = Sort.ByTitleAsc))
+ val search2 =
+ articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("batmen + bil"), sort = Sort.ByTitleAsc)
+ )
+ .get
val hits2 = search2.results
hits2.map(_.id) should equal(Seq(1))
- val Success(search3) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("bil + bilde + -flaggermusmann"), sort = Sort.ByTitleAsc)
- )
+ val search3 = articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("bil + bilde + -flaggermusmann"), sort = Sort.ByTitleAsc)
+ )
+ .get
val hits3 = search3.results
hits3.map(_.id) should equal(Seq(3, 5))
- val Success(search4) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("bil + -hulken"), sort = Sort.ByTitleAsc))
+ val search4 =
+ articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("bil + -hulken"), sort = Sort.ByTitleAsc)
+ )
+ .get
val hits4 = search4.results
hits4.map(_.id) should equal(Seq(1, 3))
}
test("search in content should be ranked lower than introduction and title") {
- val Success(search) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("mareritt+ragnarok"), sort = Sort.ByRelevanceDesc)
- )
+ val search = articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("mareritt+ragnarok"), sort = Sort.ByRelevanceDesc)
+ )
+ .get
val hits = search.results
hits.map(_.id) should equal(Seq(9, 8))
}
test("Search for all languages should return all articles in different languages") {
- val Success(search) = articleSearchService.matchingQuery(
- testSettings.copy(language = Language.AllLanguages, pageSize = 100, sort = Sort.ByTitleAsc)
- )
+ val search = articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(language = Language.AllLanguages, pageSize = 100, sort = Sort.ByTitleAsc)
+ )
+ .get
search.totalCount should equal(11)
}
test("Search for all languages should return all articles in correct language") {
- val Success(search) =
- articleSearchService.matchingQuery(testSettings.copy(language = Language.AllLanguages, pageSize = 100))
+ val search =
+ articleSearchService
+ .matchingQuery(TestData.testSettings.copy(language = Language.AllLanguages, pageSize = 100))
+ .get
val hits = search.results
search.totalCount should equal(11)
@@ -478,14 +506,16 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("Search for all languages should return all languages if copyrighted") {
- val Success(search) = articleSearchService.matchingQuery(
- testSettings.copy(
- language = Language.AllLanguages,
- license = Some(Copyrighted.toString),
- sort = Sort.ByTitleAsc,
- pageSize = 100
+ val search = articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(
+ language = Language.AllLanguages,
+ license = Some(Copyrighted.toString),
+ sort = Sort.ByTitleAsc,
+ pageSize = 100
+ )
)
- )
+ .get
val hits = search.results
search.totalCount should equal(1)
@@ -493,12 +523,17 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("Searching with query for all languages should return language that matched") {
- val Success(searchEn) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("Cats"), language = Language.AllLanguages, sort = Sort.ByRelevanceDesc)
- )
- val Success(searchNb) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("Katter"), language = Language.AllLanguages, sort = Sort.ByRelevanceDesc)
- )
+ val searchEn = articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("Cats"), language = Language.AllLanguages, sort = Sort.ByRelevanceDesc)
+ )
+ .get
+ val searchNb = articleSearchService
+ .matchingQuery(
+ TestData.testSettings
+ .copy(query = Some("Katter"), language = Language.AllLanguages, sort = Sort.ByRelevanceDesc)
+ )
+ .get
searchEn.totalCount should equal(1)
searchEn.results.head.id should equal(11)
@@ -512,9 +547,12 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("metadescription is searchable") {
- val Success(search) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("hurr dirr"), language = Language.AllLanguages, sort = Sort.ByRelevanceDesc)
- )
+ val search = articleSearchService
+ .matchingQuery(
+ TestData.testSettings
+ .copy(query = Some("hurr dirr"), language = Language.AllLanguages, sort = Sort.ByRelevanceDesc)
+ )
+ .get
search.totalCount should equal(1)
search.results.head.id should equal(11)
@@ -523,10 +561,12 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("That searching with fallback parameter returns article in language priority even if doesnt match on language") {
- val Success(search) =
- articleSearchService.matchingQuery(
- testSettings.copy(withIdIn = List(9, 10, 11), language = "en", fallback = true)
- )
+ val search =
+ articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(withIdIn = List(9, 10, 11), language = "en", fallback = true)
+ )
+ .get
search.totalCount should equal(3)
search.results.head.id should equal(9)
@@ -538,8 +578,8 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("That searching for language not in analyzer works as expected") {
- val Success(search) =
- articleSearchService.matchingQuery(testSettings.copy(language = "biz"))
+ val search =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(language = "biz")).get
search.totalCount should equal(1)
search.results.head.id should equal(11)
@@ -547,21 +587,22 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("That searching for language not in index works as expected") {
- val Success(search) =
- articleSearchService.matchingQuery(testSettings.copy(language = "mix"))
+ val search =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(language = "mix")).get
search.totalCount should equal(0)
}
test("That searching for not supported language does not break") {
- val Success(search) =
- articleSearchService.matchingQuery(testSettings.copy(language = "asdf"))
+ val search =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(language = "asdf")).get
search.totalCount should equal(0)
}
test("That metaImage altText is included in the search") {
- val Success(search) = articleSearchService.matchingQuery(testSettings.copy(withIdIn = List(1), fallback = true))
+ val search =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(withIdIn = List(1), fallback = true)).get
search.totalCount should be(1)
search.results.head.metaImage should be(
Some(
@@ -574,21 +615,23 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
val pageSize = 2
val expectedIds = List(1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13).sliding(pageSize, pageSize).toList
- val Success(initialSearch) =
- articleSearchService.matchingQuery(
- testSettings.copy(
- language = Language.AllLanguages,
- pageSize = pageSize,
- fallback = true,
- shouldScroll = true
+ val initialSearch =
+ articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(
+ language = Language.AllLanguages,
+ pageSize = pageSize,
+ fallback = true,
+ shouldScroll = true
+ )
)
- )
+ .get
- val Success(scroll1) = articleSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = articleSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = articleSearchService.scroll(scroll2.scrollId.get, "*")
- val Success(scroll4) = articleSearchService.scroll(scroll3.scrollId.get, "*")
- val Success(scroll5) = articleSearchService.scroll(scroll4.scrollId.get, "*")
+ val scroll1 = articleSearchService.scroll(initialSearch.scrollId.get, "*").get
+ val scroll2 = articleSearchService.scroll(scroll1.scrollId.get, "*").get
+ val scroll3 = articleSearchService.scroll(scroll2.scrollId.get, "*").get
+ val scroll4 = articleSearchService.scroll(scroll3.scrollId.get, "*").get
+ val scroll5 = articleSearchService.scroll(scroll4.scrollId.get, "*").get
initialSearch.results.map(_.id) should be(expectedIds.head)
scroll1.results.map(_.id) should be(expectedIds(1))
@@ -599,16 +642,19 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
}
test("That highlighting works when scrolling") {
- val Success(initialSearch) =
- articleSearchService.matchingQuery(
- testSettings.copy(
- query = Some("about"),
- pageSize = 1,
- fallback = true,
- shouldScroll = true
+ val initialSearch =
+ articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(
+ query = Some("about"),
+ pageSize = 1,
+ fallback = true,
+ shouldScroll = true
+ )
)
- )
- val Success(scroll) = articleSearchService.scroll(initialSearch.scrollId.get, "*")
+ .get
+
+ val scroll = articleSearchService.scroll(initialSearch.scrollId.get, "*").get
initialSearch.results.size should be(1)
initialSearch.results.head.id should be(10)
@@ -621,43 +667,55 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSu
test("That filtering for grepCodes works as expected") {
- val Success(search1) = articleSearchService.matchingQuery(testSettings.copy(grepCodes = Seq("KV123")))
+ val search1 = articleSearchService.matchingQuery(TestData.testSettings.copy(grepCodes = Seq("KV123"))).get
search1.totalCount should be(2)
search1.results.map(_.id) should be(Seq(1, 2))
- val Success(search2) = articleSearchService.matchingQuery(testSettings.copy(grepCodes = Seq("KV123", "KV456")))
+ val search2 =
+ articleSearchService.matchingQuery(TestData.testSettings.copy(grepCodes = Seq("KV123", "KV456"))).get
search2.totalCount should be(3)
search2.results.map(_.id) should be(Seq(1, 2, 3))
- val Success(search3) = articleSearchService.matchingQuery(testSettings.copy(grepCodes = Seq("KV456")))
+ val search3 = articleSearchService.matchingQuery(TestData.testSettings.copy(grepCodes = Seq("KV456"))).get
search3.totalCount should be(3)
search3.results.map(_.id) should be(Seq(1, 2, 3))
}
test("That 'everyone' doesn't see teacher and student articles in search") {
- val Success(search1) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("availability"), availability = Seq(Availability.everyone))
- )
+ val search1 = articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("availability"), availability = Seq(Availability.everyone))
+ )
+ .get
- val Success(search2) =
- articleSearchService.matchingQuery(testSettings.copy(query = Some("availability"), availability = Seq.empty))
+ val search2 =
+ articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("availability"), availability = Seq.empty)
+ )
+ .get
search1.results.map(_.id) should be(Seq(13))
search2.results.map(_.id) should be(Seq(13))
}
test("That 'everyone' doesn't see teacher articles in search") {
- val Success(search1) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("availability"), availability = Seq(Availability.everyone))
- )
+ val search1 = articleSearchService
+ .matchingQuery(
+ TestData.testSettings.copy(query = Some("availability"), availability = Seq(Availability.everyone))
+ )
+ .get
search1.results.map(_.id) should be(Seq(13))
}
test("That 'teachers' sees teacher articles in search") {
- val Success(search1) = articleSearchService.matchingQuery(
- testSettings.copy(query = Some("availability"), availability = Seq(Availability.teacher, Availability.everyone))
- )
+ val search1 = articleSearchService
+ .matchingQuery(
+ TestData.testSettings
+ .copy(query = Some("availability"), availability = Seq(Availability.teacher, Availability.everyone))
+ )
+ .get
search1.results.map(_.id) should be(Seq(12, 13))
}
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 d39af83f6a..6537b18d5c 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
@@ -25,16 +25,24 @@ import no.ndla.common.model.domain.article.Copyright
import no.ndla.common.model.domain.language.OptLanguageFields
import no.ndla.mapping.License.{CC_BY_SA, NA}
-import scala.util.Failure
+import scala.util.{Failure, Try}
class ContentValidatorTest extends UnitSuite with TestEnvironment {
- override val contentValidator = new ContentValidator
- val validDocument = """"""
- val validIntroduction = """
heisann heia
hopp
"""
- val invalidDocument = """"""
- val validDisclaimer =
+ override lazy val contentValidator = new ContentValidator
+ val validDocument = """"""
+ val validIntroduction = """heisann heia
hopp
"""
+ val invalidDocument = """"""
+ val validDisclaimer =
"""hallo!test
"""
+ extension (t: Try[?])
+ def asValidationError: ValidationException = {
+ t match {
+ case Failure(exception: ValidationException) => exception
+ case other => fail(s"Expected a ValidationException, but got: $other")
+ }
+ }
+
test("validateArticle does not throw an exception on a valid document") {
val article = TestData.sampleArticleWithByNcSa.copy(content = Seq(ArticleContent(validDocument, "nb")))
contentValidator.validateArticle(article, false).isSuccess should be(true)
@@ -87,7 +95,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
disclaimer = OptLanguageFields.withValue("hei
", "nb")
)
- val Failure(error: ValidationException) = contentValidator.validateArticle(article, false)
+ val error = contentValidator.validateArticle(article, false).asValidationError
error should be(
ValidationException(
"disclaimer.nb",
@@ -145,9 +153,8 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
}
test("validateArticle should fail if the title exceeds 256 bytes") {
- val article = TestData.sampleArticleWithByNcSa.copy(title = Seq(Title("A" * 257, "nb")))
- val Failure(ex: ValidationException) = contentValidator.validateArticle(article, false)
-
+ val article = TestData.sampleArticleWithByNcSa.copy(title = Seq(Title("A" * 257, "nb")))
+ val ex = contentValidator.validateArticle(article, false).asValidationError
ex.errors.length should be(1)
ex.errors.head.message should be("This field exceeds the maximum permitted length of 256 characters")
}
@@ -325,7 +332,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
test("validation should fail if metaImage altText contains html") {
val article =
TestData.sampleArticleWithByNcSa.copy(metaImage = Seq(ArticleMetaImage("1234", "Ikke krutte god", "nb")))
- val Failure(res1: ValidationException) = contentValidator.validateArticle(article, false)
+ val res1 = contentValidator.validateArticle(article, false).failed.get.asInstanceOf[ValidationException]
res1.errors should be(
Seq(ValidationMessage("metaImage.alt", "The content contains illegal html-characters. No HTML is allowed"))
)
@@ -335,34 +342,40 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
}
test("validation should fail if not imported and tags are < 3") {
- val Failure(res0: ValidationException) = contentValidator.validateArticle(
- TestData.sampleArticleWithByNcSa.copy(tags = Seq(Tag(Seq("a", "b"), "nb"))),
- false
- )
+ val res0 = contentValidator
+ .validateArticle(
+ TestData.sampleArticleWithByNcSa.copy(tags = Seq(Tag(Seq("a", "b"), "nb"))),
+ false
+ )
+ .asValidationError
res0.errors should be(
Seq(ValidationMessage("tags.nb", s"Invalid amount of tags. Articles needs 3 or more tags to be valid."))
)
- val Failure(res1: ValidationException) =
- contentValidator.validateArticle(
- TestData.sampleArticleWithByNcSa.copy(
- tags = Seq(Tag(Seq("a", "b", "c"), "nb"), Tag(Seq("a", "b"), "en"))
- ),
- false
- )
+ val res1 =
+ contentValidator
+ .validateArticle(
+ TestData.sampleArticleWithByNcSa.copy(
+ tags = Seq(Tag(Seq("a", "b", "c"), "nb"), Tag(Seq("a", "b"), "en"))
+ ),
+ false
+ )
+ .asValidationError
res1.errors should be(
Seq(ValidationMessage("tags.en", s"Invalid amount of tags. Articles needs 3 or more tags to be valid."))
)
- val Failure(res2: ValidationException) =
- contentValidator.validateArticle(
- TestData.sampleArticleWithByNcSa.copy(
- tags = Seq(Tag(Seq("a"), "en"), Tag(Seq("a"), "nb"), Tag(Seq("a", "b", "c"), "nn"))
- ),
- false
- )
+ val res2 =
+ contentValidator
+ .validateArticle(
+ TestData.sampleArticleWithByNcSa.copy(
+ tags = Seq(Tag(Seq("a"), "en"), Tag(Seq("a"), "nb"), Tag(Seq("a", "b", "c"), "nn"))
+ ),
+ false
+ )
+ .asValidationError
res2.errors.sortBy(_.field) should be(
Seq(
ValidationMessage("tags.en", s"Invalid amount of tags. Articles needs 3 or more tags to be valid."),
@@ -396,11 +409,13 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
)
res1.isSuccess should be(true)
- val Failure(res2: ValidationException) =
- contentValidator.validateArticle(
- TestData.sampleArticleWithByNcSa.copy(tags = Seq(Tag(Seq("a", "b", "c"), "nn"))),
- isImported = true
- )
+ val res2 =
+ contentValidator
+ .validateArticle(
+ TestData.sampleArticleWithByNcSa.copy(tags = Seq(Tag(Seq("a", "b", "c"), "nn"))),
+ isImported = true
+ )
+ .asValidationError
res2.errors should be(
Seq(
ValidationMessage("tags.nn", s"The content contains illegal html-characters. No HTML is allowed")
@@ -417,30 +432,34 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
}
test("validation should fail if there are no tags for any languages") {
- val Failure(res: ValidationException) =
- contentValidator.validateArticle(TestData.sampleArticleWithByNcSa.copy(tags = Seq()), false)
+ val res =
+ contentValidator.validateArticle(TestData.sampleArticleWithByNcSa.copy(tags = Seq()), false).asValidationError
res.errors.length should be(1)
res.errors.head.field should equal("tags")
res.errors.head.message should equal("The article must have at least one set of tags")
}
test("validation should fail if metaImageId is an empty string") {
- val Failure(res: ValidationException) =
- contentValidator.validateArticle(
- TestData.sampleArticleWithByNcSa.copy(
- metaImage = Seq(ArticleMetaImage("", "alt-text", "nb"))
- ),
- false
- )
+ val res =
+ contentValidator
+ .validateArticle(
+ TestData.sampleArticleWithByNcSa.copy(
+ metaImage = Seq(ArticleMetaImage("", "alt-text", "nb"))
+ ),
+ false
+ )
+ .asValidationError
res.errors.length should be(1)
res.errors.head.field should be("metaImageId")
res.errors.head.message should be("Meta image ID must be a number")
}
test("validation should fail if license is chosen and no copyright holders are provided") {
- val copyright = Copyright(CC_BY_SA.toString, None, Seq(), Seq(), Seq(), None, None, false)
- val Failure(res: ValidationException) =
- contentValidator.validateArticle(TestData.sampleArticleWithByNcSa.copy(copyright = copyright), false)
+ val copyright = Copyright(CC_BY_SA.toString, None, Seq(), Seq(), Seq(), None, None, false)
+ val res =
+ contentValidator
+ .validateArticle(TestData.sampleArticleWithByNcSa.copy(copyright = copyright), false)
+ .asValidationError
res.errors.length should be(1)
res.errors.head.field should be("license.license")
res.errors.head.message should be("At least one copyright holder is required when license is CC-BY-SA-4.0")
@@ -460,10 +479,12 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
}
test("softvalidation is more lenient than strictvalidation") {
- val Failure(strictRes: ValidationException) = contentValidator.validateArticle(
- TestData.sampleArticleWithByNcSa.copy(metaImage = Seq(ArticleMetaImage("", "alt-text", "nb"))),
- false
- )
+ val strictRes = contentValidator
+ .validateArticle(
+ TestData.sampleArticleWithByNcSa.copy(metaImage = Seq(ArticleMetaImage("", "alt-text", "nb"))),
+ false
+ )
+ .asValidationError
val softRes = contentValidator.softValidateArticle(
TestData.sampleArticleWithByNcSa.copy(metaImage = Seq(ArticleMetaImage("", "alt-text", "nb"))),
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/AudioApiProperties.scala b/audio-api/src/main/scala/no/ndla/audioapi/AudioApiProperties.scala
index 4308c097e1..bb75a540aa 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/AudioApiProperties.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/AudioApiProperties.scala
@@ -16,7 +16,7 @@ import no.ndla.network.{AuthUser, Domains}
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: AudioApiProperties
+ lazy val props: AudioApiProperties
}
class AudioApiProperties extends BaseProps with DatabaseProps with StrictLogging {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/ComponentRegistry.scala b/audio-api/src/main/scala/no/ndla/audioapi/ComponentRegistry.scala
index 47ee5a8d10..c557d83756 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/ComponentRegistry.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/ComponentRegistry.scala
@@ -61,46 +61,46 @@ class ComponentRegistry(properties: AudioApiProperties)
with TranscriptionService
with NdlaAWSTranscribeClient
with NdlaBrightcoveClient {
- override val props: AudioApiProperties = properties
- override val migrator: DBMigrator = DBMigrator(
+ override lazy val props: AudioApiProperties = properties
+ override lazy val migrator: DBMigrator = DBMigrator(
new V5__AddAgreementToAudio,
new V6__TranslateUntranslatedAuthors
)
override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
- lazy val s3Client = new NdlaS3Client(props.StorageName, props.StorageRegion)
- lazy val s3TranscribeClient = new NdlaS3Client(props.TranscribeStorageName, props.TranscribeStorageRegion)
- lazy val brightcoveClient = new NdlaBrightcoveClient()
- lazy val transcribeClient = new NdlaAWSTranscribeClient(props.TranscribeStorageRegion)
+ override lazy val s3Client = new NdlaS3Client(props.StorageName, props.StorageRegion)
+ override lazy val s3TranscribeClient = new NdlaS3Client(props.TranscribeStorageName, props.TranscribeStorageRegion)
+ override lazy val brightcoveClient = new NdlaBrightcoveClient()
+ override lazy val transcribeClient = new NdlaAWSTranscribeClient(props.TranscribeStorageRegion)
- lazy val audioRepository = new AudioRepository
- lazy val seriesRepository = new SeriesRepository
+ override lazy val audioRepository = new AudioRepository
+ override lazy val seriesRepository = new SeriesRepository
- lazy val ndlaClient = new NdlaClient
- lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
- lazy val readService = new ReadService
- lazy val writeService = new WriteService
- lazy val validationService = new ValidationService
- lazy val converterService = new ConverterService
- lazy val transcriptionService = new TranscriptionService
+ override lazy val readService = new ReadService
+ override lazy val writeService = new WriteService
+ override lazy val validationService = new ValidationService
+ override lazy val converterService = new ConverterService
+ override lazy val transcriptionService = new TranscriptionService
- lazy val internController = new InternController
- lazy val audioApiController = new AudioController
- lazy val seriesController = new SeriesController
- lazy val healthController = new HealthController
- lazy val transcriptionController = new TranscriptionController
+ override lazy val internController = new InternController
+ override lazy val audioApiController = new AudioController
+ override lazy val seriesController = new SeriesController
+ override lazy val healthController = new HealthController
+ override lazy val transcriptionController = new TranscriptionController
- var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
- lazy val searchConverterService = new SearchConverterService
- lazy val audioIndexService = new AudioIndexService
- lazy val audioSearchService = new AudioSearchService
- lazy val seriesIndexService = new SeriesIndexService
- lazy val seriesSearchService = new SeriesSearchService
- lazy val tagIndexService = new TagIndexService
- lazy val tagSearchService = new TagSearchService
+ var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val audioIndexService = new AudioIndexService
+ override lazy val audioSearchService = new AudioSearchService
+ override lazy val seriesIndexService = new SeriesIndexService
+ override lazy val seriesSearchService = new SeriesSearchService
+ override lazy val tagIndexService = new TagIndexService
+ override lazy val tagSearchService = new TagSearchService
- lazy val clock = new SystemClock
+ override lazy val clock = new SystemClock
val swagger = new SwaggerController(
List(
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/controller/AudioController.scala b/audio-api/src/main/scala/no/ndla/audioapi/controller/AudioController.scala
index 1c8cf7b52d..9283c1ff81 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/controller/AudioController.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/controller/AudioController.scala
@@ -9,7 +9,6 @@
package no.ndla.audioapi.controller
import cats.implicits.*
-import io.circe.generic.auto.*
import no.ndla.audioapi.controller.multipart.{MetaDataAndFileForm, MetaDataAndOptFileForm}
import no.ndla.audioapi.Props
import no.ndla.audioapi.model.Sort
@@ -24,7 +23,6 @@ import no.ndla.common.implicits.*
import no.ndla.common.model.api.CommaSeparatedList.*
import no.ndla.common.model.api.LanguageCode
import no.ndla.common.model.domain.UploadedFile
-import no.ndla.network.tapir.NoNullJsonPrinter.*
import no.ndla.network.tapir.{NonEmptyString, TapirController}
import no.ndla.network.tapir.TapirUtil.errorOutputsFor
import no.ndla.network.tapir.auth.Permission.AUDIO_API_WRITE
@@ -40,10 +38,9 @@ import scala.util.{Failure, Success, Try}
trait AudioController {
this: AudioRepository & ReadService & WriteService & AudioSearchService & SearchConverterService & ConverterService &
Props & ErrorHandling & TapirController =>
- val audioApiController: AudioController
+ lazy val audioApiController: AudioController
class AudioController extends TapirController {
- import props.*
val maxAudioFileSizeBytes: Int = props.MaxAudioFileSizeBytes
override val serviceName: String = "audio"
override val prefix: EndpointInput[Unit] = "audio-api" / "v1" / serviceName
@@ -58,7 +55,7 @@ trait AudioController {
private val license = query[Option[String]]("license").description("Return only audio with provided license.")
private val pageNo = query[Option[Int]]("page").description("The page number of the search hits to display.")
private val pageSize = query[Option[Int]]("page-size").description(
- s"The number of search hits to display for each page. Defaults to $DefaultPageSize and max is $MaxPageSize."
+ s"The number of search hits to display for each page. Defaults to ${props.DefaultPageSize} and max is ${props.MaxPageSize}."
)
private val audioIds = listQuery[Long]("ids").description(
"Return only audios that have one of the provided ids. To provide multiple ids, separate by comma (,)."
@@ -69,11 +66,11 @@ trait AudioController {
Default is by -relevance (desc) when query is set, and title (asc) when query is empty.""".stripMargin
)
private val scrollId = query[Option[String]]("search-context").description(
- s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${InitialScrollContextKeywords
+ s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${props.InitialScrollContextKeywords
.mkString("[", ",", "]")}.
|When scrolling, the parameters from the initial search is used, except in the case of '${this.language.name}'.
- |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after $ElasticSearchScrollKeepAlive).
- |If you are not paginating past $ElasticSearchIndexMaxResultWindow hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
+ |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after ${props.ElasticSearchScrollKeepAlive}).
+ |If you are not paginating past ${props.ElasticSearchIndexMaxResultWindow} hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
|""".stripMargin
)
private val audioType = query[Option[String]]("audio-type").description(
@@ -92,6 +89,7 @@ trait AudioController {
private val pathLanguage = path[String]("language").description("The ISO 639-1 language code describing language.")
import ErrorHelpers.*
+ import sttp.tapir.json.circe._
def getSearch: ServerEndpoint[Any, Eff] = endpoint.get
.summary("Find audio files")
@@ -112,7 +110,7 @@ trait AudioController {
case (query, language, license, sort, pageNo, pageSize, scrollId, audioType, seriesFilter, fallback) =>
val lang = language.getOrElse(LanguageCode(Language.AllLanguages))
scrollSearchOr(scrollId, lang.code) {
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query.underlying,
language.map(_.code),
@@ -138,7 +136,7 @@ trait AudioController {
.serverLogicPure { searchParams =>
val lang = searchParams.language.getOrElse(LanguageCode(Language.AllLanguages))
scrollSearchOr(searchParams.scrollId, lang.code) {
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
searchParams.query,
searchParams.language.map(_.code),
@@ -222,7 +220,7 @@ trait AudioController {
.serverLogicPure { user => formData =>
doWithStream(formData.file) { uploadedFile =>
writeService.storeNewAudio(
- formData.metadata.body,
+ formData.metadata,
uploadedFile,
user
)
@@ -243,10 +241,10 @@ trait AudioController {
formData.file match {
case Some(f) =>
doWithStream(f) { stream =>
- writeService.updateAudio(id, formData.metadata.body, Some(stream), user)
+ writeService.updateAudio(id, formData.metadata, Some(stream), user)
}
case None =>
- writeService.updateAudio(id, formData.metadata.body, None, user)
+ writeService.updateAudio(id, formData.metadata, None, user)
}
}
}
@@ -262,8 +260,8 @@ trait AudioController {
.out(jsonBody[TagsSearchResultDTO])
.errorOut(errorOutputsFor(400, 404))
.serverLogicPure { case (query, ps, pn, lang) =>
- val pageSize = ps.getOrElse(DefaultPageSize) match {
- case tooSmall if tooSmall < 1 => DefaultPageSize
+ val pageSize = ps.getOrElse(props.DefaultPageSize) match {
+ case tooSmall if tooSmall < 1 => props.DefaultPageSize
case x => x
}
val pageNo = pn.getOrElse(1) match {
@@ -313,7 +311,7 @@ trait AudioController {
orFunction: => Try[SummaryWithHeader]
): Try[SummaryWithHeader] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
audioSearchService.scroll(scroll, language) match {
case Success(scrollResult) =>
val body = searchConverterService.asApiAudioSummarySearchResult(scrollResult)
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/controller/HealthController.scala b/audio-api/src/main/scala/no/ndla/audioapi/controller/HealthController.scala
index 33b257dd0b..9960f75a64 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/controller/HealthController.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/controller/HealthController.scala
@@ -15,7 +15,7 @@ import no.ndla.network.tapir.TapirHealthController
trait HealthController {
this: NdlaS3Client & AudioRepository & Props & TapirHealthController =>
- val healthController: HealthController
+ lazy val healthController: HealthController
class HealthController extends TapirHealthController {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/controller/InternController.scala b/audio-api/src/main/scala/no/ndla/audioapi/controller/InternController.scala
index fa762a9342..2177cdd024 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/controller/InternController.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/controller/InternController.scala
@@ -31,7 +31,7 @@ import scala.util.{Failure, Success}
trait InternController {
this: AudioIndexService & ConverterService & AudioRepository & AudioIndexService & SeriesIndexService &
TagIndexService & ReadService & Props & ErrorHandling & TapirController =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController {
override val prefix: EndpointInput[Unit] = "intern"
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/controller/SeriesController.scala b/audio-api/src/main/scala/no/ndla/audioapi/controller/SeriesController.scala
index c9151ecbaf..c47a6b96f6 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/controller/SeriesController.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/controller/SeriesController.scala
@@ -34,17 +34,15 @@ import scala.util.{Failure, Success, Try}
trait SeriesController {
this: ReadService & WriteService & SeriesSearchService & SearchConverterService & ConverterService & Props &
ErrorHandling & TapirController =>
- val seriesController: SeriesController
+ lazy val seriesController: SeriesController
class SeriesController extends TapirController {
- import props.*
-
private val queryString = query[Option[String]]("query")
.description("Return only results with titles or tags matching the specified query.")
private val language =
query[Option[LanguageCode]]("language").description("The ISO 639-1 language code describing language.")
private val pageNo = query[Option[Int]]("page").description("The page number of the search hits to display.")
private val pageSize = query[Option[Int]]("page-size").description(
- s"The number of search hits to display for each page. Defaults to $DefaultPageSize and max is $MaxPageSize."
+ s"The number of search hits to display for each page. Defaults to ${props.DefaultPageSize} and max is ${props.MaxPageSize}."
)
private val sort = query[Option[String]]("sort").description(
s"""The sorting used on results.
@@ -52,11 +50,11 @@ trait SeriesController {
Default is by -relevance (desc) when query is set, and title (asc) when query is empty.""".stripMargin
)
private val scrollId = query[Option[String]]("search-context").description(
- s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${InitialScrollContextKeywords
+ s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${props.InitialScrollContextKeywords
.mkString("[", ",", "]")}.
|When scrolling, the parameters from the initial search is used, except in the case of '${this.language.name}'.
- |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after $ElasticSearchScrollKeepAlive).
- |If you are not paginating past $ElasticSearchIndexMaxResultWindow hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
+ |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after ${props.ElasticSearchScrollKeepAlive}).
+ |If you are not paginating past ${props.ElasticSearchIndexMaxResultWindow} hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
|""".stripMargin
)
private val fallback =
@@ -82,9 +80,9 @@ trait SeriesController {
.serverLogicPure { case (query, language, sort, page, pageSize, scrollId, fallback) =>
val lang = language.getOrElse(LanguageCode(Language.AllLanguages)).code
scrollSearchOr(scrollId, lang) {
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
search(query, lang, Sort.valueOf(sort), pageSize, page, shouldScroll, fallback.getOrElse(false))
- }
+ }.handleErrorsOrOk
}
def postSeriesSearch: ServerEndpoint[Any, Eff] = endpoint.post
@@ -101,11 +99,11 @@ trait SeriesController {
val sort = searchParams.sort
val pageSize = searchParams.pageSize
val page = searchParams.page
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
val fallback = searchParams.fallback.getOrElse(false)
search(query, language.code, sort, pageSize, page, shouldScroll, fallback)
- }
+ }.handleErrorsOrOk
}
def getSingleSeries: ServerEndpoint[Any, Eff] = endpoint.get
@@ -237,7 +235,7 @@ trait SeriesController {
orFunction: => Try[SummaryWithHeader]
): Try[SummaryWithHeader] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
seriesSearchService.scroll(scroll, language).map { scrollResult =>
SummaryWithHeader(
body = searchConverterService.asApiSeriesSummarySearchResult(scrollResult),
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/controller/TranscriptionController.scala b/audio-api/src/main/scala/no/ndla/audioapi/controller/TranscriptionController.scala
index 3f5c6648c6..9bbfce41b2 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/controller/TranscriptionController.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/controller/TranscriptionController.scala
@@ -23,7 +23,7 @@ import sttp.tapir.generic.auto.schemaForCaseClass
import scala.util.{Failure, Success}
trait TranscriptionController {
this: Props & TapirController & ReadService & TranscriptionService =>
- val transcriptionController: TranscriptionController
+ lazy val transcriptionController: TranscriptionController
class TranscriptionController() extends TapirController {
override val serviceName: String = "transcription"
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/controller/multipart/MultipartInput.scala b/audio-api/src/main/scala/no/ndla/audioapi/controller/multipart/MultipartInput.scala
index 73057e2203..08499e4770 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/controller/multipart/MultipartInput.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/controller/multipart/MultipartInput.scala
@@ -10,14 +10,24 @@ package no.ndla.audioapi.controller.multipart
import no.ndla.audioapi.model.api.{NewAudioMetaInformationDTO, UpdatedAudioMetaInformationDTO}
import sttp.model.Part
+import sttp.tapir.generic.auto.*
+import sttp.tapir.Codec.JsonCodec
+import sttp.tapir.json.circe.*
import java.io.File
case class MetaDataAndFileForm(
- metadata: Part[NewAudioMetaInformationDTO],
+ metadata: NewAudioMetaInformationDTO,
file: Part[File]
)
+object MetaDataAndFileForm {
+ implicit val codec: JsonCodec[NewAudioMetaInformationDTO] = circeCodec[NewAudioMetaInformationDTO]
+}
+
case class MetaDataAndOptFileForm(
- metadata: Part[UpdatedAudioMetaInformationDTO],
+ metadata: UpdatedAudioMetaInformationDTO,
file: Option[Part[File]]
)
+object MetaDataAndOptFileForm {
+ implicit val codec: JsonCodec[UpdatedAudioMetaInformationDTO] = circeCodec[UpdatedAudioMetaInformationDTO]
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioDTO.scala
index 5db8127160..e56e0bd5e0 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioDTO.scala
@@ -9,6 +9,8 @@
package no.ndla.audioapi.model.api
import sttp.tapir.Schema.annotations.description
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
@description("Url and size information about the audio")
case class AudioDTO(
@@ -17,3 +19,8 @@ case class AudioDTO(
@description("The size of the audio file") fileSize: Long,
@description("The current language for this audio") language: String
)
+
+object AudioDTO {
+ implicit val encoder: Encoder[AudioDTO] = deriveEncoder
+ implicit val decoder: Decoder[AudioDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioMetaInformationDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioMetaInformationDTO.scala
index 5d1b72d007..3795c66274 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioMetaInformationDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioMetaInformationDTO.scala
@@ -10,7 +10,10 @@ package no.ndla.audioapi.model.api
import no.ndla.common.model.NDLADate
import no.ndla.common.model.api.CopyrightDTO
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
+import io.circe.{Decoder, Encoder}
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
@description("Meta information about the audio object")
case class AudioMetaInformationDTO(
@@ -41,3 +44,11 @@ case class AudioMetaInformationDTO(
@description("The time of last update for the audio-file")
updated: NDLADate
)
+
+object AudioMetaInformationDTO {
+ implicit val encoder: Encoder[AudioMetaInformationDTO] = deriveEncoder
+ implicit val decoder: Decoder[AudioMetaInformationDTO] = deriveDecoder
+
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[AudioMetaInformationDTO] = Schema.derived
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioSummaryDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioSummaryDTO.scala
index 67e66b1e56..ccfb35c7e6 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioSummaryDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/AudioSummaryDTO.scala
@@ -8,8 +8,11 @@
package no.ndla.audioapi.model.api
+import sttp.tapir.Schema
import no.ndla.common.model.NDLADate
import sttp.tapir.Schema.annotations.description
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
@description("Short summary of information about the audio")
case class AudioSummaryDTO(
@@ -34,3 +37,11 @@ case class AudioSummaryDTO(
@description("The time and date of last update")
lastUpdated: NDLADate
)
+
+object AudioSummaryDTO {
+ implicit val encoder: Encoder[AudioSummaryDTO] = deriveEncoder
+ implicit val decoder: Decoder[AudioSummaryDTO] = deriveDecoder
+
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[AudioSummaryDTO] = Schema.derived
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/CoverPhotoDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/CoverPhotoDTO.scala
index 397e1ef8e5..d8de30f6d8 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/CoverPhotoDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/CoverPhotoDTO.scala
@@ -16,3 +16,8 @@ case class CoverPhotoDTO(
@description("Url to the coverPhoto") url: String,
@description("Alttext for the coverPhoto") altText: String
)
+
+object CoverPhotoDTO {
+ implicit val encoder: io.circe.Encoder[CoverPhotoDTO] = io.circe.generic.semiauto.deriveEncoder
+ implicit val decoder: io.circe.Decoder[CoverPhotoDTO] = io.circe.generic.semiauto.deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/DescriptionDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/DescriptionDTO.scala
index 34ddb44f35..3c859f3985 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/DescriptionDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/DescriptionDTO.scala
@@ -14,3 +14,8 @@ case class DescriptionDTO(
@description("The description of the element") description: String,
@description("ISO 639-1 code that represents the language used in the description") language: String
)
+
+object DescriptionDTO {
+ implicit val encoder: io.circe.Encoder[DescriptionDTO] = io.circe.generic.semiauto.deriveEncoder
+ implicit val decoder: io.circe.Decoder[DescriptionDTO] = io.circe.generic.semiauto.deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/ManuscriptDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/ManuscriptDTO.scala
index 36f7bcaae9..74847518d8 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/ManuscriptDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/ManuscriptDTO.scala
@@ -9,8 +9,16 @@
package no.ndla.audioapi.model.api
import sttp.tapir.Schema.annotations.description
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
case class ManuscriptDTO(
@description("The manuscript of the audio file") manuscript: String,
@description("ISO 639-1 code that represents the language used in the manuscript") language: String
)
+
+object ManuscriptDTO {
+ implicit val encoder: Encoder[ManuscriptDTO] = deriveEncoder
+ implicit val decoder: Decoder[ManuscriptDTO] = deriveDecoder
+
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewAudioMetaInformationDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewAudioMetaInformationDTO.scala
index aa36cf456d..8b345941e4 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewAudioMetaInformationDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewAudioMetaInformationDTO.scala
@@ -8,19 +8,32 @@
package no.ndla.audioapi.model.api
+import io.circe.{Decoder, Encoder}
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import no.ndla.common.model.api.CopyrightDTO
import sttp.tapir.Schema.annotations.description
-// format: off
@description("Meta information about the audio object")
case class NewAudioMetaInformationDTO(
- @description("The title of the audio file") title: String,
- @description("ISO 639-1 code that represents the language used in this resource") language: String,
- @description("Copyright information for the audio files") copyright: CopyrightDTO,
- @description("Tags for this audio file") tags: Seq[String],
- @description("Type of audio. 'standard', or 'podcast', defaults to 'standard'") audioType: Option[String],
- @description("Meta information about podcast, only applicable if audioType is 'podcast'.") podcastMeta: Option[NewPodcastMetaDTO],
- @description("Id of series if the audio is a podcast and a part of a series.") seriesId: Option[Long],
- @description("Manuscript for the audio") manuscript: Option[String]
+ @description("The title of the audio file")
+ title: String,
+ @description("ISO 639-1 code that represents the language used in this resource")
+ language: String,
+ @description("Copyright information for the audio files")
+ copyright: CopyrightDTO,
+ @description("Tags for this audio file")
+ tags: Seq[String],
+ @description("Type of audio. 'standard', or 'podcast', defaults to 'standard'")
+ audioType: Option[String],
+ @description("Meta information about podcast, only applicable if audioType is 'podcast'.")
+ podcastMeta: Option[NewPodcastMetaDTO],
+ @description("Id of series if the audio is a podcast and a part of a series.")
+ seriesId: Option[Long],
+ @description("Manuscript for the audio")
+ manuscript: Option[String]
)
-// format: on
+
+object NewAudioMetaInformationDTO {
+ implicit val encoder: Encoder[NewAudioMetaInformationDTO] = deriveEncoder
+ implicit val decoder: Decoder[NewAudioMetaInformationDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewPodcastMetaDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewPodcastMetaDTO.scala
index 79f7da6db5..61e540d8c2 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewPodcastMetaDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/NewPodcastMetaDTO.scala
@@ -9,12 +9,16 @@
package no.ndla.audioapi.model.api
import sttp.tapir.Schema.annotations.description
+import io.circe.{Decoder, Encoder}
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
-// format: off
@description("Meta information about podcast audio")
case class NewPodcastMetaDTO(
- @description("Introduction for the podcast") introduction: String,
- @description("Cover photo for the podcast") coverPhotoId: String,
- @description("Cover photo alttext for the podcast") coverPhotoAltText: String,
+ @description("Introduction for the podcast") introduction: String,
+ @description("Cover photo for the podcast") coverPhotoId: String,
+ @description("Cover photo alttext for the podcast") coverPhotoAltText: String
)
-// format: on
+object NewPodcastMetaDTO {
+ implicit val encoder: Encoder[NewPodcastMetaDTO] = deriveEncoder
+ implicit val decoder: Decoder[NewPodcastMetaDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/PodcastMetaDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/PodcastMetaDTO.scala
index 353784dcfa..a4957f8d4d 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/PodcastMetaDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/PodcastMetaDTO.scala
@@ -9,12 +9,17 @@
package no.ndla.audioapi.model.api
import sttp.tapir.Schema.annotations.description
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
-// format: off
@description("Meta information about podcast audio")
case class PodcastMetaDTO(
- @description("Introduction for the podcast") introduction: String,
- @description("Cover photo for the podcast") coverPhoto: CoverPhotoDTO,
- @description("ISO 639-1 code that represents the language used in the title") language: String
+ @description("Introduction for the podcast") introduction: String,
+ @description("Cover photo for the podcast") coverPhoto: CoverPhotoDTO,
+ @description("ISO 639-1 code that represents the language used in the title") language: String
)
-// format: on
+
+object PodcastMetaDTO {
+ implicit def encoder: Encoder[PodcastMetaDTO] = deriveEncoder
+ implicit def decoder: Decoder[PodcastMetaDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchParamsDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchParamsDTO.scala
index 6bf6c80274..8541f6e0c5 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchParamsDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchParamsDTO.scala
@@ -11,6 +11,8 @@ package no.ndla.audioapi.model.api
import no.ndla.audioapi.model.Sort
import no.ndla.common.model.api.LanguageCode
import sttp.tapir.Schema.annotations.description
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
@description("The search parameters")
case class SearchParamsDTO(
@@ -37,3 +39,8 @@ case class SearchParamsDTO(
@description("Return all matched audios whether they exist on selected language or not.")
fallback: Option[Boolean]
)
+
+object SearchParamsDTO {
+ implicit val encoder: Encoder[SearchParamsDTO] = deriveEncoder
+ implicit val decoder: Decoder[SearchParamsDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchResult.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchResult.scala
index 96172c923a..50c75439b6 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchResult.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SearchResult.scala
@@ -9,6 +9,8 @@
package no.ndla.audioapi.model.api
import sttp.tapir.Schema.annotations.description
+import io.circe.{Decoder, Encoder}
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
@description("Information about audio summary search-results")
case class AudioSummarySearchResultDTO(
@@ -19,6 +21,11 @@ case class AudioSummarySearchResultDTO(
@description("The search results") results: Seq[AudioSummaryDTO]
)
+object AudioSummarySearchResultDTO {
+ implicit val encoder: Encoder[AudioSummarySearchResultDTO] = deriveEncoder
+ implicit val decoder: Decoder[AudioSummarySearchResultDTO] = deriveDecoder
+}
+
@description("Information about series summary search-results")
case class SeriesSummarySearchResultDTO(
@description("The total number of articles matching this query") totalCount: Long,
@@ -27,6 +34,10 @@ case class SeriesSummarySearchResultDTO(
@description("The chosen search language") language: String,
@description("The search results") results: Seq[SeriesSummaryDTO]
)
+object SeriesSummarySearchResultDTO {
+ implicit val encoder: Encoder[SeriesSummarySearchResultDTO] = deriveEncoder
+ implicit val decoder: Decoder[SeriesSummarySearchResultDTO] = deriveDecoder
+}
@description("Information about tags-search-results")
case class TagsSearchResultDTO(
@@ -36,3 +47,7 @@ case class TagsSearchResultDTO(
@description("The chosen search language") language: String,
@description("The search results") results: Seq[String]
)
+object TagsSearchResultDTO {
+ implicit val encoder: Encoder[TagsSearchResultDTO] = deriveEncoder
+ implicit val decoder: Decoder[TagsSearchResultDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesDTO.scala
index bdba0330bf..7f546586a0 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesDTO.scala
@@ -8,6 +8,8 @@
package no.ndla.audioapi.model.api
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
@description("Meta information about the series")
@@ -21,3 +23,8 @@ case class SeriesDTO(
@description("A list of available languages for this series") supportedLanguages: Seq[String],
@description("Specifies if this series generates rss-feed") hasRSS: Boolean
)
+
+object SeriesDTO {
+ implicit def encoder: Encoder[SeriesDTO] = deriveEncoder
+ implicit def decoder: Decoder[SeriesDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesSummaryDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesSummaryDTO.scala
index c2daa3a752..2df87ce6af 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesSummaryDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/SeriesSummaryDTO.scala
@@ -9,6 +9,9 @@
package no.ndla.audioapi.model.api
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
@description("Short summary of information about the series")
case class SeriesSummaryDTO(
@@ -19,3 +22,10 @@ case class SeriesSummaryDTO(
@description("A list of episode summaries") episodes: Option[Seq[AudioSummaryDTO]],
@description("Cover photo for the series") coverPhoto: CoverPhotoDTO
)
+object SeriesSummaryDTO {
+ implicit val encoder: Encoder[SeriesSummaryDTO] = deriveEncoder
+ implicit val decoder: Decoder[SeriesSummaryDTO] = deriveDecoder
+
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[SeriesSummaryDTO] = Schema.derived
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/TagDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/TagDTO.scala
index ef26500a37..c2160d0035 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/TagDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/TagDTO.scala
@@ -9,9 +9,16 @@
package no.ndla.audioapi.model.api
import sttp.tapir.Schema.annotations.description
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
@description("Description of the tags of the audio")
case class TagDTO(
@description("The searchable tag.") tags: Seq[String],
@description("ISO 639-1 code that represents the language used in tag") language: String
)
+
+object TagDTO {
+ implicit val encoder: Encoder[TagDTO] = deriveEncoder
+ implicit val decoder: Decoder[TagDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/TitleDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/TitleDTO.scala
index 0c6b5510ce..86622013c1 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/TitleDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/TitleDTO.scala
@@ -8,9 +8,17 @@
package no.ndla.audioapi.model.api
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
case class TitleDTO(
@description("The title of the audio file") title: String,
@description("ISO 639-1 code that represents the language used in the title") language: String
)
+
+object TitleDTO {
+ implicit val encoder: Encoder[TitleDTO] = deriveEncoder
+ implicit val decoder: Decoder[TitleDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/api/UpdatedAudioMetaInformationDTO.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/api/UpdatedAudioMetaInformationDTO.scala
index 2ac9d14ea9..3713e3b8d5 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/api/UpdatedAudioMetaInformationDTO.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/api/UpdatedAudioMetaInformationDTO.scala
@@ -10,18 +10,32 @@ package no.ndla.audioapi.model.api
import no.ndla.common.model.api.CopyrightDTO
import sttp.tapir.Schema.annotations.description
+import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+import io.circe.{Decoder, Encoder}
-// format: off
@description("Meta information about the audio object")
case class UpdatedAudioMetaInformationDTO(
- @description("The revision number of this audio") revision: Int,
- @description("The title of the audio file") title: String,
- @description("ISO 639-1 code that represents the language used in this resource") language: String,
- @description("Copyright information for the audio files") copyright: CopyrightDTO,
- @description("Tags for this audio file") tags: Seq[String],
- @description("Type of audio. 'standard', or 'podcast', defaults to 'standard'") audioType: Option[String],
- @description("Meta information about podcast, only applicable if audioType is 'podcast'.") podcastMeta: Option[NewPodcastMetaDTO],
- @description("Id of series if the audio is a podcast and a part of a series.") seriesId: Option[Long],
- @description("Manuscript for the audio") manuscript: Option[String],
+ @description("The revision number of this audio")
+ revision: Int,
+ @description("The title of the audio file")
+ title: String,
+ @description("ISO 639-1 code that represents the language used in this resource")
+ language: String,
+ @description("Copyright information for the audio files")
+ copyright: CopyrightDTO,
+ @description("Tags for this audio file")
+ tags: Seq[String],
+ @description("Type of audio. 'standard', or 'podcast', defaults to 'standard'")
+ audioType: Option[String],
+ @description("Meta information about podcast, only applicable if audioType is 'podcast'.")
+ podcastMeta: Option[NewPodcastMetaDTO],
+ @description("Id of series if the audio is a podcast and a part of a series.")
+ seriesId: Option[Long],
+ @description("Manuscript for the audio")
+ manuscript: Option[String]
)
-// format: on
+
+object UpdatedAudioMetaInformationDTO {
+ implicit val encoder: Encoder[UpdatedAudioMetaInformationDTO] = deriveEncoder
+ implicit val decoder: Decoder[UpdatedAudioMetaInformationDTO] = deriveDecoder
+}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/domain/AudioMetaInformation.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/domain/AudioMetaInformation.scala
index 32a4744a84..c36025457d 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/domain/AudioMetaInformation.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/domain/AudioMetaInformation.scala
@@ -8,6 +8,7 @@
package no.ndla.audioapi.model.domain
+import sttp.tapir.Schema
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import no.ndla.common.CirceUtil
@@ -73,6 +74,8 @@ object AudioMetaInformation extends SQLSyntaxSupport[AudioMetaInformation] {
implicit val encoder: Encoder[AudioMetaInformation] = deriveEncoder
implicit val decoder: Decoder[AudioMetaInformation] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[AudioMetaInformation] = Schema.derived
def fromResultSet(au: SyntaxProvider[AudioMetaInformation])(rs: WrappedResultSet): AudioMetaInformation =
fromResultSet(au.resultName)(rs)
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/model/domain/Series.scala b/audio-api/src/main/scala/no/ndla/audioapi/model/domain/Series.scala
index 854da8b148..2f7c15260d 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/model/domain/Series.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/model/domain/Series.scala
@@ -19,14 +19,14 @@ import scalikejdbc.*
import scala.util.Try
/** Base series without database generated fields */
-class SeriesWithoutId(
- val title: Seq[Title],
- val coverPhoto: CoverPhoto,
- val episodes: Option[Seq[AudioMetaInformation]],
- val updated: NDLADate,
- val created: NDLADate,
- val description: Seq[Description],
- val hasRSS: Boolean
+case class SeriesWithoutId(
+ title: Seq[Title],
+ coverPhoto: CoverPhoto,
+ episodes: Option[Seq[AudioMetaInformation]],
+ updated: NDLADate,
+ created: NDLADate,
+ description: Seq[Description],
+ hasRSS: Boolean
)
object SeriesWithoutId {
implicit val encoder: Encoder[SeriesWithoutId] = deriveEncoder
@@ -39,15 +39,24 @@ object SeriesWithoutId {
case class Series(
id: Long,
revision: Int,
- override val episodes: Option[Seq[AudioMetaInformation]],
- override val title: Seq[Title],
- override val coverPhoto: CoverPhoto,
- override val updated: NDLADate,
- override val created: NDLADate,
- override val description: Seq[Description],
- override val hasRSS: Boolean
-) extends SeriesWithoutId(title, coverPhoto, episodes, updated, created, description, hasRSS) {
+ episodes: Option[Seq[AudioMetaInformation]],
+ title: Seq[Title],
+ coverPhoto: CoverPhoto,
+ updated: NDLADate,
+ created: NDLADate,
+ description: Seq[Description],
+ hasRSS: Boolean
+) {
lazy val supportedLanguages: Seq[String] = getSupportedLanguages(title, description)
+ def withoutId: SeriesWithoutId = SeriesWithoutId(
+ title = title,
+ coverPhoto = coverPhoto,
+ episodes = episodes,
+ updated = updated,
+ created = created,
+ description = description,
+ hasRSS = hasRSS
+ )
}
object Series extends SQLSyntaxSupport[Series] {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/repository/AudioRepository.scala b/audio-api/src/main/scala/no/ndla/audioapi/repository/AudioRepository.scala
index 5a68ee7b50..c0f633fc8c 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/repository/AudioRepository.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/repository/AudioRepository.scala
@@ -21,7 +21,7 @@ import scala.util.{Failure, Success, Try}
trait AudioRepository {
this: DataSource & SeriesRepository & Props & ErrorHandling =>
- val audioRepository: AudioRepository
+ lazy val audioRepository: AudioRepository
class AudioRepository extends StrictLogging with Repository[AudioMetaInformation] {
def audioCount(implicit session: DBSession = ReadOnlyAutoSession): Long =
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/repository/SeriesRepository.scala b/audio-api/src/main/scala/no/ndla/audioapi/repository/SeriesRepository.scala
index 1b0864b5f5..1992064157 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/repository/SeriesRepository.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/repository/SeriesRepository.scala
@@ -24,7 +24,7 @@ import scala.util.{Failure, Success, Try}
trait SeriesRepository {
this: DataSource & Props & ErrorHandling =>
- val seriesRepository: SeriesRepository
+ lazy val seriesRepository: SeriesRepository
class SeriesRepository extends StrictLogging with Repository[Series] {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/ConverterService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/ConverterService.scala
index df80eccd7f..61e25a8ba5 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/ConverterService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/ConverterService.scala
@@ -22,15 +22,14 @@ import no.ndla.language.model.WithLanguage
import no.ndla.mapping.License.getLicense
import no.ndla.network.tapir.auth.TokenUser
+import scala.reflect.ClassTag
import scala.util.{Failure, Success, Try}
trait ConverterService {
this: Clock & Props =>
- val converterService: ConverterService
+ lazy val converterService: ConverterService
class ConverterService extends StrictLogging {
- import props.*
-
def updateSeries(existingSeries: domain.Series, updatedSeries: api.NewSeriesDTO): domain.Series = {
val newTitle = common.Title(updatedSeries.title, updatedSeries.language)
val newDescription = domain.Description(updatedSeries.description, updatedSeries.language)
@@ -130,21 +129,27 @@ trait ConverterService {
private def maybeToApiTitle(maybeTitle: Option[common.Title]): api.TitleDTO = {
maybeTitle match {
case Some(title) => toApiTitle(title)
- case None => api.TitleDTO("", DefaultLanguage)
+ case None => api.TitleDTO("", props.DefaultLanguage)
}
}
private def toApiTags(maybeTag: Option[common.Tag]): TagDTO = {
maybeTag match {
case Some(tag) => api.TagDTO(tag.tags, tag.language)
- case None => api.TagDTO(Seq(), DefaultLanguage)
+ case None => api.TagDTO(Seq(), props.DefaultLanguage)
}
}
def toApiAudio(audio: Option[domain.Audio]): api.AudioDTO = {
audio match {
- case Some(x) => api.AudioDTO(s"$Domain/$AudioFilesUrlSuffix/${x.filePath}", x.mimeType, x.fileSize, x.language)
- case None => api.AudioDTO("", "", 0, DefaultLanguage)
+ case Some(x) =>
+ api.AudioDTO(
+ s"${props.Domain}/${props.AudioFilesUrlSuffix}/${x.filePath}",
+ x.mimeType,
+ x.fileSize,
+ x.language
+ )
+ case None => api.AudioDTO("", "", 0, props.DefaultLanguage)
}
}
@@ -190,7 +195,7 @@ trait ConverterService {
)
}
- def getPhotoUrl(meta: domain.CoverPhoto): String = s"$RawImageApiUrl/${meta.imageId}"
+ def getPhotoUrl(meta: domain.CoverPhoto): String = s"${props.RawImageApiUrl}/${meta.imageId}"
def toApiCoverPhoto(meta: domain.CoverPhoto): api.CoverPhotoDTO = {
api.CoverPhotoDTO(
@@ -252,13 +257,13 @@ trait ConverterService {
def findAndConvertDomainToApiField[DomainType <: WithLanguage](
fields: Seq[DomainType],
language: Option[String]
- )(implicit mf: Manifest[DomainType]): Try[DomainType] = {
- findByLanguageOrBestEffort(fields, language.getOrElse(DefaultLanguage)) match {
+ )(implicit ct: ClassTag[DomainType]): Try[DomainType] = {
+ findByLanguageOrBestEffort(fields, language.getOrElse(props.DefaultLanguage)) match {
case Some(field) => Success(field)
case None =>
Failure(
CouldNotFindLanguageException(
- s"Could not find value for '${mf.runtimeClass.getName}' field. This is a data inconsistency or a bug."
+ s"Could not find value for '${ct.runtimeClass.getName}' field. This is a data inconsistency or a bug."
)
)
}
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/ReadService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/ReadService.scala
index 57052e24eb..41668f7b38 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/ReadService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/ReadService.scala
@@ -18,7 +18,7 @@ import scala.util.{Failure, Success, Try}
trait ReadService {
this: AudioRepository & SeriesRepository & ConverterService & TagSearchService & SearchConverterService =>
- val readService: ReadService
+ lazy val readService: ReadService
class ReadService {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/TranscriptionService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/TranscriptionService.scala
index 4b67bc77bd..ba2f646e5d 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/TranscriptionService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/TranscriptionService.scala
@@ -24,8 +24,8 @@ import scala.util.{Failure, Success, Try}
trait TranscriptionService {
this: NdlaS3Client & Props & NdlaBrightcoveClient & NdlaAWSTranscribeClient =>
- val transcriptionService: TranscriptionService
- val s3TranscribeClient: NdlaS3Client
+ lazy val transcriptionService: TranscriptionService
+ lazy val s3TranscribeClient: NdlaS3Client
sealed trait TranscriptionResult
case class TranscriptionComplete(transcription: String) extends TranscriptionResult
@@ -92,7 +92,7 @@ trait TranscriptionService {
val transcriptionJob = transcriptionJobResponse.transcriptionJob()
val transcriptionJobStatus = transcriptionJob.transcriptionJobStatus()
- if (transcriptionJobStatus == "COMPLETED") {
+ if (transcriptionJobStatus == TranscriptionJobStatus.COMPLETED) {
val transcribeUri = s"transcription/$language/$videoId.vtt"
getObjectFromS3(transcribeUri).map(TranscriptionComplete(_))
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/ValidationService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/ValidationService.scala
index 9e14ddac51..10e86d008d 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/ValidationService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/ValidationService.scala
@@ -27,7 +27,7 @@ import scala.util.{Failure, Success, Try}
trait ValidationService {
this: ConverterService & Props =>
- val validationService: ValidationService
+ lazy val validationService: ValidationService
class ValidationService {
@@ -174,7 +174,7 @@ trait ValidationService {
} else Seq.empty
}
- def validate[T <: domain.SeriesWithoutId](series: T): Try[T] = {
+ def validate(series: domain.SeriesWithoutId): Try[domain.SeriesWithoutId] = {
val validationMessages = validateNonEmpty("title", series.title).toSeq ++
series.title.flatMap(title => validateNonEmpty("title", title.language)) ++
series.title.flatMap(title => validateTitle("title", title, Seq.empty)) ++
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/WriteService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/WriteService.scala
index 46881214ec..973386806a 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/WriteService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/WriteService.scala
@@ -29,7 +29,7 @@ import scala.util.{Failure, Random, Success, Try}
trait WriteService {
this: ConverterService & ValidationService & AudioRepository & SeriesRepository & AudioIndexService &
SeriesIndexService & TagIndexService & NdlaS3Client & ReadService & Clock =>
- val writeService: WriteService
+ lazy val writeService: WriteService
class WriteService extends StrictLogging {
@@ -49,10 +49,10 @@ trait WriteService {
episodesToValidate.toSeq,
Some(existingSeries.id)
)
- validatedSeries <- validationService.validate(merged)
- updatedSeries <- seriesRepository.update(validatedSeries)
+ validatedSeries <- validationService.validate(merged.withoutId)
+ updatedSeries <- seriesRepository.update(merged)
_ <- updateSeriesForEpisodes(None, episodesToDelete.toSeq)
- _ <- updateSeriesForEpisodes(Some(validatedSeries.id), episodesToAdd.toSeq)
+ _ <- updateSeriesForEpisodes(Some(merged.id), episodesToAdd.toSeq)
updatedWithEpisodes = updatedSeries.copy(episodes = Some(validatedEpisodes))
_ <- seriesIndexService.indexDocument(updatedWithEpisodes)
converted <- converterService.toApiSeries(updatedWithEpisodes, Some(toUpdateSeries.language))
@@ -166,8 +166,8 @@ trait WriteService {
deleteSeries(seriesId).map(_ => None)
else {
for {
- validated <- validationService.validate(newSeries)
- updated <- seriesRepository.update(validated)
+ validated <- validationService.validate(newSeries.withoutId)
+ updated <- seriesRepository.update(newSeries)
indexed <- seriesIndexService.indexDocument(updated)
converted <- converterService.toApiSeries(indexed, None)
result = Some(converted)
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioIndexService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioIndexService.scala
index dfa2dc95e1..86a0bf17f6 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioIndexService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioIndexService.scala
@@ -26,12 +26,11 @@ import scala.util.{Failure, Try}
trait AudioIndexService {
this: Elastic4sClient & SearchConverterService & IndexService & SeriesIndexService & AudioRepository & Props =>
- val audioIndexService: AudioIndexService
+ lazy val audioIndexService: AudioIndexService
- class AudioIndexService extends StrictLogging with IndexService[AudioMetaInformation, SearchableAudioInformation] {
- import props.*
- override val documentType: String = SearchDocument
- override val searchIndex: String = SearchIndex
+ class AudioIndexService extends IndexService[AudioMetaInformation, SearchableAudioInformation] with StrictLogging {
+ override val documentType: String = props.SearchDocument
+ override val searchIndex: String = props.SearchIndex
override val repository: AudioRepository = audioRepository
override def createIndexRequests(domainModel: AudioMetaInformation, indexName: String): Try[Seq[IndexRequest]] = {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioSearchService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioSearchService.scala
index 83dbb4932b..ac13bb8aad 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioSearchService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/AudioSearchService.scala
@@ -28,12 +28,10 @@ import scala.util.{Failure, Success, Try}
trait AudioSearchService {
this: Elastic4sClient & AudioIndexService & SearchConverterService & SearchService & Props & ErrorHandling =>
- val audioSearchService: AudioSearchService
+ lazy val audioSearchService: AudioSearchService
class AudioSearchService extends StrictLogging with SearchService[api.AudioSummaryDTO] {
- import props.*
-
- override val searchIndex: String = SearchIndex
+ override val searchIndex: String = props.SearchIndex
override def hitToApiModel(hitString: String, language: String): Try[api.AudioSummaryDTO] = {
for {
@@ -106,9 +104,9 @@ trait AudioSearchService {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.page.getOrElse(1) * numResults
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new Helpers.ResultWindowTooLargeException())
} else {
@@ -125,7 +123,7 @@ trait AudioSearchService {
// Only add scroll param if it is first page
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/IndexService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/IndexService.scala
index 804b387232..ab1cf0dc5f 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/IndexService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/IndexService.scala
@@ -24,7 +24,7 @@ import scala.util.{Failure, Success, Try}
trait IndexService {
this: Elastic4sClient & BaseIndexService & SearchConverterService & AudioRepository & Props & SearchLanguage =>
- trait IndexService[D, T] extends BaseIndexService with StrictLogging {
+ abstract class IndexService[D, T] extends BaseIndexService with StrictLogging {
override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
val documentType: String
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchConverterService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchConverterService.scala
index 43b78e475d..5f83bad0ac 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchConverterService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchConverterService.scala
@@ -26,7 +26,7 @@ import scala.util.Try
trait SearchConverterService {
this: ConverterService & Props & SearchLanguage =>
- val searchConverterService: SearchConverterService
+ lazy val searchConverterService: SearchConverterService
class SearchConverterService extends StrictLogging {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchService.scala
index 872a21c6a6..dce96d80ea 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SearchService.scala
@@ -29,13 +29,12 @@ trait SearchService {
this: Elastic4sClient & SearchConverterService & Props & SearchLanguage =>
trait SearchService[T] extends StrictLogging {
- import props.*
val searchIndex: String
def scroll(scrollId: String, language: String): Try[SearchResult[T]] =
e4sClient
.execute {
- searchScroll(scrollId, ElasticSearchScrollKeepAlive)
+ searchScroll(scrollId, props.ElasticSearchScrollKeepAlive)
}
.flatMap(response => {
getHits(response.result, language).map(hits => {
@@ -145,8 +144,8 @@ trait SearchService {
def getStartAtAndNumResults(page: Option[Int], pageSize: Option[Int]): (Int, Int) = {
val numResults = pageSize match {
- case Some(num) => if (num > 0) num.min(MaxPageSize) else DefaultPageSize
- case None => DefaultPageSize
+ case Some(num) => if (num > 0) num.min(props.MaxPageSize) else props.DefaultPageSize
+ case None => props.DefaultPageSize
}
val startAt = page match {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesIndexService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesIndexService.scala
index f9ebf180af..36b5f11f7c 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesIndexService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesIndexService.scala
@@ -25,12 +25,11 @@ import scala.util.{Failure, Success, Try}
trait SeriesIndexService {
this: Elastic4sClient & SearchConverterService & IndexService & SeriesRepository & Props =>
- val seriesIndexService: SeriesIndexService
+ lazy val seriesIndexService: SeriesIndexService
- class SeriesIndexService extends StrictLogging with IndexService[Series, SearchableSeries] {
- import props.*
- override val documentType: String = SeriesSearchDocument
- override val searchIndex: String = SeriesSearchIndex
+ class SeriesIndexService extends IndexService[Series, SearchableSeries] with StrictLogging {
+ override val documentType: String = props.SeriesSearchDocument
+ override val searchIndex: String = props.SeriesSearchIndex
override val repository: SeriesRepository = seriesRepository
override def createIndexRequests(domainModel: Series, indexName: String): Try[Seq[IndexRequest]] = {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesSearchService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesSearchService.scala
index b85a6a24c9..edc5a73f3d 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesSearchService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/SeriesSearchService.scala
@@ -29,12 +29,10 @@ import scala.util.{Failure, Success, Try}
trait SeriesSearchService {
this: Elastic4sClient & SeriesIndexService & SearchConverterService & SearchService & ConverterService & Props &
ErrorHandling =>
- val seriesSearchService: SeriesSearchService
+ lazy val seriesSearchService: SeriesSearchService
class SeriesSearchService extends StrictLogging with SearchService[api.SeriesSummaryDTO] {
- import props.*
-
- override val searchIndex: String = SeriesSearchIndex
+ override val searchIndex: String = props.SeriesSearchIndex
override def hitToApiModel(hitString: String, language: String): Try[api.SeriesSummaryDTO] = {
for {
@@ -88,9 +86,9 @@ trait SeriesSearchService {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.page.getOrElse(1) * numResults
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new Helpers.ResultWindowTooLargeException())
} else {
@@ -107,7 +105,7 @@ trait SeriesSearchService {
// Only add scroll param if it is first page
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagIndexService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagIndexService.scala
index e54e1fb9ce..b33376915c 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagIndexService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagIndexService.scala
@@ -21,13 +21,11 @@ import scala.util.{Success, Try}
trait TagIndexService {
this: SearchConverterService & IndexService & AudioRepository & Props =>
- val tagIndexService: TagIndexService
+ lazy val tagIndexService: TagIndexService
- class TagIndexService extends StrictLogging with IndexService[AudioMetaInformation, SearchableTag] {
- import props.*
-
- override val documentType: String = AudioTagSearchDocument
- override val searchIndex: String = AudioTagSearchIndex
+ class TagIndexService extends IndexService[AudioMetaInformation, SearchableTag] with StrictLogging {
+ override val documentType: String = props.AudioTagSearchDocument
+ override val searchIndex: String = props.AudioTagSearchIndex
override val repository: Repository[AudioMetaInformation] = audioRepository
override def createIndexRequests(domainModel: AudioMetaInformation, indexName: String): Try[Seq[IndexRequest]] = {
diff --git a/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagSearchService.scala b/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagSearchService.scala
index 388d688dba..964e193164 100644
--- a/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagSearchService.scala
+++ b/audio-api/src/main/scala/no/ndla/audioapi/service/search/TagSearchService.scala
@@ -26,12 +26,10 @@ import scala.util.{Failure, Success, Try}
trait TagSearchService {
this: Elastic4sClient & SearchConverterService & SearchService & TagIndexService & SearchConverterService & Props &
ErrorHandling =>
- val tagSearchService: TagSearchService
+ lazy val tagSearchService: TagSearchService
class TagSearchService extends StrictLogging with SearchService[String] {
- import props.*
-
- override val searchIndex: String = AudioTagSearchIndex
+ override val searchIndex: String = props.AudioTagSearchIndex
override def hitToApiModel(hit: String, language: String): Try[String] = {
CirceUtil.tryParseAs[SearchableTag](hit).map(_.tag)
@@ -73,9 +71,9 @@ trait TagSearchService {
val (startAt, numResults) = getStartAtAndNumResults(Some(page), Some(pageSize))
val requestedResultWindow = pageSize * page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new Helpers.ResultWindowTooLargeException())
} else {
@@ -88,7 +86,7 @@ trait TagSearchService {
val searchWithScroll =
if (startAt != 0) { searchToExecute }
- else { searchToExecute.scroll(ElasticSearchScrollKeepAlive) }
+ else { searchToExecute.scroll(props.ElasticSearchScrollKeepAlive) }
e4sClient.execute(searchWithScroll) match {
case Success(response) =>
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/TestEnvironment.scala b/audio-api/src/test/scala/no/ndla/audioapi/TestEnvironment.scala
index cfb2374a1c..b809f057e9 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/TestEnvironment.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/TestEnvironment.scala
@@ -59,40 +59,40 @@ trait TestEnvironment
with ErrorHandling {
override lazy val props: AudioApiProperties = new AudioApiProperties
- val dataSource: HikariDataSource = mock[HikariDataSource]
- val audioRepository: AudioRepository = mock[AudioRepository]
- val seriesRepository: SeriesRepository = mock[SeriesRepository]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val audioRepository: AudioRepository = mock[AudioRepository]
+ override lazy val seriesRepository: SeriesRepository = mock[SeriesRepository]
- val s3Client: NdlaS3Client = mock[NdlaS3Client]
- val brightcoveClient: NdlaBrightcoveClient = mock[NdlaBrightcoveClient]
- val transcribeClient: NdlaAWSTranscribeClient = mock[NdlaAWSTranscribeClient]
+ override lazy val s3Client: NdlaS3Client = mock[NdlaS3Client]
+ override lazy val brightcoveClient: NdlaBrightcoveClient = mock[NdlaBrightcoveClient]
+ override lazy val transcribeClient: NdlaAWSTranscribeClient = mock[NdlaAWSTranscribeClient]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val readService: ReadService = mock[ReadService]
- val writeService: WriteService = mock[WriteService]
- val validationService: ValidationService = mock[ValidationService]
- val converterService: ConverterService = mock[ConverterService]
- val transcriptionService: TranscriptionService = mock[TranscriptionService]
- val s3TranscribeClient: NdlaS3Client = mock[NdlaS3Client]
+ override lazy val readService: ReadService = mock[ReadService]
+ override lazy val writeService: WriteService = mock[WriteService]
+ override lazy val validationService: ValidationService = mock[ValidationService]
+ override lazy val converterService: ConverterService = mock[ConverterService]
+ override lazy val transcriptionService: TranscriptionService = mock[TranscriptionService]
+ override lazy val s3TranscribeClient: NdlaS3Client = mock[NdlaS3Client]
- val internController: InternController = mock[InternController]
- val audioApiController: AudioController = mock[AudioController]
- val healthController: HealthController = mock[HealthController]
- val seriesController: SeriesController = mock[SeriesController]
+ override lazy val internController: InternController = mock[InternController]
+ override lazy val audioApiController: AudioController = mock[AudioController]
+ override lazy val healthController: HealthController = mock[HealthController]
+ override lazy val seriesController: SeriesController = mock[SeriesController]
- var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
- val audioSearchService: AudioSearchService = mock[AudioSearchService]
- val audioIndexService: AudioIndexService = mock[AudioIndexService]
- val seriesSearchService: SeriesSearchService = mock[SeriesSearchService]
- val seriesIndexService: SeriesIndexService = mock[SeriesIndexService]
- val tagSearchService: TagSearchService = mock[TagSearchService]
- val tagIndexService: TagIndexService = mock[TagIndexService]
- val searchConverterService: SearchConverterService = mock[SearchConverterService]
+ var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
+ override lazy val audioSearchService: AudioSearchService = mock[AudioSearchService]
+ override lazy val audioIndexService: AudioIndexService = mock[AudioIndexService]
+ override lazy val seriesSearchService: SeriesSearchService = mock[SeriesSearchService]
+ override lazy val seriesIndexService: SeriesIndexService = mock[SeriesIndexService]
+ override lazy val tagSearchService: TagSearchService = mock[TagSearchService]
+ override lazy val tagIndexService: TagIndexService = mock[TagIndexService]
+ override lazy val searchConverterService: SearchConverterService = mock[SearchConverterService]
- val clock: SystemClock = mock[SystemClock]
- def services: List[TapirController] = List.empty
- val swagger: SwaggerController = mock[SwaggerController]
+ override lazy val clock: SystemClock = mock[SystemClock]
+ def services: List[TapirController] = List.empty
+ val swagger: SwaggerController = mock[SwaggerController]
}
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/controller/AudioControllerTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/controller/AudioControllerTest.scala
index 2522e090ac..3ae58870dc 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/controller/AudioControllerTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/controller/AudioControllerTest.scala
@@ -293,8 +293,6 @@ class AudioControllerTest extends UnitSuite with TestEnvironment with Retries wi
}
test("That deleting language returns audio if exists") {
- import io.circe.generic.auto.*
-
when(writeService.deleteAudioLanguageVersion(1, "nb"))
.thenReturn(Success(Some(TestData.DefaultApiImageMetaInformation)))
@@ -352,11 +350,10 @@ class AudioControllerTest extends UnitSuite with TestEnvironment with Retries wi
.get(uri"http://localhost:$serverPort/audio-api/v1/audio/ids/?ids=1,2,3")
)
response.code.code should be(200)
- import io.circe.generic.auto.*
val parsedBody = unsafeParseAs[List[api.AudioMetaInformationDTO]](response.body)
parsedBody should be(expectedResult)
- verify(readService, times(1)).getAudiosByIds(eqTo(List(1, 2, 3)), any)
+ verify(readService, times(1)).getAudiosByIds(eqTo(List(1L, 2L, 3L)), any)
}
test("That GET /?query= doesnt pass empty-string search parameter") {
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/controller/InternControllerTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/controller/InternControllerTest.scala
index 60cc47eba6..0a66697886 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/controller/InternControllerTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/controller/InternControllerTest.scala
@@ -23,7 +23,7 @@ import sttp.client3.quick.*
import scala.util.{Failure, Success}
class InternControllerTest extends UnitSuite with TestEnvironment with TapirControllerTest {
- override val converterService = new ConverterService
+ override lazy val converterService = new ConverterService
override val controller: InternController = new InternController
val DefaultDomainImageMetaInformation: AudioMetaInformation = domain.AudioMetaInformation(
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/TranscriptionServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/TranscriptionServiceTest.scala
index a389c55ace..0a42960ba6 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/TranscriptionServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/TranscriptionServiceTest.scala
@@ -23,9 +23,9 @@ import software.amazon.awssdk.services.transcribe.model.{
import scala.util.Success
class TranscriptionServiceTest extends UnitSuite with TestEnvironment {
- override val transcriptionService: TranscriptionService = new TranscriptionService
- override val brightcoveClient: NdlaBrightcoveClient = new NdlaBrightcoveClient
- override lazy val props: AudioApiProperties = new AudioApiProperties {
+ override lazy val transcriptionService: TranscriptionService = new TranscriptionService
+ override lazy val brightcoveClient: NdlaBrightcoveClient = new NdlaBrightcoveClient
+ override lazy val props: AudioApiProperties = new AudioApiProperties {
override val BrightcoveAccountId: Prop[String] = propFromTestValue("BRIGHTCOVE_ACCOUNT_ID", "123")
override val BrightcoveClientId: Prop[String] = propFromTestValue("BRIGHTCOIVE_CLIENT_ID", "123")
override val BrightcoveClientSecret: Prop[String] = propFromTestValue("BRIGHTCOVE_CLIENT_SECRET", "123")
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/ValidationServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/ValidationServiceTest.scala
index 680443707c..8e4eece230 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/ValidationServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/ValidationServiceTest.scala
@@ -19,7 +19,7 @@ import org.mockito.Mockito.{doReturn, reset, spy, when}
import java.awt.image.BufferedImage
class ValidationServiceTest extends UnitSuite with TestEnvironment {
- override val validationService: ValidationService = spy(new ValidationService)
+ override lazy val validationService: ValidationService = spy(new ValidationService)
override def beforeEach(): Unit = {
reset(validationService)
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/WriteServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/WriteServiceTest.scala
index 38e94c630d..d59f753a2e 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/WriteServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/WriteServiceTest.scala
@@ -30,8 +30,8 @@ import java.io.FileInputStream
import scala.util.{Failure, Success}
class WriteServiceTest extends UnitSuite with TestEnvironment {
- override val writeService = new WriteService
- override val converterService = new ConverterService
+ override lazy val writeService = new WriteService
+ override lazy val converterService = new ConverterService
val (newFileName1, newFileName2) = ("AbCdeF.mp3", "GhijKl.mp3")
val filePartMock: UploadedFile = mock[UploadedFile]
val s3ObjectMock: HeadObjectResponse = mock[HeadObjectResponse]
@@ -114,7 +114,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
val fis = mock[FileInputStream]
when(filePartMock.stream).thenReturn(fis)
- when(s3ObjectMock.contentLength()).thenReturn(1024)
+ when(s3ObjectMock.contentLength()).thenReturn(1024L)
when(s3ObjectMock.contentType()).thenReturn("audio/mp3")
reset(audioRepository)
@@ -281,7 +281,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(s3Client.headObject(any)).thenReturn(Success(s3ObjectMock))
when(audioIndexService.indexDocument(any[domain.AudioMetaInformation])).thenReturn(Success(afterInsert))
when(tagIndexService.indexDocument(any[domain.AudioMetaInformation])).thenReturn(Success(afterInsert))
- when(audioRepository.setSeriesId(any, any)(any)).thenReturn(Success(1))
+ when(audioRepository.setSeriesId(any, any)(any)).thenReturn(Success(1L))
val result = writeService.storeNewAudio(newAudioMeta, filePartMock, testUser)
result.isSuccess should be(true)
@@ -488,7 +488,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(audioRepository.update(any[domain.AudioMetaInformation], any[Long])).thenReturn(Success(afterInsert))
when(audioIndexService.indexDocument(any[domain.AudioMetaInformation])).thenReturn(Success(afterInsert))
when(tagIndexService.indexDocument(any[domain.AudioMetaInformation])).thenReturn(Success(afterInsert))
- when(audioRepository.setSeriesId(any, any)(any)).thenReturn(Success(1))
+ when(audioRepository.setSeriesId(any, any)(any)).thenReturn(Success(1L))
val result = writeService.updateAudio(1, updatedAudioMeta, Some(filePartMock), testUser)
result.isSuccess should be(true)
@@ -645,8 +645,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
Success(passedEpisodes)
})
- when(validationService.validate(any[domain.Series])).thenAnswer((i: InvocationOnMock) => {
- Success(i.getArgument[domain.Series](0))
+ when(validationService.validate(any[domain.SeriesWithoutId])).thenAnswer((i: InvocationOnMock) => {
+ Success(i.getArgument[domain.SeriesWithoutId](0))
})
}
@@ -663,7 +663,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
val id = i.getArgument[Long](0)
series.episodes.get.find(_.id.contains(id))
})
- when(seriesRepository.insert(any[domain.Series])(any[DBSession]))
+ when(seriesRepository.insert(any[domain.SeriesWithoutId])(any[DBSession]))
.thenReturn(Failure(new RuntimeException("weird failure there buddy")))
val updateSeries = api.NewSeriesDTO(
@@ -743,7 +743,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
val id = i.getArgument[Long](0)
series.episodes.get.find(_.id.contains(id))
})
- when(audioRepository.setSeriesId(any[Long], any[Option[Long]])(any[DBSession])).thenReturn(Success(1))
+ when(audioRepository.setSeriesId(any[Long], any[Option[Long]])(any[DBSession])).thenReturn(Success(1L))
when(seriesRepository.insert(any[domain.SeriesWithoutId])(any[DBSession]))
.thenAnswer((i: InvocationOnMock) => {
@@ -797,7 +797,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
val id = i.getArgument[Long](0)
episodesMap.get(id)
})
- when(audioRepository.setSeriesId(any[Long], any[Option[Long]])(any[DBSession])).thenReturn(Success(1))
+ when(audioRepository.setSeriesId(any[Long], any[Option[Long]])(any[DBSession])).thenReturn(Success(1L))
when(seriesRepository.update(any[domain.Series])(any[DBSession])).thenAnswer((i: InvocationOnMock) => {
Success(i.getArgument[domain.Series](0))
})
@@ -816,7 +816,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
hasRSS = Some(true)
)
- val result = writeService.updateSeries(1, updateSeries)
+ val result = writeService.updateSeries(1L, updateSeries)
result.isSuccess should be(true)
verify(audioRepository, times(1)).setSeriesId(eqTo(1L), eqTo(None))(any[DBSession])
@@ -1000,10 +1000,10 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
)
)
- val afterInsert = audio.copy(id = Some(5555), revision = Some(1))
+ val afterInsert = audio.copy(id = Some(5555L), revision = Some(1))
when(s3Client.deleteObject(any)).thenReturn(Success(mock[DeleteObjectResponse]))
- when(audioRepository.withId(5555)).thenReturn(Some(audio))
+ when(audioRepository.withId(5555L)).thenReturn(Some(audio))
when(validationService.validateAudioFile(any)).thenReturn(Seq.empty)
when(s3Client.putObject(any, any)).thenReturn(Success(mock[PutObjectResponse]))
when(s3Client.headObject(any)).thenReturn(Success(s3ObjectMock))
@@ -1019,7 +1019,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(audioRepository.update(any[domain.AudioMetaInformation], any[Long])).thenReturn(Success(afterInsert))
when(audioIndexService.indexDocument(any[domain.AudioMetaInformation])).thenReturn(Success(afterInsert))
when(tagIndexService.indexDocument(any[domain.AudioMetaInformation])).thenReturn(Success(afterInsert))
- when(audioRepository.setSeriesId(any, any)(any)).thenReturn(Success(5555))
+ when(audioRepository.setSeriesId(any, any)(any)).thenReturn(Success(5555L))
val result = writeService.updateAudio(5555, updatedAudioMeta, Some(filePartMock), testUser)
result.isSuccess should be(true)
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/search/AudioSearchServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/search/AudioSearchServiceTest.scala
index ba610c0eb4..f64b0e6f1d 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/search/AudioSearchServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/search/AudioSearchServiceTest.scala
@@ -23,18 +23,16 @@ import org.mockito.Mockito.when
import scala.util.Success
class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
- import props.*
-
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val audioSearchService = new AudioSearchService
- override val audioIndexService: AudioIndexService = new AudioIndexService {
+ override lazy val audioSearchService = new AudioSearchService
+ override lazy val audioIndexService: AudioIndexService = new AudioIndexService {
override val indexShards = 1
}
- override val seriesIndexService: SeriesIndexService = new SeriesIndexService {
+ override lazy val seriesIndexService: SeriesIndexService = new SeriesIndexService {
override val indexShards = 1
}
- override val searchConverterService = new SearchConverterService
+ override lazy val searchConverterService = new SearchConverterService
val byNcSa: Copyright =
Copyright(
@@ -254,33 +252,33 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That getStartAtAndNumResults returns default values for None-input") {
- audioSearchService.getStartAtAndNumResults(None, None) should equal((0, DefaultPageSize))
+ audioSearchService.getStartAtAndNumResults(None, None) should equal((0, props.DefaultPageSize))
}
test("That getStartAtAndNumResults returns SEARCH_MAX_PAGE_SIZE for value greater than SEARCH_MAX_PAGE_SIZE") {
- audioSearchService.getStartAtAndNumResults(None, Some(10001)) should equal((0, MaxPageSize))
+ audioSearchService.getStartAtAndNumResults(None, Some(10001)) should equal((0, props.MaxPageSize))
}
test(
"That getStartAtAndNumResults returns the correct calculated start at for page and page-size with default page-size"
) {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
audioSearchService.getStartAtAndNumResults(Some(page), None) should equal(
- (expectedStartAt, DefaultPageSize)
+ (expectedStartAt, props.DefaultPageSize)
)
}
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
val page = 123
- val expectedStartAt = (page - 1) * MaxPageSize
- audioSearchService.getStartAtAndNumResults(Some(page), Some(MaxPageSize)) should equal(
- (expectedStartAt, MaxPageSize)
+ val expectedStartAt = (page - 1) * props.MaxPageSize
+ audioSearchService.getStartAtAndNumResults(Some(page), Some(props.MaxPageSize)) should equal(
+ (expectedStartAt, props.MaxPageSize)
)
}
test("That no language returns all documents ordered by title ascending") {
- val Success(results) = audioSearchService.matchingQuery(searchSettings.copy())
+ val Success(results) = audioSearchService.matchingQuery(searchSettings.copy()): @unchecked
results.totalCount should be(6)
results.results.head.id should be(4)
results.results.last.id should be(6)
@@ -288,15 +286,17 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering on license only returns documents with given license for all languages") {
val Success(results) =
- audioSearchService.matchingQuery(searchSettings.copy(license = Some(License.PublicDomain.toString)))
+ audioSearchService.matchingQuery(searchSettings.copy(license = Some(License.PublicDomain.toString))): @unchecked
results.totalCount should be(2)
results.results.head.id should be(4)
results.results.last.id should be(2)
}
test("That paging returns only hits on current page and not more than page-size") {
- val Success(page1) = audioSearchService.matchingQuery(searchSettings.copy(page = Some(1), pageSize = Some(2)))
- val Success(page2) = audioSearchService.matchingQuery(searchSettings.copy(page = Some(2), pageSize = Some(2)))
+ val Success(page1) =
+ audioSearchService.matchingQuery(searchSettings.copy(page = Some(1), pageSize = Some(2))): @unchecked
+ val Success(page2) =
+ audioSearchService.matchingQuery(searchSettings.copy(page = Some(2), pageSize = Some(2))): @unchecked
page1.totalCount should be(6)
page1.page.get should be(1)
page1.results.size should be(2)
@@ -314,7 +314,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some("Pingvinen"),
language = Some("nb")
)
- )
+ ): @unchecked
results.totalCount should be(1)
results.results.head.id should be(2)
}
@@ -325,7 +325,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some("2"),
language = Some("nb")
)
- )
+ ): @unchecked
results.totalCount should be(1)
results.results.head.id should be(2)
}
@@ -336,7 +336,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some("and"),
language = Some("nb")
)
- )
+ ): @unchecked
results.totalCount should be(1)
results.results.head.id should be(4)
}
@@ -347,7 +347,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some("batmen"),
language = Some("nb")
)
- )
+ ): @unchecked
results.totalCount should be(0)
}
@@ -358,7 +358,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = Some("nb"),
license = Some(License.Copyrighted.toString)
)
- )
+ ): @unchecked
results.totalCount should be(1)
results.results.head.id should be(1)
}
@@ -369,7 +369,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some("bilde + bil"),
language = Some("nb")
)
- )
+ ): @unchecked
search1.results.map(_.id) should equal(Seq.empty)
val Success(search2) = audioSearchService.matchingQuery(
@@ -377,13 +377,13 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some("ute + -går"),
language = Some("nb")
)
- )
+ ): @unchecked
search2.results.map(_.id) should equal(Seq(3))
}
test("That searching for all languages and specifying no language should return the same") {
- val Success(results1) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("*")))
- val Success(results2) = audioSearchService.matchingQuery(searchSettings.copy(language = None))
+ val Success(results1) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("*"))): @unchecked
+ val Success(results2) = audioSearchService.matchingQuery(searchSettings.copy(language = None)): @unchecked
results1.totalCount should be(results2.totalCount)
results1.results.head should be(results2.results.head)
@@ -392,12 +392,12 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That searching for 'nb' should return all results") {
- val Success(results) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("nb")))
+ val Success(results) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("nb"))): @unchecked
results.totalCount should be(5)
}
test("That searching for 'en' should only return results with english title") {
- val Success(result) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("en")))
+ val Success(result) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("en"))): @unchecked
result.totalCount should be(2)
result.language should be("en")
@@ -409,7 +409,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That searching for language not in predefined list should work") {
- val Success(result) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("ukr")))
+ val Success(result) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("ukr"))): @unchecked
result.totalCount should be(1)
result.language should be("ukr")
@@ -418,14 +418,15 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That searching for language not in indexed data should not fail") {
- val Success(result) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("ait"))) // Arikem
+ val Success(result) =
+ audioSearchService.matchingQuery(searchSettings.copy(language = Some("ait"))): @unchecked // Arikem
result.totalCount should be(0)
result.language should be("ait")
}
test("That 'supported languages' should match all possible languages") {
- val Success(result1) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("en")))
- val Success(result2) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("nb")))
+ val Success(result1) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("en"))): @unchecked
+ val Success(result2) = audioSearchService.matchingQuery(searchSettings.copy(language = Some("nb"))): @unchecked
// 'Donald' with 'en', 'nb' and 'nn'
result1.results.head.supportedLanguages should be(audio4.titles.map(_.language))
@@ -453,8 +454,10 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That hit is returned in the matched language") {
- val Success(searchResultEn) = audioSearchService.matchingQuery(searchSettings.copy(query = Some("Unrelated")))
- val Success(searchResultNb) = audioSearchService.matchingQuery(searchSettings.copy(query = Some("Urelatert")))
+ val Success(searchResultEn) =
+ audioSearchService.matchingQuery(searchSettings.copy(query = Some("Unrelated"))): @unchecked
+ val Success(searchResultNb) =
+ audioSearchService.matchingQuery(searchSettings.copy(query = Some("Urelatert"))): @unchecked
searchResultNb.totalCount should be(1)
searchResultNb.results.head.title.language should be("nb")
@@ -466,35 +469,37 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That sorting by lastUpdated asc functions correctly") {
- val Success(search) = audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedAsc))
+ val Success(search) =
+ audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedAsc)): @unchecked
search.totalCount should be(6)
search.results.map(_.id) should be(Seq(5, 3, 2, 4, 6, 7))
}
test("That sorting by lastUpdated desc functions correctly") {
- val Success(search) = audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedDesc))
+ val Success(search) =
+ audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedDesc)): @unchecked
search.totalCount should be(6)
search.results.map(_.id) should be(Seq(6, 7, 4, 2, 3, 5))
}
test("That sorting by id asc functions correctly") {
- val Success(search) = audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdAsc))
+ val Success(search) = audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdAsc)): @unchecked
search.totalCount should be(6)
search.results.map(_.id) should be(Seq(2, 3, 4, 5, 6, 7))
}
test("That sorting by id desc functions correctly") {
- val Success(search) = audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdDesc))
+ val Success(search) = audioSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdDesc)): @unchecked
search.totalCount should be(6)
search.results.map(_.id) should be(Seq(7, 6, 5, 4, 3, 2))
}
test("That supportedLanguages are sorted correctly") {
- val Success(result) = audioSearchService.matchingQuery(searchSettings.copy(query = Some("Unrelated")))
+ val Success(result) = audioSearchService.matchingQuery(searchSettings.copy(query = Some("Unrelated"))): @unchecked
result.results.head.supportedLanguages should be(Seq("nb", "en"))
}
@@ -505,11 +510,11 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(initialSearch) =
audioSearchService.matchingQuery(
searchSettings.copy(pageSize = Some(pageSize), sort = Sort.ByIdAsc, shouldScroll = true)
- )
+ ): @unchecked
- val Success(scroll1) = audioSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = audioSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = audioSearchService.scroll(scroll2.scrollId.get, "*")
+ val Success(scroll1) = audioSearchService.scroll(initialSearch.scrollId.get, "*"): @unchecked
+ val Success(scroll2) = audioSearchService.scroll(scroll1.scrollId.get, "*"): @unchecked
+ val Success(scroll3) = audioSearchService.scroll(scroll2.scrollId.get, "*"): @unchecked
initialSearch.results.map(_.id) should be(expectedIds.head)
scroll1.results.map(_.id) should be(expectedIds(1))
@@ -518,18 +523,19 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That filtering for audio-type works as expected") {
- val Success(search1) = audioSearchService.matchingQuery(searchSettings.copy(audioType = None))
+ val Success(search1) = audioSearchService.matchingQuery(searchSettings.copy(audioType = None)): @unchecked
search1.totalCount should be(6)
search1.results.head.id should be(4)
search1.results.last.id should be(6)
- val Success(search2) = audioSearchService.matchingQuery(searchSettings.copy(audioType = Some(AudioType.Podcast)))
+ val Success(search2) =
+ audioSearchService.matchingQuery(searchSettings.copy(audioType = Some(AudioType.Podcast))): @unchecked
search2.totalCount should be(2)
search2.results.map(_.id) should be(Seq(7, 6))
}
test("That searching matches manuscript") {
- val Success(search1) = audioSearchService.matchingQuery(searchSettings.copy(query = Some("manuscript")))
+ val Success(search1) = audioSearchService.matchingQuery(searchSettings.copy(query = Some("manuscript"))): @unchecked
search1.totalCount should be(2)
search1.results.map(_.id) should be(Seq(2, 5))
@@ -537,35 +543,38 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering for episodes of series works as expected") {
val Success(search1) =
- audioSearchService.matchingQuery(searchSettings.copy(seriesFilter = Some(true), sort = Sort.ByIdAsc))
+ audioSearchService.matchingQuery(searchSettings.copy(seriesFilter = Some(true), sort = Sort.ByIdAsc)): @unchecked
search1.totalCount should be(1)
search1.results.map(_.id) should be(Seq(6))
val Success(search2) =
- audioSearchService.matchingQuery(searchSettings.copy(seriesFilter = Some(false), sort = Sort.ByIdAsc))
+ audioSearchService.matchingQuery(searchSettings.copy(seriesFilter = Some(false), sort = Sort.ByIdAsc)): @unchecked
search2.totalCount should be(5)
search2.results.map(_.id) should be(Seq(2, 3, 4, 5, 7))
val Success(search3) =
- audioSearchService.matchingQuery(searchSettings.copy(seriesFilter = None, sort = Sort.ByIdAsc))
+ audioSearchService.matchingQuery(searchSettings.copy(seriesFilter = None, sort = Sort.ByIdAsc)): @unchecked
search3.totalCount should be(6)
search3.results.map(_.id) should be(Seq(2, 3, 4, 5, 6, 7))
}
test("That searching for podcast meta introductions works") {
- val Success(search1) = audioSearchService.matchingQuery(searchSettings.copy(query = Some("podcastintroritehere")))
+ val Success(search1) =
+ audioSearchService.matchingQuery(searchSettings.copy(query = Some("podcastintroritehere"))): @unchecked
search1.totalCount should be(1)
search1.results.map(_.id) should be(Seq(6))
val Success(search2) =
- audioSearchService.matchingQuery(searchSettings.copy(query = Some("podcastintroritehere"), language = Some("en")))
+ audioSearchService.matchingQuery(
+ searchSettings.copy(query = Some("podcastintroritehere"), language = Some("en"))
+ ): @unchecked
search2.totalCount should be(0)
search2.results.map(_.id) should be(Seq())
}
test("That search result includes updatedBy field") {
val Success(searchResult) =
- audioSearchService.matchingQuery(searchSettings.copy(query = Some("Pingvinen")))
+ audioSearchService.matchingQuery(searchSettings.copy(query = Some("Pingvinen"))): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.lastUpdated should be(updated4)
@@ -580,7 +589,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = Some("en"),
sort = Sort.ByIdAsc
)
- )
+ ): @unchecked
result1.results.map(_.id) should be(Seq(2, 3, 4, 5, 6, 7))
result1.results.head.title.language should be("nb")
result1.results(1).title.language should be("nb")
@@ -596,7 +605,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = Some("nb"),
sort = Sort.ByIdAsc
)
- )
+ ): @unchecked
result2.results.map(_.id) should be(Seq(2, 3, 4, 5, 6, 7))
result2.results.head.title.language should be("nb")
result2.results(1).title.language should be("nb")
@@ -614,7 +623,7 @@ class AudioSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = Some("nb"),
sort = Sort.ByIdAsc
)
- )
+ ): @unchecked
result1.results.map(_.id) should be(Seq(4))
}
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/search/SearchConverterServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/search/SearchConverterServiceTest.scala
index cf9841f5d5..7da6a72ef4 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/search/SearchConverterServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/search/SearchConverterServiceTest.scala
@@ -20,7 +20,7 @@ import no.ndla.search.model.{SearchableLanguageList, SearchableLanguageValues}
class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
- override val searchConverterService = new SearchConverterService
+ override lazy val searchConverterService = new SearchConverterService
val byNcSa: Copyright =
Copyright(
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/search/SeriesSearchServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/search/SeriesSearchServiceTest.scala
index 6de5e6219a..913d6a3b1d 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/search/SeriesSearchServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/search/SeriesSearchServiceTest.scala
@@ -14,17 +14,15 @@ import no.ndla.audioapi.{TestData, TestEnvironment, UnitSuite}
import no.ndla.common.model.domain as common
import no.ndla.scalatestsuite.ElasticsearchIntegrationSuite
-import scala.util.Success
-
class SeriesSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val seriesSearchService = new SeriesSearchService
- override val seriesIndexService: SeriesIndexService = new SeriesIndexService {
+ override lazy val seriesSearchService = new SeriesSearchService
+ override lazy val seriesIndexService: SeriesIndexService = new SeriesIndexService {
override val indexShards = 1
}
- override val searchConverterService = new SearchConverterService
- override val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
val seriesToIndex: Seq[Series] = Seq(
TestData.SampleSeries.copy(
@@ -72,28 +70,27 @@ class SeriesSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSui
test("That query search works as expected") {
indexAndWait(seriesToIndex)
- val Success(result1) = seriesSearchService.matchingQuery(settings.copy(query = Some("tiger")))
+ val result1 = seriesSearchService.matchingQuery(settings.copy(query = Some("tiger"))).get
result1.results.map(_.id) should be(Seq(2))
- val Success(result2) = seriesSearchService.matchingQuery(settings.copy(query = Some("Lyd med")))
+ val result2 = seriesSearchService.matchingQuery(settings.copy(query = Some("Lyd med"))).get
result2.results.map(_.id) should be(Seq(1, 2, 3))
- val Success(result3) = seriesSearchService.matchingQuery(settings.copy(query = Some("epler")))
+ val result3 = seriesSearchService.matchingQuery(settings.copy(query = Some("epler"))).get
result3.results.map(_.id) should be(Seq(1))
- val Success(result4) =
- seriesSearchService.matchingQuery(settings.copy(query = Some("mixtepec"), language = Some("mix")))
+ val result4 = seriesSearchService.matchingQuery(settings.copy(query = Some("mixtepec"), language = Some("mix"))).get
result4.results.map(_.id) should be(Seq(3))
}
test("That descriptions are searchable") {
indexAndWait(seriesToIndex)
- val Success(result1) = seriesSearchService.matchingQuery(settings.copy(query = Some("megabeskrivelse")))
+ val result1 = seriesSearchService.matchingQuery(settings.copy(query = Some("megabeskrivelse"))).get
result1.results.map(_.id) should be(Seq(1))
- val Success(result2) =
- seriesSearchService.matchingQuery(settings.copy(query = Some("description"), language = Some("en")))
+ val result2 =
+ seriesSearchService.matchingQuery(settings.copy(query = Some("description"), language = Some("en"))).get
result2.results.map(_.id) should be(Seq(1))
}
@@ -118,27 +115,31 @@ class SeriesSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSui
)
indexAndWait(seriesToIndex)
- val Success(result1) = seriesSearchService.matchingQuery(
- settings.copy(
- query = None,
- fallback = true,
- language = Some("nb"),
- sort = Sort.ByIdAsc
+ val result1 = seriesSearchService
+ .matchingQuery(
+ settings.copy(
+ query = None,
+ fallback = true,
+ language = Some("nb"),
+ sort = Sort.ByIdAsc
+ )
)
- )
+ .get
result1.results.length should be(seriesToIndex.length)
result1.results.map(_.id) should be(Seq(1, 2, 3))
result1.results.head.title.language should be("nb")
result1.results.last.title.language should be("mix")
- val Success(result2) = seriesSearchService.matchingQuery(
- settings.copy(
- query = None,
- fallback = true,
- language = Some("en"),
- sort = Sort.ByIdAsc
+ val result2 = seriesSearchService
+ .matchingQuery(
+ settings.copy(
+ query = None,
+ fallback = true,
+ language = Some("en"),
+ sort = Sort.ByIdAsc
+ )
)
- )
+ .get
result2.results.length should be(seriesToIndex.length)
result2.results.map(_.id) should be(Seq(1, 2, 3))
result2.results.head.title.language should be("en")
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagIndexServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagIndexServiceTest.scala
index ee27a77567..ceac71cdfd 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagIndexServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagIndexServiceTest.scala
@@ -15,11 +15,11 @@ class TagIndexServiceTest extends ElasticsearchIntegrationSuite with TestEnviron
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val tagIndexService: TagIndexService = new TagIndexService {
+ override lazy val tagIndexService: TagIndexService = new TagIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
test("That indexing does not fail if no tags are present") {
tagIndexService.createIndexAndAlias()
diff --git a/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagSearchServiceTest.scala b/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagSearchServiceTest.scala
index 236c82f8a3..7a48ea5653 100644
--- a/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagSearchServiceTest.scala
+++ b/audio-api/src/test/scala/no/ndla/audioapi/service/search/TagSearchServiceTest.scala
@@ -19,12 +19,12 @@ class TagSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnviro
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val tagSearchService = new TagSearchService
- override val tagIndexService: TagIndexService = new TagIndexService {
+ override lazy val tagSearchService = new TagSearchService
+ override lazy val tagIndexService: TagIndexService = new TagIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val audio1: AudioMetaInformation = TestData.sampleAudio.copy(
tags = Seq(
@@ -82,14 +82,14 @@ class TagSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnviro
}
test("That searching for tags returns sensible results") {
- val Success(result) = tagSearchService.matchingQuery("test", "nb", 1, 100)
+ val Success(result) = tagSearchService.matchingQuery("test", "nb", 1, 100): @unchecked
result.totalCount should be(3)
result.results should be(Seq("test", "testemer", "testing"))
}
test("That only prefixes are matched") {
- val Success(result) = tagSearchService.matchingQuery("kylling", "nb", 1, 100)
+ val Success(result) = tagSearchService.matchingQuery("kylling", "nb", 1, 100): @unchecked
result.totalCount should be(1)
result.results should be(Seq("kyllingfilet"))
diff --git a/build.mill b/build.mill
index 7acc892cba..16f261e231 100644
--- a/build.mill
+++ b/build.mill
@@ -1,4 +1,4 @@
-//| mill-version: 1.0.2
+//| mill-version: 1.0.3
//| mvnDeps: [
//| "com.lihaoyi::mill-contrib-docker:$MILL_VERSION",
//| "io.circe::circe-generic:0.14.9",
diff --git a/common/src/main/scala-3/no/ndla/common/implicits/package.scala b/common/src/main/scala-3/no/ndla/common/implicits/package.scala
index 21c3991f22..ade9375d6e 100644
--- a/common/src/main/scala-3/no/ndla/common/implicits/package.scala
+++ b/common/src/main/scala-3/no/ndla/common/implicits/package.scala
@@ -3,6 +3,7 @@
* Copyright (C) 2024 NDLA
*
* See LICENSE
+ *
*/
package no.ndla.common
@@ -11,7 +12,7 @@ import io.circe.DecodingFailure.Reason
import io.circe.syntax.EncoderOps
import io.circe.{Decoder, DecodingFailure, Encoder}
-import scala.reflect.ClassTag
+import scala.annotation.unused
import scala.util.{Failure, Success, Try}
package object implicits {
@@ -39,7 +40,7 @@ package object implicits {
case class ControlFlowException(returnValue: Throwable) extends RuntimeException()
- def permitTry[A: ClassTag](f: PermittedTryContext ?=> Try[A]): Try[A] = {
+ def permitTry[A](f: PermittedTryContext ?=> Try[A]): Try[A] = {
try {
f(using PermittedTryContext())
} catch {
@@ -48,17 +49,39 @@ package object implicits {
}
}
- implicit class ctxctx[A: ClassTag](self: Try[A]) {
- def ?(using PermittedTryContext): A = {
+ implicit class ctxctx[A](self: Try[A]) {
+ def ?(using
+ @unused(
+ "This parameter is only to make sure we dont throw exceptions outside of a caught context"
+ ) ctx: PermittedTryContext
+ ): A = {
self match {
case Failure(ex) => throw ControlFlowException(ex)
case Success(value) => value
}
}
+
+ def ??(using
+ @unused(
+ "This parameter is only to make sure we dont throw exceptions outside of a caught context"
+ ) ctx: PermittedTryContext
+ ): Unit = {
+ self match {
+ case Failure(ex) => throw ControlFlowException(ex)
+ case Success(_) => ()
+ }
+ }
}
extension [T](opt: Option[T]) {
- def toTry(throwable: Throwable): Try[T] = Failure(throwable)
+ def toTry(throwable: Throwable): Try[T] = opt match {
+ case Some(value) => Success(value)
+ case None => Failure(throwable)
+ }
+ }
+
+ extension [T](t: Try[T]) {
+ def unit: Try[Unit] = t.map(_ => ())
}
implicit class StringOption(private val self: Option[String]) {
@@ -73,7 +96,7 @@ package object implicits {
implicit def eitherDecoder[A: Decoder, B: Decoder]: Decoder[Either[A, B]] = Decoder.instance { c =>
c.value.as[B] match {
case Right(value) => Right(Right(value))
- case Left(_) =>
+ case Left(_) =>
c.value.as[A] match {
case Right(value) => Right(Left(value))
case Left(_) => Left(DecodingFailure(Reason.CustomReason(s"Could not match ${c.value} to Either type"), c))
diff --git a/common/src/main/scala/no/ndla/common/CirceUtil.scala b/common/src/main/scala/no/ndla/common/CirceUtil.scala
index 5b8de2b29f..b5d796badb 100644
--- a/common/src/main/scala/no/ndla/common/CirceUtil.scala
+++ b/common/src/main/scala/no/ndla/common/CirceUtil.scala
@@ -10,11 +10,7 @@ package no.ndla.common
import enumeratum.*
import io.circe.*
-import io.circe.generic.semiauto.deriveEncoder
import io.circe.syntax.*
-import io.circe.generic.encoding.DerivedAsObjectEncoder
-import io.circe.{Decoder, Encoder}
-import shapeless.Lazy
import scala.util.{Failure, Try}
@@ -52,14 +48,11 @@ object CirceUtil {
json.mapObject(_.add("typename", Json.fromString(clazz.getSimpleName)))
}
- def deriveEncoderWithTypename[T](implicit encode: Lazy[DerivedAsObjectEncoder[T]]): Encoder[T] = {
- val encoder = deriveEncoder[T]
+ inline def deriveEncoderWithTypename[T](using encoder: Encoder[T]): Encoder[T] =
Encoder.instance[T] { value =>
- val json = encoder(value)
-
+ val json = encoder.apply(value)
addTypenameDiscriminator(json, value.getClass)
}
- }
private val stringDecoder = implicitly[Decoder[String]]
diff --git a/common/src/main/scala/no/ndla/common/Clock.scala b/common/src/main/scala/no/ndla/common/Clock.scala
index bbc8dbc74d..5cf4675ab2 100644
--- a/common/src/main/scala/no/ndla/common/Clock.scala
+++ b/common/src/main/scala/no/ndla/common/Clock.scala
@@ -11,7 +11,7 @@ package no.ndla.common
import no.ndla.common.model.NDLADate
trait Clock {
- val clock: SystemClock
+ lazy val clock: SystemClock
class SystemClock {
diff --git a/common/src/main/scala/no/ndla/common/UUIDUtil.scala b/common/src/main/scala/no/ndla/common/UUIDUtil.scala
index 35f391314e..37970cd80d 100644
--- a/common/src/main/scala/no/ndla/common/UUIDUtil.scala
+++ b/common/src/main/scala/no/ndla/common/UUIDUtil.scala
@@ -11,7 +11,7 @@ package no.ndla.common
import java.util.UUID
trait UUIDUtil {
- val uuidUtil: UUIDUtil
+ lazy val uuidUtil: UUIDUtil
class UUIDUtil {
def randomUUID(): UUID = {
diff --git a/common/src/main/scala/no/ndla/common/aws/NdlaAWSTranscribeClient.scala b/common/src/main/scala/no/ndla/common/aws/NdlaAWSTranscribeClient.scala
index 8b1f717808..9b94b025cd 100644
--- a/common/src/main/scala/no/ndla/common/aws/NdlaAWSTranscribeClient.scala
+++ b/common/src/main/scala/no/ndla/common/aws/NdlaAWSTranscribeClient.scala
@@ -14,7 +14,7 @@ import software.amazon.awssdk.services.transcribe.{TranscribeClient, TranscribeC
import scala.util.{Failure, Try}
trait NdlaAWSTranscribeClient {
- val transcribeClient: NdlaAWSTranscribeClient
+ lazy val transcribeClient: NdlaAWSTranscribeClient
class NdlaAWSTranscribeClient(region: Option[String]) {
@@ -52,16 +52,16 @@ trait NdlaAWSTranscribeClient {
.build()
)
- if (includeSubtitles) {
+ val toBuild = if (includeSubtitles) {
requestBuilder.subtitles(
Subtitles
.builder()
.formats(SubtitleFormat.valueOf(outputSubtitleFormat))
.build()
)
- }
+ } else { requestBuilder }
- client.startTranscriptionJob(requestBuilder.build())
+ client.startTranscriptionJob(toBuild.build())
}
def getTranscriptionJob(jobName: String): Try[GetTranscriptionJobResponse] = {
diff --git a/common/src/main/scala/no/ndla/common/aws/NdlaS3Client.scala b/common/src/main/scala/no/ndla/common/aws/NdlaS3Client.scala
index b677e349b1..6fded0ed89 100644
--- a/common/src/main/scala/no/ndla/common/aws/NdlaS3Client.scala
+++ b/common/src/main/scala/no/ndla/common/aws/NdlaS3Client.scala
@@ -17,7 +17,7 @@ import software.amazon.awssdk.services.s3.{S3Client, S3ClientBuilder}
import scala.util.Try
trait NdlaS3Client {
- val s3Client: NdlaS3Client
+ lazy val s3Client: NdlaS3Client
class NdlaS3Client(bucket: String, region: Option[String]) {
@@ -82,7 +82,7 @@ trait NdlaS3Client {
)
}
- def updateMetadata(key: String, metadata: java.util.Map[String, String]): Try[_] = Try {
+ def updateMetadata(key: String, metadata: java.util.Map[String, String]): Try[?] = Try {
val cor =
CopyObjectRequest
.builder()
diff --git a/common/src/main/scala/no/ndla/common/brightcove/NdlaBrightcoveClient.scala b/common/src/main/scala/no/ndla/common/brightcove/NdlaBrightcoveClient.scala
index 1888382a2b..5ff84afcdd 100644
--- a/common/src/main/scala/no/ndla/common/brightcove/NdlaBrightcoveClient.scala
+++ b/common/src/main/scala/no/ndla/common/brightcove/NdlaBrightcoveClient.scala
@@ -8,8 +8,8 @@
package no.ndla.common.brightcove
-import io.circe.Json
-import io.circe.generic.codec.DerivedAsObjectCodec.deriveCodec
+import io.circe.generic.semiauto.deriveDecoder
+import io.circe.{Decoder, Json}
import io.circe.parser.*
import sttp.client3.{HttpClientSyncBackend, UriContext, basicRequest}
import no.ndla.common.configuration.HasBaseProps
@@ -24,9 +24,13 @@ import scala.util.{Failure, Success, Try}
case class TokenResponse(access_token: String, token_type: String, expires_in: Int)
+object TokenResponse {
+ implicit def decoder: Decoder[TokenResponse] = deriveDecoder[TokenResponse]
+}
+
trait NdlaBrightcoveClient {
this: HasBaseProps =>
- val brightcoveClient: NdlaBrightcoveClient
+ lazy val brightcoveClient: NdlaBrightcoveClient
class NdlaBrightcoveClient {
private val backend = HttpClientSyncBackend()
diff --git a/common/src/main/scala/no/ndla/common/configuration/BaseComponentRegistry.scala b/common/src/main/scala/no/ndla/common/configuration/BaseComponentRegistry.scala
index 36cbf29ea7..96086500b6 100644
--- a/common/src/main/scala/no/ndla/common/configuration/BaseComponentRegistry.scala
+++ b/common/src/main/scala/no/ndla/common/configuration/BaseComponentRegistry.scala
@@ -11,6 +11,6 @@ package no.ndla.common.configuration
import no.ndla.common.Warmup
trait BaseComponentRegistry[PropType <: BaseProps] {
- val props: PropType
- val healthController: Warmup
+ lazy val props: PropType
+ lazy val healthController: Warmup
}
diff --git a/common/src/main/scala/no/ndla/common/configuration/BaseProps.scala b/common/src/main/scala/no/ndla/common/configuration/BaseProps.scala
index 70d8acf971..78f02d2639 100644
--- a/common/src/main/scala/no/ndla/common/configuration/BaseProps.scala
+++ b/common/src/main/scala/no/ndla/common/configuration/BaseProps.scala
@@ -50,8 +50,9 @@ trait BaseProps extends StrictLogging {
val prop = Prop.successful[T](key, value)
loadedProps.get(key) match {
case Some(existing: Prop[T] @unchecked) => existing.setValue(value)
- case Some(_) => throw new RuntimeException(s"Bad type when updating prop $key")
- case None => loadedProps.put(key, prop): Unit
+ case Some(_) =>
+ throw new RuntimeException("Prop with key " + key + " exists with a different type, this is a super weird bug.")
+ case None => loadedProps.put(key, prop): Unit
}
prop
}
diff --git a/common/src/main/scala/no/ndla/common/configuration/HasBaseProps.scala b/common/src/main/scala/no/ndla/common/configuration/HasBaseProps.scala
index 3bb0e8fb5b..4a2b6ad9ed 100644
--- a/common/src/main/scala/no/ndla/common/configuration/HasBaseProps.scala
+++ b/common/src/main/scala/no/ndla/common/configuration/HasBaseProps.scala
@@ -8,4 +8,4 @@
package no.ndla.common.configuration
-trait HasBaseProps { val props: BaseProps }
+trait HasBaseProps { lazy val props: BaseProps }
diff --git a/common/src/main/scala/no/ndla/common/model/api/AuthorDTO.scala b/common/src/main/scala/no/ndla/common/model/api/AuthorDTO.scala
index eb994141e6..fe5ca4ae2f 100644
--- a/common/src/main/scala/no/ndla/common/model/api/AuthorDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/AuthorDTO.scala
@@ -12,6 +12,7 @@ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import no.ndla.common.model.domain
import no.ndla.common.model.domain.ContributorType
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Information about an author")
@@ -30,4 +31,5 @@ case class AuthorDTO(
object AuthorDTO {
implicit def encoder: Encoder[AuthorDTO] = deriveEncoder[AuthorDTO]
implicit def decoder: Decoder[AuthorDTO] = deriveDecoder[AuthorDTO]
+ implicit def schema: Schema[AuthorDTO] = Schema.derived[AuthorDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/CommentDTO.scala b/common/src/main/scala/no/ndla/common/model/api/CommentDTO.scala
index efb8fd117c..509ed49e76 100644
--- a/common/src/main/scala/no/ndla/common/model/api/CommentDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/CommentDTO.scala
@@ -24,6 +24,7 @@ case class CommentDTO(
)
object CommentDTO {
- implicit def encoder: Encoder[CommentDTO] = deriveEncoder
- implicit def decoder: Decoder[CommentDTO] = deriveDecoder
+ implicit def encoder: Encoder[CommentDTO] = deriveEncoder
+ implicit def decoder: Decoder[CommentDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[CommentDTO] = sttp.tapir.Schema.derived[CommentDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/DisclaimerDTO.scala b/common/src/main/scala/no/ndla/common/model/api/DisclaimerDTO.scala
index 60ef2514a0..d1b1337026 100644
--- a/common/src/main/scala/no/ndla/common/model/api/DisclaimerDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/DisclaimerDTO.scala
@@ -21,6 +21,7 @@ case class DisclaimerDTO(
object DisclaimerDTO {
def fromLanguageValue(lv: WithLanguageAndValue[String]): DisclaimerDTO = DisclaimerDTO(lv.value, lv.language)
- implicit def encoder: Encoder[DisclaimerDTO] = deriveEncoder
- implicit def decoder: Decoder[DisclaimerDTO] = deriveDecoder
+ implicit def encoder: Encoder[DisclaimerDTO] = deriveEncoder
+ implicit def decoder: Decoder[DisclaimerDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[DisclaimerDTO] = sttp.tapir.Schema.derived[DisclaimerDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/DraftCopyrightDTO.scala b/common/src/main/scala/no/ndla/common/model/api/DraftCopyrightDTO.scala
index 5b745ad4f7..75f6ebbf3b 100644
--- a/common/src/main/scala/no/ndla/common/model/api/DraftCopyrightDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/DraftCopyrightDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.common.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import no.ndla.common.model.NDLADate
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Description of copyright information")
@@ -28,4 +29,5 @@ case class DraftCopyrightDTO(
object DraftCopyrightDTO {
implicit def encoder: Encoder[DraftCopyrightDTO] = deriveEncoder[DraftCopyrightDTO]
implicit def decoder: Decoder[DraftCopyrightDTO] = deriveDecoder[DraftCopyrightDTO]
+ implicit def schema: Schema[DraftCopyrightDTO] = Schema.derived[DraftCopyrightDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/FrontPageDTO.scala b/common/src/main/scala/no/ndla/common/model/api/FrontPageDTO.scala
index 0299693143..f8497f7bc6 100644
--- a/common/src/main/scala/no/ndla/common/model/api/FrontPageDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/FrontPageDTO.scala
@@ -13,6 +13,10 @@ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.syntax.EncoderOps
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
+import sttp.tapir.SchemaType.SProduct
+import sttp.tapir.FieldName
+import sttp.tapir.SchemaType
@description("The Menu object")
case class MenuDTO(
@@ -38,6 +42,13 @@ object MenuDTO {
implicit val encodeMenuData: Encoder[MenuDataDTO] = Encoder.instance { case menu: MenuDTO => menu.asJson }
implicit val decodeMenuData: Decoder[MenuDataDTO] = Decoder[MenuDTO].widen
+
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[MenuDTO] = Schema.derivedSchema
}
sealed trait MenuDataDTO {}
+
+object MenuDataDTO {
+ implicit def schema: Schema[MenuDataDTO] = MenuDTO.schema.as
+}
diff --git a/common/src/main/scala/no/ndla/common/model/api/LicenseDTO.scala b/common/src/main/scala/no/ndla/common/model/api/LicenseDTO.scala
index d265e4df78..90f76fc78e 100644
--- a/common/src/main/scala/no/ndla/common/model/api/LicenseDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/LicenseDTO.scala
@@ -20,6 +20,7 @@ case class LicenseDTO(
)
object LicenseDTO {
- implicit def encoder: Encoder[LicenseDTO] = deriveEncoder[LicenseDTO]
- implicit def decoder: Decoder[LicenseDTO] = deriveDecoder[LicenseDTO]
+ implicit def encoder: Encoder[LicenseDTO] = deriveEncoder[LicenseDTO]
+ implicit def decoder: Decoder[LicenseDTO] = deriveDecoder[LicenseDTO]
+ implicit def schema: sttp.tapir.Schema[LicenseDTO] = sttp.tapir.Schema.derived
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/NewCommentDTO.scala b/common/src/main/scala/no/ndla/common/model/api/NewCommentDTO.scala
index c3ed27898d..3d50e2afca 100644
--- a/common/src/main/scala/no/ndla/common/model/api/NewCommentDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/NewCommentDTO.scala
@@ -10,6 +10,7 @@ package no.ndla.common.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Information about a comment attached to an article")
@@ -21,4 +22,5 @@ case class NewCommentDTO(
object NewCommentDTO {
implicit def encoder: Encoder[NewCommentDTO] = deriveEncoder
implicit def decoder: Decoder[NewCommentDTO] = deriveDecoder
+ implicit def schema: Schema[NewCommentDTO] = Schema.derived
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/RelatedContentLinkDTO.scala b/common/src/main/scala/no/ndla/common/model/api/RelatedContentLinkDTO.scala
index cb3b2d3bd2..a76e465a6a 100644
--- a/common/src/main/scala/no/ndla/common/model/api/RelatedContentLinkDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/RelatedContentLinkDTO.scala
@@ -10,6 +10,7 @@ package no.ndla.common.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("External link related to the article")
@@ -21,4 +22,5 @@ case class RelatedContentLinkDTO(
object RelatedContentLinkDTO {
implicit def encoder: Encoder[RelatedContentLinkDTO] = deriveEncoder
implicit def decoder: Decoder[RelatedContentLinkDTO] = deriveDecoder
+ implicit def schema: Schema[RelatedContentLinkDTO] = Schema.derived
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/ResponsibleDTO.scala b/common/src/main/scala/no/ndla/common/model/api/ResponsibleDTO.scala
index 03a84af8d1..d41d59f9ad 100644
--- a/common/src/main/scala/no/ndla/common/model/api/ResponsibleDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/ResponsibleDTO.scala
@@ -20,6 +20,7 @@ case class ResponsibleDTO(
)
object ResponsibleDTO {
- implicit def encoder: Encoder[ResponsibleDTO] = deriveEncoder
- implicit def decoder: Decoder[ResponsibleDTO] = deriveDecoder
+ implicit def encoder: Encoder[ResponsibleDTO] = deriveEncoder
+ implicit def decoder: Decoder[ResponsibleDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[ResponsibleDTO] = sttp.tapir.Schema.derived[ResponsibleDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/RevisionMetaDTO.scala b/common/src/main/scala/no/ndla/common/model/api/RevisionMetaDTO.scala
index f3347f8763..0efe6a57bd 100644
--- a/common/src/main/scala/no/ndla/common/model/api/RevisionMetaDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/RevisionMetaDTO.scala
@@ -12,6 +12,7 @@ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
import no.ndla.common.model.NDLADate
+import sttp.tapir.Schema
@description("Information about the editorial notes")
case class RevisionMetaDTO(
@@ -24,4 +25,5 @@ case class RevisionMetaDTO(
object RevisionMetaDTO {
implicit def encoder: Encoder[RevisionMetaDTO] = deriveEncoder[RevisionMetaDTO]
implicit def decoder: Decoder[RevisionMetaDTO] = deriveDecoder[RevisionMetaDTO]
+ implicit def schema: Schema[RevisionMetaDTO] = Schema.derived[RevisionMetaDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/UpdateOrDelete.scala b/common/src/main/scala/no/ndla/common/model/api/UpdateOrDelete.scala
index fc51a017b4..93d954ef15 100644
--- a/common/src/main/scala/no/ndla/common/model/api/UpdateOrDelete.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/UpdateOrDelete.scala
@@ -42,8 +42,8 @@ object UpdateOrDelete {
}
}
- private[this] val marker: String = s"$$marker-${UUID.randomUUID()}-marker$$"
- private[this] val markerJson: Json = Json.fromString(marker)
+ private val marker: String = s"$$marker-${UUID.randomUUID()}-marker$$"
+ private val markerJson: Json = Json.fromString(marker)
implicit def encodeUpdateOrDelete[A](implicit encodeA: Encoder[A]): Encoder[UpdateOrDelete[A]] = Encoder.instance {
case UpdateWith(a) => encodeA(a)
diff --git a/common/src/main/scala/no/ndla/common/model/api/UpdatedCommentDTO.scala b/common/src/main/scala/no/ndla/common/model/api/UpdatedCommentDTO.scala
index 40a3ccc7e8..179802457e 100644
--- a/common/src/main/scala/no/ndla/common/model/api/UpdatedCommentDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/UpdatedCommentDTO.scala
@@ -10,6 +10,7 @@ package no.ndla.common.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Information about a comment attached to an article")
@@ -23,4 +24,5 @@ case class UpdatedCommentDTO(
object UpdatedCommentDTO {
implicit def encoder: Encoder[UpdatedCommentDTO] = deriveEncoder
implicit def decoder: Decoder[UpdatedCommentDTO] = deriveDecoder
+ implicit def schema: Schema[UpdatedCommentDTO] = Schema.derived[UpdatedCommentDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/api/frontpage/SubjectPageDTO.scala b/common/src/main/scala/no/ndla/common/model/api/frontpage/SubjectPageDTO.scala
index 9e4720293e..e384aa22ff 100644
--- a/common/src/main/scala/no/ndla/common/model/api/frontpage/SubjectPageDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/api/frontpage/SubjectPageDTO.scala
@@ -10,6 +10,7 @@ package no.ndla.common.model.api.frontpage
import io.circe.*
import io.circe.generic.semiauto.*
+import sttp.tapir.Schema
case class SubjectPageDTO(
id: Long,
@@ -27,4 +28,6 @@ case class SubjectPageDTO(
object SubjectPageDTO {
implicit def encoder: Encoder[SubjectPageDTO] = deriveEncoder[SubjectPageDTO]
implicit def decoder: Decoder[SubjectPageDTO] = deriveDecoder[SubjectPageDTO]
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[SubjectPageDTO] = Schema.derivedSchema
}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/ArticleType.scala b/common/src/main/scala/no/ndla/common/model/domain/ArticleType.scala
index 69b5ca5a62..255bbc6db9 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/ArticleType.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/ArticleType.scala
@@ -9,6 +9,9 @@
package no.ndla.common.model.domain
import enumeratum.*
+import sttp.tapir.Codec.PlainCodec
+import sttp.tapir.Schema
+import sttp.tapir.codec.enumeratum.*
import no.ndla.common.errors.ValidationException
sealed abstract class ArticleType(override val entryName: String) extends EnumEntry
@@ -18,6 +21,9 @@ object ArticleType extends Enum[ArticleType] with CirceEnum[ArticleType] {
case object TopicArticle extends ArticleType("topic-article")
case object FrontpageArticle extends ArticleType("frontpage-article")
+ implicit def schema: Schema[ArticleType] = schemaForEnumEntry[ArticleType]
+ implicit def codec: PlainCodec[ArticleType] = plainCodecEnumEntry[ArticleType]
+
val values: IndexedSeq[ArticleType] = findValues
def all: Seq[String] = ArticleType.values.map(_.entryName)
diff --git a/common/src/main/scala/no/ndla/common/model/domain/Priority.scala b/common/src/main/scala/no/ndla/common/model/domain/Priority.scala
index 83e4996557..0718da88e9 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/Priority.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/Priority.scala
@@ -38,6 +38,6 @@ object Priority extends Enum[Priority] with CirceEnum[Priority] {
)
}
- implicit val schema: Schema[Priority] = schemaForEnumEntry[Priority]
- implicit val codec: PlainCodec[Priority] = plainCodecEnumEntry[Priority]
+ implicit def schema: Schema[Priority] = schemaForEnumEntry[Priority]
+ implicit def codec: PlainCodec[Priority] = plainCodecEnumEntry[Priority]
}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticleDTO.scala b/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticleDTO.scala
index 01de2ce6fe..0309be2b7c 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticleDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticleDTO.scala
@@ -36,4 +36,6 @@ object PartialPublishArticleDTO {
implicit def eitherDec: Decoder[Either[RelatedContentLinkDTO, Long]] = eitherDecoder[RelatedContentLinkDTO, Long]
implicit val encoder: Encoder.AsObject[PartialPublishArticleDTO] = UpdateOrDelete.filterMarkers(deriveEncoder[PartialPublishArticleDTO])
implicit val decoder: Decoder[PartialPublishArticleDTO] = deriveDecoder[PartialPublishArticleDTO]
+ import sttp.tapir.generic.auto.*
+ implicit def schema: sttp.tapir.Schema[PartialPublishArticleDTO] = sttp.tapir.Schema.derivedSchema
}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticlesBulkDTO.scala b/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticlesBulkDTO.scala
index 01bad821c9..b18a16a130 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticlesBulkDTO.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/article/PartialPublishArticlesBulkDTO.scala
@@ -22,6 +22,5 @@ case class PartialPublishArticlesBulkDTO(
object PartialPublishArticlesBulkDTO {
implicit val encoder: Encoder[PartialPublishArticlesBulkDTO] = deriveEncoder
implicit val decoder: Decoder[PartialPublishArticlesBulkDTO] = deriveDecoder
-
- implicit val schema: Schema[PartialPublishArticlesBulkDTO] = Schema.any[PartialPublishArticlesBulkDTO]
+ implicit def schema: Schema[PartialPublishArticlesBulkDTO] = Schema.any[PartialPublishArticlesBulkDTO]
}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/concept/Concept.scala b/common/src/main/scala/no/ndla/common/model/domain/concept/Concept.scala
index fe37a1af4e..6847358cbb 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/concept/Concept.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/concept/Concept.scala
@@ -14,6 +14,7 @@ import no.ndla.common.model.NDLADate
import no.ndla.common.model.domain.draft.DraftCopyright
import no.ndla.common.model.domain.{Content, Responsible, Tag, Title}
import no.ndla.language.Language.getSupportedLanguages
+import sttp.tapir.Schema
case class Concept(
id: Option[Long],
@@ -39,4 +40,6 @@ case class Concept(
object Concept {
implicit val encoder: Encoder[Concept] = deriveEncoder
implicit val decoder: Decoder[Concept] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[Concept] = Schema.derivedSchema
}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/draft/Draft.scala b/common/src/main/scala/no/ndla/common/model/domain/draft/Draft.scala
index 8e124fb18c..6ce33360d8 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/draft/Draft.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/draft/Draft.scala
@@ -69,4 +69,6 @@ object Draft {
implicit def eitherDec: Decoder[Either[RelatedContentLink, Long]] = eitherDecoder[RelatedContentLink, Long]
implicit val encoder: Encoder[Draft] = deriveEncoder
implicit val decoder: Decoder[Draft] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: sttp.tapir.Schema[Draft] = sttp.tapir.Schema.derivedSchema
}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/frontpage/MovieTheme.scala b/common/src/main/scala/no/ndla/common/model/domain/frontpage/MovieTheme.scala
index d7e2103e9e..5551837fbf 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/frontpage/MovieTheme.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/frontpage/MovieTheme.scala
@@ -9,9 +9,19 @@
package no.ndla.common.model.domain.frontpage
import no.ndla.language.model.LanguageField
+import io.circe.{Encoder, Decoder}
+import io.circe.generic.semiauto.{deriveEncoder, deriveDecoder}
case class MovieTheme(name: Seq[MovieThemeName], movies: Seq[String])
+object MovieTheme {
+ implicit val encoder: Encoder[MovieTheme] = deriveEncoder
+ implicit val decoder: Decoder[MovieTheme] = deriveDecoder
+}
case class MovieThemeName(name: String, language: String) extends LanguageField[String] {
override def value: String = name
override def isEmpty: Boolean = name.isEmpty
}
+object MovieThemeName {
+ implicit val encoder: Encoder[MovieThemeName] = deriveEncoder
+ implicit val decoder: Decoder[MovieThemeName] = deriveDecoder
+}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPath.scala b/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPath.scala
index fda691ce70..e611f07ea1 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPath.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPath.scala
@@ -14,6 +14,7 @@ import no.ndla.common.model.NDLADate
import no.ndla.common.model.domain.{Comment, Content, Responsible, Tag, Title}
import no.ndla.language.Language.getSupportedLanguages
import no.ndla.common.model.domain.Priority
+import sttp.tapir.Schema
case class LearningPath(
id: Option[Long],
@@ -64,4 +65,7 @@ object LearningPath {
if (learningsteps.succeeded) learningsteps.delete
else obj
}
+
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[LearningPath] = Schema.derivedSchema
}
diff --git a/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPathStatus.scala b/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPathStatus.scala
index 6ccbedb6f7..c6a49902dd 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPathStatus.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/learningpath/LearningPathStatus.scala
@@ -10,6 +10,9 @@ package no.ndla.common.model.domain.learningpath
import enumeratum.*
import no.ndla.common.errors.{ValidationException, ValidationMessage}
+import sttp.tapir.Codec.PlainCodec
+import sttp.tapir.Schema
+import sttp.tapir.codec.enumeratum.*
import scala.util.{Failure, Success, Try}
@@ -23,6 +26,9 @@ object LearningPathStatus extends Enum[LearningPathStatus] with CirceEnum[
case object SUBMITTED extends LearningPathStatus
case object READY_FOR_SHARING extends LearningPathStatus
+ implicit val schema: Schema[LearningPathStatus] = schemaForEnumEntry[LearningPathStatus]
+ implicit val codec: PlainCodec[LearningPathStatus] = plainCodecEnumEntry[LearningPathStatus]
+
override def values: IndexedSeq[LearningPathStatus] = findValues
def valueOf(s: String): Option[LearningPathStatus] = {
diff --git a/common/src/main/scala/no/ndla/common/model/domain/myndla/UserRole.scala b/common/src/main/scala/no/ndla/common/model/domain/myndla/UserRole.scala
index 23798f60a5..29a1f51efe 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/myndla/UserRole.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/myndla/UserRole.scala
@@ -9,7 +9,6 @@
package no.ndla.common.model.domain.myndla
import enumeratum.*
-import enumeratum.{CirceEnum, EnumEntry}
import sttp.tapir.Schema
import sttp.tapir.codec.enumeratum.*
diff --git a/common/src/main/scala/no/ndla/common/model/domain/myndla/auth/AuthUtility.scala b/common/src/main/scala/no/ndla/common/model/domain/myndla/auth/AuthUtility.scala
index 6ee942cd17..a658489e19 100644
--- a/common/src/main/scala/no/ndla/common/model/domain/myndla/auth/AuthUtility.scala
+++ b/common/src/main/scala/no/ndla/common/model/domain/myndla/auth/AuthUtility.scala
@@ -35,7 +35,7 @@ object AuthUtility {
.requiredScopes(Seq.empty)
EndpointInput.Auth(
- input = sttp.tapir.header("FeideAuthorization")(feideTokenAuthCodec),
+ input = sttp.tapir.header("FeideAuthorization")(using feideTokenAuthCodec),
challenge = WWWAuthenticateChallenge.bearer,
authType = authType,
info = AuthInfo.Empty.securitySchemeName("oauth2")
diff --git a/common/src/test/scala/no/ndla/common/ContentURIUtilTest.scala b/common/src/test/scala/no/ndla/common/ContentURIUtilTest.scala
index 24acf9bfeb..32af0773fb 100644
--- a/common/src/test/scala/no/ndla/common/ContentURIUtilTest.scala
+++ b/common/src/test/scala/no/ndla/common/ContentURIUtilTest.scala
@@ -21,10 +21,12 @@ class ContentURIUtilTest extends UnitTestSuiteBase {
ContentURIUtil.parseArticleIdAndRevision("15") should be((Success(15), None))
ContentURIUtil.parseArticleIdAndRevision("15#100") should be((Success(15), Some(100)))
- val (failed, Some(100)) = ContentURIUtil.parseArticleIdAndRevision("#100")
- failed.isFailure should be(true)
- val (failed2, None) = ContentURIUtil.parseArticleIdAndRevision("")
+ val (id1, rev1) = ContentURIUtil.parseArticleIdAndRevision("#100")
+ id1.isFailure should be(true)
+ rev1 should be(Some(100))
+ val (failed2, rev2) = ContentURIUtil.parseArticleIdAndRevision("")
failed2.isFailure should be(true)
+ rev2 should be(None)
}
test("That non-matching idString will fail and not throw exception") {
diff --git a/common/src/test/scala/no/ndla/common/converter/CommonConverterTest.scala b/common/src/test/scala/no/ndla/common/converter/CommonConverterTest.scala
index 989b9b9954..093873c62f 100644
--- a/common/src/test/scala/no/ndla/common/converter/CommonConverterTest.scala
+++ b/common/src/test/scala/no/ndla/common/converter/CommonConverterTest.scala
@@ -18,8 +18,8 @@ import org.mockito.Mockito.when
import java.util.UUID
class CommonConverterTest extends UnitTestSuiteBase with CommonConverter with Clock with UUIDUtil {
- val clock: SystemClock = mock[SystemClock]
- lazy val uuidUtil: UUIDUtil = mock[UUIDUtil]
+ override lazy val clock: SystemClock = mock[SystemClock]
+ override lazy val uuidUtil: UUIDUtil = mock[UUIDUtil]
test("that mergeUpdatedCommentsWithExisting creates and updates comments correctly") {
val uuid = UUID.randomUUID()
val now = NDLADate.now()
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/ComponentRegistry.scala b/concept-api/src/main/scala/no/ndla/conceptapi/ComponentRegistry.scala
index e79d4ff5c1..6cfc99ab73 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/ComponentRegistry.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/ComponentRegistry.scala
@@ -61,34 +61,34 @@ class ComponentRegistry(properties: ConceptApiProperties)
with DraftSearchSettingsHelper
with SwaggerDocControllerConfig
with ConceptControllerHelpers {
- override val props: ConceptApiProperties = properties
- override val migrator: DBMigrator = DBMigrator(
+ override lazy val props: ConceptApiProperties = properties
+ override lazy val migrator: DBMigrator = DBMigrator(
new V23__SubjectNameAsTags(props),
new V25__SubjectNameAsTagsPublished(props)
)
override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
- lazy val draftConceptRepository = new DraftConceptRepository
- lazy val publishedConceptRepository = new PublishedConceptRepository
+ override lazy val draftConceptRepository = new DraftConceptRepository
+ override lazy val publishedConceptRepository = new PublishedConceptRepository
- lazy val draftConceptSearchService = new DraftConceptSearchService
- lazy val searchConverterService = new SearchConverterService
- lazy val draftConceptIndexService = new DraftConceptIndexService
- lazy val publishedConceptIndexService = new PublishedConceptIndexService
- lazy val publishedConceptSearchService = new PublishedConceptSearchService
+ override lazy val draftConceptSearchService = new DraftConceptSearchService
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val draftConceptIndexService = new DraftConceptIndexService
+ override lazy val publishedConceptIndexService = new PublishedConceptIndexService
+ override lazy val publishedConceptSearchService = new PublishedConceptSearchService
var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
- lazy val ndlaClient = new NdlaClient
- lazy val searchApiClient = new SearchApiClient
- lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val searchApiClient = new SearchApiClient
+ override lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
- lazy val writeService = new WriteService
- lazy val readService = new ReadService
- lazy val converterService = new ConverterService
- lazy val clock = new SystemClock
- lazy val contentValidator = new ContentValidator
+ override lazy val writeService = new WriteService
+ override lazy val readService = new ReadService
+ override lazy val converterService = new ConverterService
+ override lazy val clock = new SystemClock
+ override lazy val contentValidator = new ContentValidator
lazy val draftConceptController = new DraftConceptController
lazy val publishedConceptController = new PublishedConceptController
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/ConceptApiProperties.scala b/concept-api/src/main/scala/no/ndla/conceptapi/ConceptApiProperties.scala
index 1c538d864f..18e13d641b 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/ConceptApiProperties.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/ConceptApiProperties.scala
@@ -17,7 +17,7 @@ import no.ndla.validation.ResourceType
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: ConceptApiProperties
+ lazy val props: ConceptApiProperties
}
class ConceptApiProperties extends BaseProps with DatabaseProps with StrictLogging {
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/controller/ConceptControllerHelpers.scala b/concept-api/src/main/scala/no/ndla/conceptapi/controller/ConceptControllerHelpers.scala
index 14163a4564..097f2e5303 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/controller/ConceptControllerHelpers.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/controller/ConceptControllerHelpers.scala
@@ -19,8 +19,6 @@ import sttp.tapir.model.Delimited
trait ConceptControllerHelpers {
this: Props =>
- import props.*
-
object ConceptControllerHelpers {
val pathConceptId: EndpointInput.PathCapture[Long] =
@@ -76,7 +74,7 @@ trait ConceptControllerHelpers {
val scrollId: EndpointInput.Query[Option[String]] =
query[Option[String]]("search-context")
.description(
- s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${InitialScrollContextKeywords
+ s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${props.InitialScrollContextKeywords
.mkString("[", ",", "]")}.
|When scrolling, the parameters from the initial search is used, except in the case of '${this.language.name}' and '${this.fallback.name}'.
|This value may change between scrolls. Always use the one in the latest scroll result.
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/controller/DraftConceptController.scala b/concept-api/src/main/scala/no/ndla/conceptapi/controller/DraftConceptController.scala
index c4fc6c06a9..ebcdebbe37 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/controller/DraftConceptController.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/controller/DraftConceptController.scala
@@ -35,11 +35,9 @@ import scala.util.{Failure, Success, Try}
trait DraftConceptController {
this: WriteService & ReadService & DraftConceptSearchService & SearchConverterService & ConverterService & Props &
ConceptControllerHelpers & ErrorHandling & TapirController =>
- val draftConceptController: DraftConceptController
+ lazy val draftConceptController: DraftConceptController
class DraftConceptController extends TapirController {
- import props.*
-
override val serviceName: String = "drafts"
override val prefix: EndpointInput[Unit] = "concept-api" / "v1" / serviceName
@@ -68,7 +66,7 @@ trait DraftConceptController {
orFunction: => Try[(ConceptSearchResultDTO, DynamicHeaders)]
): Try[(ConceptSearchResultDTO, DynamicHeaders)] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
draftConceptSearchService.scroll(scroll, language.code) match {
case Success(scrollResult) =>
val body = searchConverterService.asApiConceptSearchResult(scrollResult)
@@ -191,7 +189,7 @@ trait DraftConceptController {
) =>
scrollSearchOr(scrollId, language) {
val sort = Sort.valueOf(sortStr)
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query,
@@ -240,20 +238,20 @@ trait DraftConceptController {
.errorOut(errorOutputsFor(400, 403, 404))
.serverLogicPure { searchParams =>
val scrollId = searchParams.scrollId
- val lang = searchParams.language.getOrElse(LanguageCode(DefaultLanguage))
+ val lang = searchParams.language.getOrElse(LanguageCode(props.DefaultLanguage))
scrollSearchOr(scrollId, lang) {
val query = searchParams.query
val sort = searchParams.sort
val language = searchParams.language.getOrElse(LanguageCode(AllLanguages))
- val pageSize = searchParams.pageSize.getOrElse(DefaultPageSize)
+ val pageSize = searchParams.pageSize.getOrElse(props.DefaultPageSize)
val page = searchParams.page.getOrElse(1)
val idList = searchParams.ids
val fallback = searchParams.fallback.getOrElse(false)
val tagsToFilterBy = searchParams.tags
val statusFilter = searchParams.status
val userFilter = searchParams.users
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
val embedResource = searchParams.embedResource.getOrElse(List.empty)
val embedId = searchParams.embedId
val responsibleId = searchParams.responsibleIds
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/controller/InternController.scala b/concept-api/src/main/scala/no/ndla/conceptapi/controller/InternController.scala
index 3aa391b5c1..6976774abf 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/controller/InternController.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/controller/InternController.scala
@@ -26,12 +26,11 @@ import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutorServic
import scala.language.postfixOps
import scala.util.{Failure, Success, Try}
import sttp.tapir.*
-import sttp.tapir.generic.auto.*
trait InternController {
this: IndexService & DraftConceptIndexService & PublishedConceptIndexService & ConverterService & ReadService &
DraftConceptRepository & PublishedConceptRepository & ErrorHandling & TapirController =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController {
override val prefix: EndpointInput[Unit] = "intern"
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/controller/PublishedConceptController.scala b/concept-api/src/main/scala/no/ndla/conceptapi/controller/PublishedConceptController.scala
index 02059b9dbb..9ec166a986 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/controller/PublishedConceptController.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/controller/PublishedConceptController.scala
@@ -32,11 +32,10 @@ import scala.util.{Failure, Success, Try}
trait PublishedConceptController {
this: WriteService & ReadService & PublishedConceptSearchService & SearchConverterService & Props &
ConceptControllerHelpers & ErrorHandling & TapirController =>
- val publishedConceptController: PublishedConceptController
+ lazy val publishedConceptController: PublishedConceptController
class PublishedConceptController extends TapirController {
import ConceptControllerHelpers.*
- import props.*
override val serviceName: String = "concepts"
override val prefix: EndpointInput[Unit] = "concept-api" / "v1" / serviceName
@@ -52,7 +51,7 @@ trait PublishedConceptController {
orFunction: => Try[(ConceptSearchResultDTO, DynamicHeaders)]
): Try[(ConceptSearchResultDTO, DynamicHeaders)] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
publishedConceptSearchService.scroll(scroll, language.code) match {
case Success(scrollResult) =>
val body = searchConverterService.asApiConceptSearchResult(scrollResult)
@@ -165,7 +164,7 @@ trait PublishedConceptController {
) =>
scrollSearchOr(scrollId, language) {
val sort = Sort.valueOf(sortStr)
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query,
@@ -195,18 +194,18 @@ trait PublishedConceptController {
.out(EndpointOutput.derived[DynamicHeaders])
.errorOut(errorOutputsFor(400, 403, 404))
.serverLogicPure { searchParams =>
- val lang = searchParams.language.getOrElse(LanguageCode(DefaultLanguage))
+ val lang = searchParams.language.getOrElse(LanguageCode(props.DefaultLanguage))
scrollSearchOr(searchParams.scrollId, lang) {
val query = searchParams.query
val sort = searchParams.sort
val language = searchParams.language.getOrElse(LanguageCode(Language.AllLanguages))
- val pageSize = searchParams.pageSize.getOrElse(DefaultPageSize)
+ val pageSize = searchParams.pageSize.getOrElse(props.DefaultPageSize)
val page = searchParams.page.getOrElse(1)
val idList = searchParams.ids
val fallback = searchParams.fallback.getOrElse(false)
val tagsToFilterBy = searchParams.tags
val exactTitleMatch = searchParams.exactMatch.getOrElse(false)
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
val embedResource = searchParams.embedResource
val embedId = searchParams.embedId
val conceptType = searchParams.conceptType
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/model/api/ConceptDomainDump.scala b/concept-api/src/main/scala/no/ndla/conceptapi/model/api/ConceptDomainDump.scala
index df93728a0a..7edc6d8e00 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/model/api/ConceptDomainDump.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/model/api/ConceptDomainDump.scala
@@ -24,4 +24,6 @@ case class ConceptDomainDump(
object ConceptDomainDump {
implicit val encoder: Encoder[ConceptDomainDump] = deriveEncoder
implicit val decoder: Decoder[ConceptDomainDump] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: sttp.tapir.Schema[ConceptDomainDump] = sttp.tapir.Schema.derivedSchema
}
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/model/api/TagsSearchResultDTO.scala b/concept-api/src/main/scala/no/ndla/conceptapi/model/api/TagsSearchResultDTO.scala
index 31f3dcd908..f3c84bdb04 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/model/api/TagsSearchResultDTO.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/model/api/TagsSearchResultDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.conceptapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
@description("Information about tags-search-results")
case class TagsSearchResultDTO(
@@ -24,4 +25,5 @@ case class TagsSearchResultDTO(
object TagsSearchResultDTO {
implicit val encoder: Encoder[TagsSearchResultDTO] = deriveEncoder
implicit val decoder: Decoder[TagsSearchResultDTO] = deriveDecoder
+ implicit def schema: Schema[TagsSearchResultDTO] = Schema.derived
}
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/repository/DraftConceptRepository.scala b/concept-api/src/main/scala/no/ndla/conceptapi/repository/DraftConceptRepository.scala
index 5957277cd1..c5f156cac2 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/repository/DraftConceptRepository.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/repository/DraftConceptRepository.scala
@@ -23,7 +23,7 @@ import scala.util.{Failure, Success, Try}
trait DraftConceptRepository {
this: DataSource & Props & ErrorHandling =>
- val draftConceptRepository: DraftConceptRepository
+ lazy val draftConceptRepository: DraftConceptRepository
class DraftConceptRepository extends StrictLogging with Repository[Concept] {
def insert(concept: Concept)(implicit session: DBSession = AutoSession): Concept = {
@@ -229,7 +229,7 @@ trait DraftConceptRepository {
s"${DBConcept.schemaName.getOrElse(props.MetaSchema)}.${DBConcept.tableName}_id_seq"
)
- sql"alter sequence $sequenceName restart with $idToStartAt;".executeUpdate(): Unit
+ val _ = sql"alter sequence $sequenceName restart with $idToStartAt;".executeUpdate()
}
def getTags(input: String, pageSize: Int, offset: Int, language: String)(implicit
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/repository/PublishedConceptRepository.scala b/concept-api/src/main/scala/no/ndla/conceptapi/repository/PublishedConceptRepository.scala
index 13fd3c9957..625c70db22 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/repository/PublishedConceptRepository.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/repository/PublishedConceptRepository.scala
@@ -22,7 +22,7 @@ import scala.util.{Failure, Success, Try}
trait PublishedConceptRepository {
this: DataSource =>
- val publishedConceptRepository: PublishedConceptRepository
+ lazy val publishedConceptRepository: PublishedConceptRepository
class PublishedConceptRepository extends StrictLogging with Repository[Concept] {
def insertOrUpdate(concept: Concept)(implicit session: DBSession = AutoSession): Try[Concept] = {
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/ConverterService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/ConverterService.scala
index 30733e54b6..083ad8eb4e 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/ConverterService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/ConverterService.scala
@@ -46,7 +46,7 @@ import scala.util.{Failure, Success, Try}
trait ConverterService {
this: Clock & DraftConceptRepository & StateTransitionRules & Props =>
- val converterService: ConverterService
+ lazy val converterService: ConverterService
class ConverterService extends StrictLogging {
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/ReadService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/ReadService.scala
index 18c9f4415e..2311ae192f 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/ReadService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/ReadService.scala
@@ -18,7 +18,7 @@ import scala.util.{Failure, Try}
trait ReadService {
this: DraftConceptRepository & PublishedConceptRepository & ConverterService =>
- val readService: ReadService
+ lazy val readService: ReadService
class ReadService {
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/WriteService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/WriteService.scala
index 13a94f6565..be7cac242c 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/WriteService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/WriteService.scala
@@ -31,7 +31,7 @@ import no.ndla.common.errors.OperationNotAllowedException
trait WriteService {
this: DraftConceptRepository & PublishedConceptRepository & ConverterService & ContentValidator &
DraftConceptIndexService & PublishedConceptIndexService & StrictLogging & SearchApiClient & Clock =>
- val writeService: WriteService
+ lazy val writeService: WriteService
class WriteService {
@@ -125,7 +125,7 @@ trait WriteService {
implicit val ec: ExecutionContextExecutorService = ExecutionContext.fromExecutorService(executor)
draftConceptIndexService.indexDocument(toIndex): Unit
- searchApiClient.indexDocument("concept", toIndex, Some(user)): Unit
+ val _ = searchApiClient.indexDocument("concept", toIndex, Some(user))
}
def updateConcept(id: Long, updatedConcept: api.UpdatedConceptDTO, user: TokenUser): Try[api.ConceptDTO] = {
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptIndexService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptIndexService.scala
index ea7ae3f255..5c5e3938db 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptIndexService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptIndexService.scala
@@ -8,16 +8,15 @@
package no.ndla.conceptapi.service.search
-import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.model.domain.concept.Concept
import no.ndla.conceptapi.Props
import no.ndla.conceptapi.repository.{DraftConceptRepository, Repository}
trait DraftConceptIndexService {
this: IndexService & DraftConceptRepository & SearchConverterService & Props =>
- val draftConceptIndexService: DraftConceptIndexService
+ lazy val draftConceptIndexService: DraftConceptIndexService
- class DraftConceptIndexService extends StrictLogging with IndexService {
+ class DraftConceptIndexService extends IndexService {
override val documentType: String = props.ConceptSearchDocument
override val searchIndex: String = props.DraftConceptSearchIndex
override val repository: Repository[Concept] = draftConceptRepository
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptSearchService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptSearchService.scala
index 4c606360cd..67df9ff345 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptSearchService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/DraftConceptSearchService.scala
@@ -29,11 +29,10 @@ import scala.util.{Failure, Success, Try}
trait DraftConceptSearchService {
this: Elastic4sClient & SearchService & DraftConceptIndexService & ConverterService & SearchConverterService & Props &
ErrorHandling & DraftSearchSettingsHelper =>
- val draftConceptSearchService: DraftConceptSearchService
+ lazy val draftConceptSearchService: DraftConceptSearchService
class DraftConceptSearchService extends StrictLogging with SearchService[api.ConceptSummaryDTO] {
- import props.*
- override val searchIndex: String = DraftConceptSearchIndex
+ override val searchIndex: String = props.DraftConceptSearchIndex
override def hitToApiModel(hitString: String, language: String): api.ConceptSummaryDTO =
searchConverterService.hitAsConceptSummary(hitString, language)
@@ -102,9 +101,9 @@ trait DraftConceptSearchService {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.pageSize * settings.page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new ResultWindowTooLargeException())
} else {
@@ -121,7 +120,7 @@ trait DraftConceptSearchService {
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/IndexService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/IndexService.scala
index dd34d98631..53c6f11ad1 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/IndexService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/IndexService.scala
@@ -26,7 +26,8 @@ import scala.util.{Failure, Success, Try}
trait IndexService {
this: Elastic4sClient & BaseIndexService & Props & SearchConverterService & SearchLanguage =>
- trait IndexService extends BaseIndexService with StrictLogging {
+
+ abstract class IndexService extends BaseIndexService with StrictLogging {
val repository: Repository[Concept]
override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptIndexService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptIndexService.scala
index ab8fb33c5e..c055f9e56d 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptIndexService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptIndexService.scala
@@ -8,16 +8,15 @@
package no.ndla.conceptapi.service.search
-import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.model.domain.concept.Concept
import no.ndla.conceptapi.Props
import no.ndla.conceptapi.repository.{PublishedConceptRepository, Repository}
trait PublishedConceptIndexService {
this: IndexService & PublishedConceptRepository & SearchConverterService & Props =>
- val publishedConceptIndexService: PublishedConceptIndexService
+ lazy val publishedConceptIndexService: PublishedConceptIndexService
- class PublishedConceptIndexService extends StrictLogging with IndexService {
+ class PublishedConceptIndexService extends IndexService {
override val documentType: String = props.ConceptSearchDocument
override val searchIndex: String = props.PublishedConceptSearchIndex
override val repository: Repository[Concept] = publishedConceptRepository
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchService.scala
index 0b9a91adf5..88f55d7f60 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchService.scala
@@ -29,11 +29,10 @@ import scala.util.{Failure, Success, Try}
trait PublishedConceptSearchService {
this: Elastic4sClient & SearchService & PublishedConceptIndexService & ConverterService & SearchConverterService &
Props & ErrorHandling & SearchSettingsHelper =>
- val publishedConceptSearchService: PublishedConceptSearchService
+ lazy val publishedConceptSearchService: PublishedConceptSearchService
class PublishedConceptSearchService extends StrictLogging with SearchService[api.ConceptSummaryDTO] {
- import props.*
- override val searchIndex: String = PublishedConceptSearchIndex
+ override val searchIndex: String = props.PublishedConceptSearchIndex
override def hitToApiModel(hitString: String, language: String): api.ConceptSummaryDTO =
searchConverterService.hitAsConceptSummary(hitString, language)
@@ -94,9 +93,9 @@ trait PublishedConceptSearchService {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.pageSize * settings.page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new ResultWindowTooLargeException())
} else {
@@ -113,7 +112,7 @@ trait PublishedConceptSearchService {
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchConverterService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchConverterService.scala
index 5dad8dc9d3..c85b76a6ac 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchConverterService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchConverterService.scala
@@ -31,7 +31,7 @@ import org.jsoup.Jsoup
trait SearchConverterService {
this: ConverterService =>
- val searchConverterService: SearchConverterService
+ lazy val searchConverterService: SearchConverterService
class SearchConverterService extends StrictLogging {
private def getEmbedResourcesAndIdsToIndex(
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchService.scala b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchService.scala
index c3bc5c7c9a..6c3d640152 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchService.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/service/search/SearchService.scala
@@ -31,14 +31,12 @@ trait SearchService {
this: Elastic4sClient & SearchConverterService & StrictLogging & Props =>
trait SearchService[T] {
- import props.*
-
val searchIndex: String
def scroll(scrollId: String, language: String): Try[SearchResult[T]] =
e4sClient
.execute {
- searchScroll(scrollId, ElasticSearchScrollKeepAlive)
+ searchScroll(scrollId, props.ElasticSearchScrollKeepAlive)
}
.map(response => {
val hits = getHits(response.result, language)
@@ -129,7 +127,7 @@ trait SearchService {
def getSortDefinition(sort: Sort, language: String): FieldSort = {
val sortLanguage = language match {
- case NoLanguage => DefaultLanguage
+ case NoLanguage => props.DefaultLanguage
case _ => language
}
@@ -193,7 +191,7 @@ trait SearchService {
}
def getStartAtAndNumResults(page: Int, pageSize: Int): (Int, Int) = {
- val numResults = max(pageSize.min(MaxPageSize), 0)
+ val numResults = max(pageSize.min(props.MaxPageSize), 0)
val startAt = (page - 1).max(0) * numResults
(startAt, numResults)
diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/validation/ContentValidator.scala b/concept-api/src/main/scala/no/ndla/conceptapi/validation/ContentValidator.scala
index e1d028e4d0..30a204d559 100644
--- a/concept-api/src/main/scala/no/ndla/conceptapi/validation/ContentValidator.scala
+++ b/concept-api/src/main/scala/no/ndla/conceptapi/validation/ContentValidator.scala
@@ -25,7 +25,7 @@ import scala.util.{Failure, Success, Try}
trait ContentValidator {
this: DraftConceptRepository & ConverterService & Props =>
- val contentValidator: ContentValidator
+ lazy val contentValidator: ContentValidator
class ContentValidator {
private val inlineHtmlTags = props.InlineHtmlTags
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/TestEnvironment.scala b/concept-api/src/test/scala/no/ndla/conceptapi/TestEnvironment.scala
index deb83cf012..e09ee498dc 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/TestEnvironment.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/TestEnvironment.scala
@@ -68,33 +68,33 @@ trait TestEnvironment
override def IntroductionHtmlTags: Set[String] = Set("br", "code", "em", "p", "span", "strong", "sub", "sup")
}
- val migrator: DBMigrator = mock[DBMigrator]
- val draftConceptRepository: DraftConceptRepository = mock[DraftConceptRepository]
- val publishedConceptRepository: PublishedConceptRepository = mock[PublishedConceptRepository]
+ override lazy val migrator: DBMigrator = mock[DBMigrator]
+ override lazy val draftConceptRepository: DraftConceptRepository = mock[DraftConceptRepository]
+ override lazy val publishedConceptRepository: PublishedConceptRepository = mock[PublishedConceptRepository]
- val draftConceptController: DraftConceptController = mock[DraftConceptController]
- val publishedConceptController: PublishedConceptController = mock[PublishedConceptController]
- val internController: InternController = mock[InternController]
- val healthController: TapirHealthController = mock[TapirHealthController]
+ override lazy val draftConceptController: DraftConceptController = mock[DraftConceptController]
+ override lazy val publishedConceptController: PublishedConceptController = mock[PublishedConceptController]
+ override lazy val internController: InternController = mock[InternController]
+ override lazy val healthController: TapirHealthController = mock[TapirHealthController]
- val searchConverterService: SearchConverterService = mock[SearchConverterService]
- val draftConceptIndexService: DraftConceptIndexService = mock[DraftConceptIndexService]
- val draftConceptSearchService: DraftConceptSearchService = mock[DraftConceptSearchService]
- val publishedConceptIndexService: PublishedConceptIndexService = mock[PublishedConceptIndexService]
- val publishedConceptSearchService: PublishedConceptSearchService = mock[PublishedConceptSearchService]
+ override lazy val searchConverterService: SearchConverterService = mock[SearchConverterService]
+ override lazy val draftConceptIndexService: DraftConceptIndexService = mock[DraftConceptIndexService]
+ override lazy val draftConceptSearchService: DraftConceptSearchService = mock[DraftConceptSearchService]
+ override lazy val publishedConceptIndexService: PublishedConceptIndexService = mock[PublishedConceptIndexService]
+ override lazy val publishedConceptSearchService: PublishedConceptSearchService = mock[PublishedConceptSearchService]
- var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
- val mockitoSugar: MockitoSugar = mock[MockitoSugar]
- val dataSource: HikariDataSource = mock[HikariDataSource]
- val writeService: WriteService = mock[WriteService]
- val readService: ReadService = mock[ReadService]
- val converterService: ConverterService = mock[ConverterService]
- val contentValidator: ContentValidator = mock[ContentValidator]
- val clock: SystemClock = mock[SystemClock]
+ var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
+ val mockitoSugar: MockitoSugar = mock[MockitoSugar]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val writeService: WriteService = mock[WriteService]
+ override lazy val readService: ReadService = mock[ReadService]
+ override lazy val converterService: ConverterService = mock[ConverterService]
+ override lazy val contentValidator: ContentValidator = mock[ContentValidator]
+ override lazy val clock: SystemClock = mock[SystemClock]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val searchApiClient: SearchApiClient = mock[SearchApiClient]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val searchApiClient: SearchApiClient = mock[SearchApiClient]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/repository/DraftConceptRepositoryTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/repository/DraftConceptRepositoryTest.scala
index be0fd6a421..c44161976a 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/repository/DraftConceptRepositoryTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/repository/DraftConceptRepositoryTest.scala
@@ -22,9 +22,9 @@ import scala.util.{Failure, Success, Try}
class DraftConceptRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with TestEnvironment {
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator = new DBMigrator
- var repository: DraftConceptRepository = _
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator = new DBMigrator
+ var repository: DraftConceptRepository = _
def emptyTestDatabase: Boolean = {
DB autoCommit (implicit session => {
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/repository/PublishedConceptRepositoryTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/repository/PublishedConceptRepositoryTest.scala
index 333fe85bc6..ab815eae1e 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/repository/PublishedConceptRepositoryTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/repository/PublishedConceptRepositoryTest.scala
@@ -22,9 +22,9 @@ import scala.util.{Success, Try}
class PublishedConceptRepositoryTest extends DatabaseIntegrationSuite with TestEnvironment {
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator = new DBMigrator
- var repository: PublishedConceptRepository = _
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator = new DBMigrator
+ var repository: PublishedConceptRepository = _
def emptyTestDatabase: Boolean = {
DB autoCommit (implicit session => {
@@ -203,9 +203,9 @@ class PublishedConceptRepositoryTest extends DatabaseIntegrationSuite with TestE
updated = NDLADate.fromUnixTime(0)
)
- val Success(ins1) = repository.insertOrUpdate(con1)
- val Success(ins2) = repository.insertOrUpdate(con2)
- val Success(ins3) = repository.insertOrUpdate(con3)
+ val Success(ins1) = repository.insertOrUpdate(con1): @unchecked
+ val Success(ins2) = repository.insertOrUpdate(con2): @unchecked
+ val Success(ins3) = repository.insertOrUpdate(con3): @unchecked
repository.getByPage(10, 0).sortBy(_.id.get) should be(Seq(ins1, ins2, ins3))
}
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/service/ConverterServiceTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/service/ConverterServiceTest.scala
index bdc2be632e..0c1f7a2e94 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/service/ConverterServiceTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/service/ConverterServiceTest.scala
@@ -23,8 +23,8 @@ import scala.util.{Failure, Success}
class ConverterServiceTest extends UnitSuite with TestEnvironment {
- override val converterService = new ConverterService
- val userInfo: TokenUser = TokenUser("", Set(CONCEPT_API_WRITE, CONCEPT_API_ADMIN), None)
+ override lazy val converterService = new ConverterService
+ val userInfo: TokenUser = TokenUser("", Set(CONCEPT_API_WRITE, CONCEPT_API_ADMIN), None)
test("toApiConcept converts a domain.Concept to an api.Concept with defined language") {
converterService.toApiConcept(TestData.domainConcept, "nn", fallback = false, Some(userInfo)) should be(
@@ -387,7 +387,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
)
val newConcept = TestData.emptyApiNewConcept.copy(conceptType = "gloss", glossData = Some(newGlossData))
- val Failure(result1) = converterService.toDomainConcept(newConcept, TestData.userWithWriteAccess)
+ val Failure(result1) = converterService.toDomainConcept(newConcept, TestData.userWithWriteAccess): @unchecked
result1.getMessage should include("'ikke' is not a valid gloss type")
// val newConcept2 =
@@ -464,7 +464,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
val existingConcept = TestData.domainConcept.copy(conceptType = concept.ConceptType.CONCEPT, glossData = None)
val Failure(result) =
- converterService.toDomainConcept(existingConcept, updatedConcept, TestData.userWithWriteAccess)
+ converterService.toDomainConcept(existingConcept, updatedConcept, TestData.userWithWriteAccess): @unchecked
result.getMessage should include("'ikke eksisterende' is not a valid gloss type")
}
@@ -556,7 +556,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
)
)
- val Failure(result) = converterService.toDomainGlossData(apiGlossData)
+ val Failure(result) = converterService.toDomainGlossData(apiGlossData): @unchecked
result.getMessage should include("'nonexistent' is not a valid gloss type")
}
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/service/ReadServiceTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/service/ReadServiceTest.scala
index 03e83982a5..909f06a906 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/service/ReadServiceTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/service/ReadServiceTest.scala
@@ -18,7 +18,7 @@ import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.when
class ReadServiceTest extends UnitSuite with TestEnvironment {
- override val converterService = new ConverterService
+ override lazy val converterService = new ConverterService
val service = new ReadService()
val userInfo: TokenUser = TokenUser("", Set(CONCEPT_API_WRITE), None)
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/service/WriteServiceTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/service/WriteServiceTest.scala
index bc095319a7..403ae24f81 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/service/WriteServiceTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/service/WriteServiceTest.scala
@@ -26,7 +26,7 @@ import org.mockito.Mockito.{reset, times, verify, when}
import org.mockito.stubbing.OngoingStubbing
class WriteServiceTest extends UnitSuite with TestEnvironment {
- override val converterService = new ConverterService
+ override lazy val converterService = new ConverterService
val today: NDLADate = NDLADate.now()
val yesterday: NDLADate = NDLADate.now().minusDays(1)
@@ -181,7 +181,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
}
test("That delete concept should fail when only one language") {
- val Failure(result) = service.deleteLanguage(concept.id, "nb", userInfo)
+ val Failure(result) = service.deleteLanguage(concept.id, "nb", userInfo): @unchecked
result.getMessage should equal("Only one language left")
}
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/service/search/DraftConceptSearchServiceTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/service/search/DraftConceptSearchServiceTest.scala
index 6203e8a282..f88e2363c0 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/service/search/DraftConceptSearchServiceTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/service/search/DraftConceptSearchServiceTest.scala
@@ -17,7 +17,6 @@ import no.ndla.conceptapi.model.search.DraftSearchSettings
import no.ndla.language.Language
import no.ndla.scalatestsuite.ElasticsearchIntegrationSuite
-import scala.util.Success
import no.ndla.common.model.NDLADate
import no.ndla.common.model.domain.concept.{
Concept,
@@ -34,19 +33,18 @@ import no.ndla.mapping.License
import java.util.UUID
class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnvironment {
- import props.{DefaultLanguage, DefaultPageSize}
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- val indexName: String = UUID.randomUUID().toString
- override val draftConceptSearchService: DraftConceptSearchService = new DraftConceptSearchService {
+ val indexName: String = UUID.randomUUID().toString
+ override lazy val draftConceptSearchService: DraftConceptSearchService = new DraftConceptSearchService {
override val searchIndex: String = indexName
}
- override val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
+ override lazy val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
override val indexShards = 1
override val searchIndex: String = indexName
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val byNcSa: DraftCopyright = DraftCopyright(
Some(License.CC_BY_NC_SA.toString),
@@ -221,7 +219,7 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
val searchSettings: DraftSearchSettings = DraftSearchSettings(
withIdIn = List.empty,
- searchLanguage = DefaultLanguage,
+ searchLanguage = props.DefaultLanguage,
page = 1,
pageSize = 10,
sort = Sort.ByIdAsc,
@@ -270,24 +268,23 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
"That getStartAtAndNumResults returns the correct calculated start at for page and page-size with default page-size"
) {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- draftConceptSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal(
- (expectedStartAt, DefaultPageSize)
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ draftConceptSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
)
}
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
val page = 123
- val expectedStartAt = (page - 1) * DefaultPageSize
- draftConceptSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal(
- (expectedStartAt, DefaultPageSize)
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ draftConceptSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
)
}
test("That all returns all documents ordered by id ascending") {
- val Success(results) =
- draftConceptSearchService.all(searchSettings.copy(sort = Sort.ByIdAsc))
- val hits = results.results
+ val results = draftConceptSearchService.all(searchSettings.copy(sort = Sort.ByIdAsc)).get
+ val hits = results.results
results.totalCount should be(11)
hits.head.id should be(1)
hits(1).id should be(2)
@@ -302,17 +299,16 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("That all returns all documents ordered by id descending") {
- val Success(results) =
- draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByIdDesc))
- val hits = results.results
+ val results = draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByIdDesc)).get
+ val hits = results.results
results.totalCount should be(11)
hits.head.id should be(13)
hits.last.id should be(1)
}
test("That all returns all documents ordered by title ascending") {
- val Success(results) =
- draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleAsc, fallback = true))
+ val results =
+ draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleAsc, fallback = true)).get
val hits = results.results
results.totalCount should be(12)
@@ -331,8 +327,8 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("That all returns all documents ordered by title descending") {
- val Success(results) =
- draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleDesc, fallback = true))
+ val results =
+ draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleDesc, fallback = true)).get
val hits = results.results
results.totalCount should be(12)
hits.head.id should be(7)
@@ -351,27 +347,23 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("That all returns all documents ordered by lastUpdated descending") {
- val Success(results) =
- draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByLastUpdatedDesc))
- val hits = results.results
+ val results = draftConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByLastUpdatedDesc)).get
+ val hits = results.results
results.totalCount should be(11)
hits.map(_.id) should be(Seq(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13))
}
test("That all filtered by id only returns documents with the given ids") {
- val Success(results) =
- draftConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 3)))
- val hits = results.results
+ val results = draftConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 3))).get
+ val hits = results.results
results.totalCount should be(2)
hits.head.id should be(1)
hits.last.id should be(3)
}
test("That paging returns only hits on current page and not more than page-size") {
- val Success(page1) =
- draftConceptSearchService.all(searchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByTitleAsc))
- val Success(page2) =
- draftConceptSearchService.all(searchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByTitleAsc))
+ val page1 = draftConceptSearchService.all(searchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByTitleAsc)).get
+ val page2 = draftConceptSearchService.all(searchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByTitleAsc)).get
val hits1 = page1.results
page1.totalCount should be(11)
@@ -389,59 +381,54 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("That search matches title and content ordered by relevance descending") {
- val Success(results) =
- draftConceptSearchService.matchingQuery("bil", searchSettings.copy(sort = Sort.ByRelevanceDesc))
- val hits = results.results
+ val results = draftConceptSearchService.matchingQuery("bil", searchSettings.copy(sort = Sort.ByRelevanceDesc)).get
+ val hits = results.results
results.totalCount should be(3)
hits.map(_.id) should be(Seq(1, 5, 3))
}
test("That search matches title") {
- val Success(results) =
- draftConceptSearchService.matchingQuery("Pingvinen", searchSettings.copy(sort = Sort.ByTitleAsc))
- val hits = results.results
+ val results = draftConceptSearchService.matchingQuery("Pingvinen", searchSettings.copy(sort = Sort.ByTitleAsc)).get
+ val hits = results.results
results.totalCount should be(1)
hits.head.id should be(2)
}
test("Searching with logical AND only returns results with all terms") {
- val Success(search1) =
- draftConceptSearchService.matchingQuery("bilde + bil", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val search1 =
+ draftConceptSearchService.matchingQuery("bilde + bil", searchSettings.copy(sort = Sort.ByTitleAsc)).get
val hits1 = search1.results
hits1.map(_.id) should equal(Seq(1, 3, 5))
- val Success(search2) =
- draftConceptSearchService.matchingQuery("batmen + bil", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val search2 =
+ draftConceptSearchService.matchingQuery("batmen + bil", searchSettings.copy(sort = Sort.ByTitleAsc)).get
val hits2 = search2.results
hits2.map(_.id) should equal(Seq(1))
- val Success(search3) =
- draftConceptSearchService.matchingQuery(
- "bil + bilde + -flaggermusmann",
- searchSettings.copy(sort = Sort.ByTitleAsc)
- )
+ val search3 = draftConceptSearchService
+ .matchingQuery("bil + bilde + -flaggermusmann", searchSettings.copy(sort = Sort.ByTitleAsc))
+ .get
val hits3 = search3.results
hits3.map(_.id) should equal(Seq(3, 5))
- val Success(search4) =
- draftConceptSearchService.matchingQuery("bil + -hulken", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val search4 =
+ draftConceptSearchService.matchingQuery("bil + -hulken", searchSettings.copy(sort = Sort.ByTitleAsc)).get
val hits4 = search4.results
hits4.map(_.id) should equal(Seq(1, 3))
}
test("search in content should be ranked lower than title") {
- val Success(search) =
- draftConceptSearchService.matchingQuery("mareritt + ragnarok", searchSettings.copy(sort = Sort.ByRelevanceDesc))
+ val search = draftConceptSearchService
+ .matchingQuery("mareritt + ragnarok", searchSettings.copy(sort = Sort.ByRelevanceDesc))
+ .get
val hits = search.results
hits.map(_.id) should equal(Seq(9, 8))
}
test("Search should return language it is matched in") {
- val Success(searchEn) =
- draftConceptSearchService.matchingQuery("Unrelated", searchSettings.copy(searchLanguage = "*"))
- val Success(searchNb) =
- draftConceptSearchService.matchingQuery("Urelatert", searchSettings.copy(searchLanguage = "*"))
+ val searchEn = draftConceptSearchService.matchingQuery("Unrelated", searchSettings.copy(searchLanguage = "*")).get
+ val searchNb = draftConceptSearchService.matchingQuery("Urelatert", searchSettings.copy(searchLanguage = "*")).get
searchEn.totalCount should be(1)
searchEn.results.head.title.language should be("en")
@@ -457,8 +444,8 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("Search for all languages should return all concepts in correct language") {
- val Success(search) =
- draftConceptSearchService.all(searchSettings.copy(searchLanguage = Language.AllLanguages, pageSize = 100))
+ val search =
+ draftConceptSearchService.all(searchSettings.copy(searchLanguage = Language.AllLanguages, pageSize = 100)).get
val hits = search.results
search.totalCount should equal(12)
@@ -479,10 +466,9 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("That searching with fallback parameter returns concept in language priority even if doesnt match on language") {
- val Success(search) =
- draftConceptSearchService.all(
- searchSettings.copy(withIdIn = List(9, 10, 11), searchLanguage = "en", fallback = true)
- )
+ val search = draftConceptSearchService
+ .all(searchSettings.copy(withIdIn = List(9, 10, 11), searchLanguage = "en", fallback = true))
+ .get
search.totalCount should equal(3)
search.results.head.id should equal(9)
@@ -494,9 +480,8 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("That searching for language not in analyzers works") {
- val Success(search) =
- draftConceptSearchService.all(searchSettings.copy(searchLanguage = "dhm"))
- val hits = search.results
+ val search = draftConceptSearchService.all(searchSettings.copy(searchLanguage = "dhm")).get
+ val hits = search.results
search.totalCount should equal(1)
hits.head.id should be(11)
@@ -504,8 +489,7 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("That searching for not indexed language should work and not return hits") {
- val Success(search) =
- draftConceptSearchService.all(searchSettings.copy(searchLanguage = "bij"))
+ val search = draftConceptSearchService.all(searchSettings.copy(searchLanguage = "bij")).get
search.totalCount should equal(0)
}
@@ -513,17 +497,15 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
val pageSize = 2
val expectedIds = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13).sliding(pageSize, pageSize).toList
- val Success(initialSearch) =
- draftConceptSearchService.all(
- searchSettings.copy(searchLanguage = "*", pageSize = pageSize, fallback = true, shouldScroll = true)
- )
-
- val Success(scroll1) = draftConceptSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = draftConceptSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = draftConceptSearchService.scroll(scroll2.scrollId.get, "*")
- val Success(scroll4) = draftConceptSearchService.scroll(scroll3.scrollId.get, "*")
- val Success(scroll5) = draftConceptSearchService.scroll(scroll4.scrollId.get, "*")
- val Success(scroll6) = draftConceptSearchService.scroll(scroll5.scrollId.get, "*")
+ val initialSearch = draftConceptSearchService
+ .all(searchSettings.copy(searchLanguage = "*", pageSize = pageSize, fallback = true, shouldScroll = true))
+ .get
+ val scroll1 = draftConceptSearchService.scroll(initialSearch.scrollId.get, "*").get
+ val scroll2 = draftConceptSearchService.scroll(scroll1.scrollId.get, "*").get
+ val scroll3 = draftConceptSearchService.scroll(scroll2.scrollId.get, "*").get
+ val scroll4 = draftConceptSearchService.scroll(scroll3.scrollId.get, "*").get
+ val scroll5 = draftConceptSearchService.scroll(scroll4.scrollId.get, "*").get
+ val scroll6 = draftConceptSearchService.scroll(scroll5.scrollId.get, "*").get
initialSearch.results.map(_.id) should be(expectedIds.head)
scroll1.results.map(_.id) should be(expectedIds(1))
@@ -535,19 +517,18 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("that searching for tags works and respects language/fallback") {
- val Success(search) =
- draftConceptSearchService.matchingQuery("burugle", searchSettings.copy(searchLanguage = "*"))
+ val search = draftConceptSearchService.matchingQuery("burugle", searchSettings.copy(searchLanguage = "*")).get
search.totalCount should be(1)
search.results.head.id should be(10)
- val Success(search2) =
- draftConceptSearchService.matchingQuery("burugle", searchSettings.copy(searchLanguage = "en"))
+ val search2 = draftConceptSearchService.matchingQuery("burugle", searchSettings.copy(searchLanguage = "en")).get
search2.totalCount should be(0)
- val Success(search3) =
- draftConceptSearchService.matchingQuery("burugle", searchSettings.copy(searchLanguage = "en", fallback = true))
+ val search3 = draftConceptSearchService
+ .matchingQuery("burugle", searchSettings.copy(searchLanguage = "en", fallback = true))
+ .get
search3.totalCount should be(1)
search3.results.head.id should be(10)
@@ -582,172 +563,164 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("that filtering for tags works as expected") {
- val Success(search) = draftConceptSearchService.all(searchSettings.copy(tagsToFilterBy = Set("burugle")))
+ val search = draftConceptSearchService.all(searchSettings.copy(tagsToFilterBy = Set("burugle"))).get
search.totalCount should be(1)
search.results.map(_.id) should be(Seq(10))
- val Success(search1) =
- draftConceptSearchService.all(searchSettings.copy(searchLanguage = "*", tagsToFilterBy = Set("burugle")))
+ val search1 =
+ draftConceptSearchService.all(searchSettings.copy(searchLanguage = "*", tagsToFilterBy = Set("burugle"))).get
search1.totalCount should be(1)
search1.results.map(_.id) should be(Seq(10))
}
test("Filtering by statuses works as expected with OR filtering") {
- val Success(statusSearch1) = draftConceptSearchService.all(searchSettings.copy(statusFilter = Set("PUBLISHED")))
+ val statusSearch1 = draftConceptSearchService.all(searchSettings.copy(statusFilter = Set("PUBLISHED"))).get
statusSearch1.totalCount should be(2)
statusSearch1.results.map(_.id) should be(Seq(9, 10))
- val Success(statusSearch2) = draftConceptSearchService.all(searchSettings.copy(statusFilter = Set("FOR_APPROVAL")))
+ val statusSearch2 = draftConceptSearchService.all(searchSettings.copy(statusFilter = Set("FOR_APPROVAL"))).get
statusSearch2.totalCount should be(1)
statusSearch2.results.map(_.id) should be(Seq(10))
- val Success(statusSearch3) =
- draftConceptSearchService.all(searchSettings.copy(statusFilter = Set("FOR_APPROVAL", "END_CONTROL")))
+ val statusSearch3 =
+ draftConceptSearchService.all(searchSettings.copy(statusFilter = Set("FOR_APPROVAL", "END_CONTROL"))).get
statusSearch3.totalCount should be(2)
statusSearch3.results.map(_.id) should be(Seq(8, 10))
}
test("ARCHIVED concepts should only be returned if filtered by ARCHIVED") {
- val query = "slettet"
- val Success(search1) =
- draftConceptSearchService.matchingQuery(
- query = query,
- searchSettings.copy(withIdIn = List(12), statusFilter = Set(ConceptStatus.ARCHIVED.toString))
- )
- val Success(search2) =
- draftConceptSearchService.matchingQuery(
- query = query,
- searchSettings.copy(withIdIn = List(12), statusFilter = Set.empty)
- )
+ val query = "slettet"
+ val search1 =
+ draftConceptSearchService
+ .matchingQuery(
+ query = query,
+ searchSettings.copy(withIdIn = List(12), statusFilter = Set(ConceptStatus.ARCHIVED.toString))
+ )
+ .get
+ val search2 =
+ draftConceptSearchService
+ .matchingQuery(
+ query = query,
+ searchSettings.copy(withIdIn = List(12), statusFilter = Set.empty)
+ )
+ .get
search1.results.map(_.id) should be(Seq(12))
search2.results.map(_.id) should be(Seq.empty)
}
test("Filtering by users works as expected with OR filtering") {
- val Success(res1) = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1")))
+ val res1 = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1"))).get
res1.totalCount should be(3)
res1.results.map(_.id) should be(Seq(2, 3, 7))
- val Success(res2) = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test2")))
+ val res2 = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test2"))).get
res2.totalCount should be(2)
res2.results.map(_.id) should be(Seq(3, 5))
- val Success(res3) = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("Test1")))
+ val res3 = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("Test1"))).get
res3.totalCount should be(2)
res3.results.map(_.id) should be(Seq(7, 10))
- val Success(res4) = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1", "test2")))
+ val res4 = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1", "test2"))).get
res4.totalCount should be(4)
res4.results.map(_.id) should be(Seq(2, 3, 5, 7))
- val Success(res5) = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1", "Test1")))
+ val res5 = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1", "Test1"))).get
res5.totalCount should be(4)
res5.results.map(_.id) should be(Seq(2, 3, 7, 10))
- val Success(res6) = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test2", "Test1")))
+ val res6 = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test2", "Test1"))).get
res6.totalCount should be(4)
res6.results.map(_.id) should be(Seq(3, 5, 7, 10))
- val Success(res7) = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1", "Test1", "test2")))
+ val res7 = draftConceptSearchService.all(searchSettings.copy(userFilter = Seq("test1", "Test1", "test2"))).get
res7.totalCount should be(5)
res7.results.map(_.id) should be(Seq(2, 3, 5, 7, 10))
}
test("that search on embedId matches visual element") {
- val Success(search) =
- draftConceptSearchService.all(
- searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.url"))
- )
+ val search =
+ draftConceptSearchService
+ .all(
+ searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.url"))
+ )
+ .get
search.totalCount should be(2)
search.results.map(_.id) should be(List(9, 10))
}
test("that search on embedResource matches visual element") {
- val Success(search) =
- draftConceptSearchService.all(
- searchSettings.copy(searchLanguage = Language.AllLanguages, embedResource = List("brightcove"))
- )
+ val search =
+ draftConceptSearchService
+ .all(searchSettings.copy(searchLanguage = Language.AllLanguages, embedResource = List("brightcove")))
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on embedId matches visual element image") {
- val Success(search) =
- draftConceptSearchService.all(
- searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.image"))
- )
+ val search =
+ draftConceptSearchService
+ .all(searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.image")))
+ .get
search.totalCount should be(1)
search.results.head.id should be(9)
}
test("that search on query parameter as embedId matches visual element image") {
- val Success(search) =
- draftConceptSearchService.matchingQuery(
- "test.image",
- searchSettings.copy()
- )
+ val search =
+ draftConceptSearchService
+ .matchingQuery("test.image", searchSettings.copy())
+ .get
search.totalCount should be(1)
search.results.head.id should be(9)
}
test("that search on query parameter as embedResource matches visual element") {
- val Success(search) =
- draftConceptSearchService.matchingQuery(
- "brightcove",
- searchSettings.copy()
- )
+ val search =
+ draftConceptSearchService
+ .matchingQuery("brightcove", searchSettings.copy())
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on query parameter as embedId matches visual element") {
- val Success(search) =
- draftConceptSearchService.matchingQuery(
- "test.url",
- searchSettings.copy()
- )
+ val search = draftConceptSearchService.matchingQuery("test.url", searchSettings.copy()).get
search.totalCount should be(2)
search.results.map(_.id) should be(List(9, 10))
}
test("that search on query parameter matches on concept id") {
- val Success(search) =
- draftConceptSearchService.matchingQuery(
- "2",
- searchSettings.copy()
- )
+ val search = draftConceptSearchService.matchingQuery("2", searchSettings.copy()).get
search.totalCount should be(1)
search.results.head.id should be(2)
}
test("that search on embedId and embedResource only returns results with an embed matching both params") {
- val Success(search) =
- draftConceptSearchService.all(
- searchSettings
- .copy(searchLanguage = Language.AllLanguages, embedResource = List("image"), embedId = Some("test.image"))
- )
+ val search =
+ draftConceptSearchService
+ .all(
+ searchSettings
+ .copy(searchLanguage = Language.AllLanguages, embedResource = List("image"), embedId = Some("test.image"))
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(9)
}
test("That search on embed id supports embed with multiple id attributes") {
- val Success(search1) =
- draftConceptSearchService.all(
- searchSettings.copy(embedId = Some("test.url2"))
- )
- val Success(search2) =
- draftConceptSearchService.all(
- searchSettings.copy(embedId = Some("test.id2"))
- )
+ val search1 = draftConceptSearchService.all(searchSettings.copy(embedId = Some("test.url2"))).get
+ val search2 = draftConceptSearchService.all(searchSettings.copy(embedId = Some("test.id2"))).get
search1.totalCount should be(1)
search1.results.head.id should be(10)
@@ -757,37 +730,36 @@ class DraftConceptSearchServiceTest extends ElasticsearchIntegrationSuite with T
}
test("search results should return copyright info") {
- val Success(search) =
- draftConceptSearchService.matchingQuery("hulk", searchSettings.copy(sort = Sort.ByRelevanceDesc))
- val hits = search.results
+ val search = draftConceptSearchService.matchingQuery("hulk", searchSettings.copy(sort = Sort.ByRelevanceDesc)).get
+ val hits = search.results
hits.map(_.id) should equal(Seq(5))
hits.head.copyright.head.origin should be(Some("Gotham City"))
hits.head.copyright.head.creators.length should be(1)
}
test("that sorting for status works") {
- val Success(search) =
- draftConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 8, 9, 10), sort = Sort.ByStatusAsc))
+ val search =
+ draftConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 8, 9, 10), sort = Sort.ByStatusAsc)).get
search.results.map(_.id) should be(Seq(8, 10, 1, 9))
- val Success(search2) =
- draftConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 8, 9, 10), sort = Sort.ByStatusDesc))
+ val search2 =
+ draftConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 8, 9, 10), sort = Sort.ByStatusDesc)).get
search2.results.map(_.id) should be(Seq(9, 1, 10, 8))
}
test("that filtering for conceptType works as expected") {
{
- val Success(search) = draftConceptSearchService.all(searchSettings.copy(conceptType = Some("concept")))
+ val search = draftConceptSearchService.all(searchSettings.copy(conceptType = Some("concept"))).get
search.totalCount should be(10)
}
{
- val Success(search) = draftConceptSearchService.all(searchSettings.copy(conceptType = Some("gloss")))
+ val search = draftConceptSearchService.all(searchSettings.copy(conceptType = Some("gloss"))).get
search.totalCount should be(1)
}
}
test("That searching for gloss data matches") {
- val Success(search) = draftConceptSearchService.matchingQuery("glossorama", searchSettings)
+ val search = draftConceptSearchService.matchingQuery("glossorama", searchSettings).get
search.totalCount should be(1)
search.results.head.id should be(13)
}
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchServiceTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchServiceTest.scala
index 5ac6b6cd90..eb27086fe6 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchServiceTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/service/search/PublishedConceptSearchServiceTest.scala
@@ -18,22 +18,20 @@ import no.ndla.language.Language
import no.ndla.scalatestsuite.ElasticsearchIntegrationSuite
import java.time.LocalDateTime
-import scala.util.Success
import no.ndla.common.model.NDLADate
import no.ndla.common.model.domain.concept.{Concept, ConceptContent, ConceptType, GlossData, VisualElement, WordClass}
import no.ndla.mapping.License
import no.ndla.search.model.domain.{Bucket, TermAggregation}
class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnvironment {
- import props.{DefaultLanguage, DefaultPageSize}
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val publishedConceptSearchService = new PublishedConceptSearchService
- override val publishedConceptIndexService: PublishedConceptIndexService = new PublishedConceptIndexService {
+ override lazy val publishedConceptSearchService = new PublishedConceptSearchService
+ override lazy val publishedConceptIndexService: PublishedConceptIndexService = new PublishedConceptIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val byNcSa: DraftCopyright = DraftCopyright(
Some(License.CC_BY_NC_SA.toString),
@@ -183,7 +181,7 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
val searchSettings: search.SearchSettings = search.SearchSettings(
withIdIn = List.empty,
- searchLanguage = DefaultLanguage,
+ searchLanguage = props.DefaultLanguage,
page = 1,
pageSize = 10,
sort = Sort.ByIdAsc,
@@ -229,24 +227,23 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
"That getStartAtAndNumResults returns the correct calculated start at for page and page-size with default page-size"
) {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- publishedConceptSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal(
- (expectedStartAt, DefaultPageSize)
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ publishedConceptSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
)
}
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
val page = 123
- val expectedStartAt = (page - 1) * DefaultPageSize
- publishedConceptSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal(
- (expectedStartAt, DefaultPageSize)
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ publishedConceptSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
)
}
test("That all returns all documents ordered by id ascending") {
- val Success(results) =
- publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByIdAsc))
- val hits = results.results
+ val results = publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByIdAsc)).get
+ val hits = results.results
results.totalCount should be(11)
hits.head.id should be(1)
hits(1).id should be(2)
@@ -262,18 +259,16 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("That all returns all documents ordered by id descending") {
- val Success(results) =
- publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByIdDesc))
- val hits = results.results
+ val results = publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByIdDesc)).get
+ val hits = results.results
results.totalCount should be(11)
hits.head.id should be(12)
hits.last.id should be(1)
}
test("That all returns all documents ordered by title ascending") {
- val Success(results) =
- publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleAsc))
- val hits = results.results
+ val results = publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleAsc)).get
+ val hits = results.results
results.totalCount should be(11)
hits.head.id should be(8)
@@ -289,9 +284,8 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("That all returns all documents ordered by title descending") {
- val Success(results) =
- publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleDesc))
- val hits = results.results
+ val results = publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByTitleDesc)).get
+ val hits = results.results
results.totalCount should be(11)
hits.head.id should be(7)
hits(1).id should be(10)
@@ -308,27 +302,26 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("That all returns all documents ordered by lastUpdated descending") {
- val Success(results) =
- publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByLastUpdatedDesc))
+ val results =
+ publishedConceptSearchService.all(searchSettings.copy(pageSize = 20, sort = Sort.ByLastUpdatedDesc)).get
val hits = results.results
results.totalCount should be(11)
hits.map(_.id) should be(Seq(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12))
}
test("That all filtered by id only returns documents with the given ids") {
- val Success(results) =
- publishedConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 3)))
- val hits = results.results
+ val results = publishedConceptSearchService.all(searchSettings.copy(withIdIn = List(1, 3))).get
+ val hits = results.results
results.totalCount should be(2)
hits.head.id should be(1)
hits.last.id should be(3)
}
test("That paging returns only hits on current page and not more than page-size") {
- val Success(page1) =
- publishedConceptSearchService.all(searchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByTitleAsc))
- val Success(page2) =
- publishedConceptSearchService.all(searchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByTitleAsc))
+ val page1 =
+ publishedConceptSearchService.all(searchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByTitleAsc)).get
+ val page2 =
+ publishedConceptSearchService.all(searchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByTitleAsc)).get
val hits1 = page1.results
page1.totalCount should be(11)
@@ -346,8 +339,8 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("That search matches title and content ordered by relevance descending") {
- val Success(results) =
- publishedConceptSearchService.matchingQuery("bil", searchSettings.copy(sort = Sort.ByRelevanceDesc))
+ val results =
+ publishedConceptSearchService.matchingQuery("bil", searchSettings.copy(sort = Sort.ByRelevanceDesc)).get
val hits = results.results
results.totalCount should be(3)
@@ -355,86 +348,96 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("That search matches title") {
- val Success(results) =
- publishedConceptSearchService.matchingQuery("Pingvinen", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val results =
+ publishedConceptSearchService.matchingQuery("Pingvinen", searchSettings.copy(sort = Sort.ByTitleAsc)).get
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(2)
}
test("That search for title matches correct number of concepts") {
- val Success(results) =
- publishedConceptSearchService.matchingQuery("baldur har mareritt", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val results = publishedConceptSearchService
+ .matchingQuery("baldur har mareritt", searchSettings.copy(sort = Sort.ByTitleAsc))
+ .get
results.totalCount should be(2)
}
test("That search for title with exact parameter matches correct number of concepts") {
- val Success(results) =
- publishedConceptSearchService.matchingQuery(
+ val results = publishedConceptSearchService
+ .matchingQuery(
"baldur har mareritt",
searchSettings.copy(sort = Sort.ByTitleAsc, exactTitleMatch = true)
)
+ .get
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(8)
- val Success(results2) =
- publishedConceptSearchService.matchingQuery(
- "Pingvinen",
- searchSettings.copy(sort = Sort.ByTitleAsc, exactTitleMatch = true)
- )
+ val results2 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "Pingvinen",
+ searchSettings.copy(sort = Sort.ByTitleAsc, exactTitleMatch = true)
+ )
+ .get
results2.totalCount should be(0)
- val Success(results3) =
- publishedConceptSearchService.matchingQuery(
- "baldur har MARERITT",
- searchSettings.copy(sort = Sort.ByTitleAsc, exactTitleMatch = true)
- )
+ val results3 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "baldur har MARERITT",
+ searchSettings.copy(sort = Sort.ByTitleAsc, exactTitleMatch = true)
+ )
+ .get
val hits3 = results3.results
results3.totalCount should be(1)
hits3.head.id should be(8)
}
test("Searching with logical AND only returns results with all terms") {
- val Success(search1) =
- publishedConceptSearchService.matchingQuery("bilde + bil", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val search1 =
+ publishedConceptSearchService.matchingQuery("bilde + bil", searchSettings.copy(sort = Sort.ByTitleAsc)).get
val hits1 = search1.results
hits1.map(_.id) should equal(Seq(1, 3, 5))
- val Success(search2) =
- publishedConceptSearchService.matchingQuery("batmen + bil", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val search2 =
+ publishedConceptSearchService.matchingQuery("batmen + bil", searchSettings.copy(sort = Sort.ByTitleAsc)).get
val hits2 = search2.results
hits2.map(_.id) should equal(Seq(1))
- val Success(search3) =
- publishedConceptSearchService.matchingQuery(
- "bil + bilde + -flaggermusmann",
- searchSettings.copy(sort = Sort.ByTitleAsc)
- )
+ val search3 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "bil + bilde + -flaggermusmann",
+ searchSettings.copy(sort = Sort.ByTitleAsc)
+ )
+ .get
val hits3 = search3.results
hits3.map(_.id) should equal(Seq(3, 5))
- val Success(search4) =
- publishedConceptSearchService.matchingQuery("bil + -hulken", searchSettings.copy(sort = Sort.ByTitleAsc))
+ val search4 =
+ publishedConceptSearchService.matchingQuery("bil + -hulken", searchSettings.copy(sort = Sort.ByTitleAsc)).get
val hits4 = search4.results
hits4.map(_.id) should equal(Seq(1, 3))
}
test("search in content should be ranked lower than title") {
- val Success(search) =
- publishedConceptSearchService.matchingQuery(
- "mareritt + ragnarok",
- searchSettings.copy(sort = Sort.ByRelevanceDesc)
- )
+ val search =
+ publishedConceptSearchService
+ .matchingQuery(
+ "mareritt + ragnarok",
+ searchSettings.copy(sort = Sort.ByRelevanceDesc)
+ )
+ .get
val hits = search.results
hits.map(_.id) should equal(Seq(9, 8))
}
test("Search should return language it is matched in") {
- val Success(searchEn) =
- publishedConceptSearchService.matchingQuery("Unrelated", searchSettings.copy(searchLanguage = "*"))
- val Success(searchNb) =
- publishedConceptSearchService.matchingQuery("Urelatert", searchSettings.copy(searchLanguage = "*"))
+ val searchEn =
+ publishedConceptSearchService.matchingQuery("Unrelated", searchSettings.copy(searchLanguage = "*")).get
+ val searchNb =
+ publishedConceptSearchService.matchingQuery("Urelatert", searchSettings.copy(searchLanguage = "*")).get
searchEn.totalCount should be(1)
searchEn.results.head.title.language should be("en")
@@ -450,8 +453,8 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("Search for all languages should return all concepts in correct language") {
- val Success(search) =
- publishedConceptSearchService.all(searchSettings.copy(searchLanguage = Language.AllLanguages, pageSize = 100))
+ val search =
+ publishedConceptSearchService.all(searchSettings.copy(searchLanguage = Language.AllLanguages, pageSize = 100)).get
val hits = search.results
search.totalCount should equal(12)
@@ -472,10 +475,10 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("That searching with fallback parameter returns concept in language priority even if doesnt match on language") {
- val Success(search) =
- publishedConceptSearchService.all(
- searchSettings.copy(withIdIn = List(9, 10, 11), searchLanguage = "en", fallback = true)
- )
+ val search =
+ publishedConceptSearchService
+ .all(searchSettings.copy(withIdIn = List(9, 10, 11), searchLanguage = "en", fallback = true))
+ .get
search.totalCount should equal(3)
search.results.head.id should equal(9)
@@ -490,17 +493,19 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
val pageSize = 2
val expectedIds = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12).sliding(pageSize, pageSize).toList
- val Success(initialSearch) =
- publishedConceptSearchService.all(
- searchSettings.copy(searchLanguage = "*", pageSize = pageSize, fallback = true, shouldScroll = true)
- )
+ val initialSearch =
+ publishedConceptSearchService
+ .all(
+ searchSettings.copy(searchLanguage = "*", pageSize = pageSize, fallback = true, shouldScroll = true)
+ )
+ .get
- val Success(scroll1) = publishedConceptSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = publishedConceptSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = publishedConceptSearchService.scroll(scroll2.scrollId.get, "*")
- val Success(scroll4) = publishedConceptSearchService.scroll(scroll3.scrollId.get, "*")
- val Success(scroll5) = publishedConceptSearchService.scroll(scroll4.scrollId.get, "*")
- val Success(scroll6) = publishedConceptSearchService.scroll(scroll5.scrollId.get, "*")
+ val scroll1 = publishedConceptSearchService.scroll(initialSearch.scrollId.get, "*").get
+ val scroll2 = publishedConceptSearchService.scroll(scroll1.scrollId.get, "*").get
+ val scroll3 = publishedConceptSearchService.scroll(scroll2.scrollId.get, "*").get
+ val scroll4 = publishedConceptSearchService.scroll(scroll3.scrollId.get, "*").get
+ val scroll5 = publishedConceptSearchService.scroll(scroll4.scrollId.get, "*").get
+ val scroll6 = publishedConceptSearchService.scroll(scroll5.scrollId.get, "*").get
initialSearch.results.map(_.id) should be(expectedIds.head)
scroll1.results.map(_.id) should be(expectedIds(1))
@@ -512,121 +517,137 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("that filtering for tags works as expected and respects language/fallback") {
- val Success(search) = publishedConceptSearchService.all(searchSettings.copy(tagsToFilterBy = Set("burugle")))
+ val search = publishedConceptSearchService.all(searchSettings.copy(tagsToFilterBy = Set("burugle"))).get
search.totalCount should be(1)
search.results.map(_.id) should be(Seq(10))
- val Success(search1) =
- publishedConceptSearchService.all(searchSettings.copy(searchLanguage = "*", tagsToFilterBy = Set("burugle")))
+ val search1 =
+ publishedConceptSearchService.all(searchSettings.copy(searchLanguage = "*", tagsToFilterBy = Set("burugle"))).get
search1.totalCount should be(1)
search1.results.map(_.id) should be(Seq(10))
- val Success(search2) =
- publishedConceptSearchService.all(searchSettings.copy(searchLanguage = "en", tagsToFilterBy = Set("burugle")))
+ val search2 =
+ publishedConceptSearchService.all(searchSettings.copy(searchLanguage = "en", tagsToFilterBy = Set("burugle"))).get
search2.totalCount should be(0)
- val Success(search3) =
- publishedConceptSearchService.all(
- searchSettings.copy(searchLanguage = "en", fallback = true, tagsToFilterBy = Set("burugle"))
- )
+ val search3 =
+ publishedConceptSearchService
+ .all(
+ searchSettings.copy(searchLanguage = "en", fallback = true, tagsToFilterBy = Set("burugle"))
+ )
+ .get
search3.totalCount should be(1)
search3.results.map(_.id) should be(Seq(10))
}
test("that search on embedId matches visual element") {
- val Success(search) =
- publishedConceptSearchService.all(
- searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.url"))
- )
+ val search =
+ publishedConceptSearchService
+ .all(searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.url")))
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on embedResource matches visual element") {
- val Success(search) =
- publishedConceptSearchService.all(
- searchSettings.copy(searchLanguage = Language.AllLanguages, embedResource = List("brightcove"))
- )
+ val search =
+ publishedConceptSearchService
+ .all(
+ searchSettings.copy(searchLanguage = Language.AllLanguages, embedResource = List("brightcove"))
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on embedId matches meta image") {
- val Success(search) =
- publishedConceptSearchService.all(
- searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.url"))
- )
+ val search =
+ publishedConceptSearchService
+ .all(
+ searchSettings.copy(searchLanguage = Language.AllLanguages, embedId = Some("test.url"))
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on query parameter as embedId matches meta image") {
- val Success(search) =
- publishedConceptSearchService.matchingQuery(
- "test.url",
- searchSettings.copy()
- )
+ val search =
+ publishedConceptSearchService
+ .matchingQuery(
+ "test.url",
+ searchSettings.copy()
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on query parameter as embedResource matches visual element") {
- val Success(search) =
- publishedConceptSearchService.matchingQuery(
- "brightcove",
- searchSettings.copy()
- )
+ val search =
+ publishedConceptSearchService
+ .matchingQuery(
+ "brightcove",
+ searchSettings.copy()
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on query parameter as embedId matches visual element") {
- val Success(search) =
- publishedConceptSearchService.matchingQuery(
- "test.url",
- searchSettings.copy()
- )
+ val search =
+ publishedConceptSearchService
+ .matchingQuery(
+ "test.url",
+ searchSettings.copy()
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("that search on query parameter matches on concept id") {
- val Success(search) =
- publishedConceptSearchService.matchingQuery(
- "2",
- searchSettings.copy()
- )
+ val search =
+ publishedConceptSearchService
+ .matchingQuery(
+ "2",
+ searchSettings.copy()
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(2)
}
test("that search on embedId and embedResource only returns results with an embed matching both params") {
- val Success(search) =
- publishedConceptSearchService.all(
- searchSettings
- .copy(searchLanguage = Language.AllLanguages, embedResource = List("image"), embedId = Some("test.url"))
- )
+ val search =
+ publishedConceptSearchService
+ .all(
+ searchSettings
+ .copy(searchLanguage = Language.AllLanguages, embedResource = List("image"), embedId = Some("test.url"))
+ )
+ .get
search.totalCount should be(1)
search.results.head.id should be(10)
}
test("That search on embed id supports embed with multiple id attributes") {
- val Success(search1) =
- publishedConceptSearchService.all(
- searchSettings.copy(embedId = Some("test.url2"))
- )
- val Success(search2) =
- publishedConceptSearchService.all(
- searchSettings.copy(embedId = Some("test.id2"))
- )
+ val search1 =
+ publishedConceptSearchService
+ .all(searchSettings.copy(embedId = Some("test.url2")))
+ .get
+ val search2 =
+ publishedConceptSearchService
+ .all(searchSettings.copy(embedId = Some("test.id2")))
+ .get
search1.totalCount should be(1)
search1.results.head.id should be(10)
@@ -636,48 +657,58 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
}
test("That search on exactTitleMatch only matches exact") {
- val Success(search1) =
- publishedConceptSearchService.matchingQuery(
- "\"urelatert noe noe\"",
- searchSettings.copy(fallback = true, exactTitleMatch = true)
- )
+ val search1 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "\"urelatert noe noe\"",
+ searchSettings.copy(fallback = true, exactTitleMatch = true)
+ )
+ .get
search1.totalCount should be(0)
- val Success(search2) =
- publishedConceptSearchService.matchingQuery(
- "et urelatert noe noe",
- searchSettings.copy(fallback = true, exactTitleMatch = true)
- )
+ val search2 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "et urelatert noe noe",
+ searchSettings.copy(fallback = true, exactTitleMatch = true)
+ )
+ .get
search2.totalCount should be(0)
- val Success(search3) =
- publishedConceptSearchService.matchingQuery(
- "\"englando\"",
- searchSettings.copy(fallback = true, exactTitleMatch = true)
- )
+ val search3 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "\"englando\"",
+ searchSettings.copy(fallback = true, exactTitleMatch = true)
+ )
+ .get
search3.totalCount should be(1)
search3.results.head.id should be(11)
- val Success(search4) =
- publishedConceptSearchService.matchingQuery(
- "unrelated",
- searchSettings.copy(fallback = true, exactTitleMatch = true)
- )
+ val search4 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "unrelated",
+ searchSettings.copy(fallback = true, exactTitleMatch = true)
+ )
+ .get
search4.totalCount should be(1)
search4.results.head.id should be(10)
- val Success(search5) =
- publishedConceptSearchService.matchingQuery(
- "batmen",
- searchSettings.copy(fallback = true, exactTitleMatch = true)
- )
+ val search5 =
+ publishedConceptSearchService
+ .matchingQuery(
+ "batmen",
+ searchSettings.copy(fallback = true, exactTitleMatch = true)
+ )
+ .get
search5.totalCount should be(0)
}
test("search results should return copyright info") {
- val Success(search) =
- publishedConceptSearchService.matchingQuery("hulk", searchSettings.copy(sort = Sort.ByRelevanceDesc))
+ val search =
+ publishedConceptSearchService.matchingQuery("hulk", searchSettings.copy(sort = Sort.ByRelevanceDesc)).get
val hits = search.results
hits.map(_.id) should equal(Seq(5))
hits.head.copyright.head.origin should be(Some("Gotham City"))
@@ -686,17 +717,17 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
test("filtering on conceptType should work as expected") {
{
- val Success(search) = publishedConceptSearchService.all(searchSettings.copy(conceptType = Some("concept")))
+ val search = publishedConceptSearchService.all(searchSettings.copy(conceptType = Some("concept"))).get
search.totalCount should be(10)
}
{
- val Success(search) = publishedConceptSearchService.all(searchSettings.copy(conceptType = Some("gloss")))
+ val search = publishedConceptSearchService.all(searchSettings.copy(conceptType = Some("gloss"))).get
search.totalCount should be(1)
}
}
test("That searching for gloss data matches") {
- val Success(search) = publishedConceptSearchService.matchingQuery("glossorama", searchSettings)
+ val search = publishedConceptSearchService.matchingQuery("glossorama", searchSettings).get
search.totalCount should be(1)
search.results.head.id should be(12)
}
@@ -715,7 +746,7 @@ class PublishedConceptSearchServiceTest extends ElasticsearchIntegrationSuite wi
)
)
- val Success(result) = publishedConceptSearchService.all(settings)
+ val result = publishedConceptSearchService.all(settings).get
result.aggregations should be(Seq(expectedAggregations))
}
diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/validation/ContentValidatorTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/validation/ContentValidatorTest.scala
index c51d107206..9cd2b92130 100644
--- a/concept-api/src/test/scala/no/ndla/conceptapi/validation/ContentValidatorTest.scala
+++ b/concept-api/src/test/scala/no/ndla/conceptapi/validation/ContentValidatorTest.scala
@@ -17,8 +17,8 @@ import no.ndla.conceptapi.{TestData, TestEnvironment, UnitSuite}
import scala.util.{Failure, Success}
class ContentValidatorTest extends UnitSuite with TestEnvironment {
- override val converterService = new ConverterService
- override val contentValidator = new ContentValidator
+ override lazy val converterService = new ConverterService
+ override lazy val contentValidator = new ContentValidator
val baseConcept: Concept = TestData.domainConcept.copy(responsible = Some(Responsible("hei", TestData.today)))
@@ -26,7 +26,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
val conceptToValidate = baseConcept.copy(title = Seq())
- val Failure(exception: ValidationException) = contentValidator.validateConcept(conceptToValidate)
+ val Failure(exception: ValidationException) = contentValidator.validateConcept(conceptToValidate): @unchecked
exception.errors should be(
Seq(ValidationMessage("title", "The field does not have any entries, whereas at least one is required."))
)
@@ -58,7 +58,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
val concept = baseConcept.copy(copyright =
Some(DraftCopyright(Some("CC-BY-4.0"), None, Seq(), Seq(), Seq(), None, None, false))
)
- val Failure(exception: ValidationException) = contentValidator.validateConcept(concept)
+ val Failure(exception: ValidationException) = contentValidator.validateConcept(concept): @unchecked
exception.errors should be(
Seq(ValidationMessage("license.license", "At least one copyright holder is required when license is CC-BY-4.0"))
)
diff --git a/database/src/main/scala/no/ndla/database/DBMigrator.scala b/database/src/main/scala/no/ndla/database/DBMigrator.scala
index 48d1bc4345..6cb0fd3c74 100644
--- a/database/src/main/scala/no/ndla/database/DBMigrator.scala
+++ b/database/src/main/scala/no/ndla/database/DBMigrator.scala
@@ -18,7 +18,7 @@ import scala.jdk.CollectionConverters.*
trait DBMigrator {
this: DataSource & HasDatabaseProps =>
- val migrator: DBMigrator
+ lazy val migrator: DBMigrator
case class DBMigrator(migrations: JavaMigration*) extends StrictLogging {
private def logMigrationResult(result: MigrateResult): Unit = {
diff --git a/database/src/main/scala/no/ndla/database/DBUtility.scala b/database/src/main/scala/no/ndla/database/DBUtility.scala
index 87fbb41aef..9325d5cfdc 100644
--- a/database/src/main/scala/no/ndla/database/DBUtility.scala
+++ b/database/src/main/scala/no/ndla/database/DBUtility.scala
@@ -18,7 +18,7 @@ import scalikejdbc.*
import scala.util.{Failure, Success, Try}
trait DBUtility {
- val DBUtil: DBUtility
+ lazy val DBUtil: DBUtility
class DBUtility extends StrictLogging {
def rollbackOnFailure[T](func: DBSession => Try[T]): Try[T] = {
try {
diff --git a/database/src/main/scala/no/ndla/database/DataSource.scala b/database/src/main/scala/no/ndla/database/DataSource.scala
index f670835572..75c790af09 100644
--- a/database/src/main/scala/no/ndla/database/DataSource.scala
+++ b/database/src/main/scala/no/ndla/database/DataSource.scala
@@ -15,19 +15,17 @@ import scalikejdbc.{ConnectionPool, DataSourceConnectionPool}
trait DataSource {
this: HasDatabaseProps =>
- import props.*
-
- val dataSource: HikariDataSource
+ lazy val dataSource: HikariDataSource
object DataSource extends StrictLogging {
def getHikariDataSource: HikariDataSource = {
val dataSourceConfig = new HikariConfig()
- dataSourceConfig.setUsername(MetaUserName)
- dataSourceConfig.setPassword(MetaPassword)
- dataSourceConfig.setJdbcUrl(s"jdbc:postgresql://$MetaServer:$MetaPort/$MetaResource")
+ dataSourceConfig.setUsername(props.MetaUserName)
+ dataSourceConfig.setPassword(props.MetaPassword)
+ dataSourceConfig.setJdbcUrl(s"jdbc:postgresql://${props.MetaServer}:${props.MetaPort}/${props.MetaResource}")
dataSourceConfig.setDriverClassName("org.postgresql.Driver")
- dataSourceConfig.setSchema(MetaSchema)
- dataSourceConfig.setMaximumPoolSize(MetaMaxConnections)
+ dataSourceConfig.setSchema(props.MetaSchema)
+ dataSourceConfig.setMaximumPoolSize(props.MetaMaxConnections)
new HikariDataSource(dataSourceConfig)
}
diff --git a/database/src/main/scala/no/ndla/database/DatabaseProps.scala b/database/src/main/scala/no/ndla/database/DatabaseProps.scala
index bc50aa804c..cc2b4bb5a3 100644
--- a/database/src/main/scala/no/ndla/database/DatabaseProps.scala
+++ b/database/src/main/scala/no/ndla/database/DatabaseProps.scala
@@ -28,5 +28,5 @@ trait DatabaseProps {
}
trait HasDatabaseProps {
- val props: DatabaseProps
+ lazy val props: DatabaseProps
}
diff --git a/database/src/main/scala/no/ndla/database/TableMigration.scala b/database/src/main/scala/no/ndla/database/TableMigration.scala
index 7483902127..1501d24291 100644
--- a/database/src/main/scala/no/ndla/database/TableMigration.scala
+++ b/database/src/main/scala/no/ndla/database/TableMigration.scala
@@ -13,7 +13,7 @@ import scalikejdbc.*
abstract class TableMigration[ROW_DATA] extends BaseJavaMigration {
val tableName: String
- val whereClause: SQLSyntax
+ lazy val whereClause: SQLSyntax
val chunkSize: Int = 1000
def extractRowData(rs: WrappedResultSet): ROW_DATA
def updateRow(rowData: ROW_DATA)(implicit session: DBSession): Int
@@ -33,7 +33,7 @@ abstract class TableMigration[ROW_DATA] extends BaseJavaMigration {
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
- .withinTx { session => migrateRows(session) }
+ .withinTx { session => migrateRows(using session) }
private def migrateRows(implicit session: DBSession): Unit = {
val count = countAllRows.get
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/ComponentRegistry.scala b/draft-api/src/main/scala/no/ndla/draftapi/ComponentRegistry.scala
index 16bd5cb758..fad5a3e0ba 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/ComponentRegistry.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/ComponentRegistry.scala
@@ -88,8 +88,8 @@ class ComponentRegistry(properties: DraftApiProperties)
with SearchLanguage
with V57__MigrateSavedSearch
with V66__SetHideBylineForImagesNotCopyrighted {
- override val props: DraftApiProperties = properties
- override val migrator: DBMigrator = DBMigrator(
+ override lazy val props: DraftApiProperties = properties
+ override lazy val migrator: DBMigrator = DBMigrator(
new R__RemoveEmptyStringLanguageFields(props),
new R__RemoveStatusPublishedArticles(props),
new R__SetArticleLanguageFromTaxonomy(props),
@@ -101,50 +101,50 @@ class ComponentRegistry(properties: DraftApiProperties)
new V66__SetHideBylineForImagesNotCopyrighted
)
override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
- override val DBUtil: DBUtility = new DBUtility
+ override lazy val DBUtil: DBUtility = new DBUtility
- lazy val draftRepository = new DraftRepository
- lazy val userDataRepository = new UserDataRepository
+ override lazy val draftRepository = new DraftRepository
+ override lazy val userDataRepository = new UserDataRepository
- lazy val articleSearchService = new ArticleSearchService
- lazy val articleIndexService = new ArticleIndexService
- lazy val tagSearchService = new TagSearchService
- lazy val tagIndexService = new TagIndexService
- lazy val grepCodesSearchService = new GrepCodesSearchService
- lazy val grepCodesIndexService = new GrepCodesIndexService
+ override lazy val articleSearchService = new ArticleSearchService
+ override lazy val articleIndexService = new ArticleIndexService
+ override lazy val tagSearchService = new TagSearchService
+ override lazy val tagIndexService = new TagIndexService
+ override lazy val grepCodesSearchService = new GrepCodesSearchService
+ override lazy val grepCodesIndexService = new GrepCodesIndexService
- lazy val converterService = new ConverterService
- lazy val contentValidator = new ContentValidator()
- lazy val importValidator = new ContentValidator()
+ override lazy val converterService = new ConverterService
+ override lazy val contentValidator = new ContentValidator()
+ override lazy val importValidator = new ContentValidator()
- lazy val ndlaClient = new NdlaClient
- lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
- lazy val searchConverterService = new SearchConverterService
- lazy val readService = new ReadService
- lazy val writeService = new WriteService
- lazy val reindexClient = new ReindexClient
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val readService = new ReadService
+ override lazy val writeService = new WriteService
+ override lazy val reindexClient = new ReindexClient
- lazy val fileStorage = new FileStorageService
+ override lazy val fileStorage = new FileStorageService
- lazy val s3Client = new NdlaS3Client(props.AttachmentStorageName, props.AttachmentStorageRegion)
+ override lazy val s3Client = new NdlaS3Client(props.AttachmentStorageName, props.AttachmentStorageRegion)
var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
- lazy val clock = new SystemClock
- lazy val uuidUtil = new UUIDUtil
+ override lazy val clock = new SystemClock
+ override lazy val uuidUtil = new UUIDUtil
- lazy val articleApiClient = new ArticleApiClient
- lazy val searchApiClient = new SearchApiClient
- lazy val taxonomyApiClient = new TaxonomyApiClient
- lazy val learningpathApiClient = new LearningpathApiClient
- lazy val h5pApiClient = new H5PApiClient
- lazy val imageApiClient = new ImageApiClient
+ override lazy val articleApiClient = new ArticleApiClient
+ override lazy val searchApiClient = new SearchApiClient
+ override lazy val taxonomyApiClient = new TaxonomyApiClient
+ override lazy val learningpathApiClient = new LearningpathApiClient
+ override lazy val h5pApiClient = new H5PApiClient
+ override lazy val imageApiClient = new ImageApiClient
- lazy val internController = new InternController
- lazy val draftController = new DraftController
- lazy val fileController = new FileController
- lazy val userDataController = new UserDataController
- lazy val healthController: TapirHealthController = new TapirHealthController
+ override lazy val internController = new InternController
+ override lazy val draftController = new DraftController
+ override lazy val fileController = new FileController
+ override lazy val userDataController = new UserDataController
+ override lazy val healthController: TapirHealthController = new TapirHealthController
val swagger = new SwaggerController(
List[TapirController](
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/DraftApiProperties.scala b/draft-api/src/main/scala/no/ndla/draftapi/DraftApiProperties.scala
index 4da9b7c5d2..46586d8f9f 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/DraftApiProperties.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/DraftApiProperties.scala
@@ -17,7 +17,7 @@ import no.ndla.validation.ResourceType
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: DraftApiProperties
+ lazy val props: DraftApiProperties
}
class DraftApiProperties extends BaseProps with DatabaseProps with StrictLogging {
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/caching/Memoize1.scala b/draft-api/src/main/scala/no/ndla/draftapi/caching/Memoize1.scala
index 7802002fd4..e46d92a38e 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/caching/Memoize1.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/caching/Memoize1.scala
@@ -35,7 +35,7 @@ private[caching] class Memoize[R](
val task = new Runnable {
def run(): Unit = renewCache()
}
- ex.scheduleAtFixedRate(task, 20, maxCacheAgeMs, TimeUnit.MILLISECONDS)
+ ex.scheduleAtFixedRate(task, 20, maxCacheAgeMs, TimeUnit.MILLISECONDS): Unit
}
def apply(): Option[R] = {
@@ -51,17 +51,15 @@ private[caching] class Memoize[R](
}
trait MemoizeHelpers {
this: Props =>
- import props.ApiClientsCacheAgeInMs
-
object Memoize {
def apply[R](f: () => R, shouldCacheResult: R => Boolean = (_: R) => true) =
- new Memoize(ApiClientsCacheAgeInMs, f, autoRefreshCache = false, shouldCacheResult)
+ new Memoize(props.ApiClientsCacheAgeInMs, f, autoRefreshCache = false, shouldCacheResult)
}
object MemoizeAutoRenew {
def apply[R](f: () => R, shouldCacheResult: R => Boolean = (_: R) => true) =
- new Memoize(ApiClientsCacheAgeInMs, f, autoRefreshCache = true, shouldCacheResult)
+ new Memoize(props.ApiClientsCacheAgeInMs, f, autoRefreshCache = true, shouldCacheResult)
}
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/controller/DraftController.scala b/draft-api/src/main/scala/no/ndla/draftapi/controller/DraftController.scala
index 9635ff06e5..447e348d8a 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/controller/DraftController.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/controller/DraftController.scala
@@ -9,7 +9,6 @@
package no.ndla.draftapi.controller
import cats.implicits.*
-import io.circe.generic.auto.*
import no.ndla.common.model.api.CommaSeparatedList.*
import no.ndla.common.model.api.{LanguageCode, LicenseDTO}
import no.ndla.common.model.domain.ArticleType
@@ -29,7 +28,6 @@ import no.ndla.network.tapir.auth.Permission.{ARTICLE_API_WRITE, DRAFT_API_WRITE
import no.ndla.network.tapir.{DynamicHeaders, TapirController}
import sttp.model.StatusCode
import sttp.tapir.*
-import sttp.tapir.generic.auto.*
import sttp.tapir.server.ServerEndpoint
import scala.util.{Failure, Success, Try}
@@ -37,10 +35,9 @@ import scala.util.{Failure, Success, Try}
trait DraftController {
this: ReadService & WriteService & ArticleSearchService & SearchConverterService & ConverterService &
ContentValidator & Props & ErrorHandling & TapirController =>
- val draftController: DraftController
+ lazy val draftController: DraftController
class DraftController extends TapirController {
- import props.{DefaultPageSize, InitialScrollContextKeywords}
override val serviceName: String = "drafts"
override val prefix: EndpointInput[Unit] = "draft-api" / "v1" / serviceName
@@ -72,7 +69,7 @@ trait DraftController {
.validate(Validator.min(1))
private val pageSize = query[Int]("page-size")
.description("The number of search hits to display for each page.")
- .default(DefaultPageSize)
+ .default(props.DefaultPageSize)
.validate(Validator.min(0))
private val sort = query[Option[String]]("sort").description(
"""The sorting used on results.
@@ -89,7 +86,7 @@ trait DraftController {
.description("Fallback to existing language if language is specified.")
.default(false)
private val scrollId = query[Option[String]]("search-context").description(
- s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${InitialScrollContextKeywords
+ s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${props.InitialScrollContextKeywords
.mkString("[", ",", "]")}.
|When scrolling, the parameters from the initial search is used, except in the case of '${this.language.name}' and '${this.fallback.name}'.
|This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after ${props.ElasticSearchScrollKeepAlive}).
@@ -136,7 +133,7 @@ trait DraftController {
orFunction: => Try[(ArticleSearchResultDTO, DynamicHeaders)]
): Try[(ArticleSearchResultDTO, DynamicHeaders)] = {
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
articleSearchService.scroll(scroll, language.code) match {
case Success(scrollResult) =>
val body = searchConverterService.asApiSearchResult(scrollResult)
@@ -228,8 +225,8 @@ trait DraftController {
.in(pageSize)
.in(pageNo)
.errorOut(errorOutputsFor(401, 403))
- .requirePermission(DRAFT_API_WRITE)
.out(jsonBody[GrepCodesSearchResultDTO])
+ .requirePermission(DRAFT_API_WRITE)
.serverLogicPure { _ =>
{ case (maybeQuery, pageSize, pageNo) =>
val query = maybeQuery.getOrElse("")
@@ -274,7 +271,7 @@ trait DraftController {
val sort = Sort.valueOf(maybeSort.getOrElse(""))
val idList = articleIds.values
val articleTypesFilter = articleTypes.values
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
maybeQuery,
@@ -308,13 +305,13 @@ trait DraftController {
val query = searchParams.query
val sort = searchParams.sort
val license = searchParams.license
- val pageSize = searchParams.pageSize.getOrElse(DefaultPageSize)
+ val pageSize = searchParams.pageSize.getOrElse(props.DefaultPageSize)
val page = searchParams.page.getOrElse(1)
val idList = searchParams.ids
val articleTypesFilter = searchParams.articleTypes
val fallback = searchParams.fallback.getOrElse(false)
val grepCodes = searchParams.grepCodes
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query,
@@ -357,14 +354,14 @@ trait DraftController {
.in("ids")
.summary("Fetch articles that matches ids parameter.")
.description("Returns articles that matches ids parameter.")
- .out(jsonBody[Seq[ArticleDTO]])
- .errorOut(errorOutputsFor(400, 401, 403))
- .requirePermission(DRAFT_API_WRITE)
.in(articleIds)
.in(fallback)
.in(language)
.in(pageSize)
.in(pageNo)
+ .out(jsonBody[Seq[ArticleDTO]])
+ .errorOut(errorOutputsFor(400, 401, 403))
+ .requirePermission(DRAFT_API_WRITE)
.serverLogicPure { _ =>
{ case (articleIds, fallback, language, pageSize, page) =>
readService
@@ -375,7 +372,6 @@ trait DraftController {
page.toLong,
pageSize.toLong
)
-
}
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/controller/FileController.scala b/draft-api/src/main/scala/no/ndla/draftapi/controller/FileController.scala
index e4dd4c440b..21ba781a7f 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/controller/FileController.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/controller/FileController.scala
@@ -19,10 +19,8 @@ import no.ndla.network.tapir.auth.Permission.DRAFT_API_WRITE
import sttp.model.Part
import sttp.tapir.EndpointInput
import sttp.tapir.*
-import io.circe.generic.auto.*
import no.ndla.common.model.domain
import no.ndla.network.tapir.TapirController
-import sttp.tapir.generic.auto.*
import sttp.tapir.server.ServerEndpoint
import java.io.File
@@ -30,7 +28,7 @@ import scala.util.{Failure, Success, Try}
trait FileController {
this: WriteService & ErrorHandling & Props & TapirController =>
- val fileController: FileController
+ lazy val fileController: FileController
class FileController extends TapirController {
override val serviceName: String = "files"
@@ -43,8 +41,6 @@ trait FileController {
deleteFile
)
- case class FileForm(file: Part[File])
-
def doWithStream[T](filePart: Part[File])(f: domain.UploadedFile => Try[T]): Try[T] = {
val file = domain.UploadedFile.fromFilePart(filePart)
if (file.fileSize > props.multipartFileSizeThresholdBytes) Failure(FileTooBigException())
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/controller/InternController.scala b/draft-api/src/main/scala/no/ndla/draftapi/controller/InternController.scala
index c7c81e4d15..6a1973b6f5 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/controller/InternController.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/controller/InternController.scala
@@ -28,9 +28,7 @@ import no.ndla.network.tapir.auth.TokenUser
import scalikejdbc.ReadOnlyAutoSession
import sttp.model.StatusCode
import sttp.tapir.server.ServerEndpoint
-import io.circe.generic.auto.*
import no.ndla.search.model.domain.ReindexResult
-import sttp.tapir.generic.auto.*
import java.util.concurrent.{Executors, TimeUnit}
import scala.annotation.{tailrec, unused}
@@ -41,11 +39,9 @@ import scala.util.{Failure, Success, Try}
trait InternController {
this: ReadService & WriteService & ConverterService & DraftRepository & IndexService & ArticleIndexService &
TagIndexService & GrepCodesIndexService & ArticleApiClient & TapirController & Props =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController with StrictLogging {
- import props.{DraftSearchIndex, DraftTagSearchIndex}
-
override val prefix: EndpointInput[Unit] = "intern"
override val enableSwagger = false
private val stringInternalServerError = statusCode(StatusCode.InternalServerError).and(stringBody)
@@ -116,8 +112,8 @@ trait InternController {
def pluralIndex(n: Int) = if (n == 1) "1 index" else s"$n indexes"
val indexes = for {
- articleIndex <- Future { articleIndexService.findAllIndexes(DraftSearchIndex) }
- tagIndex <- Future { tagIndexService.findAllIndexes(DraftTagSearchIndex) }
+ articleIndex <- Future { articleIndexService.findAllIndexes(props.DraftSearchIndex) }
+ tagIndex <- Future { tagIndexService.findAllIndexes(props.DraftTagSearchIndex) }
} yield (articleIndex, tagIndex)
val deleteResults: Seq[Try[?]] = Await.result(indexes, Duration(10, TimeUnit.MINUTES)) match {
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/controller/UserDataController.scala b/draft-api/src/main/scala/no/ndla/draftapi/controller/UserDataController.scala
index 920f998526..3d020f849e 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/controller/UserDataController.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/controller/UserDataController.scala
@@ -8,7 +8,6 @@
package no.ndla.draftapi.controller
-import io.circe.generic.auto.*
import no.ndla.draftapi.model.api.{ErrorHandling, UpdatedUserDataDTO, UserDataDTO}
import no.ndla.draftapi.service.{ReadService, WriteService}
import no.ndla.network.tapir.NoNullJsonPrinter.*
@@ -16,12 +15,11 @@ import no.ndla.network.tapir.TapirController
import no.ndla.network.tapir.TapirUtil.errorOutputsFor
import no.ndla.network.tapir.auth.Permission.DRAFT_API_WRITE
import sttp.tapir.*
-import sttp.tapir.generic.auto.*
import sttp.tapir.server.ServerEndpoint
trait UserDataController {
this: ReadService & WriteService & ErrorHandling & TapirController =>
- val userDataController: UserDataController
+ lazy val userDataController: UserDataController
class UserDataController extends TapirController {
override val serviceName: String = "user-data"
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/db/migration/V69__FixContributorTypes.scala b/draft-api/src/main/scala/no/ndla/draftapi/db/migration/V69__FixContributorTypes.scala
index c3f4a2660b..2fd1e2c031 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/db/migration/V69__FixContributorTypes.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/db/migration/V69__FixContributorTypes.scala
@@ -9,7 +9,6 @@
package no.ndla.draftapi.db.migration
import io.circe.syntax.EncoderOps
-import io.circe.generic.auto.*
import io.circe.{ACursor, parser}
import no.ndla.common.model.domain.{Author, ContributorType}
import no.ndla.database.DocumentMigration
@@ -57,3 +56,9 @@ class V69__FixContributorTypes extends DocumentMigration {
}
case class OldAuthor(`type`: String, name: String)
+object OldAuthor {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ implicit val encoder: Encoder[OldAuthor] = deriveEncoder
+ implicit val decoder: Decoder[OldAuthor] = deriveDecoder
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveEmptyStringLanguageFields.scala b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveEmptyStringLanguageFields.scala
index 55b595b040..2bf9bb19d9 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveEmptyStringLanguageFields.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveEmptyStringLanguageFields.scala
@@ -12,7 +12,7 @@ import no.ndla.draftapi.{DraftApiProperties, Props}
import org.flywaydb.core.api.migration.{BaseJavaMigration, Context}
class R__RemoveEmptyStringLanguageFields(properties: DraftApiProperties) extends BaseJavaMigration with Props {
- override val props: DraftApiProperties = properties
+ override lazy val props: DraftApiProperties = properties
override def getChecksum: Integer = 1
override def migrate(context: Context): Unit = {}
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveStatusPublishedArticles.scala b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveStatusPublishedArticles.scala
index d9124b8f43..3770e7fbea 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveStatusPublishedArticles.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__RemoveStatusPublishedArticles.scala
@@ -12,7 +12,7 @@ import no.ndla.draftapi.{DraftApiProperties, Props}
import org.flywaydb.core.api.migration.{BaseJavaMigration, Context}
class R__RemoveStatusPublishedArticles(properties: DraftApiProperties) extends BaseJavaMigration with Props {
- override val props: DraftApiProperties = properties
+ override lazy val props: DraftApiProperties = properties
override def getChecksum: Integer = 0
override def migrate(context: Context): Unit = {}
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala
index 952985dc89..6f8e646ca6 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleLanguageFromTaxonomy.scala
@@ -12,7 +12,7 @@ import no.ndla.draftapi.{DraftApiProperties, Props}
import org.flywaydb.core.api.migration.{BaseJavaMigration, Context}
class R__SetArticleLanguageFromTaxonomy(properties: DraftApiProperties) extends BaseJavaMigration with Props {
- override val props: DraftApiProperties = properties
+ override lazy val props: DraftApiProperties = properties
override def getChecksum: Integer = 1
override def migrate(context: Context): Unit = {}
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleTypeFromTaxonomy.scala b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleTypeFromTaxonomy.scala
index 90ac80ade6..c32be34303 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleTypeFromTaxonomy.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/R__SetArticleTypeFromTaxonomy.scala
@@ -12,7 +12,7 @@ import no.ndla.draftapi.{DraftApiProperties, Props}
import org.flywaydb.core.api.migration.{BaseJavaMigration, Context}
class R__SetArticleTypeFromTaxonomy(properties: DraftApiProperties) extends BaseJavaMigration with Props {
- override val props: DraftApiProperties = properties
+ override lazy val props: DraftApiProperties = properties
override def getChecksum: Integer = 0
override def migrate(context: Context): Unit = {}
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala
index 1ffa5f4515..1637d21370 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V33__ConvertLanguageUnknown.scala
@@ -12,6 +12,6 @@ import no.ndla.draftapi.{DraftApiProperties, Props}
import org.flywaydb.core.api.migration.{BaseJavaMigration, Context}
class V33__ConvertLanguageUnknown(properties: DraftApiProperties) extends BaseJavaMigration with Props {
- override val props: DraftApiProperties = properties
+ override lazy val props: DraftApiProperties = properties
override def migrate(context: Context): Unit = {}
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V57__MigrateSavedSearch.scala b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V57__MigrateSavedSearch.scala
index fefb5d5b78..6bdbaeedc6 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V57__MigrateSavedSearch.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/db/migrationwithdependencies/V57__MigrateSavedSearch.scala
@@ -12,7 +12,7 @@ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.syntax.EncoderOps
import io.circe.{Decoder, Encoder, parser}
import no.ndla.common.CirceUtil
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.draftapi.integration.{Node, TaxonomyApiClient}
import no.ndla.draftapi.model.api
import no.ndla.draftapi.Props
@@ -31,11 +31,9 @@ import scala.concurrent.duration.DurationInt
trait V57__MigrateSavedSearch {
this: TaxonomyApiClient with NdlaClient with Props =>
- import props.{TaxonomyUrl, TaxonomyVersionHeader, Environment, auth0ManagementClientId, auth0ManagementClientSecret}
-
class V57__MigrateSavedSearch extends BaseJavaMigration {
- val auth0Domain = AuthUser.getAuth0HostForEnv(Environment)
+ val auth0Domain = AuthUser.getAuth0HostForEnv(props.Environment)
val managementUri = uri"https://$auth0Domain/oauth/token"
val auth0Audience = s"https://$auth0Domain/api/v2/"
@@ -63,8 +61,8 @@ trait V57__MigrateSavedSearch {
def getManagementToken(): Try[String] = {
val inputBody = GetTokenBody(
- client_id = auth0ManagementClientId,
- client_secret = auth0ManagementClientSecret,
+ client_id = props.auth0ManagementClientId,
+ client_secret = props.auth0ManagementClientSecret,
audience = auth0Audience,
grant_type = "client_credentials"
)
@@ -94,7 +92,7 @@ trait V57__MigrateSavedSearch {
}
}
- def getEditors(managementToken: String): Try[Map[String, Auth0UserObject]] = {
+ def getEditors(managementToken: String): Try[Map[String, Auth0UserObject]] = permitTry {
implicit val ec: ExecutionContextExecutorService =
ExecutionContext.fromExecutorService(Executors.newWorkStealingPool(10))
val firstPage = fetchAuth0UsersByQuery(managementToken, 0).?
@@ -117,7 +115,7 @@ trait V57__MigrateSavedSearch {
lazy val managementToken = getManagementToken().get
lazy val auth0Editors = getEditors(managementToken).get
- private val TaxonomyApiEndpoint = s"$TaxonomyUrl/v1"
+ private val TaxonomyApiEndpoint = s"${props.TaxonomyUrl}/v1"
private val taxonomyTimeout = 20.seconds
def countAllRows(implicit session: DBSession): Option[Long] = {
@@ -165,7 +163,7 @@ trait V57__MigrateSavedSearch {
quickRequest
.get(uri"$url".withParams(params: _*))
.readTimeout(taxonomyTimeout)
- .header(TaxonomyVersionHeader, TaxonomyData.get),
+ .header(props.TaxonomyVersionHeader, TaxonomyData.get),
None
)
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/integration/ArticleApiClient.scala b/draft-api/src/main/scala/no/ndla/draftapi/integration/ArticleApiClient.scala
index fe535e2a64..fb9a091f1a 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/integration/ArticleApiClient.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/integration/ArticleApiClient.scala
@@ -39,7 +39,7 @@ import scala.util.{Failure, Try}
trait ArticleApiClient {
this: NdlaClient & ConverterService & Props =>
- val articleApiClient: ArticleApiClient
+ lazy val articleApiClient: ArticleApiClient
class ArticleApiClient(ArticleBaseUrl: String = s"http://${props.ArticleApiHost}") {
private val InternalEndpoint = s"$ArticleBaseUrl/intern"
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/integration/H5PApiClient.scala b/draft-api/src/main/scala/no/ndla/draftapi/integration/H5PApiClient.scala
index 7c04a06c08..0810970f25 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/integration/H5PApiClient.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/integration/H5PApiClient.scala
@@ -25,7 +25,7 @@ import scala.util.{Failure, Success, Try}
trait H5PApiClient {
this: NdlaClient with Props =>
- val h5pApiClient: H5PApiClient
+ lazy val h5pApiClient: H5PApiClient
class H5PApiClient extends StrictLogging {
private val H5PApi = s"${props.H5PAddress}/v1"
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/integration/ImageApiClient.scala b/draft-api/src/main/scala/no/ndla/draftapi/integration/ImageApiClient.scala
index e364f4f36e..bdd2fefa3f 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/integration/ImageApiClient.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/integration/ImageApiClient.scala
@@ -20,7 +20,7 @@ import scala.util.Try
trait ImageApiClient {
this: NdlaClient & ConverterService & Props =>
- val imageApiClient: ImageApiClient
+ lazy val imageApiClient: ImageApiClient
class ImageApiClient {
private val Endpoint = s"http://${props.ImageApiHost}/image-api/v3/images"
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/integration/LearningpathApiClient.scala b/draft-api/src/main/scala/no/ndla/draftapi/integration/LearningpathApiClient.scala
index 37d8d29256..f325d89875 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/integration/LearningpathApiClient.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/integration/LearningpathApiClient.scala
@@ -21,7 +21,7 @@ import scala.util.Try
trait LearningpathApiClient {
this: NdlaClient with ConverterService with Props =>
- val learningpathApiClient: LearningpathApiClient
+ lazy val learningpathApiClient: LearningpathApiClient
class LearningpathApiClient {
private val Endpoint = s"http://${props.LearningpathApiHost}/learningpath-api/v2/learningpaths"
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/integration/ReindexClient.scala b/draft-api/src/main/scala/no/ndla/draftapi/integration/ReindexClient.scala
index da407462b3..b63c3fc814 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/integration/ReindexClient.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/integration/ReindexClient.scala
@@ -17,28 +17,26 @@ import sttp.client3.quick._
trait ReindexClient {
this: Props =>
- val reindexClient: ReindexClient
+ lazy val reindexClient: ReindexClient
class ReindexClient extends StrictLogging {
- import props.internalApiUrls
-
private def reindexArticles() = {
- val req = quickRequest.post(uri"${internalApiUrls("article-api")}/index")
+ val req = quickRequest.post(uri"${props.internalApiUrls("article-api")}/index")
simpleHttpClient.send(req)
}
private def reindexAudios() = {
- val req = quickRequest.post(uri"${internalApiUrls("audio-api")}/index")
+ val req = quickRequest.post(uri"${props.internalApiUrls("audio-api")}/index")
simpleHttpClient.send(req)
}
private def reindexDrafts() = {
- val req = quickRequest.post(uri"${internalApiUrls("draft-api")}/index")
+ val req = quickRequest.post(uri"${props.internalApiUrls("draft-api")}/index")
simpleHttpClient.send(req)
}
private def reindexImages() = {
- val req = quickRequest.post(uri"${internalApiUrls("image-api")}/index")
+ val req = quickRequest.post(uri"${props.internalApiUrls("image-api")}/index")
simpleHttpClient.send(req)
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/integration/TaxonomyApiClient.scala b/draft-api/src/main/scala/no/ndla/draftapi/integration/TaxonomyApiClient.scala
index 9a4421cc0a..b4b8f2f702 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/integration/TaxonomyApiClient.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/integration/TaxonomyApiClient.scala
@@ -28,11 +28,10 @@ import scala.util.{Failure, Success, Try}
trait TaxonomyApiClient {
this: NdlaClient with Props =>
- val taxonomyApiClient: TaxonomyApiClient
- import props.{DefaultLanguage, TaxonomyUrl, TaxonomyVersionHeader}
+ lazy val taxonomyApiClient: TaxonomyApiClient
class TaxonomyApiClient extends StrictLogging {
- private val TaxonomyApiEndpoint = s"$TaxonomyUrl/v1"
+ private val TaxonomyApiEndpoint = s"${props.TaxonomyUrl}/v1"
private val taxonomyTimeout = 20.seconds
def updateTaxonomyIfExists(articleId: Long, article: Draft, user: TokenUser): Try[Long] = {
@@ -54,7 +53,7 @@ trait TaxonomyApiClient {
* List of Resources or Topics that were updated if none failed.
*/
private def updateTaxonomy(nodes: Seq[Node], titles: Seq[Title], user: TokenUser): Try[List[Node]] = {
- Language.findByLanguageOrBestEffort(titles, DefaultLanguage) match {
+ Language.findByLanguageOrBestEffort(titles, props.DefaultLanguage) match {
case Some(title) =>
val updated = nodes.map(updateTitleAndTranslations(_, title, titles, user))
updated
@@ -147,7 +146,7 @@ trait TaxonomyApiClient {
quickRequest
.get(uri"$url".withParams(params: _*))
.readTimeout(taxonomyTimeout)
- .header(TaxonomyVersionHeader, TaxonomyData.get),
+ .header(props.TaxonomyVersionHeader, TaxonomyData.get),
None
)
}
@@ -183,7 +182,7 @@ trait TaxonomyApiClient {
.put(uri)
.body(CirceUtil.toJsonString(data))
.readTimeout(taxonomyTimeout)
- .header(TaxonomyVersionHeader, TaxonomyData.get)
+ .header(props.TaxonomyVersionHeader, TaxonomyData.get)
.header("Content-Type", "application/json", replaceExisting = true)
ndlaClient.fetchRawWithForwardedAuth(request, Some(user)) match {
case Success(_) => Success(data)
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddMultipleNotesDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddMultipleNotesDTO.scala
index 191028b145..49d3798bbf 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddMultipleNotesDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddMultipleNotesDTO.scala
@@ -15,3 +15,13 @@ case class AddMultipleNotesDTO(
@description("Objects for which notes should be added to which drafts")
data: List[AddNoteDTO]
)
+
+object AddMultipleNotesDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+
+ implicit val encoder: Encoder[AddMultipleNotesDTO] = deriveEncoder
+ implicit val decoder: Decoder[AddMultipleNotesDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[AddMultipleNotesDTO] = sttp.tapir.Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddNoteDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddNoteDTO.scala
index aa328f3d67..3919a15ffa 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddNoteDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/AddNoteDTO.scala
@@ -17,3 +17,13 @@ case class AddNoteDTO(
@description("Notes to add to the draft")
notes: List[String]
)
+
+object AddNoteDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+
+ implicit val encoder: Encoder[AddNoteDTO] = deriveEncoder
+ implicit val decoder: Decoder[AddNoteDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[AddNoteDTO] = sttp.tapir.Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleContentDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleContentDTO.scala
index 50596f06d8..ccf45ce00b 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleContentDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleContentDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.draftapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
@description("The content of the article in the specified language")
case class ArticleContentDTO(
@@ -21,4 +22,5 @@ case class ArticleContentDTO(
object ArticleContentDTO {
implicit def encoder: Encoder[ArticleContentDTO] = deriveEncoder
implicit def decoder: Decoder[ArticleContentDTO] = deriveDecoder
+ implicit def schema: Schema[ArticleContentDTO] = Schema.derived[ArticleContentDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDTO.scala
index f631f294a6..29328260af 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDTO.scala
@@ -22,50 +22,86 @@ import no.ndla.common.model.api.{
RevisionMetaDTO
}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
import no.ndla.common.model.domain.Priority
-// format: off
@description("Information about the article")
case class ArticleDTO(
- @description("The unique id of the article") id: Long,
- @description("Link to article on old platform") oldNdlaUrl: Option[String],
- @description("The revision number for the article") revision: Int,
- @description("The status of this article") status: StatusDTO,
- @description("Available titles for the article") title: Option[ArticleTitleDTO],
- @description("The content of the article in available languages") content: Option[ArticleContentDTO],
- @description("Describes the copyright information for the article") copyright: Option[DraftCopyrightDTO],
- @description("Searchable tags for the article") tags: Option[ArticleTagDTO],
- @description("Required libraries in order to render the article") requiredLibraries: Seq[RequiredLibraryDTO],
- @description("A visual element article") visualElement: Option[VisualElementDTO],
- @description("An introduction for the article") introduction: Option[ArticleIntroductionDTO],
- @description("Meta description for the article") metaDescription: Option[ArticleMetaDescriptionDTO],
- @description("Meta image for the article") metaImage: Option[ArticleMetaImageDTO],
- @description("When the article was created") created: NDLADate,
- @description("When the article was last updated") updated: NDLADate,
- @description("By whom the article was last updated") updatedBy: String,
- @description("When the article was last published") published: NDLADate,
- @description("The type of article this is. Possible values are frontpage-article, standard, topic-article") articleType: String,
- @description("The languages this article supports") supportedLanguages: Seq[String],
- @description("The notes for this article draft") notes: Seq[EditorNoteDTO],
- @description("The labels attached to this article; meant for editors.") editorLabels: Seq[String],
- @description("A list of codes from GREP API connected to the article") grepCodes: Seq[String],
- @description("A list of conceptIds connected to the article") conceptIds: Seq[Long],
- @description("Value that dictates who gets to see the article. Possible values are: everyone/teacher") availability: String,
- @description("A list of content related to the article") relatedContent: Seq[RelatedContent],
- @description("A list of revisions planned for the article") revisions: Seq[RevisionMetaDTO],
- @description("Object with data representing the editor responsible for this article") responsible: Option[ResponsibleDTO],
- @description("The path to the frontpage article") slug: Option[String],
- @description("Information about comments attached to the article") comments: Seq[CommentDTO],
- @description("If the article should be prioritized. Possible values are prioritized, on-hold, unspecified") priority: Priority,
- @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]
+ @description("The unique id of the article")
+ id: Long,
+ @description("Link to article on old platform")
+ oldNdlaUrl: Option[String],
+ @description("The revision number for the article")
+ revision: Int,
+ @description("The status of this article")
+ status: StatusDTO,
+ @description("Available titles for the article")
+ title: Option[ArticleTitleDTO],
+ @description("The content of the article in available languages")
+ content: Option[ArticleContentDTO],
+ @description("Describes the copyright information for the article")
+ copyright: Option[DraftCopyrightDTO],
+ @description("Searchable tags for the article")
+ tags: Option[ArticleTagDTO],
+ @description("Required libraries in order to render the article")
+ requiredLibraries: Seq[RequiredLibraryDTO],
+ @description("A visual element article")
+ visualElement: Option[VisualElementDTO],
+ @description("An introduction for the article")
+ introduction: Option[ArticleIntroductionDTO],
+ @description("Meta description for the article")
+ metaDescription: Option[ArticleMetaDescriptionDTO],
+ @description("Meta image for the article")
+ metaImage: Option[ArticleMetaImageDTO],
+ @description("When the article was created")
+ created: NDLADate,
+ @description("When the article was last updated")
+ updated: NDLADate,
+ @description("By whom the article was last updated")
+ updatedBy: String,
+ @description("When the article was last published")
+ published: NDLADate,
+ @description("The type of article this is. Possible values are frontpage-article, standard, topic-article")
+ articleType: String,
+ @description("The languages this article supports")
+ supportedLanguages: Seq[String],
+ @description("The notes for this article draft")
+ notes: Seq[EditorNoteDTO],
+ @description("The labels attached to this article; meant for editors.")
+ editorLabels: Seq[String],
+ @description("A list of codes from GREP API connected to the article")
+ grepCodes: Seq[String],
+ @description("A list of conceptIds connected to the article")
+ conceptIds: Seq[Long],
+ @description("Value that dictates who gets to see the article. Possible values are: everyone/teacher")
+ availability: String,
+ @description("A list of content related to the article")
+ relatedContent: Seq[RelatedContent],
+ @description("A list of revisions planned for the article")
+ revisions: Seq[RevisionMetaDTO],
+ @description("Object with data representing the editor responsible for this article")
+ responsible: Option[ResponsibleDTO],
+ @description("The path to the frontpage article")
+ slug: Option[String],
+ @description("Information about comments attached to the article")
+ comments: Seq[CommentDTO],
+ @description("If the article should be prioritized. Possible values are prioritized, on-hold, unspecified")
+ priority: Priority,
+ @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 {
- implicit def relatedContentEnc: Encoder[Either[RelatedContentLinkDTO, Long]] = eitherEncoder[RelatedContentLinkDTO, Long]
- implicit def relatedContentDec: Decoder[Either[RelatedContentLinkDTO, Long]] = eitherDecoder[RelatedContentLinkDTO, Long]
+ implicit def relatedContentEnc: Encoder[Either[RelatedContentLinkDTO, Long]] =
+ eitherEncoder[RelatedContentLinkDTO, Long]
+ implicit def relatedContentDec: Decoder[Either[RelatedContentLinkDTO, Long]] =
+ eitherDecoder[RelatedContentLinkDTO, Long]
implicit def encoder: Encoder[ArticleDTO] = deriveEncoder
implicit def decoder: Decoder[ArticleDTO] = deriveDecoder
+ implicit def schema: Schema[ArticleDTO] = Schema.derived
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDomainDumpDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDomainDumpDTO.scala
index 13ccd671c3..9158af1552 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDomainDumpDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleDomainDumpDTO.scala
@@ -18,3 +18,14 @@ case class ArticleDomainDumpDTO(
@description("The number of results per page") pageSize: Int,
@description("The search results") results: Seq[draft.Draft]
)
+
+object ArticleDomainDumpDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+ import sttp.tapir.Schema
+
+ implicit val encoder: Encoder[ArticleDomainDumpDTO] = deriveEncoder
+ implicit val decoder: Decoder[ArticleDomainDumpDTO] = deriveDecoder
+ implicit def schema: Schema[ArticleDomainDumpDTO] = Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleIntroductionDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleIntroductionDTO.scala
index 2ed1e83366..af11215cad 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleIntroductionDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleIntroductionDTO.scala
@@ -14,14 +14,16 @@ import sttp.tapir.Schema.annotations.description
@description("Description of the article introduction")
case class ArticleIntroductionDTO(
- @description("The introduction content") introduction: String,
- @description("The html introduction content") htmlIntroduction: String,
- @description(
- "The ISO 639-1 language code describing which article translation this introduction belongs to"
- ) language: String
+ @description("The introduction content")
+ introduction: String,
+ @description("The html introduction content")
+ htmlIntroduction: String,
+ @description("The ISO 639-1 language code describing which article translation this introduction belongs to")
+ language: String
)
object ArticleIntroductionDTO {
- implicit def encoder: Encoder[ArticleIntroductionDTO] = deriveEncoder
- implicit def decoder: Decoder[ArticleIntroductionDTO] = deriveDecoder
+ implicit def encoder: Encoder[ArticleIntroductionDTO] = deriveEncoder
+ implicit def decoder: Decoder[ArticleIntroductionDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[ArticleIntroductionDTO] = sttp.tapir.Schema.derived[ArticleIntroductionDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaDescriptionDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaDescriptionDTO.scala
index c32f926f30..1600a8fa96 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaDescriptionDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaDescriptionDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.draftapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
@description("Meta description of the article")
case class ArticleMetaDescriptionDTO(
@@ -23,4 +24,5 @@ case class ArticleMetaDescriptionDTO(
object ArticleMetaDescriptionDTO {
implicit def encoder: Encoder[ArticleMetaDescriptionDTO] = deriveEncoder
implicit def decoder: Decoder[ArticleMetaDescriptionDTO] = deriveDecoder
+ implicit def schema: Schema[ArticleMetaDescriptionDTO] = Schema.derived[ArticleMetaDescriptionDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaImageDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaImageDTO.scala
index bea4a49fc5..c2b9dffa18 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaImageDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleMetaImageDTO.scala
@@ -14,14 +14,16 @@ import sttp.tapir.Schema.annotations.description
@description("Meta description of the article")
case class ArticleMetaImageDTO(
- @description("The meta image") url: String,
- @description("The meta image alt text") alt: String,
- @description(
- "The ISO 639-1 language code describing which article translation this meta image belongs to"
- ) language: String
+ @description("The meta image")
+ url: String,
+ @description("The meta image alt text")
+ alt: String,
+ @description("The ISO 639-1 language code describing which article translation this meta image belongs to")
+ language: String
)
object ArticleMetaImageDTO {
- implicit def encoder: Encoder[ArticleMetaImageDTO] = deriveEncoder
- implicit def decoder: Decoder[ArticleMetaImageDTO] = deriveDecoder
+ implicit def encoder: Encoder[ArticleMetaImageDTO] = deriveEncoder
+ implicit def decoder: Decoder[ArticleMetaImageDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[ArticleMetaImageDTO] = sttp.tapir.Schema.derived[ArticleMetaImageDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleRevisionHistoryDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleRevisionHistoryDTO.scala
index bce15137a8..a004ff05b5 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleRevisionHistoryDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleRevisionHistoryDTO.scala
@@ -12,8 +12,17 @@ import sttp.tapir.Schema.annotations.description
@description("Information about article revision history")
case class ArticleRevisionHistoryDTO(
- @description("The revisions of an article, with the latest revision being the first in the list") revisions: Seq[
- ArticleDTO
- ],
- @description("Whether or not the current revision is safe to delete") canDeleteCurrentRevision: Boolean
+ @description("The revisions of an article, with the latest revision being the first in the list")
+ revisions: Seq[ArticleDTO],
+ @description("Whether or not the current revision is safe to delete")
+ canDeleteCurrentRevision: Boolean
)
+
+object ArticleRevisionHistoryDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+
+ implicit val encoder: Encoder[ArticleRevisionHistoryDTO] = deriveEncoder
+ implicit val decoder: Decoder[ArticleRevisionHistoryDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[ArticleRevisionHistoryDTO] = sttp.tapir.Schema.derived
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchParamsDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchParamsDTO.scala
index ed54e7e5bd..1dd7873229 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchParamsDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchParamsDTO.scala
@@ -43,4 +43,6 @@ case class ArticleSearchParamsDTO(
object ArticleSearchParamsDTO {
implicit def encoder: Encoder[ArticleSearchParamsDTO] = deriveEncoder
implicit def decoder: Decoder[ArticleSearchParamsDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: sttp.tapir.Schema[ArticleSearchParamsDTO] = sttp.tapir.Schema.derivedSchema
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchResultDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchResultDTO.scala
index 1a0bf683b6..28c6aca62b 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchResultDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSearchResultDTO.scala
@@ -17,3 +17,13 @@ case class ArticleSearchResultDTO(
@description("The number of results per page") pageSize: Int,
@description("The search results") results: Seq[ArticleSummaryDTO]
)
+
+object ArticleSearchResultDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+
+ implicit val encoder: Encoder[ArticleSearchResultDTO] = deriveEncoder
+ implicit val decoder: Decoder[ArticleSearchResultDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[ArticleSearchResultDTO] = sttp.tapir.Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSummaryDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSummaryDTO.scala
index 5efcc2268c..32e5cfb1cf 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSummaryDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleSummaryDTO.scala
@@ -29,3 +29,14 @@ case class ArticleSummaryDTO(
@description("The status of this article") status: StatusDTO,
@description("When the article was last updated") updated: NDLADate
)
+
+object ArticleSummaryDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+
+ implicit val encoder: Encoder[ArticleSummaryDTO] = deriveEncoder
+ implicit val decoder: Decoder[ArticleSummaryDTO] = deriveDecoder
+
+ import sttp.tapir.generic.auto.*
+ implicit def schema: sttp.tapir.Schema[ArticleSummaryDTO] = sttp.tapir.Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTagDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTagDTO.scala
index 6d65aa4b08..510f3d1c0d 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTagDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTagDTO.scala
@@ -19,6 +19,7 @@ case class ArticleTagDTO(
)
object ArticleTagDTO {
- implicit def encoder: Encoder[ArticleTagDTO] = deriveEncoder
- implicit def decoder: Decoder[ArticleTagDTO] = deriveDecoder
+ implicit def encoder: Encoder[ArticleTagDTO] = deriveEncoder
+ implicit def decoder: Decoder[ArticleTagDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[ArticleTagDTO] = sttp.tapir.Schema.derived[ArticleTagDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTitleDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTitleDTO.scala
index 6a173bb5b7..f202aabe88 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTitleDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ArticleTitleDTO.scala
@@ -20,6 +20,7 @@ case class ArticleTitleDTO(
)
object ArticleTitleDTO {
- implicit def encoder: Encoder[ArticleTitleDTO] = deriveEncoder
- implicit def decoder: Decoder[ArticleTitleDTO] = deriveDecoder
+ implicit def encoder: Encoder[ArticleTitleDTO] = deriveEncoder
+ implicit def decoder: Decoder[ArticleTitleDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[ArticleTitleDTO] = sttp.tapir.Schema.derived[ArticleTitleDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ContentIdDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ContentIdDTO.scala
index 90e5b9e696..4d47650a06 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/ContentIdDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/ContentIdDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.draftapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
@description("Id for a single Article")
case class ContentIdDTO(@description("The unique id of the article") id: Long)
@@ -18,4 +19,5 @@ case class ContentIdDTO(@description("The unique id of the article") id: Long)
object ContentIdDTO {
implicit val encoder: Encoder[ContentIdDTO] = deriveEncoder
implicit val decoder: Decoder[ContentIdDTO] = deriveDecoder
+ implicit def schema: Schema[ContentIdDTO] = Schema.derived
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/EditorNoteDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/EditorNoteDTO.scala
index c6db1f7759..9460b5b369 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/EditorNoteDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/EditorNoteDTO.scala
@@ -21,6 +21,7 @@ case class EditorNoteDTO(
)
object EditorNoteDTO {
- implicit def encoder: Encoder[EditorNoteDTO] = deriveEncoder
- implicit def decoder: Decoder[EditorNoteDTO] = deriveDecoder
+ implicit def encoder: Encoder[EditorNoteDTO] = deriveEncoder
+ implicit def decoder: Decoder[EditorNoteDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[EditorNoteDTO] = sttp.tapir.Schema.derived[EditorNoteDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/FileForm.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/FileForm.scala
new file mode 100644
index 0000000000..2a883d1a6d
--- /dev/null
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/FileForm.scala
@@ -0,0 +1,19 @@
+/*
+ * Part of NDLA draft-api
+ * Copyright (C) 2025 NDLA
+ *
+ * See LICENSE
+ *
+ */
+
+package no.ndla.draftapi.model.api
+
+import java.io.File
+import sttp.model.Part
+
+case class FileForm(file: Part[File])
+
+object FileForm {
+ import sttp.tapir.Schema
+ implicit def schema: Schema[FileForm] = Schema.derived[FileForm]
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/MultiPartialPublishResultDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/MultiPartialPublishResultDTO.scala
index ad2a07a13c..590b9e61d3 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/MultiPartialPublishResultDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/MultiPartialPublishResultDTO.scala
@@ -8,6 +8,7 @@
package no.ndla.draftapi.model.api
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Single failed result")
@@ -16,8 +17,26 @@ case class PartialPublishFailureDTO(
@description("Error message") message: String
)
+object PartialPublishFailureDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+
+ implicit def encoder: Encoder[PartialPublishFailureDTO] = deriveEncoder
+ implicit def decoder: Decoder[PartialPublishFailureDTO] = deriveDecoder
+ implicit def schema: Schema[PartialPublishFailureDTO] = Schema.derived[PartialPublishFailureDTO]
+}
+
@description("A list of articles that were partial published to article-api")
case class MultiPartialPublishResultDTO(
@description("Successful ids") successes: Seq[Long],
@description("Failed ids with error messages") failures: Seq[PartialPublishFailureDTO]
)
+
+object MultiPartialPublishResultDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+
+ implicit def encoder: Encoder[MultiPartialPublishResultDTO] = deriveEncoder
+ implicit def decoder: Decoder[MultiPartialPublishResultDTO] = deriveDecoder
+ implicit def schema: Schema[MultiPartialPublishResultDTO] = Schema.derived[MultiPartialPublishResultDTO]
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/NewArticleDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/NewArticleDTO.scala
index b636532d14..d466665d64 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/NewArticleDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/NewArticleDTO.scala
@@ -15,6 +15,7 @@ import no.ndla.common.model.NDLADate
import no.ndla.common.model.api.{DraftCopyrightDTO, NewCommentDTO, RelatedContentLinkDTO, RevisionMetaDTO}
import sttp.tapir.Schema.annotations.description
import no.ndla.common.model.domain.Priority
+import sttp.tapir.Schema
// format: off
@description("Information about the article")
@@ -52,4 +53,5 @@ object NewArticleDTO {
implicit def eitherDec: Decoder[Either[RelatedContentLinkDTO, Long]] = eitherDecoder[RelatedContentLinkDTO, Long]
implicit def encoder: Encoder[NewArticleDTO] = deriveEncoder
implicit def decoder: Decoder[NewArticleDTO] = deriveDecoder
+ implicit def schema: Schema[NewArticleDTO] = Schema.derived
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/PartialPublishArticle.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/PartialPublishArticle.scala
index cc3694bdc8..d8a913566f 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/PartialPublishArticle.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/PartialPublishArticle.scala
@@ -8,8 +8,11 @@
package no.ndla.draftapi.model.api
-import enumeratum._
+import enumeratum.*
+import sttp.tapir.Codec.PlainCodec
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.codec.enumeratum.*
sealed trait PartialArticleFieldsDTO extends EnumEntry
@@ -24,6 +27,10 @@ object PartialArticleFieldsDTO extends Enum[PartialArticleFieldsDTO] with CirceE
case object tags extends PartialArticleFieldsDTO
case object revisionDate extends PartialArticleFieldsDTO
case object published extends PartialArticleFieldsDTO
+
+ implicit def schema: Schema[PartialArticleFieldsDTO] = schemaForEnumEntry[PartialArticleFieldsDTO]
+ implicit def seqSchema: Schema[Seq[PartialArticleFieldsDTO]] = schema.asIterable
+ implicit def codec: PlainCodec[PartialArticleFieldsDTO] = plainCodecEnumEntry[PartialArticleFieldsDTO]
}
@description("Partial data about articles to publish in bulk")
@@ -31,3 +38,12 @@ case class PartialBulkArticlesDTO(
@description("A list of article ids to partially publish") articleIds: Seq[Long],
@description("A list of fields that should be partially published") fields: Seq[PartialArticleFieldsDTO]
)
+
+object PartialBulkArticlesDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+
+ implicit def encoder: Encoder[PartialBulkArticlesDTO] = deriveEncoder
+ implicit def decoder: Decoder[PartialBulkArticlesDTO] = deriveDecoder
+ implicit def schema: Schema[PartialBulkArticlesDTO] = Schema.derived
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/QualityEvaluationDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/QualityEvaluationDTO.scala
index a52efdce69..33f7f2395f 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/QualityEvaluationDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/QualityEvaluationDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.draftapi.model.api
import io.circe.{Decoder, Encoder}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import no.ndla.common.model.domain.draft.Grade
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Quality evaluation of the article")
@@ -22,4 +23,5 @@ case class QualityEvaluationDTO(
object QualityEvaluationDTO {
implicit def encoder: Encoder[QualityEvaluationDTO] = deriveEncoder
implicit def decoder: Decoder[QualityEvaluationDTO] = deriveDecoder
+ implicit def schema: Schema[QualityEvaluationDTO] = Schema.derived
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/RequiredLibraryDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/RequiredLibraryDTO.scala
index 227748c0da..9bad9aea13 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/RequiredLibraryDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/RequiredLibraryDTO.scala
@@ -10,6 +10,7 @@ package no.ndla.draftapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Information about a library required to render the article")
@@ -22,4 +23,5 @@ case class RequiredLibraryDTO(
object RequiredLibraryDTO {
implicit def encoder: Encoder[RequiredLibraryDTO] = deriveEncoder[RequiredLibraryDTO]
implicit def decoder: Decoder[RequiredLibraryDTO] = deriveDecoder[RequiredLibraryDTO]
+ implicit def schema: Schema[RequiredLibraryDTO] = Schema.derived[RequiredLibraryDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/SearchResultDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/SearchResultDTO.scala
index dbd44ddad8..828e6b2a68 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/SearchResultDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/SearchResultDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.draftapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
@description("Information about search-results")
case class SearchResultDTO(
@@ -21,6 +22,13 @@ case class SearchResultDTO(
@description("The search results") results: Seq[ArticleSummaryDTO]
)
+object SearchResultDTO {
+ implicit def encoder: Encoder[SearchResultDTO] = deriveEncoder
+ implicit def decoder: Decoder[SearchResultDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[SearchResultDTO] = Schema.derivedSchema
+}
+
@description("Information and metadata about codes from GREP API")
case class GrepCodesSearchResultDTO(
@description("The total number of codes from GREP API matching this query") totalCount: Long,
@@ -29,6 +37,13 @@ case class GrepCodesSearchResultDTO(
@description("The search results") results: Seq[String]
)
+object GrepCodesSearchResultDTO {
+ implicit def encoder: Encoder[GrepCodesSearchResultDTO] = deriveEncoder
+ implicit def decoder: Decoder[GrepCodesSearchResultDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[GrepCodesSearchResultDTO] = Schema.derivedSchema
+}
+
@description("Information about tags-search-results")
case class TagsSearchResultDTO(
@description("The total number of tags matching this query") totalCount: Long,
@@ -38,6 +53,13 @@ case class TagsSearchResultDTO(
@description("The search results") results: Seq[String]
)
+object TagsSearchResultDTO {
+ implicit def encoder: Encoder[TagsSearchResultDTO] = deriveEncoder
+ implicit def decoder: Decoder[TagsSearchResultDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[TagsSearchResultDTO] = Schema.derivedSchema
+}
+
@description("Information about articles")
case class ArticleDumpDTO(
@description("The total number of articles in the database") totalCount: Long,
@@ -50,4 +72,6 @@ case class ArticleDumpDTO(
object ArticleDumpDTO {
implicit def encoder: Encoder[ArticleDumpDTO] = deriveEncoder
implicit def decoder: Decoder[ArticleDumpDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[ArticleDumpDTO] = Schema.derivedSchema
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/StatusDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/StatusDTO.scala
index 693fe0ab7a..61b2885c66 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/StatusDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/StatusDTO.scala
@@ -18,6 +18,7 @@ case class StatusDTO(
)
object StatusDTO {
- implicit def encoder: Encoder[StatusDTO] = deriveEncoder
- implicit def decoder: Decoder[StatusDTO] = deriveDecoder
+ implicit def encoder: Encoder[StatusDTO] = deriveEncoder
+ implicit def decoder: Decoder[StatusDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[StatusDTO] = sttp.tapir.Schema.derived[StatusDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedArticleDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedArticleDTO.scala
index 198967a936..d4ac18001b 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedArticleDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedArticleDTO.scala
@@ -16,46 +16,75 @@ import no.ndla.common.model.api.{
DraftCopyrightDTO,
RelatedContent,
RelatedContentLinkDTO,
+ RevisionMetaDTO,
UpdateOrDelete,
- UpdatedCommentDTO,
- RevisionMetaDTO
+ UpdatedCommentDTO
}
import sttp.tapir.Schema.annotations.description
import no.ndla.common.model.domain.Priority
+import sttp.tapir.Schema
-// format: off
@description("Information about the article")
case class UpdatedArticleDTO(
- @description("The revision number for the article") revision: Int,
- @description("The chosen language") language: Option[String],
- @description("The title of the article") title: Option[String],
- @description("The status of the article") status: Option[String],
- @description("The date the article is published") published: Option[NDLADate],
- @description("The content of the article") content: Option[String],
- @description("Searchable tags") tags: Option[Seq[String]],
- @description("An introduction") introduction: Option[String],
- @description("A meta description") metaDescription: Option[String],
- @description("An image-api ID for the article meta image") metaImage: UpdateOrDelete[NewArticleMetaImageDTO],
- @description("A visual element for the article. May be anything from an image to a video or H5P") visualElement: Option[String],
- @description("Describes the copyright information for the article") copyright: Option[DraftCopyrightDTO],
- @description("Required libraries in order to render the article") requiredLibraries: Option[Seq[RequiredLibraryDTO]],
- @description("The type of article this is. Possible values are frontpage-article, standard, topic-article") articleType: Option[String],
- @description("The notes for this article draft") notes: Option[Seq[String]],
- @description("The labels attached to this article; meant for editors.") editorLabels: Option[Seq[String]],
- @description("A list of codes from GREP API connected to the article") grepCodes: Option[Seq[String]],
- @description("A list of conceptIds connected to the article") conceptIds: Option[Seq[Long]],
- @description("Stores the new article as a separate version. Useful when making big changes that should be revertable.") createNewVersion: Option[Boolean],
- @description("Value that dictates who gets to see the article. Possible values are: everyone/teacher") availability: Option[String],
- @description("A list of content related to the article") relatedContent: Option[Seq[Either[RelatedContentLinkDTO, Long]]],
- @description("A list of all revisions of the article") revisionMeta: Option[Seq[RevisionMetaDTO]],
- @description("NDLA ID representing the editor responsible for this article") responsibleId: UpdateOrDelete[String],
- @description("The path to the frontpage article") slug: Option[String],
- @description("Information about a comment attached to an article") comments: Option[List[UpdatedCommentDTO]],
- @description("If the article should be prioritized. Possible values are prioritized, on-hold, unspecified") priority: Option[Priority],
- @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]
+ @description("The revision number for the article")
+ revision: Int,
+ @description("The chosen language")
+ language: Option[String],
+ @description("The title of the article")
+ title: Option[String],
+ @description("The status of the article")
+ status: Option[String],
+ @description("The date the article is published")
+ published: Option[NDLADate],
+ @description("The content of the article")
+ content: Option[String],
+ @description("Searchable tags")
+ tags: Option[Seq[String]],
+ @description("An introduction")
+ introduction: Option[String],
+ @description("A meta description")
+ metaDescription: Option[String],
+ @description("An image-api ID for the article meta image")
+ metaImage: UpdateOrDelete[NewArticleMetaImageDTO],
+ @description("A visual element for the article. May be anything from an image to a video or H5P")
+ visualElement: Option[String],
+ @description("Describes the copyright information for the article")
+ copyright: Option[DraftCopyrightDTO],
+ @description("Required libraries in order to render the article")
+ requiredLibraries: Option[Seq[RequiredLibraryDTO]],
+ @description("The type of article this is. Possible values are frontpage-article, standard, topic-article")
+ articleType: Option[String],
+ @description("The notes for this article draft")
+ notes: Option[Seq[String]],
+ @description("The labels attached to this article; meant for editors.")
+ editorLabels: Option[Seq[String]],
+ @description("A list of codes from GREP API connected to the article")
+ grepCodes: Option[Seq[String]],
+ @description("A list of conceptIds connected to the article")
+ conceptIds: Option[Seq[Long]],
+ @description(
+ "Stores the new article as a separate version. Useful when making big changes that should be revertable."
+ )
+ createNewVersion: Option[Boolean],
+ @description("Value that dictates who gets to see the article. Possible values are: everyone/teacher")
+ availability: Option[String],
+ @description("A list of content related to the article")
+ relatedContent: Option[Seq[Either[RelatedContentLinkDTO, Long]]],
+ @description("A list of all revisions of the article")
+ revisionMeta: Option[Seq[RevisionMetaDTO]],
+ @description("NDLA ID representing the editor responsible for this article")
+ responsibleId: UpdateOrDelete[String],
+ @description("The path to the frontpage article")
+ slug: Option[String],
+ @description("Information about a comment attached to an article")
+ comments: Option[List[UpdatedCommentDTO]],
+ @description("If the article should be prioritized. Possible values are prioritized, on-hold, unspecified")
+ priority: Option[Priority],
+ @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 {
implicit def relatedContentEncoder: Encoder[RelatedContent] = eitherEncoder[RelatedContentLinkDTO, Long]
@@ -63,4 +92,5 @@ object UpdatedArticleDTO {
implicit def encoder: Encoder[UpdatedArticleDTO] = deriveEncoder[UpdatedArticleDTO]
implicit def decoder: Decoder[UpdatedArticleDTO] = deriveDecoder[UpdatedArticleDTO]
+ implicit def schema: Schema[UpdatedArticleDTO] = Schema.derived
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedUserDataDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedUserDataDTO.scala
index c941749321..6a054e7605 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedUserDataDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UpdatedUserDataDTO.scala
@@ -17,3 +17,13 @@ case class UpdatedUserDataDTO(
@description("User's last edited concepts") latestEditedConcepts: Option[Seq[String]],
@description("User's favorite subjects") favoriteSubjects: Option[Seq[String]]
)
+
+object UpdatedUserDataDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+
+ implicit val encoder: Encoder[UpdatedUserDataDTO] = deriveEncoder
+ implicit val decoder: Decoder[UpdatedUserDataDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[UpdatedUserDataDTO] = sttp.tapir.Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UploadedFileDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UploadedFileDTO.scala
index b9b0d5d388..96476ce055 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UploadedFileDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UploadedFileDTO.scala
@@ -10,6 +10,7 @@ package no.ndla.draftapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import sttp.tapir.Schema.annotations.description
+import sttp.tapir.Schema
@description("Information about the uploaded file")
case class UploadedFileDTO(
@@ -22,4 +23,6 @@ case class UploadedFileDTO(
object UploadedFileDTO {
implicit val encoder: Encoder[UploadedFileDTO] = deriveEncoder
implicit val decoder: Decoder[UploadedFileDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[UploadedFileDTO] = Schema.derivedSchema
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UserDataDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UserDataDTO.scala
index 28e1b4bc7f..b72d3cd263 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/UserDataDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/UserDataDTO.scala
@@ -18,3 +18,13 @@ case class UserDataDTO(
@description("User's last edited concepts") latestEditedConcepts: Option[Seq[String]],
@description("User's favorite subjects") favoriteSubjects: Option[Seq[String]]
)
+
+object UserDataDTO {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+
+ implicit val encoder: Encoder[UserDataDTO] = deriveEncoder
+ implicit val decoder: Decoder[UserDataDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[UserDataDTO] = sttp.tapir.Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/api/VisualElementDTO.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/api/VisualElementDTO.scala
index 6778eadc62..3d71e2923a 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/api/VisualElementDTO.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/api/VisualElementDTO.scala
@@ -14,15 +14,14 @@ import sttp.tapir.Schema.annotations.description
@description("Description of a visual element")
case class VisualElementDTO(
- @description(
- "Html containing the visual element. May contain any legal html element, including the embed-tag"
- ) visualElement: String,
- @description(
- "The ISO 639-1 language code describing which article translation this visual element belongs to"
- ) language: String
+ @description("Html containing the visual element. May contain any legal html element, including the embed-tag")
+ visualElement: String,
+ @description("The ISO 639-1 language code describing which article translation this visual element belongs to")
+ language: String
)
object VisualElementDTO {
- implicit def encoder: Encoder[VisualElementDTO] = deriveEncoder
- implicit def decoder: Decoder[VisualElementDTO] = deriveDecoder
+ implicit def encoder: Encoder[VisualElementDTO] = deriveEncoder
+ implicit def decoder: Decoder[VisualElementDTO] = deriveDecoder
+ implicit def schema: sttp.tapir.Schema[VisualElementDTO] = sttp.tapir.Schema.derived[VisualElementDTO]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ArticleIds.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ArticleIds.scala
index 4f602bd8bc..993f2625cb 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ArticleIds.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ArticleIds.scala
@@ -9,3 +9,14 @@
package no.ndla.draftapi.model.domain
case class ArticleIds(articleId: Long, externalId: List[String], importId: Option[String] = None)
+
+object ArticleIds {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+ import sttp.tapir.Schema
+
+ implicit val encoder: Encoder[ArticleIds] = deriveEncoder
+ implicit val decoder: Decoder[ArticleIds] = deriveDecoder
+ implicit def schema: Schema[ArticleIds] = Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ImportId.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ImportId.scala
index b525325aac..39be4946f9 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ImportId.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/domain/ImportId.scala
@@ -9,3 +9,14 @@
package no.ndla.draftapi.model.domain
case class ImportId(importId: Option[String])
+
+object ImportId {
+ import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
+ import io.circe.{Decoder, Encoder}
+ import sttp.tapir.generic.auto.*
+ import sttp.tapir.Schema
+
+ implicit val encoder: Encoder[ImportId] = deriveEncoder
+ implicit val decoder: Decoder[ImportId] = deriveDecoder
+ implicit def schema: Schema[ImportId] = Schema.derivedSchema
+}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/model/domain/Sort.scala b/draft-api/src/main/scala/no/ndla/draftapi/model/domain/Sort.scala
index 59b9ff562a..efdea51a01 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/model/domain/Sort.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/model/domain/Sort.scala
@@ -37,6 +37,6 @@ object Sort extends Enum[Sort] with CirceEnum[Sort] {
}
}
- implicit val schema: Schema[Sort] = schemaForEnumEntry[Sort]
- implicit val codec: PlainCodec[Sort] = plainCodecEnumEntry[Sort]
+ implicit def schema: Schema[Sort] = schemaForEnumEntry[Sort]
+ implicit def codec: PlainCodec[Sort] = plainCodecEnumEntry[Sort]
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/repository/DraftRepository.scala b/draft-api/src/main/scala/no/ndla/draftapi/repository/DraftRepository.scala
index 06415ff1ea..205f54f600 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/repository/DraftRepository.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/repository/DraftRepository.scala
@@ -24,7 +24,7 @@ import scala.util.{Failure, Success, Try}
trait DraftRepository {
this: DataSource & ErrorHandling & Clock =>
- val draftRepository: DraftRepository
+ lazy val draftRepository: DraftRepository
class DraftRepository extends StrictLogging with Repository[Draft] {
def insert(article: Draft)(implicit session: DBSession): Draft = {
@@ -227,7 +227,7 @@ trait DraftRepository {
private def externalIdsFromResultSet(wrappedResultSet: WrappedResultSet): List[String] = {
Option(wrappedResultSet.array("external_id"))
.map(_.getArray.asInstanceOf[Array[String]])
- .getOrElse(Array.empty)
+ .getOrElse(Array.empty[String])
.toList
.flatMap(Option(_))
}
@@ -242,7 +242,7 @@ trait DraftRepository {
private def externalSubjectIdsFromResultSet(wrappedResultSet: WrappedResultSet): List[String] = {
Option(wrappedResultSet.array("external_subject_id"))
.map(_.getArray.asInstanceOf[Array[String]])
- .getOrElse(Array.empty)
+ .getOrElse(Array.empty[String])
.toList
.flatMap(Option(_))
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/repository/UserDataRepository.scala b/draft-api/src/main/scala/no/ndla/draftapi/repository/UserDataRepository.scala
index f62533ceb3..1375596b78 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/repository/UserDataRepository.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/repository/UserDataRepository.scala
@@ -20,7 +20,7 @@ import scala.util.{Success, Try}
trait UserDataRepository {
this: DataSource =>
- val userDataRepository: UserDataRepository
+ lazy val userDataRepository: UserDataRepository
class UserDataRepository extends StrictLogging {
def insert(userData: UserData)(implicit session: DBSession = AutoSession): Try[UserData] = {
@@ -44,11 +44,11 @@ trait UserDataRepository {
dataObject.setType("jsonb")
dataObject.setValue(CirceUtil.toJsonString(userData))
- sql"""
+ val _ = sql"""
update ${UserData.table}
set document=$dataObject
where user_id=${userData.userId}
- """.update(): Unit
+ """.update()
logger.info(s"Updated user data ${userData.userId}")
Success(userData)
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/ConverterService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/ConverterService.scala
index bd02d31271..2f5a25f9b7 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/ConverterService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/ConverterService.scala
@@ -13,7 +13,7 @@ import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.configuration.Constants.EmbedTagName
import no.ndla.common.converter.CommonConverter
import no.ndla.common.errors.ValidationException
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.common.model.api.{Delete, DisclaimerDTO, DraftCopyrightDTO, Missing, ResponsibleDTO, UpdateWith}
import no.ndla.common.model.domain.{ArticleContent, Priority, Responsible}
import no.ndla.common.model.domain.draft.DraftStatus.PLANNED
@@ -42,11 +42,9 @@ import scala.util.{Failure, Success, Try}
trait ConverterService {
this: Clock & DraftRepository & ArticleApiClient & StateTransitionRules & WriteService & UUIDUtil & CommonConverter &
Props =>
- val converterService: ConverterService
+ lazy val converterService: ConverterService
class ConverterService extends StrictLogging {
- import props.externalApiUrls
-
def toDomainArticle(newArticleId: Long, newArticle: api.NewArticleDTO, user: TokenUser): Try[Draft] = {
val domainTitles = Seq(common.Title(newArticle.title, newArticle.language))
val domainContent = newArticle.content
@@ -356,7 +354,7 @@ trait ConverterService {
private def toApiArticleMetaImage(metaImage: common.ArticleMetaImage): api.ArticleMetaImageDTO = {
api.ArticleMetaImageDTO(
- s"${externalApiUrls("raw-image")}/${metaImage.imageId}",
+ s"${props.externalApiUrls("raw-image")}/${metaImage.imageId}",
metaImage.altText,
metaImage.language
)
@@ -623,9 +621,9 @@ trait ConverterService {
)
.getOrElse(toMergeInto.metaImage)
- def toDomainArticle(toMergeInto: Draft, article: api.UpdatedArticleDTO, user: TokenUser): Try[Draft] = {
+ def toDomainArticle(toMergeInto: Draft, article: api.UpdatedArticleDTO, user: TokenUser): Try[Draft] = permitTry {
if (article.language.isEmpty && languageFieldIsDefined(article))
- return Failure(ValidationException("language", "This field must be specified when updating language fields"))
+ Failure(ValidationException("language", "This field must be specified when updating language fields")).?
val isNewLanguage = article.language.exists(l => !toMergeInto.supportedLanguages.contains(l))
val createdDate = toMergeInto.created
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/FileStorageService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/FileStorageService.scala
index 8dcbd19dca..24c5be827a 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/FileStorageService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/FileStorageService.scala
@@ -18,7 +18,7 @@ import scala.util.Try
trait FileStorageService {
this: NdlaS3Client with Props =>
- val fileStorage: FileStorageService
+ lazy val fileStorage: FileStorageService
class FileStorageService extends StrictLogging {
val resourceDirectory = "resources"
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/ReadService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/ReadService.scala
index 8a853abe5f..5fb8949313 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/ReadService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/ReadService.scala
@@ -34,14 +34,12 @@ import scalikejdbc.ReadOnlyAutoSession
import scala.jdk.CollectionConverters.*
import scala.math.max
-import scala.util.{Failure, Success, Try}
+import scala.util.{Failure, Success, Try, boundary}
trait ReadService {
this: DraftRepository & ConverterService & ArticleSearchService & TagSearchService & GrepCodesSearchService &
SearchConverterService & UserDataRepository & WriteService & Props & MemoizeHelpers & DBUtility =>
- val readService: ReadService
-
- import props.*
+ lazy val readService: ReadService
class ReadService {
@@ -141,7 +139,7 @@ trait ReadService {
typeAndPathOption match {
case Some((resourceType, path)) =>
- val baseUrl = Url.parse(externalApiUrls(resourceType))
+ val baseUrl = Url.parse(props.externalApiUrls(resourceType))
val pathParts = Path.parse(path).parts
embedTag.attr(
@@ -190,13 +188,15 @@ trait ReadService {
articleId: Long,
language: String,
fallback: Boolean
- ): Try[ArticleRevisionHistoryDTO] = {
+ ): Try[ArticleRevisionHistoryDTO] = boundary {
val drafts = draftRepository
.articlesWithId(articleId)
.map(addUrlsOnEmbedResources)
.sortBy(
_.revision.getOrElse(
- return Failure(api.NotFoundException(s"Revision was missing for draft of article with id $articleId"))
+ boundary.break(
+ Failure(api.NotFoundException(s"Revision was missing for draft of article with id $articleId"))
+ )
)
)
.reverse
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/WriteService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/WriteService.scala
index e6a635015b..0e6bf475de 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/WriteService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/WriteService.scala
@@ -16,8 +16,8 @@ import no.ndla.common.Clock
import no.ndla.common.ContentURIUtil.parseArticleIdAndRevision
import no.ndla.common.TryUtil.failureIf
import no.ndla.common.configuration.Constants.EmbedTagName
-import no.ndla.common.errors.{MissingIdException, NotFoundException, ValidationException, OperationNotAllowedException}
-import no.ndla.common.implicits.{OptionImplicit, TryQuestionMark}
+import no.ndla.common.errors.{MissingIdException, NotFoundException, OperationNotAllowedException, ValidationException}
+import no.ndla.common.implicits.*
import no.ndla.common.logging.logTaskTime
import no.ndla.common.model.api.UpdateWith
import no.ndla.common.model.domain.article.PartialPublishArticleDTO
@@ -48,13 +48,13 @@ import scala.concurrent.duration.*
import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutorService, Future}
import scala.jdk.CollectionConverters.*
import scala.math.max
-import scala.util.{Failure, Random, Success, Try}
+import scala.util.{Failure, Random, Success, Try, boundary}
trait WriteService {
this: DraftRepository & UserDataRepository & ConverterService & ContentValidator & ArticleIndexService &
TagIndexService & GrepCodesIndexService & Clock & ReadService & ArticleApiClient & SearchApiClient &
FileStorageService & TaxonomyApiClient & Props & DBUtility =>
- val writeService: WriteService
+ lazy val writeService: WriteService
class WriteService extends StrictLogging {
@@ -75,9 +75,9 @@ trait WriteService {
article.id match {
case None => Failure(new IllegalStateException("No id found for article when indexing. This is a bug."))
case Some(articleId) =>
- searchApiClient.indexDocument("draft", article, Some(user)): Unit
- articleIndexService.indexAsync(articleId, article): Unit
- tagIndexService.indexAsync(articleId, article): Unit
+ val _ = searchApiClient.indexDocument("draft", article, Some(user))
+ val _ = articleIndexService.indexAsync(articleId, article)
+ val _ = tagIndexService.indexAsync(articleId, article)
Success(())
}
@@ -221,23 +221,25 @@ trait WriteService {
private def migrateOutdatedGrepForDraft(
draft: Draft,
user: TokenUser
- )(session: DBSession): Try[Option[(Long, PartialPublishArticleDTO)]] = {
- val articleId = draft.id.getOrElse(-1L)
- logger.info(s"Migrating grep codes for article $articleId")
- if (draft.grepCodes.isEmpty) { return Success(None) }
- val newGrepCodeMapping = searchApiClient.convertGrepCodes(draft.grepCodes, user).?
- val updatedGrepCodes = newGrepCodeMapping.values.toSeq
- if (draft.grepCodes.sorted == updatedGrepCodes.sorted) { return Success(None) }
- val grepCodeNote = getGrepCodeNote(newGrepCodeMapping, draft, user)
- val newDraft = draft.copy(grepCodes = updatedGrepCodes, notes = draft.notes :+ grepCodeNote)
- val updated = draftRepository.updateArticle(newDraft)(session).?
- val partialPart = partialArticleFieldsUpdate(updated, grepFieldsToPublish, Language.AllLanguages)
- logger.info(
- s"Migrated grep codes for article $articleId from [${draft.grepCodes.mkString(",")}] to [${updatedGrepCodes.mkString(",")}]"
- )
- lazy val idException = MissingIdException("Article id was missing after updating grep codes. This is a bug.")
- val id = updated.id.toTry(idException).?
- Success(Some((id, partialPart)))
+ )(session: DBSession): Try[Option[(Long, PartialPublishArticleDTO)]] = permitTry {
+ boundary {
+ val articleId = draft.id.getOrElse(-1L)
+ logger.info(s"Migrating grep codes for article $articleId")
+ if (draft.grepCodes.isEmpty) { boundary.break(Success(None)) }
+ val newGrepCodeMapping = searchApiClient.convertGrepCodes(draft.grepCodes, user).?
+ val updatedGrepCodes = newGrepCodeMapping.values.toSeq
+ if (draft.grepCodes.sorted == updatedGrepCodes.sorted) { boundary.break(Success(None)) }
+ val grepCodeNote = getGrepCodeNote(newGrepCodeMapping, draft, user)
+ val newDraft = draft.copy(grepCodes = updatedGrepCodes, notes = draft.notes :+ grepCodeNote)
+ val updated = draftRepository.updateArticle(newDraft)(session).?
+ val partialPart = partialArticleFieldsUpdate(updated, grepFieldsToPublish, Language.AllLanguages)
+ logger.info(
+ s"Migrated grep codes for article $articleId from [${draft.grepCodes.mkString(",")}] to [${updatedGrepCodes.mkString(",")}]"
+ )
+ lazy val idException = MissingIdException("Article id was missing after updating grep codes. This is a bug.")
+ val id = updated.id.toTry(idException).?
+ Success(Some((id, partialPart)))
+ }
}
def migrateOutdatedGreps(user: TokenUser): Try[Unit] = logTaskTime("Migrate outdated grep codes") {
@@ -497,16 +499,17 @@ trait WriteService {
updatedApiArticle: api.UpdatedArticleDTO,
user: TokenUser,
shouldNotAutoUpdateStatus: Boolean
- ): Try[Draft] = {
+ ): Try[Draft] = permitTry {
val newManualStatus = updatedApiArticle.status.traverse(DraftStatus.valueOfOrError).?
- if (shouldNotAutoUpdateStatus && newManualStatus.isEmpty)
- return Success(convertedArticle)
-
- val oldStatus = existingArticle.status.current
- val newStatusIfUndefined = if (oldStatus == PUBLISHED) IN_PROGRESS else oldStatus
- val newStatus = newManualStatus.getOrElse(newStatusIfUndefined)
+ if (shouldNotAutoUpdateStatus && newManualStatus.isEmpty) {
+ Success(convertedArticle)
+ } else {
+ val oldStatus = existingArticle.status.current
+ val newStatusIfUndefined = if (oldStatus == PUBLISHED) IN_PROGRESS else oldStatus
+ val newStatus = newManualStatus.getOrElse(newStatusIfUndefined)
- converterService.updateStatus(newStatus, convertedArticle, user)
+ converterService.updateStatus(newStatus, convertedArticle, user)
+ }
}
def updateArticle(articleId: Long, updatedApiArticle: api.UpdatedArticleDTO, user: TokenUser): Try[api.ArticleDTO] =
@@ -884,7 +887,7 @@ trait WriteService {
taxonomyApiClient
.getChildResources(id)
.flatMap(resources => resources.traverse(setRevisions(_, revisions)))
- case _ => Success(())
+ case null => Success(())
}
})
}
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleIndexService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleIndexService.scala
index 377baa4293..e9659871a4 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleIndexService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleIndexService.scala
@@ -21,9 +21,9 @@ import no.ndla.draftapi.repository.{DraftRepository, Repository}
trait ArticleIndexService {
this: SearchConverterService with IndexService with DraftRepository with Props =>
- val articleIndexService: ArticleIndexService
+ lazy val articleIndexService: ArticleIndexService
- class ArticleIndexService extends StrictLogging with IndexService[Draft, SearchableArticle] {
+ class ArticleIndexService extends IndexService[Draft, SearchableArticle] with StrictLogging {
override val documentType: String = props.DraftSearchDocument
override val searchIndex: String = props.DraftSearchIndex
override val repository: Repository[Draft] = draftRepository
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleSearchService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleSearchService.scala
index 104de858ec..44dd5be4e3 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleSearchService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/ArticleSearchService.scala
@@ -31,11 +31,9 @@ trait ArticleSearchService {
with SearchConverterService
with Props
with ErrorHandling =>
- val articleSearchService: ArticleSearchService
+ lazy val articleSearchService: ArticleSearchService
class ArticleSearchService extends StrictLogging with SearchService[api.ArticleSummaryDTO] {
- import props.{ElasticSearchIndexMaxResultWindow, ElasticSearchScrollKeepAlive}
-
private val noCopyright = boolQuery().not(termQuery("license", License.Copyrighted.toString))
override val searchIndex: String = props.DraftSearchIndex
@@ -106,9 +104,9 @@ trait ArticleSearchService {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.pageSize * settings.page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new ResultWindowTooLargeException())
} else {
@@ -122,7 +120,7 @@ trait ArticleSearchService {
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesIndexService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesIndexService.scala
index 430f4ab981..317d94278e 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesIndexService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesIndexService.scala
@@ -20,9 +20,9 @@ import no.ndla.draftapi.repository.{DraftRepository, Repository}
trait GrepCodesIndexService {
this: SearchConverterService with IndexService with DraftRepository with Props =>
- val grepCodesIndexService: GrepCodesIndexService
+ lazy val grepCodesIndexService: GrepCodesIndexService
- class GrepCodesIndexService extends StrictLogging with IndexService[Draft, SearchableGrepCode] {
+ class GrepCodesIndexService extends IndexService[Draft, SearchableGrepCode] with StrictLogging {
override val documentType: String = props.DraftGrepCodesSearchDocument
override val searchIndex: String = props.DraftGrepCodesSearchIndex
override val repository: Repository[Draft] = draftRepository
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesSearchService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesSearchService.scala
index 6324d3cf5e..5d37d45574 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesSearchService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/GrepCodesSearchService.scala
@@ -32,11 +32,10 @@ trait GrepCodesSearchService {
with SearchConverterService
with Props
with ErrorHandling =>
- val grepCodesSearchService: GrepCodesSearchService
+ lazy val grepCodesSearchService: GrepCodesSearchService
class GrepCodesSearchService extends StrictLogging with BasicSearchService[String] {
- import props._
- override val searchIndex: String = DraftGrepCodesSearchIndex
+ override val searchIndex: String = props.DraftGrepCodesSearchIndex
def getHits(response: SearchResponse): Seq[String] = {
response.hits.hits.toList.map(hit => CirceUtil.unsafeParseAs[SearchableGrepCode](hit.sourceAsString).grepCode)
@@ -62,9 +61,9 @@ trait GrepCodesSearchService {
): Try[LanguagelessSearchResult[String]] = {
val (startAt, numResults) = getStartAtAndNumResults(page, pageSize)
val requestedResultWindow = pageSize * page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new ResultWindowTooLargeException())
} else {
@@ -77,7 +76,7 @@ trait GrepCodesSearchService {
val searchWithScroll =
if (startAt != 0) { searchToExecute }
- else { searchToExecute.scroll(ElasticSearchScrollKeepAlive) }
+ else { searchToExecute.scroll(props.ElasticSearchScrollKeepAlive) }
e4sClient.execute(searchWithScroll) match {
case Success(response) =>
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/IndexService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/IndexService.scala
index 5283ab4c5f..e0e6cae174 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/IndexService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/IndexService.scala
@@ -25,7 +25,7 @@ import scala.concurrent.{ExecutionContext, Future}
trait IndexService {
this: Elastic4sClient & BaseIndexService & Props & SearchLanguage =>
- trait IndexService[D, T <: AnyRef] extends BaseIndexService with StrictLogging {
+ abstract class IndexService[D, T <: AnyRef] extends BaseIndexService with StrictLogging {
override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
val repository: Repository[D]
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchConverterService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchConverterService.scala
index eb26c8d2d3..eec3f72b81 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchConverterService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchConverterService.scala
@@ -27,7 +27,7 @@ import org.jsoup.Jsoup
trait SearchConverterService {
this: ConverterService & SearchLanguage =>
- val searchConverterService: SearchConverterService
+ lazy val searchConverterService: SearchConverterService
class SearchConverterService extends StrictLogging {
def asSearchableArticle(ai: Draft): SearchableArticle = {
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchService.scala
index 53f79b9437..287849eed0 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/SearchService.scala
@@ -24,8 +24,6 @@ import scala.util.{Failure, Success, Try}
trait SearchService {
this: Elastic4sClient with SearchConverterService with StrictLogging with Props =>
- import props._
-
trait SearchService[T] extends BasicSearchService[T] {
def hitToApiModel(hit: String, language: String): T
@@ -50,7 +48,7 @@ trait SearchService {
def scroll(scrollId: String, language: String): Try[SearchResult[T]] =
e4sClient
.execute {
- searchScroll(scrollId, ElasticSearchScrollKeepAlive)
+ searchScroll(scrollId, props.ElasticSearchScrollKeepAlive)
}
.map(response => {
val hits = getHits(response.result, language)
@@ -67,7 +65,7 @@ trait SearchService {
def getSortDefinition(sort: Sort, language: String): FieldSort = {
val sortLanguage = language match {
- case Language.NoLanguage => DefaultLanguage
+ case Language.NoLanguage => props.DefaultLanguage
case _ => language
}
@@ -121,7 +119,7 @@ trait SearchService {
}
def getStartAtAndNumResults(page: Int, pageSize: Int): (Int, Int) = {
- val numResults = max(pageSize.min(MaxPageSize), 0)
+ val numResults = max(pageSize.min(props.MaxPageSize), 0)
val startAt = (page - 1).max(0) * numResults
(startAt, numResults)
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagIndexService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagIndexService.scala
index 76f5fbf449..f7f8d46437 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagIndexService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagIndexService.scala
@@ -20,9 +20,9 @@ import no.ndla.draftapi.repository.{DraftRepository, Repository}
trait TagIndexService {
this: SearchConverterService with IndexService with DraftRepository with Props =>
- val tagIndexService: TagIndexService
+ lazy val tagIndexService: TagIndexService
- class TagIndexService extends StrictLogging with IndexService[Draft, SearchableTag] {
+ class TagIndexService extends IndexService[Draft, SearchableTag] with StrictLogging {
override val documentType: String = props.DraftTagSearchDocument
override val searchIndex: String = props.DraftTagSearchIndex
override val repository: Repository[Draft] = draftRepository
diff --git a/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagSearchService.scala b/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagSearchService.scala
index 1152bc8399..62519805a3 100644
--- a/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagSearchService.scala
+++ b/draft-api/src/main/scala/no/ndla/draftapi/service/search/TagSearchService.scala
@@ -32,11 +32,10 @@ trait TagSearchService {
with SearchConverterService
with Props
with ErrorHandling =>
- val tagSearchService: TagSearchService
+ lazy val tagSearchService: TagSearchService
class TagSearchService extends StrictLogging with SearchService[String] {
- import props._
- override val searchIndex: String = DraftTagSearchIndex
+ override val searchIndex: String = props.DraftTagSearchIndex
override def hitToApiModel(hit: String, language: String): String = {
val searchableTag = CirceUtil.unsafeParseAs[SearchableTag](hit)
@@ -83,9 +82,9 @@ trait TagSearchService {
val (startAt, numResults) = getStartAtAndNumResults(page, pageSize)
val requestedResultWindow = pageSize * page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new ResultWindowTooLargeException())
} else {
@@ -98,7 +97,7 @@ trait TagSearchService {
val searchWithScroll =
if (startAt != 0) { searchToExecute }
- else { searchToExecute.scroll(ElasticSearchScrollKeepAlive) }
+ else { searchToExecute.scroll(props.ElasticSearchScrollKeepAlive) }
e4sClient.execute(searchWithScroll) match {
case Success(response) =>
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 7a737b5e6a..615d5100a6 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
@@ -32,11 +32,10 @@ import scala.util.{Failure, Success, Try}
trait ContentValidator {
this: DraftRepository & ConverterService & ArticleApiClient & Props =>
- val contentValidator: ContentValidator
- val importValidator: ContentValidator
+ lazy val contentValidator: ContentValidator
+ lazy val importValidator: ContentValidator
class ContentValidator {
- import props.{BrightcoveVideoScriptUrl, H5PResizerScriptUrl, NRKVideoScriptUrl}
private val inlineHtmlTags = props.InlineHtmlTags
private val introductionHtmlTags = props.IntroductionHtmlTags
@@ -294,7 +293,7 @@ trait ContentValidator {
}
private def validateRequiredLibrary(requiredLibrary: RequiredLibrary): Option[ValidationMessage] = {
- val permittedLibraries = Seq(BrightcoveVideoScriptUrl, H5PResizerScriptUrl) ++ NRKVideoScriptUrl
+ val permittedLibraries = Seq(props.BrightcoveVideoScriptUrl, props.H5PResizerScriptUrl) ++ props.NRKVideoScriptUrl
if (permittedLibraries.contains(requiredLibrary.url)) {
None
} else {
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/TestEnvironment.scala b/draft-api/src/test/scala/no/ndla/draftapi/TestEnvironment.scala
index 374f0b2f9c..2015a415da 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/TestEnvironment.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/TestEnvironment.scala
@@ -74,56 +74,57 @@ trait TestEnvironment
with MemoizeHelpers
with DBMigrator
with Props
- with V57__MigrateSavedSearch {
+ with V57__MigrateSavedSearch
+ with ImageApiClient {
lazy val props: DraftApiProperties = new DraftApiProperties {
override def InlineHtmlTags: Set[String] = Set("code", "em", "span", "strong", "sub", "sup")
override def IntroductionHtmlTags: Set[String] = InlineHtmlTags ++ Set("br", "p")
}
- val migrator: DBMigrator = mock[DBMigrator]
- val DBUtil: DBUtility = mock[DBUtility]
+ override lazy val migrator: DBMigrator = mock[DBMigrator]
+ override lazy val DBUtil: DBUtility = mock[DBUtility]
- val articleSearchService: ArticleSearchService = mock[ArticleSearchService]
- val articleIndexService: ArticleIndexService = mock[ArticleIndexService]
- val tagSearchService: TagSearchService = mock[TagSearchService]
- val tagIndexService: TagIndexService = mock[TagIndexService]
- val grepCodesSearchService: GrepCodesSearchService = mock[GrepCodesSearchService]
- val grepCodesIndexService: GrepCodesIndexService = mock[GrepCodesIndexService]
+ override lazy val articleSearchService: ArticleSearchService = mock[ArticleSearchService]
+ override lazy val articleIndexService: ArticleIndexService = mock[ArticleIndexService]
+ override lazy val tagSearchService: TagSearchService = mock[TagSearchService]
+ override lazy val tagIndexService: TagIndexService = mock[TagIndexService]
+ override lazy val grepCodesSearchService: GrepCodesSearchService = mock[GrepCodesSearchService]
+ override lazy val grepCodesIndexService: GrepCodesIndexService = mock[GrepCodesIndexService]
- val internController: InternController = mock[InternController]
- val draftController: DraftController = mock[DraftController]
- val fileController: FileController = mock[FileController]
- val userDataController: UserDataController = mock[UserDataController]
- val healthController: TapirHealthController = mock[TapirHealthController]
+ override lazy val internController: InternController = mock[InternController]
+ override lazy val draftController: DraftController = mock[DraftController]
+ override lazy val fileController: FileController = mock[FileController]
+ override lazy val userDataController: UserDataController = mock[UserDataController]
+ override lazy val healthController: TapirHealthController = mock[TapirHealthController]
- val dataSource: HikariDataSource = mock[HikariDataSource]
- val draftRepository: DraftRepository = mock[DraftRepository]
- val userDataRepository: UserDataRepository = mock[UserDataRepository]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val draftRepository: DraftRepository = mock[DraftRepository]
+ override lazy val userDataRepository: UserDataRepository = mock[UserDataRepository]
- val converterService: ConverterService = mock[ConverterService]
+ override lazy val converterService: ConverterService = mock[ConverterService]
- val readService: ReadService = mock[ReadService]
- val writeService: WriteService = mock[WriteService]
- val contentValidator: ContentValidator = mock[ContentValidator]
- val importValidator: ContentValidator = mock[ContentValidator]
- val reindexClient: ReindexClient = mock[ReindexClient]
+ override lazy val readService: ReadService = mock[ReadService]
+ override lazy val writeService: WriteService = mock[WriteService]
+ override lazy val contentValidator: ContentValidator = mock[ContentValidator]
+ override lazy val importValidator: ContentValidator = mock[ContentValidator]
+ override lazy val reindexClient: ReindexClient = mock[ReindexClient]
- lazy val fileStorage: FileStorageService = mock[FileStorageService]
- val s3Client: NdlaS3Client = mock[NdlaS3Client]
+ override lazy val fileStorage: FileStorageService = mock[FileStorageService]
+ override lazy val s3Client: NdlaS3Client = mock[NdlaS3Client]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val searchConverterService: SearchConverterService = mock[SearchConverterService]
- var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
- override val learningpathApiClient: LearningpathApiClient = mock[LearningpathApiClient]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val searchConverterService: SearchConverterService = mock[SearchConverterService]
+ var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
+ override lazy val learningpathApiClient: LearningpathApiClient = mock[LearningpathApiClient]
- val clock: SystemClock = mock[SystemClock]
- val uuidUtil: UUIDUtil = mock[UUIDUtil]
+ override lazy val clock: SystemClock = mock[SystemClock]
+ override lazy val uuidUtil: UUIDUtil = mock[UUIDUtil]
- val articleApiClient: ArticleApiClient = mock[ArticleApiClient]
- val searchApiClient: SearchApiClient = mock[SearchApiClient]
- val taxonomyApiClient: TaxonomyApiClient = mock[TaxonomyApiClient]
- val h5pApiClient: H5PApiClient = mock[H5PApiClient]
- val imageApiClient: ImageApiClient = mock[ImageApiClient]
+ override lazy val articleApiClient: ArticleApiClient = mock[ArticleApiClient]
+ override lazy val searchApiClient: SearchApiClient = mock[SearchApiClient]
+ override lazy val taxonomyApiClient: TaxonomyApiClient = mock[TaxonomyApiClient]
+ override lazy val h5pApiClient: H5PApiClient = mock[H5PApiClient]
+ override lazy val imageApiClient: ImageApiClient = mock[ImageApiClient]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/integration/TaxonomyApiClientTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/integration/TaxonomyApiClientTest.scala
index 524e249aa0..1783dae8e0 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/integration/TaxonomyApiClientTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/integration/TaxonomyApiClientTest.scala
@@ -21,7 +21,7 @@ import scala.util.{Failure, Success}
class TaxonomyApiClientTest extends UnitSuite with TestEnvironment {
- override val taxonomyApiClient: TaxonomyApiClient = spy(new TaxonomyApiClient)
+ override lazy val taxonomyApiClient: TaxonomyApiClient = spy(new TaxonomyApiClient)
override def beforeEach(): Unit = {
// Since we use spy, we reset the mock before each test allowing verify to be accurate
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/repository/DraftRepositoryTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/repository/DraftRepositoryTest.scala
index 362e8ac73c..e85d9bbd7b 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/repository/DraftRepositoryTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/repository/DraftRepositoryTest.scala
@@ -24,10 +24,10 @@ import java.util.UUID
import scala.util.{Success, Try}
class DraftRepositoryTest extends DatabaseIntegrationSuite with TestEnvironment {
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator: DBMigrator = new DBMigrator
- var repository: DraftRepository = _
- val sampleArticle: Draft = TestData.sampleArticleWithByNcSa
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator: DBMigrator = new DBMigrator
+ var repository: DraftRepository = _
+ val sampleArticle: Draft = TestData.sampleArticleWithByNcSa
def emptyTestDatabase(): Unit = DB autoCommit (implicit session => {
sql"delete from articledata;".execute()(session)
@@ -312,7 +312,7 @@ class DraftRepositoryTest extends DatabaseIntegrationSuite with TestEnvironment
test("withId parse relatedContent correctly") {
repository.insert(sampleArticle.copy(id = Some(1), relatedContent = Seq(Right(2))))(AutoSession)
- val Right(relatedId) = repository.withId(1)(ReadOnlyAutoSession).get.relatedContent.head
+ val Right(relatedId) = repository.withId(1)(ReadOnlyAutoSession).get.relatedContent.head: @unchecked
relatedId should be(2L)
}
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/repository/UserDataRepositoryTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/repository/UserDataRepositoryTest.scala
index 33af7bdd0d..a774a78ed6 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/repository/UserDataRepositoryTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/repository/UserDataRepositoryTest.scala
@@ -20,9 +20,9 @@ import scalikejdbc.*
import scala.util.{Failure, Success, Try}
class UserDataRepositoryTest extends DatabaseIntegrationSuite with TestEnvironment {
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator: DBMigrator = new DBMigrator
- var repository: UserDataRepository = _
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator: DBMigrator = new DBMigrator
+ var repository: UserDataRepository = _
def emptyTestDatabase: Boolean = {
DB autoCommit (implicit session => {
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/ConverterServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/ConverterServiceTest.scala
index db6338fe96..8dcdf568ff 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/ConverterServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/ConverterServiceTest.scala
@@ -110,7 +110,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
when(clock.now()).thenReturn(expectedTime)
- val Success(result) = service.toDomainArticle(1, apiArticle, TestData.userWithWriteAccess)
+ val Success(result) = service.toDomainArticle(1, apiArticle, TestData.userWithWriteAccess): @unchecked
result.content.head.content should equal(expectedContent)
result.visualElement.head.resource should equal(expectedVisualElement)
result.created should equal(expectedTime)
@@ -139,20 +139,20 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set())),
updatedArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
res.title.find(_.language == "nb").get.title should equal("kakemonster")
}
test("updateStatus should return an IO[Failure] if the status change is illegal") {
val Failure(res: IllegalStatusStateTransition) =
- service.updateStatus(PUBLISHED, TestData.sampleArticleWithByNcSa, TestData.userWithWriteAccess)
+ service.updateStatus(PUBLISHED, TestData.sampleArticleWithByNcSa, TestData.userWithWriteAccess): @unchecked
res.getMessage should equal(
s"Cannot go to PUBLISHED when article is ${TestData.sampleArticleWithByNcSa.status.current}"
)
}
test("stateTransitionsToApi should return only disabled entries if user has no roles") {
- val Success(res) = service.stateTransitionsToApi(TestData.userWithNoRoles, None)
+ val Success(res) = service.stateTransitionsToApi(TestData.userWithNoRoles, None): @unchecked
res.forall { case (_, to) => to.isEmpty } should be(true)
}
@@ -161,7 +161,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
val article: Draft =
TestData.sampleArticleWithPublicDomain.copy(id = Some(articleId), status = Status(DraftStatus.PLANNED, Set()))
when(draftRepository.withId(eqTo(articleId))(any)).thenReturn(Some(article))
- val Success(noTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId))
+ val Success(noTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId)): @unchecked
noTrans(PLANNED.toString) should contain(DraftStatus.ARCHIVED.toString)
noTrans(IN_PROGRESS.toString) should contain(DraftStatus.ARCHIVED.toString)
noTrans(EXTERNAL_REVIEW.toString) should contain(DraftStatus.ARCHIVED.toString)
@@ -179,7 +179,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
val article: Draft =
TestData.sampleArticleWithPublicDomain.copy(id = Some(articleId), status = Status(DraftStatus.PUBLISHED, Set()))
when(draftRepository.withId(eqTo(articleId))(any)).thenReturn(Some(article))
- val Success(noTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId))
+ val Success(noTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId)): @unchecked
noTrans(PLANNED.toString) should not contain (DraftStatus.ARCHIVED.toString)
noTrans(IN_PROGRESS.toString) should not contain (DraftStatus.ARCHIVED.toString)
@@ -197,7 +197,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
val unpublished: Draft =
TestData.sampleArticleWithPublicDomain.copy(id = Some(articleId), status = Status(DraftStatus.IN_PROGRESS, Set()))
when(draftRepository.withId(eqTo(articleId))(any)).thenReturn(Some(unpublished))
- val Success(transOne) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId))
+ val Success(transOne) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId)): @unchecked
transOne(IN_PROGRESS.toString) should not contain (DraftStatus.LANGUAGE.toString)
val published: Draft =
@@ -206,7 +206,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
status = Status(DraftStatus.IN_PROGRESS, Set(DraftStatus.PUBLISHED))
)
when(draftRepository.withId(eqTo(articleId))(any)).thenReturn(Some(published))
- val Success(transTwo) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId))
+ val Success(transTwo) = service.stateTransitionsToApi(TestData.userWithWriteAccess, Some(articleId)): @unchecked
transTwo(IN_PROGRESS.toString) should contain(DraftStatus.LANGUAGE.toString)
}
@@ -219,7 +219,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
status = Status(DraftStatus.PLANNED, Set(DraftStatus.PUBLISHED))
)
when(draftRepository.withId(eqTo(articleId))(any)).thenReturn(Some(article))
- val Success(noTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, None)
+ val Success(noTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, None): @unchecked
noTrans(PLANNED.toString) should not contain (DraftStatus.ARCHIVED)
noTrans(IN_PROGRESS.toString) should not contain (DraftStatus.ARCHIVED)
@@ -233,8 +233,8 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
}
test("stateTransitionsToApi should return different number of transitions based on access") {
- val Success(adminTrans) = service.stateTransitionsToApi(TestData.userWithAdminAccess, None)
- val Success(writeTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, None)
+ val Success(adminTrans) = service.stateTransitionsToApi(TestData.userWithAdminAccess, None): @unchecked
+ val Success(writeTrans) = service.stateTransitionsToApi(TestData.userWithWriteAccess, None): @unchecked
// format: off
writeTrans(PLANNED.toString).length should be(adminTrans(PLANNED.toString).length)
@@ -250,12 +250,12 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
}
test("stateTransitionsToApi should have transitions from all statuses if admin") {
- val Success(adminTrans) = service.stateTransitionsToApi(TestData.userWithAdminAccess, None)
+ val Success(adminTrans) = service.stateTransitionsToApi(TestData.userWithAdminAccess, None): @unchecked
adminTrans.size should be(DraftStatus.values.size - 1)
}
test("stateTransitionsToApi should have transitions in inserted order") {
- val Success(adminTrans) = service.stateTransitionsToApi(TestData.userWithAdminAccess, None)
+ val Success(adminTrans) = service.stateTransitionsToApi(TestData.userWithAdminAccess, None): @unchecked
adminTrans(LANGUAGE.toString) should be(
Seq(
IN_PROGRESS.toString,
@@ -555,25 +555,25 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set()), notes = existingNotes),
updatedArticleWithoutNotes,
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) =
service.toDomainArticle(
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set()), notes = Seq.empty),
updatedArticleWithoutNotes,
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) =
service.toDomainArticle(
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set()), notes = existingNotes),
updatedArticleWithNotes,
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res4) =
service.toDomainArticle(
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set()), notes = Seq.empty),
updatedArticleWithNotes,
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.notes should be(existingNotes)
res2.notes should be(Seq.empty)
@@ -587,7 +587,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
val article =
TestData.sampleDomainArticle.copy(status = status, responsible = Some(Responsible("hei", clock.now())))
val Failure(res: IllegalStatusStateTransition) =
- service.updateStatus(ARCHIVED, article, TestData.userWithPublishAccess)
+ service.updateStatus(ARCHIVED, article, TestData.userWithPublishAccess): @unchecked
res.getMessage should equal(s"Cannot go to ARCHIVED when article contains ${status.other}")
}
@@ -603,19 +603,19 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set()), notes = existingNotes),
updatedArticleWithNotes.copy(language = Some("sna")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) =
service.toDomainArticle(
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set()), notes = existingNotes),
updatedArticleWithNotes.copy(language = Some("nb")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) =
service.toDomainArticle(
TestData.sampleDomainArticle.copy(status = Status(PLANNED, Set()), notes = existingNotes),
updatedArticleWithoutNotes.copy(language = Some("sna")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.notes.map(_.note) should be(Seq("swoop", "fleibede", s"Ny språkvariant 'sna' ble lagt til."))
res2.notes.map(_.note) should be(Seq("swoop", "fleibede"))
@@ -628,13 +628,13 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
1,
TestData.newArticle.copy(grepCodes = Some(Seq("a", "b"))),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) = service.toDomainArticle(
1,
TestData.newArticle.copy(grepCodes = None),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.grepCodes should be(Seq("a", "b"))
res2.grepCodes should be(Seq.empty)
@@ -645,19 +645,19 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
TestData.sampleDomainArticle.copy(grepCodes = Seq("a", "b", "c")),
TestData.sampleApiUpdateArticle.copy(grepCodes = Some(Seq("x", "y"))),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) = service.toDomainArticle(
TestData.sampleDomainArticle.copy(grepCodes = Seq("a", "b", "c")),
TestData.sampleApiUpdateArticle.copy(grepCodes = Some(Seq.empty)),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) = service.toDomainArticle(
TestData.sampleDomainArticle.copy(grepCodes = Seq("a", "b", "c")),
TestData.sampleApiUpdateArticle.copy(grepCodes = None),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.grepCodes should be(Seq("x", "y"))
res2.grepCodes should be(Seq.empty)
@@ -674,20 +674,20 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
beforeUpdate,
TestData.sampleApiUpdateArticle.copy(language = Some("nb"), metaImage = Delete),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) = service.toDomainArticle(
beforeUpdate,
TestData.sampleApiUpdateArticle
.copy(language = Some("nb"), metaImage = UpdateWith(api.NewArticleMetaImageDTO("1", "Hola"))),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) = service.toDomainArticle(
beforeUpdate,
TestData.sampleApiUpdateArticle.copy(language = Some("nb"), metaImage = Missing),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.metaImage should be(Seq(ArticleMetaImage("2", "Hej", "nn")))
res2.metaImage should be(Seq(ArticleMetaImage("2", "Hej", "nn"), ArticleMetaImage("1", "Hola", "nb")))
@@ -717,7 +717,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
existingArticle,
apiArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
}
@@ -759,19 +759,19 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
1,
TestData.newArticle.copy(availability = Some(Availability.teacher.toString)),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) = service.toDomainArticle(
1,
TestData.newArticle.copy(availability = None),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) = service.toDomainArticle(
1,
TestData.newArticle.copy(availability = Some("Krutte go")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.availability should be(Availability.teacher)
res1.availability should not be (Availability.everyone)
@@ -785,19 +785,19 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
TestData.sampleDomainArticle.copy(availability = Availability.everyone),
TestData.sampleApiUpdateArticle.copy(availability = Some(Availability.teacher.toString)),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) = service.toDomainArticle(
TestData.sampleDomainArticle.copy(availability = Availability.everyone),
TestData.sampleApiUpdateArticle.copy(availability = Some("Krutte go")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) = service.toDomainArticle(
TestData.sampleDomainArticle.copy(availability = Availability.teacher),
TestData.sampleApiUpdateArticle.copy(availability = None),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.availability should be(Availability.teacher)
res2.availability should be(Availability.everyone)
@@ -819,7 +819,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
.copy(status = Status(PLANNED, Set()), notes = existingNotes, responsible = Some(existingRepsonsible)),
updatedArticleWithNotes.copy(language = Some("nb"), responsibleId = UpdateWith("nyid")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) =
service.toDomainArticle(
@@ -827,14 +827,14 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
.copy(status = Status(PLANNED, Set()), notes = existingNotes, responsible = None),
updatedArticleWithNotes.copy(language = Some("nb"), responsibleId = UpdateWith("nyid")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) =
service.toDomainArticle(
TestData.sampleDomainArticle
.copy(status = Status(PLANNED, Set()), notes = existingNotes, responsible = Some(existingRepsonsible)),
updatedArticleWithNotes.copy(language = Some("nb")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.notes.map(_.note) should be(Seq("swoop", "fleibede", "Ansvarlig endret."))
res2.notes.map(_.note) should be(Seq("swoop", "fleibede", "Ansvarlig endret."))
@@ -854,21 +854,21 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
.copy(status = Status(PLANNED, Set()), responsible = Some(existingRepsonsible)),
updatedArticle.copy(language = Some("nb"), responsibleId = UpdateWith("nyid")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res2) =
service.toDomainArticle(
TestData.sampleDomainArticle
.copy(status = Status(PLANNED, Set()), responsible = None),
updatedArticle.copy(language = Some("nb"), responsibleId = UpdateWith("nyid")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
val Success(res3) =
service.toDomainArticle(
TestData.sampleDomainArticle
.copy(status = Status(PLANNED, Set()), responsible = Some(existingRepsonsible)),
updatedArticle.copy(language = Some("nb"), responsibleId = UpdateWith("oldId")),
TestData.userWithWriteAccess
- )
+ ): @unchecked
res1.responsible.get.responsibleId should be("nyid")
res1.responsible.get.lastUpdated should not be (yesterday)
@@ -948,7 +948,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
test("that toArticleApiArticle fails if copyright is not present") {
val draft = TestData.sampleDomainArticle.copy(copyright = None)
- val Failure(result1: ValidationException) = service.toArticleApiArticle(draft)
+ val Failure(result1: ValidationException) = service.toArticleApiArticle(draft): @unchecked
result1.errors.head.message should be("Copyright must be present when publishing an article")
}
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/ReadServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/ReadServiceTest.scala
index e5b0b95f29..b9b3844bea 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/ReadServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/ReadServiceTest.scala
@@ -20,9 +20,7 @@ import scalikejdbc.DBSession
import scala.util.{Failure, Success}
class ReadServiceTest extends UnitSuite with TestEnvironment {
- import props.externalApiUrls
-
- val externalImageApiUrl: String = externalApiUrls("image")
+ val externalImageApiUrl: String = props.externalApiUrls("image")
val resourceIdAttr: String = s"${TagAttribute.DataResource_Id}"
val resourceAttr: String = s"${TagAttribute.DataResource}"
val imageType: String = s"${ResourceType.Image}"
@@ -42,8 +40,8 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
val articleContent2: ArticleContent = ArticleContent(content2, "und")
- override val readService = new ReadService
- override val converterService = new ConverterService
+ override lazy val readService = new ReadService
+ override lazy val converterService = new ConverterService
test("withId adds urls and ids on embed resources") {
val visualElementBefore =
@@ -128,7 +126,7 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
fallback = true,
page = 1,
pageSize = 10
- )
+ ): @unchecked
result.length should be(3)
verify(draftRepository, times(1)).withIds(any, any, any)(any)
@@ -143,7 +141,7 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
fallback = true,
page = 1,
pageSize = 10
- )
+ ): @unchecked
result.errors.head.message should be("Query parameter 'ids' is missing")
verify(draftRepository, times(0)).withIds(any, any, any)(any)
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/StateTransitionRulesTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/StateTransitionRulesTest.scala
index 5c469e215b..ef8e402560 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/StateTransitionRulesTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/StateTransitionRulesTest.scala
@@ -47,7 +47,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
test("doTransition should succeed when performing a legal transition") {
val expected = common.Status(PUBLISHED, Set.empty)
val (Success(res), _) =
- doTransitionWithoutSideEffect(InProcessArticle, PUBLISHED, TestData.userWithAdminAccess)
+ doTransitionWithoutSideEffect(InProcessArticle, PUBLISHED, TestData.userWithAdminAccess): @unchecked
res.status should equal(expected)
}
@@ -59,7 +59,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = ExternalReviewStatus),
EXTERNAL_REVIEW,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res.status should equal(expected)
val expected2 = common.Status(IN_PROGRESS, Set(PUBLISHED))
@@ -68,7 +68,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = PublishedStatus),
IN_PROGRESS,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res2.status should equal(expected2)
}
@@ -80,7 +80,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = PublishedStatus),
ARCHIVED,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res1.status should equal(expected1)
val expected2 = common.Status(ARCHIVED, Set.empty)
@@ -89,7 +89,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = UnpublishedStatus),
ARCHIVED,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res2.status should equal(expected2)
val expected3 = common.Status(ARCHIVED, Set.empty)
@@ -98,7 +98,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = InProcessStatus),
ARCHIVED,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res3.status should equal(expected3)
val expected4 = common.Status(ARCHIVED, Set.empty)
@@ -107,7 +107,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = ExternalReviewStatus),
ARCHIVED,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res4.status should equal(expected4)
val expected5 = common.Status(ARCHIVED, Set.empty)
@@ -116,7 +116,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = PlannedStatus),
ARCHIVED,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res5.status should equal(expected5)
val expected6 = common.Status(ARCHIVED, Set.empty)
@@ -125,7 +125,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
InProcessArticle.copy(status = PublishedStatus),
ARCHIVED,
TestData.userWithPublishAccess
- )
+ ): @unchecked
res6.status should equal(expected6)
}
@@ -157,7 +157,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
.thenReturn(Success(expectedArticle))
val (Success(res), sideEffect) =
- doTransitionWithoutSideEffect(InProcessArticle, PUBLISHED, TestData.userWithAdminAccess)
+ doTransitionWithoutSideEffect(InProcessArticle, PUBLISHED, TestData.userWithAdminAccess): @unchecked
sideEffect.map(sf => sf.run(res, TestData.userWithAdminAccess).get.status should equal(expectedStatus))
val captor = ArgumentCaptor.forClass(classOf[Draft])
@@ -180,7 +180,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
when(articleApiClient.unpublishArticle(any[Draft], any)).thenReturn(Success(expectedArticle))
val (Success(res), sideEffect) =
- doTransitionWithoutSideEffect(PublishedArticle, UNPUBLISHED, TestData.userWithAdminAccess)
+ doTransitionWithoutSideEffect(PublishedArticle, UNPUBLISHED, TestData.userWithAdminAccess): @unchecked
sideEffect.map(sf => sf.run(res, TestData.userWithAdminAccess).get.status should equal(expectedStatus))
val captor = ArgumentCaptor.forClass(classOf[Draft])
@@ -199,7 +199,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
when(articleIndexService.deleteDocument(UnpublishedArticle.id.get)).thenReturn(Success(UnpublishedArticle.id.get))
val (Success(res), sideEffect) =
- doTransitionWithoutSideEffect(UnpublishedArticle, ARCHIVED, TestData.userWithPublishAccess)
+ doTransitionWithoutSideEffect(UnpublishedArticle, ARCHIVED, TestData.userWithPublishAccess): @unchecked
sideEffect.map(sf => sf.run(res, TestData.userWithAdminAccess).get.status should equal(expectedStatus))
verify(articleIndexService, times(0))
@@ -209,7 +209,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
test("user without required roles should not be permitted to perform the status transition") {
val proposalArticle = TestData.sampleArticleWithByNcSa.copy(status = InProcessStatus)
val (Failure(ex: IllegalStatusStateTransition), _) =
- doTransitionWithoutSideEffect(proposalArticle, PUBLISHED, TestData.userWithWriteAccess)
+ doTransitionWithoutSideEffect(proposalArticle, PUBLISHED, TestData.userWithWriteAccess): @unchecked
ex.getMessage should equal("Cannot go to PUBLISHED when article is IN_PROGRESS")
}
@@ -217,7 +217,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
val expected = common.Status(UNPUBLISHED, Set())
val publishedArticle = InProcessArticle.copy(status = common.Status(current = PUBLISHED, other = Set()))
val (Success(res), _) =
- doTransitionWithoutSideEffect(publishedArticle, UNPUBLISHED, TestData.userWithAdminAccess)
+ doTransitionWithoutSideEffect(publishedArticle, UNPUBLISHED, TestData.userWithAdminAccess): @unchecked
res.status should equal(expected)
}
@@ -243,7 +243,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
when(searchApiClient.publishedWhereUsed(any[Long], any)).thenReturn(Seq(result))
val Failure(res: ValidationException) =
- StateTransitionRules.checkIfArticleIsInUse.run(article, TestData.userWithAdminAccess)
+ StateTransitionRules.checkIfArticleIsInUse.run(article, TestData.userWithAdminAccess): @unchecked
res.errors should equal(
Seq(
ValidationMessage("status.current", "Article is in use in these published article(s) 1 (Title)")
@@ -286,7 +286,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
when(taxonomyApiClient.queryNodes(articleId)).thenReturn(Success(List.empty))
val Failure(res: ValidationException) =
- StateTransitionRules.checkIfArticleIsInUse.run(article, TestData.userWithAdminAccess)
+ StateTransitionRules.checkIfArticleIsInUse.run(article, TestData.userWithAdminAccess): @unchecked
res.errors.head.message should equal("Learningpath(s) 1 (Title) contains a learning step that uses this article")
}
@@ -298,7 +298,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
when(draftRepository.getIdFromExternalId(any[String])(any[DBSession])).thenReturn(Some(articleId))
val Failure(res: ValidationException) =
- StateTransitionRules.checkIfArticleIsInUse.run(article, TestData.userWithAdminAccess)
+ StateTransitionRules.checkIfArticleIsInUse.run(article, TestData.userWithAdminAccess): @unchecked
res.errors.head.message should equal("Learningpath(s) 1 (Title) contains a learning step that uses this article")
}
@@ -422,7 +422,7 @@ class StateTransitionRulesTest extends UnitSuite with TestEnvironment {
.thenReturn(Success(expectedArticle))
val (Success(res), sideEffect) =
- doTransitionWithoutSideEffect(InProcessArticle, PUBLISHED, TestData.userWithAdminAccess)
+ doTransitionWithoutSideEffect(InProcessArticle, PUBLISHED, TestData.userWithAdminAccess): @unchecked
sideEffect.map(sf => sf.run(res, TestData.userWithAdminAccess).get.status should equal(expectedStatus))
val captor = ArgumentCaptor.forClass(classOf[Draft])
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/WriteServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/WriteServiceTest.scala
index c936914061..0c80726404 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/WriteServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/WriteServiceTest.scala
@@ -34,7 +34,7 @@ import scala.concurrent.Future
import scala.util.{Failure, Success, Try}
class WriteServiceTest extends UnitSuite with TestEnvironment {
- override val converterService = new ConverterService
+ override lazy val converterService = new ConverterService
val today: NDLADate = NDLADate.now()
val yesterday: NDLADate = NDLADate.now().minusDays(1)
@@ -65,7 +65,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
doAnswer((i: InvocationOnMock) => {
val x = i.getArgument[DBSession => Try[?]](0)
x(mock[DBSession])
- }).when(DBUtil).rollbackOnFailure(any)
+ }).when(DBUtil).rollbackOnFailure(any())
when(draftRepository.withId(eqTo(articleId))(any)).thenReturn(Option(article))
when(articleIndexService.indexDocument(any[Draft])).thenAnswer((invocation: InvocationOnMock) =>
@@ -261,7 +261,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
existing.id.get,
updatedArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
result.status should equal(api.StatusDTO("IN_PROGRESS", Seq.empty))
}
@@ -279,7 +279,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
existing.id.get,
updatedArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
result.status should equal(api.StatusDTO("IN_PROGRESS", Seq("PUBLISHED")))
}
@@ -296,7 +296,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
existing.id.get,
updatedArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
result.status should equal(api.StatusDTO("IN_PROGRESS", Seq.empty))
}
@@ -310,7 +310,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
existing.id.get,
updatedArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
result.status should equal(api.StatusDTO("EXTERNAL_REVIEW", Seq.empty))
}
@@ -324,7 +324,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
existing.id.get,
updatedArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
result.status should equal(api.StatusDTO("INTERNAL_REVIEW", Seq.empty))
}
@@ -344,13 +344,13 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
existing.id.get,
updatedArticle,
TestData.userWithWriteAccess
- )
+ ): @unchecked
result.status should equal(api.StatusDTO("END_CONTROL", Seq.empty))
}
}
test("That delete article should fail when only one language") {
- val Failure(result) = service.deleteLanguage(article.id.get, "nb", TokenUser("asdf", Set(), None))
+ val Failure(result) = service.deleteLanguage(article.id.get, "nb", TokenUser("asdf", Set(), None)): @unchecked
result.getMessage should equal("Only one language left")
}
@@ -571,7 +571,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
val existing = TestData.sampleDomainArticle.copy(status = TestData.statusWithPublished)
when(draftRepository.withId(eqTo(existing.id.get))(any)).thenReturn(Some(existing))
- val Success(result1) = service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess)
+ val Success(result1) =
+ service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess): @unchecked
result1.status.current should be(existing.status.current.toString)
result1.status.other.sorted should be(existing.status.other.map(_.toString).toSeq.sorted)
}
@@ -591,7 +592,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
status = TestData.statusWithPublished
)
when(draftRepository.withId(eqTo(existing.id.get))(any)).thenReturn(Some(existing))
- val Success(result1) = service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess)
+ val Success(result1) =
+ service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess): @unchecked
result1.status.current should be(existing.status.current.toString)
result1.status.other.sorted should be(existing.status.other.map(_.toString).toSeq.sorted)
}
@@ -636,7 +638,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(writeService.partialPublish(any, any, any, any)).thenReturn((existing.id.get, Success(existing)))
when(articleApiClient.partialPublishArticle(any, any, any)).thenReturn(Success(existing.id.get))
- val Success(result1) = service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess)
+ val Success(result1) =
+ service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess): @unchecked
result1.status.current should be(existing.status.current.toString)
result1.status.other.sorted should be(existing.status.other.map(_.toString).toSeq.sorted)
@@ -687,7 +690,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(writeService.partialPublish(any, any, any, any)).thenReturn((existing.id.get, Success(existing)))
when(articleApiClient.partialPublishArticle(any, any, any)).thenReturn(Success(existing.id.get))
- val Success(result1) = service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess)
+ val Success(result1) =
+ service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess): @unchecked
result1.status.current should not be existing.status.current.toString
result1.status.current should be(DraftStatus.IN_PROGRESS.toString)
@@ -738,7 +742,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(writeService.partialPublish(any, any, any, any)).thenReturn((existing.id.get, Success(existing)))
when(articleApiClient.partialPublishArticle(any, any, any)).thenReturn(Success(existing.id.get))
- val Success(result1) = service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess)
+ val Success(result1) =
+ service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess): @unchecked
result1.status.current should not be existing.status.current.toString
result1.status.current should be(DraftStatus.IN_PROGRESS.toString)
@@ -1061,7 +1066,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(writeService.partialPublish(any, any, any, any)).thenReturn((existing.id.get, Success(existing)))
when(articleApiClient.partialPublishArticle(any, any, any)).thenReturn(Success(existing.id.get))
- val Success(result1) = service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess)
+ val Success(result1) =
+ service.updateArticle(existing.id.get, updatedArticle, TestData.userWithWriteAccess): @unchecked
result1.status.current should be(existing.status.current.toString)
result1.status.other.sorted should be(existing.status.other.map(_.toString).toSeq.sorted)
@@ -1094,7 +1100,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(draftRepository.newEmptyArticleId()(any[DBSession])).thenReturn(Success(10L))
- val Success(_) = service.newArticle(newArt, TestData.userWithWriteAccess)
+ val Success(_) = service.newArticle(newArt, TestData.userWithWriteAccess): @unchecked
val captor: ArgumentCaptor[Draft] = ArgumentCaptor.forClass(classOf[Draft])
Mockito.verify(draftRepository).insert(captor.capture())(any)
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/search/ArticleSearchServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/search/ArticleSearchServiceTest.scala
index b59b35375e..b6e6bfa150 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/search/ArticleSearchServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/search/ArticleSearchServiceTest.scala
@@ -21,16 +21,14 @@ import no.ndla.scalatestsuite.ElasticsearchIntegrationSuite
import scala.util.Success
class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnvironment {
- import props.{DefaultLanguage, DefaultPageSize, MaxPageSize}
-
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val articleSearchService = new ArticleSearchService
- override val articleIndexService: ArticleIndexService = new ArticleIndexService {
+ override lazy val articleSearchService = new ArticleSearchService
+ override lazy val articleIndexService: ArticleIndexService = new ArticleIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val byNcSa: DraftCopyright = DraftCopyright(
Some(License.CC_BY_NC_SA.toString),
@@ -232,21 +230,25 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
}
test("That getStartAtAndNumResults returns SEARCH_MAX_PAGE_SIZE for value greater than SEARCH_MAX_PAGE_SIZE") {
- articleSearchService.getStartAtAndNumResults(0, 10001) should equal((0, MaxPageSize))
+ articleSearchService.getStartAtAndNumResults(0, 10001) should equal((0, props.MaxPageSize))
}
test(
"That getStartAtAndNumResults returns the correct calculated start at for page and page-size with default page-size"
) {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- articleSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal((expectedStartAt, DefaultPageSize))
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ articleSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
+ )
}
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
val page = 123
- val expectedStartAt = (page - 1) * DefaultPageSize
- articleSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal((expectedStartAt, DefaultPageSize))
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ articleSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ (expectedStartAt, props.DefaultPageSize)
+ )
}
test("all should return only articles of a given type if a type filter is specified") {
@@ -254,16 +256,16 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
articleTypes = Seq(ArticleType.TopicArticle.entryName)
)
- )
+ ): @unchecked
results.totalCount should be(3)
results.results.map(_.id) should be(Seq(8, 9, 11))
val Success(results2) = articleSearchService.matchingQuery(
searchSettings.copy(
- searchLanguage = DefaultLanguage,
+ searchLanguage = props.DefaultLanguage,
articleTypes = ArticleType.all
)
- )
+ ): @unchecked
results2.totalCount should be(9)
}
@@ -272,7 +274,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
sort = Sort.ByIdAsc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(9)
hits.head.id should be(1)
@@ -291,7 +293,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
sort = Sort.ByIdDesc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(9)
hits.head.id should be(11)
@@ -303,7 +305,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(9)
hits.head.id should be(8)
@@ -322,7 +324,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
sort = Sort.ByTitleDesc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(9)
hits.head.id should be(7)
@@ -341,7 +343,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
sort = Sort.ByLastUpdatedDesc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(9)
hits.head.id should be(3)
@@ -353,7 +355,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
sort = Sort.ByLastUpdatedAsc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(9)
hits.map(_.id) should be(Seq(5, 6, 7, 8, 9, 11, 1, 2, 3))
@@ -365,7 +367,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
license = Some(License.PublicDomain.toString),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(8)
hits.map(_.id) should be(Seq(8, 9, 3, 5, 11, 6, 2, 7))
@@ -376,7 +378,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchSettings.copy(
withIdIn = List(1, 3)
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(2)
hits.head.id should be(1)
@@ -390,7 +392,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
pageSize = 2,
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits1 = page1.results
page1.totalCount should be(9)
page1.page.get should be(1)
@@ -404,7 +406,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
pageSize = 2,
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits2 = page2.results
page2.totalCount should be(9)
@@ -421,7 +423,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
sort = Sort.ByRelevanceDesc,
articleTypes = Seq(ArticleType.TopicArticle.entryName)
)
- )
+ ): @unchecked
results.totalCount should be(0)
val Success(results2) = articleSearchService.matchingQuery(
@@ -430,7 +432,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
sort = Sort.ByRelevanceDesc,
articleTypes = Seq(ArticleType.Standard.entryName)
)
- )
+ ): @unchecked
results2.totalCount should be(3)
}
@@ -441,7 +443,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("bil"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(3)
@@ -455,7 +457,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
withIdIn = List(3),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(3)
@@ -467,7 +469,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("Pingvinen"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(2)
@@ -479,7 +481,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("and"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(3)
@@ -491,7 +493,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("supermann"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
results.totalCount should be(0)
}
@@ -502,7 +504,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
license = Some(License.Copyrighted.toString),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = results.results
results.totalCount should be(1)
hits.head.id should be(4)
@@ -514,7 +516,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("bilde + bil"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits1 = search1.results
hits1.map(_.id) should equal(Seq(1, 3, 5))
@@ -523,7 +525,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("batmen + bil"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits2 = search2.results
hits2.map(_.id) should equal(Seq(1))
@@ -532,7 +534,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("bil + bilde - flaggermusmann"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits3 = search3.results
hits3.map(_.id) should equal(Seq(1, 3, 5))
@@ -541,7 +543,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("bil - hulken"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits4 = search4.results
hits4.map(_.id) should equal(Seq(1, 3, 5))
}
@@ -552,7 +554,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("mareritt + ragnarok"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = search.results
hits.map(_.id) should equal(Seq(9, 8))
}
@@ -563,7 +565,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("kakemonster"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
search.totalCount should be(1)
search.results.head.id should be(5)
}
@@ -575,7 +577,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
sort = Sort.ByIdAsc,
pageSize = 100
)
- )
+ ): @unchecked
val hits = search.results
search.totalCount should equal(10)
@@ -601,7 +603,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
sort = Sort.ByTitleAsc,
pageSize = 100
)
- )
+ ): @unchecked
val hits = search.results
search.totalCount should equal(1)
@@ -615,14 +617,14 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchLanguage = Language.AllLanguages,
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val Success(searchNb) = articleSearchService.matchingQuery(
searchSettings.copy(
query = Some("Store"),
searchLanguage = Language.AllLanguages,
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
searchEn.totalCount should equal(1)
searchEn.results.head.id should equal(11)
@@ -642,7 +644,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
searchLanguage = "en",
fallback = true
)
- )
+ ): @unchecked
search.totalCount should equal(3)
search.results.head.id should equal(9)
@@ -654,7 +656,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
}
test("That searching for language not in analyzers works as expected") {
- val Success(search) = articleSearchService.matchingQuery(searchSettings.copy(searchLanguage = "biz"))
+ val Success(search) = articleSearchService.matchingQuery(searchSettings.copy(searchLanguage = "biz")): @unchecked
search.totalCount should equal(1)
search.results.head.id should equal(11)
@@ -662,13 +664,13 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
}
test("That searching for language not in index works as expected") {
- val Success(search) = articleSearchService.matchingQuery(searchSettings.copy(searchLanguage = "mix"))
+ val Success(search) = articleSearchService.matchingQuery(searchSettings.copy(searchLanguage = "mix")): @unchecked
search.totalCount should equal(0)
}
test("That searching for unsupported language code works as expected") {
- val Success(search) = articleSearchService.matchingQuery(searchSettings.copy(searchLanguage = "asdf"))
+ val Success(search) = articleSearchService.matchingQuery(searchSettings.copy(searchLanguage = "asdf")): @unchecked
search.totalCount should equal(0)
}
@@ -684,13 +686,13 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
pageSize = pageSize,
shouldScroll = true
)
- )
+ ): @unchecked
- val Success(scroll1) = articleSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = articleSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = articleSearchService.scroll(scroll2.scrollId.get, "*")
- val Success(scroll4) = articleSearchService.scroll(scroll3.scrollId.get, "*")
- val Success(scroll5) = articleSearchService.scroll(scroll4.scrollId.get, "*")
+ val Success(scroll1) = articleSearchService.scroll(initialSearch.scrollId.get, "*"): @unchecked
+ val Success(scroll2) = articleSearchService.scroll(scroll1.scrollId.get, "*"): @unchecked
+ val Success(scroll3) = articleSearchService.scroll(scroll2.scrollId.get, "*"): @unchecked
+ val Success(scroll4) = articleSearchService.scroll(scroll3.scrollId.get, "*"): @unchecked
+ val Success(scroll5) = articleSearchService.scroll(scroll4.scrollId.get, "*"): @unchecked
initialSearch.results.map(_.id) should be(expectedIds.head)
scroll1.results.map(_.id) should be(expectedIds(1))
@@ -709,8 +711,8 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
pageSize = 1,
shouldScroll = true
)
- )
- val Success(scroll) = articleSearchService.scroll(initialSearch.scrollId.get, "*")
+ ): @unchecked
+ val Success(scroll) = articleSearchService.scroll(initialSearch.scrollId.get, "*"): @unchecked
initialSearch.results.size should be(1)
initialSearch.results.head.id should be(10)
@@ -727,7 +729,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
query = Some("kyllingkanon"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
search.totalCount should be(1)
search.results.head.id should be(5)
@@ -741,7 +743,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
sort = Sort.ByRelevanceDesc,
fallback = true
)
- )
+ ): @unchecked
search.results.map(_.id) should be(Seq(10))
}
@@ -754,7 +756,7 @@ class ArticleSearchServiceTest extends ElasticsearchIntegrationSuite with TestEn
fallback = true,
grepCodes = Seq("KM1234")
)
- )
+ ): @unchecked
search.totalCount should be(1)
search.results.head.id should be(5)
}
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/search/DraftSearchConverterServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/search/DraftSearchConverterServiceTest.scala
index 82ad14ad40..f12738bfa4 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/search/DraftSearchConverterServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/search/DraftSearchConverterServiceTest.scala
@@ -16,9 +16,8 @@ import no.ndla.search.model.{SearchableLanguageList, SearchableLanguageValues}
import no.ndla.common.model.domain.draft.Draft
class DraftSearchConverterServiceTest extends UnitSuite with TestEnvironment {
-
- override val searchConverterService = new SearchConverterService
- val sampleArticle: Draft = TestData.sampleArticleWithPublicDomain.copy()
+ override lazy val searchConverterService = new SearchConverterService
+ val sampleArticle: Draft = TestData.sampleArticleWithPublicDomain.copy()
val titles: List[Title] = List(
Title("Bokmål tittel", "nb"),
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesIndexServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesIndexServiceTest.scala
index e5f65ff20a..d68b92b421 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesIndexServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesIndexServiceTest.scala
@@ -15,11 +15,11 @@ class GrepCodesIndexServiceTest extends ElasticsearchIntegrationSuite with TestE
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val grepCodesIndexService: GrepCodesIndexService = new GrepCodesIndexService {
+ override lazy val grepCodesIndexService: GrepCodesIndexService = new GrepCodesIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
test("That indexing does not fail if no grepCodes are present") {
tagIndexService.createIndexWithName(props.DraftGrepCodesSearchIndex)
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesSearchServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesSearchServiceTest.scala
index d452824008..171fe985ac 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesSearchServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/search/GrepCodesSearchServiceTest.scala
@@ -18,12 +18,12 @@ class GrepCodesSearchServiceTest extends ElasticsearchIntegrationSuite with Test
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val grepCodesSearchService = new GrepCodesSearchService
- override val grepCodesIndexService: GrepCodesIndexService = new GrepCodesIndexService {
+ override lazy val grepCodesSearchService = new GrepCodesSearchService
+ override lazy val grepCodesIndexService: GrepCodesIndexService = new GrepCodesIndexService {
override val indexShards: Int = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val article1: Draft = TestData.sampleDomainArticle.copy(
grepCodes = Seq("KE101", "KE115", "TT555")
@@ -57,31 +57,31 @@ class GrepCodesSearchServiceTest extends ElasticsearchIntegrationSuite with Test
}
test("That searching for grepcodes returns sensible results") {
- val Success(result) = grepCodesSearchService.matchingQuery("KE", 1, 100)
+ val Success(result) = grepCodesSearchService.matchingQuery("KE", 1, 100): @unchecked
result.totalCount should be(3)
result.results should be(Seq("KE101", "KE115", "KE105"))
- val Success(result2) = grepCodesSearchService.matchingQuery("KE115", 1, 100)
+ val Success(result2) = grepCodesSearchService.matchingQuery("KE115", 1, 100): @unchecked
result2.totalCount should be(1)
result2.results should be(Seq("KE115"))
}
test("That searching for grepcodes returns sensible results even if lowercase") {
- val Success(result) = grepCodesSearchService.matchingQuery("ke", 1, 100)
+ val Success(result) = grepCodesSearchService.matchingQuery("ke", 1, 100): @unchecked
result.totalCount should be(3)
result.results should be(Seq("KE101", "KE115", "KE105"))
- val Success(result2) = grepCodesSearchService.matchingQuery("ke115", 1, 100)
+ val Success(result2) = grepCodesSearchService.matchingQuery("ke115", 1, 100): @unchecked
result2.totalCount should be(1)
result2.results should be(Seq("KE115"))
}
test("That only prefixes are matched with grepcodes") {
- val Success(result) = grepCodesSearchService.matchingQuery("TT", 1, 100)
+ val Success(result) = grepCodesSearchService.matchingQuery("TT", 1, 100): @unchecked
result.totalCount should be(1)
result.results should be(Seq("TT555"))
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagIndexServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagIndexServiceTest.scala
index 5a98ac2302..eb1d2ea287 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagIndexServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagIndexServiceTest.scala
@@ -15,11 +15,11 @@ class TagIndexServiceTest extends ElasticsearchIntegrationSuite with TestEnviron
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val tagIndexService: TagIndexService = new TagIndexService {
+ override lazy val tagIndexService: TagIndexService = new TagIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
test("That indexing does not fail if no tags are present") {
tagIndexService.createIndexAndAlias()
diff --git a/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagSearchServiceTest.scala b/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagSearchServiceTest.scala
index 47b839a2aa..436b3fd23d 100644
--- a/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagSearchServiceTest.scala
+++ b/draft-api/src/test/scala/no/ndla/draftapi/service/search/TagSearchServiceTest.scala
@@ -19,12 +19,12 @@ class TagSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnviro
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val tagSearchService = new TagSearchService
- override val tagIndexService: TagIndexService = new TagIndexService {
+ override lazy val tagSearchService = new TagSearchService
+ override lazy val tagIndexService: TagIndexService = new TagIndexService {
override val indexShards = 1
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val article1: Draft = TestData.sampleDomainArticle.copy(
tags = Seq(
@@ -84,14 +84,14 @@ class TagSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnviro
}
test("That searching for tags returns sensible results") {
- val Success(result) = tagSearchService.matchingQuery("test", "nb", 1, 100)
+ val Success(result) = tagSearchService.matchingQuery("test", "nb", 1, 100): @unchecked
result.totalCount should be(3)
result.results should be(Seq("test", "testemer", "testing"))
}
test("That only prefixes are matched") {
- val Success(result) = tagSearchService.matchingQuery("kylling", "nb", 1, 100)
+ val Success(result) = tagSearchService.matchingQuery("kylling", "nb", 1, 100): @unchecked
result.totalCount should be(1)
result.results should be(Seq("kyllingfilet"))
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 9b14f12d38..b39f5879f1 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
@@ -20,11 +20,11 @@ import java.util.UUID
import scala.util.Failure
class ContentValidatorTest extends UnitSuite with TestEnvironment {
- override val contentValidator = new ContentValidator()
- override val converterService: ConverterService = new ConverterService
- val validDocument = """"""
- val invalidDocument = """"""
- val validDisclaimer =
+ override lazy val contentValidator = new ContentValidator()
+ override lazy val converterService: ConverterService = new ConverterService
+ val validDocument = """"""
+ val invalidDocument = """"""
+ val validDisclaimer =
"""hallo!test
"""
val articleToValidate: Draft =
@@ -68,7 +68,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
content = Seq(ArticleContent(validDocument, "nb")),
disclaimer = OptLanguageFields.withValue("hei
", "nb")
)
- val Failure(error: ValidationException) = contentValidator.validateArticle(article)
+ val Failure(error: ValidationException) = contentValidator.validateArticle(article): @unchecked
val expected = ValidationException(
"disclaimer.nb",
"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"
@@ -127,7 +127,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
test("validateArticle should fail if the title exceeds 256 bytes") {
val article = articleToValidate.copy(title = Seq(Title("A" * 257, "nb")))
- val Failure(ex: ValidationException) = contentValidator.validateArticle(article)
+ val Failure(ex: ValidationException) = contentValidator.validateArticle(article): @unchecked
ex.errors.length should be(1)
ex.errors.head.message should be("This field exceeds the maximum permitted length of 256 characters")
@@ -135,7 +135,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
test("validateArticle should fail if the title is empty") {
val article = articleToValidate.copy(title = Seq(Title("", "nb")))
- val Failure(ex: ValidationException) = contentValidator.validateArticle(article)
+ val Failure(ex: ValidationException) = contentValidator.validateArticle(article): @unchecked
ex.errors.length should be(1)
ex.errors.head.message should be("This field does not meet the minimum length requirement of 1 characters")
@@ -143,7 +143,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
test("validateArticle should fail if the title is whitespace") {
val article = articleToValidate.copy(title = Seq(Title(" ", "nb")))
- val Failure(ex: ValidationException) = contentValidator.validateArticle(article)
+ val Failure(ex: ValidationException) = contentValidator.validateArticle(article): @unchecked
ex.errors.length should be(1)
ex.errors.head.message should be("This field does not meet the minimum length requirement of 1 characters")
@@ -317,7 +317,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
test("validation should fail if metaImage altText contains html") {
val article =
articleToValidate.copy(metaImage = Seq(ArticleMetaImage("1234", "Ikke krutte god", "nb")))
- val Failure(res1: ValidationException) = contentValidator.validateArticle(article)
+ val Failure(res1: ValidationException) = contentValidator.validateArticle(article): @unchecked
res1.errors should be(
Seq(ValidationMessage("metaImage.alt", "The content contains illegal html-characters. No HTML is allowed"))
)
@@ -332,7 +332,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
articleToValidate.copy(
metaImage = Seq(ArticleMetaImage("", "alt-text", "nb"))
)
- )
+ ): @unchecked
res.errors.length should be(1)
res.errors.head.field should be("metaImageId")
@@ -345,7 +345,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
articleToValidate.copy(
revisionMeta = Seq.empty
)
- )
+ ): @unchecked
res.errors.length should be(1)
res.errors.head.field should be("revisionMeta")
@@ -359,7 +359,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
articleType = ArticleType.TopicArticle,
slug = Some("pepe")
)
- )
+ ): @unchecked
res.errors.length should be(1)
res.errors.head.field should be("articleType")
@@ -375,7 +375,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
articleType = ArticleType.FrontpageArticle,
slug = None
)
- )
+ ): @unchecked
res.errors.length should be(1)
res.errors.head.field should be("slug")
@@ -391,7 +391,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
articleType = ArticleType.FrontpageArticle,
slug = Some("ugyldig slug")
)
- )
+ ): @unchecked
res.errors.length should be(1)
res.errors.head.field should be("slug")
@@ -409,7 +409,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
)
contentValidator.validateArticleOnLanguage(article, Some("nb")).failIfFailure
- val Failure(error: ValidationException) = contentValidator.validateArticle(article)
+ val Failure(error: ValidationException) = contentValidator.validateArticle(article): @unchecked
val Seq(err1, err2) = error.errors
err1.message.contains("The content contains illegal tags and/or attributes.") should be(true)
err2.message should be("An article must consist of one or more blocks. Illegal tag(s) are div ")
@@ -469,7 +469,7 @@ class ContentValidatorTest extends UnitSuite with TestEnvironment {
val result = contentValidator.validateArticleOnLanguage(Some(oldArticle), article, Some("nb"))
result.isFailure should be(true)
- val Failure(validationError: ValidationException) = result
+ val Failure(validationError: ValidationException) = result: @unchecked
validationError.errors.length should be(1)
validationError.errors.head.message should be("An article must contain at least one planned revision date")
}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/ComponentRegistry.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/ComponentRegistry.scala
index 57ab4ae8ca..0053d59eda 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/ComponentRegistry.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/ComponentRegistry.scala
@@ -39,27 +39,27 @@ class ComponentRegistry(properties: FrontpageApiProperties)
with DBMigrator
with ConverterService
with SwaggerDocControllerConfig {
- override val props: FrontpageApiProperties = properties
- override val migrator: DBMigrator = DBMigrator()
- override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
+ override lazy val props: FrontpageApiProperties = properties
+ override lazy val migrator: DBMigrator = DBMigrator()
+ override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
- override val clock = new SystemClock
+ override lazy val clock = new SystemClock
- override val subjectPageRepository = new SubjectPageRepository
- override val frontPageRepository = new FrontPageRepository
- override val filmFrontPageRepository = new FilmFrontPageRepository
+ override lazy val subjectPageRepository = new SubjectPageRepository
+ override lazy val frontPageRepository = new FrontPageRepository
+ override lazy val filmFrontPageRepository = new FilmFrontPageRepository
- override val readService = new ReadService
- override val writeService = new WriteService
+ override lazy val readService = new ReadService
+ override lazy val writeService = new WriteService
- override val subjectPageController = new SubjectPageController
- override val frontPageController = new FrontPageController
- override val filmPageController = new FilmPageController
- override val internController = new InternController
- val healthController = new TapirHealthController
+ override lazy val subjectPageController = new SubjectPageController
+ override lazy val frontPageController = new FrontPageController
+ override lazy val filmPageController = new FilmPageController
+ override lazy val internController = new InternController
+ override lazy val healthController = new TapirHealthController
- override val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
- override val ndlaClient: NdlaClient = new NdlaClient
+ override lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
+ override lazy val ndlaClient: NdlaClient = new NdlaClient
val swagger = new SwaggerController(
List(
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/FrontpageApiProperties.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/FrontpageApiProperties.scala
index 31a130a746..70bab4d869 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/FrontpageApiProperties.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/FrontpageApiProperties.scala
@@ -15,7 +15,7 @@ import no.ndla.database.{DatabaseProps, HasDatabaseProps}
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: FrontpageApiProperties
+ lazy val props: FrontpageApiProperties
}
class FrontpageApiProperties extends BaseProps with DatabaseProps {
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FilmPageController.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FilmPageController.scala
index 0769ca30aa..cb069058e1 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FilmPageController.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FilmPageController.scala
@@ -23,7 +23,7 @@ import sttp.tapir.server.ServerEndpoint
trait FilmPageController {
this: ReadService & WriteService & ErrorHandling & TapirController =>
- val filmPageController: FilmPageController
+ lazy val filmPageController: FilmPageController
class FilmPageController extends TapirController {
override val serviceName: String = "filmfrontpage"
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FrontPageController.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FrontPageController.scala
index 70baa53daa..272fff4cb6 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FrontPageController.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/FrontPageController.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.controller
-import io.circe.generic.auto.*
import no.ndla.common.model.api.FrontPageDTO
import no.ndla.frontpageapi.model.api.*
import no.ndla.frontpageapi.service.{ReadService, WriteService}
@@ -22,7 +21,7 @@ import sttp.tapir.server.ServerEndpoint
trait FrontPageController {
this: ReadService & WriteService & ErrorHandling & TapirController =>
- val frontPageController: FrontPageController
+ lazy val frontPageController: FrontPageController
class FrontPageController() extends TapirController {
override val serviceName: String = "frontpage"
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/InternController.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/InternController.scala
index b66a684513..f0861f45f1 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/InternController.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/InternController.scala
@@ -25,7 +25,7 @@ import scala.util.{Failure, Success}
trait InternController {
this: ReadService & WriteService & Props & ErrorHandling & TapirController =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController {
override val prefix: EndpointInput[Unit] = "intern"
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/SubjectPageController.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/SubjectPageController.scala
index 45334b9fa5..1befba6162 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/SubjectPageController.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/controller/SubjectPageController.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.controller
-import io.circe.generic.auto.*
import no.ndla.common.errors.ValidationException
import no.ndla.common.model.api.CommaSeparatedList.*
import no.ndla.common.model.api.LanguageCode
@@ -26,7 +25,7 @@ import sttp.tapir.server.ServerEndpoint
trait SubjectPageController {
this: ReadService & WriteService & Props & ErrorHandling & TapirController =>
- val subjectPageController: SubjectPageController
+ lazy val subjectPageController: SubjectPageController
class SubjectPageController extends TapirController {
override val serviceName: String = "subjectpage"
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V2__convert_subjects_to_object.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V2__convert_subjects_to_object.scala
index 1f70f0c173..8cd1efb1ed 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V2__convert_subjects_to_object.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V2__convert_subjects_to_object.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import io.circe.generic.auto.*
import io.circe.generic.semiauto.*
import io.circe.parser.*
import io.circe.syntax.*
@@ -21,10 +20,6 @@ import scalikejdbc.*
import scala.util.{Failure, Success}
class V2__convert_subjects_to_object extends BaseJavaMigration {
-
- implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
- implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
-
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
.withinTx { implicit session =>
@@ -60,9 +55,33 @@ class V2__convert_subjects_to_object extends BaseJavaMigration {
}
case class V2_FrontPageData(topical: List[String], categories: List[V2_SubjectCollection])
+object V2_FrontPageData {
+ implicit val decoder: Decoder[V2_FrontPageData] = deriveDecoder
+ implicit val encoder: Encoder[V2_FrontPageData] = deriveEncoder
+}
case class V2_SubjectCollection(name: String, subjects: List[V2_SubjectFilters])
+object V2_SubjectCollection {
+ implicit val decoder: Decoder[V2_SubjectCollection] = deriveDecoder
+ implicit val encoder: Encoder[V2_SubjectCollection] = deriveEncoder
+}
case class V2_SubjectFilters(id: String, filters: List[String])
+object V2_SubjectFilters {
+ implicit val decoder: Decoder[V2_SubjectFilters] = deriveDecoder
+ implicit val encoder: Encoder[V2_SubjectFilters] = deriveEncoder
+}
case class V1_DBFrontPage(id: Long, document: String)
+object V1_DBFrontPage {
+ implicit val decoder: Decoder[V1_DBFrontPage] = deriveDecoder
+ implicit val encoder: Encoder[V1_DBFrontPage] = deriveEncoder
+}
case class V1_DBFrontPageData(topical: List[String], categories: List[V1_DBSubjectCollection])
+object V1_DBFrontPageData {
+ implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
+ implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
+}
case class V1_DBSubjectCollection(name: String, subjects: List[String])
+object V1_DBSubjectCollection {
+ implicit val decoder: Decoder[V1_DBSubjectCollection] = deriveDecoder
+ implicit val encoder: Encoder[V1_DBSubjectCollection] = deriveEncoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V3__introduce_layout.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V3__introduce_layout.scala
index 3fcceb6298..32e19192ad 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V3__introduce_layout.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V3__introduce_layout.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import io.circe.generic.auto.*
import io.circe.generic.semiauto.*
import io.circe.parser.*
import io.circe.syntax.*
@@ -22,8 +21,12 @@ import scala.util.{Failure, Success}
class V3__introduce_layout extends BaseJavaMigration {
- implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
- implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
+ implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
+ implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
+ implicit val v2decoder: Decoder[V2_SubjectFrontPageData] = deriveDecoder
+ implicit val v2encoder: Encoder[V2_SubjectFrontPageData] = deriveEncoder
+ implicit val v3decoder: Decoder[V3_SubjectFrontPageData] = deriveDecoder
+ implicit val v3encoder: Encoder[V3_SubjectFrontPageData] = deriveEncoder
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
@@ -71,6 +74,10 @@ class V3__introduce_layout extends BaseJavaMigration {
}
case class V2_DBSubjectPage(id: Long, document: String)
+object V2_DBSubjectPage {
+ implicit val encoder: Encoder[V2_DBSubjectPage] = deriveEncoder
+ implicit val decoder: Decoder[V2_DBSubjectPage] = deriveDecoder
+}
case class V2_SubjectFrontPageData(
id: Option[Long],
name: String,
@@ -87,8 +94,20 @@ case class V2_SubjectFrontPageData(
goTo: List[String]
)
case class V2_BannerImage(mobileImageId: Long, desktopImageId: Long)
+object V2_BannerImage {
+ implicit val encoder: Encoder[V2_BannerImage] = deriveEncoder
+ implicit val decoder: Decoder[V2_BannerImage] = deriveDecoder
+}
case class V2_AboutSubject(title: String, description: String, visualElement: V2_VisualElement)
+object V2_AboutSubject {
+ implicit val encoder: Encoder[V2_AboutSubject] = deriveEncoder
+ implicit val decoder: Decoder[V2_AboutSubject] = deriveDecoder
+}
case class V2_VisualElement(`type`: String, id: String, alt: Option[String])
+object V2_VisualElement {
+ implicit val encoder: Encoder[V2_VisualElement] = deriveEncoder
+ implicit val decoder: Decoder[V2_VisualElement] = deriveDecoder
+}
case class V3_SubjectFrontPageData(
id: Option[Long],
@@ -105,3 +124,7 @@ case class V3_SubjectFrontPageData(
latestContent: Option[List[String]],
goTo: List[String]
)
+object V3_SubjectFrontPageData {
+ implicit val encoder: Encoder[V3_SubjectFrontPageData] = deriveEncoder
+ implicit val decoder: Decoder[V3_SubjectFrontPageData] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V4__add_language_to_about.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V4__add_language_to_about.scala
index 703d106298..89f56c0905 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V4__add_language_to_about.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V4__add_language_to_about.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import io.circe.generic.auto.*
import io.circe.generic.semiauto.*
import io.circe.parser.parse
import io.circe.syntax.*
@@ -22,10 +21,6 @@ import scalikejdbc.*
import scala.util.{Failure, Success}
class V4__add_language_to_about extends BaseJavaMigration {
-
- implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
- implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
-
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
.withinTx { implicit session =>
@@ -90,4 +85,12 @@ case class V4_SubjectFrontPageData(
latestContent: Option[List[String]],
goTo: List[String]
)
+object V4_SubjectFrontPageData {
+ implicit val encoder: Encoder[V4_SubjectFrontPageData] = deriveEncoder
+ implicit val decoder: Decoder[V4_SubjectFrontPageData] = deriveDecoder
+}
case class V4_AboutSubject(title: String, description: String, language: String, visualElement: V2_VisualElement)
+object V4_AboutSubject {
+ implicit val encoder: Encoder[V4_AboutSubject] = deriveEncoder
+ implicit val decoder: Decoder[V4_AboutSubject] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V5__add_meta_description.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V5__add_meta_description.scala
index 71c84918f4..0db65e1de8 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V5__add_meta_description.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V5__add_meta_description.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import io.circe.generic.auto.*
import io.circe.generic.semiauto.*
import io.circe.parser.parse
import io.circe.syntax.*
@@ -23,8 +22,16 @@ import scala.util.{Failure, Success}
class V5__add_meta_description extends BaseJavaMigration {
- implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
- implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
+ implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
+ implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
+ implicit val v4decoder: Decoder[V4_SubjectFrontPageData] = deriveDecoder
+ implicit val v4encoder: Encoder[V4_SubjectFrontPageData] = deriveEncoder
+
+ implicit val v5decoder: Decoder[V5_SubjectFrontPageData] = deriveDecoder
+ implicit val v5encoder: Encoder[V5_SubjectFrontPageData] = deriveEncoder
+
+ implicit val v5MetaDescriptionDecoder: Decoder[V5_MetaDescription] = deriveDecoder
+ implicit val v5MetaDescriptionEncoder: Encoder[V5_MetaDescription] = deriveEncoder
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
@@ -73,6 +80,10 @@ class V5__add_meta_description extends BaseJavaMigration {
}
case class V5_MetaDescription(metaDescription: String, language: String)
+object V5_MetaDescription {
+ implicit val encoder: Encoder[V5_MetaDescription] = deriveEncoder
+ implicit val decoder: Decoder[V5_MetaDescription] = deriveDecoder
+}
case class V5_SubjectFrontPageData(
id: Option[Long],
name: String,
@@ -89,3 +100,7 @@ case class V5_SubjectFrontPageData(
latestContent: Option[List[String]],
goTo: List[String]
)
+object V5_SubjectFrontPageData {
+ implicit val encoder: Encoder[V5_SubjectFrontPageData] = deriveEncoder
+ implicit val decoder: Decoder[V5_SubjectFrontPageData] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V8__add_subject_links.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V8__add_subject_links.scala
index 054545d1c0..6d5a14a6b6 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V8__add_subject_links.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/db/migration/V8__add_subject_links.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import io.circe.generic.auto.*
import io.circe.generic.semiauto.*
import io.circe.parser.parse
import io.circe.syntax.*
@@ -22,10 +21,6 @@ import scalikejdbc.*
import scala.util.{Failure, Success}
class V8__add_subject_links extends BaseJavaMigration {
-
- implicit val decoder: Decoder[V1_DBFrontPageData] = deriveDecoder
- implicit val encoder: Encoder[V1_DBFrontPageData] = deriveEncoder
-
override def migrate(context: Context): Unit = DB(context.getConnection)
.autoClose(false)
.withinTx { implicit session =>
@@ -78,3 +73,7 @@ case class V8_SubjectFrontPageData(
buildsOn: List[String],
leadsTo: List[String]
)
+object V8_SubjectFrontPageData {
+ implicit val encoder: Encoder[V8_SubjectFrontPageData] = deriveEncoder
+ implicit val decoder: Decoder[V8_SubjectFrontPageData] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdateBannerImageDTO.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdateBannerImageDTO.scala
index 8e54d9eaf4..4c5308fd39 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdateBannerImageDTO.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdateBannerImageDTO.scala
@@ -8,4 +8,11 @@
package no.ndla.frontpageapi.model.api
+import io.circe.generic.semiauto.{deriveEncoder, deriveDecoder}
+import io.circe.{Encoder, Decoder}
+
case class NewOrUpdateBannerImageDTO(mobileImageId: Option[Long], desktopImageId: Long)
+object NewOrUpdateBannerImageDTO {
+ implicit val encoder: Encoder[NewOrUpdateBannerImageDTO] = deriveEncoder
+ implicit val decoder: Decoder[NewOrUpdateBannerImageDTO] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedAboutSubjectDTO.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedAboutSubjectDTO.scala
index 2e84b22550..6512a01d92 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedAboutSubjectDTO.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedAboutSubjectDTO.scala
@@ -8,9 +8,17 @@
package no.ndla.frontpageapi.model.api
+import io.circe.generic.semiauto.{deriveEncoder, deriveDecoder}
+import io.circe.{Encoder, Decoder}
+
case class NewOrUpdatedAboutSubjectDTO(
title: String,
description: String,
language: String,
visualElement: NewOrUpdatedVisualElementDTO
)
+object NewOrUpdatedAboutSubjectDTO {
+
+ implicit val encoder: Encoder[NewOrUpdatedAboutSubjectDTO] = deriveEncoder
+ implicit val decoder: Decoder[NewOrUpdatedAboutSubjectDTO] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedMetaDescriptionDTO.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedMetaDescriptionDTO.scala
index 3e05a05e0d..f9a00db1ae 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedMetaDescriptionDTO.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedMetaDescriptionDTO.scala
@@ -8,7 +8,14 @@
package no.ndla.frontpageapi.model.api
+import io.circe.generic.semiauto.{deriveEncoder, deriveDecoder}
+import io.circe.{Encoder, Decoder}
+
case class NewOrUpdatedMetaDescriptionDTO(
metaDescription: String,
language: String
)
+object NewOrUpdatedMetaDescriptionDTO {
+ implicit val encoder: Encoder[NewOrUpdatedMetaDescriptionDTO] = deriveEncoder
+ implicit val decoder: Decoder[NewOrUpdatedMetaDescriptionDTO] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedVisualElementDTO.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedVisualElementDTO.scala
index 2a8f7f6448..febfae84e9 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedVisualElementDTO.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewOrUpdatedVisualElementDTO.scala
@@ -8,4 +8,11 @@
package no.ndla.frontpageapi.model.api
+import io.circe.generic.semiauto.{deriveEncoder, deriveDecoder}
+import io.circe.{Encoder, Decoder}
+
case class NewOrUpdatedVisualElementDTO(`type`: String, id: String, alt: Option[String])
+object NewOrUpdatedVisualElementDTO {
+ implicit val encoder: Encoder[NewOrUpdatedVisualElementDTO] = deriveEncoder
+ implicit val decoder: Decoder[NewOrUpdatedVisualElementDTO] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewSubjectPageDTO.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewSubjectPageDTO.scala
index f72f7f7746..2357998ac1 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewSubjectPageDTO.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/NewSubjectPageDTO.scala
@@ -8,6 +8,10 @@
package no.ndla.frontpageapi.model.api
+import io.circe.generic.semiauto.*
+import io.circe.Encoder
+import io.circe.Decoder
+
case class NewSubjectPageDTO(
name: String,
externalId: Option[String],
@@ -19,3 +23,8 @@ case class NewSubjectPageDTO(
buildsOn: Option[List[String]],
leadsTo: Option[List[String]]
)
+
+object NewSubjectPageDTO {
+ implicit val encoder: Encoder[NewSubjectPageDTO] = deriveEncoder
+ implicit val decoder: Decoder[NewSubjectPageDTO] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/UpdatedSubjectPageDTO.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/UpdatedSubjectPageDTO.scala
index 3131f9b083..cc0f5a1c55 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/UpdatedSubjectPageDTO.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/api/UpdatedSubjectPageDTO.scala
@@ -8,6 +8,9 @@
package no.ndla.frontpageapi.model.api
+import io.circe.generic.semiauto.*
+import io.circe.{Decoder, Encoder}
+
case class UpdatedSubjectPageDTO(
name: Option[String],
externalId: Option[String],
@@ -19,3 +22,7 @@ case class UpdatedSubjectPageDTO(
buildsOn: Option[List[String]],
leadsTo: Option[List[String]]
)
+object UpdatedSubjectPageDTO {
+ implicit val encoder: Encoder[UpdatedSubjectPageDTO] = deriveEncoder
+ implicit val decoder: Decoder[UpdatedSubjectPageDTO] = deriveDecoder
+}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FilmFrontPage.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FilmFrontPage.scala
index 300cc12df8..11b4d4ee90 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FilmFrontPage.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FilmFrontPage.scala
@@ -10,7 +10,6 @@ package no.ndla.frontpageapi.model.domain
import cats.implicits.*
import io.circe.generic.semiauto.*
-import io.circe.generic.auto.*
import io.circe.parser.*
import io.circe.{Decoder, Encoder}
import no.ndla.common.model.domain.frontpage.{AboutSubject, MovieTheme}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FrontPage.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FrontPage.scala
index 4c87ba27dc..742c4baf94 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FrontPage.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/model/domain/FrontPage.scala
@@ -8,9 +8,8 @@
package no.ndla.frontpageapi.model.domain
-import io.circe.Encoder
+import io.circe.{Decoder, Encoder}
import io.circe.generic.semiauto.*
-import io.circe.generic.auto.*
import io.circe.parser.*
import no.ndla.frontpageapi.Props
import scalikejdbc.WrappedResultSet
@@ -20,6 +19,10 @@ import cats.implicits.*
import scala.util.Try
case class Menu(articleId: Long, menu: List[Menu], hideLevel: Boolean)
+object Menu {
+ implicit val encoder: Encoder[Menu] = deriveEncoder[Menu]
+ implicit val decoder: Decoder[Menu] = deriveDecoder[Menu]
+}
case class FrontPage(
articleId: Long,
@@ -28,6 +31,7 @@ case class FrontPage(
object FrontPage {
implicit val encoder: Encoder[FrontPage] = deriveEncoder[FrontPage]
+ implicit val decoder: Decoder[FrontPage] = deriveDecoder[FrontPage]
private[domain] def decodeJson(document: String): Try[FrontPage] = {
parse(document).flatMap(_.as[FrontPage]).toTry
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FilmFrontPageRepository.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FilmFrontPageRepository.scala
index 5b3cb97356..a4207209c7 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FilmFrontPageRepository.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FilmFrontPageRepository.scala
@@ -19,7 +19,7 @@ import scala.util.{Failure, Success, Try}
trait FilmFrontPageRepository {
this: DataSource & DBFilmFrontPage =>
- val filmFrontPageRepository: FilmFrontPageRepository
+ lazy val filmFrontPageRepository: FilmFrontPageRepository
class FilmFrontPageRepository {
val logger: Logger = org.log4s.getLogger
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FrontPageRepository.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FrontPageRepository.scala
index 5a59863413..5bc430a9af 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FrontPageRepository.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/FrontPageRepository.scala
@@ -20,7 +20,7 @@ import scala.util.Try
trait FrontPageRepository {
this: DataSource & DBFrontPage =>
- val frontPageRepository: FrontPageRepository
+ lazy val frontPageRepository: FrontPageRepository
class FrontPageRepository extends StrictLogging {
import FrontPage._
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/SubjectPageRepository.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/SubjectPageRepository.scala
index 0974791b42..728ab431e6 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/SubjectPageRepository.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/repository/SubjectPageRepository.scala
@@ -13,7 +13,6 @@ import org.log4s.{Logger, getLogger}
import org.postgresql.util.PGobject
import scalikejdbc.*
import io.circe.syntax.*
-import io.circe.generic.auto.*
import no.ndla.common.model.domain.frontpage.SubjectPage
import no.ndla.database.DataSource
import no.ndla.frontpageapi.model.domain.DBSubjectPage
@@ -22,7 +21,7 @@ import scala.util.{Failure, Success, Try}
trait SubjectPageRepository {
this: DataSource & DBSubjectPage =>
- val subjectPageRepository: SubjectPageRepository
+ lazy val subjectPageRepository: SubjectPageRepository
class SubjectPageRepository {
val logger: Logger = getLogger
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ConverterService.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ConverterService.scala
index 20d5c59aec..75c3d40335 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ConverterService.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ConverterService.scala
@@ -34,8 +34,6 @@ trait ConverterService {
this: Props =>
object ConverterService {
- import props.{BrightcoveAccountId, BrightcovePlayer, RawImageApiUrl}
-
private def toApiMenu(menu: domain.Menu): model.api.MenuDTO =
model.api.MenuDTO(menu.articleId, menu.menu.map(toApiMenu), Some(menu.hideLevel))
@@ -138,7 +136,7 @@ trait ConverterService {
val url = visual.`type` match {
case VisualElementType.Image => createImageUrl(visual.id.toLong)
case VisualElementType.Brightcove =>
- s"https://players.brightcove.net/$BrightcoveAccountId/${BrightcovePlayer}_default/index.html?videoId=${visual.id}"
+ s"https://players.brightcove.net/${props.BrightcoveAccountId}/${props.BrightcovePlayer}_default/index.html?videoId=${visual.id}"
}
VisualElementDTO(visual.`type`.entryName, url, visual.alt)
}
@@ -236,6 +234,6 @@ trait ConverterService {
}
private def createImageUrl(id: Long): String = createImageUrl(id.toString)
- private def createImageUrl(id: String): String = s"$RawImageApiUrl/id/$id"
+ private def createImageUrl(id: String): String = s"${props.RawImageApiUrl}/id/$id"
}
}
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ReadService.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ReadService.scala
index 8cfd9446a2..f11628c294 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ReadService.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/ReadService.scala
@@ -23,7 +23,7 @@ import scala.util.{Failure, Success, Try}
trait ReadService {
this: SubjectPageRepository & FrontPageRepository & FilmFrontPageRepository & ConverterService =>
- val readService: ReadService
+ lazy val readService: ReadService
class ReadService {
@@ -47,7 +47,7 @@ trait ReadService {
}
}
- def subjectPage(id: Long, language: String, fallback: Boolean): Try[SubjectPageDTO] = {
+ def subjectPage(id: Long, language: String, fallback: Boolean): Try[SubjectPageDTO] = permitTry {
val maybeSubject = subjectPageRepository.withId(id).?
val converted = maybeSubject.traverse(ConverterService.toApiSubjectPage(_, language, fallback)).?
converted.toTry(SubjectPageNotFoundException(id))
@@ -58,7 +58,7 @@ trait ReadService {
pageSize: Int,
language: String,
fallback: Boolean
- ): Try[List[SubjectPageDTO]] = {
+ ): Try[List[SubjectPageDTO]] = permitTry {
val offset = pageSize * (page - 1)
val data = subjectPageRepository.all(offset, pageSize).?
val converted = data.map(ConverterService.toApiSubjectPage(_, language, fallback))
diff --git a/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/WriteService.scala b/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/WriteService.scala
index 5002e41e3e..4d5359211c 100644
--- a/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/WriteService.scala
+++ b/frontpage-api/src/main/scala/no/ndla/frontpageapi/service/WriteService.scala
@@ -21,7 +21,7 @@ import scala.util.{Failure, Success, Try}
trait WriteService {
this: SubjectPageRepository & FrontPageRepository & FilmFrontPageRepository & Props & ConverterService =>
- val writeService: WriteService
+ lazy val writeService: WriteService
class WriteService {
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestData.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestData.scala
index c6b7772698..79469bd543 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestData.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestData.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi
-import io.circe.generic.auto.*
import io.circe.syntax.*
import no.ndla.common.model
import no.ndla.common.model.api.frontpage.{AboutSubjectDTO, BannerImageDTO, SubjectPageDTO, VisualElementDTO}
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestEnvironment.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestEnvironment.scala
index d11d6975a9..b6452567ef 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestEnvironment.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/TestEnvironment.scala
@@ -41,22 +41,22 @@ trait TestEnvironment
with DBMigrator {
override lazy val props = new FrontpageApiProperties
- override val clock: SystemClock = mock[SystemClock]
- override val migrator: DBMigrator = mock[DBMigrator]
- override val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val clock: SystemClock = mock[SystemClock]
+ override lazy val migrator: DBMigrator = mock[DBMigrator]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
- override val filmPageController: FilmPageController = mock[FilmPageController]
- override val subjectPageController: SubjectPageController = mock[SubjectPageController]
- override val frontPageController: FrontPageController = mock[FrontPageController]
- override val subjectPageRepository: SubjectPageRepository = mock[SubjectPageRepository]
- override val frontPageRepository: FrontPageRepository = mock[FrontPageRepository]
- override val filmFrontPageRepository: FilmFrontPageRepository = mock[FilmFrontPageRepository]
- override val healthController: TapirHealthController = mock[TapirHealthController]
- override val readService: ReadService = mock[ReadService]
- override val writeService: WriteService = mock[WriteService]
+ override lazy val filmPageController: FilmPageController = mock[FilmPageController]
+ override lazy val subjectPageController: SubjectPageController = mock[SubjectPageController]
+ override lazy val frontPageController: FrontPageController = mock[FrontPageController]
+ override lazy val subjectPageRepository: SubjectPageRepository = mock[SubjectPageRepository]
+ override lazy val frontPageRepository: FrontPageRepository = mock[FrontPageRepository]
+ override lazy val filmFrontPageRepository: FilmFrontPageRepository = mock[FilmFrontPageRepository]
+ override lazy val healthController: TapirHealthController = mock[TapirHealthController]
+ override lazy val readService: ReadService = mock[ReadService]
+ override lazy val writeService: WriteService = mock[WriteService]
- override val ndlaClient: NdlaClient = mock[NdlaClient]
- override val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V4__AddLanguageToAboutTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V4__AddLanguageToAboutTest.scala
index c0448564ec..57dde281ef 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V4__AddLanguageToAboutTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V4__AddLanguageToAboutTest.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import no.ndla.frontpageapi.db.migration.{V2_DBSubjectPage, V4__add_language_to_about}
import no.ndla.frontpageapi.{TestEnvironment, UnitSuite}
class V4__AddLanguageToAboutTest extends UnitSuite with TestEnvironment {
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V5__AddMetaDescriptionTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V5__AddMetaDescriptionTest.scala
index 14fc4f5977..a070369828 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V5__AddMetaDescriptionTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V5__AddMetaDescriptionTest.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import no.ndla.frontpageapi.db.migration.{V2_DBSubjectPage, V5__add_meta_description}
import no.ndla.frontpageapi.{TestEnvironment, UnitSuite}
class V5__AddMetaDescriptionTest extends UnitSuite with TestEnvironment {
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V8__AddSubjectLinksTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V8__AddSubjectLinksTest.scala
index 0fe52608cf..5f2a9cedd7 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V8__AddSubjectLinksTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/db/migration/V8__AddSubjectLinksTest.scala
@@ -8,7 +8,6 @@
package no.ndla.frontpageapi.db.migration
-import no.ndla.frontpageapi.db.migration.{V2_DBSubjectPage, V8__add_subject_links}
import no.ndla.frontpageapi.{TestEnvironment, UnitSuite}
class V8__AddSubjectLinksTest extends UnitSuite with TestEnvironment {
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/api/FrontPageTest/FrontPageTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/api/FrontPageTest/FrontPageTest.scala
index b09a7c5871..8052cb9474 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/api/FrontPageTest/FrontPageTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/api/FrontPageTest/FrontPageTest.scala
@@ -9,7 +9,6 @@
package no.ndla.frontpageapi.model.api.FrontPageTest
import no.ndla.frontpageapi.{TestEnvironment, UnitSuite}
-import io.circe.generic.auto.*
import io.circe.syntax.*
import io.circe.parser.*
import no.ndla.common.model.api.{FrontPageDTO, MenuDTO}
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/domain/SubjectPageTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/domain/SubjectPageTest.scala
index e103935b32..33b39a68f8 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/domain/SubjectPageTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/model/domain/SubjectPageTest.scala
@@ -15,8 +15,8 @@ import scala.util.Success
class SubjectPageTest extends UnitSuite with TestEnvironment {
test("decodeJson should use correct id") {
- val Success(subject) = SubjectPage.decodeJson(TestData.domainSubjectJson, 10)
- subject.id should be(Some(10))
+ val subject = SubjectPage.decodeJson(TestData.domainSubjectJson, 10)
+ subject.map(_.id) should be(Success(Some(10)))
}
}
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ConverterServiceTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ConverterServiceTest.scala
index 0addf01b84..f6ef474d43 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ConverterServiceTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ConverterServiceTest.scala
@@ -42,12 +42,12 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
val about = TestData.apiNewSubjectPage.about.map(_.copy(visualElement = visualElement))
val page = TestData.apiNewSubjectPage.copy(about = about)
- val Failure(res: ValidationException) = ConverterService.toDomainSubjectPage(page)
- val expectedError = ValidationException(
+ val result = ConverterService.toDomainSubjectPage(page)
+ val expectedError = ValidationException(
"visualElement.type",
"'not an image' is an invalid visual element type"
)
- res should be(expectedError)
+ result should be(Failure(expectedError))
}
test("toDomainSubjectPage should return a success if visual element type is valid") {
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ReadServiceTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ReadServiceTest.scala
index 712bd5fc34..5afe7cd587 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ReadServiceTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/ReadServiceTest.scala
@@ -17,7 +17,7 @@ import org.mockito.Mockito.when
import scala.util.Success
class ReadServiceTest extends UnitSuite with TestEnvironment {
- override val readService: ReadService = new ReadService
+ override lazy val readService: ReadService = new ReadService
test("That all subjectpages does not fail on 404 because of language") {
val norwegianSubjectPage = TestData.domainSubjectPage.copy(
@@ -39,7 +39,8 @@ class ReadServiceTest extends UnitSuite with TestEnvironment {
)
)
- when(subjectPageRepository.all(any, any)(any)).thenReturn(Success(List(norwegianSubjectPage, englishSubjectPage)))
+ when(subjectPageRepository.all(any, any)(using any))
+ .thenReturn(Success(List(norwegianSubjectPage, englishSubjectPage)))
val result = readService.subjectPages(1, 10, "en", fallback = false)
result.get.map(_.id) should be(List(2))
diff --git a/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/WriteServiceTest.scala b/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/WriteServiceTest.scala
index ea5b8dc051..252fdafec8 100644
--- a/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/WriteServiceTest.scala
+++ b/frontpage-api/src/test/scala/no/ndla/frontpageapi/service/WriteServiceTest.scala
@@ -18,7 +18,7 @@ import org.mockito.Mockito.when
import scala.util.Success
class WriteServiceTest extends UnitSuite with TestEnvironment {
- override val writeService: WriteService = new WriteService
+ override lazy val writeService: WriteService = new WriteService
test("That language is deleted for subject page") {
val subjectPage = TestData.domainSubjectPage.copy(
@@ -27,7 +27,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
metaDescription = TestData.domainSubjectPage.metaDescription ++ Seq(MetaDescription("Description", "nn"))
)
when(subjectPageRepository.withId(any)).thenReturn(Success(Some(subjectPage)))
- when(subjectPageRepository.updateSubjectPage(any)(any)).thenAnswer(i => Success(i.getArgument(0)))
+ when(subjectPageRepository.updateSubjectPage(any)(using any)).thenAnswer(i => Success(i.getArgument(0)))
val result = writeService.deleteSubjectPageLanguage(subjectPage.id.get, "nn")
result should be(
@@ -41,7 +41,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
test("That deleting last language for subject page throws exception") {
when(subjectPageRepository.withId(any)).thenReturn(Success(Some(TestData.domainSubjectPage)))
- when(subjectPageRepository.updateSubjectPage(any)(any)).thenAnswer(i => Success(i.getArgument(0)))
+ when(subjectPageRepository.updateSubjectPage(any)(using any)).thenAnswer(i => Success(i.getArgument(0)))
val result = writeService.deleteSubjectPageLanguage(TestData.domainSubjectPage.id.get, "nb")
result.isFailure should be(true)
@@ -55,8 +55,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
movieTheme.copy(name = movieTheme.name ++ Seq(MovieThemeName("FooBar", "nn")))
)
)
- when(filmFrontPageRepository.get(any)).thenReturn(Some(filmFrontPage))
- when(filmFrontPageRepository.update(any)(any)).thenAnswer(i => Success(i.getArgument(0)))
+ when(filmFrontPageRepository.get(using any)).thenReturn(Some(filmFrontPage))
+ when(filmFrontPageRepository.update(any)(using any)).thenAnswer(i => Success(i.getArgument(0)))
val result = writeService.deleteFilmFrontPageLanguage("nn")
result should be(Success(ConverterService.toApiFilmFrontPage(TestData.domainFilmFrontPage, None)))
@@ -69,8 +69,8 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
movieTheme.copy(name = movieTheme.name.filter(_.language == "nb"))
)
)
- when(filmFrontPageRepository.get(any)).thenReturn(Some(filmFrontPage))
- when(filmFrontPageRepository.update(any)(any)).thenAnswer(i => Success(i.getArgument(0)))
+ when(filmFrontPageRepository.get(using any)).thenReturn(Some(filmFrontPage))
+ when(filmFrontPageRepository.update(any)(using any)).thenAnswer(i => Success(i.getArgument(0)))
val result = writeService.deleteFilmFrontPageLanguage("nb")
result.isFailure should be(true)
diff --git a/image-api/src/main/scala/no/ndla/imageapi/ComponentRegistry.scala b/image-api/src/main/scala/no/ndla/imageapi/ComponentRegistry.scala
index c4065033d8..52a8470765 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/ComponentRegistry.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/ComponentRegistry.scala
@@ -66,40 +66,40 @@ class ComponentRegistry(properties: ImageApiProperties)
with Random
with NdlaS3Client
with SwaggerDocControllerConfig {
- override val props: ImageApiProperties = properties
+ override lazy val props: ImageApiProperties = properties
- override val migrator: DBMigrator = DBMigrator(
+ override lazy val migrator: DBMigrator = DBMigrator(
new V6__AddAgreementToImages,
new V7__TranslateUntranslatedAuthors
)
override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
- lazy val s3Client = new NdlaS3Client(props.StorageName, props.StorageRegion)
+ override lazy val s3Client = new NdlaS3Client(props.StorageName, props.StorageRegion)
- lazy val imageIndexService = new ImageIndexService
- lazy val imageSearchService = new ImageSearchService
- lazy val tagIndexService = new TagIndexService
- lazy val tagSearchService = new TagSearchService
- lazy val imageRepository = new ImageRepository
- lazy val readService = new ReadService
- lazy val writeService = new WriteService
- lazy val validationService = new ValidationService
- lazy val imageStorage = new AmazonImageStorageService
- lazy val ndlaClient = new NdlaClient
- lazy val converterService = new ConverterService
- var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
- lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
- lazy val searchConverterService = new SearchConverterService
+ override lazy val imageIndexService = new ImageIndexService
+ override lazy val imageSearchService = new ImageSearchService
+ override lazy val tagIndexService = new TagIndexService
+ override lazy val tagSearchService = new TagSearchService
+ override lazy val imageRepository = new ImageRepository
+ override lazy val readService = new ReadService
+ override lazy val writeService = new WriteService
+ override lazy val validationService = new ValidationService
+ override lazy val imageStorage = new AmazonImageStorageService
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val converterService = new ConverterService
+ var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
+ override lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
+ override lazy val searchConverterService = new SearchConverterService
- lazy val imageConverter = new ImageConverter
- lazy val clock = new SystemClock
- lazy val random = new Random
+ override lazy val imageConverter = new ImageConverter
+ override lazy val clock = new SystemClock
+ override lazy val random = new Random
- lazy val imageControllerV2 = new ImageControllerV2
- lazy val imageControllerV3 = new ImageControllerV3
- lazy val rawController = new RawController
- lazy val internController = new InternController
- lazy val healthController = new HealthController
+ override lazy val imageControllerV2 = new ImageControllerV2
+ override lazy val imageControllerV3 = new ImageControllerV3
+ override lazy val rawController = new RawController
+ override lazy val internController = new InternController
+ override lazy val healthController = new HealthController
val swagger = new SwaggerController(
List[TapirController](
diff --git a/image-api/src/main/scala/no/ndla/imageapi/ImageApiProperties.scala b/image-api/src/main/scala/no/ndla/imageapi/ImageApiProperties.scala
index 39e3fd9013..9addde3904 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/ImageApiProperties.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/ImageApiProperties.scala
@@ -16,7 +16,7 @@ import no.ndla.network.{AuthUser, Domains}
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: ImageApiProperties
+ lazy val props: ImageApiProperties
}
class ImageApiProperties extends BaseProps with DatabaseProps with StrictLogging {
diff --git a/image-api/src/main/scala/no/ndla/imageapi/controller/BaseImageController.scala b/image-api/src/main/scala/no/ndla/imageapi/controller/BaseImageController.scala
index 65dadbe31b..9a9bae2cd7 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/controller/BaseImageController.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/controller/BaseImageController.scala
@@ -27,9 +27,6 @@ trait BaseImageController {
/** Base class for sharing code between Image controllers. */
trait BaseImageController {
-
- import props.*
-
val queryParam: EndpointInput.Query[Option[String]] =
query[Option[String]]("query")
.description("Return only images with titles, alt-texts or tags matching the specified query.")
@@ -66,7 +63,7 @@ trait BaseImageController {
.description("The page number of the search hits to display.")
val pageSize: EndpointInput.Query[Option[Int]] = query[Option[Int]]("page-size")
.description(
- s"The number of search hits to display for each page. Defaults to $DefaultPageSize and max is $MaxPageSize."
+ s"The number of search hits to display for each page. Defaults to ${props.DefaultPageSize} and max is ${props.MaxPageSize}."
)
val pathImageId: EndpointInput.PathCapture[Long] =
@@ -77,11 +74,11 @@ trait BaseImageController {
path[String]("external_id").description("External node id of the image that needs to be fetched.")
val scrollId: EndpointInput.Query[Option[String]] = query[Option[String]]("search-context").description(
- s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${InitialScrollContextKeywords
+ s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${props.InitialScrollContextKeywords
.mkString("[", ",", "]")}.
|When scrolling, the parameters from the initial search is used, except in the case of '${this.language.name}'.
- |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after $ElasticSearchScrollKeepAlive).
- |If you are not paginating past $ElasticSearchIndexMaxResultWindow hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
+ |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after ${props.ElasticSearchScrollKeepAlive}).
+ |If you are not paginating past ${props.ElasticSearchIndexMaxResultWindow} hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
|""".stripMargin
)
@@ -106,7 +103,7 @@ trait BaseImageController {
query[Option[Boolean]]("podcast-friendly")
.description("Filter images that are podcast friendly. Width==heigth and between 1400 and 3000.")
- val maxImageFileSizeBytes: Int = MaxImageFileSizeBytes
+ val maxImageFileSizeBytes: Int = props.MaxImageFileSizeBytes
def doWithStream[T](filePart: Part[File])(f: UploadedFile => Try[T]): Try[T] = {
val file = UploadedFile.fromFilePart(filePart)
diff --git a/image-api/src/main/scala/no/ndla/imageapi/controller/HealthController.scala b/image-api/src/main/scala/no/ndla/imageapi/controller/HealthController.scala
index a3b3635c62..86795123d3 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/controller/HealthController.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/controller/HealthController.scala
@@ -15,7 +15,7 @@ import no.ndla.network.tapir.TapirHealthController
trait HealthController {
this: ImageStorageService & ImageRepository & Props & TapirHealthController =>
- val healthController: HealthController
+ lazy val healthController: HealthController
class HealthController extends TapirHealthController {
diff --git a/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV2.scala b/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV2.scala
index 9fefc24e1b..e69c63d071 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV2.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV2.scala
@@ -33,12 +33,10 @@ import scala.util.{Failure, Success, Try}
trait ImageControllerV2 {
this: ImageRepository & ImageSearchService & ConverterService & ReadService & WriteService & SearchConverterService &
Props & ErrorHandling & BaseImageController & TapirController =>
- val imageControllerV2: ImageControllerV2
+ lazy val imageControllerV2: ImageControllerV2
class ImageControllerV2 extends TapirController with BaseImageController {
import ErrorHelpers.*
- import props.*
-
override val serviceName: String = "images V2"
override val prefix: EndpointInput[Unit] = "image-api" / "v2" / "images"
override val endpoints: List[ServerEndpoint[Any, Eff]] = List(
@@ -65,7 +63,7 @@ trait ImageControllerV2 {
orFunction: => Try[(SearchResultDTO, DynamicHeaders)]
): Try[(SearchResultDTO, DynamicHeaders)] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
imageSearchService.scrollV2(scroll, language.code, user) match {
case Success(scrollResult) =>
val body = searchConverterService.asApiSearchResult(scrollResult)
@@ -167,7 +165,7 @@ trait ImageControllerV2 {
) =>
scrollSearchOr(scrollId, language, user) {
val sort = Sort.valueOf(sortStr)
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
val modelReleasedStatus = modelReleased.values.flatMap(ModelReleasedStatus.valueOf)
search(
@@ -208,7 +206,7 @@ trait ImageControllerV2 {
val page = searchParams.page
val podcastFriendly = searchParams.podcastFriendly
val sort = searchParams.sort
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
val modelReleasedStatus =
searchParams.modelReleased.getOrElse(Seq.empty).flatMap(ModelReleasedStatus.valueOf)
diff --git a/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV3.scala b/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV3.scala
index 93a828817d..be3ec315ee 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV3.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/controller/ImageControllerV3.scala
@@ -33,12 +33,10 @@ import scala.util.{Failure, Success, Try}
trait ImageControllerV3 {
this: ImageRepository & ImageSearchService & ConverterService & ReadService & WriteService & SearchConverterService &
Props & ErrorHandling & BaseImageController & TapirController =>
- val imageControllerV3: ImageControllerV3
+ lazy val imageControllerV3: ImageControllerV3
class ImageControllerV3 extends TapirController with BaseImageController {
import ErrorHelpers.*
- import props.*
-
override val serviceName: String = "images V3"
override val prefix: EndpointInput[Unit] = "image-api" / "v3" / "images"
@@ -56,7 +54,7 @@ trait ImageControllerV3 {
user: Option[TokenUser]
)(orFunction: => Try[(SearchResultV3DTO, DynamicHeaders)]): Try[(SearchResultV3DTO, DynamicHeaders)] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
for {
scrollResult <- imageSearchService.scroll(scroll, language)
body <- searchConverterService.asApiSearchResultV3(scrollResult, language, user)
@@ -162,7 +160,7 @@ trait ImageControllerV3 {
) =>
scrollSearchOr(scrollId, language.code, user) {
val sort = Sort.valueOf(sortStr)
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
val modelReleasedStatus = modelReleased.values.flatMap(ModelReleasedStatus.valueOf)
val licenseOpt = license.orElse(Option.when(includeCopyrighted)("all"))
@@ -209,7 +207,7 @@ trait ImageControllerV3 {
val page = searchParams.page
val podcastFriendly = searchParams.podcastFriendly
val sort = searchParams.sort
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
val modelReleasedStatus =
searchParams.modelReleased.getOrElse(Seq.empty).flatMap(ModelReleasedStatus.valueOf)
val userFilter = searchParams.users.getOrElse(List.empty)
diff --git a/image-api/src/main/scala/no/ndla/imageapi/controller/InternController.scala b/image-api/src/main/scala/no/ndla/imageapi/controller/InternController.scala
index e5c601b87f..dddf6547d3 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/controller/InternController.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/controller/InternController.scala
@@ -32,7 +32,7 @@ import scala.util.{Failure, Success}
trait InternController {
this: ImageRepository & ReadService & ConverterService & ImageIndexService & TagIndexService & ImageRepository &
Props & ErrorHandling & TapirController =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController with StrictLogging {
import ErrorHelpers.*
diff --git a/image-api/src/main/scala/no/ndla/imageapi/controller/RawController.scala b/image-api/src/main/scala/no/ndla/imageapi/controller/RawController.scala
index d97cdffd62..861034f3f0 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/controller/RawController.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/controller/RawController.scala
@@ -26,7 +26,7 @@ import scala.util.{Failure, Success, Try}
trait RawController {
this: ImageStorageService & ImageConverter & ImageRepository & ErrorHandling & Props & ReadService &
TapirController =>
- val rawController: RawController
+ lazy val rawController: RawController
class RawController extends TapirController {
override val serviceName: String = "raw"
diff --git a/image-api/src/main/scala/no/ndla/imageapi/model/domain/ImageStream.scala b/image-api/src/main/scala/no/ndla/imageapi/model/domain/ImageStream.scala
index 6254d22c85..4412094696 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/model/domain/ImageStream.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/model/domain/ImageStream.scala
@@ -16,5 +16,5 @@ trait ImageStream {
def stream: InputStream
def fileName: String
def format: String = fileName.substring(fileName.lastIndexOf(".") + 1)
- val sourceImage: BufferedImage
+ lazy val sourceImage: BufferedImage
}
diff --git a/image-api/src/main/scala/no/ndla/imageapi/repository/ImageRepository.scala b/image-api/src/main/scala/no/ndla/imageapi/repository/ImageRepository.scala
index 3b33927773..fb98faf4f6 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/repository/ImageRepository.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/repository/ImageRepository.scala
@@ -21,7 +21,7 @@ import scala.util.{Success, Try}
trait ImageRepository {
this: DataSource & ConverterService =>
- val imageRepository: ImageRepository
+ lazy val imageRepository: ImageRepository
class ImageRepository extends StrictLogging with Repository[ImageMetaInformation] {
def imageCount(implicit session: DBSession = ReadOnlyAutoSession): Long =
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/ConverterService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/ConverterService.scala
index abf343ccab..e8061bed9e 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/ConverterService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/ConverterService.scala
@@ -33,11 +33,9 @@ import scala.util.{Failure, Success, Try}
trait ConverterService {
this: Clock & Props =>
- val converterService: ConverterService
+ lazy val converterService: ConverterService
class ConverterService extends StrictLogging {
- import props.DefaultLanguage
-
def asApiAuthor(domainAuthor: commonDomain.Author): commonApi.AuthorDTO = {
commonApi.AuthorDTO(domainAuthor.`type`, domainAuthor.name)
}
@@ -100,16 +98,16 @@ trait ConverterService {
val rawPath = props.RawImageUrlBase
val title = findByLanguageOrBestEffort(imageMeta.titles, language)
.map(asApiImageTitle)
- .getOrElse(api.ImageTitleDTO("", DefaultLanguage))
+ .getOrElse(api.ImageTitleDTO("", props.DefaultLanguage))
val alttext = findByLanguageOrBestEffort(imageMeta.alttexts, language)
.map(asApiImageAltText)
- .getOrElse(api.ImageAltTextDTO("", DefaultLanguage))
+ .getOrElse(api.ImageAltTextDTO("", props.DefaultLanguage))
val tags = findByLanguageOrBestEffort(imageMeta.tags, language)
.map(asApiImageTag)
- .getOrElse(api.ImageTagDTO(Seq(), DefaultLanguage))
+ .getOrElse(api.ImageTagDTO(Seq(), props.DefaultLanguage))
val caption = findByLanguageOrBestEffort(imageMeta.captions, language)
.map(asApiCaption)
- .getOrElse(api.ImageCaptionDTO("", DefaultLanguage))
+ .getOrElse(api.ImageCaptionDTO("", props.DefaultLanguage))
getImageFromMeta(imageMeta, language).flatMap(image => {
val apiUrl = asApiUrl(image.fileName, rawPath.some)
@@ -174,16 +172,16 @@ trait ConverterService {
): Try[api.ImageMetaInformationV2DTO] = {
val title = findByLanguageOrBestEffort(imageMeta.titles, language)
.map(asApiImageTitle)
- .getOrElse(api.ImageTitleDTO("", DefaultLanguage))
+ .getOrElse(api.ImageTitleDTO("", props.DefaultLanguage))
val alttext = findByLanguageOrBestEffort(imageMeta.alttexts, language)
.map(asApiImageAltText)
- .getOrElse(api.ImageAltTextDTO("", DefaultLanguage))
+ .getOrElse(api.ImageAltTextDTO("", props.DefaultLanguage))
val tags = findByLanguageOrBestEffort(imageMeta.tags, language)
.map(asApiImageTag)
- .getOrElse(api.ImageTagDTO(Seq(), DefaultLanguage))
+ .getOrElse(api.ImageTagDTO(Seq(), props.DefaultLanguage))
val caption = findByLanguageOrBestEffort(imageMeta.captions, language)
.map(asApiCaption)
- .getOrElse(api.ImageCaptionDTO("", DefaultLanguage))
+ .getOrElse(api.ImageCaptionDTO("", props.DefaultLanguage))
getImageFromMeta(imageMeta, language).flatMap(image => {
val apiUrl = asApiUrl(image.fileName, rawBaseUrl)
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/ImageConverter.scala b/image-api/src/main/scala/no/ndla/imageapi/service/ImageConverter.scala
index 12f44280f4..cead8be8a3 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/ImageConverter.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/ImageConverter.scala
@@ -24,7 +24,7 @@ import scala.util.{Success, Try}
trait ImageConverter {
this: Props =>
- val imageConverter: ImageConverter
+ lazy val imageConverter: ImageConverter
case class PixelPoint(x: Int, y: Int) // A point given with pixles
case class PercentPoint(x: Double, y: Double) { // A point given with values from MinValue to MaxValue. MinValue,MinValue is top-left, MaxValue,MaxValue is bottom-right
import PercentPoint.*
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/ImageStorageService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/ImageStorageService.scala
index 8625dce39d..2c9df53059 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/ImageStorageService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/ImageStorageService.scala
@@ -26,13 +26,12 @@ import scala.util.{Failure, Success, Try}
trait ImageStorageService {
this: NdlaS3Client & ReadService & Props =>
- val imageStorage: AmazonImageStorageService
+ lazy val imageStorage: AmazonImageStorageService
class AmazonImageStorageService extends StrictLogging {
- import props.ValidMimeTypes
case class NdlaImage(s3Object: NdlaS3Object, fileName: String) extends ImageStream {
- lazy val imageContent: Array[Byte] = s3Object.stream.readAllBytes()
- override val sourceImage: BufferedImage = ImageIO.read(stream)
+ lazy val imageContent: Array[Byte] = s3Object.stream.readAllBytes()
+ override lazy val sourceImage: BufferedImage = ImageIO.read(stream)
override def contentType: String = {
val s3ContentType = s3Object.contentType
@@ -42,7 +41,7 @@ trait ImageStorageService {
logger.warn(s"Couldn't get meta for $fileName so using s3 content-type of '$s3ContentType'", ex)
s3ContentType
case Success(meta)
- if meta.contentType != "" && meta.contentType != "binary/octet-stream" && ValidMimeTypes.contains(
+ if meta.contentType != "" && meta.contentType != "binary/octet-stream" && props.ValidMimeTypes.contains(
meta.contentType
) =>
updateContentType(s3Object.key, meta.contentType) match {
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/Random.scala b/image-api/src/main/scala/no/ndla/imageapi/service/Random.scala
index 6c4985f0c0..a9f63c2c46 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/Random.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/Random.scala
@@ -9,7 +9,7 @@
package no.ndla.imageapi.service
trait Random {
- val random: Random
+ lazy val random: Random
class Random {
def string(length: Int): String = {
scala.util.Random.alphanumeric.take(length).mkString
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/ReadService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/ReadService.scala
index 77818bfcda..3a9c2fe0a0 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/ReadService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/ReadService.scala
@@ -26,7 +26,7 @@ import scala.util.{Failure, Success, Try}
trait ReadService {
this: ConverterService & ValidationService & ImageRepository & ImageIndexService & ImageStorageService &
TagSearchService & SearchConverterService =>
- val readService: ReadService
+ lazy val readService: ReadService
class ReadService extends StrictLogging {
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/ValidationService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/ValidationService.scala
index 56d0c94dd8..1cd41012a0 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/ValidationService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/ValidationService.scala
@@ -22,29 +22,28 @@ import scala.util.{Failure, Success, Try}
trait ValidationService {
this: Props =>
- val validationService: ValidationService
+ lazy val validationService: ValidationService
class ValidationService {
- import props.{ValidFileExtensions, ValidMimeTypes}
def validateImageFile(imageFile: UploadedFile): Option[ValidationMessage] = {
val fn = imageFile.fileName.getOrElse("").stripPrefix("\"").stripSuffix("\"")
- if (!hasValidFileExtension(fn, ValidFileExtensions))
+ if (!hasValidFileExtension(fn, props.ValidFileExtensions))
return Some(
ValidationMessage(
"file",
- s"The file $fn does not have a known file extension. Must be one of ${ValidFileExtensions
+ s"The file $fn does not have a known file extension. Must be one of ${props.ValidFileExtensions
.mkString(",")}"
)
)
val actualMimeType = imageFile.contentType.getOrElse("")
- if (!ValidMimeTypes.contains(actualMimeType))
+ if (!props.ValidMimeTypes.contains(actualMimeType))
return Some(
ValidationMessage(
"file",
- s"The file $fn is not a valid image file. Only valid type is '${ValidMimeTypes.mkString(",")}', but was '$actualMimeType'"
+ s"The file $fn is not a valid image file. Only valid type is '${props.ValidMimeTypes.mkString(",")}', but was '$actualMimeType'"
)
)
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/WriteService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/WriteService.scala
index e95114c00a..825dbe6f39 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/WriteService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/WriteService.scala
@@ -40,7 +40,7 @@ import scala.util.{Failure, Success, Try}
trait WriteService {
this: ConverterService & ValidationService & ImageRepository & ImageIndexService & ImageStorageService &
TagIndexService & Clock & Props & Random =>
- val writeService: WriteService
+ lazy val writeService: WriteService
class WriteService extends StrictLogging {
@@ -87,7 +87,6 @@ trait WriteService {
case None =>
logger.warn("Deleting language for image without imagefile. This is weird.")
Success(())
- case _ => Success(())
}
}
@@ -95,7 +94,7 @@ trait WriteService {
imageId: Long,
language: String,
user: TokenUser
- ): Try[Option[ImageMetaInformation]] =
+ ): Try[Option[ImageMetaInformation]] = permitTry {
imageRepository.withId(imageId) match {
case Some(existing) if converterService.getSupportedLanguages(existing).contains(language) =>
val newImage = converterService.withoutLanguage(existing, language, user)
@@ -114,6 +113,7 @@ trait WriteService {
case None =>
Failure(new ImageNotFoundException(s"Image with id $imageId was not found, and could not be deleted."))
}
+ }
def deleteImageAndFiles(imageId: Long): Try[Long] = {
imageRepository.withId(imageId) match {
@@ -167,11 +167,11 @@ trait WriteService {
file: UploadedFile,
copiedFrom: Option[ImageMetaInformation],
language: String
- ): Try[ImageMetaInformation] = {
- validationService.validateImageFile(file) match {
- case Some(validationMessage) => return Failure(new ValidationException(errors = Seq(validationMessage)))
- case _ =>
- }
+ ): Try[ImageMetaInformation] = permitTry {
+ (validationService.validateImageFile(file) match {
+ case Some(validationMessage) => Failure(new ValidationException(errors = Seq(validationMessage)))
+ case _ => Success(())
+ }).?
validationService.validate(toInsert, copiedFrom).??
val insertedMeta = Try(imageRepository.insert(toInsert)).?
@@ -213,7 +213,7 @@ trait WriteService {
newImage: NewImageMetaInformationV2DTO,
file: UploadedFile,
user: TokenUser
- ): Try[ImageMetaInformation] = {
+ ): Try[ImageMetaInformation] = permitTry {
val toInsert = converterService.asDomainImageMetaInformationV2(newImage, user).?
insertAndStoreImage(toInsert, file, None, newImage.language)
}
@@ -334,7 +334,7 @@ trait WriteService {
oldImage: ImageMetaInformation,
language: String,
user: TokenUser
- ): Try[ImageMetaInformation] = {
+ ): Try[ImageMetaInformation] = permitTry {
val imageForLang = oldImage.images.getOrElse(Seq.empty).find(_.language == language)
val allOtherPaths = oldImage.images.getOrElse(Seq.empty).filterNot(_.language == language).map(_.fileName)
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageIndexService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageIndexService.scala
index 8a620665d1..6113671848 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageIndexService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageIndexService.scala
@@ -12,7 +12,6 @@ import com.sksamuel.elastic4s.ElasticDsl.*
import com.sksamuel.elastic4s.fields.{ElasticField, ObjectField}
import com.sksamuel.elastic4s.requests.indexes.IndexRequest
import com.sksamuel.elastic4s.requests.mappings.MappingDefinition
-import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.CirceUtil
import no.ndla.imageapi.Props
import no.ndla.imageapi.model.domain.ImageMetaInformation
@@ -22,9 +21,9 @@ import no.ndla.search.SearchLanguage
trait ImageIndexService {
this: SearchConverterService & IndexService & ImageRepository & Props & SearchLanguage =>
- val imageIndexService: ImageIndexService
+ lazy val imageIndexService: ImageIndexService
- class ImageIndexService extends StrictLogging with IndexService[ImageMetaInformation, SearchableImage] {
+ class ImageIndexService extends IndexService {
override val documentType: String = props.SearchDocument
override val searchIndex: String = props.SearchIndex
override val repository: Repository[ImageMetaInformation] = imageRepository
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageSearchService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageSearchService.scala
index 5f884fb6dd..9c011927bd 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageSearchService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/search/ImageSearchService.scala
@@ -30,13 +30,13 @@ import no.ndla.search.Elastic4sClient
import scala.util.{Failure, Success, Try}
trait ImageSearchService {
- this: Elastic4sClient & ImageIndexService & SearchService & SearchConverterService & Props & ErrorHandling =>
- val imageSearchService: ImageSearchService
- class ImageSearchService extends StrictLogging with SearchService[(SearchableImage, MatchedLanguage)] {
- import props.{ElasticSearchIndexMaxResultWindow, ElasticSearchScrollKeepAlive}
- private val noCopyright = boolQuery().not(termQuery("license", License.Copyrighted.toString))
- override val searchIndex: String = props.SearchIndex
- override val indexService: ImageIndexService = imageIndexService
+ this: Elastic4sClient & ImageIndexService & SearchService & SearchConverterService & Props & ErrorHandling &
+ IndexService =>
+ lazy val imageSearchService: ImageSearchService
+ class ImageSearchService extends SearchService[(SearchableImage, MatchedLanguage)] with StrictLogging {
+ private val noCopyright = boolQuery().not(termQuery("license", License.Copyrighted.toString))
+ override val searchIndex: String = props.SearchIndex
+ override val indexService: IndexService = imageIndexService
def hitToApiModel(hit: String, matchedLanguage: String): Try[(SearchableImage, MatchedLanguage)] = {
val searchableImage = CirceUtil.tryParseAs[SearchableImage](hit)
@@ -170,9 +170,9 @@ trait ImageSearchService {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.page.getOrElse(1) * numResults
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(new ResultWindowTooLargeException(ImageErrorHelpers.WINDOW_TOO_LARGE_DESCRIPTION))
} else {
@@ -188,7 +188,7 @@ trait ImageSearchService {
// Only add scroll param if it is first page
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/search/IndexService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/search/IndexService.scala
index 845d11fbf7..d6ef490e5b 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/search/IndexService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/search/IndexService.scala
@@ -12,6 +12,7 @@ import cats.implicits.*
import com.sksamuel.elastic4s.requests.indexes.IndexRequest
import com.typesafe.scalalogging.StrictLogging
import no.ndla.imageapi.Props
+import no.ndla.imageapi.model.domain.ImageMetaInformation
import no.ndla.imageapi.repository.{ImageRepository, Repository}
import no.ndla.search.model.domain.{BulkIndexResult, ReindexResult}
import no.ndla.search.{BaseIndexService, Elastic4sClient}
@@ -21,13 +22,13 @@ import scala.util.{Failure, Success, Try}
trait IndexService {
this: Elastic4sClient & ImageRepository & BaseIndexService & Props =>
- trait IndexService[D, T <: AnyRef] extends BaseIndexService with StrictLogging {
+ abstract class IndexService extends BaseIndexService with StrictLogging {
override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
- val repository: Repository[D]
+ val repository: Repository[ImageMetaInformation]
- def createIndexRequests(domainModel: D, indexName: String): Seq[IndexRequest]
+ def createIndexRequests(domainModel: ImageMetaInformation, indexName: String): Seq[IndexRequest]
- def indexDocument(imported: D): Try[D] = {
+ def indexDocument(imported: ImageMetaInformation): Try[ImageMetaInformation] = {
for {
_ <- createIndexIfNotExists()
requests = createIndexRequests(imported, searchIndex)
@@ -61,7 +62,7 @@ trait IndexService {
}
}
- def indexDocuments(contents: Seq[D], indexName: String): Try[BulkIndexResult] = {
+ def indexDocuments(contents: Seq[ImageMetaInformation], indexName: String): Try[BulkIndexResult] = {
if (contents.isEmpty) {
Success(BulkIndexResult.empty)
} else {
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchConverterService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchConverterService.scala
index 8a0672b2f9..a8b5ae16f9 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchConverterService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchConverterService.scala
@@ -31,7 +31,7 @@ import scala.util.{Failure, Success, Try}
trait SearchConverterService {
this: ConverterService & Props & SearchLanguage =>
- val searchConverterService: SearchConverterService
+ lazy val searchConverterService: SearchConverterService
class SearchConverterService extends StrictLogging {
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchService.scala
index 98a0d0f1f0..869483b73a 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/search/SearchService.scala
@@ -26,9 +26,9 @@ import cats.implicits.*
trait SearchService {
this: Elastic4sClient & IndexService & SearchConverterService & Props =>
- trait SearchService[T] extends StrictLogging {
+ abstract class SearchService[T] extends StrictLogging {
val searchIndex: String
- val indexService: IndexService[?, ?]
+ val indexService: IndexService
def hitToApiModel(hit: String, language: String): Try[T]
@@ -95,7 +95,7 @@ trait SearchService {
}
}
- protected def getStartAtAndNumResults(page: Option[Int], pageSize: Option[Int]): (Int, Int) = {
+ def getStartAtAndNumResults(page: Option[Int], pageSize: Option[Int]): (Int, Int) = {
val numResults = pageSize match {
case Some(num) =>
if (num > 0) num.min(props.MaxPageSize) else props.DefaultPageSize
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/search/TagIndexService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/search/TagIndexService.scala
index 60b94ba9bd..c54e41f6fd 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/search/TagIndexService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/search/TagIndexService.scala
@@ -11,7 +11,6 @@ package no.ndla.imageapi.service.search
import com.sksamuel.elastic4s.ElasticDsl.*
import com.sksamuel.elastic4s.requests.indexes.IndexRequest
import com.sksamuel.elastic4s.requests.mappings.MappingDefinition
-import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.CirceUtil
import no.ndla.imageapi.Props
import no.ndla.imageapi.model.domain.ImageMetaInformation
@@ -20,9 +19,9 @@ import no.ndla.imageapi.repository.{ImageRepository, Repository}
trait TagIndexService {
this: SearchConverterService & IndexService & ImageRepository & Props =>
- val tagIndexService: TagIndexService
+ lazy val tagIndexService: TagIndexService
- class TagIndexService extends StrictLogging with IndexService[ImageMetaInformation, SearchableTag] {
+ class TagIndexService extends IndexService {
override val documentType: String = props.TagSearchDocument
override val searchIndex: String = props.TagSearchIndex
override val repository: Repository[ImageMetaInformation] = imageRepository
diff --git a/image-api/src/main/scala/no/ndla/imageapi/service/search/TagSearchService.scala b/image-api/src/main/scala/no/ndla/imageapi/service/search/TagSearchService.scala
index 76b461e62f..4f86e68ca0 100644
--- a/image-api/src/main/scala/no/ndla/imageapi/service/search/TagSearchService.scala
+++ b/image-api/src/main/scala/no/ndla/imageapi/service/search/TagSearchService.scala
@@ -25,13 +25,12 @@ import scala.util.{Failure, Success, Try}
trait TagSearchService {
this: Elastic4sClient & SearchConverterService & SearchService & TagIndexService & SearchConverterService & Props &
- ErrorHandling =>
- val tagSearchService: TagSearchService
+ ErrorHandling & IndexService =>
+ lazy val tagSearchService: TagSearchService
- class TagSearchService extends StrictLogging with SearchService[String] {
- import props.{ElasticSearchIndexMaxResultWindow, ElasticSearchScrollKeepAlive, TagSearchIndex}
- override val searchIndex: String = TagSearchIndex
- override val indexService: TagIndexService = tagIndexService
+ class TagSearchService extends SearchService[String] with StrictLogging {
+ override val searchIndex: String = props.TagSearchIndex
+ override val indexService: IndexService = tagIndexService
override def hitToApiModel(hit: String, language: String): Try[String] = {
CirceUtil.tryParseAs[SearchableTag](hit).map(_.tag)
@@ -92,9 +91,9 @@ trait TagSearchService {
val (startAt, numResults) = getStartAtAndNumResults(Some(page), Some(pageSize))
val requestedResultWindow = pageSize * page
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are $props.ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
)
Failure(new ResultWindowTooLargeException(ImageErrorHelpers.WINDOW_TOO_LARGE_DESCRIPTION))
} else {
@@ -107,7 +106,7 @@ trait TagSearchService {
val searchWithScroll =
if (startAt != 0) { searchToExecute }
- else { searchToExecute.scroll(ElasticSearchScrollKeepAlive) }
+ else { searchToExecute.scroll(props.ElasticSearchScrollKeepAlive) }
e4sClient.execute(searchWithScroll) match {
case Success(response) =>
diff --git a/image-api/src/test/scala/no/ndla/imageapi/TestData.scala b/image-api/src/test/scala/no/ndla/imageapi/TestData.scala
index 6d16a8eb76..e447d6d7c8 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/TestData.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/TestData.scala
@@ -22,9 +22,9 @@ import java.awt.image.BufferedImage
import java.io.InputStream
import javax.imageio.ImageIO
-trait TestData {
+trait TestDataTrait {
- class TestData {
+ class TestDataClass {
def updated(): NDLADate = NDLADate.of(2017, 4, 1, 12, 15, 32)
diff --git a/image-api/src/test/scala/no/ndla/imageapi/TestEnvironment.scala b/image-api/src/test/scala/no/ndla/imageapi/TestEnvironment.scala
index f1c2eac1f7..65f7a0de0a 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/TestEnvironment.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/TestEnvironment.scala
@@ -70,41 +70,41 @@ trait TestEnvironment
with Props
with ErrorHandling
with DBMigrator
- with TestData
+ with TestDataTrait
with Random {
- lazy val props = new ImageApiProperties
- val TestData = new TestData
+ override lazy val props = new ImageApiProperties
+ val TestData: TestDataClass = new TestDataClass
- val migrator: DBMigrator = mock[DBMigrator]
- val s3Client: NdlaS3Client = mock[NdlaS3Client]
+ override lazy val migrator: DBMigrator = mock[DBMigrator]
+ override lazy val s3Client: NdlaS3Client = mock[NdlaS3Client]
- val dataSource: HikariDataSource = mock[HikariDataSource]
- val imageIndexService: ImageIndexService = mock[ImageIndexService]
- val imageSearchService: ImageSearchService = mock[ImageSearchService]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val imageIndexService: ImageIndexService = mock[ImageIndexService]
+ override lazy val imageSearchService: ImageSearchService = mock[ImageSearchService]
- val tagIndexService: TagIndexService = mock[TagIndexService]
- val tagSearchService: TagSearchService = mock[TagSearchService]
+ override lazy val tagIndexService: TagIndexService = mock[TagIndexService]
+ override lazy val tagSearchService: TagSearchService = mock[TagSearchService]
- val imageRepository: ImageRepository = mock[ImageRepository]
- val readService: ReadService = mock[ReadService]
- val writeService: WriteService = mock[WriteService]
- val imageStorage: AmazonImageStorageService = mock[AmazonImageStorageService]
+ override lazy val imageRepository: ImageRepository = mock[ImageRepository]
+ override lazy val readService: ReadService = mock[ReadService]
+ override lazy val writeService: WriteService = mock[WriteService]
+ override lazy val imageStorage: AmazonImageStorageService = mock[AmazonImageStorageService]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val rawController: RawController = mock[RawController]
- val healthController: HealthController = mock[HealthController]
- val internController: InternController = mock[InternController]
- val imageControllerV2: ImageControllerV2 = mock[ImageControllerV2]
- val imageControllerV3: ImageControllerV3 = mock[ImageControllerV3]
- val converterService: ConverterService = mock[ConverterService]
- val validationService: ValidationService = mock[ValidationService]
- var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
- val searchConverterService: SearchConverterService = mock[SearchConverterService]
- val imageConverter: ImageConverter = mock[ImageConverter]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val rawController: RawController = mock[RawController]
+ override lazy val healthController: HealthController = mock[HealthController]
+ override lazy val internController: InternController = mock[InternController]
+ override lazy val imageControllerV2: ImageControllerV2 = mock[ImageControllerV2]
+ override lazy val imageControllerV3: ImageControllerV3 = mock[ImageControllerV3]
+ override lazy val converterService: ConverterService = mock[ConverterService]
+ override lazy val validationService: ValidationService = mock[ValidationService]
+ var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
+ override lazy val searchConverterService: SearchConverterService = mock[SearchConverterService]
+ override lazy val imageConverter: ImageConverter = mock[ImageConverter]
- val clock: SystemClock = mock[SystemClock]
- val random: Random = mock[Random]
+ override lazy val clock: SystemClock = mock[SystemClock]
+ override lazy val random: Random = mock[Random]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV2Test.scala b/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV2Test.scala
index 9024bcea93..22d1f60ee3 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV2Test.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV2Test.scala
@@ -41,8 +41,8 @@ class ImageControllerV2Test extends UnitSuite with TestEnvironment with TapirCon
val authHeaderWithWrongRole =
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ik9FSTFNVVU0T0RrNU56TTVNekkyTXpaRE9EazFOMFl3UXpkRE1EUXlPRFZDUXpRM1FUSTBNQSJ9.eyJodHRwczovL25kbGEubm8vbmRsYV9pZCI6Inh4eHl5eSIsImlzcyI6Imh0dHBzOi8vbmRsYS5ldS5hdXRoMC5jb20vIiwic3ViIjoieHh4eXl5QGNsaWVudHMiLCJhdWQiOiJuZGxhX3N5c3RlbSIsImlhdCI6MTUxMDMwNTc3MywiZXhwIjoxNTEwMzkyMTczLCJwZXJtaXNzaW9ucyI6WyJzb21lOm90aGVyIl0sImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.u8o7-FXyVzWurle2tP1pngad8KRja6VjFdmy71T4m0k"
- override val converterService = new ConverterService
- val controller: ImageControllerV2 = new ImageControllerV2 {
+ override lazy val converterService = new ConverterService
+ override val controller: ImageControllerV2 = new ImageControllerV2 {
override val maxImageFileSizeBytes: Int = 10
}
diff --git a/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV3Test.scala b/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV3Test.scala
index f15ec189a9..3fe06a8b4e 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV3Test.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/controller/ImageControllerV3Test.scala
@@ -22,8 +22,8 @@ class ImageControllerV3Test extends UnitSuite with TestEnvironment with TapirCon
val authHeaderWithWrongRole =
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ik9FSTFNVVU0T0RrNU56TTVNekkyTXpaRE9EazFOMFl3UXpkRE1EUXlPRFZDUXpRM1FUSTBNQSJ9.eyJodHRwczovL25kbGEubm8vbmRsYV9pZCI6Inh4eHl5eSIsImlzcyI6Imh0dHBzOi8vbmRsYS5ldS5hdXRoMC5jb20vIiwic3ViIjoieHh4eXl5QGNsaWVudHMiLCJhdWQiOiJuZGxhX3N5c3RlbSIsImlhdCI6MTUxMDMwNTc3MywiZXhwIjoxNTEwMzkyMTczLCJwZXJtaXNzaW9ucyI6WyJzb21lOm90aGVyIl0sImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.u8o7-FXyVzWurle2tP1pngad8KRja6VjFdmy71T4m0k"
- override val converterService = new ConverterService
- val controller: ImageControllerV3 = new ImageControllerV3
+ override lazy val converterService = new ConverterService
+ override val controller: ImageControllerV3 = new ImageControllerV3
override def beforeEach(): Unit = {
reset(clock)
diff --git a/image-api/src/test/scala/no/ndla/imageapi/controller/InternControllerTest.scala b/image-api/src/test/scala/no/ndla/imageapi/controller/InternControllerTest.scala
index d1c7710236..5e1f519abb 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/controller/InternControllerTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/controller/InternControllerTest.scala
@@ -25,8 +25,8 @@ import org.mockito.ArgumentMatchers.{any, eq as eqTo}
import org.mockito.Mockito.{doReturn, never, reset, verify, verifyNoMoreInteractions, when}
class InternControllerTest extends UnitSuite with TestEnvironment with TapirControllerTest {
- override val converterService = new ConverterService
- val controller: InternController = new InternController
+ override lazy val converterService = new ConverterService
+ override val controller: InternController = new InternController
val updated: NDLADate = NDLADate.of(2017, 4, 1, 12, 15, 32)
val BySa: LicenseDefinition = getLicense(CC_BY.toString).get
diff --git a/image-api/src/test/scala/no/ndla/imageapi/controller/RawControllerTest.scala b/image-api/src/test/scala/no/ndla/imageapi/controller/RawControllerTest.scala
index cdfdbbbf64..85f7f9aadd 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/controller/RawControllerTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/controller/RawControllerTest.scala
@@ -26,8 +26,8 @@ class RawControllerTest extends UnitSuite with TestEnvironment with TapirControl
val imageGifName = "ndla_logo.gif"
val imageSvgName = "logo.svg"
- override val imageConverter = new ImageConverter
- val controller: RawController = new RawController
+ override lazy val imageConverter = new ImageConverter
+ override val controller: RawController = new RawController
val id = 1L
val idGif = 1L
diff --git a/image-api/src/test/scala/no/ndla/imageapi/integration/ImageStorageServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/integration/ImageStorageServiceTest.scala
index e29d605b07..fb3c4ad79f 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/integration/ImageStorageServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/integration/ImageStorageServiceTest.scala
@@ -18,11 +18,11 @@ import scala.util.{Failure, Success}
class ImageStorageServiceTest extends UnitSuite with TestEnvironment {
- val ImageStorageName = props.StorageName
- val ImageWithNoThumb = TestData.nonexistingWithoutThumb
- val Content = "content"
- val ContentType = "image/jpeg"
- override val imageStorage = new AmazonImageStorageService
+ val ImageStorageName = props.StorageName
+ val ImageWithNoThumb = TestData.nonexistingWithoutThumb
+ val Content = "content"
+ val ContentType = "image/jpeg"
+ override lazy val imageStorage = new AmazonImageStorageService
override def beforeEach(): Unit = {
reset(s3Client)
diff --git a/image-api/src/test/scala/no/ndla/imageapi/repository/ImageRepositoryTest.scala b/image-api/src/test/scala/no/ndla/imageapi/repository/ImageRepositoryTest.scala
index 9b83b24542..9fece1919d 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/repository/ImageRepositoryTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/repository/ImageRepositoryTest.scala
@@ -18,8 +18,8 @@ import scala.util.{Success, Try}
import scalikejdbc.*
class ImageRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with TestEnvironment {
- override val dataSource = testDataSource.get
- override val migrator = new DBMigrator
+ override lazy val dataSource = testDataSource.get
+ override lazy val migrator = new DBMigrator
var repository: ImageRepository = _
this.setDatabaseEnvironment()
diff --git a/image-api/src/test/scala/no/ndla/imageapi/service/ConverterServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/service/ConverterServiceTest.scala
index 9a04228cec..875213ba81 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/service/ConverterServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/service/ConverterServiceTest.scala
@@ -18,7 +18,7 @@ import scala.util.Success
class ConverterServiceTest extends UnitSuite with TestEnvironment {
- override val converterService = new ConverterService
+ override lazy val converterService = new ConverterService
val updated: NDLADate = NDLADate.of(2017, 4, 1, 12, 15, 32)
@@ -77,13 +77,21 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
test("That asApiImageMetaInformationWithDomainUrl returns links with domain urls") {
{
val Success(apiImage) =
- converterService.asApiImageMetaInformationWithDomainUrlV2(DefaultImageMetaInformation, Some("nb"), None)
+ converterService.asApiImageMetaInformationWithDomainUrlV2(
+ DefaultImageMetaInformation,
+ Some("nb"),
+ None
+ ): @unchecked
apiImage.metaUrl should equal(s"${props.ImageApiV2UrlBase}1")
apiImage.imageUrl should equal(s"${props.RawImageUrlBase}/123.png")
}
{
val Success(apiImage) =
- converterService.asApiImageMetaInformationWithDomainUrlV2(WantingImageMetaInformation, Some("nb"), None)
+ converterService.asApiImageMetaInformationWithDomainUrlV2(
+ WantingImageMetaInformation,
+ Some("nb"),
+ None
+ ): @unchecked
apiImage.metaUrl should equal(s"${props.ImageApiV2UrlBase}1")
apiImage.imageUrl should equal(s"${props.RawImageUrlBase}/123.png")
}
@@ -91,14 +99,18 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
test("That asApiImageMetaInformationWithApplicationUrlAndSingleLanguage returns links with applicationUrl") {
val Success(apiImage) =
- converterService.asApiImageMetaInformationWithApplicationUrlV2(DefaultImageMetaInformation, None, None)
+ converterService.asApiImageMetaInformationWithApplicationUrlV2(
+ DefaultImageMetaInformation,
+ None,
+ None
+ ): @unchecked
apiImage.metaUrl should equal(s"${props.Domain}/image-api/v2/images/1")
apiImage.imageUrl should equal(s"${props.Domain}/image-api/raw/123.png")
}
test("That asApiImageMetaInformationWithDomainUrlAndSingleLanguage returns links with domain urls") {
val Success(apiImage) =
- converterService.asApiImageMetaInformationWithDomainUrlV2(DefaultImageMetaInformation, None, None)
+ converterService.asApiImageMetaInformationWithDomainUrlV2(DefaultImageMetaInformation, None, None): @unchecked
apiImage.metaUrl should equal("http://api-gateway.ndla-local/image-api/v2/images/1")
apiImage.imageUrl should equal("http://api-gateway.ndla-local/image-api/raw/123.png")
}
@@ -110,7 +122,7 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
DefaultImageMetaInformation,
Some("RandomLangauge"),
None
- )
+ ): @unchecked
apiImage.metaUrl should equal(s"${props.Domain}/image-api/v2/images/1")
apiImage.imageUrl should equal(s"${props.Domain}/image-api/raw/123.png")
@@ -122,28 +134,32 @@ class ConverterServiceTest extends UnitSuite with TestEnvironment {
DefaultImageMetaInformation,
Some("RandomLangauge"),
None
- )
+ ): @unchecked
apiImage.metaUrl should equal("http://api-gateway.ndla-local/image-api/v2/images/1")
apiImage.imageUrl should equal("http://api-gateway.ndla-local/image-api/raw/123.png")
}
test("that asImageMetaInformationV2 properly") {
- val Success(result1) = converterService.asImageMetaInformationV2(MultiLangImage, Some("nb"), "", None, None)
+ val Success(result1) =
+ converterService.asImageMetaInformationV2(MultiLangImage, Some("nb"), "", None, None): @unchecked
result1.id should be("2")
result1.title.language should be("nn")
- val Success(result2) = converterService.asImageMetaInformationV2(MultiLangImage, Some("en"), "", None, None)
+ val Success(result2) =
+ converterService.asImageMetaInformationV2(MultiLangImage, Some("en"), "", None, None): @unchecked
result2.id should be("2")
result2.title.language should be("en")
- val Success(result3) = converterService.asImageMetaInformationV2(MultiLangImage, Some("nn"), "", None, None)
+ val Success(result3) =
+ converterService.asImageMetaInformationV2(MultiLangImage, Some("nn"), "", None, None): @unchecked
result3.id should be("2")
result3.title.language should be("nn")
}
test("that asImageMetaInformationV2 returns sorted supportedLanguages") {
- val Success(result) = converterService.asImageMetaInformationV2(MultiLangImage, Some("nb"), "", None, None)
+ val Success(result) =
+ converterService.asImageMetaInformationV2(MultiLangImage, Some("nb"), "", None, None): @unchecked
result.supportedLanguages should be(Seq("nn", "en", "und"))
}
diff --git a/image-api/src/test/scala/no/ndla/imageapi/service/ReadServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/service/ReadServiceTest.scala
index 3d55284e5d..30df860e72 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/service/ReadServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/service/ReadServiceTest.scala
@@ -23,8 +23,8 @@ import scalikejdbc.DBSession
import scala.util.{Failure, Success}
class ReadServiceTest extends UnitSuite with TestEnvironment {
- override val readService = new ReadService
- override val converterService = new ConverterService
+ override lazy val readService = new ReadService
+ override lazy val converterService = new ConverterService
test("That path to id conversion works as expected for id paths") {
val id = 1234L
diff --git a/image-api/src/test/scala/no/ndla/imageapi/service/ValidationServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/service/ValidationServiceTest.scala
index 14fee1cf3d..0f9dfe19b8 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/service/ValidationServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/service/ValidationServiceTest.scala
@@ -18,7 +18,7 @@ import no.ndla.mapping.License.CC_BY
import org.mockito.Mockito.{reset, when}
class ValidationServiceTest extends UnitSuite with TestEnvironment {
- override val validationService = new ValidationService
+ override lazy val validationService = new ValidationService
val fileMock: UploadedFile = mock[UploadedFile]
def updated(): NDLADate = NDLADate.of(2017, 4, 1, 12, 15, 32)
@@ -67,7 +67,7 @@ class ValidationServiceTest extends UnitSuite with TestEnvironment {
test("validateImageFile returns a validation message if file has an unknown extension") {
val fileName = "image.asdf"
when(fileMock.fileName).thenReturn(Some(fileName))
- val Some(result) = validationService.validateImageFile(fileMock)
+ val Some(result) = validationService.validateImageFile(fileMock): @unchecked
result.message.contains(s"The file $fileName does not have a known file extension") should be(true)
}
@@ -76,7 +76,7 @@ class ValidationServiceTest extends UnitSuite with TestEnvironment {
val fileName = "image.jpg"
when(fileMock.fileName).thenReturn(Some(fileName))
when(fileMock.contentType).thenReturn(Some("text/html"))
- val Some(result) = validationService.validateImageFile(fileMock)
+ val Some(result) = validationService.validateImageFile(fileMock): @unchecked
result.message.contains(s"The file $fileName is not a valid image file.") should be(true)
}
diff --git a/image-api/src/test/scala/no/ndla/imageapi/service/WriteServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/service/WriteServiceTest.scala
index 5239e41f09..492db485a5 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/service/WriteServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/service/WriteServiceTest.scala
@@ -28,10 +28,10 @@ import java.io.ByteArrayInputStream
import scala.util.{Failure, Success}
class WriteServiceTest extends UnitSuite with TestEnvironment {
- override val writeService = new WriteService
- override val converterService = new ConverterService
- val newFileName = "AbCdeF.mp3"
- val fileMock1: UploadedFile = mock[UploadedFile]
+ override lazy val writeService = new WriteService
+ override lazy val converterService = new ConverterService
+ val newFileName = "AbCdeF.mp3"
+ val fileMock1: UploadedFile = mock[UploadedFile]
val newImageMeta: NewImageMetaInformationV2DTO = NewImageMetaInformationV2DTO(
"title",
@@ -85,7 +85,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(fileMock1.contentType).thenReturn(Some("image/jpeg"))
val bytes = TestData.NdlaLogoImage.stream.readAllBytes()
when(fileMock1.stream).thenReturn(new ByteArrayInputStream(bytes))
- when(fileMock1.fileSize).thenReturn(1024)
+ when(fileMock1.fileSize).thenReturn(1024L)
when(fileMock1.fileName).thenReturn(Some("file.jpg"))
when(random.string(any)).thenCallRealMethod()
@@ -94,7 +94,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
reset(imageStorage)
reset(tagIndexService)
when(imageRepository.insert(any[ImageMetaInformation])(any[DBSession]))
- .thenReturn(domainImageMeta.copy(id = Some(1)))
+ .thenReturn(domainImageMeta.copy(id = Some(1L)))
}
test("randomFileName should return a random filename with a given length and extension") {
@@ -185,16 +185,17 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
.thenReturn(Success(newFileName))
when(imageIndexService.indexDocument(any[ImageMetaInformation])).thenReturn(Failure(new RuntimeException))
when(imageStorage.deleteObject(any)).thenReturn(Success(()))
- when(imageRepository.insert(any)(any)).thenReturn(domainImageMeta.copy(id = Some(100)))
- when(imageRepository.insertImageFile(any, any, any)(any)).thenAnswer((i: InvocationOnMock) => {
+ when(imageRepository.insert(any)(using any)).thenReturn(domainImageMeta.copy(id = Some(100L)))
+ when(imageRepository.insertImageFile(any, any, any)(using any)).thenAnswer((i: InvocationOnMock) => {
val imageId = i.getArgument[Long](0)
val fileName = i.getArgument[String](1)
val document = i.getArgument[ImageFileDataDocument](2)
- Success(document.toFull(1, fileName, imageId))
+ Success(document.toFull(1L, fileName, imageId))
})
- writeService.storeNewImage(newImageMeta, fileMock1, TokenUser.SystemUser).isFailure should be(true)
- verify(imageRepository, times(1)).insert(any[ImageMetaInformation])(any[DBSession])
+ val result = writeService.storeNewImage(newImageMeta, fileMock1, TokenUser.SystemUser)
+ result.isFailure should be(true)
+ verify(imageRepository, times(1)).insert(any[ImageMetaInformation])(using any[DBSession])
verify(imageStorage, times(1)).deleteObject(any[String])
}
@@ -578,7 +579,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(fileMock.fileName).thenReturn(Some("someupload.jpg"))
when(fileMock.contentType).thenReturn(Some("image/jpg"))
when(fileMock.stream).thenReturn(TestData.NdlaLogoImage.stream)
- when(fileMock.fileSize).thenReturn(1337)
+ when(fileMock.fileSize).thenReturn(1337L)
when(validationService.validateImageFile(any)).thenReturn(None)
when(validationService.validate(any, any)).thenAnswer((i: InvocationOnMock) => {
Success(i.getArgument[domain.ImageMetaInformation](0))
@@ -671,7 +672,7 @@ class WriteServiceTest extends UnitSuite with TestEnvironment {
when(fileMock.fileName).thenReturn(Some("someupload.jpg"))
when(fileMock.contentType).thenReturn(Some("image/jpg"))
when(fileMock.stream).thenReturn(TestData.NdlaLogoImage.stream)
- when(fileMock.fileSize).thenReturn(1337)
+ when(fileMock.fileSize).thenReturn(1337L)
when(validationService.validateImageFile(any)).thenReturn(None)
when(validationService.validate(any, any)).thenAnswer((i: InvocationOnMock) => {
Success(i.getArgument[domain.ImageMetaInformation](0))
diff --git a/image-api/src/test/scala/no/ndla/imageapi/service/search/ImageSearchServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/service/search/ImageSearchServiceTest.scala
index c2fc1a04da..92066476fa 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/service/search/ImageSearchServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/service/search/ImageSearchServiceTest.scala
@@ -22,28 +22,20 @@ import no.ndla.network.tapir.auth.TokenUser
import no.ndla.scalatestsuite.ElasticsearchIntegrationSuite
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.when
-import org.scalatest.PrivateMethodTester
import scala.util.Success
-class ImageSearchServiceTest
- extends ElasticsearchIntegrationSuite
- with UnitSuite
- with TestEnvironment
- with PrivateMethodTester {
+class ImageSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
import TestData.searchSettings
- import props.{DefaultPageSize, MaxPageSize}
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- override val searchConverterService = new SearchConverterService
- override val converterService = new ConverterService
- override val imageIndexService: ImageIndexService = new ImageIndexService {
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val imageIndexService: ImageIndexService = new ImageIndexService {
override val indexShards = 1
}
- override val imageSearchService = new ImageSearchService
-
- val getStartAtAndNumResults: PrivateMethod[(Int, Int)] = PrivateMethod[(Int, Int)](Symbol("getStartAtAndNumResults"))
+ override lazy val imageSearchService = new ImageSearchService
val largeImage: ImageFileData = ImageFileData(1, "large-full-url", 10000, "jpg", None, "und", 4)
val smallImage: ImageFileData = ImageFileData(2, "small-full-url", 100, "jpg", None, "und", 6)
@@ -191,20 +183,20 @@ class ImageSearchServiceTest
}
test("That getStartAtAndNumResults returns default values for None-input") {
- imageSearchService invokePrivate getStartAtAndNumResults(None, None) should equal((0, DefaultPageSize))
+ imageSearchService.getStartAtAndNumResults(None, None) should equal((0, props.DefaultPageSize))
}
test("That getStartAtAndNumResults returns SEARCH_MAX_PAGE_SIZE for value greater than SEARCH_MAX_PAGE_SIZE") {
- imageSearchService invokePrivate getStartAtAndNumResults(None, Some(10001)) should equal((0, MaxPageSize))
+ imageSearchService.getStartAtAndNumResults(None, Some(10001)) should equal((0, props.MaxPageSize))
}
test(
"That getStartAtAndNumResults returns the correct calculated start at for page and page-size with default page-size"
) {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- imageSearchService invokePrivate getStartAtAndNumResults(Some(page), None) should equal(
- (expectedStartAt, DefaultPageSize)
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ imageSearchService.getStartAtAndNumResults(Some(page), None) should equal(
+ (expectedStartAt, props.DefaultPageSize)
)
}
@@ -212,7 +204,7 @@ class ImageSearchServiceTest
val page = 123
val pageSize = 43
val expectedStartAt = (page - 1) * pageSize
- imageSearchService invokePrivate getStartAtAndNumResults(Some(page), Some(pageSize)) should equal(
+ imageSearchService.getStartAtAndNumResults(Some(page), Some(pageSize)) should equal(
(expectedStartAt, pageSize)
)
}
@@ -227,7 +219,8 @@ class ImageSearchServiceTest
}
test("That all filtering on minimumsize only returns images larger than minimumsize") {
- val Success(searchResult) = imageSearchService.matchingQuery(searchSettings.copy(minimumSize = Some(500)), None)
+ val Success(searchResult) =
+ imageSearchService.matchingQuery(searchSettings.copy(minimumSize = Some(500)), None): @unchecked
searchResult.totalCount should be(2)
searchResult.results.size should be(2)
searchResult.results.head.id should be("1")
@@ -236,7 +229,7 @@ class ImageSearchServiceTest
test("That all filtering on license only returns images with given license") {
val Success(searchResult) =
- imageSearchService.matchingQuery(searchSettings.copy(license = Some(PublicDomain.toString)), None)
+ imageSearchService.matchingQuery(searchSettings.copy(license = Some(PublicDomain.toString)), None): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("2")
@@ -244,9 +237,9 @@ class ImageSearchServiceTest
test("That paging returns only hits on current page and not more than page-size") {
val Success(searchResultPage1) =
- imageSearchService.matchingQuery(searchSettings.copy(page = Some(1), pageSize = Some(2)), None)
+ imageSearchService.matchingQuery(searchSettings.copy(page = Some(1), pageSize = Some(2)), None): @unchecked
val Success(searchResultPage2) =
- imageSearchService.matchingQuery(searchSettings.copy(page = Some(2), pageSize = Some(2)), None)
+ imageSearchService.matchingQuery(searchSettings.copy(page = Some(2), pageSize = Some(2)), None): @unchecked
searchResultPage1.totalCount should be(5)
searchResultPage1.page.get should be(1)
searchResultPage1.pageSize should be(2)
@@ -267,7 +260,7 @@ class ImageSearchServiceTest
imageSearchService.matchingQuery(
searchSettings.copy(minimumSize = Some(500), license = Some(PublicDomain.toString)),
None
- )
+ ): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("2")
@@ -275,7 +268,7 @@ class ImageSearchServiceTest
test("That search matches title and alttext ordered by relevance") {
val res = imageSearchService.matchingQuery(searchSettings.copy(query = Some("bil")), None)
- val Success(searchResult) = res
+ val Success(searchResult) = res: @unchecked
searchResult.totalCount should be(2)
searchResult.results.size should be(2)
searchResult.results.head.id should be("1")
@@ -284,7 +277,10 @@ class ImageSearchServiceTest
test("That search matches title") {
val Success(searchResult) =
- imageSearchService.matchingQuery(searchSettings.copy(query = Some("Pingvinen"), language = "nb"), None)
+ imageSearchService.matchingQuery(
+ searchSettings.copy(query = Some("Pingvinen"), language = "nb"),
+ None
+ ): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("2")
@@ -292,14 +288,15 @@ class ImageSearchServiceTest
test("That search matches id search") {
val Success(searchResult) =
- imageSearchService.matchingQuery(searchSettings.copy(query = Some("1"), language = "nb"), None)
+ imageSearchService.matchingQuery(searchSettings.copy(query = Some("1"), language = "nb"), None): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("1")
}
test("That search on author matches corresponding author on image") {
- val Success(searchResult) = imageSearchService.matchingQuery(searchSettings.copy(query = Some("Bruce Wayne")), None)
+ val Success(searchResult) =
+ imageSearchService.matchingQuery(searchSettings.copy(query = Some("Bruce Wayne")), None): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("2")
@@ -307,7 +304,7 @@ class ImageSearchServiceTest
test("That search matches tags") {
val Success(searchResult) =
- imageSearchService.matchingQuery(searchSettings.copy(query = Some("and"), language = "nb"), None)
+ imageSearchService.matchingQuery(searchSettings.copy(query = Some("and"), language = "nb"), None): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("3")
@@ -315,7 +312,7 @@ class ImageSearchServiceTest
test("That search defaults to nb if no language is specified") {
val Success(searchResult) =
- imageSearchService.matchingQuery(searchSettings.copy(query = Some("Bilde av en and")), None)
+ imageSearchService.matchingQuery(searchSettings.copy(query = Some("Bilde av en and")), None): @unchecked
searchResult.totalCount should be(4)
searchResult.results.size should be(4)
searchResult.results.head.id should be("1")
@@ -325,7 +322,8 @@ class ImageSearchServiceTest
}
test("That search matches title with unknown language analyzed in Norwegian") {
- val Success(searchResult) = imageSearchService.matchingQuery(searchSettings.copy(query = Some("blomstene")), None)
+ val Success(searchResult) =
+ imageSearchService.matchingQuery(searchSettings.copy(query = Some("blomstene")), None): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("4")
@@ -341,7 +339,7 @@ class ImageSearchServiceTest
pageSize = Some(10)
),
None
- )
+ ): @unchecked
search1.results.map(_.id) should equal(Seq("1", "3"))
val Success(search2) = imageSearchService.matchingQuery(
@@ -352,7 +350,7 @@ class ImageSearchServiceTest
pageSize = Some(10)
),
None
- )
+ ): @unchecked
search2.results.map(_.id) should equal(Seq("1", "2"))
val Success(search3) = imageSearchService.matchingQuery(
@@ -363,7 +361,7 @@ class ImageSearchServiceTest
pageSize = Some(10)
),
None
- )
+ ): @unchecked
search3.results.map(_.id) should equal(Seq("2", "3"))
val Success(search4) = imageSearchService.matchingQuery(
@@ -374,7 +372,7 @@ class ImageSearchServiceTest
pageSize = Some(10)
),
None
- )
+ ): @unchecked
search4.results.map(_.id) should equal(Seq("1"))
}
@@ -385,7 +383,7 @@ class ImageSearchServiceTest
language = "*"
),
None
- )
+ ): @unchecked
searchResult1.totalCount should be(1)
searchResult1.results.size should be(1)
searchResult1.results.head.id should be("5")
@@ -399,7 +397,7 @@ class ImageSearchServiceTest
sort = Sort.ByTitleDesc
),
None
- )
+ ): @unchecked
searchResult2.totalCount should be(1)
searchResult2.results.size should be(1)
searchResult2.results.head.id should be("5")
@@ -413,7 +411,7 @@ class ImageSearchServiceTest
language = "ait" // Arikem
),
None
- )
+ ): @unchecked
searchResult1.totalCount should be(0)
}
@@ -424,7 +422,7 @@ class ImageSearchServiceTest
language = "en"
),
None
- )
+ ): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.id should be("5")
@@ -437,7 +435,7 @@ class ImageSearchServiceTest
language = "nn"
),
None
- )
+ ): @unchecked
searchResult2.totalCount should be(1)
searchResult2.results.size should be(1)
searchResult2.results.head.id should be("5")
@@ -452,7 +450,7 @@ class ImageSearchServiceTest
language = "nn"
),
None
- )
+ ): @unchecked
result.totalCount should be(1)
result.results.size should be(1)
@@ -469,11 +467,11 @@ class ImageSearchServiceTest
shouldScroll = true
),
None
- )
+ ): @unchecked
- val Success(scroll1) = imageSearchService.scrollV2(initialSearch.scrollId.get, "*", None)
- val Success(scroll2) = imageSearchService.scrollV2(scroll1.scrollId.get, "*", None)
- val Success(scroll3) = imageSearchService.scrollV2(scroll2.scrollId.get, "*", None)
+ val Success(scroll1) = imageSearchService.scrollV2(initialSearch.scrollId.get, "*", None): @unchecked
+ val Success(scroll2) = imageSearchService.scrollV2(scroll1.scrollId.get, "*", None): @unchecked
+ val Success(scroll3) = imageSearchService.scrollV2(scroll2.scrollId.get, "*", None): @unchecked
initialSearch.results.map(_.id) should be(expectedIds.head)
scroll1.results.map(_.id) should be(expectedIds(1))
@@ -491,11 +489,11 @@ class ImageSearchServiceTest
shouldScroll = true
),
None
- )
+ ): @unchecked
- val Success(scroll1) = imageSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = imageSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = imageSearchService.scroll(scroll2.scrollId.get, "*")
+ val Success(scroll1) = imageSearchService.scroll(initialSearch.scrollId.get, "*"): @unchecked
+ val Success(scroll2) = imageSearchService.scroll(scroll1.scrollId.get, "*"): @unchecked
+ val Success(scroll3) = imageSearchService.scroll(scroll2.scrollId.get, "*"): @unchecked
initialSearch.results.map(_._1.id) should be(expectedIds.head)
scroll1.results.map(_._1.id) should be(expectedIds(1))
@@ -510,7 +508,7 @@ class ImageSearchServiceTest
sort = Sort.ByTitleDesc
),
None
- )
+ ): @unchecked
searchResult1.results.map(_.id) should be(Seq("2", "3", "1"))
}
@@ -522,7 +520,7 @@ class ImageSearchServiceTest
language = "*"
),
None
- )
+ ): @unchecked
searchResult1.results.map(_.id) should be(Seq())
@@ -532,7 +530,7 @@ class ImageSearchServiceTest
language = "*"
),
Some(TokenUser("someeditor", Set(IMAGE_API_WRITE), None))
- )
+ ): @unchecked
searchResult2.results.map(_.id) should be(Seq("2"))
}
@@ -545,7 +543,7 @@ class ImageSearchServiceTest
modelReleased = Seq(NO)
),
None
- )
+ ): @unchecked
searchResult1.results.map(_.id) should be(Seq("1"))
@@ -555,7 +553,7 @@ class ImageSearchServiceTest
modelReleased = Seq(NOT_APPLICABLE)
),
None
- )
+ ): @unchecked
searchResult2.results.map(_.id) should be(Seq("2"))
@@ -565,7 +563,7 @@ class ImageSearchServiceTest
modelReleased = Seq(YES)
),
None
- )
+ ): @unchecked
searchResult3.results.map(_.id) should be(Seq("3", "4", "5"))
@@ -575,7 +573,7 @@ class ImageSearchServiceTest
modelReleased = Seq.empty
),
None
- )
+ ): @unchecked
searchResult4.results.map(_.id) should be(Seq("1", "2", "3", "4", "5"))
@@ -585,7 +583,7 @@ class ImageSearchServiceTest
modelReleased = Seq(NO, NOT_APPLICABLE)
),
None
- )
+ ): @unchecked
searchResult5.results.map(_.id) should be(Seq("1", "2"))
@@ -593,7 +591,7 @@ class ImageSearchServiceTest
test("That search result includes updatedBy field") {
val Success(searchResult) =
- imageSearchService.matchingQuery(searchSettings.copy(query = Some("1"), language = "nb"), None)
+ imageSearchService.matchingQuery(searchSettings.copy(query = Some("1"), language = "nb"), None): @unchecked
searchResult.totalCount should be(1)
searchResult.results.size should be(1)
searchResult.results.head.lastUpdated should be(updated)
@@ -607,7 +605,7 @@ class ImageSearchServiceTest
language = "und"
),
None
- )
+ ): @unchecked
searchResult1.totalCount should be(1)
searchResult1.results.size should be(1)
searchResult1.results.head.id should be("5")
@@ -620,7 +618,7 @@ class ImageSearchServiceTest
language = "en"
),
None
- )
+ ): @unchecked
searchResult2.totalCount should be(1)
searchResult2.results.size should be(1)
searchResult2.results.head.id should be("5")
@@ -635,7 +633,7 @@ class ImageSearchServiceTest
podcastFriendly = Some(true)
),
None
- )
+ ): @unchecked
searchResult1.results.map(_.id) should be(Seq("5"))
}
diff --git a/image-api/src/test/scala/no/ndla/imageapi/service/search/SearchServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/service/search/SearchServiceTest.scala
index fa9a178055..160f37a41b 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/service/search/SearchServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/service/search/SearchServiceTest.scala
@@ -16,7 +16,7 @@ import scala.util.Success
class SearchServiceTest extends UnitSuite with TestEnvironment {
- override val imageSearchService = new ImageSearchService
+ override lazy val imageSearchService = new ImageSearchService
test("That createEmptyIndexIfNoIndexesExist never creates empty index if an index already exists") {
when(imageIndexService.findAllIndexes(any[String])).thenReturn(Success(Seq("index1")))
diff --git a/image-api/src/test/scala/no/ndla/imageapi/service/search/TagSearchServiceTest.scala b/image-api/src/test/scala/no/ndla/imageapi/service/search/TagSearchServiceTest.scala
index a9295f9b21..a6b677d506 100644
--- a/image-api/src/test/scala/no/ndla/imageapi/service/search/TagSearchServiceTest.scala
+++ b/image-api/src/test/scala/no/ndla/imageapi/service/search/TagSearchServiceTest.scala
@@ -20,16 +20,16 @@ class TagSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse("http://localhost:9200"))
- val indexName = "tags-testing"
- override val tagSearchService: TagSearchService = new TagSearchService {
+ val indexName = "tags-testing"
+ override lazy val tagSearchService: TagSearchService = new TagSearchService {
override val searchIndex: String = indexName
}
- override val tagIndexService: TagIndexService = new TagIndexService {
+ override lazy val tagIndexService: TagIndexService = new TagIndexService {
override val indexShards: Int = 1
override val searchIndex: String = indexName
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val image1: ImageMetaInformation = TestData.elg.copy(
tags = Seq(
@@ -88,14 +88,14 @@ class TagSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite
}
test("That searching for tags returns sensible results") {
- val Success(result) = tagSearchService.matchingQuery("test", "nb", 1, 100, Sort.ByRelevanceDesc)
+ val Success(result) = tagSearchService.matchingQuery("test", "nb", 1, 100, Sort.ByRelevanceDesc): @unchecked
result.totalCount should be(3)
result.results should be(Seq("test", "testemer", "testing"))
}
test("That only prefixes are matched") {
- val Success(result) = tagSearchService.matchingQuery("kylling", "nb", 1, 100, Sort.ByRelevanceDesc)
+ val Success(result) = tagSearchService.matchingQuery("kylling", "nb", 1, 100, Sort.ByRelevanceDesc): @unchecked
result.totalCount should be(1)
result.results should be(Seq("kyllingfilet"))
diff --git a/integration-tests/src/test/scala/no/ndla/integrationtests/draftapi/articleapi/ArticleApiClientTest.scala b/integration-tests/src/test/scala/no/ndla/integrationtests/draftapi/articleapi/ArticleApiClientTest.scala
index 93f3d03783..459e5b91f6 100644
--- a/integration-tests/src/test/scala/no/ndla/integrationtests/draftapi/articleapi/ArticleApiClientTest.scala
+++ b/integration-tests/src/test/scala/no/ndla/integrationtests/draftapi/articleapi/ArticleApiClientTest.scala
@@ -34,7 +34,7 @@ class ArticleApiClientTest
with DatabaseIntegrationSuite
with UnitSuite
with draftapi.TestEnvironment {
- override val ndlaClient = new NdlaClient
+ override lazy val ndlaClient = new NdlaClient
// NOTE: There is some weirdness with loading the resources in validation library if this isn't called.
// For some reason this fixes that.
@@ -80,8 +80,8 @@ class ArticleApiClientTest
super.afterAll()
}
- val idResponse: ContentIdDTO = ContentIdDTO(1)
- override val converterService = new ConverterService
+ val idResponse: ContentIdDTO = ContentIdDTO(1)
+ override lazy val converterService = new ConverterService
val testCopyright: common.draft.DraftCopyright = common.draft.DraftCopyright(
Some("CC-BY-SA-4.0"),
@@ -141,9 +141,9 @@ class ArticleApiClientTest
val authHeaderMap: Map[String, String] = Map("Authorization" -> s"Bearer $exampleToken")
val authUser: TokenUser = TokenUser.SystemUser.copy(originalToken = Some(exampleToken))
- class LocalArticleApiTestData extends articleapi.Props with articleapi.TestData {
- override val props: ArticleApiProperties = articleApiProperties
- val td = new TestData
+ class LocalArticleApiTestData extends articleapi.Props with articleapi.TestDataT {
+ override lazy val props: ArticleApiProperties = articleApiProperties
+ val td = new TestDataClass
def setupArticles(): Try[Boolean] =
(1L to 10)
diff --git a/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/articleapi/ArticleApiClientTest.scala b/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/articleapi/ArticleApiClientTest.scala
index 9623259465..41f43841a7 100644
--- a/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/articleapi/ArticleApiClientTest.scala
+++ b/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/articleapi/ArticleApiClientTest.scala
@@ -30,9 +30,9 @@ class ArticleApiClientTest
with UnitSuite
with searchapi.TestEnvironment
with HasDatabaseProps {
- override val ndlaClient = new NdlaClient
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val articleApiPort: Int = findFreePort
val pgc: PostgreSQLContainer[?] = postgresContainer.get
@@ -77,9 +77,9 @@ class ArticleApiClientTest
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9FSTFNVVU0T0RrNU56TTVNekkyTXpaRE9EazFOMFl3UXpkRE1EUXlPRFZDUXpRM1FUSTBNQSJ9.eyJodHRwczovL25kbGEubm8vY2xpZW50X2lkIjogInh4eHl5eSIsICJpc3MiOiAiaHR0cHM6Ly9uZGxhLmV1LmF1dGgwLmNvbS8iLCAic3ViIjogInh4eHl5eUBjbGllbnRzIiwgImF1ZCI6ICJuZGxhX3N5c3RlbSIsICJpYXQiOiAxNTEwMzA1NzczLCAiZXhwIjogMTUxMDM5MjE3MywgInNjb3BlIjogImFydGljbGVzLXRlc3Q6cHVibGlzaCBkcmFmdHMtdGVzdDp3cml0ZSBkcmFmdHMtdGVzdDpzZXRfdG9fcHVibGlzaCBhcnRpY2xlcy10ZXN0OndyaXRlIiwgImd0eSI6ICJjbGllbnQtY3JlZGVudGlhbHMifQ.gsM-U84ykgaxMSbL55w6UYIIQUouPIB6YOmJuj1KhLFnrYctu5vwYBo80zyr1je9kO_6L-rI7SUnrHVao9DFBZJmfFfeojTxIT3CE58hoCdxZQZdPUGePjQzROWRWeDfG96iqhRcepjbVF9pMhKp6FNqEVOxkX00RZg9vFT8iMM"
val authHeaderMap: Map[String, String] = Map("Authorization" -> s"Bearer $exampleToken")
- class LocalArticleApiTestData extends articleapi.Props with articleapi.TestData {
- override val props: ArticleApiProperties = articleApiProperties
- val td = new TestData
+ class LocalArticleApiTestData extends articleapi.Props with articleapi.TestDataT {
+ override lazy val props: ArticleApiProperties = articleApiProperties
+ val td = new TestDataClass
def setupArticles(): Try[Boolean] =
(1L to 10)
diff --git a/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/draftapi/DraftApiClientTest.scala b/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/draftapi/DraftApiClientTest.scala
index a18607121f..69048699b0 100644
--- a/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/draftapi/DraftApiClientTest.scala
+++ b/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/draftapi/DraftApiClientTest.scala
@@ -32,9 +32,9 @@ class DraftApiClientTest
with UnitSuite
with searchapi.TestEnvironment
with HasDatabaseProps {
- override val ndlaClient = new NdlaClient
- override val searchConverterService = new SearchConverterService
- override val DBUtil = new DBUtility
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val DBUtil = new DBUtility
val draftApiPort: Int = findFreePort
val pgc: PostgreSQLContainer[?] = postgresContainer.get
diff --git a/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/learningpathapi/LearningpathApiClientTest.scala b/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/learningpathapi/LearningpathApiClientTest.scala
index 0e6e06af03..9e359bab00 100644
--- a/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/learningpathapi/LearningpathApiClientTest.scala
+++ b/integration-tests/src/test/scala/no/ndla/integrationtests/searchapi/learningpathapi/LearningpathApiClientTest.scala
@@ -32,9 +32,9 @@ class LearningpathApiClientTest
with UnitSuite
with searchapi.TestEnvironment
with HasDatabaseProps {
- override val ndlaClient = new NdlaClient
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val learningpathApiPort: Int = findFreePort
val pgc: PostgreSQLContainer[?] = postgresContainer.get
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/ComponentRegistry.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/ComponentRegistry.scala
index 7c01e1dec8..8a25839af0 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/ComponentRegistry.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/ComponentRegistry.scala
@@ -82,8 +82,8 @@ class ComponentRegistry(properties: LearningpathApiProperties)
with ErrorHandling
with SwaggerDocControllerConfig
with SearchLanguage {
- override val props: LearningpathApiProperties = properties
- override val migrator: DBMigrator = DBMigrator(
+ override lazy val props: LearningpathApiProperties = properties
+ override lazy val migrator: DBMigrator = DBMigrator(
new V11__CreatedByNdlaStatusForOwnersWithRoles,
new V13__StoreNDLAStepsAsIframeTypes,
new V14__ConvertLanguageUnknown,
@@ -92,32 +92,32 @@ class ComponentRegistry(properties: LearningpathApiProperties)
new V33__AiDefaultEnabledOrgs
)
override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
- override val DBUtil: DBUtility = new DBUtility
+ override lazy val DBUtil: DBUtility = new DBUtility
- lazy val learningPathRepository = new LearningPathRepository
- lazy val readService = new ReadService
- lazy val updateService = new UpdateService
- lazy val searchConverterService = new SearchConverterService
- lazy val searchService = new SearchService
- lazy val searchIndexService = new SearchIndexService
- lazy val converterService = new ConverterService
- lazy val clock = new SystemClock
- lazy val uuidUtil = new UUIDUtil
- lazy val taxonomyApiClient = new TaxonomyApiClient
- lazy val ndlaClient = new NdlaClient
- lazy val languageValidator = new LanguageValidator
- lazy val titleValidator = new TitleValidator
- lazy val learningPathValidator = new LearningPathValidator
- lazy val learningStepValidator = new LearningStepValidator
- var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
- lazy val searchApiClient = new SearchApiClient
- lazy val oembedProxyClient = new OembedProxyClient
- lazy val myndlaApiClient = new MyNDLAApiClient
+ override lazy val learningPathRepository = new LearningPathRepository
+ override lazy val readService = new ReadService
+ override lazy val updateService = new UpdateService
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val searchService = new SearchService
+ override lazy val searchIndexService = new SearchIndexService
+ override lazy val converterService = new ConverterService
+ override lazy val clock = new SystemClock
+ override lazy val uuidUtil = new UUIDUtil
+ override lazy val taxonomyApiClient = new TaxonomyApiClient
+ override lazy val ndlaClient = new NdlaClient
+ override lazy val languageValidator = new LanguageValidator
+ override lazy val titleValidator = new TitleValidator
+ override lazy val learningPathValidator = new LearningPathValidator
+ override lazy val learningStepValidator = new LearningStepValidator
+ var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
+ override lazy val searchApiClient = new SearchApiClient
+ override lazy val oembedProxyClient = new OembedProxyClient
+ override lazy val myndlaApiClient = new MyNDLAApiClient
- lazy val learningpathControllerV2 = new LearningpathControllerV2
- lazy val internController = new InternController
- lazy val statsController = new StatsController
- lazy val healthController: TapirHealthController = new TapirHealthController
+ override lazy val learningpathControllerV2 = new LearningpathControllerV2
+ override lazy val internController = new InternController
+ override lazy val statsController = new StatsController
+ override lazy val healthController: TapirHealthController = new TapirHealthController
val swagger = new SwaggerController(
List[TapirController](
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/LearningpathApiProperties.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/LearningpathApiProperties.scala
index d9efe7791f..3068417c39 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/LearningpathApiProperties.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/LearningpathApiProperties.scala
@@ -16,7 +16,7 @@ import no.ndla.network.{AuthUser, Domains}
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: LearningpathApiProperties
+ lazy val props: LearningpathApiProperties
}
class LearningpathApiProperties extends BaseProps with DatabaseProps with StrictLogging {
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/InternController.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/InternController.scala
index 3e212624c8..785f4c4ed3 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/InternController.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/InternController.scala
@@ -29,7 +29,7 @@ import scala.util.{Failure, Success}
trait InternController {
this: SearchIndexService & SearchService & LearningPathRepositoryComponent & ReadService & UpdateService & Props &
ErrorHandling & TapirController =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController {
override val prefix: EndpointInput[Unit] = "intern"
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/LearningpathControllerV2.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/LearningpathControllerV2.scala
index c536294a82..af13c96736 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/LearningpathControllerV2.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/LearningpathControllerV2.scala
@@ -38,17 +38,11 @@ trait LearningpathControllerV2 {
this: ReadService & UpdateService & SearchService & LanguageValidator & ConverterService & TaxonomyApiClient &
SearchConverterServiceComponent & Props & ErrorHandling & TapirController =>
- val learningpathControllerV2: LearningpathControllerV2
+ lazy val learningpathControllerV2: LearningpathControllerV2
class LearningpathControllerV2 extends TapirController {
import ErrorHelpers.*
- import props.{
- DefaultLanguage,
- ElasticSearchIndexMaxResultWindow,
- ElasticSearchScrollKeepAlive,
- InitialScrollContextKeywords
- }
override val serviceName: String = "learningpaths"
override val prefix: EndpointInput[Unit] = "learningpath-api" / "v2" / serviceName
@@ -94,11 +88,11 @@ trait LearningpathControllerV2 {
private val learningPathStatus = path[String]("STATUS").description("Status of LearningPaths")
private val scrollId = query[Option[String]]("search-context")
.description(
- s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${InitialScrollContextKeywords
+ s"""A unique string obtained from a search you want to keep scrolling in. To obtain one from a search, provide one of the following values: ${props.InitialScrollContextKeywords
.mkString("[", ",", "]")}.
|When scrolling, the parameters from the initial search is used, except in the case of '${this.language.name}' and '${this.fallback.name}'.
- |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after $ElasticSearchScrollKeepAlive).
- |If you are not paginating past $ElasticSearchIndexMaxResultWindow hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
+ |This value may change between scrolls. Always use the one in the latest scroll result (The context, if unused, dies after ${props.ElasticSearchScrollKeepAlive}).
+ |If you are not paginating past ${props.ElasticSearchIndexMaxResultWindow} hits, you can ignore this and use '${this.pageNo.name}' and '${this.pageSize.name}' instead.
|""".stripMargin
)
private val verificationStatus = query[Option[String]]("verificationStatus")
@@ -120,7 +114,7 @@ trait LearningpathControllerV2 {
orFunction: => Try[(SearchResultV2DTO, DynamicHeaders)]
): Try[(SearchResultV2DTO, DynamicHeaders)] =
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
searchService.scroll(scroll, language.code) match {
case Success(scrollResult) =>
val body = searchConverterService.asApiSearchResult(scrollResult)
@@ -236,7 +230,7 @@ trait LearningpathControllerV2 {
.serverLogicPure {
case (query, tag, idList, language, pageNo, pageSize, sortStr, fallback, scrollId, verificationStatus) =>
scrollSearchOr(scrollId, language) {
- val shouldScroll = scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query,
language.code,
@@ -263,7 +257,7 @@ trait LearningpathControllerV2 {
.serverLogicPure { searchParams =>
val language = searchParams.language.getOrElse(LanguageCode(AllLanguages))
scrollSearchOr(searchParams.scrollId, language) {
- val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = searchParams.scrollId.exists(props.InitialScrollContextKeywords.contains)
search(
query = searchParams.query,
searchLanguage = language.code,
@@ -402,7 +396,7 @@ trait LearningpathControllerV2 {
.learningStepStatusForV2(
pathId,
stepId,
- DefaultLanguage,
+ props.DefaultLanguage,
fallback,
user
)
@@ -417,7 +411,7 @@ trait LearningpathControllerV2 {
.out(jsonBody[List[LearningPathV2DTO]])
.errorOut(errorOutputsFor(401, 403, 404))
.withRequiredMyNDLAUserOrTokenUser
- .serverLogicPure { user => _ => readService.withOwnerV2(user, DefaultLanguage, true).asRight }
+ .serverLogicPure { user => _ => readService.withOwnerV2(user, props.DefaultLanguage, true).asRight }
def getLicenses: ServerEndpoint[Any, Eff] = endpoint.get
.summary("Show all valid licenses")
@@ -617,7 +611,7 @@ trait LearningpathControllerV2 {
pathId,
pathStatus,
user,
- DefaultLanguage,
+ props.DefaultLanguage,
updateLearningPathStatus.message
)
.map { learningPath =>
@@ -649,7 +643,7 @@ trait LearningpathControllerV2 {
pathId,
learningpath.LearningPathStatus.DELETED,
user,
- DefaultLanguage
+ props.DefaultLanguage
) match {
case Failure(ex) => returnLeftError(ex)
case Success(_) =>
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/StatsController.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/StatsController.scala
index 91ee7c25d2..3129b17144 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/StatsController.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/controller/StatsController.scala
@@ -19,7 +19,7 @@ import sttp.tapir.server.ServerEndpoint
trait StatsController {
this: ReadService & Props & ErrorHandling & TapirController =>
- val statsController: StatsController
+ lazy val statsController: StatsController
class StatsController extends TapirController {
override val serviceName: String = "stats"
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/OembedProxyClient.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/OembedProxyClient.scala
index 550b2d3b7e..9e2a826da8 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/OembedProxyClient.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/OembedProxyClient.scala
@@ -28,12 +28,11 @@ object OembedResponse {
trait OembedProxyClient {
this: NdlaClient & Props =>
- val oembedProxyClient: OembedProxyClient
+ lazy val oembedProxyClient: OembedProxyClient
class OembedProxyClient extends StrictLogging {
- import props.ApiGatewayHost
private val OembedProxyTimeout = 90.seconds
- private val OembedProxyBaseUrl = s"http://$ApiGatewayHost/oembed-proxy/v1"
+ private val OembedProxyBaseUrl = s"http://${props.ApiGatewayHost}/oembed-proxy/v1"
def getIframeUrl(url: String): Try[String] = {
getOembed(url) match {
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/SearchApiClient.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/SearchApiClient.scala
index b162c0238c..0c6849e995 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/SearchApiClient.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/SearchApiClient.scala
@@ -26,17 +26,16 @@ import scala.util.{Failure, Success, Try}
trait SearchApiClient {
this: NdlaClient & Props =>
- val searchApiClient: SearchApiClient
+ lazy val searchApiClient: SearchApiClient
class SearchApiClient extends StrictLogging {
- import props.SearchApiHost
private val IndexTimeout = 90.seconds
@unused
- private val SearchApiBaseUrl = s"http://$SearchApiHost"
+ private val SearchApiBaseUrl = s"http://${props.SearchApiHost}"
def deleteLearningPathDocument(id: Long, user: Option[TokenUser]): Try[?] = {
val req = quickRequest
- .delete(uri"http://$SearchApiHost/intern/learningpath/$id")
+ .delete(uri"http://${props.SearchApiHost}/intern/learningpath/$id")
.readTimeout(IndexTimeout)
doRawRequest(req, user)
@@ -49,7 +48,7 @@ trait SearchApiClient {
val body = CirceUtil.toJsonString(document)
val req = quickRequest
- .post(uri"http://$SearchApiHost/intern/learningpath/")
+ .post(uri"http://${props.SearchApiHost}/intern/learningpath/")
.header("Content-Type", "application/json", replaceExisting = true)
.body(body)
.readTimeout(IndexTimeout)
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/TaxonomyApiClient.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/TaxonomyApiClient.scala
index 2ebbd2a165..cdc7cb1b81 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/TaxonomyApiClient.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/integration/TaxonomyApiClient.scala
@@ -30,12 +30,11 @@ import scala.util.{Failure, Success, Try}
trait TaxonomyApiClient {
this: NdlaClient & Props =>
- val taxonomyApiClient: TaxonomyApiClient
+ lazy val taxonomyApiClient: TaxonomyApiClient
class TaxonomyApiClient extends StrictLogging {
- import props.{TaxonomyUrl, DefaultLanguage}
private val taxonomyTimeout = 20.seconds
- private val TaxonomyApiEndpoint = s"$TaxonomyUrl/v1"
+ private val TaxonomyApiEndpoint = s"${props.TaxonomyUrl}/v1"
private val LearningPathResourceTypeId = "urn:resourcetype:learningPath"
def updateTaxonomyForLearningPath(
@@ -49,7 +48,7 @@ trait TaxonomyApiClient {
case Some(learningPathId) =>
val contentUri = s"urn:learningpath:$learningPathId"
- Language.findByLanguageOrBestEffort(learningPath.title, DefaultLanguage) match {
+ Language.findByLanguageOrBestEffort(learningPath.title, props.DefaultLanguage) match {
case None =>
Failure(TaxonomyUpdateException("Can't update taxonomy resource when learningpath is missing titles."))
case Some(mainTitle) =>
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/model/api/LearningPathDomainDumpDTO.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/model/api/LearningPathDomainDumpDTO.scala
index 9f4cef23d2..02860a3d8f 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/model/api/LearningPathDomainDumpDTO.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/model/api/LearningPathDomainDumpDTO.scala
@@ -11,6 +11,7 @@ package no.ndla.learningpathapi.model.api
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import no.ndla.common.model.domain.learningpath.{LearningPath, LearningStep}
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
@description("Information about learningpaths")
@@ -24,6 +25,8 @@ case class LearningPathDomainDumpDTO(
object LearningPathDomainDumpDTO {
implicit val encoder: Encoder[LearningPathDomainDumpDTO] = deriveEncoder
implicit val decoder: Decoder[LearningPathDomainDumpDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[LearningPathDomainDumpDTO] = Schema.derivedSchema
}
@description("Information about learningsteps")
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponent.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponent.scala
index 9611664605..ae7e139f97 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponent.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponent.scala
@@ -29,7 +29,7 @@ import scala.util.Try
trait LearningPathRepositoryComponent extends StrictLogging {
this: DataSource & Props =>
- val learningPathRepository: LearningPathRepository
+ lazy val learningPathRepository: LearningPathRepository
def inTransaction[A](work: DBSession => A)(implicit session: DBSession = null): A = {
Option(session) match {
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ConverterService.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ConverterService.scala
index 595809fd78..d21c26492a 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ConverterService.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ConverterService.scala
@@ -12,7 +12,7 @@ import cats.implicits.*
import io.lemonlabs.uri.typesafe.dsl.*
import no.ndla.common.converter.CommonConverter
import no.ndla.common.errors.{AccessDeniedException, NotFoundException}
-import no.ndla.common.implicits.OptionImplicit
+import no.ndla.common.implicits.*
import no.ndla.common.model.api.{Delete, Missing, ResponsibleDTO, UpdateOrDelete, UpdateWith}
import no.ndla.common.model.domain.{ContributorType, Responsible, learningpath}
import no.ndla.common.model.domain.learningpath.{
@@ -48,11 +48,9 @@ trait ConverterService {
this: LearningPathRepositoryComponent & LanguageValidator & LearningPathValidator & OembedProxyClient & Clock &
CommonConverter & Props =>
- val converterService: ConverterService
+ lazy val converterService: ConverterService
class ConverterService {
- import props.*
-
def asEmbedUrlV2(embedUrl: api.EmbedUrlV2DTO, language: String): EmbedUrl = {
learningpath.EmbedUrl(embedUrl.url, language, EmbedType.valueOfOrError(embedUrl.embedType))
}
@@ -748,7 +746,7 @@ trait ConverterService {
)
hostOpt match {
- case Some(host) if NdlaFrontendHostNames.contains(host.toString) =>
+ case Some(host) if props.NdlaFrontendHostNames.contains(host.toString) =>
oembedProxyClient
.getIframeUrl(embedUrl.url)
.map(newUrl => {
@@ -775,25 +773,25 @@ trait ConverterService {
}
def createUrlToLearningPath(lp: LearningPath): String = {
- s"$Domain$LearningpathControllerPath${lp.id.get}"
+ s"${props.Domain}${props.LearningpathControllerPath}${lp.id.get}"
}
def createUrlToLearningPath(lp: api.LearningPathV2DTO): String = {
- s"$Domain$LearningpathControllerPath${lp.id}"
+ s"${props.Domain}${props.LearningpathControllerPath}${lp.id}"
}
private def createUrlToImageApi(imageId: String): String = {
- s"${ExternalApiUrls.ImageApiUrl}/$imageId"
+ s"${props.ExternalApiUrls.ImageApiUrl}/$imageId"
}
private def createUrlToImageApiRaw(imageId: String): String = {
- s"${ExternalApiUrls.ImageApiRawUrl}/id/$imageId"
+ s"${props.ExternalApiUrls.ImageApiRawUrl}/id/$imageId"
}
private def createEmbedUrl(embedUrlOrPath: EmbedUrlV2DTO): EmbedUrlV2DTO = {
embedUrlOrPath.url.hostOption match {
case Some(_) => embedUrlOrPath
case None =>
- embedUrlOrPath.copy(url = s"$NdlaFrontendProtocol://$NdlaFrontendHost${embedUrlOrPath.url}")
+ embedUrlOrPath.copy(url = s"${props.NdlaFrontendProtocol}://${props.NdlaFrontendHost}${embedUrlOrPath.url}")
}
}
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ReadService.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ReadService.scala
index 3acb10c3b0..d61bf2be54 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ReadService.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/ReadService.scala
@@ -27,7 +27,7 @@ import scala.util.{Failure, Success, Try}
trait ReadService {
this: LearningPathRepositoryComponent & ConverterService & Clock & MyNDLAApiClient =>
- val readService: ReadService
+ lazy val readService: ReadService
class ReadService {
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/UpdateService.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/UpdateService.scala
index d7285e02fe..900f0bf899 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/UpdateService.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/UpdateService.scala
@@ -27,14 +27,14 @@ import no.ndla.network.model.{CombinedUser, CombinedUserRequired}
import no.ndla.network.tapir.auth.TokenUser
import scala.annotation.tailrec
-import scala.util.{Failure, Success, Try}
+import scala.util.{Failure, Success, Try, boundary}
import no.ndla.language.Language
import no.ndla.database.DBUtility
trait UpdateService {
this: LearningPathRepositoryComponent & ReadService & ConverterService & SearchIndexService & Clock &
LearningStepValidator & LearningPathValidator & TaxonomyApiClient & SearchApiClient & DBUtility & Props =>
- val updateService: UpdateService
+ lazy val updateService: UpdateService
class UpdateService {
@@ -286,49 +286,51 @@ trait UpdateService {
learningStepToUpdate: UpdatedLearningStepV2DTO,
owner: CombinedUserRequired
): Try[LearningStepV2DTO] = writeDuringWriteRestrictionOrAccessDenied(owner) {
- withId(learningPathId).flatMap(_.canEditLearningpath(owner)) match {
- case Failure(ex) => Failure(ex)
- case Success(learningPath) =>
- learningPathRepository.learningStepWithId(learningPathId, learningStepId) match {
- case None =>
- Failure(
- NotFoundException(
- s"Could not find learningstep with id '$learningStepId' to update with learningpath id '$learningPathId'."
+ permitTry {
+ withId(learningPathId).flatMap(_.canEditLearningpath(owner)) match {
+ case Failure(ex) => Failure(ex)
+ case Success(learningPath) =>
+ learningPathRepository.learningStepWithId(learningPathId, learningStepId) match {
+ case None =>
+ Failure(
+ NotFoundException(
+ s"Could not find learningstep with id '$learningStepId' to update with learningpath id '$learningPathId'."
+ )
)
- )
- case Some(existing) =>
- val validated = for {
- toUpdate <- converterService.mergeLearningSteps(existing, learningStepToUpdate)
- validated <- learningStepValidator.validate(toUpdate, allowUnknownLanguage = true)
- } yield validated
-
- validated match {
- case Failure(ex) => Failure(ex)
- case Success(toUpdate) =>
- learningStepValidator.validate(toUpdate, allowUnknownLanguage = true).??
-
- val (updatedStep, updatedPath) = inTransaction { implicit session =>
- val updatedStep =
- learningPathRepository.updateLearningStep(toUpdate)
- val pathToUpdate = converterService.insertLearningStep(learningPath, updatedStep, owner)
- val updatedPath = learningPathRepository.update(pathToUpdate)
-
- (updatedStep, updatedPath)
- }
-
- updateSearchAndTaxonomy(updatedPath, owner.tokenUser)
- .flatMap(_ =>
- converterService.asApiLearningStepV2(
- updatedStep,
- updatedPath,
- learningStepToUpdate.language,
- fallback = true,
- owner
+ case Some(existing) =>
+ val validated = for {
+ toUpdate <- converterService.mergeLearningSteps(existing, learningStepToUpdate)
+ validated <- learningStepValidator.validate(toUpdate, allowUnknownLanguage = true)
+ } yield validated
+
+ validated match {
+ case Failure(ex) => Failure(ex)
+ case Success(toUpdate) =>
+ learningStepValidator.validate(toUpdate, allowUnknownLanguage = true).??
+
+ val (updatedStep, updatedPath) = inTransaction { implicit session =>
+ val updatedStep =
+ learningPathRepository.updateLearningStep(toUpdate)
+ val pathToUpdate = converterService.insertLearningStep(learningPath, updatedStep, owner)
+ val updatedPath = learningPathRepository.update(pathToUpdate)
+
+ (updatedStep, updatedPath)
+ }
+
+ updateSearchAndTaxonomy(updatedPath, owner.tokenUser)
+ .flatMap(_ =>
+ converterService.asApiLearningStepV2(
+ updatedStep,
+ updatedPath,
+ learningStepToUpdate.language,
+ fallback = true,
+ owner
+ )
)
- )
- }
+ }
- }
+ }
+ }
}
}
@@ -367,33 +369,35 @@ trait UpdateService {
owner: CombinedUserRequired
): Try[LearningStepV2DTO] =
writeDuringWriteRestrictionOrAccessDenied(owner) {
- withId(learningPathId).flatMap(_.canEditLearningpath(owner)) match {
- case Failure(ex) => Failure(ex)
- case Success(learningPath) =>
- val stepsToChange = learningPathRepository.learningStepsFor(learningPathId)
- val stepToUpdate = stepsToChange.find(_.id.contains(learningStepId)) match {
- case Some(ls) if ls.status == DELETED && newStatus == DELETED =>
- val msg = s"Learningstep with id $learningStepId for learningpath with id $learningPathId not found"
- return Failure(NotFoundException(msg))
- case None =>
- val msg = s"Learningstep with id $learningStepId for learningpath with id $learningPathId not found"
- return Failure(NotFoundException(msg))
- case Some(ls) => ls
- }
+ boundary {
- val (updatedPath, updatedStep) =
- updateWithStepSeqNo(learningStepId, newStatus, learningPath, stepToUpdate, stepsToChange, owner)
+ withId(learningPathId).flatMap(_.canEditLearningpath(owner)) match {
+ case Failure(ex) => Failure(ex)
+ case Success(learningPath) =>
+ val stepsToChange = learningPathRepository.learningStepsFor(learningPathId)
+ val stepToUpdate = stepsToChange.find(_.id.contains(learningStepId)) match {
+ case Some(ls) if ls.status == DELETED && newStatus == DELETED =>
+ val msg = s"Learningstep with id $learningStepId for learningpath with id $learningPathId not found"
+ boundary.break(Failure(NotFoundException(msg)))
+ case None =>
+ val msg = s"Learningstep with id $learningStepId for learningpath with id $learningPathId not found"
+ boundary.break(Failure(NotFoundException(msg)))
+ case Some(ls) => ls
+ }
- updateSearchAndTaxonomy(updatedPath, owner.tokenUser).flatMap(_ =>
- converterService.asApiLearningStepV2(
- updatedStep,
- updatedPath,
- props.DefaultLanguage,
- fallback = true,
- owner
- )
- )
+ val (updatedPath, updatedStep) =
+ updateWithStepSeqNo(learningStepId, newStatus, learningPath, stepToUpdate, stepsToChange, owner)
+ updateSearchAndTaxonomy(updatedPath, owner.tokenUser).flatMap(_ =>
+ converterService.asApiLearningStepV2(
+ updatedStep,
+ updatedPath,
+ props.DefaultLanguage,
+ fallback = true,
+ owner
+ )
+ )
+ }
}
}
@@ -425,7 +429,7 @@ trait UpdateService {
def addOrSubtract(seqNo: Int): Int = if (from > to) seqNo + 1 else seqNo - 1
inTransaction { implicit session =>
- learningPathRepository.updateLearningStep(learningStep.copy(seqNo = seqNo)): Unit
+ val _ = learningPathRepository.updateLearningStep(learningStep.copy(seqNo = seqNo))
toUpdate.foreach(step => {
learningPathRepository.updateLearningStep(step.copy(seqNo = addOrSubtract(step.seqNo)))
})
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchConverterServiceComponent.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchConverterServiceComponent.scala
index ee49a3ba8f..e2a0fa04b4 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchConverterServiceComponent.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchConverterServiceComponent.scala
@@ -24,11 +24,9 @@ import no.ndla.search.model.{LanguageValue, SearchableLanguageList, SearchableLa
trait SearchConverterServiceComponent {
this: ConverterService & Props & SearchLanguage =>
- val searchConverterService: SearchConverterService
+ lazy val searchConverterService: SearchConverterService
class SearchConverterService {
- import props.DefaultLanguage
-
def asApiLearningPathSummaryV2(
searchableLearningPath: SearchableLearningPath,
language: String
@@ -48,11 +46,11 @@ trait SearchConverterServiceComponent {
searchableLearningPath.id,
revision = None,
findByLanguageOrBestEffort(titles, language)
- .getOrElse(api.TitleDTO("", DefaultLanguage)),
+ .getOrElse(api.TitleDTO("", props.DefaultLanguage)),
findByLanguageOrBestEffort(descriptions, language)
- .getOrElse(api.DescriptionDTO("", DefaultLanguage)),
+ .getOrElse(api.DescriptionDTO("", props.DefaultLanguage)),
findByLanguageOrBestEffort(introductions, language)
- .getOrElse(api.IntroductionDTO("", DefaultLanguage)),
+ .getOrElse(api.IntroductionDTO("", props.DefaultLanguage)),
createUrlToLearningPath(searchableLearningPath.id),
searchableLearningPath.coverPhotoUrl,
searchableLearningPath.duration,
@@ -60,7 +58,7 @@ trait SearchConverterServiceComponent {
searchableLearningPath.created,
searchableLearningPath.lastUpdated,
findByLanguageOrBestEffort(tags, language)
- .getOrElse(api.LearningPathTagsDTO(Seq(), DefaultLanguage)),
+ .getOrElse(api.LearningPathTagsDTO(Seq(), props.DefaultLanguage)),
searchableLearningPath.copyright,
supportedLanguages,
searchableLearningPath.isBasedOn,
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchIndexService.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchIndexService.scala
index 104f1eb17c..c7d0bde1fd 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchIndexService.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchIndexService.scala
@@ -28,13 +28,12 @@ import no.ndla.search.model.domain.{BulkIndexResult, ElasticIndexingException, R
trait SearchIndexService {
this: Elastic4sClient & SearchConverterServiceComponent & LearningPathRepositoryComponent & SearchApiClient &
BaseIndexService & Props & SearchLanguage =>
- val searchIndexService: SearchIndexService
+ lazy val searchIndexService: SearchIndexService
class SearchIndexService extends BaseIndexService with StrictLogging {
- import props.{SearchDocument, SearchIndex, ElasticSearchIndexMaxResultWindow}
- override val documentType: String = SearchDocument
- override val searchIndex: String = SearchIndex
- override val MaxResultWindowOption: Int = ElasticSearchIndexMaxResultWindow
+ override val documentType: String = props.SearchDocument
+ override val searchIndex: String = props.SearchIndex
+ override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
def indexDocuments: Try[ReindexResult] = indexDocuments(None)
def indexDocuments(numShards: Option[Int]): Try[ReindexResult] = synchronized {
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchService.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchService.scala
index fae2668024..5a451f63f1 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchService.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/service/search/SearchService.scala
@@ -33,16 +33,15 @@ import scala.util.{Failure, Success, Try}
import no.ndla.learningpathapi.integration.TaxonomyApiClient
trait SearchService extends StrictLogging {
- this: SearchIndexService & Elastic4sClient & SearchConverterServiceComponent & TaxonomyApiClient & Props & ErrorHandling =>
- val searchService: SearchService
+ this: SearchIndexService & Elastic4sClient & SearchConverterServiceComponent & TaxonomyApiClient & Props &
+ ErrorHandling =>
+ lazy val searchService: SearchService
class SearchService {
- import props.{DefaultLanguage, ElasticSearchIndexMaxResultWindow, ElasticSearchScrollKeepAlive}
-
def scroll(scrollId: String, language: String): Try[SearchResult] =
e4sClient
.execute {
- searchScroll(scrollId, ElasticSearchScrollKeepAlive)
+ searchScroll(scrollId, props.ElasticSearchScrollKeepAlive)
}
.map(response => {
val hits = getHitsV2(response.result, language)
@@ -194,9 +193,9 @@ trait SearchService extends StrictLogging {
val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
val requestedResultWindow = settings.page.getOrElse(1) * numResults
- if (requestedResultWindow > ElasticSearchIndexMaxResultWindow) {
+ if (requestedResultWindow > props.ElasticSearchIndexMaxResultWindow) {
logger.info(
- s"Max supported results are $ElasticSearchIndexMaxResultWindow, user requested $requestedResultWindow"
+ s"Max supported results are ${props.ElasticSearchIndexMaxResultWindow}, user requested $requestedResultWindow"
)
Failure(LearningpathHelpers.ResultWindowTooLargeException())
} else {
@@ -211,7 +210,7 @@ trait SearchService extends StrictLogging {
// Only add scroll param if it is first page
val searchWithScroll =
if (startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute.explain(true) }
e4sClient.execute(searchWithScroll) match {
@@ -263,7 +262,7 @@ trait SearchService extends StrictLogging {
private def getSortDefinition(sort: Sort, language: String) = {
val sortLanguage = language match {
- case NoLanguage => DefaultLanguage
+ case NoLanguage => props.DefaultLanguage
case _ => language
}
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LanguageValidator.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LanguageValidator.scala
index e8f6029663..63286df837 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LanguageValidator.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LanguageValidator.scala
@@ -12,7 +12,7 @@ import no.ndla.common.errors.ValidationMessage
import no.ndla.mapping.ISO639.get6391CodeFor6392CodeMappings
trait LanguageValidator {
- val languageValidator: LanguageValidator
+ lazy val languageValidator: LanguageValidator
class LanguageValidator {
private def languageCodeSupported6391(languageCode: String, allowUnknownLanguage: Boolean): Boolean = {
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningPathValidator.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningPathValidator.scala
index 1ab1454536..4c0de26bf1 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningPathValidator.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningPathValidator.scala
@@ -17,7 +17,7 @@ import no.ndla.mapping.License.getLicense
trait LearningPathValidator {
this: LanguageValidator & TitleValidator & TextValidator =>
- val learningPathValidator: LearningPathValidator
+ lazy val learningPathValidator: LearningPathValidator
class LearningPathValidator(descriptionRequired: Boolean = false) {
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningStepValidator.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningStepValidator.scala
index df895789a6..35c2dbeb0f 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningStepValidator.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/LearningStepValidator.scala
@@ -15,7 +15,7 @@ import scala.util.{Failure, Success, Try}
trait LearningStepValidator {
this: TitleValidator & LanguageValidator & TextValidator & UrlValidator =>
- val learningStepValidator: LearningStepValidator
+ lazy val learningStepValidator: LearningStepValidator
class LearningStepValidator {
val noHtmlTextValidator = new TextValidator(allowHtml = false)
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TextValidator.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TextValidator.scala
index 5579d44376..c0db951d80 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TextValidator.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TextValidator.scala
@@ -17,10 +17,8 @@ trait TextValidator {
this: Props =>
class TextValidator(allowHtml: Boolean) {
- import props.*
-
val IllegalContentInBasicText: String =
- s"The content contains illegal html-characters. Allowed characters are ${AllowedHtmlTags.mkString(", ")}"
+ s"The content contains illegal html-characters. Allowed characters are ${props.AllowedHtmlTags.mkString(", ")}"
val IllegalContentInPlainText =
"The content contains illegal html-characters. No HTML is allowed."
diff --git a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TitleValidator.scala b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TitleValidator.scala
index 4e3d0d3452..82da0eab9a 100644
--- a/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TitleValidator.scala
+++ b/learningpath-api/src/main/scala/no/ndla/learningpathapi/validation/TitleValidator.scala
@@ -13,7 +13,7 @@ import no.ndla.common.model.domain.Title
trait TitleValidator {
this: LanguageValidator & TextValidator =>
- val titleValidator: TitleValidator
+ lazy val titleValidator: TitleValidator
class TitleValidator(titleRequired: Boolean = true) {
private val MISSING_TITLE = "At least one title is required."
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/TestEnvironment.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/TestEnvironment.scala
index baed973d58..6929764f60 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/TestEnvironment.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/TestEnvironment.scala
@@ -66,36 +66,35 @@ trait TestEnvironment
with RedisClient {
lazy val props = new LearningpathApiProperties
- val migrator: DBMigrator = mock[DBMigrator]
- val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val migrator: DBMigrator = mock[DBMigrator]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
- val learningPathRepository: LearningPathRepository = mock[LearningPathRepository]
- val learningPathRepositoryComponent: LearningPathRepositoryComponent = mock[LearningPathRepositoryComponent]
- val readService: ReadService = mock[ReadService]
- val updateService: UpdateService = mock[UpdateService]
- val searchConverterService: SearchConverterService = mock[SearchConverterService]
- val searchService: SearchService = mock[SearchService]
- val searchIndexService: SearchIndexService = mock[SearchIndexService]
- val converterService: ConverterService = org.mockito.Mockito.spy(new ConverterService)
- val clock: SystemClock = mock[SystemClock]
- val uuidUtil: UUIDUtil = mock[UUIDUtil]
- val taxonomyApiClient: TaxonomyApiClient = mock[TaxonomyApiClient]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val languageValidator: LanguageValidator = mock[LanguageValidator]
- val learningpathControllerV2: LearningpathControllerV2 = mock[LearningpathControllerV2]
- val statsController: StatsController = mock[StatsController]
- val internController: InternController = mock[InternController]
- val healthController: TapirHealthController = mock[TapirHealthController]
- val learningStepValidator: LearningStepValidator = mock[LearningStepValidator]
- val learningPathValidator: LearningPathValidator = mock[LearningPathValidator]
- val titleValidator: TitleValidator = mock[TitleValidator]
+ override lazy val learningPathRepository: LearningPathRepository = mock[LearningPathRepository]
+ override lazy val readService: ReadService = mock[ReadService]
+ override lazy val updateService: UpdateService = mock[UpdateService]
+ override lazy val searchConverterService: SearchConverterService = mock[SearchConverterService]
+ override lazy val searchService: SearchService = mock[SearchService]
+ override lazy val searchIndexService: SearchIndexService = mock[SearchIndexService]
+ override lazy val converterService: ConverterService = org.mockito.Mockito.spy(new ConverterService)
+ override lazy val clock: SystemClock = mock[SystemClock]
+ override lazy val uuidUtil: UUIDUtil = mock[UUIDUtil]
+ override lazy val taxonomyApiClient: TaxonomyApiClient = mock[TaxonomyApiClient]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val languageValidator: LanguageValidator = mock[LanguageValidator]
+ override lazy val learningpathControllerV2: LearningpathControllerV2 = mock[LearningpathControllerV2]
+ override lazy val statsController: StatsController = mock[StatsController]
+ override lazy val internController: InternController = mock[InternController]
+ override lazy val healthController: TapirHealthController = mock[TapirHealthController]
+ override lazy val learningStepValidator: LearningStepValidator = mock[LearningStepValidator]
+ override lazy val learningPathValidator: LearningPathValidator = mock[LearningPathValidator]
+ override lazy val titleValidator: TitleValidator = mock[TitleValidator]
var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
- val searchApiClient: SearchApiClient = mock[SearchApiClient]
- val oembedProxyClient: OembedProxyClient = mock[OembedProxyClient]
- val feideApiClient: FeideApiClient = mock[FeideApiClient]
- val redisClient: RedisClient = mock[RedisClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val DBUtil: DBUtility = mock[DBUtility]
+ override lazy val searchApiClient: SearchApiClient = mock[SearchApiClient]
+ override lazy val oembedProxyClient: OembedProxyClient = mock[OembedProxyClient]
+ override lazy val feideApiClient: FeideApiClient = mock[FeideApiClient]
+ override lazy val redisClient: RedisClient = mock[RedisClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val DBUtil: DBUtility = mock[DBUtility]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponentIntegrationTest.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponentIntegrationTest.scala
index 86cce3199e..c19e10349a 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponentIntegrationTest.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/repository/LearningPathRepositoryComponentIntegrationTest.scala
@@ -41,8 +41,8 @@ class LearningPathRepositoryComponentIntegrationTest
with TestEnvironment {
override val schemaName = "learningpathapi_test"
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator: DBMigrator = DBMigrator()
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator: DBMigrator = DBMigrator()
var repository: LearningPathRepository = _
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ConverterServiceTest.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ConverterServiceTest.scala
index c5baadceea..165b97780a 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ConverterServiceTest.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ConverterServiceTest.scala
@@ -31,7 +31,6 @@ import scala.util.{Failure, Success}
import no.ndla.common.model.domain.Priority
class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
- import props.DefaultLanguage
val clinton: commonApi.AuthorDTO = commonApi.AuthorDTO(ContributorType.Writer, "Crooked Hillary")
val license: commonApi.LicenseDTO =
commonApi.LicenseDTO(
@@ -105,7 +104,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
),
articleId = Some(123L)
)
- val apiTags: List[api.LearningPathTagsDTO] = List(api.LearningPathTagsDTO(Seq("tag"), DefaultLanguage))
+ val apiTags: List[api.LearningPathTagsDTO] = List(api.LearningPathTagsDTO(Seq("tag"), props.DefaultLanguage))
val randomDate: NDLADate = NDLADate.now()
var service: ConverterService = _
@@ -115,15 +114,15 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
revision = Some(1),
externalId = None,
isBasedOn = None,
- title = List(Title("tittel", DefaultLanguage)),
- description = List(Description("deskripsjon", DefaultLanguage)),
+ title = List(Title("tittel", props.DefaultLanguage)),
+ description = List(Description("deskripsjon", props.DefaultLanguage)),
coverPhotoId = None,
duration = Some(60),
status = LearningPathStatus.PRIVATE,
verificationStatus = LearningPathVerificationStatus.CREATED_BY_NDLA,
created = randomDate,
lastUpdated = randomDate,
- tags = List(Tag(List("tag"), DefaultLanguage)),
+ tags = List(Tag(List("tag"), props.DefaultLanguage)),
owner = "me",
copyright = LearningpathCopyright(CC_BY.toString, List.empty),
isMyNDLAOwner = false,
@@ -143,8 +142,8 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
1,
1,
None,
- api.TitleDTO("tittel", DefaultLanguage),
- api.DescriptionDTO("deskripsjon", DefaultLanguage),
+ api.TitleDTO("tittel", props.DefaultLanguage),
+ api.DescriptionDTO("deskripsjon", props.DefaultLanguage),
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1",
List.empty,
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1/learningsteps",
@@ -154,7 +153,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
LearningPathVerificationStatus.CREATED_BY_NDLA.toString,
randomDate,
randomDate,
- api.LearningPathTagsDTO(Seq("tag"), DefaultLanguage),
+ api.LearningPathTagsDTO(Seq("tag"), props.DefaultLanguage),
api.CopyrightDTO(
commonApi.LicenseDTO(
CC_BY.toString,
@@ -176,7 +175,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
)
service.asApiLearningpathV2(
domainLearningPath.copy(title = domainLearningPath.title :+ Title("test", "en")),
- DefaultLanguage,
+ props.DefaultLanguage,
false,
TokenUser("me", Set.empty, None).toCombined
) should equal(expected)
@@ -199,8 +198,8 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
1,
1,
None,
- api.TitleDTO("tittel", DefaultLanguage),
- api.DescriptionDTO("deskripsjon", DefaultLanguage),
+ api.TitleDTO("tittel", props.DefaultLanguage),
+ api.DescriptionDTO("deskripsjon", props.DefaultLanguage),
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1",
List.empty,
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1/learningsteps",
@@ -210,7 +209,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
LearningPathVerificationStatus.CREATED_BY_NDLA.toString,
randomDate,
randomDate,
- api.LearningPathTagsDTO(Seq("tag"), DefaultLanguage),
+ api.LearningPathTagsDTO(Seq("tag"), props.DefaultLanguage),
api.CopyrightDTO(
commonApi.LicenseDTO(
CC_BY.toString,
@@ -243,16 +242,16 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
api.LearningPathSummaryV2DTO(
1,
Some(1),
- api.TitleDTO("tittel", DefaultLanguage),
- api.DescriptionDTO("deskripsjon", DefaultLanguage),
- api.IntroductionDTO("", DefaultLanguage),
+ api.TitleDTO("tittel", props.DefaultLanguage),
+ api.DescriptionDTO("deskripsjon", props.DefaultLanguage),
+ api.IntroductionDTO("", props.DefaultLanguage),
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1",
None,
Some(60),
LearningPathStatus.PRIVATE.toString,
randomDate,
randomDate,
- api.LearningPathTagsDTO(Seq("tag"), DefaultLanguage),
+ api.LearningPathTagsDTO(Seq("tag"), props.DefaultLanguage),
api.CopyrightDTO(
commonApi.LicenseDTO(
CC_BY.toString,
@@ -278,9 +277,9 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
1,
1,
1,
- api.TitleDTO("tittel", DefaultLanguage),
+ api.TitleDTO("tittel", props.DefaultLanguage),
None,
- Some(api.DescriptionDTO("deskripsjon", DefaultLanguage)),
+ Some(api.DescriptionDTO("deskripsjon", props.DefaultLanguage)),
None,
None,
showTitle = false,
@@ -289,13 +288,13 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1/learningsteps/1",
canEdit = true,
"ACTIVE",
- Seq(DefaultLanguage)
+ Seq(props.DefaultLanguage)
)
)
service.asApiLearningStepV2(
domainLearningStep2,
domainLearningPath,
- DefaultLanguage,
+ props.DefaultLanguage,
false,
TokenUser("me", Set.empty, None).toCombined
) should equal(learningstep)
@@ -325,9 +324,9 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
1,
1,
1,
- api.TitleDTO("tittel", DefaultLanguage),
+ api.TitleDTO("tittel", props.DefaultLanguage),
None,
- Some(api.DescriptionDTO("deskripsjon", DefaultLanguage)),
+ Some(api.DescriptionDTO("deskripsjon", props.DefaultLanguage)),
None,
None,
showTitle = false,
@@ -336,7 +335,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1/learningsteps/1",
canEdit = true,
"ACTIVE",
- Seq(DefaultLanguage)
+ Seq(props.DefaultLanguage)
)
)
service.asApiLearningStepV2(
@@ -353,13 +352,15 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
api.LearningStepSummaryV2DTO(
1,
1,
- api.TitleDTO("tittel", DefaultLanguage),
+ api.TitleDTO("tittel", props.DefaultLanguage),
"INTRODUCTION",
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1/learningsteps/1"
)
)
- service.asApiLearningStepSummaryV2(domainLearningStep2, domainLearningPath, DefaultLanguage) should equal(expected)
+ service.asApiLearningStepSummaryV2(domainLearningStep2, domainLearningPath, props.DefaultLanguage) should equal(
+ expected
+ )
}
test("asApiLearningStepSummaryV2 returns what we have when not supported language is given") {
@@ -367,7 +368,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
api.LearningStepSummaryV2DTO(
1,
1,
- api.TitleDTO("tittel", DefaultLanguage),
+ api.TitleDTO("tittel", props.DefaultLanguage),
"INTRODUCTION",
"http://api-gateway.ndla-local/learningpath-api/v2/learningpaths/1/learningsteps/1"
)
@@ -380,8 +381,8 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
test("asApiLearningPathTagsSummary converts api LearningPathTags to api LearningPathTagsSummary") {
val expected =
- Some(api.LearningPathTagsSummaryDTO(DefaultLanguage, Seq(DefaultLanguage), Seq("tag")))
- service.asApiLearningPathTagsSummary(apiTags, DefaultLanguage, false) should equal(expected)
+ Some(api.LearningPathTagsSummaryDTO(props.DefaultLanguage, Seq(props.DefaultLanguage), Seq("tag")))
+ service.asApiLearningPathTagsSummary(apiTags, props.DefaultLanguage, false) should equal(expected)
}
test("asApiLearningPathTagsSummary returns None if fallback is false and language is unsupported") {
@@ -392,7 +393,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
"asApiLearningPathTagsSummary converts api LearningPathTags to api LearningPathTagsSummary if language is undefined and fallback is true"
) {
val expected =
- Some(api.LearningPathTagsSummaryDTO(DefaultLanguage, Seq(DefaultLanguage), Seq("tag")))
+ Some(api.LearningPathTagsSummaryDTO(props.DefaultLanguage, Seq(props.DefaultLanguage), Seq("tag")))
service.asApiLearningPathTagsSummary(apiTags, "hurr durr I'm a language", true) should equal(expected)
}
@@ -464,7 +465,7 @@ class ConverterServiceTest extends UnitSuite with UnitTestEnvironment {
s"${props.Domain}/image-api/raw/id/1",
s"${props.Domain}/image-api/v3/images/1"
)
- val Some(result) = service.asCoverPhoto("1")
+ val Some(result) = service.asCoverPhoto("1"): @unchecked
result should equal(expectedResult)
}
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ReadServiceTest.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ReadServiceTest.scala
index db79f17020..7a666462b2 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ReadServiceTest.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/ReadServiceTest.scala
@@ -145,7 +145,8 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
test("That withIdV2 returns None when id does not exist") {
when(learningPathRepository.withId(eqTo(PUBLISHED_ID))(any[DBSession])).thenReturn(None)
- val Failure(ex) = service.withIdV2(PUBLISHED_ID, "nb", fallback = false, TokenUser.PublicUser.toCombined)
+ val Failure(ex) =
+ service.withIdV2(PUBLISHED_ID, "nb", fallback = false, TokenUser.PublicUser.toCombined): @unchecked
ex.isInstanceOf[NotFoundException]
}
@@ -170,14 +171,14 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
test("That withId throws an AccessDeniedException when the status is PRIVATE and no user") {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
- val Failure(ex) = service.withIdV2(PRIVATE_ID, "nb", fallback = false, TokenUser.PublicUser.toCombined)
+ val Failure(ex) = service.withIdV2(PRIVATE_ID, "nb", fallback = false, TokenUser.PublicUser.toCombined): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
test("That withId throws an AccessDeniedException when the status is PRIVATE and user is not the owner") {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
- val Failure(ex) = service.withIdV2(PRIVATE_ID, "nb", fallback = false, PUBLISHED_OWNER.toCombined)
+ val Failure(ex) = service.withIdV2(PRIVATE_ID, "nb", fallback = false, PUBLISHED_OWNER.toCombined): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -192,7 +193,7 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
test("That statusFor returns None when id does not exist") {
when(learningPathRepository.withId(eqTo(PUBLISHED_ID))(any[DBSession])).thenReturn(None)
- val Failure(ex) = service.statusFor(PUBLISHED_ID, TokenUser.PublicUser.toCombined)
+ val Failure(ex) = service.statusFor(PUBLISHED_ID, TokenUser.PublicUser.toCombined): @unchecked
ex.isInstanceOf[NotFoundException]
}
@@ -208,14 +209,14 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
- val Failure(ex) = service.statusFor(2, TokenUser.PublicUser.toCombined)
+ val Failure(ex) = service.statusFor(2, TokenUser.PublicUser.toCombined): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
test("That statusFor throws an AccessDeniedException when the status is PRIVATE and user is not the owner") {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
- val Failure(ex) = service.statusFor(2, PUBLISHED_OWNER.toCombined)
+ val Failure(ex) = service.statusFor(2, PUBLISHED_OWNER.toCombined): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -235,7 +236,7 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
"nb",
fallback = false,
TokenUser.PublicUser.toCombined
- )
+ ): @unchecked
ex.isInstanceOf[NotFoundException]
}
@@ -250,7 +251,7 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
"nb",
fallback = false,
TokenUser.PublicUser.toCombined
- )
+ ): @unchecked
ex.isInstanceOf[NotFoundException]
}
@@ -299,7 +300,7 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
"nb",
fallback = false,
TokenUser.PublicUser.toCombined
- )
+ ): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -313,7 +314,7 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
"nb",
fallback = false,
PUBLISHED_OWNER.toCombined
- )
+ ): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -336,7 +337,13 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
test("That learningstepV2For returns None when the learningPath does not exist") {
when(learningPathRepository.withId(eqTo(PUBLISHED_ID))(any[DBSession])).thenReturn(None)
val Failure(ex) =
- service.learningstepV2For(PUBLISHED_ID, STEP1.id.get, "nb", fallback = false, TokenUser.PublicUser.toCombined)
+ service.learningstepV2For(
+ PUBLISHED_ID,
+ STEP1.id.get,
+ "nb",
+ fallback = false,
+ TokenUser.PublicUser.toCombined
+ ): @unchecked
ex.isInstanceOf[NotFoundException]
}
@@ -346,7 +353,13 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.learningStepWithId(eqTo(PUBLISHED_ID), eqTo(STEP1.id.get))(any[DBSession]))
.thenReturn(None)
val Failure(ex) =
- service.learningstepV2For(PUBLISHED_ID, STEP1.id.get, "nb", fallback = false, TokenUser.PublicUser.toCombined)
+ service.learningstepV2For(
+ PUBLISHED_ID,
+ STEP1.id.get,
+ "nb",
+ fallback = false,
+ TokenUser.PublicUser.toCombined
+ ): @unchecked
ex.isInstanceOf[NotFoundException]
}
@@ -380,7 +393,13 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
val Failure(ex) =
- service.learningstepV2For(PRIVATE_ID, STEP1.id.get, "nb", fallback = false, TokenUser.PublicUser.toCombined)
+ service.learningstepV2For(
+ PRIVATE_ID,
+ STEP1.id.get,
+ "nb",
+ fallback = false,
+ TokenUser.PublicUser.toCombined
+ ): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -388,7 +407,13 @@ class ReadServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
val Failure(ex) =
- service.learningstepV2For(PRIVATE_ID, STEP1.id.get, "nb", fallback = false, PUBLISHED_OWNER.toCombined)
+ service.learningstepV2For(
+ PRIVATE_ID,
+ STEP1.id.get,
+ "nb",
+ fallback = false,
+ PUBLISHED_OWNER.toCombined
+ ): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/UpdateServiceTest.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/UpdateServiceTest.scala
index a2cfd84191..ada007eac9 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/UpdateServiceTest.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/UpdateServiceTest.scala
@@ -343,7 +343,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
doAnswer((i: InvocationOnMock) => {
val x = i.getArgument[DBSession => Try[?]](0)
x(mock[DBSession])
- }).when(DBUtil).rollbackOnFailure(any)
+ }).when(DBUtil).rollbackOnFailure(any())
}
test("That addLearningPathV2 inserts the given LearningPathV2") {
@@ -360,7 +360,8 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
test("That updateLearningPathV2 returns Failure when the given ID does not exist") {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession])).thenReturn(None)
- val Failure(ex) = service.updateLearningPathV2(PRIVATE_ID, UPDATED_PRIVATE_LEARNINGPATHV2, PRIVATE_OWNER.toCombined)
+ val Failure(ex) =
+ service.updateLearningPathV2(PRIVATE_ID, UPDATED_PRIVATE_LEARNINGPATHV2, PRIVATE_OWNER.toCombined): @unchecked
ex should be(NotFoundException("Could not find learningpath with id '2'."))
}
@@ -420,7 +421,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
PRIVATE_ID,
UPDATED_PRIVATE_LEARNINGPATHV2,
TokenUser("not_the_owner", Set.empty, None).toCombined
- )
+ ): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -449,7 +450,12 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
test("That updateLearningPathStatusV2 returns None when the given ID does not exist") {
when(learningPathRepository.withIdIncludingDeleted(eqTo(PRIVATE_ID))(any[DBSession])).thenReturn(None)
val Failure(ex) =
- service.updateLearningPathStatusV2(PRIVATE_ID, LearningPathStatus.PUBLISHED, PRIVATE_OWNER.toCombined, "nb")
+ service.updateLearningPathStatusV2(
+ PRIVATE_ID,
+ LearningPathStatus.PUBLISHED,
+ PRIVATE_OWNER.toCombined,
+ "nb"
+ ): @unchecked
ex should be(NotFoundException(s"Could not find learningpath with id '$PRIVATE_ID'."))
}
@@ -614,7 +620,12 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withIdIncludingDeleted(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
val Failure(ex) =
- service.updateLearningPathStatusV2(PRIVATE_ID, LearningPathStatus.PUBLISHED, PRIVATE_OWNER.toCombined, "nb")
+ service.updateLearningPathStatusV2(
+ PRIVATE_ID,
+ LearningPathStatus.PUBLISHED,
+ PRIVATE_OWNER.toCombined,
+ "nb"
+ ): @unchecked
ex should be(AccessDeniedException("You need to be a publisher to publish learningpaths."))
}
@@ -656,7 +667,12 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withIdIncludingDeleted(eqTo(PUBLISHED_ID))(any[DBSession]))
.thenReturn(Some(PUBLISHED_LEARNINGPATH))
val Failure(ex) =
- service.updateLearningPathStatusV2(PUBLISHED_ID, LearningPathStatus.PRIVATE, PRIVATE_OWNER.toCombined, "nb")
+ service.updateLearningPathStatusV2(
+ PUBLISHED_ID,
+ LearningPathStatus.PRIVATE,
+ PRIVATE_OWNER.toCombined,
+ "nb"
+ ): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -712,7 +728,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
test("That addLearningStepV2 returns None when the given learningpath does not exist") {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession])).thenReturn(None)
- val Failure(ex) = service.addLearningStepV2(PRIVATE_ID, NEW_STEPV2, PRIVATE_OWNER.toCombined)
+ val Failure(ex) = service.addLearningStepV2(PRIVATE_ID, NEW_STEPV2, PRIVATE_OWNER.toCombined): @unchecked
ex.isInstanceOf[NotFoundException] should be(true)
verify(learningPathRepository, never).insertLearningStep(any[LearningStep])(any)
verify(learningPathRepository, never).update(any[LearningPath])(any)
@@ -763,7 +779,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
test("That addLearningStepV2 throws an AccessDeniedException when the given user is NOT the owner") {
when(learningPathRepository.withId(eqTo(PUBLISHED_ID))(any[DBSession])).thenReturn(Some(PUBLISHED_LEARNINGPATH))
- val Failure(ex) = service.addLearningStepV2(PUBLISHED_ID, NEW_STEPV2, PRIVATE_OWNER.toCombined)
+ val Failure(ex) = service.addLearningStepV2(PUBLISHED_ID, NEW_STEPV2, PRIVATE_OWNER.toCombined): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -771,7 +787,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withId(eqTo(PUBLISHED_ID))(any[DBSession])).thenReturn(None)
val Failure(ex) =
- service.updateLearningStepV2(PUBLISHED_ID, STEP1.id.get, UPDATED_STEPV2, PUBLISHED_OWNER.toCombined)
+ service.updateLearningStepV2(PUBLISHED_ID, STEP1.id.get, UPDATED_STEPV2, PUBLISHED_OWNER.toCombined): @unchecked
ex.isInstanceOf[NotFoundException] should be(true)
verify(learningPathRepository, never).updateLearningStep(any[LearningStep])(any)
@@ -783,7 +799,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.learningStepWithId(eqTo(PUBLISHED_ID), eqTo(STEP1.id.get))(any[DBSession]))
.thenReturn(None)
val Failure(ex) =
- service.updateLearningStepV2(PUBLISHED_ID, STEP1.id.get, UPDATED_STEPV2, PUBLISHED_OWNER.toCombined)
+ service.updateLearningStepV2(PUBLISHED_ID, STEP1.id.get, UPDATED_STEPV2, PUBLISHED_OWNER.toCombined): @unchecked
ex.isInstanceOf[NotFoundException] should be(true)
verify(learningPathRepository, never).updateLearningStep(any[LearningStep])(any[DBSession])
verify(learningPathRepository, never).update(any[LearningPath])(any[DBSession])
@@ -846,7 +862,8 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
test("That updateLearningStepV2 throws an AccessDeniedException when the given user is NOT the owner") {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession])).thenReturn(Some(PRIVATE_LEARNINGPATH))
when(learningPathRepository.learningStepWithId(PRIVATE_ID, STEP1.id.get)).thenReturn(Some(STEP1))
- val Failure(ex) = service.updateLearningStepV2(PRIVATE_ID, STEP1.id.get, UPDATED_STEPV2, PUBLISHED_OWNER.toCombined)
+ val Failure(ex) =
+ service.updateLearningStepV2(PRIVATE_ID, STEP1.id.get, UPDATED_STEPV2, PUBLISHED_OWNER.toCombined): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -854,7 +871,12 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withId(eqTo(PUBLISHED_ID))(any[DBSession])).thenReturn(None)
val Failure(ex) =
- service.updateLearningStepStatusV2(PUBLISHED_ID, STEP1.id.get, StepStatus.DELETED, PUBLISHED_OWNER.toCombined)
+ service.updateLearningStepStatusV2(
+ PUBLISHED_ID,
+ STEP1.id.get,
+ StepStatus.DELETED,
+ PUBLISHED_OWNER.toCombined
+ ): @unchecked
ex.isInstanceOf[NotFoundException] should be(true)
}
@@ -865,7 +887,12 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
.thenReturn(Seq())
val Failure(ex) =
- service.updateLearningStepStatusV2(PUBLISHED_ID, STEP1.id.get, StepStatus.DELETED, PUBLISHED_OWNER.toCombined)
+ service.updateLearningStepStatusV2(
+ PUBLISHED_ID,
+ STEP1.id.get,
+ StepStatus.DELETED,
+ PUBLISHED_OWNER.toCombined
+ ): @unchecked
ex.isInstanceOf[NotFoundException] should be(true)
}
@@ -1001,7 +1028,12 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.learningStepWithId(PRIVATE_ID, STEP1.id.get))
.thenReturn(Some(STEP1))
val Failure(ex) =
- service.updateLearningStepStatusV2(PRIVATE_ID, STEP1.id.get, StepStatus.DELETED, PUBLISHED_OWNER.toCombined)
+ service.updateLearningStepStatusV2(
+ PRIVATE_ID,
+ STEP1.id.get,
+ StepStatus.DELETED,
+ PUBLISHED_OWNER.toCombined
+ ): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -1012,7 +1044,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
.thenReturn(Some(STEP1))
val Failure(exception: ValidationException) =
- service.updateSeqNo(PRIVATE_ID, STEP1.id.get, 100, PRIVATE_OWNER.toCombined)
+ service.updateSeqNo(PRIVATE_ID, STEP1.id.get, 100, PRIVATE_OWNER.toCombined): @unchecked
exception.errors.length should be(1)
exception.errors.head.field should equal("seqNo")
@@ -1116,7 +1148,8 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
when(learningPathRepository.withId(eqTo(PRIVATE_ID))(any[DBSession]))
.thenReturn(Some(PRIVATE_LEARNINGPATH))
- val Failure(ex) = service.newFromExistingV2(PRIVATE_ID, NEW_COPIED_LEARNINGPATHV2, PUBLISHED_OWNER.toCombined)
+ val Failure(ex) =
+ service.newFromExistingV2(PRIVATE_ID, NEW_COPIED_LEARNINGPATHV2, PUBLISHED_OWNER.toCombined): @unchecked
ex should be(AccessDeniedException("You do not have access to the requested resource."))
}
@@ -1286,7 +1319,8 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
test("That newFromExistingV2 returns None when given id does not exist") {
when(learningPathRepository.withId(eqTo(PUBLISHED_ID))(any[DBSession])).thenReturn(None)
- val Failure(ex) = service.newFromExistingV2(PUBLISHED_ID, NEW_COPIED_LEARNINGPATHV2, PUBLISHED_OWNER.toCombined)
+ val Failure(ex) =
+ service.newFromExistingV2(PUBLISHED_ID, NEW_COPIED_LEARNINGPATHV2, PUBLISHED_OWNER.toCombined): @unchecked
ex.isInstanceOf[NotFoundException] should be(true)
}
@@ -1521,7 +1555,7 @@ class UpdateServiceTest extends UnitSuite with UnitTestEnvironment {
STEP1.id.get,
"nb",
PRIVATE_OWNER.toCombined
- )
+ ): @unchecked
result.getMessage should equal("Cannot delete last title for step with id 1")
}
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/search/SearchServiceTest.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/search/SearchServiceTest.scala
index 7922d15bef..92459f2be3 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/search/SearchServiceTest.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/service/search/SearchServiceTest.scala
@@ -35,13 +35,12 @@ import scala.util.Success
import no.ndla.common.model.domain.Priority
class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
- import props.{DefaultPageSize, MaxPageSize}
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.get)
- override val searchConverterService: SearchConverterService = new SearchConverterService
- override val searchIndexService: SearchIndexService = new SearchIndexService {
+ override lazy val searchConverterService: SearchConverterService = new SearchConverterService
+ override lazy val searchIndexService: SearchIndexService = new SearchIndexService {
override val indexShards: Int = 1 // 1 shard for accurate scoring in tests
}
- override val searchService: SearchService = new SearchService
+ override lazy val searchService: SearchService = new SearchService
val paul: Author = Author(ContributorType.Writer, "Truly Weird Rand Paul")
val license: String = License.PublicDomain.toString
@@ -206,7 +205,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
fallback = true,
sort = Sort.ByIdDesc
)
- )
+ ): @unchecked
res.results.length should be(res.totalCount)
res.totalCount should be(5)
}
@@ -219,25 +218,25 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
fallback = false,
sort = Sort.ByIdDesc
)
- )
+ ): @unchecked
res.results.length should be(res.totalCount)
res.totalCount should be(0)
}
test("That getStartAtAndNumResults returns default values for None-input") {
- searchService.getStartAtAndNumResults(None, None) should equal((0, DefaultPageSize))
+ searchService.getStartAtAndNumResults(None, None) should equal((0, props.DefaultPageSize))
}
test("That getStartAtAndNumResults returns SEARCH_MAX_PAGE_SIZE for value greater than SEARCH_MAX_PAGE_SIZE") {
- searchService.getStartAtAndNumResults(None, Some(10001)) should equal((0, MaxPageSize))
+ searchService.getStartAtAndNumResults(None, Some(10001)) should equal((0, props.MaxPageSize))
}
test(
"That getStartAtAndNumResults returns the correct calculated start at for page and page-size with default page-size"
) {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- searchService.getStartAtAndNumResults(Some(page), None) should equal((expectedStartAt, DefaultPageSize))
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ searchService.getStartAtAndNumResults(Some(page), None) should equal((expectedStartAt, props.DefaultPageSize))
}
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
@@ -252,7 +251,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
searchSettings.copy(
sort = Sort.ByTitleDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(4)
@@ -268,7 +267,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
searchSettings.copy(
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(4)
@@ -283,7 +282,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
searchSettings.copy(
sort = Sort.ByIdDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(4)
@@ -299,7 +298,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByIdAsc,
language = Some("*")
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(5)
@@ -315,7 +314,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
searchSettings.copy(
sort = Sort.ByDurationDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(4)
@@ -327,7 +326,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
searchSettings.copy(
sort = Sort.ByDurationAsc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(4)
@@ -339,7 +338,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
searchSettings.copy(
sort = Sort.ByLastUpdatedDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(4)
@@ -352,7 +351,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
searchSettings.copy(
sort = Sort.ByLastUpdatedAsc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(4)
@@ -367,7 +366,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByTitleAsc,
language = Some(Language.AllLanguages)
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(2)
@@ -383,7 +382,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some("en"),
fallback = true
)
- )
+ ): @unchecked
searchResult.totalCount should be(1)
}
@@ -396,7 +395,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some("en"),
fallback = false
)
- )
+ ): @unchecked
searchResult.totalCount should be(0)
}
@@ -407,7 +406,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
query = Some("heltene"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -422,7 +421,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByTitleAsc,
language = Some(Language.AllLanguages)
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -436,7 +435,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByTitleAsc,
language = Some("en")
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -450,7 +449,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByTitleAsc,
language = Some("djb")
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -463,7 +462,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByTitleAsc,
language = Some("kra")
)
- )
+ ): @unchecked
searchResult.totalCount should be(0)
}
@@ -475,7 +474,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
taggedWith = Some("superhelt"),
language = Some("nb")
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(2)
@@ -492,7 +491,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
taggedWith = Some("kanfly"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -505,7 +504,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
query = Some("tøff rar"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(2)
@@ -521,7 +520,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
query = Some("and flaggermus fugl"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(3)
@@ -539,7 +538,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
taggedWith = Some("kanfly"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(2)
@@ -553,7 +552,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
query = Some("and flaggremsu"),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -566,7 +565,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
query = Some("kjeltring + batman"),
sort = Sort.ByRelevanceAsc
)
- )
+ ): @unchecked
searchResult1.totalCount should be(0)
val Success(searchResult2) = searchService.matchingQuery(
@@ -574,7 +573,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
query = Some("tøff + morsom + -and"),
sort = Sort.ByRelevanceAsc
)
- )
+ ): @unchecked
val hits2 = searchResult2.results
searchResult2.totalCount should be(1)
@@ -585,7 +584,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
query = Some("tøff | morsom | kjeltring"),
sort = Sort.ByIdAsc
)
- )
+ ): @unchecked
val hits3 = searchResult3.results
searchResult3.totalCount should be(3)
@@ -599,14 +598,14 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some(Language.AllLanguages),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val Success(searchEn) = searchService.matchingQuery(
searchSettings.copy(
query = Some("Unrelated"),
language = Some(Language.AllLanguages),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
searchEn.totalCount should be(1)
searchEn.results.head.id should be(UnrelatedId)
@@ -629,7 +628,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByTitleAsc,
language = Some(Language.AllLanguages)
)
- )
+ ): @unchecked
search.totalCount should be(5)
search.results.head.id should be(BatmanId)
@@ -648,7 +647,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByTitleAsc,
language = Some(Language.AllLanguages)
)
- )
+ ): @unchecked
search.results.head.supportedLanguages should be(Seq("nb", "en"))
}
@@ -658,7 +657,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some("en"),
fallback = true
)
- )
+ ): @unchecked
search.totalCount should be(5)
search.results.head.id should be(PenguinId)
@@ -682,11 +681,11 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
fallback = true,
shouldScroll = true
)
- )
+ ): @unchecked
- val Success(scroll1) = searchService.scroll(initialSearch.scrollId.get, "all")
- val Success(scroll2) = searchService.scroll(scroll1.scrollId.get, "all")
- val Success(scroll3) = searchService.scroll(scroll2.scrollId.get, "all")
+ val Success(scroll1) = searchService.scroll(initialSearch.scrollId.get, "all"): @unchecked
+ val Success(scroll2) = searchService.scroll(scroll1.scrollId.get, "all"): @unchecked
+ val Success(scroll3) = searchService.scroll(scroll2.scrollId.get, "all"): @unchecked
initialSearch.results.map(_.id) should be(expectedIds.head)
scroll1.results.map(_.id) should be(expectedIds(1))
@@ -704,7 +703,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
verificationStatus = Some("EXTERNAL"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -720,7 +719,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
verificationStatus = Some("CREATED_BY_NDLA"),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = searchResult.results
searchResult.totalCount should be(1)
@@ -733,7 +732,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
sort = Sort.ByIdAsc,
language = Some(Language.AllLanguages)
)
- )
+ ): @unchecked
searchResult.totalCount should be(5)
searchResult.results.map(_.id) should be(Seq(1, 2, 3, 4, 5))
@@ -746,7 +745,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some(Language.AllLanguages),
status = List(learningpath.LearningPathStatus.PUBLISHED, learningpath.LearningPathStatus.UNLISTED)
)
- )
+ ): @unchecked
searchResult.totalCount should be(6)
searchResult.results.map(_.id) should be(Seq(1, 2, 3, 4, 5, 6))
@@ -757,7 +756,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some(Language.AllLanguages),
status = List(learningpath.LearningPathStatus.UNLISTED)
)
- )
+ ): @unchecked
searchResult2.totalCount should be(1)
searchResult2.results.map(_.id) should be(Seq(6))
@@ -770,7 +769,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some(Language.AllLanguages),
withPaths = List("https://ndla.no/article/1", "https://ndla.no/article/2")
)
- )
+ ): @unchecked
searchResult.totalCount should be(2)
searchResult.results.map(_.id) should be(Seq(1, 2))
@@ -781,7 +780,7 @@ class SearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite wit
language = Some(Language.AllLanguages),
withPaths = List("https://ndla.no/article/2")
)
- )
+ ): @unchecked
searchResult2.totalCount should be(0)
}
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/LearningPathValidatorTest.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/LearningPathValidatorTest.scala
index 9330b0b1e4..2801534047 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/LearningPathValidatorTest.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/LearningPathValidatorTest.scala
@@ -26,7 +26,7 @@ class LearningPathValidatorTest extends UnitSuite with TestEnvironment {
var validator: LearningPathValidator = _
- override val clock = new SystemClock
+ override lazy val clock = new SystemClock
override def beforeEach(): Unit = {
validator = new LearningPathValidator
diff --git a/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/TextValidatorTest.scala b/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/TextValidatorTest.scala
index 6f7993084c..3d48b1fb26 100644
--- a/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/TextValidatorTest.scala
+++ b/learningpath-api/src/test/scala/no/ndla/learningpathapi/validation/TextValidatorTest.scala
@@ -11,8 +11,6 @@ package no.ndla.learningpathapi.validation
import no.ndla.learningpathapi.{TestEnvironment, UnitSuite}
class TextValidatorTest extends UnitSuite with TestEnvironment {
- import props.AllowedHtmlTags
-
var allowedHtmlValidator: TextValidator = _
var noHtmlValidator: TextValidator = _
@@ -22,7 +20,7 @@ class TextValidatorTest extends UnitSuite with TestEnvironment {
}
test("That TextValidator allows all tags in AllowedHtmlTags tags") {
- AllowedHtmlTags.foreach(tag => {
+ props.AllowedHtmlTags.foreach(tag => {
val starttext = s"<$tag>This is text with $tag"
val text = starttext + (if (tag.equals("br")) "" else s"$tag>")
allowedHtmlValidator.validate("path1.path2", text) should equal(None)
@@ -38,7 +36,7 @@ class TextValidatorTest extends UnitSuite with TestEnvironment {
test("That TextValidator does not allow tags outside BasicHtmlTags") {
val illegalTag = "aside"
- AllowedHtmlTags.contains(illegalTag) should be(right = false)
+ props.AllowedHtmlTags.contains(illegalTag) should be(right = false)
val text = s"<$illegalTag>This is text with $illegalTag$illegalTag>"
diff --git a/modules/DefaultOptions.mill b/modules/DefaultOptions.mill
index 0c5e82af35..fffc9018e0 100644
--- a/modules/DefaultOptions.mill
+++ b/modules/DefaultOptions.mill
@@ -10,6 +10,11 @@ trait DefaultOptions extends ScalaModule {
private def scala3: VersionCheckFunc = version => version.startsWith("3.")
private def scala3and2: VersionCheckFunc = version => scala2(version) && scala3(version)
+ extension (opts: Seq[NDLAScalaOption])
+ def filterByVersion(version: String): Seq[String] = opts
+ .filter { o => o.versionCheck(version) }
+ .map(_.name)
+
case class NDLAScalaOption(name: String, versionCheck: VersionCheckFunc = _ => true)
given Conversion[String, NDLAScalaOption] =
@@ -28,6 +33,7 @@ trait DefaultOptions extends ScalaModule {
"-language:higherKinds",
"-language:implicitConversions",
"-Xfatal-warnings",
+ "-deprecation",
"-Xlint:adapted-args" -> scala2,
"-Xlint:constant" -> scala2,
"-Xlint:delayedinit-select" -> scala2,
@@ -57,10 +63,11 @@ trait DefaultOptions extends ScalaModule {
"-Wunused:imports",
"-Wunused:locals",
"-Wunused:params",
- "-Wunused:patvars",
"-Wunused:privates",
- "-Wconf:src=src_managed/.*:silent"
- ).filter(_.versionCheck(scalaVersion())).map(_.name)
+ "-Wconf:src=src_managed/.*:silent",
+ "-Yretain-trees" -> scala3,
+ "-Xmax-inlines:50" -> scala3
+ ).filterByVersion(scalaVersion())
}
def scalacOptionsOnlyRun: T[Seq[String]] = Task {
@@ -68,13 +75,13 @@ trait DefaultOptions extends ScalaModule {
"-Wdead-code" -> scala2,
"-Wvalue-discard",
"-Wnonunit-statement"
- ).filter(_.versionCheck(scalaVersion())).map(_.name)
+ ).filterByVersion(scalaVersion())
}
def testJavaOptions: T[Seq[String]] = Task {
Seq[NDLAScalaOption](
"-XX:+EnableDynamicAgentLoading",
"-Xshare:off"
- ).filter(_.versionCheck(scalaVersion())).map(_.name)
+ ).filterByVersion(scalaVersion())
}
}
diff --git a/modules/versions.mill b/modules/versions.mill
index 720a0ae55f..b548a3d1a3 100644
--- a/modules/versions.mill
+++ b/modules/versions.mill
@@ -3,20 +3,19 @@ package build.modules
import mill._, mill.scalalib._
object SharedDependencies {
- val ScalaVersion = "2.13.16"
+ val ScalaVersion = "3.3.6"
val HikariConnectionPoolV = "6.3.0"
val ScalaLoggingV = "3.9.5"
val ScalaTestV = "3.2.19"
val Log4JV = "2.25.0"
val AwsSdkV = "2.31.64"
- val MockitoV = "1.17.30"
val Elastic4sV = "8.11.5"
val JacksonV = "2.19.1"
val CatsEffectV = "3.6.1"
val FlywayV = "11.10.5"
val PostgresV = "42.7.7"
val Http4sV = "0.23.30"
- val TapirV = "1.11.34"
+ val TapirV = "1.11.41"
val ApiSpecV = "0.11.9"
val SttpV = "3.11.0"
val CirceV = "0.14.14"
@@ -43,7 +42,7 @@ object SharedDependencies {
def testing: Seq[Dep] = Seq(
mvn"org.scalatest::scalatest:$ScalaTestV",
- mvn"org.scalatestplus::mockito-5-10:3.2.18.0",
+ mvn"org.scalatestplus::mockito-5-18:3.2.19.0",
mvn"org.testcontainers:elasticsearch:$TestContainersV",
mvn"org.testcontainers:testcontainers:$TestContainersV",
mvn"org.testcontainers:postgresql:$TestContainersV"
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/ComponentRegistry.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/ComponentRegistry.scala
index dc758f6cfa..57963e7f60 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/ComponentRegistry.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/ComponentRegistry.scala
@@ -71,37 +71,36 @@ class ComponentRegistry(properties: MyNdlaApiProperties)
with LearningPathApiClient
with V16__MigrateResourcePaths
with NdlaClient {
- override val props: MyNdlaApiProperties = properties
+ override lazy val props: MyNdlaApiProperties = properties
+ override lazy val healthController: TapirHealthController = new TapirHealthController
+ override lazy val clock: SystemClock = new SystemClock
+ override lazy val folderController: FolderController = new FolderController
+ override lazy val robotController: RobotController = new RobotController
+ override lazy val feideApiClient: FeideApiClient = new FeideApiClient
+ override lazy val redisClient = new RedisClient(props.RedisHost, props.RedisPort)
+ override lazy val folderRepository: FolderRepository = new FolderRepository
+ override lazy val folderConverterService: FolderConverterService = new FolderConverterService
+ override lazy val folderReadService: FolderReadService = new FolderReadService
+ override lazy val folderWriteService: FolderWriteService = new FolderWriteService
+ override lazy val userRepository: UserRepository = new UserRepository
+ override lazy val robotRepository: RobotRepository = new RobotRepository
+ override lazy val robotService: RobotService = new RobotService
+ override lazy val userService: UserService = new UserService
+ override lazy val userController: UserController = new UserController
+ override lazy val configRepository: ConfigRepository = new ConfigRepository
+ override lazy val configService: ConfigService = new ConfigService
+ override lazy val configController: ConfigController = new ConfigController
+ lazy val statsController: StatsController = new StatsController
+ override lazy val nodebb: NodeBBClient = new NodeBBClient
+ override lazy val searchApiClient: SearchApiClient = new SearchApiClient
+ override lazy val taxonomyApiClient: TaxonomyApiClient = new TaxonomyApiClient
+ override lazy val learningPathApiClient: LearningPathApiClient = new LearningPathApiClient
+ override lazy val ndlaClient: NdlaClient = new NdlaClient
+ override lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
+ lazy val v16__MigrateResourcePaths: V16__MigrateResourcePaths = new V16__MigrateResourcePaths
+ override lazy val DBUtil = new DBUtility
- lazy val healthController: TapirHealthController = new TapirHealthController
- lazy val clock: SystemClock = new SystemClock
- lazy val folderController: FolderController = new FolderController
- lazy val robotController: RobotController = new RobotController
- lazy val feideApiClient: FeideApiClient = new FeideApiClient
- lazy val redisClient = new RedisClient(props.RedisHost, props.RedisPort)
- lazy val folderRepository: FolderRepository = new FolderRepository
- lazy val folderConverterService: FolderConverterService = new FolderConverterService
- lazy val folderReadService: FolderReadService = new FolderReadService
- lazy val folderWriteService: FolderWriteService = new FolderWriteService
- lazy val userRepository: UserRepository = new UserRepository
- lazy val robotRepository: RobotRepository = new RobotRepository
- lazy val robotService: RobotService = new RobotService
- lazy val userService: UserService = new UserService
- lazy val userController: UserController = new UserController
- lazy val configRepository: ConfigRepository = new ConfigRepository
- lazy val configService: ConfigService = new ConfigService
- lazy val configController: ConfigController = new ConfigController
- lazy val statsController: StatsController = new StatsController
- lazy val nodebb: NodeBBClient = new NodeBBClient
- lazy val searchApiClient: SearchApiClient = new SearchApiClient
- lazy val taxonomyApiClient: TaxonomyApiClient = new TaxonomyApiClient
- lazy val learningPathApiClient: LearningPathApiClient = new LearningPathApiClient
- lazy val ndlaClient: NdlaClient = new NdlaClient
- lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
- lazy val v16__MigrateResourcePaths: V16__MigrateResourcePaths = new V16__MigrateResourcePaths
- lazy val DBUtil = new DBUtility
-
- override val migrator: DBMigrator = DBMigrator(v16__MigrateResourcePaths)
+ override lazy val migrator: DBMigrator = DBMigrator(v16__MigrateResourcePaths)
override lazy val dataSource: HikariDataSource = DataSource.getHikariDataSource
val swagger = new SwaggerController(
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/MyNdlaApiProperties.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/MyNdlaApiProperties.scala
index 7306c2c999..8da1b21471 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/MyNdlaApiProperties.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/MyNdlaApiProperties.scala
@@ -15,7 +15,7 @@ import no.ndla.network.AuthUser
import scala.util.Properties.*
trait Props extends HasBaseProps with HasDatabaseProps {
- val props: MyNdlaApiProperties
+ lazy val props: MyNdlaApiProperties
}
class MyNdlaApiProperties extends BaseProps with DatabaseProps {
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/ConfigController.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/ConfigController.scala
index 3cd3d13610..b22a120fbf 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/ConfigController.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/ConfigController.scala
@@ -25,7 +25,7 @@ import no.ndla.network.tapir.auth.Permission.LEARNINGPATH_API_ADMIN
trait ConfigController {
this: ErrorHandling & ConfigService & TapirController =>
- val configController: ConfigController
+ lazy val configController: ConfigController
class ConfigController extends TapirController {
override val serviceName: String = "config"
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/FolderController.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/FolderController.scala
index 92c0113702..411ffe3ec5 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/FolderController.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/FolderController.scala
@@ -40,7 +40,7 @@ import java.util.UUID
trait FolderController {
this: FolderReadService & FolderWriteService & ErrorHandling & TapirController =>
- val folderController: FolderController
+ lazy val folderController: FolderController
class FolderController extends TapirController {
override val serviceName: String = "folders"
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/RobotController.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/RobotController.scala
index 2ac506998e..afebac5a4e 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/RobotController.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/RobotController.scala
@@ -23,7 +23,7 @@ import java.util.UUID
trait RobotController {
this: ErrorHandling & TapirController & RobotService =>
- val robotController: RobotController
+ lazy val robotController: RobotController
class RobotController extends TapirController {
override val serviceName: String = "robots"
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/UserController.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/UserController.scala
index 13c5453a44..360b7382a0 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/UserController.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/controller/UserController.scala
@@ -23,7 +23,7 @@ import no.ndla.myndlaapi.service.{FolderReadService, FolderWriteService, UserSer
trait UserController {
this: ErrorHandling & UserService & MyNDLAAuthHelpers & FolderWriteService & FolderReadService & TapirController =>
- val userController: UserController
+ lazy val userController: UserController
class UserController extends TapirController {
override val serviceName: String = "users"
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/db/migrationwithdependencies/V16__MigrateResourcePaths.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/db/migrationwithdependencies/V16__MigrateResourcePaths.scala
index 74f6ab8ad4..069aa69db9 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/db/migrationwithdependencies/V16__MigrateResourcePaths.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/db/migrationwithdependencies/V16__MigrateResourcePaths.scala
@@ -20,7 +20,7 @@ trait V16__MigrateResourcePaths {
class V16__MigrateResourcePaths extends TableMigration[ResourceRow] {
override val tableName: String = "resources"
- override val whereClause: scalikejdbc.SQLSyntax = sqls"path is not null"
+ override lazy val whereClause: scalikejdbc.SQLSyntax = sqls"path is not null"
override val chunkSize: Int = 1000
override def extractRowData(rs: WrappedResultSet): ResourceRow = ResourceRow(
UUID.fromString(rs.string("id")),
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/LearningPathApiClient.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/LearningPathApiClient.scala
index c6a0a3476e..acb5fbe6cf 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/LearningPathApiClient.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/LearningPathApiClient.scala
@@ -21,12 +21,11 @@ import scala.util.Try
trait LearningPathApiClient {
this: NdlaClient & Props =>
- val learningPathApiClient: LearningPathApiClient
+ lazy val learningPathApiClient: LearningPathApiClient
class LearningPathApiClient extends StrictLogging {
- import props.LearningpathApiUrl
private val learningPathTimeout = 20.seconds
- def getStats: Try[LearningPathStatsDTO] = get[LearningPathStatsDTO](s"$LearningpathApiUrl/intern/stats")
+ def getStats: Try[LearningPathStatsDTO] = get[LearningPathStatsDTO](s"${props.LearningpathApiUrl}/intern/stats")
private def get[A: Decoder](url: String, params: (String, String)*): Try[A] = {
val request = quickRequest.get(uri"$url".withParams(params*)).readTimeout(learningPathTimeout)
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/SearchApiClient.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/SearchApiClient.scala
index c5881f366f..aa5f2feb8b 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/SearchApiClient.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/SearchApiClient.scala
@@ -21,7 +21,7 @@ import scala.util.{Failure, Success, Try}
trait SearchApiClient {
this: NdlaClient & Props =>
- val searchApiClient: SearchApiClient
+ lazy val searchApiClient: SearchApiClient
class SearchApiClient extends StrictLogging {
private val internEndpoint = s"${props.SearchApiUrl}/intern"
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/TaxonomyApiClient.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/TaxonomyApiClient.scala
index c540ec8298..acd085e7e9 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/TaxonomyApiClient.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/TaxonomyApiClient.scala
@@ -20,7 +20,7 @@ import scala.util.{Success, Try}
trait TaxonomyApiClient {
this: NdlaClient & Props =>
- val taxonomyApiClient: TaxonomyApiClient
+ lazy val taxonomyApiClient: TaxonomyApiClient
class TaxonomyApiClient extends StrictLogging {
private val resolveEndpoint = s"${props.TaxonomyUrl}/v1/url/resolve"
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/nodebb/NodeBBClient.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/nodebb/NodeBBClient.scala
index f126ea3c95..dc816a5668 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/nodebb/NodeBBClient.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/integration/nodebb/NodeBBClient.scala
@@ -12,7 +12,7 @@ import cats.implicits.catsSyntaxOptionId
import com.typesafe.scalalogging.StrictLogging
import io.circe.generic.auto.*
import io.circe.parser.parse
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.myndlaapi.Props
import no.ndla.network.model.FeideAccessToken
import sttp.client3.Response
@@ -20,11 +20,11 @@ import sttp.client3.quick.*
import sttp.model.headers.CookieWithMeta
import scala.annotation.tailrec
-import scala.util.{Failure, Success, Try}
+import scala.util.{Failure, Success, Try, boundary}
trait NodeBBClient {
this: Props =>
- val nodebb: NodeBBClient
+ lazy val nodebb: NodeBBClient
class NodeBBClient extends StrictLogging {
private val baseUrl: String = props.nodeBBUrl
@@ -32,7 +32,7 @@ trait NodeBBClient {
case class NodeBBSession(csrfToken: String, cookies: Seq[CookieWithMeta])
- private def getCSRFToken(feideToken: FeideAccessToken): Try[NodeBBSession] = {
+ private def getCSRFToken(feideToken: FeideAccessToken): Try[NodeBBSession] = permitTry {
val request = quickRequest
.get(uri"$baseUrl/api/config")
.header("FeideAuthorization", s"Bearer $feideToken")
@@ -65,19 +65,21 @@ trait NodeBBClient {
}
}
- def getUserId(feideToken: FeideAccessToken): Try[Option[Long]] = {
- val request = quickRequest
- .get(uri"$baseUrl/api/config")
- .header("FeideAuthorization", s"Bearer $feideToken")
- val resp = doReq(request).?
+ def getUserId(feideToken: FeideAccessToken): Try[Option[Long]] = boundary {
+ permitTry {
+ val request = quickRequest
+ .get(uri"$baseUrl/api/config")
+ .header("FeideAuthorization", s"Bearer $feideToken")
+ val resp = doReq(request).?
- if (resp.code.code == 403) return Success(None)
+ if (resp.code.code == 403) boundary.break(Success(None))
- val body = resp.body
- parse(body)
- .flatMap(_.as[UserSelf])
- .toTry
- .map(_.uid.some)
+ val body = resp.body
+ parse(body)
+ .flatMap(_.as[UserSelf])
+ .toTry
+ .map(_.uid.some)
+ }
}
def deleteUser(userId: Option[Long], feideToken: FeideAccessToken): Try[Unit] = {
@@ -91,19 +93,20 @@ trait NodeBBClient {
}
}
- def deleteUserWithCSRF(userId: Long, feideToken: FeideAccessToken, nodebbSession: NodeBBSession): Try[Unit] = {
- val request = quickRequest
- .delete(uri"$baseUrl/api/v3/users/$userId/account")
- .header("FeideAuthorization", s"Bearer $feideToken")
- .header("X-CSRF-Token", nodebbSession.csrfToken)
- .cookies(nodebbSession.cookies)
- val resp = doReq(request).?
- if (resp.isSuccess) Success(())
- else {
- val msg = s"Failed to delete nodebb user with id $userId, Got code: ${resp.code}, with body:\n\n${resp.body}"
- logger.error(msg)
- Failure(new Exception(msg))
+ def deleteUserWithCSRF(userId: Long, feideToken: FeideAccessToken, nodebbSession: NodeBBSession): Try[Unit] =
+ permitTry {
+ val request = quickRequest
+ .delete(uri"$baseUrl/api/v3/users/$userId/account")
+ .header("FeideAuthorization", s"Bearer $feideToken")
+ .header("X-CSRF-Token", nodebbSession.csrfToken)
+ .cookies(nodebbSession.cookies)
+ val resp = doReq(request).?
+ if (resp.isSuccess) Success(())
+ else {
+ val msg = s"Failed to delete nodebb user with id $userId, Got code: ${resp.code}, with body:\n\n${resp.body}"
+ logger.error(msg)
+ Failure(new Exception(msg))
+ }
}
- }
}
}
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/api/FolderDTO.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/api/FolderDTO.scala
index d0c775352a..750e8a1508 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/api/FolderDTO.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/api/FolderDTO.scala
@@ -15,6 +15,7 @@ import io.circe.{Decoder, Encoder}
import no.ndla.common.model.NDLADate
import no.ndla.common.model.domain.ResourceType
import no.ndla.myndlaapi.model.domain.{CopyableFolder, CopyableResource}
+import sttp.tapir.Schema
import sttp.tapir.Schema.annotations.description
import java.util.UUID
@@ -48,6 +49,8 @@ case class FolderDTO(
object FolderDTO {
implicit val folderEncoder: Encoder[FolderDTO] = deriveEncoder
implicit val folderDecoder: Decoder[FolderDTO] = deriveDecoder
+ import sttp.tapir.generic.auto.*
+ implicit def schema: Schema[FolderDTO] = Schema.derivedSchema
implicit val folderDataEncoder: Encoder[FolderDataDTO] = Encoder.instance { case folder: FolderDTO => folder.asJson }
implicit val folderDataDecoder: Decoder[FolderDataDTO] = Decoder[FolderDTO].widen
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/DBMyNDLAUser.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/DBMyNDLAUser.scala
index 78d14ed09e..79761392c3 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/DBMyNDLAUser.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/DBMyNDLAUser.scala
@@ -17,11 +17,9 @@ object DBMyNDLAUser extends SQLSyntaxSupport[MyNDLAUser] {
override val tableName = "my_ndla_users"
def fromResultSet(lp: SyntaxProvider[MyNDLAUser])(rs: WrappedResultSet): MyNDLAUser =
- fromResultSet((s: String) => lp.resultName.c(s))(rs)
+ fromResultSetWithWrapper((s: String) => lp.resultName.c(s))(rs)
- def fromResultSet(rs: WrappedResultSet): MyNDLAUser = fromResultSet((s: String) => s)(rs)
-
- def fromResultSet(colNameWrapper: String => String)(rs: WrappedResultSet): MyNDLAUser = {
+ private def fromResultSetWithWrapper(colNameWrapper: String => String)(rs: WrappedResultSet): MyNDLAUser = {
val jsonString = rs.string(colNameWrapper("document"))
val metaData = CirceUtil.unsafeParseAs[MyNDLAUserDocument](jsonString)
val id = rs.long(colNameWrapper("id"))
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/Resource.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/Resource.scala
index 69d4e2be24..4585d9009d 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/Resource.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/Resource.scala
@@ -12,7 +12,7 @@ import cats.implicits.*
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import no.ndla.common.CirceUtil
-import no.ndla.common.implicits.OptionImplicit
+import no.ndla.common.implicits.*
import no.ndla.common.model.NDLADate
import no.ndla.common.model.domain.ResourceType
import no.ndla.network.model.FeideID
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/RobotDefinition.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/RobotDefinition.scala
index 1181f826ce..f644471641 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/RobotDefinition.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/RobotDefinition.scala
@@ -12,7 +12,7 @@ import io.circe.{Decoder, Encoder}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import no.ndla.common.CirceUtil
import no.ndla.common.errors.{AccessDeniedException, NotFoundException}
-import no.ndla.common.implicits.OptionImplicit
+import no.ndla.common.implicits.*
import no.ndla.common.model.NDLADate
import no.ndla.myndlaapi.model.api.robot.RobotConfigurationDTO
import no.ndla.network.model.FeideID
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/SavedSharedFolder.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/SavedSharedFolder.scala
index ecfe2e2840..e4d5348271 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/SavedSharedFolder.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/model/domain/SavedSharedFolder.scala
@@ -28,10 +28,9 @@ object SavedSharedFolder extends SQLSyntaxSupport[SavedSharedFolder] {
override val tableName = "saved_shared_folder"
- def fromResultSet(sp: SyntaxProvider[SavedSharedFolder])(rs: WrappedResultSet): Try[SavedSharedFolder] =
+ def fromResultSet(sp: SyntaxProvider[SavedSharedFolder], rs: WrappedResultSet): Try[SavedSharedFolder] = {
fromResultSet((s: String) => sp.resultName.c(s))(rs)
-
- def fromResultSet(rs: WrappedResultSet): Try[SavedSharedFolder] = fromResultSet((s: String) => s)(rs)
+ }
def fromResultSet(colNameWrapper: String => String)(rs: WrappedResultSet): Try[SavedSharedFolder] = {
import no.ndla.myndlaapi.uuidBinder
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/ConfigRepository.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/ConfigRepository.scala
index 81743d2943..4b81b622c3 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/ConfigRepository.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/ConfigRepository.scala
@@ -19,7 +19,7 @@ import sqls.count
import scala.util.{Success, Try}
trait ConfigRepository {
- val configRepository: ConfigRepository
+ lazy val configRepository: ConfigRepository
import ConfigMeta.*
@@ -51,12 +51,12 @@ trait ConfigRepository {
if (updatedCount != 1) {
logger.info(s"No existing value for ${config.key}, inserting the value.")
- withSQL {
+ val _ = withSQL {
insertInto(ConfigMeta).namedValues(
ConfigMeta.column.c("configkey") -> config.key.entryName,
ConfigMeta.column.c("value") -> config
)
- }.update(): Unit
+ }.update()
Success(config)
} else {
logger.info(s"Value for ${config.key} updated.")
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/FolderRepository.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/FolderRepository.scala
index ec19ec2e66..3ff5caf344 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/FolderRepository.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/FolderRepository.scala
@@ -39,7 +39,7 @@ import scala.util.{Failure, Success, Try}
trait FolderRepository {
this: Clock & DBUtility =>
- val folderRepository: FolderRepository
+ lazy val folderRepository: FolderRepository
class FolderRepository extends StrictLogging {
def getSession(readOnly: Boolean): DBSession =
@@ -60,7 +60,7 @@ trait FolderRepository {
val shared = if (folderData.status == FolderStatus.SHARED) Some(created) else None
val column = Folder.column.c _
- withSQL {
+ val _ = withSQL {
insert
.into(Folder)
.namedValues(
@@ -75,7 +75,7 @@ trait FolderRepository {
column("shared") -> shared,
column("description") -> folderData.description
)
- }.update(): Unit
+ }.update()
logger.info(s"Inserted new folder with id: $newId")
folderData.toFullFolder(
@@ -100,7 +100,7 @@ trait FolderRepository {
val newId = UUID.randomUUID()
val column = Resource.column.c _
- withSQL {
+ val _ = withSQL {
insert
.into(Resource)
.namedValues(
@@ -111,7 +111,7 @@ trait FolderRepository {
column("created") -> created,
column("document") -> DBUtil.asJsonb(document)
)
- }.update(): Unit
+ }.update()
logger.info(s"Inserted new resource with id: $newId")
document.toFullResource(newId, path, resourceType, feideId, created, None)
@@ -123,7 +123,7 @@ trait FolderRepository {
rank: Int,
favoritedDate: NDLADate
)(implicit session: DBSession = AutoSession): Try[FolderResource] = Try {
- withSQL {
+ val _ = withSQL {
insert
.into(FolderResource)
.namedValues(
@@ -132,7 +132,7 @@ trait FolderRepository {
FolderResource.column.rank -> rank,
FolderResource.column.favoritedDate -> favoritedDate
)
- }.update(): Unit
+ }.update()
logger.info(s"Inserted new folder-resource connection with folder id $folderId and resource id $resourceId")
FolderResource(folderId = folderId, resourceId = resourceId, rank = rank, favoritedDate = favoritedDate)
@@ -527,7 +527,7 @@ trait FolderRepository {
.toManies(
rs => Resource.fromResultSetSyntaxProviderWithConnection(r, fr)(rs).sequence,
rs => Try(DBMyNDLAUser.fromResultSet(u)(rs)).toOption,
- rs => Try(SavedSharedFolder.fromResultSet(sfu)(rs)).toOption
+ rs => Try(SavedSharedFolder.fromResultSet(sfu, rs)).toOption
)
.map((folder, resources, user, savedSharedFolder) => {
toCompileFolder(folder, resources.toList, user.toList, savedSharedFolder.toList)
@@ -762,9 +762,7 @@ trait FolderRepository {
)
}
- insertSql
- .batch(batchParams*)
- .apply(): Unit
+ val _ = insertSql.batch(batchParams*).apply()
}
}
@@ -808,9 +806,9 @@ trait FolderRepository {
}
batchParams.map { params =>
- insertSql
+ val _ = insertSql
.batch(params*)
- .apply(): Unit
+ .apply()
}
}.flatten
}
@@ -836,9 +834,7 @@ trait FolderRepository {
)
}
- insertSql
- .batch(batchParams*)
- .apply(): Unit
+ val _ = insertSql.batch(batchParams*).apply()
}
def numberOfResources()(implicit session: DBSession = ReadOnlyAutoSession): Try[Option[Long]] = Try {
@@ -868,7 +864,7 @@ trait FolderRepository {
def createFolderUserConnection(folderId: UUID, feideId: FeideID, rank: Int)(implicit
session: DBSession = AutoSession
): Try[SavedSharedFolder] = Try {
- withSQL {
+ val _ = withSQL {
insert
.into(SavedSharedFolder)
.namedValues(
@@ -876,7 +872,7 @@ trait FolderRepository {
SavedSharedFolder.column.feideId -> feideId,
SavedSharedFolder.column.rank -> rank
)
- }.update(): Unit
+ }.update()
logger.info(s"Inserted new sharedFolder-user connection with folder id $folderId and feide id $feideId")
SavedSharedFolder(folderId = folderId, feideId = feideId, rank = rank)
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/RobotRepository.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/RobotRepository.scala
index 317f196ef6..2d0eb0bda6 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/RobotRepository.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/RobotRepository.scala
@@ -23,7 +23,7 @@ import scala.util.{Failure, Success, Try}
trait RobotRepository {
this: Clock & DBUtility =>
- val robotRepository: RobotRepository
+ lazy val robotRepository: RobotRepository
class RobotRepository extends StrictLogging {
def getSession(readOnly: Boolean): DBSession =
@@ -36,7 +36,7 @@ trait RobotRepository {
def updateRobotDefinition(robot: RobotDefinition)(implicit session: DBSession): Try[Unit] = Try {
val column = RobotDefinition.column.c _
- withSQL {
+ val _ = withSQL {
update(RobotDefinition)
.set(
column("status") -> robot.status.entryName,
@@ -47,7 +47,7 @@ trait RobotRepository {
.where
.eq(column("id"), robot.id)
}
- .update(): Unit
+ .update()
logger.info(s"Updted robot definition with ID: ${robot.id}")
}
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/UserRepository.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/UserRepository.scala
index 9f19bcc5da..0214eaa553 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/UserRepository.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/repository/UserRepository.scala
@@ -22,7 +22,7 @@ import scala.util.{Failure, Success, Try}
trait UserRepository {
this: DBUtility =>
- val userRepository: UserRepository
+ lazy val userRepository: UserRepository
class UserRepository extends StrictLogging {
@@ -148,11 +148,11 @@ trait UserRepository {
}
def deleteAllUsers(implicit session: DBSession): Try[Unit] = Try {
- sql"delete from ${DBMyNDLAUser.table}".execute(): Unit
+ val _ = sql"delete from ${DBMyNDLAUser.table}".execute()
}
def resetSequences(implicit session: DBSession): Try[Unit] = Try {
- sql"alter sequence my_ndla_users_id_seq restart with 1".execute(): Unit
+ val _ = sql"alter sequence my_ndla_users_id_seq restart with 1".execute()
}
def userWithFeideId(feideId: FeideID)(implicit session: DBSession = ReadOnlyAutoSession): Try[Option[MyNDLAUser]] =
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/ConfigService.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/ConfigService.scala
index a20b22d024..d5a61dd59d 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/ConfigService.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/ConfigService.scala
@@ -22,7 +22,7 @@ import scala.util.{Failure, Success, Try}
trait ConfigService {
this: ConfigRepository & Clock =>
- val configService: ConfigService
+ lazy val configService: ConfigService
class ConfigService {
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderConverterService.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderConverterService.scala
index de34e8ffa0..22f2768728 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderConverterService.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderConverterService.scala
@@ -12,7 +12,7 @@ import cats.implicits.*
import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.{Clock, model}
import no.ndla.common.errors.ValidationException
-import no.ndla.common.implicits.{OptionImplicit, TryQuestionMark}
+import no.ndla.common.implicits.*
import no.ndla.common.model.api.myndla.UpdatedMyNDLAUserDTO
import no.ndla.common.model.domain.myndla
import no.ndla.common.model.domain.myndla.{
@@ -34,7 +34,7 @@ import scala.util.{Failure, Success, Try}
trait FolderConverterService {
this: Clock & NodeBBClient =>
- val folderConverterService: FolderConverterService
+ lazy val folderConverterService: FolderConverterService
class FolderConverterService extends StrictLogging {
def toApiFolder(
@@ -273,7 +273,7 @@ trait FolderConverterService {
updatedUser: UpdatedMyNDLAUserDTO,
updaterToken: Option[TokenUser],
feideToken: Option[FeideAccessToken]
- ): Try[DomainMyNDLAUser] = {
+ ): Try[DomainMyNDLAUser] = permitTry {
val favoriteSubjects = updatedUser.favoriteSubjects.getOrElse(domainUserData.favoriteSubjects)
val arenaEnabled = {
if (updaterToken.hasPermission(LEARNINGPATH_API_ADMIN))
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderReadService.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderReadService.scala
index e8dd9fb374..3181af5ce0 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderReadService.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderReadService.scala
@@ -11,7 +11,7 @@ package no.ndla.myndlaapi.service
import cats.implicits.*
import no.ndla.common.Clock
import no.ndla.common.errors.NotFoundException
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.common.model.api.SingleResourceStatsDTO
import no.ndla.common.model.api.myndla.MyNDLAUserDTO
import no.ndla.common.model.domain.TryMaybe.*
@@ -35,7 +35,7 @@ trait FolderReadService {
this: FolderConverterService & FolderRepository & UserRepository & FeideApiClient & Clock & ConfigService &
UserService & DBUtility & LearningPathApiClient & RobotRepository =>
- val folderReadService: FolderReadService
+ lazy val folderReadService: FolderReadService
class FolderReadService {
private def getSubFoldersAndResources(
@@ -345,7 +345,7 @@ trait FolderReadService {
def getFavouriteStatsForResource(
resourceIds: List[String],
resourceTypes: List[String]
- ): Try[List[SingleResourceStatsDTO]] = {
+ ): Try[List[SingleResourceStatsDTO]] = permitTry {
implicit val session: DBSession = folderRepository.getSession(true)
val result =
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderWriteService.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderWriteService.scala
index 750e256a8d..655c68309b 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderWriteService.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/FolderWriteService.scala
@@ -56,7 +56,7 @@ trait FolderWriteService {
this: FolderReadService & Clock & FeideApiClient & FolderRepository & FolderConverterService & UserRepository &
ConfigService & UserService & SearchApiClient & DBUtility =>
- val folderWriteService: FolderWriteService
+ lazy val folderWriteService: FolderWriteService
class FolderWriteService extends StrictLogging {
val MaxFolderDepth = 5L
@@ -323,9 +323,9 @@ trait FolderWriteService {
session: DBSession
): Try[UUID] = {
folderRepository.folderResourceConnectionCount(resourceId) match {
- case Failure(exception) => Failure(exception)
- case Success(count) if count == 1 => folderRepository.deleteResource(resourceId)
- case Success(_) => folderRepository.deleteFolderResourceConnection(folderId, resourceId)
+ case Failure(exception) => Failure(exception)
+ case Success(count) if count == 1L => folderRepository.deleteResource(resourceId)
+ case Success(_) => folderRepository.deleteFolderResourceConnection(folderId, resourceId)
}
}
@@ -466,7 +466,7 @@ trait FolderWriteService {
folderSortObject: domain.FolderSortObject,
sortRequest: api.FolderSortRequestDTO,
feideAccessToken: Option[FeideAccessToken]
- ): Try[Unit] = {
+ ): Try[Unit] = permitTry {
implicit val session: DBSession = folderRepository.getSession(readOnly = false)
val feideId = feideApiClient.getFeideID(feideAccessToken).?
canWriteDuringMyNDLAWriteRestrictionsOrAccessDenied(feideId, feideAccessToken).??
@@ -577,8 +577,7 @@ trait FolderWriteService {
isCloning: Boolean
)(implicit
session: DBSession
- ): Try[domain.Folder] = {
-
+ ): Try[domain.Folder] = permitTry {
val parentId = getMaybeParentId(newFolder.parentId).?
val maybeSiblings = getFolderWithDirectChildren(parentId, feideId).?
val nextRank = getNextRank(maybeSiblings.childrenFolders)
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/RobotService.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/RobotService.scala
index f68faef4b1..0ea8c090d4 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/RobotService.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/RobotService.scala
@@ -10,7 +10,7 @@ package no.ndla.myndlaapi.service
import no.ndla.common.Clock
import no.ndla.common.errors.NotFoundException
-import no.ndla.common.implicits.OptionImplicit
+import no.ndla.common.implicits.*
import no.ndla.database.DBUtility
import no.ndla.myndlaapi.model.api.robot.{CreateRobotDefinitionDTO, ListOfRobotDefinitionsDTO, RobotDefinitionDTO}
import no.ndla.myndlaapi.model.domain.{RobotConfiguration, RobotDefinition, RobotStatus}
@@ -24,7 +24,7 @@ import scala.util.Try
trait RobotService {
this: RobotRepository & DBUtility & Clock & FeideApiClient & FolderWriteService =>
- val robotService: RobotService
+ lazy val robotService: RobotService
class RobotService {
diff --git a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/UserService.scala b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/UserService.scala
index 48719a5cbb..c31eeb1695 100644
--- a/myndla-api/src/main/scala/no/ndla/myndlaapi/service/UserService.scala
+++ b/myndla-api/src/main/scala/no/ndla/myndlaapi/service/UserService.scala
@@ -10,7 +10,7 @@ package no.ndla.myndlaapi.service
import no.ndla.common.Clock
import no.ndla.common.errors.{AccessDeniedException, NotFoundException}
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.common.model.api.myndla
import no.ndla.common.model.api.myndla.UpdatedMyNDLAUserDTO
import no.ndla.common.model.domain.myndla.{MyNDLAGroup, MyNDLAUser, MyNDLAUserDocument, UserRole}
@@ -27,7 +27,7 @@ trait UserService {
this: FeideApiClient & FolderConverterService & ConfigService & UserRepository & Clock & FolderWriteService &
NodeBBClient & FolderRepository & DBUtility =>
- val userService: UserService
+ lazy val userService: UserService
class UserService {
def getMyNdlaUserDataDomain(
@@ -170,7 +170,7 @@ trait UserService {
userData: MyNDLAUser
)(implicit
session: DBSession
- ): Try[MyNDLAUser] = {
+ ): Try[MyNDLAUser] = permitTry {
val feideUser = feideApiClient.getFeideExtendedUser(feideAccessToken).?
val organization = feideApiClient.getOrganization(feideAccessToken).?
val feideGroups = feideApiClient.getFeideGroups(feideAccessToken).?
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/TestEnvironment.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/TestEnvironment.scala
index b0ea257992..e3eda2603a 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/TestEnvironment.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/TestEnvironment.scala
@@ -68,34 +68,34 @@ trait TestEnvironment
with SearchApiClient
with LearningPathApiClient
with NdlaClient {
- lazy val props = new MyNdlaApiProperties
- lazy val clock: SystemClock = mock[SystemClock]
- val dataSource: HikariDataSource = mock[HikariDataSource]
- val migrator: DBMigrator = mock[DBMigrator]
- val folderRepository: FolderRepository = mock[FolderRepository]
- val robotRepository: RobotRepository = mock[RobotRepository]
- val folderReadService: FolderReadService = mock[FolderReadService]
- val folderWriteService: FolderWriteService = mock[FolderWriteService]
- val folderConverterService: FolderConverterService = mock[FolderConverterService]
- val robotService: RobotService = mock[RobotService]
- val userService: UserService = mock[UserService]
- val configService: ConfigService = mock[ConfigService]
- val userRepository: UserRepository = mock[UserRepository]
- val configRepository: ConfigRepository = mock[ConfigRepository]
- val feideApiClient: FeideApiClient = mock[FeideApiClient]
- val configController: ConfigController = mock[ConfigController]
- val robotController: RobotController = mock[RobotController]
- val redisClient: RedisClient = mock[RedisClient]
- val folderController: FolderController = mock[FolderController]
- val userController: UserController = mock[UserController]
- val statsController: StatsController = mock[StatsController]
- val healthController: TapirHealthController = mock[TapirHealthController]
- val nodebb: NodeBBClient = mock[NodeBBClient]
- val searchApiClient: SearchApiClient = mock[SearchApiClient]
- val learningPathApiClient: LearningPathApiClient = mock[LearningPathApiClient]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val DBUtil: DBUtility = mock[DBUtility]
+ override lazy val props = new MyNdlaApiProperties
+ override lazy val clock: SystemClock = mock[SystemClock]
+ override lazy val dataSource: HikariDataSource = mock[HikariDataSource]
+ override lazy val migrator: DBMigrator = mock[DBMigrator]
+ override lazy val folderRepository: FolderRepository = mock[FolderRepository]
+ override lazy val robotRepository: RobotRepository = mock[RobotRepository]
+ override lazy val folderReadService: FolderReadService = mock[FolderReadService]
+ override lazy val folderWriteService: FolderWriteService = mock[FolderWriteService]
+ override lazy val folderConverterService: FolderConverterService = mock[FolderConverterService]
+ override lazy val robotService: RobotService = mock[RobotService]
+ override lazy val userService: UserService = mock[UserService]
+ override lazy val configService: ConfigService = mock[ConfigService]
+ override lazy val userRepository: UserRepository = mock[UserRepository]
+ override lazy val configRepository: ConfigRepository = mock[ConfigRepository]
+ override lazy val feideApiClient: FeideApiClient = mock[FeideApiClient]
+ override lazy val configController: ConfigController = mock[ConfigController]
+ override lazy val robotController: RobotController = mock[RobotController]
+ override lazy val redisClient: RedisClient = mock[RedisClient]
+ override lazy val folderController: FolderController = mock[FolderController]
+ override lazy val userController: UserController = mock[UserController]
+ val statsController: StatsController = mock[StatsController]
+ override lazy val healthController: TapirHealthController = mock[TapirHealthController]
+ override lazy val nodebb: NodeBBClient = mock[NodeBBClient]
+ override lazy val searchApiClient: SearchApiClient = mock[SearchApiClient]
+ override lazy val learningPathApiClient: LearningPathApiClient = mock[LearningPathApiClient]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val DBUtil: DBUtility = mock[DBUtility]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/ConfigRepositoryTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/ConfigRepositoryTest.scala
index 1beb5daae4..c1b6618629 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/ConfigRepositoryTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/ConfigRepositoryTest.scala
@@ -18,9 +18,9 @@ import scalikejdbc.*
import scala.util.Success
class ConfigRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with TestEnvironment {
- override val schemaName: String = "myndlaapi_test"
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator = new DBMigrator
+ override val schemaName: String = "myndlaapi_test"
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator = new DBMigrator
var repository: ConfigRepository = _
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/FolderRepositoryTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/FolderRepositoryTest.scala
index 0e7bd00ab9..eaad6e0236 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/FolderRepositoryTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/FolderRepositoryTest.scala
@@ -25,11 +25,11 @@ import java.util.UUID
import scala.util.{Success, Try}
class FolderRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with TestEnvironment {
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator: DBMigrator = new DBMigrator
- var repository: FolderRepository = _
- override val userRepository: UserRepository = new UserRepository
- override val DBUtil: DBUtility = new DBUtility
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator: DBMigrator = new DBMigrator
+ var repository: FolderRepository = _
+ override lazy val userRepository: UserRepository = new UserRepository
+ override lazy val DBUtil: DBUtility = new DBUtility
def emptyTestDatabase: Boolean = {
DB autoCommit (implicit session => {
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/RobotRepositoryTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/RobotRepositoryTest.scala
index 1aef7d1128..b24de62fc6 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/RobotRepositoryTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/repository/RobotRepositoryTest.scala
@@ -21,10 +21,10 @@ import java.util.UUID
import scala.util.{Success, Try}
class RobotRepositoryTest extends DatabaseIntegrationSuite with UnitSuite with TestEnvironment {
- override val dataSource: HikariDataSource = testDataSource.get
- override val migrator: DBMigrator = new DBMigrator
- var repository: RobotRepository = _
- override val DBUtil: DBUtility = new DBUtility
+ override lazy val dataSource: HikariDataSource = testDataSource.get
+ override lazy val migrator: DBMigrator = new DBMigrator
+ var repository: RobotRepository = _
+ override lazy val DBUtil: DBUtility = new DBUtility
def emptyTestDatabase: Boolean = {
DB autoCommit (implicit session => {
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/ConfigServiceTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/ConfigServiceTest.scala
index 35d44d51c2..8e55629878 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/ConfigServiceTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/ConfigServiceTest.scala
@@ -44,7 +44,7 @@ class ConfigServiceTest extends UnitTestSuite with TestEnvironment {
ConfigKey.LearningpathWriteRestricted,
ConfigMetaValueDTO(true),
TokenUser("Kari", Set(LEARNINGPATH_API_PUBLISH), None)
- )
+ ): @unchecked
ex.isInstanceOf[AccessDeniedException] should be(true)
}
@@ -55,7 +55,7 @@ class ConfigServiceTest extends UnitTestSuite with TestEnvironment {
ConfigKey.LearningpathWriteRestricted,
ConfigMetaValueDTO(true),
TokenUser("Kari", Set(LEARNINGPATH_API_ADMIN), None)
- )
+ ): @unchecked
}
test("That validation fails if IsWriteRestricted is not a boolean") {
@@ -65,7 +65,7 @@ class ConfigServiceTest extends UnitTestSuite with TestEnvironment {
ConfigKey.LearningpathWriteRestricted,
ConfigMetaValueDTO(List("123")),
TokenUser("Kari", Set(LEARNINGPATH_API_ADMIN), None)
- )
+ ): @unchecked
ex.isInstanceOf[ValidationException] should be(true)
}
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderConverterServiceTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderConverterServiceTest.scala
index d735ab6fe6..00cd7bc624 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderConverterServiceTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderConverterServiceTest.scala
@@ -236,7 +236,7 @@ class FolderConverterServiceTest extends UnitTestSuite with TestEnvironment {
List(api.BreadcrumbDTO(id = mainFolderUUID, name = "mainFolder")),
None,
true
- )
+ ): @unchecked
result should be(expected)
}
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderReadServiceTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderReadServiceTest.scala
index 87cead3e53..99dda1ce6b 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderReadServiceTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderReadServiceTest.scala
@@ -29,8 +29,8 @@ import scala.util.{Failure, Success, Try}
class FolderReadServiceTest extends UnitTestSuite with TestEnvironment {
- val service = new FolderReadService
- override val folderConverterService: FolderConverterService = org.mockito.Mockito.spy(new FolderConverterService)
+ val service = new FolderReadService
+ override lazy val folderConverterService: FolderConverterService = org.mockito.Mockito.spy(new FolderConverterService)
override def beforeEach(): Unit = {
super.beforeEach()
@@ -40,7 +40,7 @@ class FolderReadServiceTest extends UnitTestSuite with TestEnvironment {
doAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Nothing]](0)
func(mock[DBSession])
- }).when(DBUtil).rollbackOnFailure(any)
+ }).when(DBUtil).rollbackOnFailure(any())
}
test("That getSingleFolder returns folder and its data when user is the owner") {
@@ -403,23 +403,23 @@ class FolderReadServiceTest extends UnitTestSuite with TestEnvironment {
)
.thenReturn(Success(Some(folderWithId)))
- val Failure(result: NotFoundException) = service.getSharedFolder(folderUUID, None)
+ val Failure(result: NotFoundException) = service.getSharedFolder(folderUUID, None): @unchecked
result.message should be("Folder does not exist")
}
test("That getting stats fetches stats for my ndla usage") {
- when(userRepository.usersGrouped()(any)).thenReturn(Success(Map(UserRole.EMPLOYEE -> 2, UserRole.STUDENT -> 3)))
- when(folderRepository.numberOfFolders()(any)).thenReturn(Success(Some(10)))
- when(folderRepository.numberOfResources()(any)).thenReturn(Success(Some(20)))
- when(folderRepository.numberOfTags()(any)).thenReturn(Success(Some(10)))
- when(userRepository.numberOfFavouritedSubjects()(any)).thenReturn(Success(Some(15)))
- when(folderRepository.numberOfSharedFolders()(any)).thenReturn(Success(Some(5)))
- when(learningPathApiClient.getStats).thenReturn(Success(LearningPathStatsDTO(25)))
+ when(userRepository.usersGrouped()(any)).thenReturn(Success(Map(UserRole.EMPLOYEE -> 2L, UserRole.STUDENT -> 3L)))
+ when(folderRepository.numberOfFolders()(any)).thenReturn(Success(Some(10L)))
+ when(folderRepository.numberOfResources()(any)).thenReturn(Success(Some(20L)))
+ when(folderRepository.numberOfTags()(any)).thenReturn(Success(Some(10L)))
+ when(userRepository.numberOfFavouritedSubjects()(any)).thenReturn(Success(Some(15L)))
+ when(folderRepository.numberOfSharedFolders()(any)).thenReturn(Success(Some(5L)))
+ when(learningPathApiClient.getStats).thenReturn(Success(LearningPathStatsDTO(25L)))
when(folderRepository.numberOfResourcesGrouped()(any))
- .thenReturn(Success(List((1, "article"), (2, "learningpath"), (3, "video"))))
- when(folderRepository.numberOfUsersWithFavourites(any)).thenReturn(Success(Some(3)))
- when(folderRepository.numberOfUsersWithoutFavourites(any)).thenReturn(Success(Some(2)))
- when(userRepository.numberOfUsersInArena(any)).thenReturn(Success(Some(4)))
+ .thenReturn(Success(List((1L, "article"), (2L, "learningpath"), (3L, "video"))))
+ when(folderRepository.numberOfUsersWithFavourites(any)).thenReturn(Success(Some(3L)))
+ when(folderRepository.numberOfUsersWithoutFavourites(any)).thenReturn(Success(Some(2L)))
+ when(userRepository.numberOfUsersInArena(any)).thenReturn(Success(Some(4L)))
service.getStats.unsafeGet should be(
api.StatsDTO(
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderWriteServiceTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderWriteServiceTest.scala
index 10931f3c32..a8b002329e 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderWriteServiceTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/FolderWriteServiceTest.scala
@@ -32,8 +32,8 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
val MaxFolderDepth = 5L
- val service = new FolderWriteService
- override val folderConverterService: FolderConverterService = spy(new FolderConverterService)
+ val service = new FolderWriteService
+ override lazy val folderConverterService: FolderConverterService = spy(new FolderConverterService)
override def beforeEach(): Unit = {
super.beforeEach()
@@ -42,7 +42,7 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
doAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Nothing]](0)
func(mock[DBSession])
- }).when(DBUtil).rollbackOnFailure(any)
+ }).when(DBUtil).rollbackOnFailure(any())
}
test("that a user without access cannot delete a folder") {
@@ -59,7 +59,7 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(folderRepository.foldersWithFeideAndParentID(any, any)(any)).thenReturn(Success(List.empty))
when(feideApiClient.getFeideID(any)).thenReturn(Success(wrongFeideId))
when(userService.getOrCreateMyNDLAUserIfNotExist(any, any)(any)).thenReturn(Success(emptyMyNDLAUser))
- when(folderRepository.folderResourceConnectionCount(any)(any)).thenReturn(Success(0))
+ when(folderRepository.folderResourceConnectionCount(any)(any)).thenReturn(Success(0L))
when(folderRepository.folderWithId(eqTo(id))(any)).thenReturn(Success(folderWithChildren))
val x = service.deleteFolder(id, Some("token"))
@@ -90,14 +90,14 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
)
val correctFeideId = "FEIDE"
- when(folderRepository.withTx(any[DBSession => Try[Unit]])).thenAnswer((i: InvocationOnMock) => {
+ when(folderRepository.withTx(any[DBSession => Try[Unit]]())).thenAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Unit]](0)
func(mock[DBSession])
})
when(folderRepository.foldersWithFeideAndParentID(any, any)(any)).thenReturn(Success(List.empty))
when(feideApiClient.getFeideID(any)).thenReturn(Success(correctFeideId))
when(userService.getOrCreateMyNDLAUserIfNotExist(any, any)(any)).thenReturn(Success(emptyMyNDLAUser))
- when(folderRepository.folderResourceConnectionCount(any)(any[DBSession])).thenReturn(Success(1))
+ when(folderRepository.folderResourceConnectionCount(any)(any[DBSession])).thenReturn(Success(1L))
when(folderRepository.folderWithId(eqTo(mainFolderId))(any)).thenReturn(Success(folder))
when(folderReadService.getSingleFolderWithContent(eqTo(folder.id), any, eqTo(true))(any))
.thenReturn(Success(folderWithChildren))
@@ -140,14 +140,14 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
)
val correctFeideId = "FEIDE"
- when(folderRepository.withTx(any[DBSession => Try[Unit]])).thenAnswer((i: InvocationOnMock) => {
+ when(folderRepository.withTx(any[DBSession => Try[Unit]]())).thenAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Unit]](0)
func(mock[DBSession])
})
when(folderRepository.foldersWithFeideAndParentID(any, any)(any)).thenReturn(Success(List.empty))
when(feideApiClient.getFeideID(any)).thenReturn(Success(correctFeideId))
when(userService.getOrCreateMyNDLAUserIfNotExist(any, any)(any)).thenReturn(Success(emptyMyNDLAUser))
- when(folderRepository.folderResourceConnectionCount(eqTo(resourceId))(any)).thenReturn(Success(5))
+ when(folderRepository.folderResourceConnectionCount(eqTo(resourceId))(any)).thenReturn(Success(5L))
when(folderRepository.folderWithId(eqTo(mainFolderId))(any)).thenReturn(Success(folder))
when(folderReadService.getSingleFolderWithContent(eqTo(folder.id), any, eqTo(true))(any))
.thenReturn(Success(folderWithChildren))
@@ -184,8 +184,8 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(userService.getOrCreateMyNDLAUserIfNotExist(any, any)(any)).thenReturn(Success(emptyMyNDLAUser))
when(folderRepository.folderWithId(eqTo(folderId))(any)).thenReturn(Success(folder))
when(folderRepository.resourceWithId(eqTo(resourceId))(any)).thenReturn(Success(resource))
- when(folderRepository.folderResourceConnectionCount(eqTo(resourceId))(any)).thenReturn(Success(2))
- when(folderRepository.withTx(any[DBSession => Try[Unit]])).thenAnswer((i: InvocationOnMock) => {
+ when(folderRepository.folderResourceConnectionCount(eqTo(resourceId))(any)).thenReturn(Success(2L))
+ when(folderRepository.withTx(any[DBSession => Try[Unit]]())).thenAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Unit]](0)
func(mock[DBSession])
})
@@ -217,11 +217,11 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(userService.getOrCreateMyNDLAUserIfNotExist(any, any)(any)).thenReturn(Success(emptyMyNDLAUser))
when(folderRepository.folderWithId(eqTo(folderId))(any)).thenReturn(Success(folder))
when(folderRepository.resourceWithId(eqTo(resourceId))(any)).thenReturn(Success(resource))
- when(folderRepository.folderResourceConnectionCount(eqTo(resourceId))(any)).thenReturn(Success(1))
+ when(folderRepository.folderResourceConnectionCount(eqTo(resourceId))(any)).thenReturn(Success(1L))
when(folderRepository.deleteFolderResourceConnection(eqTo(folderId), eqTo(resourceId))(any))
.thenReturn(Success(resourceId))
when(folderRepository.deleteResource(eqTo(resourceId))(any)).thenReturn(Success(resourceId))
- when(folderRepository.withTx(any[DBSession => Try[Unit]])).thenAnswer((i: InvocationOnMock) => {
+ when(folderRepository.withTx(any[DBSession => Try[Unit]]())).thenAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Unit]](0)
func(mock[DBSession])
})
@@ -446,16 +446,16 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(folderReadService.getSingleFolderWithContent(eqTo(folder1Id), eqTo(true), eqTo(true))(any[DBSession]))
.thenReturn(Success(folder1))
when(folderRepository.folderResourceConnectionCount(eqTo(resource1Id))(any[DBSession]))
- .thenReturn(Success(2), Success(1))
+ .thenReturn(Success(2L), Success(1L))
when(folderRepository.deleteFolderResourceConnection(eqTo(folder1Id), eqTo(resource1Id))(any[DBSession]))
.thenReturn(Success(resource1Id))
when(folderRepository.deleteResource(eqTo(resource1Id))(any[DBSession])).thenReturn(Success(resource1Id))
when(folderRepository.folderResourceConnectionCount(eqTo(resource2Id))(any[DBSession]))
- .thenReturn(Success(2), Success(1))
+ .thenReturn(Success(2L), Success(1L))
when(folderRepository.deleteFolderResourceConnection(eqTo(folder2Id), eqTo(resource2Id))(any[DBSession]))
.thenReturn(Success(resource2Id))
when(folderRepository.deleteResource(eqTo(resource2Id))(any[DBSession])).thenReturn(Success(resource2Id))
- when(folderRepository.folderResourceConnectionCount(eqTo(resource3Id))(any[DBSession])).thenReturn(Success(1))
+ when(folderRepository.folderResourceConnectionCount(eqTo(resource3Id))(any[DBSession])).thenReturn(Success(1L))
when(folderRepository.deleteResource(eqTo(resource3Id))(any[DBSession])).thenReturn(Success(resource3Id))
when(folderRepository.deleteFolder(eqTo(folder3Id))(any[DBSession])).thenReturn(Success(folder3Id))
when(folderRepository.deleteFolder(eqTo(folder2Id))(any[DBSession])).thenReturn(Success(folder2Id))
@@ -463,13 +463,14 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(folderRepository.deleteFolderUserConnection(eqTo(Some(folder3Id)), eqTo(None))(any)).thenReturn(Success(0))
when(folderRepository.deleteFolderUserConnection(eqTo(Some(folder2Id)), eqTo(None))(any)).thenReturn(Success(0))
when(folderRepository.deleteFolderUserConnection(eqTo(Some(folder1Id)), eqTo(None))(any)).thenReturn(Success(0))
- when(folderRepository.withTx(any[DBSession => Try[Unit]])).thenAnswer((i: InvocationOnMock) => {
+ when(folderRepository.withTx(any[DBSession => Try[Unit]]())).thenAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Unit]](0)
func(mock[DBSession])
})
when(folderRepository.foldersWithFeideAndParentID(any, any)(any)).thenReturn(Success(List.empty))
- service.deleteFolder(folder1Id, Some("FEIDEF")) should be(Success(folder1Id))
+ val result = service.deleteFolder(folder1Id, Some("FEIDEF"))
+ result should be(Success(folder1Id))
verify(folderReadService, times(1)).getSingleFolderWithContent(eqTo(folder1Id), eqTo(true), eqTo(true))(any)
verify(folderRepository, times(5)).folderResourceConnectionCount(any)(any)
@@ -513,7 +514,7 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(folderRepository.getFoldersDepth(eqTo(parentId))(any[DBSession])).thenReturn(Success(MaxFolderDepth))
when(folderRepository.getConnections(any)(any)).thenReturn(Success(List.empty))
- val Failure(result: ValidationException) = service.newFolder(newFolder, Some(feideId))
+ val Failure(result: ValidationException) = service.newFolder(newFolder, Some(feideId)): @unchecked
result.errors.head.message should be(
s"Folder can not be created, max folder depth limit of $MaxFolderDepth reached."
)
@@ -825,7 +826,7 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
)
)
- when(folderRepository.withTx(any[DBSession => Try[Unit]])).thenAnswer((i: InvocationOnMock) => {
+ when(folderRepository.withTx(any[DBSession => Try[Unit]]())).thenAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Unit]](0)
func(mock[DBSession])
})
@@ -967,7 +968,8 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(userService.getOrCreateMyNDLAUserIfNotExist(any, any)(any)).thenReturn(Success(myNDLAUser))
val updatedFolder = api.UpdatedFolderDTO(name = None, status = Some("shared"), description = None)
- val Failure(result) = service.isOperationAllowedOrAccessDenied("feideid", Some("accesstoken"), updatedFolder)
+ val Failure(result) =
+ service.isOperationAllowedOrAccessDenied("feideid", Some("accesstoken"), updatedFolder): @unchecked
result.getMessage should be("You do not have necessary permissions to share folders.")
}
@@ -979,7 +981,8 @@ class FolderWriteServiceTest extends UnitTestSuite with TestEnvironment {
when(configService.isMyNDLAWriteRestricted).thenReturn(Success(true))
val updatedFolder = api.UpdatedFolderDTO(name = Some("asd"), status = None, description = None)
- val Failure(result) = service.isOperationAllowedOrAccessDenied("feideid", Some("accesstoken"), updatedFolder)
+ val Failure(result) =
+ service.isOperationAllowedOrAccessDenied("feideid", Some("accesstoken"), updatedFolder): @unchecked
result.getMessage should be("You do not have write access while write restriction is active.")
}
diff --git a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/UserServiceTest.scala b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/UserServiceTest.scala
index f8432db592..32e905db78 100644
--- a/myndla-api/src/test/scala/no/ndla/myndlaapi/service/UserServiceTest.scala
+++ b/myndla-api/src/test/scala/no/ndla/myndlaapi/service/UserServiceTest.scala
@@ -25,8 +25,8 @@ import scala.util.{Failure, Success, Try}
class UserServiceTest extends UnitTestSuite with TestEnvironment {
- val service: UserService = spy(new UserService)
- override val folderConverterService: FolderConverterService = spy(new FolderConverterService)
+ val service: UserService = spy(new UserService)
+ override lazy val folderConverterService: FolderConverterService = spy(new FolderConverterService)
override def beforeEach(): Unit = {
super.beforeEach()
@@ -145,7 +145,7 @@ class UserServiceTest extends UnitTestSuite with TestEnvironment {
doAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Nothing]](0)
func(mock[DBSession])
- }).when(DBUtil).rollbackOnFailure(any)
+ }).when(DBUtil).rollbackOnFailure(any())
when(userRepository.reserveFeideIdIfNotExists(any)(any)).thenReturn(Success(false))
val feideId = "feide"
@@ -227,7 +227,7 @@ class UserServiceTest extends UnitTestSuite with TestEnvironment {
doAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Nothing]](0)
func(mock[DBSession])
- }).when(DBUtil).rollbackOnFailure(any)
+ }).when(DBUtil).rollbackOnFailure(any())
when(userRepository.reserveFeideIdIfNotExists(any)(any)).thenReturn(Success(true))
val feideId = "feide"
@@ -285,7 +285,7 @@ class UserServiceTest extends UnitTestSuite with TestEnvironment {
doAnswer((i: InvocationOnMock) => {
val func = i.getArgument[DBSession => Try[Nothing]](0)
func(mock[DBSession])
- }).when(DBUtil).rollbackOnFailure(any)
+ }).when(DBUtil).rollbackOnFailure(any())
when(userRepository.reserveFeideIdIfNotExists(any)(any)).thenReturn(Success(true))
val feideId = "feide"
diff --git a/network/src/main/scala/no/ndla/network/NdlaClient.scala b/network/src/main/scala/no/ndla/network/NdlaClient.scala
index 84f1003fff..71816e0df9 100644
--- a/network/src/main/scala/no/ndla/network/NdlaClient.scala
+++ b/network/src/main/scala/no/ndla/network/NdlaClient.scala
@@ -19,13 +19,13 @@ import sttp.client3.quick.*
import scala.util.{Failure, Success, Try}
trait NdlaClient {
- val ndlaClient: NdlaClient
+ lazy val ndlaClient: NdlaClient
class NdlaClient {
val client: SimpleHttpClient = simpleHttpClient
private val ResponseErrorBodyCharacterCutoff = 1000
- def fetch[A: Decoder](request: NdlaRequest): Try[A] = {
+ def fetch[A](request: NdlaRequest)(implicit decoder: Decoder[A]): Try[A] = {
doFetch(addCorrelationId(request))
}
diff --git a/network/src/main/scala/no/ndla/network/clients/FeideApiClient.scala b/network/src/main/scala/no/ndla/network/clients/FeideApiClient.scala
index 466245626c..7d932b5892 100644
--- a/network/src/main/scala/no/ndla/network/clients/FeideApiClient.scala
+++ b/network/src/main/scala/no/ndla/network/clients/FeideApiClient.scala
@@ -86,7 +86,7 @@ object FeideExtendedUserInfo {
trait FeideApiClient {
this: RedisClient =>
- val feideApiClient: FeideApiClient
+ lazy val feideApiClient: FeideApiClient
class FeideApiClient extends StrictLogging {
diff --git a/network/src/main/scala/no/ndla/network/clients/FrontpageApiClient.scala b/network/src/main/scala/no/ndla/network/clients/FrontpageApiClient.scala
index 4dde218701..9e6af8d6c7 100644
--- a/network/src/main/scala/no/ndla/network/clients/FrontpageApiClient.scala
+++ b/network/src/main/scala/no/ndla/network/clients/FrontpageApiClient.scala
@@ -18,7 +18,7 @@ import scala.util.Try
trait FrontpageApiClient {
this: HasBaseProps & NdlaClient =>
- val frontpageApiClient: FrontpageApiClient
+ lazy val frontpageApiClient: FrontpageApiClient
class FrontpageApiClient {
val timeout: FiniteDuration = 15.seconds
diff --git a/network/src/main/scala/no/ndla/network/clients/MyNDLAApiClient.scala b/network/src/main/scala/no/ndla/network/clients/MyNDLAApiClient.scala
index fa1fb562db..e232211ec6 100644
--- a/network/src/main/scala/no/ndla/network/clients/MyNDLAApiClient.scala
+++ b/network/src/main/scala/no/ndla/network/clients/MyNDLAApiClient.scala
@@ -23,7 +23,7 @@ import scala.util.{Failure, Success, Try}
trait MyNDLAApiClient {
this: HasBaseProps & NdlaClient =>
- val myndlaApiClient: MyNDLAApiClient
+ lazy val myndlaApiClient: MyNDLAApiClient
class MyNDLAApiClient {
private val statsEndpoint = s"http://${props.MyNDLAApiHost}/myndla-api/v1/stats"
diff --git a/network/src/main/scala/no/ndla/network/clients/RedisClient.scala b/network/src/main/scala/no/ndla/network/clients/RedisClient.scala
index 26f109aef6..0abd0b8c10 100644
--- a/network/src/main/scala/no/ndla/network/clients/RedisClient.scala
+++ b/network/src/main/scala/no/ndla/network/clients/RedisClient.scala
@@ -18,7 +18,7 @@ import scala.util.{Failure, Success, Try}
trait RedisClient {
this: HasBaseProps =>
- val redisClient: RedisClient
+ lazy val redisClient: RedisClient
class RedisClient(
host: String,
port: Int,
@@ -37,7 +37,7 @@ trait RedisClient {
Success(newExpireTime)
}
- private def updateCache(accessToken: FeideAccessToken, field: String, data: String): Try[_] = {
+ private def updateCache(accessToken: FeideAccessToken, field: String, data: String): Try[?] = {
for {
newExpireTime <- getKeyExpireTime(accessToken)
_ <- jedis.hset(accessToken, field, data)
diff --git a/network/src/main/scala/no/ndla/network/clients/SearchApiClient.scala b/network/src/main/scala/no/ndla/network/clients/SearchApiClient.scala
index a3b143f76d..89b53f6d83 100644
--- a/network/src/main/scala/no/ndla/network/clients/SearchApiClient.scala
+++ b/network/src/main/scala/no/ndla/network/clients/SearchApiClient.scala
@@ -26,7 +26,7 @@ import scala.util.{Failure, Success, Try}
trait SearchApiClient {
this: HasBaseProps & NdlaClient =>
- val searchApiClient: SearchApiClient
+ lazy val searchApiClient: SearchApiClient
class SearchApiClient(SearchApiBaseUrl: String = s"http://${props.SearchApiHost}") extends StrictLogging {
private val InternalEndpoint = s"$SearchApiBaseUrl/intern"
diff --git a/network/src/main/scala/no/ndla/network/tapir/NdlaTapirMain.scala b/network/src/main/scala/no/ndla/network/tapir/NdlaTapirMain.scala
index 263633df6c..ad52533207 100644
--- a/network/src/main/scala/no/ndla/network/tapir/NdlaTapirMain.scala
+++ b/network/src/main/scala/no/ndla/network/tapir/NdlaTapirMain.scala
@@ -19,7 +19,7 @@ import sttp.tapir.server.jdkhttp.HttpServer
import scala.concurrent.Future
import scala.concurrent.duration.{Duration, DurationInt}
import scala.io.Source
-import scala.util.Try
+import scala.util.{Try, boundary}
trait NdlaTapirMain[T <: TapirApplication] {
val logger: Logger = getLogger
@@ -45,7 +45,7 @@ trait NdlaTapirMain[T <: TapirApplication] {
private def performWarmup(): Unit = if (!props.disableWarmup) {
import scala.concurrent.ExecutionContext.Implicits.global
- Future {
+ val fut = Future {
// Since we don't really have a good way to check whether server is ready lets just wait a bit
Thread.sleep(500)
val warmupStart = System.currentTimeMillis()
@@ -55,19 +55,21 @@ trait NdlaTapirMain[T <: TapirApplication] {
val warmupTime = System.currentTimeMillis() - warmupStart
logger.info(s"Warmup procedure finished in ${warmupTime}ms.")
- }: Unit
+ }
+
+ fut: Unit
} else {
componentRegistry.healthController.setWarmedUp()
}
- private def waitForActiveRequests(timeout: Duration): Unit = {
+ private def waitForActiveRequests(timeout: Duration): Unit = boundary {
val startTime = System.currentTimeMillis()
val activeRequests = componentRegistry.Routes.activeRequests.get()
logTaskTime(s"Waiting for $activeRequests active requests to finish...", timeout, logTaskStart = true) {
while (componentRegistry.Routes.activeRequests.get() > 0) {
if (System.currentTimeMillis() - startTime > timeout.toMillis) {
logger.warn(s"Timeout of $timeout reached while waiting for active requests to finish.")
- return
+ boundary.break()
}
Thread.sleep(100)
}
@@ -96,10 +98,7 @@ trait NdlaTapirMain[T <: TapirApplication] {
* than the default logger shutdown handler will allow
*/
private def shutdownLogger(): Unit = {
- LoggerContext.getContext(false) match {
- case context: LoggerContext => context.stop()
- case _ => println("No LoggerContext found, cannot stop logging context.")
- }
+ LoggerContext.getContext(false).stop()
}
private def runServer(): Try[Unit] = {
diff --git a/network/src/main/scala/no/ndla/network/tapir/NonEmptyString.scala b/network/src/main/scala/no/ndla/network/tapir/NonEmptyString.scala
index ec24b2a09e..ea307dfe94 100644
--- a/network/src/main/scala/no/ndla/network/tapir/NonEmptyString.scala
+++ b/network/src/main/scala/no/ndla/network/tapir/NonEmptyString.scala
@@ -28,6 +28,9 @@ class NonEmptyString private (val underlying: String) {
object NonEmptyString {
def apply(underlying: String): Option[NonEmptyString] = fromString(underlying)
+ given CanEqual[NonEmptyString, String] = CanEqual.derived
+ given CanEqual[String, NonEmptyString] = CanEqual.derived
+
private def validateString(underlying: String): Boolean = underlying.trim.nonEmpty
def fromOptString(s: Option[String]): Option[NonEmptyString] =
diff --git a/network/src/main/scala/no/ndla/network/tapir/Routes.scala b/network/src/main/scala/no/ndla/network/tapir/Routes.scala
index 1d5390ffd9..0826e7f556 100644
--- a/network/src/main/scala/no/ndla/network/tapir/Routes.scala
+++ b/network/src/main/scala/no/ndla/network/tapir/Routes.scala
@@ -169,7 +169,7 @@ trait Routes {
req.attribute(requestBody).foreach { body =>
if (body.nonEmpty) {
val requestBodyStr = new String(body, UTF_8)
- MDC.put("requestBody", requestBodyStr)
+ MDC.put("requestBody", requestBodyStr): Unit
}
}
@@ -203,7 +203,7 @@ trait Routes {
if (code >= 500) logger.error(s)
else logger.info(s)
- activeRequests.decrementAndGet()
+ activeRequests.decrementAndGet(): Unit
}
RequestInfo.clear()
@@ -247,6 +247,8 @@ trait Routes {
val endpoints = services.flatMap(_.builtEndpoints)
+ logger.info(s"Starting $name on port $port")
+
val server = JdkHttpServer()
.options(options)
.executor(executor)
@@ -255,8 +257,6 @@ trait Routes {
.port(port)
.start()
- logger.info(s"Starting $name on port $port")
-
warmupFunc
server
diff --git a/network/src/main/scala/no/ndla/network/tapir/SwaggerControllerConfig.scala b/network/src/main/scala/no/ndla/network/tapir/SwaggerControllerConfig.scala
index 4605ff2609..f1e577110c 100644
--- a/network/src/main/scala/no/ndla/network/tapir/SwaggerControllerConfig.scala
+++ b/network/src/main/scala/no/ndla/network/tapir/SwaggerControllerConfig.scala
@@ -23,16 +23,15 @@ trait SwaggerControllerConfig {
this: HasBaseProps & TapirController =>
class SwaggerController(services: List[TapirController], swaggerInfo: SwaggerInfo) extends TapirController {
- import props.*
-
def getServices(): List[TapirController] = services :+ this
val info: Info = Info(
title = props.ApplicationName,
version = "1.0",
description = swaggerInfo.description.some,
- termsOfService = TermsUrl.some,
- contact = Contact(name = ContactName.some, url = ContactUrl.some, email = ContactEmail.some).some,
+ termsOfService = props.TermsUrl.some,
+ contact =
+ Contact(name = props.ContactName.some, url = props.ContactUrl.some, email = props.ContactEmail.some).some,
license = License("GPL v3.0", "https://www.gnu.org/licenses/gpl-3.0.en.html".some).some
)
diff --git a/network/src/main/scala/no/ndla/network/tapir/TapirHealthController.scala b/network/src/main/scala/no/ndla/network/tapir/TapirHealthController.scala
index 1886802e26..06b1aef77a 100644
--- a/network/src/main/scala/no/ndla/network/tapir/TapirHealthController.scala
+++ b/network/src/main/scala/no/ndla/network/tapir/TapirHealthController.scala
@@ -16,7 +16,7 @@ import sttp.tapir.*
trait TapirHealthController {
this: TapirController =>
- val healthController: TapirHealthController
+ lazy val healthController: TapirHealthController
class TapirHealthController extends Warmup with TapirController {
@volatile private var isShuttingDown: Boolean = false
override val enableSwagger: Boolean = false
diff --git a/network/src/main/scala/no/ndla/network/tapir/TapirUtil.scala b/network/src/main/scala/no/ndla/network/tapir/TapirUtil.scala
index 0036e0e33a..5954b2e37e 100644
--- a/network/src/main/scala/no/ndla/network/tapir/TapirUtil.scala
+++ b/network/src/main/scala/no/ndla/network/tapir/TapirUtil.scala
@@ -42,6 +42,6 @@ object TapirUtil {
val variants = variantsForCodes(codesToGetVariantFor)
val err = variants :+ internalServerErrorDefaultVariant
- oneOf[AllErrors](err.head, err.tail: _*)
+ oneOf[AllErrors](err.head, err.tail*)
}
}
diff --git a/network/src/main/scala/no/ndla/network/tapir/auth/TokenUser.scala b/network/src/main/scala/no/ndla/network/tapir/auth/TokenUser.scala
index 101a9aec56..07138ed452 100644
--- a/network/src/main/scala/no/ndla/network/tapir/auth/TokenUser.scala
+++ b/network/src/main/scala/no/ndla/network/tapir/auth/TokenUser.scala
@@ -113,7 +113,7 @@ object TokenUser {
.requiredScopes(permissions.map(_.entryName))
EndpointInput.Auth(
- input = sttp.tapir.header(HeaderNames.Authorization)(authCodec),
+ input = sttp.tapir.header(HeaderNames.Authorization)(using authCodec),
challenge = WWWAuthenticateChallenge.bearer,
authType = authType,
info = AuthInfo.Empty.securitySchemeName("oauth2")
diff --git a/network/src/test/scala/no/ndla/network/NdlaClientTest.scala b/network/src/test/scala/no/ndla/network/NdlaClientTest.scala
index 88fcbe7270..7ed79360fe 100644
--- a/network/src/test/scala/no/ndla/network/NdlaClientTest.scala
+++ b/network/src/test/scala/no/ndla/network/NdlaClientTest.scala
@@ -29,8 +29,8 @@ class NdlaClientTest extends UnitSuite with NdlaClient {
|}
""".stripMargin
- val httpClientMock: SimpleHttpClient = mock[SimpleHttpClient]
- val ndlaClient: NdlaClient = new NdlaClient {
+ val httpClientMock: SimpleHttpClient = mock[SimpleHttpClient]
+ override lazy val ndlaClient: NdlaClient = new NdlaClient {
override val client = httpClientMock
}
diff --git a/network/src/test/scala/no/ndla/network/tapir/NonEmptyStringTest.scala b/network/src/test/scala/no/ndla/network/tapir/NonEmptyStringTest.scala
index da28bbc2bb..6b76016ee8 100644
--- a/network/src/test/scala/no/ndla/network/tapir/NonEmptyStringTest.scala
+++ b/network/src/test/scala/no/ndla/network/tapir/NonEmptyStringTest.scala
@@ -9,6 +9,7 @@
package no.ndla.network.tapir
import no.ndla.network.UnitSuite
+import org.scalatest.EitherValues.convertEitherToValuable
class NonEmptyStringTest extends UnitSuite {
@@ -42,27 +43,27 @@ class NonEmptyStringTest extends UnitSuite {
import io.circe.generic.auto._
case class SomeObject(cantbeempty: Option[NonEmptyString])
- val jsonString = """{"cantbeempty": ""}"""
- val Right(Right(result)) = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
- result.cantbeempty should be(None)
+ val jsonString = """{"cantbeempty": ""}"""
+ val result = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
+ result should be(Right(Right(SomeObject(None))))
}
test("That decoding a json-string returns Some(str) if valid string is passed") {
import io.circe.generic.auto._
case class SomeObject(cantbeempty: Option[NonEmptyString])
- val jsonString = """{"cantbeempty": "spirrevipp"}"""
- val Right(Right(result)) = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
- result.cantbeempty.get.underlying should be("spirrevipp")
+ val jsonString = """{"cantbeempty": "spirrevipp"}"""
+ val result = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
+ result.value.value.cantbeempty.get.underlying should be("spirrevipp")
}
test("That decoding missing field returns None for optionals") {
import io.circe.generic.auto._
case class SomeObject(cantbeempty: Option[NonEmptyString])
- val jsonString = """{}"""
- val Right(Right(result)) = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
- result.cantbeempty should be(None)
+ val jsonString = """{}"""
+ val result = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
+ result.value.value.cantbeempty should be(None)
}
test("That encoding json simply makes a normal string :^)") {
@@ -85,13 +86,13 @@ class NonEmptyStringTest extends UnitSuite {
import io.circe.generic.auto._
case class SomeObject(cantbeempty: NonEmptyString)
- val jsonString1 = """{"cantbeempty": "spirrevipp"}"""
- val Right(Right(result1)) = io.circe.parser.parse(jsonString1).map(_.as[SomeObject])
- result1.cantbeempty.underlying should be("spirrevipp")
+ val jsonString1 = """{"cantbeempty": "spirrevipp"}"""
+ val result1 = io.circe.parser.parse(jsonString1).map(_.as[SomeObject])
+ result1.value.value.cantbeempty.underlying should be("spirrevipp")
- val jsonString = """{"cantbeempty": ""}"""
- val Right(Left(failure)) = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
- failure.message should be(NonEmptyString.parseErrorMessage)
+ val jsonString = """{"cantbeempty": ""}"""
+ val failure = io.circe.parser.parse(jsonString).map(_.as[SomeObject])
+ failure.value.swap.value.message should be(NonEmptyString.parseErrorMessage)
}
test("That comparisons works as expected") {
diff --git a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/ComponentRegistry.scala b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/ComponentRegistry.scala
index 71cc484ea6..5e78f889b4 100644
--- a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/ComponentRegistry.scala
+++ b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/ComponentRegistry.scala
@@ -29,7 +29,7 @@ class ComponentRegistry(properties: OEmbedProxyProperties)
with ErrorHandling
with Clock
with SwaggerDocControllerConfig {
- override val props: OEmbedProxyProperties = properties
+ override lazy val props: OEmbedProxyProperties = properties
lazy val providerService = new ProviderService
lazy val oEmbedService = new OEmbedService
diff --git a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/OEmbedProxyProperties.scala b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/OEmbedProxyProperties.scala
index 0b28c12984..d2ec3d3c1f 100644
--- a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/OEmbedProxyProperties.scala
+++ b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/OEmbedProxyProperties.scala
@@ -14,7 +14,7 @@ import no.ndla.network.{AuthUser, Domains}
import scala.util.Properties.propOrElse
trait Props extends HasBaseProps {
- val props: OEmbedProxyProperties
+ lazy val props: OEmbedProxyProperties
}
class OEmbedProxyProperties extends BaseProps {
diff --git a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/caching/Memoize1.scala b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/caching/Memoize1.scala
index 948c9d78a9..9816cda7c9 100644
--- a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/caching/Memoize1.scala
+++ b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/caching/Memoize1.scala
@@ -23,7 +23,7 @@ class Memoize[R](maxCacheAgeMs: Long, retryTimeInMs: Long, f: () => R, autoRefre
lastUpdated + maxCacheAgeMs <= System.currentTimeMillis()
}
- private[this] var cache: Option[CacheValue] = None
+ private var cache: Option[CacheValue] = None
private def renewCache(): Unit = {
try {
@@ -44,7 +44,7 @@ class Memoize[R](maxCacheAgeMs: Long, retryTimeInMs: Long, f: () => R, autoRefre
val task = new Runnable {
def run(): Unit = renewCache()
}
- ex.scheduleAtFixedRate(task, 20, maxCacheAgeMs, TimeUnit.MILLISECONDS)
+ ex.scheduleAtFixedRate(task, 20, maxCacheAgeMs, TimeUnit.MILLISECONDS): Unit
}
def apply(): R = {
@@ -59,17 +59,14 @@ class Memoize[R](maxCacheAgeMs: Long, retryTimeInMs: Long, f: () => R, autoRefre
}
trait MemoizeHelpers {
this: Props =>
- import props.{ProviderListRetryTimeInMs, ProviderListCacheAgeInMs}
-
object Memoize {
-
def apply[R](f: () => R) =
- new Memoize(ProviderListCacheAgeInMs, ProviderListRetryTimeInMs, f, autoRefreshCache = false)
+ new Memoize(props.ProviderListCacheAgeInMs, props.ProviderListRetryTimeInMs, f, autoRefreshCache = false)
}
object MemoizeAutoRenew {
def apply[R](f: () => R) =
- new Memoize(ProviderListCacheAgeInMs, ProviderListRetryTimeInMs, f, autoRefreshCache = true)
+ new Memoize(props.ProviderListCacheAgeInMs, props.ProviderListRetryTimeInMs, f, autoRefreshCache = true)
}
}
diff --git a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/controller/OEmbedProxyController.scala b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/controller/OEmbedProxyController.scala
index 23b10d5a6a..f34a4bfce0 100644
--- a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/controller/OEmbedProxyController.scala
+++ b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/controller/OEmbedProxyController.scala
@@ -9,7 +9,6 @@
package no.ndla.oembedproxy.controller
import cats.implicits.*
-import io.circe.generic.auto.*
import no.ndla.network.tapir.NoNullJsonPrinter.jsonBody
import no.ndla.network.tapir.TapirController
import no.ndla.network.tapir.TapirUtil.errorOutputsFor
@@ -23,7 +22,7 @@ import scala.util.{Failure, Success}
trait OEmbedProxyController {
this: OEmbedServiceComponent & ErrorHandling & TapirController =>
- val oEmbedProxyController: OEmbedProxyController
+ lazy val oEmbedProxyController: OEmbedProxyController
class OEmbedProxyController extends TapirController {
override val serviceName: String = "oembed"
diff --git a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/OEmbedServiceComponent.scala b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/OEmbedServiceComponent.scala
index 812133af2a..11afb78022 100644
--- a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/OEmbedServiceComponent.scala
+++ b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/OEmbedServiceComponent.scala
@@ -23,7 +23,7 @@ import scala.concurrent.duration.FiniteDuration
trait OEmbedServiceComponent {
this: NdlaClient & ProviderService =>
- val oEmbedService: OEmbedService
+ lazy val oEmbedService: OEmbedService
class OEmbedService(optionalProviders: Option[List[OEmbedProvider]] = None) extends StrictLogging {
private val remoteTimeout: FiniteDuration = 10.seconds
diff --git a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/ProviderService.scala b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/ProviderService.scala
index 6bbd17debc..526e596082 100644
--- a/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/ProviderService.scala
+++ b/oembed-proxy/src/main/scala/no/ndla/oembedproxy/service/ProviderService.scala
@@ -26,7 +26,7 @@ import sttp.client3.quick.*
trait ProviderService {
this: NdlaClient & Props & MemoizeHelpers =>
- val providerService: ProviderService
+ lazy val providerService: ProviderService
class ProviderService extends StrictLogging {
val NdlaFrontendEndpoint: OEmbedEndpoint =
diff --git a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/TestEnvironment.scala b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/TestEnvironment.scala
index 4206b4b51a..bfe2b56bde 100644
--- a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/TestEnvironment.scala
+++ b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/TestEnvironment.scala
@@ -31,13 +31,13 @@ trait TestEnvironment
with Clock {
override lazy val props = new OEmbedProxyProperties
- val oEmbedService: OEmbedService = mock[OEmbedService]
- val oEmbedProxyController: OEmbedProxyController = mock[OEmbedProxyController]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val providerService: ProviderService = mock[ProviderService]
- val healthController: TapirHealthController = mock[TapirHealthController]
- val clock: SystemClock = mock[SystemClock]
+ lazy val oEmbedService: OEmbedService = mock[OEmbedService]
+ lazy val oEmbedProxyController: OEmbedProxyController = mock[OEmbedProxyController]
+ lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ lazy val providerService: ProviderService = mock[ProviderService]
+ lazy val healthController: TapirHealthController = mock[TapirHealthController]
+ lazy val clock: SystemClock = mock[SystemClock]
def services: List[TapirController] = List.empty
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/caching/MemoizeTest.scala b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/caching/MemoizeTest.scala
index 3b6117b22e..8d7c3bf1a7 100644
--- a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/caching/MemoizeTest.scala
+++ b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/caching/MemoizeTest.scala
@@ -20,7 +20,7 @@ class MemoizeTest extends UnitSuite with TestEnvironment {
test("That an uncached value will do an actual call") {
val targetMock = mock[Target]
- val memoizedTarget = new Memoize[String](Long.MaxValue, Long.MaxValue, targetMock.targetMethod _, false)
+ val memoizedTarget = new Memoize[String](Long.MaxValue, Long.MaxValue, targetMock.targetMethod, false)
when(targetMock.targetMethod()).thenReturn("Hello from mock")
memoizedTarget() should equal("Hello from mock")
@@ -29,7 +29,7 @@ class MemoizeTest extends UnitSuite with TestEnvironment {
test("That a cached value will not forward the call to the target") {
val targetMock = mock[Target]
- val memoizedTarget = new Memoize[String](Long.MaxValue, Long.MaxValue, targetMock.targetMethod _, false)
+ val memoizedTarget = new Memoize[String](Long.MaxValue, Long.MaxValue, targetMock.targetMethod, false)
when(targetMock.targetMethod()).thenReturn("Hello from mock")
Seq(1 to 10).foreach(_ => {
@@ -42,7 +42,7 @@ class MemoizeTest extends UnitSuite with TestEnvironment {
val cacheMaxAgeInMs = 20L
val cacheRetryInMs = 20L
val targetMock = mock[Target]
- val memoizedTarget = new Memoize[String](cacheMaxAgeInMs, cacheRetryInMs, targetMock.targetMethod _, false)
+ val memoizedTarget = new Memoize[String](cacheMaxAgeInMs, cacheRetryInMs, targetMock.targetMethod, false)
when(targetMock.targetMethod()).thenReturn("Hello from mock")
@@ -59,7 +59,7 @@ class MemoizeTest extends UnitSuite with TestEnvironment {
val cacheMaxAgeInMs = 20L
val cacheRetryInMs = 20L
val targetMock = mock[Target]
- val memoizedTarget = new Memoize[String](cacheMaxAgeInMs, cacheRetryInMs, targetMock.targetMethod _, false)
+ val memoizedTarget = new Memoize[String](cacheMaxAgeInMs, cacheRetryInMs, targetMock.targetMethod, false)
when(targetMock.targetMethod())
.thenReturn("Hello from mock")
diff --git a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/controller/HealthControllerTest.scala b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/controller/HealthControllerTest.scala
index 011f9b9a71..6909f78649 100644
--- a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/controller/HealthControllerTest.scala
+++ b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/controller/HealthControllerTest.scala
@@ -13,7 +13,7 @@ import no.ndla.tapirtesting.TapirControllerTest
import sttp.client3.quick._
class HealthControllerTest extends UnitSuite with TestEnvironment with TapirControllerTest {
- lazy val controller: TapirHealthController = new TapirHealthController
+ val controller: TapirHealthController = new TapirHealthController
controller.setWarmedUp()
test("That /health returns 200 ok") {
diff --git a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/OEmbedServiceTest.scala b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/OEmbedServiceTest.scala
index 4ef96b67ce..994be31081 100644
--- a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/OEmbedServiceTest.scala
+++ b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/OEmbedServiceTest.scala
@@ -59,21 +59,19 @@ class OEmbedServiceTest extends UnitSuite with TestEnvironment {
Some("")
)
- override val oEmbedService = new OEmbedService(Some(List(ndlaProvider, youtubeProvider)))
- val providerMemoize = new Memoize(0, 0, () => List[OEmbedProvider](), false)
- override val providerService: ProviderService = new ProviderService {
+ override lazy val oEmbedService = new OEmbedService(Some(List(ndlaProvider, youtubeProvider)))
+ val providerMemoize = new Memoize(0, 0, () => List[OEmbedProvider](), false)
+ override lazy val providerService: ProviderService = new ProviderService {
override val loadProviders: Memoize[List[OEmbedProvider]] = providerMemoize
}
test("That get returns Failure(ProviderNotSupportedException) when no providers support the url") {
- val Failure(ex: ProviderNotSupportedException) =
- oEmbedService.get(url = "ABC", None, None)
-
- ex.getMessage should equal("Could not find an oembed-provider for the url 'ABC'")
+ val ex = oEmbedService.get(url = "ABC", None, None)
+ ex should be(Failure(ProviderNotSupportedException("Could not find an oembed-provider for the url 'ABC'")))
}
test("That get returns a failure with HttpRequestException when receiving http error") {
- when(ndlaClient.fetch[OEmbedDTO](any[NdlaRequest])(any))
+ when(ndlaClient.fetch[OEmbedDTO](any[NdlaRequest])(using any))
.thenReturn(Failure(new HttpRequestException("An error occured")))
val oembedTry = oEmbedService.get("https://www.youtube.com/abc", None, None)
oembedTry.isFailure should be(true)
@@ -81,7 +79,7 @@ class OEmbedServiceTest extends UnitSuite with TestEnvironment {
}
test("That get returns a Success with an oEmbed when http call is successful") {
- when(ndlaClient.fetch[OEmbedDTO](any[NdlaRequest])(any))
+ when(ndlaClient.fetch[OEmbedDTO](any[NdlaRequest])(using any))
.thenReturn(Success(OEmbedResponse))
val oembedTry = oEmbedService.get("https://ndla.no/abc", None, None)
oembedTry.isSuccess should be(true)
diff --git a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/ProviderServiceTest.scala b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/ProviderServiceTest.scala
index 0b1059d257..af8882a965 100644
--- a/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/ProviderServiceTest.scala
+++ b/oembed-proxy/src/test/scala/no/ndla/oembedproxy/service/ProviderServiceTest.scala
@@ -39,11 +39,11 @@ class ProviderServiceTest extends UnitSuite with TestEnvironment {
)
)
- override val providerService = new ProviderService
+ override lazy val providerService = new ProviderService
test("That loadProvidersFromRequest fails on invalid url/bad response") {
val invalidUrl = "invalidUrl123"
- when(ndlaClient.fetch[OEmbedDTO](any[NdlaRequest])(any))
+ when(ndlaClient.fetch[OEmbedDTO](any[NdlaRequest])(using any))
.thenReturn(Failure(new HttpRequestException("An error occured")))
intercept[DoNotUpdateMemoizeException] {
providerService.loadProvidersFromRequest(quickRequest.get(uri"$invalidUrl"))
@@ -51,7 +51,7 @@ class ProviderServiceTest extends UnitSuite with TestEnvironment {
}
test("That loadProvidersFromRequest does not return an incomplete provider") {
- when(ndlaClient.fetch[List[OEmbedProvider]](any[NdlaRequest])(any))
+ when(ndlaClient.fetch[List[OEmbedProvider]](any[NdlaRequest])(using any))
.thenReturn(Success(List(IncompleteProvider)))
val providers = providerService.loadProvidersFromRequest(mock[NdlaRequest])
@@ -59,7 +59,7 @@ class ProviderServiceTest extends UnitSuite with TestEnvironment {
}
test("That loadProvidersFromRequest works for a single provider") {
- when(ndlaClient.fetch[List[OEmbedProvider]](any[NdlaRequest])(any))
+ when(ndlaClient.fetch[List[OEmbedProvider]](any[NdlaRequest])(using any))
.thenReturn(Success(List(CompleteProvider)))
val providers = providerService.loadProvidersFromRequest(mock[NdlaRequest])
@@ -67,7 +67,7 @@ class ProviderServiceTest extends UnitSuite with TestEnvironment {
}
test("That loadProvidersFromRequest only returns the complete provider") {
- when(ndlaClient.fetch[List[OEmbedProvider]](any[NdlaRequest])(any))
+ when(ndlaClient.fetch[List[OEmbedProvider]](any[NdlaRequest])(using any))
.thenReturn(Success(List(IncompleteProvider, CompleteProvider)))
val providers = providerService.loadProvidersFromRequest(mock[NdlaRequest])
diff --git a/search-api/src/main/scala/no/ndla/searchapi/ComponentRegistry.scala b/search-api/src/main/scala/no/ndla/searchapi/ComponentRegistry.scala
index dbefa97931..f5c27c7681 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/ComponentRegistry.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/ComponentRegistry.scala
@@ -61,41 +61,40 @@ class ComponentRegistry(properties: SearchApiProperties)
with Props
with SwaggerDocControllerConfig
with GrepSearchService {
- override val props: SearchApiProperties = properties
- import props._
+ override lazy val props: SearchApiProperties = properties
- lazy val ndlaClient = new NdlaClient
- var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(SearchServer)
+ override lazy val ndlaClient = new NdlaClient
+ var e4sClient: NdlaE4sClient = Elastic4sClientFactory.getClient(props.SearchServer)
- lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
+ override lazy val myndlaApiClient: MyNDLAApiClient = new MyNDLAApiClient
- lazy val taxonomyApiClient = new TaxonomyApiClient
- lazy val grepApiClient = new GrepApiClient
+ override lazy val taxonomyApiClient = new TaxonomyApiClient
+ override lazy val grepApiClient = new GrepApiClient
- lazy val draftApiClient = new DraftApiClient(DraftApiUrl)
- lazy val draftConceptApiClient = new DraftConceptApiClient(ConceptApiUrl)
- lazy val learningPathApiClient = new LearningPathApiClient(LearningpathApiUrl)
- lazy val articleApiClient = new ArticleApiClient(ArticleApiUrl)
- lazy val feideApiClient = new FeideApiClient
- lazy val redisClient = new RedisClient(props.RedisHost, props.RedisPort)
- lazy val frontpageApiClient = new FrontpageApiClient
+ override lazy val draftApiClient = new DraftApiClient(props.DraftApiUrl)
+ override lazy val draftConceptApiClient = new DraftConceptApiClient(props.ConceptApiUrl)
+ override lazy val learningPathApiClient = new LearningPathApiClient(props.LearningpathApiUrl)
+ override lazy val articleApiClient = new ArticleApiClient(props.ArticleApiUrl)
+ override lazy val feideApiClient = new FeideApiClient
+ override lazy val redisClient = new RedisClient(props.RedisHost, props.RedisPort)
+ override lazy val frontpageApiClient = new FrontpageApiClient
- lazy val converterService = new ConverterService
- lazy val searchConverterService = new SearchConverterService
- lazy val multiSearchService = new MultiSearchService
- lazy val articleIndexService = new ArticleIndexService
- lazy val draftConceptIndexService = new DraftConceptIndexService
- lazy val learningPathIndexService = new LearningPathIndexService
- lazy val draftIndexService = new DraftIndexService
- lazy val multiDraftSearchService = new MultiDraftSearchService
- lazy val grepIndexService = new GrepIndexService
- lazy val grepSearchService = new GrepSearchService
- lazy val nodeIndexService = new NodeIndexService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
+ override lazy val multiSearchService = new MultiSearchService
+ override lazy val articleIndexService = new ArticleIndexService
+ override lazy val draftConceptIndexService = new DraftConceptIndexService
+ override lazy val learningPathIndexService = new LearningPathIndexService
+ override lazy val draftIndexService = new DraftIndexService
+ override lazy val multiDraftSearchService = new MultiDraftSearchService
+ override lazy val grepIndexService = new GrepIndexService
+ override lazy val grepSearchService = new GrepSearchService
+ override lazy val nodeIndexService = new NodeIndexService
- lazy val searchController = new SearchController
- lazy val healthController: TapirHealthController = new TapirHealthController
- lazy val internController = new InternController
- lazy val clock: SystemClock = new SystemClock
+ override lazy val searchController = new SearchController
+ override lazy val healthController: TapirHealthController = new TapirHealthController
+ override lazy val internController = new InternController
+ override lazy val clock: SystemClock = new SystemClock
val swagger = new SwaggerController(
List[TapirController](
diff --git a/search-api/src/main/scala/no/ndla/searchapi/SearchApiProperties.scala b/search-api/src/main/scala/no/ndla/searchapi/SearchApiProperties.scala
index 1f187bf33b..3175e342fb 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/SearchApiProperties.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/SearchApiProperties.scala
@@ -17,7 +17,7 @@ import scala.util.Properties.*
import scala.util.{Failure, Success, Try}
trait Props extends HasBaseProps {
- val props: SearchApiProperties
+ lazy val props: SearchApiProperties
}
class SearchApiProperties extends BaseProps with StrictLogging {
diff --git a/search-api/src/main/scala/no/ndla/searchapi/controller/InternController.scala b/search-api/src/main/scala/no/ndla/searchapi/controller/InternController.scala
index 4c43b22074..4bb3afeea8 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/controller/InternController.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/controller/InternController.scala
@@ -52,7 +52,7 @@ trait InternController {
this: IndexService & ArticleIndexService & LearningPathIndexService & DraftIndexService & DraftConceptIndexService &
NodeIndexService & TaxonomyApiClient & GrepApiClient & GrepIndexService & Props & ErrorHandling & MyNDLAApiClient &
TapirController =>
- val internController: InternController
+ lazy val internController: InternController
class InternController extends TapirController with StrictLogging {
import ErrorHelpers._
diff --git a/search-api/src/main/scala/no/ndla/searchapi/controller/SearchController.scala b/search-api/src/main/scala/no/ndla/searchapi/controller/SearchController.scala
index 8c04ba311c..aa09167537 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/controller/SearchController.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/controller/SearchController.scala
@@ -60,11 +60,9 @@ import no.ndla.common.model.domain.Priority
trait SearchController {
this: SearchApiClient & MultiSearchService & SearchConverterService & SearchService & MultiDraftSearchService &
FeideApiClient & Props & ErrorHandling & TapirController & GrepSearchService & GetSearchQueryParams =>
- val searchController: SearchController
+ lazy val searchController: SearchController
class SearchController extends TapirController {
- import props.*
-
override val serviceName: String = "search"
override val prefix: EndpointInput[Unit] = "search-api" / "v1" / serviceName
@@ -199,7 +197,7 @@ trait SearchController {
orFunction: => Try[(MultiSearchResultDTO, DynamicHeaders)]
): Try[(MultiSearchResultDTO, DynamicHeaders)] = {
scrollId match {
- case Some(scroll) if !InitialScrollContextKeywords.contains(scroll) =>
+ case Some(scroll) if !props.InitialScrollContextKeywords.contains(scroll) =>
for {
scrollResult <- scroller.scroll(scroll, language.code)
body = searchConverterService.toApiMultiSearchResult(scrollResult)
@@ -461,7 +459,7 @@ trait SearchController {
p match {
case None => SearchSettings.default
case Some(params) =>
- val shouldScroll = params.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = params.scrollId.exists(props.InitialScrollContextKeywords.contains)
SearchSettings(
query = params.query,
fallback = params.fallback.getOrElse(false),
@@ -498,7 +496,7 @@ trait SearchController {
p match {
case None => MultiDraftSearchSettings.default(user)
case Some(params) =>
- val shouldScroll = params.scrollId.exists(InitialScrollContextKeywords.contains)
+ val shouldScroll = params.scrollId.exists(props.InitialScrollContextKeywords.contains)
MultiDraftSearchSettings(
user = user,
query = params.query,
diff --git a/search-api/src/main/scala/no/ndla/searchapi/integration/ArticleApiClient.scala b/search-api/src/main/scala/no/ndla/searchapi/integration/ArticleApiClient.scala
index 83ba74f6af..849f82ea17 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/integration/ArticleApiClient.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/integration/ArticleApiClient.scala
@@ -13,7 +13,7 @@ import no.ndla.network.NdlaClient
trait ArticleApiClient {
this: NdlaClient & SearchApiClient =>
- val articleApiClient: ArticleApiClient
+ lazy val articleApiClient: ArticleApiClient
class ArticleApiClient(val baseUrl: String) extends SearchApiClient[Article] {
override val searchPath = "article-api/v2/articles"
diff --git a/search-api/src/main/scala/no/ndla/searchapi/integration/DraftApiClient.scala b/search-api/src/main/scala/no/ndla/searchapi/integration/DraftApiClient.scala
index a7d2f8acf7..bf109f8128 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/integration/DraftApiClient.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/integration/DraftApiClient.scala
@@ -14,7 +14,7 @@ import no.ndla.searchapi.Props
trait DraftApiClient {
this: NdlaClient & SearchApiClient & Props =>
- val draftApiClient: DraftApiClient
+ lazy val draftApiClient: DraftApiClient
class DraftApiClient(val baseUrl: String) extends SearchApiClient[Draft] {
override val searchPath = "draft-api/v1/drafts"
diff --git a/search-api/src/main/scala/no/ndla/searchapi/integration/DraftConceptApiClient.scala b/search-api/src/main/scala/no/ndla/searchapi/integration/DraftConceptApiClient.scala
index 19cfda6622..4144c2c9cc 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/integration/DraftConceptApiClient.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/integration/DraftConceptApiClient.scala
@@ -13,7 +13,7 @@ import no.ndla.network.NdlaClient
trait DraftConceptApiClient {
this: NdlaClient & SearchApiClient =>
- val draftConceptApiClient: DraftConceptApiClient
+ lazy val draftConceptApiClient: DraftConceptApiClient
class DraftConceptApiClient(val baseUrl: String) extends SearchApiClient[Concept] {
override val searchPath = "concept-api/v1/drafts"
diff --git a/search-api/src/main/scala/no/ndla/searchapi/integration/GrepApiClient.scala b/search-api/src/main/scala/no/ndla/searchapi/integration/GrepApiClient.scala
index cd9792e2ee..2e729bb60c 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/integration/GrepApiClient.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/integration/GrepApiClient.scala
@@ -12,7 +12,7 @@ import cats.implicits.*
import com.typesafe.scalalogging.StrictLogging
import io.circe.Decoder
import no.ndla.common.CirceUtil
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.common.logging.logTaskTime
import no.ndla.common.model.NDLADate
import no.ndla.network.NdlaClient
@@ -30,11 +30,10 @@ import scala.util.{Failure, Success, Try, Using}
trait GrepApiClient {
this: NdlaClient & Props =>
- val grepApiClient: GrepApiClient
+ lazy val grepApiClient: GrepApiClient
class GrepApiClient extends StrictLogging {
- import props.GrepApiUrl
- private val grepDumpUrl = s"$GrepApiUrl/kl06/v201906/dump/json"
+ private val grepDumpUrl = s"${props.GrepApiUrl}/kl06/v201906/dump/json"
private def readFile(file: File): Try[String] = Try {
Using.resource(scala.io.Source.fromFile(file)) { source =>
@@ -58,12 +57,16 @@ trait GrepApiClient {
private def getKjerneelementerLK20(dump: File): Try[List[GrepKjerneelement]] =
readGrepJsonFiles[GrepKjerneelement](dump, "kjerneelementer-lk20")
+
private def getKompetansemaalLK20(dump: File): Try[List[GrepKompetansemaal]] =
readGrepJsonFiles[GrepKompetansemaal](dump, "kompetansemaal-lk20")
+
private def getKompetansemaalsettLK20(dump: File): Try[List[GrepKompetansemaalSett]] =
readGrepJsonFiles[GrepKompetansemaalSett](dump, "kompetansemaalsett-lk20")
+
private def getTverrfagligeTemaerLK20(dump: File): Try[List[GrepTverrfagligTema]] =
readGrepJsonFiles[GrepTverrfagligTema](dump, "tverrfaglige-temaer-lk20")
+
private def getLaereplanerLK20(dump: File): Try[List[GrepLaererplan]] =
readGrepJsonFiles[GrepLaererplan](dump, "laereplaner-lk20")
@@ -91,18 +94,22 @@ trait GrepApiClient {
}
f.delete(): Unit
}
+
def release(resource: File): Unit = deleteDirectory(resource)
}
- private def getGrepBundleUncached: Try[GrepBundle] = logTaskTime("Fetching grep bundle", 30.seconds) {
- val date = NDLADate.now().toUTCEpochSecond
- val tempDirPath = Try(Files.createTempDirectory(s"grep-dump-$date")).?
- Using(tempDirPath.toFile) { tempDir =>
- val zippedDump = fetchDump(tempDir).?
- val unzippedDump = ZipUtil.unzip(zippedDump, tempDir, deleteArchive = true).?
- getBundleFromDump(unzippedDump).?
+ private def getGrepBundleUncached: Try[GrepBundle] =
+ logTaskTime("Fetching grep bundle", 30.seconds) {
+ permitTry {
+ val date = NDLADate.now().toUTCEpochSecond
+ val tempDirPath = Try(Files.createTempDirectory(s"grep-dump-$date")).?
+ Using(tempDirPath.toFile) { tempDir =>
+ val zippedDump = fetchDump(tempDir).?
+ val unzippedDump = ZipUtil.unzip(zippedDump, tempDir, deleteArchive = true).?
+ getBundleFromDump(unzippedDump).?
+ }
+ }
}
- }
case class GrepDumpDownloadException(message: String) extends RuntimeException(message) {
def withCause(cause: Throwable): GrepDumpDownloadException = {
diff --git a/search-api/src/main/scala/no/ndla/searchapi/integration/LearningPathApiClient.scala b/search-api/src/main/scala/no/ndla/searchapi/integration/LearningPathApiClient.scala
index a1416e7fed..2cc949012f 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/integration/LearningPathApiClient.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/integration/LearningPathApiClient.scala
@@ -22,7 +22,7 @@ import scala.util.{Failure, Success, Try}
trait LearningPathApiClient {
this: NdlaClient & StrictLogging & SearchApiClient =>
- val learningPathApiClient: LearningPathApiClient
+ lazy val learningPathApiClient: LearningPathApiClient
class LearningPathApiClient(val baseUrl: String) extends SearchApiClient[LearningPath] {
override val searchPath = "learningpath-api/v2/learningpaths"
diff --git a/search-api/src/main/scala/no/ndla/searchapi/integration/TaxonomyApiClient.scala b/search-api/src/main/scala/no/ndla/searchapi/integration/TaxonomyApiClient.scala
index 9e07ac4e6a..458839e214 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/integration/TaxonomyApiClient.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/integration/TaxonomyApiClient.scala
@@ -30,12 +30,10 @@ import scala.util.{Failure, Success, Try}
trait TaxonomyApiClient {
this: NdlaClient & Props =>
- val taxonomyApiClient: TaxonomyApiClient
+ lazy val taxonomyApiClient: TaxonomyApiClient
class TaxonomyApiClient extends StrictLogging {
- import props.TaxonomyUrl
-
- private val TaxonomyApiEndpoint = s"$TaxonomyUrl/v1"
+ private val TaxonomyApiEndpoint = s"${props.TaxonomyUrl}/v1"
private val timeoutSeconds = 600.seconds
private def getNodes(shouldUsePublishedTax: Boolean): Try[ListBuffer[Node]] =
get[ListBuffer[Node]](
diff --git a/search-api/src/main/scala/no/ndla/searchapi/integration/ZipUtil.scala b/search-api/src/main/scala/no/ndla/searchapi/integration/ZipUtil.scala
index fe39cf165a..bc029bb65f 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/integration/ZipUtil.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/integration/ZipUtil.scala
@@ -32,7 +32,9 @@ object ZipUtil {
zis.close()
fis.close()
- if (deleteArchive) zipFile.delete()
+ if (deleteArchive) {
+ val _ = zipFile.delete()
+ }
targetDir
}
diff --git a/search-api/src/main/scala/no/ndla/searchapi/model/api/grep/GrepStatusDTO.scala b/search-api/src/main/scala/no/ndla/searchapi/model/api/grep/GrepStatusDTO.scala
index 626da96ec5..3463ddf4bc 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/model/api/grep/GrepStatusDTO.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/model/api/grep/GrepStatusDTO.scala
@@ -11,7 +11,7 @@ package no.ndla.searchapi.model.api.grep
import enumeratum.*
import io.circe.syntax.EncoderOps
import io.circe.{Decoder, Encoder}
-import no.ndla.common.implicits.OptionImplicit
+import no.ndla.common.implicits.*
import sttp.tapir.Schema
import sttp.tapir.codec.enumeratum.*
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/ConverterService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/ConverterService.scala
index 3c2070021b..9942a62a00 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/ConverterService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/ConverterService.scala
@@ -31,11 +31,9 @@ import no.ndla.searchapi.model.domain.*
trait ConverterService {
this: Props =>
- val converterService: ConverterService
+ lazy val converterService: ConverterService
class ConverterService {
- import props.Domain
-
def searchResultToApiModel(searchResults: ApiSearchResults): SearchResultsDTO = {
searchResults match {
case a: ArticleApiSearchResults => articleSearchResultsToApi(a)
@@ -101,7 +99,7 @@ trait ConverterService {
private def imageSearchResultToApi(image: ImageApiSearchResult): ImageResultDTO = {
val scheme = ApplicationUrl.get.schemeOption.getOrElse("https://")
- val host = ApplicationUrl.get.hostOption.map(_.toString).getOrElse(Domain)
+ val host = ApplicationUrl.get.hostOption.map(_.toString).getOrElse(props.Domain)
val previewUrl = image.previewUrl.withHost(host).withScheme(scheme)
val metaUrl = image.metaUrl.withHost(host).withScheme(scheme)
@@ -129,7 +127,7 @@ trait ConverterService {
private def audioSearchResultToApi(audio: AudioApiSearchResult): AudioResultDTO = {
val scheme = ApplicationUrl.get.schemeOption.getOrElse("https://")
- val host = ApplicationUrl.get.hostOption.map(_.toString).getOrElse(Domain)
+ val host = ApplicationUrl.get.hostOption.map(_.toString).getOrElse(props.Domain)
val url = audio.url.withHost(host).withScheme(scheme).toString
AudioResultDTO(
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/ArticleIndexService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/ArticleIndexService.scala
index 046a577196..46b194f63c 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/ArticleIndexService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/ArticleIndexService.scala
@@ -18,20 +18,19 @@ import no.ndla.common.CirceUtil
import no.ndla.common.model.api.search.SearchType
import no.ndla.common.model.domain.article.Article
import no.ndla.searchapi.Props
-import no.ndla.searchapi.integration.ArticleApiClient
+import no.ndla.searchapi.integration.{ArticleApiClient, SearchApiClient}
import no.ndla.searchapi.model.domain.IndexingBundle
import scala.util.Try
trait ArticleIndexService {
- this: SearchConverterService & IndexService & ArticleApiClient & Props =>
- val articleIndexService: ArticleIndexService
+ this: SearchConverterService & IndexService & ArticleApiClient & Props & SearchApiClient =>
+ lazy val articleIndexService: ArticleIndexService
class ArticleIndexService extends StrictLogging with IndexService[Article] {
- import props.SearchIndex
- override val documentType: String = "article"
- override val searchIndex: String = SearchIndex(SearchType.Articles)
- override val apiClient: ArticleApiClient = articleApiClient
+ override val documentType: String = "article"
+ override val searchIndex: String = props.SearchIndex(SearchType.Articles)
+ override val apiClient: SearchApiClient[Article] = articleApiClient
override def createIndexRequest(
domainModel: Article,
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftConceptIndexService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftConceptIndexService.scala
index 6fbd8df76d..42ad99eb09 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftConceptIndexService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftConceptIndexService.scala
@@ -17,21 +17,20 @@ import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.CirceUtil
import no.ndla.common.model.api.search.SearchType
import no.ndla.searchapi.Props
-import no.ndla.searchapi.integration.DraftConceptApiClient
+import no.ndla.searchapi.integration.{DraftConceptApiClient, SearchApiClient}
import no.ndla.searchapi.model.domain.IndexingBundle
import no.ndla.common.model.domain.concept.Concept
import scala.util.Try
trait DraftConceptIndexService {
- this: SearchConverterService & IndexService & DraftConceptApiClient & Props =>
- val draftConceptIndexService: DraftConceptIndexService
+ this: SearchConverterService & IndexService & DraftConceptApiClient & Props & SearchApiClient =>
+ lazy val draftConceptIndexService: DraftConceptIndexService
- class DraftConceptIndexService extends StrictLogging with IndexService[Concept] {
- import props.SearchIndex
- override val documentType: String = "concept"
- override val searchIndex: String = SearchIndex(SearchType.Concepts)
- override val apiClient: DraftConceptApiClient = draftConceptApiClient
+ class DraftConceptIndexService extends IndexService[Concept] with StrictLogging {
+ override val documentType: String = "concept"
+ override val searchIndex: String = props.SearchIndex(SearchType.Concepts)
+ override val apiClient: SearchApiClient[Concept] = draftConceptApiClient
override def createIndexRequest(
domainModel: Concept,
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftIndexService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftIndexService.scala
index 0adbb155da..32ef025feb 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftIndexService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/DraftIndexService.scala
@@ -18,20 +18,19 @@ import no.ndla.common.CirceUtil
import no.ndla.common.model.api.search.SearchType
import no.ndla.common.model.domain.draft.Draft
import no.ndla.searchapi.Props
-import no.ndla.searchapi.integration.DraftApiClient
+import no.ndla.searchapi.integration.{DraftApiClient, SearchApiClient}
import no.ndla.searchapi.model.domain.IndexingBundle
import scala.util.Try
trait DraftIndexService {
- this: SearchConverterService & IndexService & DraftApiClient & Props =>
- import props.SearchIndex
- val draftIndexService: DraftIndexService
+ this: SearchConverterService & IndexService & DraftApiClient & Props & SearchApiClient =>
+ lazy val draftIndexService: DraftIndexService
class DraftIndexService extends StrictLogging with IndexService[Draft] {
- override val documentType: String = "draft"
- override val searchIndex: String = SearchIndex(SearchType.Drafts)
- override val apiClient: DraftApiClient = draftApiClient
+ override val documentType: String = "draft"
+ override val searchIndex: String = props.SearchIndex(SearchType.Drafts)
+ override val apiClient: SearchApiClient[Draft] = draftApiClient
override def createIndexRequest(
domainModel: Draft,
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepIndexService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepIndexService.scala
index 5327b43f51..68c4134bcb 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepIndexService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepIndexService.scala
@@ -9,7 +9,7 @@
package no.ndla.searchapi.service.search
import cats.implicits.toTraverseOps
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import com.sksamuel.elastic4s.ElasticDsl.*
import com.sksamuel.elastic4s.fields.ObjectField
import com.sksamuel.elastic4s.requests.indexes.IndexRequest
@@ -26,12 +26,11 @@ import scala.util.{Success, Try}
trait GrepIndexService {
this: SearchConverterService & IndexService & Props & GrepApiClient =>
- val grepIndexService: GrepIndexService
+ lazy val grepIndexService: GrepIndexService
class GrepIndexService extends BulkIndexingService with StrictLogging {
- import props.SearchIndex
override val documentType: String = "grep"
- override val searchIndex: String = SearchIndex(SearchType.Grep)
+ override val searchIndex: String = props.SearchIndex(SearchType.Grep)
override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
override def getMapping: MappingDefinition = {
@@ -55,7 +54,7 @@ trait GrepIndexService {
}
}
- def createIndexRequest(grepElement: GrepElement, indexName: String): Try[IndexRequest] = {
+ def createIndexRequest(grepElement: GrepElement, indexName: String): Try[IndexRequest] = permitTry {
val searchable = searchConverterService.asSearchableGrep(grepElement).?
val source = CirceUtil.toJsonString(searchable)
Success(indexInto(indexName).doc(source).id(grepElement.kode))
@@ -68,7 +67,7 @@ trait GrepIndexService {
.flatten
}
- def sendToElastic(grepBundle: Option[GrepBundle], indexName: String): Try[BulkIndexResult] = {
+ def sendToElastic(grepBundle: Option[GrepBundle], indexName: String): Try[BulkIndexResult] = permitTry {
val bundle = (grepBundle match {
case Some(value) => Success(value)
case None => grepApiClient.getGrepBundle()
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepSearchService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepSearchService.scala
index fd30f13341..7b3da32260 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepSearchService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/GrepSearchService.scala
@@ -17,7 +17,7 @@ import com.sksamuel.elastic4s.requests.searches.sort.SortOrder.{Asc, Desc}
import com.sksamuel.elastic4s.requests.searches.{SearchHit, SearchRequest, SearchResponse}
import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.CirceUtil
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.common.model.api.search.SearchType
import no.ndla.language.Language.AllLanguages
import no.ndla.language.model.Iso639
@@ -35,15 +35,14 @@ import no.ndla.searchapi.model.grep.{
}
import no.ndla.searchapi.model.search.SearchableGrepElement
-import scala.util.{Failure, Success, Try}
+import scala.util.{Failure, Success, Try, boundary}
trait GrepSearchService {
this: Props & SearchService & GrepIndexService & BaseIndexService & Elastic4sClient & SearchConverterService =>
- val grepSearchService: GrepSearchService
+ lazy val grepSearchService: GrepSearchService
class GrepSearchService extends SearchService with StrictLogging {
- import props.SearchIndex
- override val searchIndex: List[String] = List(SearchType.Grep).map(SearchIndex)
+ override val searchIndex: List[String] = List(SearchType.Grep).map(props.SearchIndex)
override val indexServices: List[BaseIndexService] = List(grepIndexService)
def grepSortDefinition(maybeSort: Option[GrepSortDTO], language: String): FieldSort = maybeSort match {
@@ -158,7 +157,7 @@ trait GrepSearchService {
executeAsSearchableGreps(searchToExecute)
}
- def searchGreps(input: GrepSearchInputDTO): Try[GrepSearchResultsDTO] = {
+ def searchGreps(input: GrepSearchInputDTO): Try[GrepSearchResultsDTO] = permitTry {
val searchLanguage = input.language match {
case Some(lang) if Iso639.get(lang).isSuccess => lang
case _ => AllLanguages
@@ -204,7 +203,7 @@ trait GrepSearchService {
CirceUtil.tryParseAs[SearchableGrepElement](jsonString)
}
- private def hitToResult(hit: SearchHit, language: String): Try[GrepResultDTO] = {
+ private def hitToResult(hit: SearchHit, language: String): Try[GrepResultDTO] = permitTry {
val searchable = hitToSearchable(hit).?
GrepResultDTO.fromSearchable(searchable, language)
}
@@ -213,32 +212,35 @@ trait GrepSearchService {
response.result.hits.hits.toList.traverse { hit => f(hit) }
}
- private def getCoreElementReplacement(core: GrepKjerneelement): Try[String] = {
- val lpCode = core.`tilhoerer-laereplan`.kode
- val foundLp = getSingleCodeById(lpCode) match {
- case Success(Some(lp)) => lp
- case Failure(ex) => return Failure(ex)
- case Success(None) =>
- logger.warn(s"Could not find læreplan for core element: ${core.kode} (LP: $lpCode)")
- return Success(core.kode)
- }
+ private def getCoreElementReplacement(core: GrepKjerneelement): Try[String] = permitTry {
+ boundary {
+ val lpCode = core.`tilhoerer-laereplan`.kode
+ val foundLp = getSingleCodeById(lpCode) match {
+ case Success(Some(lp)) => lp
+ case Failure(ex) => boundary.break(Failure(ex))
+ case Success(None) =>
+ logger.warn(s"Could not find læreplan for core element: ${core.kode} (LP: $lpCode)")
+ boundary.break(Success(core.kode))
+ }
- val domainObject = foundLp.domainObject match {
- case lp: GrepLaererplan => lp
- case _ =>
- val msg =
- s"Got unexpected domain object when looking up læreplan (${foundLp.code}) for replacement for core element (${core.kode})"
- logger.error(msg)
- return Failure(new RuntimeException(msg))
- }
- getLaererplanReplacement(domainObject) match {
- case None => Success(core.kode)
- case Some(replacementPlan) =>
- val elementsInPlan = elementsWithLpCode(replacementPlan).?
- val foundReplacement = elementsInPlan.find { x =>
- core.tittel.tekst == x.domainObject.getTitle
- }
- Success(foundReplacement.map(_.code).getOrElse(core.kode))
+ val domainObject = foundLp.domainObject match {
+ case lp: GrepLaererplan => lp
+ case _ =>
+ val msg =
+ s"Got unexpected domain object when looking up læreplan (${foundLp.code}) for replacement for core element (${core.kode})"
+ logger.error(msg)
+ boundary.break(Failure(new RuntimeException(msg)))
+ }
+
+ getLaererplanReplacement(domainObject) match {
+ case None => Success(core.kode)
+ case Some(replacementPlan) =>
+ val elementsInPlan = elementsWithLpCode(replacementPlan).?
+ val foundReplacement = elementsInPlan.find { x =>
+ core.tittel.tekst == x.domainObject.getTitle
+ }
+ Success(foundReplacement.map(_.code).getOrElse(core.kode))
+ }
}
}
@@ -252,7 +254,7 @@ trait GrepSearchService {
executeAsSearchableGreps(searchToExecute)
}
- def getKompetansemaalReplacement(goal: GrepKompetansemaal): Try[String] = {
+ def getKompetansemaalReplacement(goal: GrepKompetansemaal): Try[String] = permitTry {
val reuseOf = getReuseOf(goal.kode).?
reuseOf match {
case head :: Nil =>
@@ -289,7 +291,7 @@ trait GrepSearchService {
result.map(r => code.code -> r)
}
- def getReplacements(codes: List[String]): Try[Map[String, String]] = {
+ def getReplacements(codes: List[String]): Try[Map[String, String]] = permitTry {
val foundOldCodes = getCodesById(codes).?
val foundAllCodes = foundOldCodes.map(_.code).toSet
val missingCodes = codes.toSet.diff(foundAllCodes)
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/IndexService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/IndexService.scala
index 7a931cbc48..b0248c6e9e 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/IndexService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/IndexService.scala
@@ -28,7 +28,7 @@ trait IndexService {
this: Elastic4sClient & SearchApiClient & BaseIndexService & TaxonomyApiClient & GrepApiClient & Props &
MyNDLAApiClient & SearchLanguage =>
- trait BulkIndexingService extends BaseIndexService {
+ abstract class BulkIndexingService extends BaseIndexService {
protected def languageValuesMapping(name: String, keepRaw: Boolean = false): Seq[ElasticField] = {
val subfields = List(
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/LearningPathIndexService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/LearningPathIndexService.scala
index 9e5f17b735..0807e37f2e 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/LearningPathIndexService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/LearningPathIndexService.scala
@@ -18,20 +18,19 @@ import no.ndla.common.CirceUtil
import no.ndla.common.model.api.search.SearchType
import no.ndla.common.model.domain.learningpath.LearningPath
import no.ndla.searchapi.Props
-import no.ndla.searchapi.integration.LearningPathApiClient
+import no.ndla.searchapi.integration.{LearningPathApiClient, SearchApiClient}
import no.ndla.searchapi.model.domain.IndexingBundle
import scala.util.Try
trait LearningPathIndexService {
- this: SearchConverterService & IndexService & LearningPathApiClient & Props =>
- import props.SearchIndex
- val learningPathIndexService: LearningPathIndexService
+ this: SearchConverterService & IndexService & LearningPathApiClient & Props & SearchApiClient =>
+ lazy val learningPathIndexService: LearningPathIndexService
class LearningPathIndexService extends StrictLogging with IndexService[LearningPath] {
- override val documentType: String = "learningpath"
- override val searchIndex: String = SearchIndex(SearchType.LearningPaths)
- override val apiClient: LearningPathApiClient = learningPathApiClient
+ override val documentType: String = "learningpath"
+ override val searchIndex: String = props.SearchIndex(SearchType.LearningPaths)
+ override val apiClient: SearchApiClient[LearningPath] = learningPathApiClient
override def createIndexRequest(
domainModel: LearningPath,
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiDraftSearchService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiDraftSearchService.scala
index f1f122565b..e13b04f652 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiDraftSearchService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiDraftSearchService.scala
@@ -16,17 +16,16 @@ import com.sksamuel.elastic4s.requests.searches.queries.{Query, RangeQuery}
import com.sksamuel.elastic4s.requests.searches.term.TermsQuery
import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.errors.{ValidationException, ValidationMessage}
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.common.model.NDLADate
import no.ndla.common.model.api.search.{LearningResourceType, SearchType}
-import no.ndla.common.model.domain.Content
import no.ndla.common.model.domain.draft.DraftStatus
import no.ndla.common.model.domain.learningpath.LearningPathStatus
import no.ndla.language.Language.AllLanguages
import no.ndla.language.model.Iso639
import no.ndla.network.tapir.auth.TokenUser
import no.ndla.search.AggregationBuilder.{buildTermsAggregation, getAggregationsFromResult}
-import no.ndla.search.Elastic4sClient
+import no.ndla.search.{BaseIndexService, Elastic4sClient}
import no.ndla.searchapi.Props
import no.ndla.searchapi.model.api.{ErrorHandling, SubjectAggregationDTO, SubjectAggregationsDTO}
import no.ndla.searchapi.model.domain.SearchResult
@@ -36,18 +35,17 @@ import scala.util.{Failure, Success, Try}
trait MultiDraftSearchService {
this: Elastic4sClient & SearchConverterService & IndexService & SearchService & DraftIndexService &
- LearningPathIndexService & Props & ErrorHandling & DraftConceptIndexService =>
- val multiDraftSearchService: MultiDraftSearchService
+ LearningPathIndexService & Props & ErrorHandling & DraftConceptIndexService & BaseIndexService =>
+ lazy val multiDraftSearchService: MultiDraftSearchService
class MultiDraftSearchService extends StrictLogging with SearchService with TaxonomyFiltering {
- import props.{ElasticSearchScrollKeepAlive, SearchIndex}
override val searchIndex: List[String] = List(
SearchType.Drafts,
SearchType.LearningPaths,
SearchType.Concepts
- ).map(SearchIndex)
+ ).map(props.SearchIndex)
- override val indexServices: List[IndexService[? <: Content]] = List(
+ override val indexServices: List[BaseIndexService] = List(
draftIndexService,
learningPathIndexService,
draftConceptIndexService
@@ -130,7 +128,7 @@ trait MultiDraftSearchService {
settings.resultTypes match {
case Some(list) if list.nonEmpty =>
val idxs = list.map { st =>
- val index = SearchIndex(st)
+ val index = props.SearchIndex(st)
val isValidIndex = searchIndex.contains(index)
if (isValidIndex) Right(index)
@@ -150,7 +148,7 @@ trait MultiDraftSearchService {
if (errors.nonEmpty) Failure(new ValidationException(s"Got invalid `resultTypes` for endpoint", errors))
else Success(idxs.collect { case Right(i) => i })
- case _ => Success(List(SearchType.Drafts, SearchType.LearningPaths).map(SearchIndex))
+ case _ => Success(List(SearchType.Drafts, SearchType.LearningPaths).map(props.SearchIndex))
}
}
@@ -217,7 +215,7 @@ trait MultiDraftSearchService {
e4sClient.execute(searchToExecute).map(_.result.totalHits)
}
- def executeSearch(settings: MultiDraftSearchSettings, baseQuery: BoolQuery): Try[SearchResult] = {
+ def executeSearch(settings: MultiDraftSearchSettings, baseQuery: BoolQuery): Try[SearchResult] = permitTry {
val searchLanguage = settings.language match {
case lang if Iso639.get(lang).isSuccess && !settings.fallback => lang
case _ => AllLanguages
@@ -240,7 +238,7 @@ trait MultiDraftSearchService {
// Only add scroll param if it is first page
val searchWithScroll =
if (pagination.startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiSearchService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiSearchService.scala
index 8b4bf8ebf4..5475efe357 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiSearchService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/MultiSearchService.scala
@@ -17,7 +17,7 @@ import com.sksamuel.elastic4s.requests.searches.queries.compound.BoolQuery
import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.CirceUtil
import no.ndla.common.errors.{ValidationException, ValidationMessage}
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.common.model.api.search.SearchType
import no.ndla.common.model.domain.Availability
import no.ndla.language.Language.AllLanguages
@@ -25,7 +25,7 @@ import no.ndla.language.model.Iso639
import no.ndla.mapping.License
import no.ndla.network.tapir.NonEmptyString
import no.ndla.search.AggregationBuilder.{buildTermsAggregation, getAggregationsFromResult}
-import no.ndla.search.Elastic4sClient
+import no.ndla.search.{BaseIndexService, Elastic4sClient}
import no.ndla.searchapi.Props
import no.ndla.searchapi.model.api.ErrorHandling
import no.ndla.searchapi.model.domain.SearchResult
@@ -36,23 +36,21 @@ import scala.util.{Failure, Success, Try}
trait MultiSearchService {
this: Elastic4sClient & SearchConverterService & SearchService & IndexService & ArticleIndexService &
- LearningPathIndexService & Props & ErrorHandling & NodeIndexService =>
+ LearningPathIndexService & Props & ErrorHandling & NodeIndexService & BaseIndexService =>
- val multiSearchService: MultiSearchService
-
- class MultiSearchService extends StrictLogging with SearchService with TaxonomyFiltering {
- import props.{ElasticSearchScrollKeepAlive, SearchIndex}
+ lazy val multiSearchService: MultiSearchService
+ class MultiSearchService extends SearchService with StrictLogging with TaxonomyFiltering {
override val searchIndex: List[String] =
- List(SearchType.Articles, SearchType.LearningPaths, SearchType.Nodes).map(SearchIndex)
- override val indexServices: List[BulkIndexingService] = List(
+ List(SearchType.Articles, SearchType.LearningPaths, SearchType.Nodes).map(props.SearchIndex)
+ override val indexServices: List[BaseIndexService] = List(
articleIndexService,
learningPathIndexService,
nodeIndexService
)
private def getIndexFilter(indexes: List[SearchType]): Query = {
- val indexNames = indexes.map(SearchIndex)
+ val indexNames = indexes.map(props.SearchIndex)
termsQuery("_index", indexNames)
}
@@ -137,7 +135,7 @@ trait MultiSearchService {
settings.resultTypes match {
case Some(list) if list.nonEmpty =>
val idxs = list.map { st =>
- val index = SearchIndex(st)
+ val index = props.SearchIndex(st)
val isValidIndex = searchIndex.contains(index)
if (isValidIndex) Right(index)
@@ -157,13 +155,13 @@ trait MultiSearchService {
if (errors.nonEmpty) Failure(new ValidationException(s"Got invalid `resultTypes` for endpoint", errors))
else Success(idxs.collect { case Right(i) => i })
- case _ => Success(List(SearchType.Articles, SearchType.LearningPaths).map(SearchIndex))
+ case _ => Success(List(SearchType.Articles, SearchType.LearningPaths).map(props.SearchIndex))
}
}
- private def logShardErrors(response: RequestSuccess[SearchResponse]) = {
+ private def logShardErrors(response: RequestSuccess[SearchResponse]): Unit = {
if (response.result.shards.failed > 0) {
- response.body.map { body =>
+ val _ = response.body.map { body =>
CirceUtil.tryParse(body) match {
case Failure(ex) =>
logger.error(s"Got error parsing search response: $body", ex)
@@ -180,7 +178,7 @@ trait MultiSearchService {
}
}
- def executeSearch(settings: SearchSettings, filteredSearch: BoolQuery): Try[SearchResult] = {
+ def executeSearch(settings: SearchSettings, filteredSearch: BoolQuery): Try[SearchResult] = permitTry {
val searchLanguage = settings.language match {
case lang if Iso639.get(lang).isSuccess && !settings.fallback => lang
case _ => AllLanguages
@@ -203,7 +201,7 @@ trait MultiSearchService {
// Only add scroll param if it is first page
val searchWithScroll =
if (pagination.startAt == 0 && settings.shouldScroll) {
- searchToExecute.scroll(ElasticSearchScrollKeepAlive)
+ searchToExecute.scroll(props.ElasticSearchScrollKeepAlive)
} else { searchToExecute }
e4sClient.execute(searchWithScroll) match {
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/NodeIndexService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/NodeIndexService.scala
index 824b933085..3c0409be33 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/NodeIndexService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/NodeIndexService.scala
@@ -31,11 +31,11 @@ import scala.util.{Failure, Success, Try}
trait NodeIndexService {
this: SearchConverterService & IndexService & Props & TaxonomyApiClient & ArticleApiClient & FrontpageApiClient &
GrepApiClient =>
- val nodeIndexService: NodeIndexService
- class NodeIndexService extends StrictLogging with BulkIndexingService {
- import props.SearchIndex
+ lazy val nodeIndexService: NodeIndexService
+
+ class NodeIndexService extends BulkIndexingService with StrictLogging {
override val documentType: String = "nodes"
- override val searchIndex: String = SearchIndex(SearchType.Nodes)
+ override val searchIndex: String = props.SearchIndex(SearchType.Nodes)
override val MaxResultWindowOption: Int = props.ElasticSearchIndexMaxResultWindow
override def getMapping: MappingDefinition = {
@@ -118,7 +118,7 @@ trait NodeIndexService {
.flatten
}
- def sendToElastic(indexingBundle: IndexingBundle, indexName: String): Try[BulkIndexResult] = {
+ def sendToElastic(indexingBundle: IndexingBundle, indexName: String): Try[BulkIndexResult] = permitTry {
val taxBundle = indexingBundle.taxonomyBundle match {
case None => taxonomyApiClient.getTaxonomyBundle(true).?
case Some(value) => value
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchConverterService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchConverterService.scala
index b4b60c42ab..16e5da8958 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchConverterService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchConverterService.scala
@@ -77,7 +77,7 @@ import scala.util.{Failure, Success, Try}
trait SearchConverterService {
this: DraftApiClient & TaxonomyApiClient & ConverterService & Props & MyNDLAApiClient & SearchLanguage =>
- val searchConverterService: SearchConverterService
+ lazy val searchConverterService: SearchConverterService
class SearchConverterService extends StrictLogging {
@@ -119,7 +119,7 @@ trait SearchConverterService {
})
}
- def nodeHitAsMultiSummary(hit: SearchHit, language: String): Try[NodeHitDTO] = {
+ def nodeHitAsMultiSummary(hit: SearchHit, language: String): Try[NodeHitDTO] = permitTry {
val searchableNode = CirceUtil.tryParseAs[SearchableNode](hit.sourceAsString).?
val title = searchableNode.title.getLanguageOrDefault(language).getOrElse("")
val url = searchableNode.url.map(urlPath => s"${props.ndlaFrontendUrl}$urlPath")
@@ -368,63 +368,68 @@ trait SearchConverterService {
)
}
- def asSearchableLearningPath(lp: LearningPath, indexingBundle: IndexingBundle): Try[SearchableLearningPath] = {
- val taxonomyContexts = indexingBundle.taxonomyBundle match {
- case Some(bundle) =>
- Success(getTaxonomyContexts(lp.id.get, "learningpath", bundle, filterVisibles = true, filterContexts = false))
- case None =>
- taxonomyApiClient.getTaxonomyContext(
- s"urn:learningpath:${lp.id.get}",
- filterVisibles = true,
- filterContexts = false,
- shouldUsePublishedTax = true
- )
- }
-
- val favorited = getFavoritedCountFor(indexingBundle, lp.id.get.toString, List(MyNDLAResourceType.Learningpath)).?
+ def asSearchableLearningPath(lp: LearningPath, indexingBundle: IndexingBundle): Try[SearchableLearningPath] =
+ permitTry {
+ val taxonomyContexts = indexingBundle.taxonomyBundle match {
+ case Some(bundle) =>
+ Success(
+ getTaxonomyContexts(lp.id.get, "learningpath", bundle, filterVisibles = true, filterContexts = false)
+ )
+ case None =>
+ taxonomyApiClient.getTaxonomyContext(
+ s"urn:learningpath:${lp.id.get}",
+ filterVisibles = true,
+ filterContexts = false,
+ shouldUsePublishedTax = true
+ )
+ }
- val supportedLanguages = getSupportedLanguages(lp.title, lp.description).toList
- val defaultTitle = lp.title.sortBy(title => ISO639.languagePriority.reverse.indexOf(title.language)).lastOption
- val license = api.learningpath.CopyrightDTO(
- asLearningPathApiLicense(lp.copyright.license),
- lp.copyright.contributors.map(c => AuthorDTO(c.`type`, c.name))
- )
- val contexts = asSearchableTaxonomyContexts(taxonomyContexts.getOrElse(List.empty))
+ val favorited =
+ getFavoritedCountFor(indexingBundle, lp.id.get.toString, List(MyNDLAResourceType.Learningpath)).?
- Success(
- SearchableLearningPath(
- id = lp.id.get,
- title = model.SearchableLanguageValues(lp.title.map(t => LanguageValue(t.language, t.title))),
- content = model.SearchableLanguageValues(
- lp.title.map(t => LanguageValue(t.language, "*"))
- ),
- description =
- model.SearchableLanguageValues(lp.description.map(d => LanguageValue(d.language, d.description))),
- coverPhotoId = lp.coverPhotoId,
- duration = lp.duration,
- status = lp.status.toString,
- owner = lp.owner,
- verificationStatus = lp.verificationStatus.toString,
- lastUpdated = lp.lastUpdated,
- defaultTitle = defaultTitle.map(_.title),
- tags = SearchableLanguageList(lp.tags.map(tag => LanguageValue(tag.language, tag.tags))),
- learningsteps = lp.learningsteps.getOrElse(Seq.empty).map(asSearchableLearningStep).toList,
- license = lp.copyright.license,
- copyright = license,
- isBasedOn = lp.isBasedOn,
- supportedLanguages = supportedLanguages,
- authors = lp.copyright.contributors.map(_.name).toList,
- context = contexts.find(_.isPrimary),
- contexts = contexts,
- contextids =
- indexingBundle.taxonomyBundle.map(getTaxonomyContexids(lp.id.get, "learningpath", _)).getOrElse(List.empty),
- favorited = favorited,
- learningResourceType = LearningResourceType.LearningPath,
- typeName = getTypeNames(LearningResourceType.LearningPath),
- priority = lp.priority
+ val supportedLanguages = getSupportedLanguages(lp.title, lp.description).toList
+ val defaultTitle = lp.title.sortBy(title => ISO639.languagePriority.reverse.indexOf(title.language)).lastOption
+ val license = api.learningpath.CopyrightDTO(
+ asLearningPathApiLicense(lp.copyright.license),
+ lp.copyright.contributors.map(c => AuthorDTO(c.`type`, c.name))
)
- )
- }
+ val contexts = asSearchableTaxonomyContexts(taxonomyContexts.getOrElse(List.empty))
+
+ Success(
+ SearchableLearningPath(
+ id = lp.id.get,
+ title = model.SearchableLanguageValues(lp.title.map(t => LanguageValue(t.language, t.title))),
+ content = model.SearchableLanguageValues(
+ lp.title.map(t => LanguageValue(t.language, "*"))
+ ),
+ description =
+ model.SearchableLanguageValues(lp.description.map(d => LanguageValue(d.language, d.description))),
+ coverPhotoId = lp.coverPhotoId,
+ duration = lp.duration,
+ status = lp.status.toString,
+ owner = lp.owner,
+ verificationStatus = lp.verificationStatus.toString,
+ lastUpdated = lp.lastUpdated,
+ defaultTitle = defaultTitle.map(_.title),
+ tags = SearchableLanguageList(lp.tags.map(tag => LanguageValue(tag.language, tag.tags))),
+ learningsteps = lp.learningsteps.getOrElse(Seq.empty).map(asSearchableLearningStep).toList,
+ license = lp.copyright.license,
+ copyright = license,
+ isBasedOn = lp.isBasedOn,
+ supportedLanguages = supportedLanguages,
+ authors = lp.copyright.contributors.map(_.name).toList,
+ context = contexts.find(_.isPrimary),
+ contexts = contexts,
+ contextids = indexingBundle.taxonomyBundle
+ .map(getTaxonomyContexids(lp.id.get, "learningpath", _))
+ .getOrElse(List.empty),
+ favorited = favorited,
+ learningResourceType = LearningResourceType.LearningPath,
+ typeName = getTypeNames(LearningResourceType.LearningPath),
+ priority = lp.priority
+ )
+ )
+ }
private def getFavoritedCountFor(
indexingBundle: IndexingBundle,
@@ -440,7 +445,7 @@ trait SearchConverterService {
}
}
- def asSearchableConcept(c: Concept, indexingBundle: IndexingBundle): Try[SearchableConcept] = {
+ def asSearchableConcept(c: Concept, indexingBundle: IndexingBundle): Try[SearchableConcept] = permitTry {
val title = model.SearchableLanguageValues(c.title.map(t => LanguageValue(t.language, toPlaintext(t.title))))
val content = SearchableLanguageValues.fromFieldsMap(c.content)(toPlaintext)
val tags = SearchableLanguageList.fromFields(c.tags)
@@ -483,7 +488,7 @@ trait SearchConverterService {
)
}
- def asSearchableDraft(draft: Draft, indexingBundle: IndexingBundle): Try[SearchableDraft] = {
+ def asSearchableDraft(draft: Draft, indexingBundle: IndexingBundle): Try[SearchableDraft] = permitTry {
val taxonomyContexts = {
val draftId = draft.id.get
indexingBundle.taxonomyBundle match {
@@ -727,7 +732,7 @@ trait SearchConverterService {
hit: SearchHit,
language: String,
filterInactive: Boolean
- ): Try[MultiSearchSummaryDTO] = {
+ ): Try[MultiSearchSummaryDTO] = permitTry {
val searchableArticle = CirceUtil.tryParseAs[SearchableArticle](hit.sourceAsString).?
val context = searchableArticle.context.map(c => searchableContextToApiContext(c, language))
@@ -801,7 +806,7 @@ trait SearchConverterService {
hit: SearchHit,
language: String,
filterInactive: Boolean
- ): Try[MultiSearchSummaryDTO] = {
+ ): Try[MultiSearchSummaryDTO] = permitTry {
val searchableDraft = CirceUtil.tryParseAs[SearchableDraft](hit.sourceAsString).?
val context = searchableDraft.context.map(c => searchableContextToApiContext(c, language))
@@ -889,7 +894,7 @@ trait SearchConverterService {
hit: SearchHit,
language: String,
filterInactive: Boolean
- ): Try[MultiSearchSummaryDTO] = {
+ ): Try[MultiSearchSummaryDTO] = permitTry {
val searchableLearningPath = CirceUtil.tryParseAs[SearchableLearningPath](hit.sourceAsString).?
val context = searchableLearningPath.context.map(c => searchableContextToApiContext(c, language))
@@ -958,7 +963,7 @@ trait SearchConverterService {
)
}
- def conceptHitAsMultiSummary(hit: SearchHit, language: String): Try[MultiSearchSummaryDTO] = {
+ def conceptHitAsMultiSummary(hit: SearchHit, language: String): Try[MultiSearchSummaryDTO] = permitTry {
val searchableConcept = CirceUtil.tryParseAs[SearchableConcept](hit.sourceAsString).?
val titles =
diff --git a/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchService.scala b/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchService.scala
index 8241c35cf6..f397aee3da 100644
--- a/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchService.scala
+++ b/search-api/src/main/scala/no/ndla/searchapi/service/search/SearchService.scala
@@ -46,7 +46,6 @@ trait SearchService {
ErrorHandling & SearchLanguage =>
trait SearchService {
- import props.{DefaultLanguage, ElasticSearchScrollKeepAlive, MaxPageSize}
val searchIndex: List[String]
val indexServices: List[BaseIndexService]
@@ -232,7 +231,7 @@ trait SearchService {
query
.map(q => {
val searchLanguage =
- if (language == Language.AllLanguages || fallback) DefaultLanguage else language
+ if (language == Language.AllLanguages || fallback) props.DefaultLanguage else language
Seq(
suggestion(q, "title", searchLanguage),
suggestion(q, "content", searchLanguage)
@@ -278,7 +277,7 @@ trait SearchService {
def scroll(scrollId: String, language: String): Try[SearchResult] = {
e4sClient
.execute {
- searchScroll(scrollId, ElasticSearchScrollKeepAlive)
+ searchScroll(scrollId, props.ElasticSearchScrollKeepAlive)
}
.flatMap(response => {
getHits(response.result, language, filterInactive = false).map(hits => {
@@ -305,7 +304,7 @@ trait SearchService {
protected def defaultSort(default: String, withLanguage: String, order: SortOrder, language: String): FieldSort = {
val sortLanguage = language match {
- case Language.NoLanguage => DefaultLanguage
+ case Language.NoLanguage => props.DefaultLanguage
case _ => language
}
@@ -355,7 +354,7 @@ trait SearchService {
private val maxResultWindow = props.ElasticSearchIndexMaxResultWindow
def getStartAtAndNumResults(page: Int, pageSize: Int): Try[SearchPagination] = {
- val safePageSize = max(pageSize.min(MaxPageSize), 0)
+ val safePageSize = max(pageSize.min(props.MaxPageSize), 0)
val safePage = page.max(1)
val startAt = (safePage - 1) * safePageSize
val resultWindow = startAt + safePageSize
diff --git a/search-api/src/test/scala/no/ndla/searchapi/TestEnvironment.scala b/search-api/src/test/scala/no/ndla/searchapi/TestEnvironment.scala
index e10b0a0aef..241fe7efeb 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/TestEnvironment.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/TestEnvironment.scala
@@ -70,42 +70,42 @@ trait TestEnvironment
with Props {
override lazy val props: TestProps = new TestProps
- val searchController: SearchController = mock[SearchController]
- val internController: InternController = mock[InternController]
- val healthController: TapirHealthController = mock[TapirHealthController]
+ override lazy val searchController: SearchController = mock[SearchController]
+ override lazy val internController: InternController = mock[InternController]
+ override lazy val healthController: TapirHealthController = mock[TapirHealthController]
- val ndlaClient: NdlaClient = mock[NdlaClient]
- var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
+ override lazy val ndlaClient: NdlaClient = mock[NdlaClient]
+ var e4sClient: NdlaE4sClient = mock[NdlaE4sClient]
- val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
+ override lazy val myndlaApiClient: MyNDLAApiClient = mock[MyNDLAApiClient]
- val taxonomyApiClient: TaxonomyApiClient = mock[TaxonomyApiClient]
- val grepApiClient: GrepApiClient = mock[GrepApiClient]
+ override lazy val taxonomyApiClient: TaxonomyApiClient = mock[TaxonomyApiClient]
+ override lazy val grepApiClient: GrepApiClient = mock[GrepApiClient]
- val draftApiClient: DraftApiClient = mock[DraftApiClient]
- val learningPathApiClient: LearningPathApiClient = mock[LearningPathApiClient]
- val articleApiClient: ArticleApiClient = mock[ArticleApiClient]
- val draftConceptApiClient: DraftConceptApiClient = mock[DraftConceptApiClient]
- val feideApiClient: FeideApiClient = mock[FeideApiClient]
- val redisClient: RedisClient = mock[RedisClient]
- val frontpageApiClient: FrontpageApiClient = mock[FrontpageApiClient]
- val DBUtil: DBUtility = mock[DBUtility]
+ override lazy val draftApiClient: DraftApiClient = mock[DraftApiClient]
+ override lazy val learningPathApiClient: LearningPathApiClient = mock[LearningPathApiClient]
+ override lazy val articleApiClient: ArticleApiClient = mock[ArticleApiClient]
+ override lazy val draftConceptApiClient: DraftConceptApiClient = mock[DraftConceptApiClient]
+ override lazy val feideApiClient: FeideApiClient = mock[FeideApiClient]
+ override lazy val redisClient: RedisClient = mock[RedisClient]
+ override lazy val frontpageApiClient: FrontpageApiClient = mock[FrontpageApiClient]
+ override lazy val DBUtil: DBUtility = mock[DBUtility]
- val clock: SystemClock = mock[SystemClock]
+ override lazy val clock: SystemClock = mock[SystemClock]
- val converterService: ConverterService = mock[ConverterService]
- val searchConverterService: SearchConverterService = mock[SearchConverterService]
- val multiSearchService: MultiSearchService = mock[MultiSearchService]
- val grepSearchService: GrepSearchService = mock[GrepSearchService]
+ override lazy val converterService: ConverterService = mock[ConverterService]
+ override lazy val searchConverterService: SearchConverterService = mock[SearchConverterService]
+ override lazy val multiSearchService: MultiSearchService = mock[MultiSearchService]
+ override lazy val grepSearchService: GrepSearchService = mock[GrepSearchService]
- val articleIndexService: ArticleIndexService = mock[ArticleIndexService]
- val learningPathIndexService: LearningPathIndexService = mock[LearningPathIndexService]
- val draftIndexService: DraftIndexService = mock[DraftIndexService]
- val draftConceptIndexService: DraftConceptIndexService = mock[DraftConceptIndexService]
- val grepIndexService: GrepIndexService = mock[GrepIndexService]
- val nodeIndexService: NodeIndexService = mock[NodeIndexService]
+ override lazy val articleIndexService: ArticleIndexService = mock[ArticleIndexService]
+ override lazy val learningPathIndexService: LearningPathIndexService = mock[LearningPathIndexService]
+ override lazy val draftIndexService: DraftIndexService = mock[DraftIndexService]
+ override lazy val draftConceptIndexService: DraftConceptIndexService = mock[DraftConceptIndexService]
+ override lazy val grepIndexService: GrepIndexService = mock[GrepIndexService]
+ override lazy val nodeIndexService: NodeIndexService = mock[NodeIndexService]
- val multiDraftSearchService: MultiDraftSearchService = mock[MultiDraftSearchService]
+ override lazy val multiDraftSearchService: MultiDraftSearchService = mock[MultiDraftSearchService]
override def services: List[TapirController] = List()
val swagger: SwaggerController = mock[SwaggerController]
diff --git a/search-api/src/test/scala/no/ndla/searchapi/controller/InternControllerTest.scala b/search-api/src/test/scala/no/ndla/searchapi/controller/InternControllerTest.scala
index a96fa5ee54..6bb96a9dc0 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/controller/InternControllerTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/controller/InternControllerTest.scala
@@ -12,6 +12,6 @@ import no.ndla.searchapi.{TestEnvironment, UnitSuite}
import no.ndla.tapirtesting.TapirControllerTest
class InternControllerTest extends UnitSuite with TestEnvironment with TapirControllerTest {
- override val converterService = new ConverterService
- val controller: InternController = new InternController
+ override lazy val converterService = new ConverterService
+ override val controller: InternController = new InternController
}
diff --git a/search-api/src/test/scala/no/ndla/searchapi/controller/SearchControllerTest.scala b/search-api/src/test/scala/no/ndla/searchapi/controller/SearchControllerTest.scala
index fce284e19e..b926567d8c 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/controller/SearchControllerTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/controller/SearchControllerTest.scala
@@ -25,8 +25,8 @@ import java.time.Month
import scala.util.Success
class SearchControllerTest extends UnitSuite with TestEnvironment with TapirControllerTest {
- override val converterService = new ConverterService
- val controller: SearchController = new SearchController()
+ override lazy val converterService = new ConverterService
+ override val controller: SearchController = new SearchController()
override def beforeEach(): Unit = {
reset(clock)
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/ConverterServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/ConverterServiceTest.scala
index 698d519bcf..a07a9e614f 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/ConverterServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/ConverterServiceTest.scala
@@ -14,7 +14,7 @@ import no.ndla.searchapi.model.api
class ConverterServiceTest extends UnitSuite with TestEnvironment {
ApplicationUrl.applicationUrl.set("https://unit-test")
- override val converterService = new ConverterService
+ override lazy val converterService = new ConverterService
test("searchResultToApiModel should return the api model of the corresponding input domain model") {
converterService.searchResultToApiModel(TestData.sampleArticleSearch).isInstanceOf[api.ArticleResultsDTO]
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/ArticleIndexServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/ArticleIndexServiceTest.scala
index d1dc4ece50..90f488777d 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/ArticleIndexServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/ArticleIndexServiceTest.scala
@@ -25,7 +25,7 @@ import scala.util.Success
class ArticleIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val articleIndexService: ArticleIndexService = new ArticleIndexService {
+ override lazy val articleIndexService: ArticleIndexService = new ArticleIndexService {
override val indexShards = 1
}
@@ -35,8 +35,8 @@ class ArticleIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSui
articleIndexService.createIndexWithGeneratedName
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
test("That articles are indexed correctly") {
articleIndexService
@@ -74,7 +74,7 @@ class ArticleIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSui
val Success(response) = e4sClient.execute {
search(articleIndexService.searchIndex)
- }
+ }: @unchecked
val sources = response.result.hits.hits.map(_.sourceAsString)
val articles = sources.map(source => CirceUtil.unsafeParseAs[SearchableArticle](source))
@@ -87,7 +87,7 @@ class ArticleIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSui
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(expectedArticle6) =
searchConverterService.asSearchableArticle(
article6,
@@ -96,7 +96,7 @@ class ArticleIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSui
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(expectedArticle7) =
searchConverterService.asSearchableArticle(
article7,
@@ -105,11 +105,11 @@ class ArticleIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSui
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
- val Some(actualArticle5) = articles.find(p => p.id == article5.id.get)
- val Some(actualArticle6) = articles.find(p => p.id == article6.id.get)
- val Some(actualArticle7) = articles.find(p => p.id == article7.id.get)
+ val Some(actualArticle5) = articles.find(p => p.id == article5.id.get): @unchecked
+ val Some(actualArticle6) = articles.find(p => p.id == article6.id.get): @unchecked
+ val Some(actualArticle7) = articles.find(p => p.id == article7.id.get): @unchecked
actualArticle5 should be(expectedArticle5)
actualArticle6 should be(expectedArticle6)
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftConceptIndexServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftConceptIndexServiceTest.scala
index 9d94a9641c..75bc37c557 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftConceptIndexServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftConceptIndexServiceTest.scala
@@ -21,7 +21,7 @@ import no.ndla.searchapi.{TestData, TestEnvironment, UnitSuite}
class DraftConceptIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
+ override lazy val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
override val indexShards = 1
}
@@ -31,8 +31,8 @@ class DraftConceptIndexServiceTest extends ElasticsearchIntegrationSuite with Un
articleIndexService.createIndexWithGeneratedName
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
test("That mapping contains every field after serialization") {
val languageValues = SearchableLanguageValues(Seq(LanguageValue("nb", "hei"), LanguageValue("en", "hå")))
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftIndexServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftIndexServiceTest.scala
index e38a1b94d0..0f79e3d4fd 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftIndexServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/DraftIndexServiceTest.scala
@@ -26,7 +26,7 @@ class DraftIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSuite
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val draftIndexService: DraftIndexService = new DraftIndexService {
+ override lazy val draftIndexService: DraftIndexService = new DraftIndexService {
override val indexShards = 1
}
@@ -41,8 +41,8 @@ class DraftIndexServiceTest extends ElasticsearchIntegrationSuite with UnitSuite
when(myndlaApiClient.getStatsFor(any, any)).thenReturn(Success(List.empty))
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
test("That mapping contains every field after serialization") {
val now = NDLADate.now()
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/GrepSearchServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/GrepSearchServiceTest.scala
index 1959f770f4..809f08b3a4 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/GrepSearchServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/GrepSearchServiceTest.scala
@@ -20,12 +20,12 @@ import no.ndla.searchapi.model.grep.*
class GrepSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnvironment {
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val grepIndexService: GrepIndexService = new GrepIndexService {
+ override lazy val grepIndexService: GrepIndexService = new GrepIndexService {
override val indexShards = 1
}
- override val grepSearchService = new GrepSearchService
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val grepSearchService = new GrepSearchService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
override def beforeEach(): Unit = {
if (elasticSearchContainer.isSuccess) {
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/IndexServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/IndexServiceTest.scala
index 699d66307f..fa17a690b9 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/IndexServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/IndexServiceTest.scala
@@ -37,7 +37,7 @@ class IndexServiceTest extends ElasticsearchIntegrationSuite with TestEnvironmen
searchIndexService.cleanupIndexes(s"${testIndexPrefix}_article")
- val Success(response) = e4sClient.execute(getAliases())
+ val Success(response) = e4sClient.execute(getAliases()): @unchecked
val result = response.result.mappings
val indexNames = result.map(_._1.name)
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/LearningPathIndexServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/LearningPathIndexServiceTest.scala
index 7d553b3c3c..8b260712ec 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/LearningPathIndexServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/LearningPathIndexServiceTest.scala
@@ -31,7 +31,7 @@ class LearningPathIndexServiceTest extends ElasticsearchIntegrationSuite with Un
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
+ override lazy val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
override val indexShards = 1
}
@@ -46,8 +46,8 @@ class LearningPathIndexServiceTest extends ElasticsearchIntegrationSuite with Un
when(myndlaApiClient.getStatsFor(any, any)).thenReturn(Success(List.empty))
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
test("That mapping contains every field after serialization") {
val domainLearningPath = TestData.learningPath1.copy(
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceAtomicTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceAtomicTest.scala
index 5fe4633ae8..32648b86bc 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceAtomicTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceAtomicTest.scala
@@ -17,7 +17,6 @@ import no.ndla.common.model.api.search.{ApiTaxonomyContextDTO, LearningResourceT
import no.ndla.common.model.domain.*
import no.ndla.common.model.domain.concept.{ConceptContent, ConceptType}
import no.ndla.common.model.domain.draft.{Draft, DraftStatus}
-import no.ndla.common.model.domain.{EditorNote, Priority, Responsible, RevisionMeta, RevisionStatus}
import no.ndla.network.tapir.NonEmptyString
import no.ndla.scalatestsuite.ElasticsearchIntegrationSuite
import no.ndla.search.model.{LanguageValue, SearchableLanguageList, SearchableLanguageValues}
@@ -33,23 +32,23 @@ import scala.util.{Success, Try}
class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite with TestEnvironment {
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val articleIndexService: ArticleIndexService = new ArticleIndexService {
+ override lazy val articleIndexService: ArticleIndexService = new ArticleIndexService {
override val indexShards = 1
}
- override val draftIndexService: DraftIndexService = new DraftIndexService {
+ override lazy val draftIndexService: DraftIndexService = new DraftIndexService {
override val indexShards = 1
}
- override val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
+ override lazy val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
override val indexShards = 1
}
- override val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
+ override lazy val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
override val indexShards = 1
}
- override val multiDraftSearchService: MultiDraftSearchService = new MultiDraftSearchService {
+ override lazy val multiDraftSearchService: MultiDraftSearchService = new MultiDraftSearchService {
override val enableExplanations = true
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
override def beforeEach(): Unit = {
if (elasticSearchContainer.isSuccess) {
@@ -104,7 +103,7 @@ class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite wi
val Success(search1) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(embedId = Some("3"), embedResource = List("content-link"))
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.map(_.id) should be(List(2))
@@ -112,7 +111,7 @@ class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite wi
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(embedId = Some("3"), embedResource = List("content-link", "related-content"))
- )
+ ): @unchecked
search2.totalCount should be(2)
search2.summaryResults.map(_.id) should be(List(1, 2))
@@ -182,7 +181,7 @@ class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite wi
val Success(search1) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(sort = Sort.ByRevisionDateAsc)
- )
+ ): @unchecked
search1.totalCount should be(4)
search1.summaryResults.map(_.id) should be(List(3, 1, 2, 4))
@@ -190,7 +189,7 @@ class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite wi
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(sort = Sort.ByRevisionDateDesc)
- )
+ ): @unchecked
search2.totalCount should be(4)
search2.summaryResults.map(_.id) should be(List(1, 3, 2, 4))
@@ -260,7 +259,7 @@ class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite wi
val Success(search1) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("trylleformel").get))
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.map(_.id) should be(List(3))
@@ -917,7 +916,7 @@ class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite wi
val Success(search1) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(embedId = Some(videoId), embedResource = List("video"))
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.map(_.id) should be(List(1))
@@ -982,17 +981,17 @@ class MultiDraftSearchServiceAtomicTest extends ElasticsearchIntegrationSuite wi
val Success(search1) = searchService.matchingQuery(
multiDraftSearchSettings.copy(sort = Sort.ByParentTopicNameAsc)
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(List(1, 2, 3))
val Success(search2) = searchService.matchingQuery(
multiDraftSearchSettings.copy(sort = Sort.ByPrimaryRootAsc)
- )
+ ): @unchecked
search2.summaryResults.map(_.id) should be(List(2, 3, 1))
val Success(search3) = searchService.matchingQuery(
multiDraftSearchSettings.copy(sort = Sort.ByResourceTypeAsc)
- )
+ ): @unchecked
search3.summaryResults.map(_.id) should be(List(3, 1, 2))
}
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceTest.scala
index 8c5b4a42b9..98681e2e07 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiDraftSearchServiceTest.scala
@@ -28,26 +28,24 @@ import no.ndla.searchapi.SearchTestUtility.*
import scala.util.Success
class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with TestEnvironment {
- import props.DefaultPageSize
-
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val articleIndexService: ArticleIndexService = new ArticleIndexService {
+ override lazy val articleIndexService: ArticleIndexService = new ArticleIndexService {
override val indexShards = 1
}
- override val draftIndexService: DraftIndexService = new DraftIndexService {
+ override lazy val draftIndexService: DraftIndexService = new DraftIndexService {
override val indexShards = 1
}
- override val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
+ override lazy val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
override val indexShards = 1
}
- override val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
+ override lazy val draftConceptIndexService: DraftConceptIndexService = new DraftConceptIndexService {
override val indexShards = 1
}
- override val multiDraftSearchService: MultiDraftSearchService = new MultiDraftSearchService {
+ override lazy val multiDraftSearchService: MultiDraftSearchService = new MultiDraftSearchService {
override val enableExplanations = true
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
val indexingBundle: IndexingBundle =
IndexingBundle(Some(emptyGrepBundle), Some(taxonomyTestBundle), Some(TestData.myndlaTestBundle))
@@ -103,43 +101,47 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- multiDraftSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal(
- Success(SearchPagination(page, DefaultPageSize, expectedStartAt))
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ multiDraftSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ Success(SearchPagination(page, props.DefaultPageSize, expectedStartAt))
)
}
test("That all returns all documents ordered by id ascending") {
- val Success(results) = multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByIdAsc))
- val expected = idsForLang("nb").sorted
+ val Success(results) =
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByIdAsc)): @unchecked
+ val expected = idsForLang("nb").sorted
results.totalCount should be(expected.size)
results.summaryResults.map(_.id) should be(expected)
}
test("That all returns all documents ordered by id descending") {
- val Success(results) = multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByIdDesc))
- val expected = idsForLang("nb").sorted.reverse
+ val Success(results) =
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByIdDesc)): @unchecked
+ val expected = idsForLang("nb").sorted.reverse
results.totalCount should be(expected.size)
results.summaryResults.map(_.id) should be(expected)
}
test("That all returns all documents ordered by title ascending") {
- val Success(results) = multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByTitleAsc))
- val expected = titlesForLang("nb").sorted
+ val Success(results) =
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByTitleAsc)): @unchecked
+ val expected = titlesForLang("nb").sorted
results.totalCount should be(expected.size)
results.summaryResults.map(_.title.title) should be(expected)
}
test("That all returns all documents ordered by title descending") {
- val Success(results) = multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByTitleDesc))
- val expected = titlesForLang("nb").sorted.reverse
+ val Success(results) =
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByTitleDesc)): @unchecked
+ val expected = titlesForLang("nb").sorted.reverse
results.totalCount should be(expected.size)
results.summaryResults.map(_.title.title) should be(expected)
}
test("That all returns all documents ordered by lastUpdated descending") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByLastUpdatedDesc))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByLastUpdatedDesc)): @unchecked
val expected = idsForLang("nb")
results.totalCount should be(expected.size)
results.summaryResults.head.id should be(4)
@@ -148,7 +150,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That all returns all documents ordered by lastUpdated ascending") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByLastUpdatedAsc))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(sort = Sort.ByLastUpdatedAsc)): @unchecked
val expected = idsForLang("nb")
results.totalCount should be(expected.size)
results.summaryResults.head.id should be(5)
@@ -158,9 +160,13 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That paging returns only hits on current page and not more than page-size") {
val Success(page1) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByIdAsc))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByIdAsc)
+ ): @unchecked
val Success(page2) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByIdAsc))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByIdAsc)
+ ): @unchecked
val expected = idsForLang("nb")
val hits1 = page1.summaryResults
val hits2 = page2.summaryResults
@@ -180,7 +186,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("bil").get), sort = Sort.ByRelevanceDesc)
- )
+ ): @unchecked
results.totalCount should be(3)
results.summaryResults.map(_.id) should be(Seq(1, 5, 3))
}
@@ -193,7 +199,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
sort = Sort.ByRelevanceDesc,
withIdIn = List(3)
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(3)
@@ -204,7 +210,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("Pingvinen").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
results.summaryResults.map(_.contexts.head.contextType) should be(Seq("learningpath", "standard"))
results.summaryResults.map(_.id) should be(Seq(1, 2))
@@ -215,7 +221,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(sort = Sort.ByIdAsc, userFilter = List("ndalId54321"))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(13)
hits.head.id should be(1)
@@ -227,7 +233,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(sort = Sort.ByIdAsc, userFilter = List("ndalId12345"))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(5)
@@ -238,7 +244,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("and").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(2)
hits.head.id should be(3)
@@ -254,7 +260,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
license = Some(License.Copyrighted.toString),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(4)
@@ -267,7 +273,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("bilde + bil").get),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits1 = search1.summaryResults
hits1.map(_.id) should equal(Seq(1, 3, 5))
@@ -277,7 +283,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("batmen + bil").get),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits2 = search2.summaryResults
hits2.map(_.id) should equal(Seq(1))
}
@@ -288,7 +294,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("-flaggermusmann + (bil + bilde)").get),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should equal(Seq(3, 5))
val Success(search2) =
@@ -297,7 +303,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("bil + -hulken").get),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
search2.summaryResults.map(_.id) should equal(Seq(1, 3))
}
@@ -308,7 +314,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("mareritt+ragnarok").get),
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val hits = search.summaryResults
hits.map(_.id) should equal(Seq(9, 8))
}
@@ -316,14 +322,16 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("Search for all languages should return all articles in different languages") {
val Success(search) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = AllLanguages, pageSize = 100, sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
search.totalCount should equal(titlesForLang("*").size)
}
test("Search for all languages should return all articles in correct language") {
val Success(search) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(language = AllLanguages, pageSize = 100))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(language = AllLanguages, pageSize = 100)
+ ): @unchecked
val hits = search.summaryResults
search.totalCount should equal(idsForLang("*").size)
@@ -358,7 +366,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
pageSize = 100,
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = search.summaryResults
search.totalCount should equal(1)
@@ -369,7 +377,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(searchEn) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings
.copy(query = Some(NonEmptyString.fromString("Cats").get), language = AllLanguages, sort = Sort.ByRelevanceDesc)
- )
+ ): @unchecked
val Success(searchNb) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings
.copy(
@@ -377,7 +385,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = AllLanguages,
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
searchEn.totalCount should equal(1)
searchEn.summaryResults.head.id should equal(11)
@@ -393,7 +401,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("Searching with query for unknown language should return nothing") {
val Success(search) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "mix", sort = Sort.ByRelevanceDesc)
- )
+ ): @unchecked
search.totalCount should equal(0)
}
@@ -406,7 +414,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = AllLanguages,
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
search.totalCount should equal(1)
search.summaryResults.head.id should equal(11)
@@ -418,7 +426,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(fallback = true, language = "en", withIdIn = List(9, 10, 11))
- )
+ ): @unchecked
search.totalCount should equal(3)
search.summaryResults.head.id should equal(9)
@@ -430,21 +438,25 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
}
test("That private learningpaths are only returned if user is owner") {
- val Success(search) = multiDraftSearchService.matchingQuery(
- multiDraftSearchSettings.copy(
- resultTypes = Some(List(SearchType.LearningPaths)),
- fallback = true
+ val search = multiDraftSearchService
+ .matchingQuery(
+ multiDraftSearchSettings.copy(
+ resultTypes = Some(List(SearchType.LearningPaths)),
+ fallback = true
+ )
)
- )
+ .get
search.totalCount should equal(6)
- val Success(search2) = multiDraftSearchService.matchingQuery(
- multiDraftSearchSettings.copy(
- resultTypes = Some(List(SearchType.LearningPaths)),
- fallback = true,
- user = TokenUser("private", Set(LEARNINGPATH_API_WRITE), None)
+ val search2 = multiDraftSearchService
+ .matchingQuery(
+ multiDraftSearchSettings.copy(
+ resultTypes = Some(List(SearchType.LearningPaths)),
+ fallback = true,
+ user = TokenUser("private", Set(LEARNINGPATH_API_WRITE), None)
+ )
)
- )
+ .get
search2.totalCount should equal(7)
}
@@ -452,7 +464,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", subjects = List("urn:subject:2"))
- )
+ ): @unchecked
search.totalCount should be(7)
search.summaryResults.map(_.id) should be(Seq(1, 5, 5, 6, 7, 11, 12))
}
@@ -461,7 +473,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", subjects = List("urn:subject:2"), filterInactive = true)
- )
+ ): @unchecked
search.totalCount should be(4)
search.summaryResults.flatMap(_.contexts).toList.length should be(5)
search.summaryResults.map(_.id) should be(Seq(5, 6, 11, 12))
@@ -471,14 +483,14 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(subjects = List("urn:subject:2", "urn:subject:1"))
- )
+ ): @unchecked
search.totalCount should be(15)
search.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 11, 12))
}
test("That filtering for invisible subjects returns all drafts with any of listed subjects") {
val Success(search) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(subjects = List("urn:subject:3")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(subjects = List("urn:subject:3"))): @unchecked
search.totalCount should be(2)
search.summaryResults.map(_.id) should be(Seq(1, 15))
}
@@ -487,21 +499,21 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(resourceTypes = List("urn:resourcetype:academicArticle"))
- )
+ ): @unchecked
search.totalCount should be(2)
search.summaryResults.map(_.id) should be(Seq(2, 5))
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(resourceTypes = List("urn:resourcetype:subjectMaterial"))
- )
+ ): @unchecked
search2.totalCount should be(8)
search2.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 5, 6, 7, 12))
val Success(search3) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(resourceTypes = List("urn:resourcetype:learningpath"))
- )
+ ): @unchecked
search3.totalCount should be(4)
search3.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4))
}
@@ -512,7 +524,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = "*",
learningResourceTypes = List(LearningResourceType.Article, LearningResourceType.TopicArticle)
)
- )
+ ): @unchecked
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15))
search.totalCount should be(14)
@@ -524,7 +536,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = "*",
filterInactive = false
)
- )
+ ): @unchecked
val totalCount = search.totalCount
val ids = search.summaryResults.map(_.id).length
@@ -535,7 +547,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = "*",
filterInactive = true
)
- )
+ ): @unchecked
totalCount should be > search2.totalCount
ids should be > search2.summaryResults.map(_.id).length
@@ -545,10 +557,10 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That filtering on learning-resource-type works") {
val Success(search) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", learningResourceTypes = List(LearningResourceType.Article))
- )
+ ): @unchecked
val Success(search2) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", learningResourceTypes = List(LearningResourceType.TopicArticle))
- )
+ ): @unchecked
search.totalCount should be(8)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 5, 6, 7, 12))
@@ -560,13 +572,13 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That filtering on article-type works") {
val Success(search) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", articleTypes = List(ArticleType.Standard.entryName))
- )
+ ): @unchecked
val Success(search2) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", articleTypes = List(ArticleType.TopicArticle.entryName))
- )
+ ): @unchecked
val Success(search3) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", articleTypes = List(ArticleType.FrontpageArticle.entryName))
- )
+ ): @unchecked
search.totalCount should be(8)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 5, 6, 7, 12))
@@ -581,7 +593,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That filtering on learningpath learningresourcetype returns learningpaths") {
val Success(search) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", learningResourceTypes = List(LearningResourceType.LearningPath))
- )
+ ): @unchecked
search.totalCount should be(6)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 5, 6))
@@ -592,21 +604,21 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", supportedLanguages = List("en"))
- )
+ ): @unchecked
search.totalCount should be(9)
search.summaryResults.map(_.id) should be(Seq(2, 3, 4, 5, 6, 10, 11, 13, 15))
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", supportedLanguages = List("en", "nb"), pageSize = 100)
- )
+ ): @unchecked
search2.totalCount should be(21)
search2.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16))
val Success(search3) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "*", supportedLanguages = List("nb"))
- )
+ ): @unchecked
search3.totalCount should be(18)
search3.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16))
}
@@ -615,7 +627,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = "nb", supportedLanguages = List("en"))
- )
+ ): @unchecked
search.totalCount should be(6)
search.summaryResults.map(_.id) should be(Seq(2, 3, 4, 11, 13, 15))
@@ -624,7 +636,9 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That meta image are returned when searching") {
val Success(search) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(language = "en", withIdIn = List(10)))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(language = "en", withIdIn = List(10))
+ ): @unchecked
search.totalCount should be(1)
search.summaryResults.head.id should be(10)
@@ -637,7 +651,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(noteQuery = Some(NonEmptyString.fromString("kakemonster").get))
- )
+ ): @unchecked
search.totalCount should be(1)
search.summaryResults.head.id should be(5)
@@ -645,7 +659,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(noteQuery = Some(NonEmptyString.fromString("Katter").get))
- )
+ ): @unchecked
search2.totalCount should be(0)
}
@@ -654,7 +668,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("kakemonster").get))
- )
+ ): @unchecked
search.totalCount should be(1)
search.summaryResults.head.id should be(5)
@@ -662,7 +676,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That filtering for topics returns every child learningResource") {
val Success(search) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(topics = List("urn:topic:1")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(topics = List("urn:topic:1"))): @unchecked
search.totalCount should be(8)
@@ -675,13 +689,13 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("Kjekspolitiet").get),
language = AllLanguages
)
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.map(_.id) should be(Seq(1))
val Success(search2) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("Svims").get), language = AllLanguages)
- )
+ ): @unchecked
search2.totalCount should be(2)
search2.summaryResults.map(_.id) should be(Seq(2, 5))
}
@@ -689,12 +703,12 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That filtering by relevance id works when no subject is specified") {
val Success(search1) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = AllLanguages, relevanceIds = List("urn:relevance:core"))
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12))
val Success(search2) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = AllLanguages, relevanceIds = List("urn:relevance:supplementary"))
- )
+ ): @unchecked
search2.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 4, 5, 12, 15))
val Success(search3) = multiDraftSearchService.matchingQuery(
@@ -702,7 +716,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = AllLanguages,
relevanceIds = List("urn:relevance:supplementary", "urn:relevance:core")
)
- )
+ ): @unchecked
search3.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 15))
}
@@ -710,7 +724,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search1) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings
.copy(language = AllLanguages, subjects = List("urn:subject:2"), relevanceIds = List("urn:relevance:core"))
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(1, 5, 6, 7, 11))
}
@@ -721,20 +735,20 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(initialSearch) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = AllLanguages, pageSize = pageSize, shouldScroll = true)
- )
-
- val Success(scroll1) = multiDraftSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = multiDraftSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = multiDraftSearchService.scroll(scroll2.scrollId.get, "*")
- val Success(scroll4) = multiDraftSearchService.scroll(scroll3.scrollId.get, "*")
- val Success(scroll5) = multiDraftSearchService.scroll(scroll4.scrollId.get, "*")
- val Success(scroll6) = multiDraftSearchService.scroll(scroll5.scrollId.get, "*")
- val Success(scroll7) = multiDraftSearchService.scroll(scroll6.scrollId.get, "*")
- val Success(scroll8) = multiDraftSearchService.scroll(scroll7.scrollId.get, "*")
- val Success(scroll9) = multiDraftSearchService.scroll(scroll8.scrollId.get, "*")
- val Success(scroll10) = multiDraftSearchService.scroll(scroll9.scrollId.get, "*")
- val Success(scroll11) = multiDraftSearchService.scroll(scroll10.scrollId.get, "*")
- val Success(scroll12) = multiDraftSearchService.scroll(scroll11.scrollId.get, "*")
+ ): @unchecked
+
+ val Success(scroll1) = multiDraftSearchService.scroll(initialSearch.scrollId.get, "*"): @unchecked
+ val Success(scroll2) = multiDraftSearchService.scroll(scroll1.scrollId.get, "*"): @unchecked
+ val Success(scroll3) = multiDraftSearchService.scroll(scroll2.scrollId.get, "*"): @unchecked
+ val Success(scroll4) = multiDraftSearchService.scroll(scroll3.scrollId.get, "*"): @unchecked
+ val Success(scroll5) = multiDraftSearchService.scroll(scroll4.scrollId.get, "*"): @unchecked
+ val Success(scroll6) = multiDraftSearchService.scroll(scroll5.scrollId.get, "*"): @unchecked
+ val Success(scroll7) = multiDraftSearchService.scroll(scroll6.scrollId.get, "*"): @unchecked
+ val Success(scroll8) = multiDraftSearchService.scroll(scroll7.scrollId.get, "*"): @unchecked
+ val Success(scroll9) = multiDraftSearchService.scroll(scroll8.scrollId.get, "*"): @unchecked
+ val Success(scroll10) = multiDraftSearchService.scroll(scroll9.scrollId.get, "*"): @unchecked
+ val Success(scroll11) = multiDraftSearchService.scroll(scroll10.scrollId.get, "*"): @unchecked
+ val Success(scroll12) = multiDraftSearchService.scroll(scroll11.scrollId.get, "*"): @unchecked
initialSearch.summaryResults.map(_.id) should be(ids.head)
scroll1.summaryResults.map(_.id) should be(ids(1))
@@ -758,7 +772,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
learningResourceTypes = List(LearningResourceType.Article, LearningResourceType.TopicArticle),
statusFilter = List(DraftStatus.IN_PROGRESS)
)
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(10, 11))
val Success(search2) = multiDraftSearchService.matchingQuery(
@@ -767,7 +781,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
learningResourceTypes = List(LearningResourceType.Article, LearningResourceType.TopicArticle),
statusFilter = List(DraftStatus.IMPORTED)
)
- )
+ ): @unchecked
search2.summaryResults.map(_.id) should be(Seq())
val Success(search3) = multiDraftSearchService.matchingQuery(
@@ -777,7 +791,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
statusFilter = List(DraftStatus.IMPORTED),
includeOtherStatuses = true
)
- )
+ ): @unchecked
search3.summaryResults.map(_.id) should be(Seq(12))
}
@@ -787,7 +801,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search1) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(language = AllLanguages, statusFilter = List(DraftStatus.IN_PROGRESS))
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(expectedIds)
}
@@ -796,11 +810,11 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search1) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("kultgammeltnotat").get))
- )
+ ): @unchecked
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(noteQuery = Some(NonEmptyString.fromString("kultgammeltnotat").get))
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.head.id should be(5)
@@ -811,11 +825,11 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That filtering on grepCodes returns articles which has grepCodes") {
val Success(search1) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(grepCodes = List("K123")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(grepCodes = List("K123"))): @unchecked
val Success(search2) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(grepCodes = List("K456")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(grepCodes = List("K456"))): @unchecked
val Success(search3) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(grepCodes = List("K123", "K456")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(grepCodes = List("K123", "K456"))): @unchecked
search1.summaryResults.map(_.id) should be(Seq(1, 2, 3))
search2.summaryResults.map(_.id) should be(Seq(1, 2, 5))
@@ -826,18 +840,18 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search1) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(statusFilter = List(DraftStatus.ARCHIVED))
- )
+ ): @unchecked
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(statusFilter = List(DraftStatus.UNPUBLISHED))
- )
+ ): @unchecked
val Success(search3) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(
withIdIn = List(14, 17), // 14 is archived, 17 is unpublished
statusFilter = List.empty
)
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(14))
search2.summaryResults.map(_.id) should be(Seq(17))
@@ -848,7 +862,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings
.copy(query = Some(NonEmptyString.fromString("bil").get), language = AllLanguages, sort = Sort.ByRelevanceDesc)
- )
+ ): @unchecked
search.totalCount should equal(3)
search.suggestions.length should equal(2)
@@ -866,7 +880,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = AllLanguages,
searchDecompounded = true
)
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.map(_.id) should be(Seq(13))
@@ -877,7 +891,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = "nb",
searchDecompounded = true
)
- )
+ ): @unchecked
search2.totalCount should be(1)
search2.summaryResults.map(_.id) should be(Seq(13))
@@ -891,7 +905,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = AllLanguages,
searchDecompounded = false
)
- )
+ ): @unchecked
search1.totalCount should be(0)
search1.summaryResults.map(_.id) should be(Seq.empty)
@@ -902,7 +916,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
language = "nb",
searchDecompounded = false
)
- )
+ ): @unchecked
search2.totalCount should be(0)
search2.summaryResults.map(_.id) should be(Seq.empty)
@@ -911,7 +925,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("Search query should not be decompounded (only indexed documents)") {
val Success(search1) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("Bilsøster").get), language = AllLanguages)
- )
+ ): @unchecked
search1.totalCount should be(0)
}
@@ -919,7 +933,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That searches for embed attributes matches") {
val Success(search) = multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("Flubber").get), language = AllLanguages)
- )
+ ): @unchecked
search.summaryResults.map(_.id) should be(Seq(12))
}
@@ -927,13 +941,13 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(embedResource = List("conc"), embedId = Some("55"))
- )
+ ): @unchecked
results.totalCount should be(0)
}
test("That searches for data-resource_id matches") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedId = Some("222")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedId = Some("222"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -947,7 +961,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
embedResource = List("image"),
embedId = Some("55")
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -962,13 +976,13 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
embedResource = List("concept"),
embedId = Some("77")
)
- )
+ ): @unchecked
results.totalCount should be(0)
}
test("That search on embed data-resource matches") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedResource = List("video")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedResource = List("video"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -976,7 +990,9 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That search on embed data-url matches") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedId = Some("http://test.test")))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(embedId = Some("http://test.test"))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -986,7 +1002,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("77").get))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -996,7 +1012,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("video").get))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -1006,7 +1022,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("11").get))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(11)
@@ -1014,7 +1030,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That search on embed data-content-id matches") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedId = Some("111")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedId = Some("111"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -1022,7 +1038,9 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That search on embed id with language filter does only return correct language") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(language = "en", embedId = Some("222")))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(language = "en", embedId = Some("222"))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(13)
@@ -1030,7 +1048,9 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That search on embed id with language filter=all matches") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(language = "*", embedId = Some("222")))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(language = "*", embedId = Some("222"))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(2)
hits.map(_.id) should be(Seq(12, 13))
@@ -1038,7 +1058,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That search on visual element id matches") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedId = Some("333")))
+ multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(embedId = Some("333"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(12))
@@ -1046,7 +1066,9 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
test("That search on meta image url matches ") {
val Success(results) =
- multiDraftSearchService.matchingQuery(multiDraftSearchSettings.copy(language = "*", embedId = Some("123")))
+ multiDraftSearchService.matchingQuery(
+ multiDraftSearchSettings.copy(language = "*", embedId = Some("123"))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(10))
@@ -1056,7 +1078,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("\"delt-streng\"").get), language = "*")
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(15))
@@ -1066,7 +1088,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(results) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(query = Some(NonEmptyString.fromString("\"delt\\-streng\"").get), language = "*")
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(15))
@@ -1079,7 +1101,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("\"delt!streng\" \"delt?streng\"").get),
language = "*"
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(13))
@@ -1092,7 +1114,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("\"delt!streng\"+\"delt-streng\"").get),
language = "*"
)
- )
+ ): @unchecked
results.totalCount should be(0)
}
@@ -1103,7 +1125,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("\"delt!streng\"+-\"delt-streng\"").get),
language = "*"
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(13))
@@ -1116,7 +1138,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("\"delt!streng\"+-Helsesøster").get),
language = "*"
)
- )
+ ): @unchecked
results.totalCount should be(0)
}
@@ -1127,7 +1149,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("\"delt!streng\" + Helsesøster").get),
language = "*"
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(13))
@@ -1140,7 +1162,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
query = Some(NonEmptyString.fromString("\"artikkeltekst med fire deler\"").get),
language = "*"
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(12))
@@ -1151,7 +1173,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings
.copy(language = AllLanguages, embedResource = List("concept"), embedId = Some("222"))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -1161,11 +1183,11 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
val Success(search1) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(embedId = Some("test-image.id"))
- )
+ ): @unchecked
val Success(search2) =
multiDraftSearchService.matchingQuery(
multiDraftSearchSettings.copy(embedId = Some("test-image.url"))
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.head.id should be(12)
@@ -1182,7 +1204,7 @@ class MultiDraftSearchServiceTest extends ElasticsearchIntegrationSuite with Tes
sort = Sort.ByRelevanceDesc,
withIdIn = List(3)
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.lastUpdated should be(a[NDLADate])
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceAtomicTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceAtomicTest.scala
index d04f0e5c9c..598f9dfd34 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceAtomicTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceAtomicTest.scala
@@ -30,23 +30,23 @@ import scala.util.Success
class MultiSearchServiceAtomicTest extends ElasticsearchIntegrationSuite with TestEnvironment {
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val articleIndexService: ArticleIndexService = new ArticleIndexService {
+ override lazy val articleIndexService: ArticleIndexService = new ArticleIndexService {
override val indexShards = 1
}
- override val draftIndexService: DraftIndexService = new DraftIndexService {
+ override lazy val draftIndexService: DraftIndexService = new DraftIndexService {
override val indexShards = 1
}
- override val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
+ override lazy val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
override val indexShards = 1
}
- override val nodeIndexService: NodeIndexService = new NodeIndexService {
+ override lazy val nodeIndexService: NodeIndexService = new NodeIndexService {
override val indexShards = 1
}
- override val multiSearchService = new MultiSearchService {
+ override lazy val multiSearchService = new MultiSearchService {
override val enableExplanations = true
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
override def beforeEach(): Unit = {
if (elasticSearchContainer.isSuccess) {
@@ -98,7 +98,7 @@ class MultiSearchServiceAtomicTest extends ElasticsearchIntegrationSuite with Te
val Success(search1) =
multiSearchService.matchingQuery(
TestData.searchSettings.copy(embedId = Some("3"), embedResource = List("content-link"))
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.map(_.id) should be(List(2))
@@ -106,7 +106,7 @@ class MultiSearchServiceAtomicTest extends ElasticsearchIntegrationSuite with Te
val Success(search2) =
multiSearchService.matchingQuery(
TestData.searchSettings.copy(embedId = Some("3"), embedResource = List("content-link", "related-content"))
- )
+ ): @unchecked
search2.totalCount should be(2)
search2.summaryResults.map(_.id) should be(List(1, 2))
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceTest.scala
index d0cf0554ad..2df5d2a91c 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/MultiSearchServiceTest.scala
@@ -27,28 +27,26 @@ import no.ndla.searchapi.SearchTestUtility.*
import scala.util.Success
class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuite with TestEnvironment {
- import props.DefaultPageSize
-
e4sClient = Elastic4sClientFactory.getClient(elasticSearchHost.getOrElse(""))
- override val articleIndexService: ArticleIndexService = new ArticleIndexService {
+ override lazy val articleIndexService: ArticleIndexService = new ArticleIndexService {
override val indexShards = 1
}
- override val draftIndexService: DraftIndexService = new DraftIndexService {
+ override lazy val draftIndexService: DraftIndexService = new DraftIndexService {
override val indexShards = 1
}
- override val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
+ override lazy val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
override val indexShards = 1
}
- override val nodeIndexService: NodeIndexService = new NodeIndexService {
+ override lazy val nodeIndexService: NodeIndexService = new NodeIndexService {
override val indexShards = 1
}
- override val multiSearchService = new MultiSearchService {
+ override lazy val multiSearchService = new MultiSearchService {
override val enableExplanations = true
}
- override val converterService = new ConverterService
- override val searchConverterService = new SearchConverterService
+ override lazy val converterService = new ConverterService
+ override lazy val searchConverterService = new SearchConverterService
override def beforeAll(): Unit = {
super.beforeAll()
@@ -127,14 +125,14 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That getStartAtAndNumResults returns the correct calculated start at for page and page-size") {
val page = 74
- val expectedStartAt = (page - 1) * DefaultPageSize
- multiSearchService.getStartAtAndNumResults(page, DefaultPageSize) should equal(
- Success(SearchPagination(page, DefaultPageSize, expectedStartAt))
+ val expectedStartAt = (page - 1) * props.DefaultPageSize
+ multiSearchService.getStartAtAndNumResults(page, props.DefaultPageSize) should equal(
+ Success(SearchPagination(page, props.DefaultPageSize, expectedStartAt))
)
}
test("That all returns all documents ordered by id ascending") {
- val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdAsc))
+ val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdAsc)): @unchecked
val hits = results.summaryResults
results.totalCount should be(idsForLang("nb").size)
@@ -142,7 +140,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That all returns all documents ordered by id descending") {
- val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdDesc))
+ val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByIdDesc)): @unchecked
val hits = results.summaryResults
results.totalCount should be(idsForLang("nb").size)
@@ -150,30 +148,32 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That all returns all documents ordered by title ascending") {
- val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByTitleAsc))
+ val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByTitleAsc)): @unchecked
val hits = results.summaryResults
results.totalCount should be(titlesForLang("nb").size)
hits.map(_.title.title) should be(titlesForLang("nb").sorted)
}
test("That all returns all documents ordered by title descending") {
- val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByTitleDesc))
+ val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByTitleDesc)): @unchecked
val hits = results.summaryResults
results.totalCount should be(titlesForLang("nb").size)
hits.map(_.title.title) should be(titlesForLang("nb").sorted.reverse)
}
test("That all returns all documents ordered by lastUpdated descending") {
- val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedDesc))
- val hits = results.summaryResults
+ val Success(results) =
+ multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedDesc)): @unchecked
+ val hits = results.summaryResults
results.totalCount should be(idsForLang("nb").size)
hits.head.id should be(3)
hits.last.id should be(5)
}
test("That all returns all documents ordered by lastUpdated ascending") {
- val Success(results) = multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedAsc))
- val hits = results.summaryResults
+ val Success(results) =
+ multiSearchService.matchingQuery(searchSettings.copy(sort = Sort.ByLastUpdatedAsc)): @unchecked
+ val hits = results.summaryResults
results.totalCount should be(idsForLang("nb").size)
hits.head.id should be(5)
hits(1).id should be(1)
@@ -182,9 +182,9 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That paging returns only hits on current page and not more than page-size") {
val Success(page1) =
- multiSearchService.matchingQuery(searchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByTitleAsc))
+ multiSearchService.matchingQuery(searchSettings.copy(page = 1, pageSize = 2, sort = Sort.ByTitleAsc)): @unchecked
val Success(page2) =
- multiSearchService.matchingQuery(searchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByTitleAsc))
+ multiSearchService.matchingQuery(searchSettings.copy(page = 2, pageSize = 2, sort = Sort.ByTitleAsc)): @unchecked
val hits1 = page1.summaryResults
val hits2 = page2.summaryResults
page1.totalCount should be(idsForLang("nb").size)
@@ -203,7 +203,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("bil").get), sort = Sort.ByRelevanceDesc)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(3)
hits.map(_.id) should be(Seq(1, 5, 3))
@@ -213,7 +213,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("bil").get), sort = Sort.ByRelevanceDesc, withIdIn = List(3))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(3)
@@ -224,7 +224,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("Pingvinen").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
val hits = results.summaryResults
hits.map(_.contexts.head.contextType) should be(Seq("learningpath", "standard"))
hits.map(_.id) should be(Seq(1, 2))
@@ -233,7 +233,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search matches tags") {
val Success(results) = multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("and").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(2)
hits.head.id should be(3)
@@ -245,7 +245,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("supermann").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
results.totalCount should be(0)
}
@@ -257,7 +257,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
license = Some(License.Copyrighted.toString),
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(4)
@@ -267,14 +267,14 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("bilde + bil").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
val hits1 = search1.summaryResults
hits1.map(_.id) should equal(Seq(1, 3, 5))
val Success(search2) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("batmen + bil").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
val hits2 = search2.summaryResults
hits2.map(_.id) should equal(Seq(1))
@@ -283,13 +283,13 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("Searching with NOT returns expected results") {
val Success(search1) = multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("bil + bilde + -flaggermusmann").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should equal(Seq(3, 5))
val Success(search2) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("bil + -hulken").get), sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
search2.summaryResults.map(_.id) should equal(Seq(1, 3))
}
@@ -297,7 +297,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("mareritt+ragnarok").get), sort = Sort.ByRelevanceDesc)
- )
+ ): @unchecked
val hits = search.summaryResults
hits.map(_.id) should equal(Seq(9, 8))
}
@@ -305,14 +305,14 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("Search for all languages should return all articles in different languages") {
val Success(search) = multiSearchService.matchingQuery(
searchSettings.copy(language = AllLanguages, pageSize = 100, sort = Sort.ByTitleAsc)
- )
+ ): @unchecked
search.totalCount should equal(titlesForLang("*").size)
}
test("Search for all languages should return all articles in correct language") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(language = AllLanguages, pageSize = 100))
+ multiSearchService.matchingQuery(searchSettings.copy(language = AllLanguages, pageSize = 100)): @unchecked
val hits = search.summaryResults
val exp = titlesForLang("*")
@@ -349,7 +349,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
pageSize = 100,
sort = Sort.ByTitleAsc
)
- )
+ ): @unchecked
val hits = search.summaryResults
search.totalCount should equal(1)
@@ -363,14 +363,14 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = AllLanguages,
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
val Success(searchNb) = multiSearchService.matchingQuery(
searchSettings.copy(
Some(NonEmptyString.fromString("Katter").get),
language = AllLanguages,
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
searchEn.totalCount should equal(1)
searchEn.summaryResults.head.id should equal(11)
@@ -386,7 +386,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("Searching for unknown language should return nothing") {
val Success(searchEn) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "mix", sort = Sort.ByRelevanceDesc))
+ multiSearchService.matchingQuery(searchSettings.copy(language = "mix", sort = Sort.ByRelevanceDesc)): @unchecked
searchEn.totalCount should equal(0)
}
@@ -398,7 +398,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = AllLanguages,
sort = Sort.ByRelevanceDesc
)
- )
+ ): @unchecked
search.totalCount should equal(1)
search.summaryResults.head.id should equal(11)
@@ -410,7 +410,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search) =
multiSearchService.matchingQuery(
searchSettings.copy(fallback = true, language = "en", withIdIn = List(9, 10, 11))
- )
+ ): @unchecked
search.totalCount should equal(3)
search.summaryResults.head.id should equal(9)
@@ -423,7 +423,9 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering for subjects works as expected") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "*", subjects = List("urn:subject:2")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(language = "*", subjects = List("urn:subject:2"))
+ ): @unchecked
search.totalCount should be(7)
search.summaryResults.head.contexts.length should be(2)
search.summaryResults.head.contexts
@@ -433,30 +435,38 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering for subjects returns all resources with any of listed subjects") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(subjects = List("urn:subject:2", "urn:subject:1")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(subjects = List("urn:subject:2", "urn:subject:1"))
+ ): @unchecked
search.totalCount should be(14)
search.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 11, 12))
}
test("That filtering for invisible subjects returns nothing") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(subjects = List("urn:subject:3")))
+ multiSearchService.matchingQuery(searchSettings.copy(subjects = List("urn:subject:3"))): @unchecked
search.totalCount should be(0)
}
test("That filtering for resource-types works as expected") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(resourceTypes = List("urn:resourcetype:academicArticle")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(resourceTypes = List("urn:resourcetype:academicArticle"))
+ ): @unchecked
search.totalCount should be(2)
search.summaryResults.map(_.id) should be(Seq(2, 5))
val Success(search2) =
- multiSearchService.matchingQuery(searchSettings.copy(resourceTypes = List("urn:resourcetype:subjectMaterial")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(resourceTypes = List("urn:resourcetype:subjectMaterial"))
+ ): @unchecked
search2.totalCount should be(7)
search2.summaryResults.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 12))
val Success(search3) =
- multiSearchService.matchingQuery(searchSettings.copy(resourceTypes = List("urn:resourcetype:learningpath")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(resourceTypes = List("urn:resourcetype:learningpath"))
+ ): @unchecked
search3.totalCount should be(4)
search3.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4))
}
@@ -464,7 +474,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering for multiple resource-types returns resources from both") {
val Success(search) = multiSearchService.matchingQuery(
searchSettings.copy(resourceTypes = List("urn:resourcetype:subjectMaterial", "urn:resourcetype:reviewResource"))
- )
+ ): @unchecked
search.totalCount should be(7)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 12))
}
@@ -472,10 +482,10 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering on learning-resource-type works") {
val Success(search) = multiSearchService.matchingQuery(
searchSettings.copy(language = "*", learningResourceTypes = List(LearningResourceType.Article))
- )
+ ): @unchecked
val Success(search2) = multiSearchService.matchingQuery(
searchSettings.copy(language = "*", learningResourceTypes = List(LearningResourceType.TopicArticle))
- )
+ ): @unchecked
search.totalCount should be(7)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 12))
@@ -487,13 +497,13 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering on article-type works") {
val Success(search) = multiSearchService.matchingQuery(
searchSettings.copy(language = "*", articleTypes = List(ArticleType.Standard.entryName))
- )
+ ): @unchecked
val Success(search2) = multiSearchService.matchingQuery(
searchSettings.copy(language = "*", articleTypes = List(ArticleType.TopicArticle.entryName))
- )
+ ): @unchecked
val Success(search3) = multiSearchService.matchingQuery(
searchSettings.copy(language = "*", articleTypes = List(ArticleType.FrontpageArticle.entryName))
- )
+ ): @unchecked
search.totalCount should be(7)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 12))
@@ -512,7 +522,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = "*",
learningResourceTypes = List(LearningResourceType.Article, LearningResourceType.TopicArticle)
)
- )
+ ): @unchecked
search.totalCount should be(11)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12))
@@ -521,7 +531,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering on learningpath learningresourcetype returns learningpaths") {
val Success(search) = multiSearchService.matchingQuery(
searchSettings.copy(language = "*", learningResourceTypes = List(LearningResourceType.LearningPath))
- )
+ ): @unchecked
search.totalCount should be(6)
search.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 5, 6))
@@ -537,7 +547,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = "*",
filterInactive = false
)
- )
+ ): @unchecked
val totalCount = search.totalCount
val ids = search.summaryResults.map(_.id).length
@@ -548,7 +558,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = "*",
filterInactive = true
)
- )
+ ): @unchecked
totalCount should be > search2.totalCount
ids should be > search2.summaryResults.map(_.id).length
@@ -557,24 +567,28 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering on supportedLanguages works") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "*", supportedLanguages = List("en")))
+ multiSearchService.matchingQuery(searchSettings.copy(language = "*", supportedLanguages = List("en"))): @unchecked
search.totalCount should be(8)
search.summaryResults.map(_.id) should be(Seq(2, 3, 4, 5, 6, 10, 11, 12))
val Success(search2) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "*", supportedLanguages = List("en", "nb")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(language = "*", supportedLanguages = List("en", "nb"))
+ ): @unchecked
search2.totalCount should be(18)
search2.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 14))
val Success(search3) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "*", supportedLanguages = List("nb")))
+ multiSearchService.matchingQuery(searchSettings.copy(language = "*", supportedLanguages = List("nb"))): @unchecked
search3.totalCount should be(15)
search3.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14))
}
test("That filtering on supportedLanguages should still prioritize the selected language") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "nb", supportedLanguages = List("en")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(language = "nb", supportedLanguages = List("en"))
+ ): @unchecked
search.totalCount should be(5)
search.summaryResults.map(_.id) should be(Seq(2, 3, 4, 11, 12))
@@ -582,7 +596,8 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That meta image are returned when searching") {
- val Success(search) = multiSearchService.matchingQuery(searchSettings.copy(language = "en", withIdIn = List(10)))
+ val Success(search) =
+ multiSearchService.matchingQuery(searchSettings.copy(language = "en", withIdIn = List(10))): @unchecked
search.totalCount should be(1)
search.summaryResults.head.id should be(10)
@@ -595,14 +610,14 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("Kjekspolitiet").get), language = AllLanguages)
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.map(_.id) should be(Seq(1))
val Success(search2) =
multiSearchService.matchingQuery(
searchSettings.copy(Some(NonEmptyString.fromString("Svims").get), language = AllLanguages)
- )
+ ): @unchecked
search2.totalCount should be(2)
search2.summaryResults.map(_.id) should be(Seq(2, 5))
}
@@ -610,12 +625,12 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering by relevance id makes sense (with and without subject/filter)") {
val Success(search1) = multiSearchService.matchingQuery(
searchSettings.copy(language = AllLanguages, relevanceIds = List("urn:relevance:core"))
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12))
val Success(search2) = multiSearchService.matchingQuery(
searchSettings.copy(language = AllLanguages, relevanceIds = List("urn:relevance:supplementary"))
- )
+ ): @unchecked
search2.summaryResults.map(_.id) should be(Seq(1, 2, 3, 4, 5, 12))
val Success(search3) = multiSearchService.matchingQuery(
@@ -623,7 +638,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
language = AllLanguages,
relevanceIds = List("urn:relevance:supplementary", "urn:relevance:core")
)
- )
+ ): @unchecked
search3.summaryResults.map(_.id) should be(Seq(1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12))
}
@@ -631,7 +646,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) = multiSearchService.matchingQuery(
searchSettings
.copy(language = AllLanguages, subjects = List("urn:subject:2"), relevanceIds = List("urn:relevance:core"))
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(1, 5, 6, 7, 11))
}
@@ -643,17 +658,17 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(initialSearch) =
multiSearchService.matchingQuery(
searchSettings.copy(language = AllLanguages, pageSize = pageSize, shouldScroll = true)
- )
-
- val Success(scroll1) = multiSearchService.scroll(initialSearch.scrollId.get, "*")
- val Success(scroll2) = multiSearchService.scroll(scroll1.scrollId.get, "*")
- val Success(scroll3) = multiSearchService.scroll(scroll2.scrollId.get, "*")
- val Success(scroll4) = multiSearchService.scroll(scroll3.scrollId.get, "*")
- val Success(scroll5) = multiSearchService.scroll(scroll4.scrollId.get, "*")
- val Success(scroll6) = multiSearchService.scroll(scroll5.scrollId.get, "*")
- val Success(scroll7) = multiSearchService.scroll(scroll6.scrollId.get, "*")
- val Success(scroll8) = multiSearchService.scroll(scroll7.scrollId.get, "*")
- val Success(scroll9) = multiSearchService.scroll(scroll8.scrollId.get, "*")
+ ): @unchecked
+
+ val Success(scroll1) = multiSearchService.scroll(initialSearch.scrollId.get, "*"): @unchecked
+ val Success(scroll2) = multiSearchService.scroll(scroll1.scrollId.get, "*"): @unchecked
+ val Success(scroll3) = multiSearchService.scroll(scroll2.scrollId.get, "*"): @unchecked
+ val Success(scroll4) = multiSearchService.scroll(scroll3.scrollId.get, "*"): @unchecked
+ val Success(scroll5) = multiSearchService.scroll(scroll4.scrollId.get, "*"): @unchecked
+ val Success(scroll6) = multiSearchService.scroll(scroll5.scrollId.get, "*"): @unchecked
+ val Success(scroll7) = multiSearchService.scroll(scroll6.scrollId.get, "*"): @unchecked
+ val Success(scroll8) = multiSearchService.scroll(scroll7.scrollId.get, "*"): @unchecked
+ val Success(scroll9) = multiSearchService.scroll(scroll8.scrollId.get, "*"): @unchecked
initialSearch.summaryResults.map(_.id) should be(ids.head)
scroll1.summaryResults.map(_.id) should be(ids(1))
@@ -669,9 +684,13 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filtering on context-types works") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(resourceTypes = List("urn:resourcetype:academicArticle")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(resourceTypes = List("urn:resourcetype:academicArticle"))
+ ): @unchecked
val Success(search2) =
- multiSearchService.matchingQuery(searchSettings.copy(resourceTypes = List("urn:resourcetype:movieAndClip")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(resourceTypes = List("urn:resourcetype:movieAndClip"))
+ ): @unchecked
search.totalCount should be(2)
search.summaryResults.map(_.id) should be(Seq(2, 5))
@@ -680,10 +699,10 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
}
test("That filtering on grepCodes returns articles which has grepCodes") {
- val Success(search1) = multiSearchService.matchingQuery(searchSettings.copy(grepCodes = List("KM123")))
- val Success(search2) = multiSearchService.matchingQuery(searchSettings.copy(grepCodes = List("KE12")))
+ val Success(search1) = multiSearchService.matchingQuery(searchSettings.copy(grepCodes = List("KM123"))): @unchecked
+ val Success(search2) = multiSearchService.matchingQuery(searchSettings.copy(grepCodes = List("KE12"))): @unchecked
val Success(search3) =
- multiSearchService.matchingQuery(searchSettings.copy(grepCodes = List("KM123", "KE34", "TT2")))
+ multiSearchService.matchingQuery(searchSettings.copy(grepCodes = List("KM123", "KE34", "TT2"))): @unchecked
search1.summaryResults.map(_.id) should be(Seq(1, 2, 3))
search2.summaryResults.map(_.id) should be(Seq(1, 5))
@@ -694,13 +713,15 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("\"utforsking og problemløysing\"").get))
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(1, 5))
}
test("That search result has traits if content has embeds") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(query = Some(NonEmptyString.fromString("Ekstrastoff").get)))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(query = Some(NonEmptyString.fromString("Ekstrastoff").get))
+ ): @unchecked
search.totalCount should be(1)
search.summaryResults.head.id should be(12)
search.summaryResults.head.traits should be(List(SearchTrait.H5p))
@@ -708,7 +729,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search can be filtered by traits") {
val Success(search) =
- multiSearchService.matchingQuery(searchSettings.copy(traits = List(SearchTrait.H5p)))
+ multiSearchService.matchingQuery(searchSettings.copy(traits = List(SearchTrait.H5p))): @unchecked
search.totalCount should be(1)
search.summaryResults.head.id should be(12)
search.summaryResults.head.traits should be(List(SearchTrait.H5p))
@@ -726,7 +747,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("Helse søster").get), language = AllLanguages)
- )
+ ): @unchecked
search1.summaryResults.map(_.id) should be(Seq(12))
search1.totalCount should be(1)
@@ -734,7 +755,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search2) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("Helse søster").get), language = "nb")
- )
+ ): @unchecked
search2.summaryResults.map(_.id) should be(Seq(12))
search2.totalCount should be(1)
@@ -743,7 +764,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That filterByNoResourceType works by filtering out every document that does not have resourceTypes") {
val Success(search1) = multiSearchService.matchingQuery(
searchSettings.copy(language = AllLanguages, sort = Sort.ByIdAsc, filterByNoResourceType = true)
- )
+ ): @unchecked
search1.summaryResults.map(_.id).sorted should be(Seq(6, 8, 9, 10, 11, 14))
}
@@ -751,20 +772,22 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("Bilsøster").get), language = AllLanguages)
- )
+ ): @unchecked
search1.totalCount should be(0)
}
test("That searches for embedResource does not partial match") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(embedResource = List("vid"), embedId = Some("55")))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(embedResource = List("vid"), embedId = Some("55"))
+ ): @unchecked
results.totalCount should be(0)
}
test("That searches for data-resource_id matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("66")))
+ multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("66"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -778,7 +801,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
embedResource = List("video"),
embedId = Some("77")
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -793,13 +816,13 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
embedResource = List("video"),
embedId = Some("77")
)
- )
+ ): @unchecked
results.totalCount should be(0)
}
test("That search on embed data-resource matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(embedResource = List("video")))
+ multiSearchService.matchingQuery(searchSettings.copy(embedResource = List("video"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -807,7 +830,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on embed data-content-id matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("111")))
+ multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("111"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -815,7 +838,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on embed data-url matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("http://test")))
+ multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("http://test"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -823,7 +846,9 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on query as embed data-resource_id matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(query = Some(NonEmptyString.fromString("77").get)))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(query = Some(NonEmptyString.fromString("77").get))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -831,7 +856,9 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on query as embed data-resouce matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(query = Some(NonEmptyString.fromString("video").get)))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(query = Some(NonEmptyString.fromString("video").get))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -839,7 +866,9 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on query as article id matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(query = Some(NonEmptyString.fromString("11").get)))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(query = Some(NonEmptyString.fromString("11").get))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(11)
@@ -847,7 +876,9 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on query as deleted context id matches") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(query = Some(NonEmptyString.fromString("asdf1255").get)))
+ multiSearchService.matchingQuery(
+ searchSettings.copy(query = Some(NonEmptyString.fromString("asdf1255").get))
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -855,7 +886,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on embed id with language filter does only return correct language") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "en", embedId = Some("222")))
+ multiSearchService.matchingQuery(searchSettings.copy(language = "en", embedId = Some("222"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(12)
@@ -863,7 +894,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on embed id with language filter=all matches ") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(language = AllLanguages, embedId = Some("222")))
+ multiSearchService.matchingQuery(searchSettings.copy(language = AllLanguages, embedId = Some("222"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(2)
hits.map(_.id) should be(Seq(11, 12))
@@ -871,7 +902,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on visual element id matches ") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("333")))
+ multiSearchService.matchingQuery(searchSettings.copy(embedId = Some("333"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(12))
@@ -879,7 +910,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
test("That search on meta image url matches ") {
val Success(results) =
- multiSearchService.matchingQuery(searchSettings.copy(language = "*", embedId = Some("442")))
+ multiSearchService.matchingQuery(searchSettings.copy(language = "*", embedId = Some("442"))): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(10))
@@ -889,7 +920,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("\"delt-streng\"").get), language = "*")
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(12))
@@ -899,7 +930,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("\"delt\\-streng\"").get), language = "*")
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(12))
@@ -912,7 +943,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some(NonEmptyString.fromString("\"delt!streng\" \"delt?streng\"").get),
language = "*"
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(11))
@@ -925,7 +956,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some(NonEmptyString.fromString("\"delt!streng\"+\"delt-streng\"").get),
language = "*"
)
- )
+ ): @unchecked
results.totalCount should be(0)
}
@@ -936,7 +967,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some(NonEmptyString.fromString("\"delt!streng\"+-\"delt-streng\"").get),
language = "*"
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(11))
@@ -946,7 +977,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("\"delt!streng\"+-katt").get), language = "*")
- )
+ ): @unchecked
results.totalCount should be(0)
}
@@ -954,7 +985,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("\"delt!streng\" + katt").get), language = "*")
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(11))
@@ -967,7 +998,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some(NonEmptyString.fromString("\"artikkeltekst med fire deler\"").get),
language = "*"
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.map(_.id) should be(Seq(10))
@@ -977,7 +1008,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(results) =
multiSearchService.matchingQuery(
searchSettings.copy(language = AllLanguages, embedResource = List("concept"), embedId = Some("222"))
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.id should be(11)
@@ -987,11 +1018,11 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) =
multiSearchService.matchingQuery(
searchSettings.copy(embedId = Some("test-id1"))
- )
+ ): @unchecked
val Success(search2) =
multiSearchService.matchingQuery(
searchSettings.copy(embedId = Some("http://test"))
- )
+ ): @unchecked
search1.totalCount should be(1)
search1.summaryResults.head.id should be(12)
@@ -1004,7 +1035,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
val Success(search1) =
multiSearchService.matchingQuery(
searchSettings.copy(query = Some(NonEmptyString.fromString("utilgjengelig").get), availability = List.empty)
- )
+ ): @unchecked
search1.totalCount should be(0)
search1.summaryResults.map(_.id) should be(Seq.empty)
@@ -1013,7 +1044,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some(NonEmptyString.fromString("utilgjengelig").get),
availability = List(Availability.everyone)
)
- )
+ ): @unchecked
search2.totalCount should be(0)
search2.summaryResults.map(_.id) should be(Seq.empty)
@@ -1022,7 +1053,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
query = Some(NonEmptyString.fromString("utilgjengelig").get),
availability = List(Availability.everyone, Availability.teacher)
)
- )
+ ): @unchecked
search3.totalCount should be(1)
search3.summaryResults.map(_.id) should be(Seq(13))
}
@@ -1035,7 +1066,7 @@ class MultiSearchServiceTest extends ElasticsearchIntegrationSuite with UnitSuit
sort = Sort.ByRelevanceDesc,
withIdIn = List(3)
)
- )
+ ): @unchecked
val hits = results.summaryResults
results.totalCount should be(1)
hits.head.lastUpdated should be(a[NDLADate])
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchConverterServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchConverterServiceTest.scala
index d3c1014684..1087229568 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchConverterServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchConverterServiceTest.scala
@@ -36,8 +36,8 @@ import scala.util.{Success, Try}
class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
- override val searchConverterService = new SearchConverterService
- val sampleArticle: Article = TestData.sampleArticleWithPublicDomain.copy()
+ override lazy val searchConverterService = new SearchConverterService
+ val sampleArticle: Article = TestData.sampleArticleWithPublicDomain.copy()
val titles: List[Title] = List(
Title("Bokmål tittel", "nb"),
@@ -129,7 +129,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article,
IndexingBundle(Some(TestData.emptyGrepBundle), Some(emptyBundle), Some(TestData.myndlaTestBundle))
- )
+ ): @unchecked
verifyTitles(searchableArticle)
}
@@ -139,7 +139,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article,
IndexingBundle(Some(TestData.emptyGrepBundle), Some(emptyBundle), Some(TestData.myndlaTestBundle))
- )
+ ): @unchecked
verifyArticles(searchableArticle)
}
@@ -149,7 +149,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article,
IndexingBundle(Some(TestData.emptyGrepBundle), Some(emptyBundle), Some(TestData.myndlaTestBundle))
- )
+ ): @unchecked
verifyTags(searchableArticle)
}
@@ -159,7 +159,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article,
IndexingBundle(Some(TestData.emptyGrepBundle), Some(emptyBundle), Some(TestData.myndlaTestBundle))
- )
+ ): @unchecked
verifyTitles(searchableArticle)
verifyArticles(searchableArticle)
@@ -175,7 +175,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable4) =
searchConverterService.asSearchableArticle(
TestData.article4,
@@ -184,7 +184,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable7) =
searchConverterService.asSearchableArticle(
TestData.article7,
@@ -193,7 +193,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchable2.contexts.head.resourceTypeIds.sorted should be(
Seq("urn:resourcetype:subjectMaterial", "urn:resourcetype:academicArticle").sorted
@@ -219,7 +219,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable4) =
searchConverterService.asSearchableArticle(
TestData.article4,
@@ -228,7 +228,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable6) =
searchConverterService.asSearchableArticle(
TestData.article6,
@@ -237,7 +237,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchable1.contexts.size should be(2)
searchable1.contexts.head.breadcrumbs.languageValues.map(_.value) should be(
@@ -289,7 +289,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable4) =
searchConverterService.asSearchableArticle(
TestData.article4,
@@ -298,7 +298,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable5) =
searchConverterService.asSearchableArticle(
TestData.article5,
@@ -307,7 +307,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchable1.contexts.size should be(2)
searchable1.contexts.map(_.domainObject.root.languageValues.map(_.value)) should be(
@@ -337,7 +337,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(taxonomyBundleInvisibleMetadata),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable4) =
searchConverterService.asSearchableArticle(
TestData.article4,
@@ -346,7 +346,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(taxonomyBundleInvisibleMetadata),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable5) =
searchConverterService.asSearchableArticle(
TestData.article5,
@@ -355,7 +355,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(taxonomyBundleInvisibleMetadata),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchable1.contexts.size should be(0)
searchable4.contexts.size should be(0)
@@ -377,7 +377,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(taxonomyBundleInvisibleMetadata),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable4) =
searchConverterService.asSearchableArticle(
TestData.article4,
@@ -386,7 +386,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(taxonomyBundleInvisibleMetadata),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable5) =
searchConverterService.asSearchableArticle(
TestData.article5,
@@ -395,7 +395,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(taxonomyBundleInvisibleMetadata),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchable1.contexts.size should be(0)
searchable4.contexts.size should be(0)
@@ -411,7 +411,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable4) =
searchConverterService.asSearchableArticle(
TestData.article4,
@@ -420,7 +420,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
val Success(searchable5) =
searchConverterService.asSearchableArticle(
TestData.article5,
@@ -429,7 +429,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchable1.contexts.size should be(2)
searchable4.contexts.size should be(1)
@@ -445,7 +445,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(TestData.taxonomyTestBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchable1.contexts.size should be(3)
}
@@ -465,7 +465,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
Some(emptyBundle),
Some(TestData.myndlaTestBundle)
)
- )
+ ): @unchecked
searchableArticle.grepContexts should equal(grepContexts)
}
@@ -484,7 +484,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article,
IndexingBundle(Some(TestData.grepBundle), Some(emptyBundle), Some(TestData.myndlaTestBundle))
- )
+ ): @unchecked
searchableArticle.grepContexts should equal(grepContexts)
}
@@ -496,7 +496,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article,
IndexingBundle(Some(TestData.grepBundle), Some(emptyBundle), Some(TestData.myndlaTestBundle))
- )
+ ): @unchecked
searchableArticle.grepContexts should equal(grepContexts)
}
@@ -511,7 +511,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableDraft(
draft,
IndexingBundle(Some(TestData.emptyGrepBundle), Some(emptyBundle), None)
- )
+ ): @unchecked
searchableArticle.grepContexts should equal(grepContexts)
}
@@ -576,7 +576,10 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
SearchableGrepContext("TT2", Some("tittel2"), "Published")
)
val Success(searchableArticle) =
- searchConverterService.asSearchableDraft(draft, IndexingBundle(Some(grepBundle), Some(emptyBundle), None))
+ searchConverterService.asSearchableDraft(
+ draft,
+ IndexingBundle(Some(grepBundle), Some(emptyBundle), None)
+ ): @unchecked
searchableArticle.grepContexts should equal(grepContexts)
}
@@ -626,7 +629,10 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
val grepContexts = List.empty
val Success(searchableArticle) =
- searchConverterService.asSearchableDraft(draft, IndexingBundle(Some(grepBundle), Some(emptyBundle), None))
+ searchConverterService.asSearchableDraft(
+ draft,
+ IndexingBundle(Some(grepBundle), Some(emptyBundle), None)
+ ): @unchecked
searchableArticle.grepContexts should equal(grepContexts)
}
@@ -647,7 +653,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article,
IndexingBundle(Some(TestData.emptyGrepBundle), Some(emptyBundle), None)
- )
+ ): @unchecked
searchableArticle.traits should equal(List(SearchTrait.H5p))
val article2 =
@@ -673,7 +679,7 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
searchConverterService.asSearchableArticle(
article2,
IndexingBundle(Some(TestData.emptyGrepBundle), Some(emptyBundle), None)
- )
+ ): @unchecked
searchableArticle2.traits should equal(List(SearchTrait.H5p, SearchTrait.Video))
}
@@ -754,7 +760,11 @@ class SearchConverterServiceTest extends UnitSuite with TestEnvironment {
SearchableGrepContext("KV123", Some("tittel123"), "Published")
)
val Success(searchableNode) =
- searchConverterService.asSearchableNode(node, None, IndexingBundle(Some(grepBundle), Some(emptyBundle), None))
+ searchConverterService.asSearchableNode(
+ node,
+ None,
+ IndexingBundle(Some(grepBundle), Some(emptyBundle), None)
+ ): @unchecked
searchableNode.grepContexts should equal(grepContexts)
}
diff --git a/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchServiceTest.scala b/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchServiceTest.scala
index bf4fd64c9d..2c0034405d 100644
--- a/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchServiceTest.scala
+++ b/search-api/src/test/scala/no/ndla/searchapi/service/search/SearchServiceTest.scala
@@ -13,10 +13,10 @@ import no.ndla.searchapi.{TestEnvironment, UnitSuite}
class SearchServiceTest extends UnitSuite with TestEnvironment {
- override val draftIndexService: DraftIndexService = new DraftIndexService {
+ override lazy val draftIndexService: DraftIndexService = new DraftIndexService {
override val indexShards = 1
}
- override val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
+ override lazy val learningPathIndexService: LearningPathIndexService = new LearningPathIndexService {
override val indexShards = 1
}
diff --git a/search/src/main/scala/no/ndla/search/BaseIndexService.scala b/search/src/main/scala/no/ndla/search/BaseIndexService.scala
index 66d71123b6..87eaec12dd 100644
--- a/search/src/main/scala/no/ndla/search/BaseIndexService.scala
+++ b/search/src/main/scala/no/ndla/search/BaseIndexService.scala
@@ -17,18 +17,18 @@ import com.sksamuel.elastic4s.requests.indexes.{CreateIndexRequest, IndexRequest
import com.sksamuel.elastic4s.requests.mappings.MappingDefinition
import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.configuration.HasBaseProps
-import no.ndla.common.implicits.TryQuestionMark
+import no.ndla.common.implicits.*
import no.ndla.search.model.domain.{BulkIndexResult, ElasticIndexingException, ReindexResult}
import java.text.SimpleDateFormat
import java.util.Calendar
import scala.util.{Failure, Success, Try}
+import scala.util.boundary
trait BaseIndexService {
this: Elastic4sClient & HasBaseProps & SearchLanguage =>
- trait BaseIndexService extends StrictLogging {
- import SearchLanguage.NynorskLanguageAnalyzer
+ abstract class BaseIndexService extends StrictLogging {
val documentType: String
val searchIndex: String
val MaxResultWindowOption: Int
@@ -38,7 +38,7 @@ trait BaseIndexService {
val analysis: Analysis =
Analysis(
- analyzers = List(NynorskLanguageAnalyzer),
+ analyzers = List(SearchLanguage.NynorskLanguageAnalyzer),
tokenFilters = SearchLanguage.NynorskTokenFilters
)
@@ -146,22 +146,24 @@ trait BaseIndexService {
def createIndexWithGeneratedName: Try[String] =
createIndexWithName(getNewIndexName())
- def reindexWithShards(numShards: Int): Try[?] = {
- logger.info(s"Internal reindexing $searchIndex with $numShards shards...")
- val maybeAliasTarget = getAliasTarget.?
- val currentIndex = maybeAliasTarget match {
- case Some(target) => target
- case None =>
- logger.info(s"No existing $searchIndex index to reindex from")
- return Success(())
- }
+ def reindexWithShards(numShards: Int): Try[?] = boundary {
+ permitTry {
+ logger.info(s"Internal reindexing $searchIndex with $numShards shards...")
+ val maybeAliasTarget = getAliasTarget.?
+ val currentIndex = maybeAliasTarget match {
+ case Some(target) => target
+ case None =>
+ logger.info(s"No existing $searchIndex index to reindex from")
+ boundary.break(Success(()))
+ }
- for {
- newIndex <- createIndexWithGeneratedName(numShards.some)
- _ = logger.info(s"Created index $newIndex for internal reindexing")
- _ <- e4sClient.execute(reindex(currentIndex, newIndex))
- _ <- updateAliasTarget(currentIndex.some, newIndex)
- } yield ()
+ for {
+ newIndex <- createIndexWithGeneratedName(numShards.some)
+ _ = logger.info(s"Created index $newIndex for internal reindexing")
+ _ <- e4sClient.execute(reindex(currentIndex, newIndex))
+ _ <- updateAliasTarget(currentIndex.some, newIndex)
+ } yield ()
+ }
}
def createIndexIfNotExists(): Try[?] = getAliasTarget.flatMap {
diff --git a/search/src/main/scala/no/ndla/search/Elastic4sClient.scala b/search/src/main/scala/no/ndla/search/Elastic4sClient.scala
index c81be5e56f..808caf108c 100644
--- a/search/src/main/scala/no/ndla/search/Elastic4sClient.scala
+++ b/search/src/main/scala/no/ndla/search/Elastic4sClient.scala
@@ -20,6 +20,7 @@ import java.util.concurrent.Executors
import scala.concurrent.duration.DurationInt
import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutor, Future}
import scala.util.{Failure, Success, Try}
+import scala.reflect.ClassTag
trait Elastic4sClient {
this: HasBaseProps =>
@@ -35,14 +36,19 @@ trait Elastic4sClient {
private val clientExecutionContext: ExecutionContextExecutor =
ExecutionContext.fromExecutor(Executors.newWorkStealingPool(props.MAX_SEARCH_THREADS))
- def executeAsync[T, U](
+ def executeAsync[T, U: ClassTag](
request: T
- )(implicit handler: Handler[T, U], mf: Manifest[U], ec: ExecutionContext): Future[Try[RequestSuccess[U]]] = {
- val result = client.execute(request).map {
- case failure: RequestFailure if failure.status == 409 =>
- Failure(DocumentConflictException(failure.error.reason))
- case failure: RequestFailure => Failure(NdlaSearchException(request, failure))
- case result: RequestSuccess[U] => Success(result)
+ )(implicit
+ handler: Handler[T, U],
+ ec: ExecutionContext
+ ): Future[Try[RequestSuccess[U]]] = {
+ val response = client.execute(request)
+ val result = response.map {
+ case RequestSuccess(status, body, headers, result) =>
+ Success(RequestSuccess[U](status, body, headers, result))
+ case RequestFailure(status, _, _, error) if status == 409 =>
+ Failure(DocumentConflictException(error.reason))
+ case failure: RequestFailure => Failure(NdlaSearchException(request, failure))
}
result.onComplete {
@@ -55,11 +61,11 @@ trait Elastic4sClient {
def executeBlocking[T, U](
request: T
- )(implicit handler: Handler[T, U], mf: Manifest[U], ec: ExecutionContext): Try[RequestSuccess[U]] = {
+ )(implicit handler: Handler[T, U], ct: ClassTag[U], ec: ExecutionContext): Try[RequestSuccess[U]] = {
Try(Await.result(this.executeAsync(request), elasticTimeout)).flatten
}
- def execute[T, U](request: T)(implicit handler: Handler[T, U], mf: Manifest[U]): Try[RequestSuccess[U]] = {
+ def execute[T, U](request: T)(implicit handler: Handler[T, U], ct: ClassTag[U]): Try[RequestSuccess[U]] = {
implicit val ec: ExecutionContextExecutor = clientExecutionContext
val future = this.executeAsync(request)
diff --git a/tapirtesting/src/main/scala/no/ndla/tapirtesting/TapirControllerTest.scala b/tapirtesting/src/main/scala/no/ndla/tapirtesting/TapirControllerTest.scala
index ca9ac6330b..a590260351 100644
--- a/tapirtesting/src/main/scala/no/ndla/tapirtesting/TapirControllerTest.scala
+++ b/tapirtesting/src/main/scala/no/ndla/tapirtesting/TapirControllerTest.scala
@@ -15,6 +15,7 @@ import no.ndla.network.NdlaClient
import no.ndla.network.clients.MyNDLAApiClient
import no.ndla.network.tapir.{Routes, TapirController, TapirErrorHandling}
import no.ndla.scalatestsuite.UnitTestSuite
+import scala.compiletime.uninitialized
trait TapirControllerTest
extends UnitTestSuite
@@ -29,7 +30,7 @@ trait TapirControllerTest
val controller: TapirController
override def services: List[TapirController] = List(controller)
- var server: HttpServer = _
+ var server: HttpServer = uninitialized
override def beforeAll(): Unit = {
super.beforeAll()
diff --git a/testbase/src/main/scala/no/ndla/testbase/TestSuiteLoggingSetup.scala b/testbase/src/main/scala/no/ndla/testbase/TestSuiteLoggingSetup.scala
index faf7bfe903..7c5c5bab03 100644
--- a/testbase/src/main/scala/no/ndla/testbase/TestSuiteLoggingSetup.scala
+++ b/testbase/src/main/scala/no/ndla/testbase/TestSuiteLoggingSetup.scala
@@ -53,10 +53,7 @@ trait TestSuiteLoggingSetup extends AnyFunSuite with BeforeAndAfterEach with Bef
}
private def shutdownLogger(): Unit = {
- LoggerContext.getContext(false) match {
- case context: LoggerContext => context.stop()
- case _ => println("No LoggerContext found, cannot stop logging context.")
- }
+ LoggerContext.getContext(false).stop()
}
override def withFixture(test: NoArgTest): Outcome = {
diff --git a/validation/src/main/scala/no/ndla/validation/TagValidator.scala b/validation/src/main/scala/no/ndla/validation/TagValidator.scala
index c24c786ca8..e912a7af22 100644
--- a/validation/src/main/scala/no/ndla/validation/TagValidator.scala
+++ b/validation/src/main/scala/no/ndla/validation/TagValidator.scala
@@ -9,6 +9,7 @@
package no.ndla.validation
import io.circe.parser
+import cats.implicits.*
import io.lemonlabs.uri.typesafe.dsl.*
import no.ndla.common.configuration.Constants.EmbedTagName
import no.ndla.common.errors.ValidationMessage
@@ -266,19 +267,19 @@ object TagValidator {
)
)
}
- tagRules.children.map(childrenRule => {
+ tagRules.children.flatMap(childrenRule => {
if (childrenRule.required && embed.childNodeSize() == 0) {
ValidationMessage(
fieldName,
s"Tag '$EmbedTagName' with `data-resource=$resourceType` requires at least one child."
- )
+ ).some
} else {
val childrenTagNames = embed.children().asScala.toList.map(_.tagName())
if (childrenRule.allowedChildren.isEmpty && childrenTagNames.nonEmpty) {
ValidationMessage(
fieldName,
s"Tag '$EmbedTagName' with `data-resource=$resourceType` can only have plaintext children."
- )
+ ).some
} else {
val onlyValidChildren = childrenTagNames.forall(tag => childrenRule.allowedChildren.get.contains(tag))
if (!onlyValidChildren) {
@@ -287,9 +288,9 @@ object TagValidator {
s"Tag '$EmbedTagName' with `data-resource=$resourceType` can only have the following children tags: [${childrenRule.allowedChildren
.getOrElse(List.empty)
.mkString(", ")}]."
- )
+ ).some
} else {
- return None
+ None
}
}
}