Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions services/api/src/main/kotlin/db/migration/R__Boards_seed.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,31 +62,30 @@ class R__Boards_seed : BaseJavaMigration() {
val boardRows = boards.associateBy { row -> row.getValue("number") }
val boardIds = boards.associate { row -> row.getValue("number") to upsertBoard(connection, row) }

var written = 0
var attached = 0
var skipped = 0
seats.forEach { row ->
// Counted from what came back rather than tallied as it goes: a var written inside a
// lambda is a boxed reference the reader has to hold in their head, and static analysis
// reads it as a local that is never assigned at all.
val outcomes = seats.map { row ->
val number = row.getValue("board")
val boardId = boardIds[number]
val boardRow = boardRows[number]
// Absent where the board it sits on is deleted, or where the file names a board
// that has no row of its own.
if (boardId == null || boardRow == null) {
// The board it sits on is deleted, or the file names one that has no row at all.
skipped += 1
return@forEach
}
when (upsertSeat(connection, boardId, boardRow, row)) {
Seat.ATTACHED -> { written += 1; attached += 1 }
Seat.WRITTEN -> written += 1
Seat.LEFT_DELETED -> skipped += 1
Seat.LEFT_DELETED
} else {
upsertSeat(connection, boardId, boardRow, row)
}
}

val attached = outcomes.count { it == Seat.ATTACHED }
val written = outcomes.count { it != Seat.LEFT_DELETED }
if (attached > 0) log.info("[boards-seed] {} seats found the account they were recorded under", attached)
log.info(
"[boards-seed] {} boards and {} seats applied ({} left to their deletion)",
boardIds.values.count { it != null },
written,
skipped,
outcomes.size - written,
)
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions services/api/src/test/kotlin/db/migration/BoardSeedParsingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package db.migration
import net.blueshell.api.board.domain.BoardSeed
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import java.nio.file.Files
import java.nio.file.Path
import java.time.LocalDate

/**
Expand Down Expand Up @@ -88,6 +90,48 @@ class BoardSeedParsingTest {
assertThat(seats.none { it.getValue("name").contains('"') }).isTrue()
}

/**
* Every picture the files name, as the art directory would spell it.
*
* The rule is one substitution: the master for a row is that row's own `image` with
* `.webp` for an extension. There is no lookup table to fall out of step.
*/
private fun artNamed(rows: List<Map<String, String>>): List<String> =
rows.map { it.getValue("image") }
.filter { it.isNotBlank() }
.map { "db/seed/boards/art/" + it.substringBeforeLast('.') + ".webp" }

@Test
fun `every picture the files name ships beside them`() {
// The photographs are still asset names the frontend loads, and they are also the
// masters the api will store. Naming one that is not here would be a board drawn
// blank on a fresh database, which no test further down the stack would catch.
val missing = (artNamed(boards) + artNamed(seats))
.filter { javaClass.classLoader.getResource(it) == null }

assertThat(missing).isEmpty()
}

@Test
fun `the art directory holds nothing the files do not name`() {
// The other direction: a picture nobody points at is megabytes nobody notices. Read
// off the source tree rather than the classpath, because the packaged resources are
// inside a jar by the time a test runs and a jar is not a directory to walk.
val art = Path.of("src/main/resources/db/seed/boards/art")
assertThat(Files.isDirectory(art))
.describedAs("the shipped board art at %s", art.toAbsolutePath())
.isTrue()

val named = (artNamed(boards) + artNamed(seats)).toSet()
val shipped = Files.walk(art).use { paths ->
paths.filter { it.fileName.toString().endsWith(".webp") }
.map { "db/seed/boards/art/${it.parent.fileName}/${it.fileName}" }
.toList()
}

assertThat(shipped).hasSize(26).allMatch { it in named }
}

@Test
fun `every seat names a board the boards file lists`() {
val numbers = boards.map { it.getValue("number") }.toSet()
Expand Down
Loading