package social.grain import org.junit.Assert.assertEquals import org.junit.Test import social.grain.data.model.AtLabel import social.grain.data.model.LabelDefinition import social.grain.data.model.LabelLocale import social.grain.util.LabelAction import social.grain.util.resolveLabels /** * What a label does to the thing it's attached to. * * Every gating decision in the app comes through this one function, and the * failure it has to be held to is silent: a label that resolves a step too mild * doesn't throw or look broken, it just shows the reader something a moderator * said not to show them. */ class LabelResolutionTest { private fun label(value: String, neg: Boolean? = null) = AtLabel(`val` = value, neg = neg) private fun definition( identifier: String, blurs: String?, defaultSetting: String?, name: String = identifier, ) = LabelDefinition( identifier = identifier, locales = listOf(LabelLocale(name)), blurs = blurs, defaultSetting = defaultSetting, ) @Test fun `no labels resolves to no action`() { assertEquals(LabelAction.NONE, resolveLabels(null, emptyList()).action) assertEquals(LabelAction.NONE, resolveLabels(emptyList(), emptyList()).action) } @Test fun `child safety hides without server definitions`() { // The appview publishes csae, so the fallback only runs when // describeLabels didn't answer. Falling back to a badge there would put // the one category we least want shown in front of a reader, at the // exact moment nothing else is available to stop it. val csae = resolveLabels(listOf(label("csae")), emptyList()) assertEquals(LabelAction.HIDE, csae.action) assertEquals("Child Safety", csae.name) } @Test fun `well-known labels resolve without server definitions`() { val porn = resolveLabels(listOf(label("porn")), emptyList()) assertEquals(LabelAction.WARN_MEDIA, porn.action) assertEquals("Adult Content", porn.name) assertEquals(LabelAction.HIDE, resolveLabels(listOf(label("!hide")), emptyList()).action) assertEquals( LabelAction.WARN_CONTENT, resolveLabels(listOf(label("!warn")), emptyList()).action, ) } @Test fun `a server definition wins over the fallback for the same identifier`() { val definitions = listOf(definition("porn", blurs = "content", defaultSetting = "hide")) val result = resolveLabels(listOf(label("porn")), definitions) assertEquals(LabelAction.HIDE, result.action) } @Test fun `blurs media with a hide setting warns rather than hiding`() { val definitions = listOf(definition("nsfl", blurs = "media", defaultSetting = "hide")) assertEquals( LabelAction.WARN_MEDIA, resolveLabels(listOf(label("nsfl")), definitions).action, ) } @Test fun `a label that blurs nothing is only a badge`() { val definitions = listOf(definition("spoiler", blurs = "none", defaultSetting = "warn")) val result = resolveLabels(listOf(label("spoiler")), definitions) assertEquals(LabelAction.BADGE, result.action) assertEquals("spoiler", result.name) } @Test fun `an ignored label does nothing`() { val definitions = listOf(definition("noop", blurs = "media", defaultSetting = "ignore")) assertEquals(LabelAction.NONE, resolveLabels(listOf(label("noop")), definitions).action) } /** An identifier nobody has a definition for is still worth naming. */ @Test fun `an unknown label is badged rather than dropped`() { val result = resolveLabels(listOf(label("some-new-label")), emptyList()) assertEquals(LabelAction.BADGE, result.action) assertEquals("some-new-label", result.name) } @Test fun `the most restrictive label wins`() { val result = resolveLabels( listOf(label("some-new-label"), label("porn"), label("dmca-violation")), emptyList(), ) assertEquals(LabelAction.HIDE, result.action) assertEquals("DMCA Violation", result.name) } /** * `gore` is defined as blurring media but defaulting to hide, and media * blurring caps the action at a cover-in-place rather than a full hide — * a photo that can be blurred doesn't need the whole card taken away. */ @Test fun `hiding is capped at a media warning when only the media blurs`() { val result = resolveLabels(listOf(label("gore")), emptyList()) assertEquals(LabelAction.WARN_MEDIA, result.action) assertEquals("Graphic Violence", result.name) } @Test fun `a negated label is retracted, not applied`() { assertEquals( LabelAction.NONE, resolveLabels(listOf(label("porn", neg = true)), emptyList()).action, ) } @Test fun `a negation doesn't retract a different label on the same subject`() { val result = resolveLabels( listOf(label("porn", neg = true), label("dmca-violation")), emptyList(), ) assertEquals(LabelAction.HIDE, result.action) assertEquals("DMCA Violation", result.name) } @Test fun `the display name comes from the definition's first locale`() { val definitions = listOf( definition("custom", blurs = "media", defaultSetting = "warn", name = "Custom Warning"), ) assertEquals("Custom Warning", resolveLabels(listOf(label("custom")), definitions).name) } }