package moe.lava.neon.tests.api.endpoints

import io.kotest.assertions.throwables.shouldNotThrowAny
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.ktor.client.statement.request
import io.ktor.http.content.TextContent
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import moe.lava.neon.api.ApiClient
import moe.lava.neon.api.endpoints.getExperiments
import moe.lava.neon.api.endpoints.login
import moe.lava.neon.tests.api.DiscordApiMock
import moe.lava.neon.tests.api.withFactory

class AuthTest : FunSpec({
    val mock = DiscordApiMock()
    val client = ApiClient(mock.engine, false)

    var fp: String? = null
    withFactory(
        testName = "get experiments",
        endpoint = "experiments",
        response = client::getExperiments
    ) { res ->
        val body = res.body()
        fp = body.fingerprint
    }

    val email = "hello@example.com"
    val password = "supersecurepassword"
    mock.createLogin(email, password)
    withFactory(
        testName = "login with real creds",
        endpoint = "auth/login",
        response = { client.login(email, password, fp!!) }
    ) { res ->
        val req = res.response.request
        val headers = req.headers
        test("has correct fingerprint") {
            headers["X-Fingerprint"] shouldBe fp
        }
        context("has correct body") {
            val body = shouldNotThrowAny { Json.parseToJsonElement((req.content as TextContent).text).jsonObject }
            test("has correct login") {
                body["login"]?.jsonPrimitive?.content shouldBe email
            }
            test("has correct password") {
                body["password"]?.jsonPrimitive?.content shouldBe password
            }
        }
    }
})
