From cfab8c127b55fdf0016308cfee1cab9ce990dcce Mon Sep 17 00:00:00 2001 From: Jonas Natten Date: Wed, 5 Feb 2025 08:28:51 +0100 Subject: [PATCH] concept-api: Migrate `:`-separated tags to separate tags --- .../db/migration/V22__SplitTags.scala | 37 +++++++++++++++ .../db/migration/V22__SplitTagsTest.scala | 45 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 concept-api/src/main/scala/no/ndla/conceptapi/db/migration/V22__SplitTags.scala create mode 100644 concept-api/src/test/scala/no/ndla/conceptapi/db/migration/V22__SplitTagsTest.scala diff --git a/concept-api/src/main/scala/no/ndla/conceptapi/db/migration/V22__SplitTags.scala b/concept-api/src/main/scala/no/ndla/conceptapi/db/migration/V22__SplitTags.scala new file mode 100644 index 0000000000..0ff82057f7 --- /dev/null +++ b/concept-api/src/main/scala/no/ndla/conceptapi/db/migration/V22__SplitTags.scala @@ -0,0 +1,37 @@ +/* + * Part of NDLA concept-api + * Copyright (C) 2025 NDLA + * + * See LICENSE + * + */ + +package no.ndla.conceptapi.db.migration + +import io.circe.parser +import io.circe.syntax.EncoderOps +import io.circe.generic.auto.* +import no.ndla.database.DocumentMigration + +case class TagsObject(tags: List[String], language: String) + +class V22__SplitTags extends DocumentMigration { + override val columnName: String = "document" + override val tableName: String = "conceptdata" + + private def convertTags(tags: List[TagsObject]): List[TagsObject] = tags.map { to => + val splitTags = to.tags.flatMap(_.split(":")).filterNot(_.isEmpty) + to.copy(tags = splitTags) + } + + override def convertColumn(document: String): String = { + val oldDocument = parser.parse(document).toTry.get + oldDocument.hcursor.downField("tags").as[Option[List[TagsObject]]].toTry.get match { + case None => document + case Some(tags) => + val convertedTags = convertTags(tags).asJson + val newDocument = oldDocument.mapObject(_.remove("tags").add("tags", convertedTags)) + newDocument.noSpaces + } + } +} diff --git a/concept-api/src/test/scala/no/ndla/conceptapi/db/migration/V22__SplitTagsTest.scala b/concept-api/src/test/scala/no/ndla/conceptapi/db/migration/V22__SplitTagsTest.scala new file mode 100644 index 0000000000..bd46b146d5 --- /dev/null +++ b/concept-api/src/test/scala/no/ndla/conceptapi/db/migration/V22__SplitTagsTest.scala @@ -0,0 +1,45 @@ +/* + * Part of NDLA concept-api + * Copyright (C) 2025 NDLA + * + * See LICENSE + * + */ + +package no.ndla.conceptapi.db.migration + +import no.ndla.conceptapi.UnitSuite + +class V22__SplitTagsTest extends UnitSuite { + + val migration = new V22__SplitTags + + test("That converting colon separated tags works") { + val oldDocument = + """{"tags":[{"tags":["tag1:tag2:tag3"],"language":"nb"},{"tags":["tag4:tag5:tag6"],"language":"en"}]}""" + val converted = migration.convertColumn(oldDocument) + val expectedDocument = + """{"tags":[{"tags":["tag1","tag2","tag3"],"language":"nb"},{"tags":["tag4","tag5","tag6"],"language":"en"}]}""" + converted should be(expectedDocument) + } + + test("That converting colon separated tags works with empty values") { + val oldDocument = """{"tags":[{"tags":["tag1::","apekatt",":snabeldyr:"],"language":"nb"}]}""" + val converted = migration.convertColumn(oldDocument) + val expectedDocument = """{"tags":[{"tags":["tag1","apekatt","snabeldyr"],"language":"nb"}]}""" + converted should be(expectedDocument) + } + + test("That non colon separated tags are not changed") { + val oldDocument = """{"tags":[{"tags":["tag1","apekatt","snabeldyr"],"language":"nb"}]}""" + val converted = migration.convertColumn(oldDocument) + val expectedDocument = """{"tags":[{"tags":["tag1","apekatt","snabeldyr"],"language":"nb"}]}""" + converted should be(expectedDocument) + } + + test("That no tags doesn't crash") { + val oldDocument = """{"someotherfield":"yabadabado"}""" + val converted = migration.convertColumn(oldDocument) + converted should be(oldDocument) + } +}