diff --git a/android/app/src/main/java/tv/orbit/classic/EventIdeas.kt b/android/app/src/main/java/tv/orbit/classic/EventIdeas.kt index 4eedd4c..42fc291 100644 --- a/android/app/src/main/java/tv/orbit/classic/EventIdeas.kt +++ b/android/app/src/main/java/tv/orbit/classic/EventIdeas.kt @@ -242,11 +242,14 @@ internal object EventIdeaHistory { file.writeText(JSONArray(all.map { if (it.optInt("rules") < EVENT_IDEA_RULES && it.optString("decision") == "proposed") JSONObject(it.toString()).put("decision", "withdrawn: rules changed") else it }).toString()) } fun record(file: File, ideas: List, nowMs: Long) = runCatching { - val all = load(file); val known = all.map { it.optString("signature") }.toSet() + // An idea withdrawn only because the rules changed, and proposed again under the new ones, is shown again: its old entry goes. + val again = ideas.map { it.signature }.toSet() + val all = load(file).filterNot { it.optString("signature") in again && it.optString("decision").startsWith("withdrawn") } + val known = all.map { it.optString("signature") }.toSet() val added = ideas.filter { it.signature !in known }.map { i -> JSONObject().put("signature", i.signature).put("theme", i.theme).put("source", i.source).put("format", i.format.name).put("evening", i.evening?.toString()) .put("films", JSONArray(i.films.map { it.id })).put("titles", JSONArray(i.films.map { it.title })).put("reasons", JSONArray(i.reasons)).put("shownMs", nowMs).put("decision", "proposed").put("rules", EVENT_IDEA_RULES) } - if (added.isNotEmpty()) file.writeText(JSONArray(all + added).toString()) + if (added.isNotEmpty() || all.size != load(file).size) file.writeText(JSONArray(all + added).toString()) } } diff --git a/android/app/src/test/java/tv/orbit/classic/EventIdeasTest.kt b/android/app/src/test/java/tv/orbit/classic/EventIdeasTest.kt index 9845adf..3a713f8 100644 --- a/android/app/src/test/java/tv/orbit/classic/EventIdeasTest.kt +++ b/android/app/src/test/java/tv/orbit/classic/EventIdeasTest.kt @@ -79,4 +79,17 @@ class EventIdeasTest { val sat = ideaEvening(IdeaFormat.SaturdayTriple, LocalDate.of(2026, 11, 14), 0L, emptySet(), 6 * 3_600_000L, london)!! assertEquals(LocalDate.of(2026, 11, 21), sat.toLocalDate()) // Universal Monsters has the 14th } + + @Test fun anIdeaWithdrawnOnlyForARuleChangeComesBackWhenProposedAgain() { + val file = java.io.File.createTempFile("history", ".json").apply { deleteOnExit(); writeText("[]") } + val idea = EventIdea("franchise:X|FridayDouble", "X Night", "franchise", IdeaFormat.FridayDouble, java.time.LocalDateTime.of(2026, 12, 4, 20, 0), + listOf(film("1", "X", setOf("Action")), film("2", "X II", setOf("Action"))), listOf("why"), 7.0) + EventIdeaHistory.record(file, listOf(idea), 1) + file.writeText(file.readText().replace("\"rules\":$EVENT_IDEA_RULES", "\"rules\":1")) + EventIdeaHistory.withdrawOld(file) + assertEquals("withdrawn: rules changed", EventIdeaHistory.load(file).single().optString("decision")) + EventIdeaHistory.record(file, listOf(idea), 2) + assertEquals("proposed", EventIdeaHistory.load(file).single().optString("decision")) + assertEquals(2L, EventIdeaHistory.load(file).single().optLong("shownMs")) + } }