/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package com.runicgateway.app.data.appearance

import kotlinx.serialization.json.JsonPrimitive
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test

/**
 * The second-stage parse of a JSON-valued settings row (THEMING_AND_NAV.md §3).
 * The rule under test is the one the web client's `parseJsonSetting` states:
 * anything that is not a plain object reads as **absent**, never as an error.
 */
class SettingsJsonTest {

    @Test fun parsesAPlainObject() {
        val parsed = parseJsonSetting("""{"/wiki":{"label":"Codex","order":0}}""")
        assertEquals(1, parsed!!.size)
        assertEquals(setOf("/wiki"), parsed.keys)
    }

    @Test fun parsesTheWrappedPublicShape() {
        val parsed = parseJsonSetting(
            """{"items":{"/":{"hidden":true}},"sections":[{"id":"s1","label":"Play"}],"links":[]}""",
        )
        assertEquals(setOf("items", "sections", "links"), parsed!!.keys)
    }

    @Test fun absentValuesReadAsNull() {
        assertNull(parseJsonSetting(null))
        assertNull(parseJsonSetting(""))
    }

    @Test fun malformedJsonReadsAsNull() {
        assertNull(parseJsonSetting("{"))
        assertNull(parseJsonSetting("""{"a":}"""))
        assertNull(parseJsonSetting("not json at all"))
    }

    @Test fun nonObjectJsonReadsAsNull() {
        // A stored `null`, number, string or array is as unusable to every
        // consumer of these keys as a syntax error is.
        assertNull(parseJsonSetting("null"))
        assertNull(parseJsonSetting("4"))
        assertNull(parseJsonSetting("\"x\""))
        assertNull(parseJsonSetting("[]"))
    }

    @Test fun unusualKeysAndValuesSurviveVerbatim() {
        // The parse stage validates the *kind*, not the shape — a nonsense entry
        // is dropped later, by the phase that reads it.
        val parsed = parseJsonSetting("""{"/site/news":{"order":"first"},"nonsense":7}""")
        assertEquals(JsonPrimitive(7), parsed!!["nonsense"])
    }
}
