From f36fa22391cd0bde1857af9df089c1bbaac5e4c1 Mon Sep 17 00:00:00 2001 From: mkr Date: Wed, 26 Jun 2024 08:09:28 +0200 Subject: [PATCH] Update to Play 3.0, Scala 2.13 and JDK 17 * Bumping pac4j to 6.x and play-pac4j to 12.x * Play 3.0 includes the akka -> pekko transition * Explicit scalatest/scalatestplus dependencies * Docker base image bumped to eclipse-temurin:17-jre-focal --- Dockerfile | 7 +++- app/controllers/ApiController.scala | 26 +++++++------ app/models/DatabaseExecutionContext.scala | 2 +- app/models/SearchManagementRepository.scala | 2 +- app/models/config/TargetEnvironment.scala | 2 +- app/models/eventhistory/ActivityLog.scala | 2 +- app/models/input/TagInputAssociation.scala | 2 +- .../querqy/QuerqyRulesTxtGenerator.scala | 4 +- app/models/rules/Rule.scala | 3 +- app/models/rules/SynonymRule.scala | 2 +- .../spellings/AlternativeSpelling.scala | 2 +- .../CanonicalSpellingValidator.scala | 1 + .../ConfiguredBasicAuthAuthenticator.scala | 16 +++++--- app/modules/SecurityModule.scala | 38 ++++++++++++------- app/services/RulesTxtImportService.scala | 4 +- app/services/RulesUsageService.scala | 2 +- build.sbt | 17 ++++----- conf/application.conf | 2 +- conf/routes | 2 +- project/build.properties | 2 +- project/plugins.sbt | 2 +- test/controllers/HealthControllerSpec.scala | 2 +- test/models/DBCompatibilitySpec.scala | 6 ++- test/models/InputTagSpec.scala | 6 ++- test/models/QuerqyRulesTxtGeneratorSpec.scala | 10 ++--- test/models/SearchInputWithRulesSpec.scala | 5 ++- .../SearchManagementRepositorySpec.scala | 5 ++- test/models/SolrIndexSpec.scala | 5 ++- test/models/SuggestedSolrFieldSpec.scala | 5 ++- .../CustomUpDownDropdownMappingsSpec.scala | 5 ++- test/models/config/SmuiVersionSpec.scala | 7 ++-- .../config/TargetEnvironmentConfigSpec.scala | 7 ++-- .../DeactivatedEventHistorySpec.scala | 7 ++-- .../eventhistory/EventHistorySpec.scala | 5 ++- test/models/input/InputValidatorSpec.scala | 5 ++- .../QuerqyExactMatchRulesGeneratorSpec.scala | 9 ++--- .../QuerqyReplaceRulesGeneratorSpec.scala | 5 ++- test/models/rules/DeleteRuleSpec.scala | 5 ++- test/models/rules/FilterRuleSpec.scala | 5 ++- test/models/rules/RedirectRuleSpec.scala | 5 ++- test/models/rules/SynonymRuleSpec.scala | 5 ++- test/models/rules/UpDownRuleSpec.scala | 5 ++- .../CanonicalSpellingValidatorSpec.scala | 5 ++- test/routes/ApiRoutesSpec.scala | 5 ++- ...tDeploymentServiceConfigVariantsSpec.scala | 16 ++++---- .../RulesTxtDeploymentServiceSimpleSpec.scala | 5 ++- test/services/RulesTxtImportServiceSpec.scala | 5 ++- ...viceWithTaggingAndPredefinedTagsSpec.scala | 5 ++- ...WithTaggingWithoutPredefinedTagsSpec.scala | 5 ++- 49 files changed, 174 insertions(+), 131 deletions(-) diff --git a/Dockerfile b/Dockerfile index 166eee99..53a73a36 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,11 @@ # syntax = docker/dockerfile:1.0-experimental -FROM openjdk:11-buster as builder +FROM eclipse-temurin:17-jdk-focal as builder ARG NODE_VERSION=16 +RUN apt-get update \ + && apt-get install -y curl gnupg + RUN echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list \ && curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | apt-key add \ && apt-get update \ @@ -22,7 +25,7 @@ WORKDIR /smui RUN --mount=target=/root/.ivy2,type=cache sbt "set assembly / test := {}" clean assembly -FROM openjdk:11-jre-slim-buster +FROM eclipse-temurin:17-jre-focal RUN apt-get update \ && apt-get install -y --no-install-recommends openssh-client sshpass bash curl git \ diff --git a/app/controllers/ApiController.scala b/app/controllers/ApiController.scala index 3a46e3cf..caed3737 100644 --- a/app/controllers/ApiController.scala +++ b/app/controllers/ApiController.scala @@ -1,8 +1,8 @@ package controllers import java.io.{OutputStream, PipedInputStream, PipedOutputStream} -import akka.stream.scaladsl.{Source, StreamConverters} -import akka.util.ByteString +import org.apache.pekko.stream.scaladsl.{Source, StreamConverters} +import org.apache.pekko.util.ByteString import javax.inject.Inject import play.api.Logging @@ -14,7 +14,6 @@ import java.nio.file.Paths import java.time.format.DateTimeFormatter import java.time.LocalDateTime import scala.concurrent.{ExecutionContext, Future} -import collection.JavaConverters._ import models.FeatureToggleModel.FeatureToggleService import models._ import models.config.SmuiVersion @@ -24,10 +23,11 @@ import models.querqy.QuerqyRulesTxtGenerator import models.reports.RulesUsageReport import models.rules.{DeleteRule, FilterRule, RedirectRule, SynonymRule, UpDownRule} import models.spellings.{CanonicalSpellingId, CanonicalSpellingValidator, CanonicalSpellingWithAlternatives} -import org.pac4j.core.profile.{ProfileManager, UserProfile} -import org.pac4j.play.PlayWebContext +import org.pac4j.core.profile.UserProfile +import org.pac4j.play.context.PlayFrameworkParameters import org.pac4j.play.scala.{Security, SecurityComponents} import play.api.libs.Files +import scala.jdk.CollectionConverters.ListHasAsScala import services.{RulesTxtDeploymentService, RulesTxtImportService, RulesUsageService} @@ -48,7 +48,7 @@ class ApiController @Inject()(val controllerComponents: SecurityComponents, case class ApiResult(result: String, message: String, returnId: Option[Id]) - implicit val apiResultWrites = Json.writes[ApiResult] + implicit val apiResultWrites: OWrites[ApiResult] = Json.writes[ApiResult] def getFeatureToggles: Action[AnyContent] = Action { Ok(Json.toJson(featureToggleService.getJsFrontendToggleList)) @@ -411,7 +411,7 @@ class ApiController @Inject()(val controllerComponents: SecurityComponents, rules_txt.ref.copyTo(Paths.get(tmp_file_path), replace = true) // process rules.txt file val bufferedSource = scala.io.Source.fromFile(tmp_file_path) - val filePayload = bufferedSource.getLines.mkString("\n") + val filePayload = bufferedSource.getLines().mkString("\n") try { val importStatistics = rulesTxtImportService.importFromFilePayload(filePayload, SolrIndexId(solrIndexId)) val apiResultMsg = "Import from rules.txt file successful with following statistics:\n" + @@ -442,7 +442,7 @@ class ApiController @Inject()(val controllerComponents: SecurityComponents, case class DeploymentInfo(msg: Option[String]) - implicit val logDeploymentInfoWrites = Json.writes[DeploymentInfo] + implicit val logDeploymentInfoWrites: OWrites[DeploymentInfo] = Json.writes[DeploymentInfo] @deprecated("The old style of retrieving a deployment log summary as plain text will be removed", "SMUI version > 3.15.1") def getLatestDeploymentResultV1(solrIndexId: String, targetSystem: String): Action[AnyContent] = Action.async { request: Request[AnyContent] => @@ -490,7 +490,7 @@ class ApiController @Inject()(val controllerComponents: SecurityComponents, case class DeploymentDetailedInfo(targetSystem: String, formattedDateTime: String, result: Int) - implicit val logDeploymentDetailedInfoWrites = Json.writes[DeploymentDetailedInfo] + implicit val logDeploymentDetailedInfoWrites: OWrites[DeploymentDetailedInfo] = Json.writes[DeploymentDetailedInfo] def getLatestDeploymentResult(solrIndexId: String): Action[AnyContent] = Action.async { request: Request[AnyContent] => Future { @@ -543,7 +543,7 @@ class ApiController @Inject()(val controllerComponents: SecurityComponents, val ERROR = Value("ERROR") } - implicit val smuiVersionInfoWrites = Json.writes[SmuiVersionInfo] + implicit val smuiVersionInfoWrites: OWrites[SmuiVersionInfo] = Json.writes[SmuiVersionInfo] // TODO consider outsourcing this "business logic" into the (config) model def getLatestVersionInfo() = Action.async { @@ -686,8 +686,10 @@ class ApiController @Inject()(val controllerComponents: SecurityComponents, } private def getProfiles(request: RequestHeader): List[UserProfile] = { - val webContext = new PlayWebContext(request) - val profileManager = new ProfileManager(webContext, controllerComponents.sessionStore) + val parameters = new PlayFrameworkParameters(request) + val webContext = controllerComponents.config.getWebContextFactory.newContext(parameters) + val sessionStore = controllerComponents.config.getSessionStoreFactory.newSessionStore(parameters) + val profileManager = controllerComponents.config.getProfileManagerFactory.apply(webContext, sessionStore) profileManager.getProfiles.asScala.toList } diff --git a/app/models/DatabaseExecutionContext.scala b/app/models/DatabaseExecutionContext.scala index ef2c7703..dec2cc42 100644 --- a/app/models/DatabaseExecutionContext.scala +++ b/app/models/DatabaseExecutionContext.scala @@ -2,7 +2,7 @@ package models import javax.inject._ -import akka.actor.ActorSystem +import org.apache.pekko.actor.ActorSystem import play.api.libs.concurrent.CustomExecutionContext /** diff --git a/app/models/SearchManagementRepository.scala b/app/models/SearchManagementRepository.scala index aa8b6771..3308a5ef 100644 --- a/app/models/SearchManagementRepository.scala +++ b/app/models/SearchManagementRepository.scala @@ -46,7 +46,7 @@ class SearchManagementRepository @Inject()(dbapi: DBApi, toggleService: FeatureT def deleteSolrIndex(solrIndexId: String): Int = db.withTransaction { implicit connection => val solrIndexIdId = SolrIndexId(solrIndexId) - val inputTags = InputTag.loadAll.filter(_.solrIndexId== Option(solrIndexIdId)) + val inputTags = InputTag.loadAll().filter(_.solrIndexId== Option(solrIndexIdId)) if (inputTags.size > 0) { throw new Exception("Can't delete rules collection that has " + inputTags.size + "tags existing"); } diff --git a/app/models/config/TargetEnvironment.scala b/app/models/config/TargetEnvironment.scala index 95a4495c..130f9a66 100644 --- a/app/models/config/TargetEnvironment.scala +++ b/app/models/config/TargetEnvironment.scala @@ -36,7 +36,7 @@ package object TargetEnvironment extends Logging { implicit val jsonFormatTargetEnvironmentGroup: OFormat[TargetEnvironmentGroup] = Json.format[TargetEnvironmentGroup] implicit val jsonFormatTargetEnvironmentInstance: OFormat[TargetEnvironmentInstance] = Json.format[TargetEnvironmentInstance] - implicit val jsonFormatTargetEnvironmentConfig = new Format[ Seq[TargetEnvironmentInstance] ] { + implicit val jsonFormatTargetEnvironmentConfig: Format[Seq[TargetEnvironmentInstance]] = new Format[Seq[TargetEnvironmentInstance] ] { def writes(targetEnvironmentConfig: Seq[TargetEnvironmentInstance]): JsValue = JsArray( diff --git a/app/models/eventhistory/ActivityLog.scala b/app/models/eventhistory/ActivityLog.scala index 66ac442b..d207eab2 100644 --- a/app/models/eventhistory/ActivityLog.scala +++ b/app/models/eventhistory/ActivityLog.scala @@ -93,7 +93,7 @@ object ActivityLog extends Logging { private def diffTermStatus(entity: String, beforeTerm: String, beforeStatus: Boolean, afterTerm: String, afterStatus: Boolean, smuiEventType: SmuiEventType.Value): Option[DiffSummary] = { val termDiff = if (beforeTerm.trim.equals(afterTerm.trim)) None else Some(afterTerm.trim) - val statDiff = if (beforeStatus.equals(afterStatus)) None else Some(afterStatus) + val statDiff = if (beforeStatus == afterStatus) None else Some(afterStatus) if (termDiff.isDefined || statDiff.isDefined) { diff --git a/app/models/input/TagInputAssociation.scala b/app/models/input/TagInputAssociation.scala index 2e2b393d..53ea2beb 100644 --- a/app/models/input/TagInputAssociation.scala +++ b/app/models/input/TagInputAssociation.scala @@ -60,7 +60,7 @@ object TagInputAssociation { map { case tag ~ inputId => inputId -> tag } - }.groupBy(_._1).mapValues(_.map(_._2)) + }.groupBy(_._1).view.mapValues(_.map(_._2)).toMap } def deleteBySearchInputId(id: SearchInputId)(implicit connection: Connection): Int = { diff --git a/app/models/querqy/QuerqyRulesTxtGenerator.scala b/app/models/querqy/QuerqyRulesTxtGenerator.scala index 75719e83..57abe640 100644 --- a/app/models/querqy/QuerqyRulesTxtGenerator.scala +++ b/app/models/querqy/QuerqyRulesTxtGenerator.scala @@ -110,11 +110,11 @@ class QuerqyRulesTxtGenerator @Inject()(searchManagementRepository: SearchManage } if (featureToggleService.isRuleTaggingActive) { val tagsByProperty = searchInput.tags.filter(i => i.exported && i.property.nonEmpty).groupBy(_.property.get) - jsonProperties ++= tagsByProperty.mapValues(tags => Json.toJsFieldJsValueWrapper(tags.map(_.value))).toSeq + jsonProperties ++= tagsByProperty.view.mapValues(tags => Json.toJsFieldJsValueWrapper(tags.map(_.value))).toSeq } if (jsonProperties.nonEmpty) { - retSearchInputRulesTxtPartial.append(renderJsonProperties(jsonProperties)) + retSearchInputRulesTxtPartial.append(renderJsonProperties(jsonProperties.toSeq)) } retSearchInputRulesTxtPartial.toString() diff --git a/app/models/rules/Rule.scala b/app/models/rules/Rule.scala index ec91160b..1760fc3e 100644 --- a/app/models/rules/Rule.scala +++ b/app/models/rules/Rule.scala @@ -55,7 +55,8 @@ trait RuleObject[T <: Rule] extends CommonRuleFields { val sqlParser: RowParser[T] - def updateForSearchInput(searchInputId: SearchInputId, rules: Seq[T])(implicit connection: Connection) { + def updateForSearchInput(searchInputId: SearchInputId, rules: Seq[T]) + (implicit connection: Connection): Unit = { // TODO consider to really determine an update/delete diff to ensure that last_update timestamps only updated for affected rules SQL"delete from #$TABLE_NAME where #$SEARCH_INPUT_ID = $searchInputId".execute() diff --git a/app/models/rules/SynonymRule.scala b/app/models/rules/SynonymRule.scala index e1515382..3684fa5b 100644 --- a/app/models/rules/SynonymRule.scala +++ b/app/models/rules/SynonymRule.scala @@ -49,7 +49,7 @@ object SynonymRule extends RuleObjectWithTerm[SynonymRule] { SQL"select * from #$TABLE_NAME where #$TYPE = #$TYPE_UNDIRECTED AND #$SEARCH_INPUT_ID in ($idGroup)".as((sqlParser ~ get[SearchInputId](SEARCH_INPUT_ID)).*).map { case rule ~ id => id -> rule } - }.groupBy(_._1).mapValues(_.map(_._2)) + }.groupBy(_._1).view.mapValues(_.map(_._2)).toMap } override def createWithNewIdFrom(rule: SynonymRule): SynonymRule = { diff --git a/app/models/spellings/AlternativeSpelling.scala b/app/models/spellings/AlternativeSpelling.scala index 0fb8102f..52b5a7d0 100644 --- a/app/models/spellings/AlternativeSpelling.scala +++ b/app/models/spellings/AlternativeSpelling.scala @@ -79,6 +79,6 @@ object AlternativeSpelling { SQL"select * from #$TABLE_NAME where #$CANONICAL_SPELLING_ID in ($idGroup)".as((sqlParser ~ get[CanonicalSpellingId](CANONICAL_SPELLING_ID)).*).map { case alternativeSpelling ~ id => id -> alternativeSpelling } - }.groupBy(_._1).mapValues(_.map(_._2)) + }.groupBy(_._1).view.mapValues(_.map(_._2)).toMap } } diff --git a/app/models/spellings/CanonicalSpellingValidator.scala b/app/models/spellings/CanonicalSpellingValidator.scala index 39e35757..19204da3 100644 --- a/app/models/spellings/CanonicalSpellingValidator.scala +++ b/app/models/spellings/CanonicalSpellingValidator.scala @@ -95,6 +95,7 @@ object CanonicalSpellingValidator { val allSpellings = allCanonicalSpellings .flatMap(canonical => canonical.alternativeSpellings.map(alternative => alternative.term.toLowerCase.trim -> canonical.term.toLowerCase.trim)) .groupBy(_._1) + .view .mapValues(_.map(_._2)) allSpellings.get(canonical).map { canonicalsHavingThatAlternative => s"Canonical spelling $canonical is already an alternative spelling of ${canonicalsHavingThatAlternative.mkString(",")}" diff --git a/app/modules/ConfiguredBasicAuthAuthenticator.scala b/app/modules/ConfiguredBasicAuthAuthenticator.scala index f8c64dc5..54971988 100644 --- a/app/modules/ConfiguredBasicAuthAuthenticator.scala +++ b/app/modules/ConfiguredBasicAuthAuthenticator.scala @@ -1,21 +1,24 @@ package modules -import org.pac4j.core.context.WebContext -import org.pac4j.core.context.session.SessionStore -import org.pac4j.core.credentials.{Credentials, UsernamePasswordCredentials} +import org.pac4j.core.context.CallContext import org.pac4j.core.credentials.authenticator.Authenticator +import org.pac4j.core.credentials.{Credentials, UsernamePasswordCredentials} import org.pac4j.core.exception.CredentialsException import org.pac4j.core.profile.CommonProfile import org.pac4j.core.util.{CommonHelper, Pac4jConstants} +import java.util.Optional + case class ConfiguredBasicAuthAuthenticator(validUserId: String, validPassword: String) extends Authenticator { - override def validate(credentials: Credentials, context: WebContext, sessionStore: SessionStore): Unit = { + override def validate(callContext: CallContext, credentials: Credentials): Optional[Credentials] = { + import scala.jdk.javaapi.OptionConverters + if (credentials == null) throw new CredentialsException("No credential") val userCredentials = credentials.asInstanceOf[UsernamePasswordCredentials] - val username = userCredentials.getUsername() - val password = userCredentials.getPassword() + val username = userCredentials.getUsername + val password = userCredentials.getPassword if (CommonHelper.isBlank(username)) throw new CredentialsException("Username cannot be blank") if (CommonHelper.isBlank(password)) throw new CredentialsException("Password cannot be blank") if (CommonHelper.areNotEquals(username.toLowerCase, validUserId.toLowerCase)) throw new CredentialsException("Username : '" + username + "' does not match valid user") @@ -24,6 +27,7 @@ case class ConfiguredBasicAuthAuthenticator(validUserId: String, validPassword: profile.setId(username) profile.addAttribute(Pac4jConstants.USERNAME, username) userCredentials.setUserProfile(profile) + OptionConverters.toJava(Some(userCredentials)) } } diff --git a/app/modules/SecurityModule.scala b/app/modules/SecurityModule.scala index 8af1d785..7b121782 100644 --- a/app/modules/SecurityModule.scala +++ b/app/modules/SecurityModule.scala @@ -1,15 +1,19 @@ package modules import com.google.inject.{AbstractModule, Provides} -import org.pac4j.core.client.{Client, Clients} +import org.pac4j.core.client.Clients import org.pac4j.core.client.direct.AnonymousClient import org.pac4j.core.config.Config -import org.pac4j.core.context.session.SessionStore +import org.pac4j.core.context.FrameworkParameters +import org.pac4j.core.context.session.{SessionStore, SessionStoreFactory} import org.pac4j.core.profile.CommonProfile +import org.pac4j.core.profile.factory.ProfileManagerFactory import org.pac4j.http.client.direct.DirectBasicAuthClient +import org.pac4j.play.context.PlayContextFactory +import org.pac4j.play.http.PlayHttpActionAdapter import org.pac4j.play.scala.{DefaultSecurityComponents, Pac4jScalaTemplateHelper, SecurityComponents} import org.pac4j.play.store.{PlayCookieSessionStore, ShiroAesDataEncrypter} -import org.pac4j.play.{CallbackController, LogoutController} +import org.pac4j.play.{CallbackController, LogoutController, PlayWebContext} import org.pac4j.saml.client.SAML2Client import org.pac4j.saml.config.SAML2Configuration import play.api.{Configuration, Environment} @@ -42,23 +46,31 @@ class SecurityModule(environment: Environment, configuration: Configuration) ext } @Provides - def provideConfig(): Config = { + def provideConfig(sessionStore: SessionStore): Config = { val maybeConfiguredClientName = configuration.getOptional[String](ConfigKeyAuthClient).filter(_.nonEmpty) - val config: Option[Config] = maybeConfiguredClientName.map { - case "DirectBasicAuthClient" => createConfiguredDirectBasicAuthConfig(s"$ConfigKeyPrefixClientConfig.ConfiguredDirectBasicAuthClient") - case "SAML2Client" => createSaml2Config(s"$ConfigKeyPrefixClientConfig.SAML2Client") + val maybeClients = maybeConfiguredClientName.map { + case "DirectBasicAuthClient" => createConfiguredDirectBasicAuthClient(s"$ConfigKeyPrefixClientConfig.ConfiguredDirectBasicAuthClient") + case "SAML2Client" => createSaml2Client(s"$ConfigKeyPrefixClientConfig.SAML2Client") case other => throw new RuntimeException(s"Unsupported auth client config value: $other") } - config.getOrElse(new Config()) + val config = new Config() + for (clients <- maybeClients) { + config.setClients(clients) + } + config.setSessionStoreFactory((_: FrameworkParameters) => sessionStore) + config.setHttpActionAdapter(PlayHttpActionAdapter.INSTANCE) + config.setWebContextFactory(PlayContextFactory.INSTANCE) + config.setProfileManagerFactory(ProfileManagerFactory.DEFAULT) + config } - private def createConfiguredDirectBasicAuthConfig(keyPrefix: String): Config = { + private def createConfiguredDirectBasicAuthClient(keyPrefix: String): Clients = { val username = configuration.get[String](s"$keyPrefix.username") val password = configuration.get[String](s"$keyPrefix.password") - new Config(new DirectBasicAuthClient(ConfiguredBasicAuthAuthenticator(username, password))) + new Clients(new DirectBasicAuthClient(ConfiguredBasicAuthAuthenticator(username, password))) } - private def createSaml2Config(keyPrefix: String): Config = { + private def createSaml2Client(keyPrefix: String): Clients = { val cfg = new SAML2Configuration( configuration.get[String](s"$keyPrefix.keystore"), configuration.get[String](s"$keyPrefix.keystorePassword"), @@ -68,10 +80,8 @@ class SecurityModule(environment: Environment, configuration: Configuration) ext cfg.setServiceProviderEntityId(configuration.get[String](s"$keyPrefix.serviceProviderEntityId")) cfg.setServiceProviderMetadataPath(configuration.get[String](s"$keyPrefix.serviceProviderMetadataPath")) cfg.setMaximumAuthenticationLifetime(configuration.get[Long](s"$keyPrefix.maximumAuthenticationLifetime")) - val allClients = Option(new SAML2Client(cfg)).toSeq :+ new AnonymousClient() // callback URL path as configured in `routes` - val clients = new Clients(s"$baseUrl/callback", allClients:_*) - new Config(clients) + new Clients(s"$baseUrl/callback", new SAML2Client(cfg), new AnonymousClient) } } diff --git a/app/services/RulesTxtImportService.scala b/app/services/RulesTxtImportService.scala index 53b49f88..8cdb2ef7 100644 --- a/app/services/RulesTxtImportService.scala +++ b/app/services/RulesTxtImportService.scala @@ -220,7 +220,7 @@ class RulesTxtImportService @Inject() (querqyRulesTxtGenerator: QuerqyRulesTxtGe def tagsFingerprint(input: PreliminarySearchInput): String = { //Sorting is necessary because play.api.libs.json considers JsArray with same elements but different ordering as not equal. (behaviour tested up to play version 2.8.8) def sortArrays(json: JsValue): JsValue = json match { - case JsObject(obj) => JsObject(obj.toMap.mapValues(sortArrays(_)).toList) + case JsObject(obj) => JsObject(obj.toMap.view.mapValues(sortArrays).toList) case JsArray(arr) => JsArray(arr.map(sortArrays).sortBy(_.toString)) case other => other } @@ -257,7 +257,7 @@ class RulesTxtImportService @Inject() (querqyRulesTxtGenerator: QuerqyRulesTxtGe if(a_synonymRule.term == b_input.term) { println("^-- Found according synonym on " + b_input.term + " in = " + a_synonymRule) a_synonymRule.asInstanceOf[PreliminarySynonymRule].synonymType = SynonymRule.TYPE_UNDIRECTED - break + break() } } skip_i += j diff --git a/app/services/RulesUsageService.scala b/app/services/RulesUsageService.scala index be5ca69b..c700ebd9 100644 --- a/app/services/RulesUsageService.scala +++ b/app/services/RulesUsageService.scala @@ -5,7 +5,7 @@ import org.apache.commons.csv.CSVFormat import play.api.{Configuration, Logging} import javax.inject.Inject -import scala.collection.JavaConverters.iterableAsScalaIterableConverter +import scala.jdk.CollectionConverters.IterableHasAsScala case class RulesUsage(inputId: SearchInputId, keywords: String, diff --git a/build.sbt b/build.sbt index 5e3c813d..225acc48 100644 --- a/build.sbt +++ b/build.sbt @@ -1,10 +1,10 @@ import com.typesafe.sbt.GitBranchPrompt name := "search-management-ui" -version := "4.1.2" +version := "4.2.0" maintainer := "Contact productful.io " -scalaVersion := "2.12.17" +scalaVersion := "2.13.14" ThisBuild / evictionErrorLevel := Level.Info @@ -40,7 +40,7 @@ resolvers ++= Seq( ) lazy val JacksonVersion = "2.15.2" -lazy val Pac4jVersion = "5.7.1" +lazy val Pac4jVersion = "6.0.4" lazy val JacksonCoreExclusion = ExclusionRule(organization = "com.fasterxml.jackson.core") @@ -64,18 +64,16 @@ libraryDependencies ++= { "org.postgresql" % "postgresql" % "42.5.1", "org.xerial" % "sqlite-jdbc" % "3.40.0.0", "org.playframework.anorm" %% "anorm" % "2.7.0", - "com.typesafe.play" %% "play-json" % "2.9.3", - "com.pauldijou" %% "jwt-play" % "4.1.0", "com.fasterxml.jackson.module" %% "jackson-module-scala" % JacksonVersion, "org.apache.commons" % "commons-csv" % "1.10.0", "org.apache.shiro" % "shiro-core" % "1.12.0", "org.pac4j" % "pac4j-http" % Pac4jVersion excludeAll (JacksonCoreExclusion, BcProv15Exclusion, SpringJclBridgeExclusion), "org.pac4j" % "pac4j-saml" % Pac4jVersion excludeAll (JacksonCoreExclusion, BcProv15Exclusion, SpringJclBridgeExclusion), - "org.pac4j" %% "play-pac4j" % "11.1.0-PLAY2.8", + "org.pac4j" %% "play-pac4j" % "12.0.0-PLAY3.0", "com.google.cloud" % "google-cloud-storage" % "2.33.0", - "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.0" % Test, - "org.mockito" % "mockito-all" % "1.10.19" % Test, - "com.pauldijou" %% "jwt-play" % "4.1.0", + "org.scalatest" %% "scalatest" % "3.2.18" % Test, + "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test, + "org.scalatestplus" %% "mockito-5-10" % "3.2.18.0" % Test, "com.h2database" % "h2" % "1.4.197" % Test, // H2 DB for testing // Other databases as docker containers for testing with specific databases "com.dimafeng" %% "testcontainers-scala" % "0.40.11" % Test, @@ -106,6 +104,7 @@ assembly / assemblyMergeStrategy := { case x if x.endsWith(".proto") => MergeStrategy.first case "play/reference-overrides.conf" => MergeStrategy.concat case PathList("META-INF", "spring.factories") => MergeStrategy.concat + case PathList("META-INF", "spring", "aot.factories") => MergeStrategy.concat case x => val oldStrategy = (assembly / assemblyMergeStrategy).value oldStrategy(x) diff --git a/conf/application.conf b/conf/application.conf index f8dffc59..b8065618 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -109,7 +109,7 @@ toggle.ui-concept.custom.up-down-dropdown-mappings=${?SMUI_CUSTOM_UPDOWN_MAPPING # application instance specific: Play Filter / Security configuration # ~~~~~ -play.http.secret.key="generated application secret" +play.http.secret.key="dummy application secret with some higher entropy" play.http.secret.key=${?SMUI_PLAY_APPLICATION_SECRET} diff --git a/conf/routes b/conf/routes index 3ac9fa9b..bd9e6a0b 100644 --- a/conf/routes +++ b/conf/routes @@ -18,7 +18,7 @@ GET /api/v1/solr-index controllers.ApiC GET /api/v1/solr-index/:solrIndexId controllers.ApiController.getSolrIndex(solrIndexId: String) PUT /api/v1/solr-index controllers.ApiController.addNewSolrIndex DELETE /api/v1/solr-index/:solrIndexId controllers.ApiController.deleteSolrIndex(solrIndexId: String) -GET /api/v1/inputTags controllers.ApiController.listAllInputTags +GET /api/v1/inputTags controllers.ApiController.listAllInputTags() GET /api/v1/:solrIndexId/search-input controllers.ApiController.listAllSearchInputs(solrIndexId: String) GET /api/v1/search-input/:searchInputId controllers.ApiController.getDetailedSearchInput(searchInputId: String) PUT /api/v1/:solrIndexId/search-input controllers.ApiController.addNewSearchInput(solrIndexId: String) diff --git a/project/build.properties b/project/build.properties index c8fcab54..081fdbbc 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.6.2 +sbt.version=1.10.0 diff --git a/project/plugins.sbt b/project/plugins.sbt index da372d3a..c6cc607b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.18") +addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.4") addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.2") addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.6.4") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0") diff --git a/test/controllers/HealthControllerSpec.scala b/test/controllers/HealthControllerSpec.scala index 3aeb422f..c3962af5 100644 --- a/test/controllers/HealthControllerSpec.scala +++ b/test/controllers/HealthControllerSpec.scala @@ -1,6 +1,6 @@ package controllers -import org.scalatest.mockito.MockitoSugar +import org.scalatestplus.mockito.MockitoSugar import org.scalatestplus.play._ import play.api.http.ContentTypes import play.api.mvc.Result diff --git a/test/models/DBCompatibilitySpec.scala b/test/models/DBCompatibilitySpec.scala index 79c8f198..c91279c2 100644 --- a/test/models/DBCompatibilitySpec.scala +++ b/test/models/DBCompatibilitySpec.scala @@ -2,7 +2,9 @@ package models import java.time.LocalDateTime import scala.util.Try -import org.scalatest.{BeforeAndAfterAll, FlatSpec, Matchers} +import org.scalatest.BeforeAndAfterAll +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import play.api.db.Database import models.input.{InputTag, InputTagId, SearchInput, SearchInputWithRules} import models.eventhistory.InputEvent @@ -11,7 +13,7 @@ import models.rules._ import models.spellings.{AlternativeSpelling, AlternativeSpellingId, CanonicalSpelling, CanonicalSpellingWithAlternatives} import services.SmuiMigrationLock -abstract class DBCompatibilitySpec extends FlatSpec with Matchers with TestData with BeforeAndAfterAll { +abstract class DBCompatibilitySpec extends AnyFlatSpec with Matchers with TestData with BeforeAndAfterAll { protected def db: Database diff --git a/test/models/InputTagSpec.scala b/test/models/InputTagSpec.scala index 548c7310..c00fc0dc 100644 --- a/test/models/InputTagSpec.scala +++ b/test/models/InputTagSpec.scala @@ -4,10 +4,12 @@ import java.time.LocalDateTime import models.input.{SearchInput, InputTag, TagInputAssociation, PredefinedTag, InputTagId} import org.h2.jdbc.JdbcBatchUpdateException -import org.scalatest.{BeforeAndAfterEach, FlatSpec, Matchers} +import org.scalatest.BeforeAndAfterEach +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import utils.WithInMemoryDB -class InputTagSpec extends FlatSpec with Matchers with BeforeAndAfterEach with WithInMemoryDB { +class InputTagSpec extends AnyFlatSpec with Matchers with BeforeAndAfterEach with WithInMemoryDB { private val index = SolrIndex(name = "de", description = "German") private val inputTags = Seq( diff --git a/test/models/QuerqyRulesTxtGeneratorSpec.scala b/test/models/QuerqyRulesTxtGeneratorSpec.scala index 4e9c82d8..889d7464 100644 --- a/test/models/QuerqyRulesTxtGeneratorSpec.scala +++ b/test/models/QuerqyRulesTxtGeneratorSpec.scala @@ -4,12 +4,12 @@ import models.FeatureToggleModel.FeatureToggleService import models.input.{SearchInputId, SearchInputWithRules, InputTag} import models.querqy.QuerqyRulesTxtGenerator import models.rules._ -import models.spellings.{AlternativeSpelling, AlternativeSpellingId, CanonicalSpellingId, CanonicalSpellingWithAlternatives} -import org.mockito.Mockito._ -import org.scalatest.mockito.MockitoSugar -import org.scalatest.{FlatSpec, Matchers} +import org.mockito.Mockito.when +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import org.scalatestplus.mockito.MockitoSugar -class QuerqyRulesTxtGeneratorSpec extends FlatSpec with Matchers with MockitoSugar { +class QuerqyRulesTxtGeneratorSpec extends AnyFlatSpec with Matchers with MockitoSugar { val searchManagementRepository = mock[SearchManagementRepository] val featureToggleService = mock[FeatureToggleService] diff --git a/test/models/SearchInputWithRulesSpec.scala b/test/models/SearchInputWithRulesSpec.scala index 1e9037a6..088ca315 100644 --- a/test/models/SearchInputWithRulesSpec.scala +++ b/test/models/SearchInputWithRulesSpec.scala @@ -2,13 +2,14 @@ package models import java.sql.Connection -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import utils.WithInMemoryDB import models.input.{SearchInput, SearchInputWithRules, InputTag, TagInputAssociation} import models.rules.{SynonymRule, SynonymRuleId} -class SearchInputWithRulesSpec extends FlatSpec with Matchers with WithInMemoryDB with TestData { +class SearchInputWithRulesSpec extends AnyFlatSpec with Matchers with WithInMemoryDB with TestData { private val tag = InputTag.create(None, Some("tenant"), "MO", exported = true) diff --git a/test/models/SearchManagementRepositorySpec.scala b/test/models/SearchManagementRepositorySpec.scala index 8f98d799..3f03bbd8 100644 --- a/test/models/SearchManagementRepositorySpec.scala +++ b/test/models/SearchManagementRepositorySpec.scala @@ -2,10 +2,11 @@ package models import models.input.{InputTag, SearchInput} import models.spellings.CanonicalSpelling -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class SearchManagementRepositorySpec extends FlatSpec with Matchers with TestData with ApplicationTestBase { +class SearchManagementRepositorySpec extends AnyFlatSpec with Matchers with TestData with ApplicationTestBase { protected def createTestCore(): Unit = { repo.addNewSolrIndex(SolrIndex(core1Id, "core1", "First core")) diff --git a/test/models/SolrIndexSpec.scala b/test/models/SolrIndexSpec.scala index 996b8dfc..96edb76a 100644 --- a/test/models/SolrIndexSpec.scala +++ b/test/models/SolrIndexSpec.scala @@ -1,11 +1,12 @@ package models import org.h2.jdbc.JdbcSQLException -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import utils.WithInMemoryDB -class SolrIndexSpec extends FlatSpec with Matchers with WithInMemoryDB with TestData { +class SolrIndexSpec extends AnyFlatSpec with Matchers with WithInMemoryDB with TestData { "SolrIndex" should "be creatable" in { db.withConnection { implicit conn => diff --git a/test/models/SuggestedSolrFieldSpec.scala b/test/models/SuggestedSolrFieldSpec.scala index 45f7b4f9..d275568a 100644 --- a/test/models/SuggestedSolrFieldSpec.scala +++ b/test/models/SuggestedSolrFieldSpec.scala @@ -2,12 +2,13 @@ package models import org.h2.jdbc.JdbcSQLException -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import utils.WithInMemoryDB -class SuggestedSolrFieldSpec extends FlatSpec with Matchers with WithInMemoryDB with TestData { +class SuggestedSolrFieldSpec extends AnyFlatSpec with Matchers with WithInMemoryDB with TestData { "SuggestedField" should "be creatable" in { db.withConnection { implicit conn => diff --git a/test/models/config/CustomUpDownDropdownMappingsSpec.scala b/test/models/config/CustomUpDownDropdownMappingsSpec.scala index dc7acb80..c30b6780 100644 --- a/test/models/config/CustomUpDownDropdownMappingsSpec.scala +++ b/test/models/config/CustomUpDownDropdownMappingsSpec.scala @@ -1,6 +1,7 @@ package models.config -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import play.api.inject.Injector import play.api.{Application, Mode} @@ -9,7 +10,7 @@ import play.api.db.{Database, Databases} import models.FeatureToggleModel._ -class CustomUpDownDropdownMappingsSpec extends FlatSpec with Matchers { +class CustomUpDownDropdownMappingsSpec extends AnyFlatSpec with Matchers { private val db: Database = Databases.inMemory() diff --git a/test/models/config/SmuiVersionSpec.scala b/test/models/config/SmuiVersionSpec.scala index 297299ec..8d256a56 100644 --- a/test/models/config/SmuiVersionSpec.scala +++ b/test/models/config/SmuiVersionSpec.scala @@ -1,8 +1,9 @@ package models.config -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class SmuiVersionSpec extends FlatSpec with Matchers { +class SmuiVersionSpec extends AnyFlatSpec with Matchers { "SmuiVersion" should "correctly interpret equality" in { SmuiVersion(1, 0, 0) shouldEqual SmuiVersion(1, 0, 0) @@ -44,7 +45,7 @@ class SmuiVersionSpec extends FlatSpec with Matchers { "SmuiVersion for next deployment" should "be greater than latest version provided on DockerHub" in { - val latestDockerHub = SmuiVersion.latestVersionFromDockerHub + val latestDockerHub = SmuiVersion.latestVersionFromDockerHub() val current = SmuiVersion.parse(models.buildInfo.BuildInfo.version) current.get.greaterThan(latestDockerHub.get) shouldEqual true diff --git a/test/models/config/TargetEnvironmentConfigSpec.scala b/test/models/config/TargetEnvironmentConfigSpec.scala index 18fada37..053a499b 100644 --- a/test/models/config/TargetEnvironmentConfigSpec.scala +++ b/test/models/config/TargetEnvironmentConfigSpec.scala @@ -1,17 +1,16 @@ package models.config -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import play.api.inject.Injector import play.api.{Application, Mode} import play.api.inject.guice.GuiceApplicationBuilder import play.api.db.{Database, Databases} -import com.typesafe.config._ - import models.config.TargetEnvironment._ -class TargetEnvironmentConfigSpec extends FlatSpec with Matchers { +class TargetEnvironmentConfigSpec extends AnyFlatSpec with Matchers { private val db: Database = Databases.inMemory() diff --git a/test/models/eventhistory/DeactivatedEventHistorySpec.scala b/test/models/eventhistory/DeactivatedEventHistorySpec.scala index e04eac27..29218a62 100644 --- a/test/models/eventhistory/DeactivatedEventHistorySpec.scala +++ b/test/models/eventhistory/DeactivatedEventHistorySpec.scala @@ -1,13 +1,12 @@ package models.eventhistory -import java.time.LocalDateTime - import models.ApplicationTestBase import models.input.SearchInputId import models.spellings.CanonicalSpellingId -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class DeactivatedEventHistorySpec extends FlatSpec with Matchers with ApplicationTestBase { +class DeactivatedEventHistorySpec extends AnyFlatSpec with Matchers with ApplicationTestBase { private var inputIds: Seq[SearchInputId] = Seq.empty private var spellingIds: Seq[CanonicalSpellingId] = Seq.empty diff --git a/test/models/eventhistory/EventHistorySpec.scala b/test/models/eventhistory/EventHistorySpec.scala index 6a1356c9..3c038fc6 100644 --- a/test/models/eventhistory/EventHistorySpec.scala +++ b/test/models/eventhistory/EventHistorySpec.scala @@ -1,6 +1,7 @@ package models.eventhistory -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import org.scalatest.matchers.{BeMatcher, MatchResult} import java.time.LocalDateTime @@ -27,7 +28,7 @@ trait CustomerMatchers { } -class EventHistorySpec extends FlatSpec with Matchers with CustomerMatchers with ApplicationTestBase { +class EventHistorySpec extends AnyFlatSpec with Matchers with CustomerMatchers with ApplicationTestBase { private var inputIds: Seq[SearchInputId] = Seq.empty private var spellingIds: Seq[CanonicalSpellingId] = Seq.empty diff --git a/test/models/input/InputValidatorSpec.scala b/test/models/input/InputValidatorSpec.scala index b65c0c8f..84bed21c 100644 --- a/test/models/input/InputValidatorSpec.scala +++ b/test/models/input/InputValidatorSpec.scala @@ -1,8 +1,9 @@ package models.input -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class InputValidatorSpec extends FlatSpec with Matchers { +class InputValidatorSpec extends AnyFlatSpec with Matchers { "InputValidator" should "validate invalid input terms correctly" in { diff --git a/test/models/querqy/QuerqyExactMatchRulesGeneratorSpec.scala b/test/models/querqy/QuerqyExactMatchRulesGeneratorSpec.scala index cab6591e..dd49844b 100644 --- a/test/models/querqy/QuerqyExactMatchRulesGeneratorSpec.scala +++ b/test/models/querqy/QuerqyExactMatchRulesGeneratorSpec.scala @@ -4,13 +4,12 @@ import models.FeatureToggleModel.FeatureToggleService import models.SearchManagementRepository import models.input.{SearchInputId, SearchInput, SearchInputWithRules} import models.rules._ -import models.querqy.QuerqyRulesTxtGenerator -import org.mockito.Mockito._ -import org.scalatest.mockito.MockitoSugar -import org.scalatest.{FlatSpec, Matchers} +import org.scalatestplus.mockito.MockitoSugar +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class QuerqyExactMatchRulesGeneratorSpec extends FlatSpec with Matchers with MockitoSugar { +class QuerqyExactMatchRulesGeneratorSpec extends AnyFlatSpec with Matchers with MockitoSugar { val searchManagementRepository = mock[SearchManagementRepository] val featureToggleService = mock[FeatureToggleService] diff --git a/test/models/querqy/QuerqyReplaceRulesGeneratorSpec.scala b/test/models/querqy/QuerqyReplaceRulesGeneratorSpec.scala index 04ab401a..96f98d08 100644 --- a/test/models/querqy/QuerqyReplaceRulesGeneratorSpec.scala +++ b/test/models/querqy/QuerqyReplaceRulesGeneratorSpec.scala @@ -1,9 +1,10 @@ package models.querqy import models.spellings.{AlternativeSpelling, AlternativeSpellingId, CanonicalSpellingId, CanonicalSpellingWithAlternatives} -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class QuerqyReplaceRulesGeneratorSpec extends FlatSpec with Matchers { +class QuerqyReplaceRulesGeneratorSpec extends AnyFlatSpec with Matchers { import models.querqy.{QuerqyReplaceRulesGenerator => generator} diff --git a/test/models/rules/DeleteRuleSpec.scala b/test/models/rules/DeleteRuleSpec.scala index 69e80547..27f3c0c5 100644 --- a/test/models/rules/DeleteRuleSpec.scala +++ b/test/models/rules/DeleteRuleSpec.scala @@ -1,8 +1,9 @@ package models.rules -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class DeleteRuleSpec extends FlatSpec with Matchers { +class DeleteRuleSpec extends AnyFlatSpec with Matchers { val rule1 = DeleteRule(DeleteRuleId(), "term1", isActive = true) val rule2 = DeleteRule(DeleteRuleId(), "term2", isActive = false) diff --git a/test/models/rules/FilterRuleSpec.scala b/test/models/rules/FilterRuleSpec.scala index bba111c0..f70e7a67 100644 --- a/test/models/rules/FilterRuleSpec.scala +++ b/test/models/rules/FilterRuleSpec.scala @@ -1,8 +1,9 @@ package models.rules -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class FilterRuleSpec extends FlatSpec with Matchers { +class FilterRuleSpec extends AnyFlatSpec with Matchers { val rule1 = FilterRule(FilterRuleId(), "term1", isActive = true) val rule2 = FilterRule(FilterRuleId(), "term2", isActive = false) diff --git a/test/models/rules/RedirectRuleSpec.scala b/test/models/rules/RedirectRuleSpec.scala index d2797e9a..c6cf1b9f 100644 --- a/test/models/rules/RedirectRuleSpec.scala +++ b/test/models/rules/RedirectRuleSpec.scala @@ -1,8 +1,9 @@ package models.rules -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class RedirectRuleSpec extends FlatSpec with Matchers { +class RedirectRuleSpec extends AnyFlatSpec with Matchers { val rule1 = RedirectRule(RedirectRuleId(), "target1", isActive = true) val rule2 = RedirectRule(RedirectRuleId(), "target2", isActive = false) diff --git a/test/models/rules/SynonymRuleSpec.scala b/test/models/rules/SynonymRuleSpec.scala index f04f6f99..43719477 100644 --- a/test/models/rules/SynonymRuleSpec.scala +++ b/test/models/rules/SynonymRuleSpec.scala @@ -1,8 +1,9 @@ package models.rules -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class SynonymRuleSpec extends FlatSpec with Matchers { +class SynonymRuleSpec extends AnyFlatSpec with Matchers { val rule1 = SynonymRule(SynonymRuleId(), SynonymRule.TYPE_DIRECTED, "term1", isActive = true) val rule2 = SynonymRule(SynonymRuleId(), SynonymRule.TYPE_UNDIRECTED, "term2", isActive = false) diff --git a/test/models/rules/UpDownRuleSpec.scala b/test/models/rules/UpDownRuleSpec.scala index 1c4c7161..0bbdd378 100644 --- a/test/models/rules/UpDownRuleSpec.scala +++ b/test/models/rules/UpDownRuleSpec.scala @@ -1,8 +1,9 @@ package models.rules -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class UpDownRuleSpec extends FlatSpec with Matchers { +class UpDownRuleSpec extends AnyFlatSpec with Matchers { val rule1 = UpDownRule(UpDownRuleId(), UpDownRule.TYPE_DOWN, 100, "term1", isActive = true) val rule2 = UpDownRule(UpDownRuleId(), UpDownRule.TYPE_UP, 200, "term1", isActive = false) diff --git a/test/models/spellings/CanonicalSpellingValidatorSpec.scala b/test/models/spellings/CanonicalSpellingValidatorSpec.scala index 02ef5a79..abf1ddab 100644 --- a/test/models/spellings/CanonicalSpellingValidatorSpec.scala +++ b/test/models/spellings/CanonicalSpellingValidatorSpec.scala @@ -1,8 +1,9 @@ package models.spellings -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class CanonicalSpellingValidatorSpec extends FlatSpec with Matchers { +class CanonicalSpellingValidatorSpec extends AnyFlatSpec with Matchers { import models.spellings.{CanonicalSpellingValidator => validator} diff --git a/test/routes/ApiRoutesSpec.scala b/test/routes/ApiRoutesSpec.scala index 73187711..6572cfe8 100644 --- a/test/routes/ApiRoutesSpec.scala +++ b/test/routes/ApiRoutesSpec.scala @@ -3,7 +3,8 @@ package routes import models.spellings.{AlternativeSpelling, AlternativeSpellingId, CanonicalSpelling, CanonicalSpellingWithAlternatives} import models.{ApplicationTestBase} import models.input.{ListItem, ListItemType} -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import play.api.http.ContentTypes import play.api.libs.json.Json import play.api.mvc.Result @@ -12,7 +13,7 @@ import play.api.test.Helpers.{GET, route, _} import scala.concurrent.Future -class ApiRoutesSpec extends FlatSpec with Matchers with ApplicationTestBase { +class ApiRoutesSpec extends AnyFlatSpec with Matchers with ApplicationTestBase { override protected def beforeAll(): Unit = { super.beforeAll() diff --git a/test/services/RulesTxtDeploymentServiceConfigVariantsSpec.scala b/test/services/RulesTxtDeploymentServiceConfigVariantsSpec.scala index c185856d..dc7fa1a7 100644 --- a/test/services/RulesTxtDeploymentServiceConfigVariantsSpec.scala +++ b/test/services/RulesTxtDeploymentServiceConfigVariantsSpec.scala @@ -1,6 +1,8 @@ package services -import org.scalatest.{FlatSpec, Matchers, Suite} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.Suite import models.ApplicationTestBase import models.input.SearchInputWithRules import models.rules.{SynonymRule, SynonymRuleId} @@ -57,7 +59,7 @@ trait CommonRulesTxtDeploymentServiceConfigVariantsSpecBase extends ApplicationT * Variants for different rules.txt, replace-rules.txt, decompound-rules.txt */ -class RulesTxtOnlyDeploymentConfigVariantSpec extends FlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { +class RulesTxtOnlyDeploymentConfigVariantSpec extends AnyFlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { override protected lazy val additionalAppConfig = Seq( "smui2solr.SRC_TMP_FILE" -> "/changed-common-rules-temp-path/search-management-ui_rules-txt.tmp", @@ -90,7 +92,7 @@ class RulesTxtOnlyDeploymentConfigVariantSpec extends FlatSpec with Matchers wit } -class RulesAndReplaceTxtDeploymentConfigVariantSpec extends FlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { +class RulesAndReplaceTxtDeploymentConfigVariantSpec extends AnyFlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { override protected lazy val activateSpelling = true @@ -137,7 +139,7 @@ class RulesAndReplaceTxtDeploymentConfigVariantSpec extends FlatSpec with Matche } -class RulesAndDecompoundTxtDeploymentConfigVariantSpec extends FlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { +class RulesAndDecompoundTxtDeploymentConfigVariantSpec extends AnyFlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { override protected lazy val activateSpelling = false @@ -188,7 +190,7 @@ class RulesAndDecompoundTxtDeploymentConfigVariantSpec extends FlatSpec with Mat } -class RulesReplaceAndDecompoundTxtDeploymentConfigVariantSpec extends FlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { +class RulesReplaceAndDecompoundTxtDeploymentConfigVariantSpec extends AnyFlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { override protected lazy val activateSpelling = true @@ -257,7 +259,7 @@ class RulesReplaceAndDecompoundTxtDeploymentConfigVariantSpec extends FlatSpec w * Interface with deployment script (for regular and "GIT" target alike) */ -class RulesTxtDeploymentRegularTargetSpec extends FlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { +class RulesTxtDeploymentRegularTargetSpec extends AnyFlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { override protected lazy val activateSpelling = true @@ -320,7 +322,7 @@ class RulesTxtDeploymentRegularTargetSpec extends FlatSpec with Matchers with Co } -class RulesTxtDeploymentGitTargetSpec extends FlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { +class RulesTxtDeploymentGitTargetSpec extends AnyFlatSpec with Matchers with CommonRulesTxtDeploymentServiceConfigVariantsSpecBase { override protected lazy val activateSpelling = true diff --git a/test/services/RulesTxtDeploymentServiceSimpleSpec.scala b/test/services/RulesTxtDeploymentServiceSimpleSpec.scala index a1327a78..606d4ee8 100644 --- a/test/services/RulesTxtDeploymentServiceSimpleSpec.scala +++ b/test/services/RulesTxtDeploymentServiceSimpleSpec.scala @@ -6,9 +6,10 @@ import java.util.zip.ZipInputStream import models.ApplicationTestBase import models.input.SearchInputId import org.apache.commons.io.IOUtils -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class RulesTxtDeploymentServiceSpec extends FlatSpec with Matchers with ApplicationTestBase { +class RulesTxtDeploymentServiceSpec extends AnyFlatSpec with Matchers with ApplicationTestBase { private lazy val service = injector.instanceOf[RulesTxtDeploymentService] private var inputIds: Seq[SearchInputId] = Seq.empty diff --git a/test/services/RulesTxtImportServiceSpec.scala b/test/services/RulesTxtImportServiceSpec.scala index 5a89d65b..fa5a78a8 100644 --- a/test/services/RulesTxtImportServiceSpec.scala +++ b/test/services/RulesTxtImportServiceSpec.scala @@ -2,9 +2,10 @@ package services import models.ApplicationTestBase import models.input.SearchInputWithRules -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class RulesTxtImportServiceSpec extends FlatSpec with Matchers with ApplicationTestBase { +class RulesTxtImportServiceSpec extends AnyFlatSpec with Matchers with ApplicationTestBase { private lazy val service = injector.instanceOf[RulesTxtImportService] diff --git a/test/services/RulesTxtImportServiceWithTaggingAndPredefinedTagsSpec.scala b/test/services/RulesTxtImportServiceWithTaggingAndPredefinedTagsSpec.scala index 527cd600..6389296f 100644 --- a/test/services/RulesTxtImportServiceWithTaggingAndPredefinedTagsSpec.scala +++ b/test/services/RulesTxtImportServiceWithTaggingAndPredefinedTagsSpec.scala @@ -3,9 +3,10 @@ package services import models.ApplicationTestBase import models.input.SearchInputWithRules import models.rules.SynonymRule -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class RulesTxtImportServiceWithTaggingAndPredefinedTagsSpec extends FlatSpec with Matchers with ApplicationTestBase { +class RulesTxtImportServiceWithTaggingAndPredefinedTagsSpec extends AnyFlatSpec with Matchers with ApplicationTestBase { private lazy val service = injector.instanceOf[RulesTxtImportService] diff --git a/test/services/RulesTxtImportServiceWithTaggingWithoutPredefinedTagsSpec.scala b/test/services/RulesTxtImportServiceWithTaggingWithoutPredefinedTagsSpec.scala index 7e21271f..3655565e 100644 --- a/test/services/RulesTxtImportServiceWithTaggingWithoutPredefinedTagsSpec.scala +++ b/test/services/RulesTxtImportServiceWithTaggingWithoutPredefinedTagsSpec.scala @@ -3,9 +3,10 @@ package services import models.ApplicationTestBase import models.input.SearchInputWithRules import models.rules.SynonymRule -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class RulesTxtImportServiceWithTaggingWithoutPredefinedTagsSpec extends FlatSpec with Matchers with ApplicationTestBase { +class RulesTxtImportServiceWithTaggingWithoutPredefinedTagsSpec extends AnyFlatSpec with Matchers with ApplicationTestBase { private lazy val service = injector.instanceOf[RulesTxtImportService]