package test

import (
	"fmt"
	"testing"

	"blackforestbytes.com/simplecloudnotifier/api/apierr"
	tt "blackforestbytes.com/simplecloudnotifier/test/util"
	"github.com/gin-gonic/gin"
	"gogs.mikescher.com/BlackForestBytes/goext/langext"
)

func TestGetChannelPreview(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	type chanlist struct {
		Channels []gin.H `json:"channels"`
	}

	clist := tt.RequestAuthGet[chanlist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data.User[0].UID))

	chan1 := *langext.ArrFirstOrNil(clist.Channels, func(v gin.H) bool { return v["internal_name"] == "Reminders" })

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", data.User[0].UID, chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[0].ReadKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", data.User[0].UID, chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[0].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[0].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

	{
		tt.RequestAuthGetShouldFail(t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", data.User[0].UID, chan1["channel_id"]), 401, apierr.USER_AUTH_FAILED)
	}

	{
		tt.RequestAuthGetShouldFail(t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", data.User[0].UID, chan1["channel_id"]), 401, apierr.USER_AUTH_FAILED)
	}

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[1].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

	{
		chan1_rq := tt.RequestAuthGet[gin.H](t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chan1["channel_id"]))
		tt.AssertEqual(t, "channel_id", chan1["channel_id"], chan1_rq["channel_id"])
		tt.AssertEqual(t, "display_name", "Reminders", chan1_rq["display_name"])
		tt.AssertEqual(t, "internal_name", "Reminders", chan1_rq["internal_name"])
		tt.AssertEqual(t, "description_name", nil, chan1_rq["description_name"])
	}

}

func TestGetUserPreview(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	{
		user_rq_1 := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.User[0].UID))
		tt.AssertEqual(t, "user_id", data.User[0].UID, user_rq_1["user_id"])

		user_rq_2 := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))
		tt.AssertEqual(t, "user_id", user_rq_1["user_id"], user_rq_2["user_id"])
		tt.AssertEqual(t, "username", user_rq_1["username"], user_rq_2["username"])
	}

	{
		user_rq_1 := tt.RequestAuthGet[gin.H](t, data.User[0].ReadKey, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.User[0].UID))
		tt.AssertEqual(t, "user_id", data.User[0].UID, user_rq_1["user_id"])

		user_rq_2 := tt.RequestAuthGet[gin.H](t, data.User[0].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))
		tt.AssertEqual(t, "user_id", user_rq_1["user_id"], user_rq_2["user_id"])
		tt.AssertEqual(t, "username", user_rq_1["username"], user_rq_2["username"])
	}

	{
		tt.RequestAuthGetShouldFail(t, data.User[0].SendKey, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.User[0].UID), 401, apierr.USER_AUTH_FAILED)
	}

	{
		tt.RequestAuthGetShouldFail(t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.User[0].UID), 401, apierr.USER_AUTH_FAILED)
		tt.RequestAuthGetShouldFail(t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.User[0].UID), 401, apierr.USER_AUTH_FAILED)
		tt.RequestAuthGetShouldFail(t, data.User[1].SendKey, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.User[0].UID), 401, apierr.USER_AUTH_FAILED)
	}

	{
		tt.RequestAuthGet[gin.H](t, data.User[0].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))
		tt.RequestAuthGet[gin.H](t, data.User[0].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))
		tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))

		tt.RequestAuthGet[gin.H](t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))
		tt.RequestAuthGet[gin.H](t, data.User[1].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))
		tt.RequestAuthGet[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[0].UID))
	}

	{
		user_rq_1 := tt.RequestAuthGet[gin.H](t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/users/%s", data.User[2].UID))
		tt.AssertEqual(t, "username", "Dreamer23", user_rq_1["username"])
	}

}

func TestGetKeyTokenPreviewByID(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	type keyobj struct {
		AllChannels  bool     `json:"all_channels"`
		Channels     []string `json:"channels"`
		KeytokenId   string   `json:"keytoken_id"`
		MessagesSent int      `json:"messages_sent"`
		Name         string   `json:"name"`
		OwnerUserId  string   `json:"owner_user_id"`
		Permissions  string   `json:"permissions"`
	}
	type keylist struct {
		Keys []keyobj `json:"keys"`
	}

	klist := tt.RequestAuthGet[keylist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.User[0].UID))

	{
		rq_1 := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.User[0].UID, klist.Keys[0].KeytokenId))
		tt.AssertEqual(t, "all_channels", klist.Keys[0].AllChannels, rq_1["all_channels"])
		tt.AssertStrRepEqual(t, "channels", klist.Keys[0].Channels, rq_1["channels"])
		tt.AssertEqual(t, "keytoken_id", klist.Keys[0].KeytokenId, rq_1["keytoken_id"])
		tt.AssertEqual(t, "messages_sent", klist.Keys[0].MessagesSent, rq_1["messages_sent"])
		tt.AssertEqual(t, "name", klist.Keys[0].Name, rq_1["name"])
		tt.AssertEqual(t, "owner_user_id", klist.Keys[0].OwnerUserId, rq_1["owner_user_id"])
		tt.AssertEqual(t, "permissions", klist.Keys[0].Permissions, rq_1["permissions"])
	}

	{
		rq_2 := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", klist.Keys[0].KeytokenId))
		tt.AssertEqual(t, "all_channels", klist.Keys[0].AllChannels, rq_2["all_channels"])
		tt.AssertStrRepEqual(t, "channels", klist.Keys[0].Channels, rq_2["channels"])
		tt.AssertEqual(t, "keytoken_id", klist.Keys[0].KeytokenId, rq_2["keytoken_id"])
		tt.AssertEqual(t, "name", klist.Keys[0].Name, rq_2["name"])
		tt.AssertEqual(t, "owner_user_id", klist.Keys[0].OwnerUserId, rq_2["owner_user_id"])
		tt.AssertEqual(t, "permissions", klist.Keys[0].Permissions, rq_2["permissions"])
	}

	{
		tt.RequestAuthGetShouldFail(t, data.User[0].SendKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.User[0].UID, klist.Keys[0].KeytokenId), 401, apierr.USER_AUTH_FAILED)
		tt.RequestAuthGetShouldFail(t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.User[0].UID, klist.Keys[0].KeytokenId), 401, apierr.USER_AUTH_FAILED)
		tt.RequestAuthGetShouldFail(t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.User[0].UID, klist.Keys[0].KeytokenId), 401, apierr.USER_AUTH_FAILED)
		tt.RequestAuthGetShouldFail(t, data.User[1].SendKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.User[0].UID, klist.Keys[0].KeytokenId), 401, apierr.USER_AUTH_FAILED)
	}

	{
		rq_2 := tt.RequestAuthGet[gin.H](t, data.User[0].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", klist.Keys[0].KeytokenId))
		tt.AssertEqual(t, "all_channels", klist.Keys[0].AllChannels, rq_2["all_channels"])
		tt.AssertStrRepEqual(t, "channels", klist.Keys[0].Channels, rq_2["channels"])
		tt.AssertEqual(t, "keytoken_id", klist.Keys[0].KeytokenId, rq_2["keytoken_id"])
		tt.AssertEqual(t, "name", klist.Keys[0].Name, rq_2["name"])
		tt.AssertEqual(t, "owner_user_id", klist.Keys[0].OwnerUserId, rq_2["owner_user_id"])
		tt.AssertEqual(t, "permissions", klist.Keys[0].Permissions, rq_2["permissions"])
	}

	{
		rq_2 := tt.RequestAuthGet[gin.H](t, data.User[0].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", klist.Keys[0].KeytokenId))
		tt.AssertEqual(t, "all_channels", klist.Keys[0].AllChannels, rq_2["all_channels"])
		tt.AssertStrRepEqual(t, "channels", klist.Keys[0].Channels, rq_2["channels"])
		tt.AssertEqual(t, "keytoken_id", klist.Keys[0].KeytokenId, rq_2["keytoken_id"])
		tt.AssertEqual(t, "name", klist.Keys[0].Name, rq_2["name"])
		tt.AssertEqual(t, "owner_user_id", klist.Keys[0].OwnerUserId, rq_2["owner_user_id"])
		tt.AssertEqual(t, "permissions", klist.Keys[0].Permissions, rq_2["permissions"])
	}

	{
		rq_2 := tt.RequestAuthGet[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", klist.Keys[0].KeytokenId))
		tt.AssertEqual(t, "all_channels", klist.Keys[0].AllChannels, rq_2["all_channels"])
		tt.AssertStrRepEqual(t, "channels", klist.Keys[0].Channels, rq_2["channels"])
		tt.AssertEqual(t, "keytoken_id", klist.Keys[0].KeytokenId, rq_2["keytoken_id"])
		tt.AssertEqual(t, "name", klist.Keys[0].Name, rq_2["name"])
		tt.AssertEqual(t, "owner_user_id", klist.Keys[0].OwnerUserId, rq_2["owner_user_id"])
		tt.AssertEqual(t, "permissions", klist.Keys[0].Permissions, rq_2["permissions"])
	}

	{
		rq_2 := tt.RequestAuthGet[gin.H](t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", klist.Keys[0].KeytokenId))
		tt.AssertEqual(t, "all_channels", klist.Keys[0].AllChannels, rq_2["all_channels"])
		tt.AssertStrRepEqual(t, "channels", klist.Keys[0].Channels, rq_2["channels"])
		tt.AssertEqual(t, "keytoken_id", klist.Keys[0].KeytokenId, rq_2["keytoken_id"])
		tt.AssertEqual(t, "name", klist.Keys[0].Name, rq_2["name"])
		tt.AssertEqual(t, "owner_user_id", klist.Keys[0].OwnerUserId, rq_2["owner_user_id"])
		tt.AssertEqual(t, "permissions", klist.Keys[0].Permissions, rq_2["permissions"])
	}

	{
		rq_2 := tt.RequestAuthGet[gin.H](t, data.User[1].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", klist.Keys[0].KeytokenId))
		tt.AssertEqual(t, "all_channels", klist.Keys[0].AllChannels, rq_2["all_channels"])
		tt.AssertStrRepEqual(t, "channels", klist.Keys[0].Channels, rq_2["channels"])
		tt.AssertEqual(t, "keytoken_id", klist.Keys[0].KeytokenId, rq_2["keytoken_id"])
		tt.AssertEqual(t, "name", klist.Keys[0].Name, rq_2["name"])
		tt.AssertEqual(t, "owner_user_id", klist.Keys[0].OwnerUserId, rq_2["owner_user_id"])
		tt.AssertEqual(t, "permissions", klist.Keys[0].Permissions, rq_2["permissions"])
	}

}

func TestGetKeyTokenPreviewByToken(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	type keyobj struct {
		AllChannels  bool     `json:"all_channels"`
		Channels     []string `json:"channels"`
		KeytokenId   string   `json:"keytoken_id"`
		MessagesSent int      `json:"messages_sent"`
		Name         string   `json:"name"`
		OwnerUserId  string   `json:"owner_user_id"`
		Permissions  string   `json:"permissions"`
	}
	type keylist struct {
		Keys []keyobj `json:"keys"`
	}

	klist := tt.RequestAuthGet[keylist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.User[0].UID))

	adminKeyObj := *langext.ArrFirstOrNil(klist.Keys, func(v keyobj) bool { return v.Permissions == "A" })
	readKeyObj := *langext.ArrFirstOrNil(klist.Keys, func(v keyobj) bool { return v.Permissions == "UR;CR" })
	sendKeyObj := *langext.ArrFirstOrNil(klist.Keys, func(v keyobj) bool { return v.Permissions == "CS" })

	// Test with User[0]'s keys accessing their own key previews via token value
	{
		rqAdmin := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].AdminKey))
		tt.AssertEqual(t, "keytoken_id", adminKeyObj.KeytokenId, rqAdmin["keytoken_id"])
		tt.AssertEqual(t, "name", adminKeyObj.Name, rqAdmin["name"])
		tt.AssertEqual(t, "owner_user_id", adminKeyObj.OwnerUserId, rqAdmin["owner_user_id"])
		tt.AssertEqual(t, "permissions", adminKeyObj.Permissions, rqAdmin["permissions"])

		rqRead := tt.RequestAuthGet[gin.H](t, data.User[0].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].ReadKey))
		tt.AssertEqual(t, "keytoken_id", readKeyObj.KeytokenId, rqRead["keytoken_id"])
		tt.AssertEqual(t, "name", readKeyObj.Name, rqRead["name"])
		tt.AssertEqual(t, "owner_user_id", readKeyObj.OwnerUserId, rqRead["owner_user_id"])
		tt.AssertEqual(t, "permissions", readKeyObj.Permissions, rqRead["permissions"])

		rqSend := tt.RequestAuthGet[gin.H](t, data.User[0].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].SendKey))
		tt.AssertEqual(t, "keytoken_id", sendKeyObj.KeytokenId, rqSend["keytoken_id"])
		tt.AssertEqual(t, "name", sendKeyObj.Name, rqSend["name"])
		tt.AssertEqual(t, "owner_user_id", sendKeyObj.OwnerUserId, rqSend["owner_user_id"])
		tt.AssertEqual(t, "permissions", sendKeyObj.Permissions, rqSend["permissions"])
	}

	// Test with User[1]'s keys accessing User[0]'s key previews via token value (should work as preview is public)
	{
		rqAdmin := tt.RequestAuthGet[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].AdminKey))
		tt.AssertEqual(t, "keytoken_id", adminKeyObj.KeytokenId, rqAdmin["keytoken_id"])
		tt.AssertEqual(t, "name", adminKeyObj.Name, rqAdmin["name"])
		tt.AssertEqual(t, "owner_user_id", adminKeyObj.OwnerUserId, rqAdmin["owner_user_id"])
		tt.AssertEqual(t, "permissions", adminKeyObj.Permissions, rqAdmin["permissions"])

		rqRead := tt.RequestAuthGet[gin.H](t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].ReadKey))
		tt.AssertEqual(t, "keytoken_id", readKeyObj.KeytokenId, rqRead["keytoken_id"])
		tt.AssertEqual(t, "name", readKeyObj.Name, rqRead["name"])
		tt.AssertEqual(t, "owner_user_id", readKeyObj.OwnerUserId, rqRead["owner_user_id"])
		tt.AssertEqual(t, "permissions", readKeyObj.Permissions, rqRead["permissions"])

		rqSend := tt.RequestAuthGet[gin.H](t, data.User[1].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].SendKey))
		tt.AssertEqual(t, "keytoken_id", sendKeyObj.KeytokenId, rqSend["keytoken_id"])
		tt.AssertEqual(t, "name", sendKeyObj.Name, rqSend["name"])
		tt.AssertEqual(t, "owner_user_id", sendKeyObj.OwnerUserId, rqSend["owner_user_id"])
		tt.AssertEqual(t, "permissions", sendKeyObj.Permissions, rqSend["permissions"])
	}

	// Test with User[1]'s keys accessing User[0]'s key previews via token value (should work as preview is public)
	{
		rqAdmin := tt.RequestAuthGet[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].AdminKey))
		tt.AssertEqual(t, "keytoken_id", adminKeyObj.KeytokenId, rqAdmin["keytoken_id"])
		tt.AssertEqual(t, "name", adminKeyObj.Name, rqAdmin["name"])
		tt.AssertEqual(t, "owner_user_id", adminKeyObj.OwnerUserId, rqAdmin["owner_user_id"])
		tt.AssertEqual(t, "permissions", adminKeyObj.Permissions, rqAdmin["permissions"])

		rqRead := tt.RequestAuthGet[gin.H](t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].ReadKey))
		tt.AssertEqual(t, "keytoken_id", readKeyObj.KeytokenId, rqRead["keytoken_id"])
		tt.AssertEqual(t, "name", readKeyObj.Name, rqRead["name"])
		tt.AssertEqual(t, "owner_user_id", readKeyObj.OwnerUserId, rqRead["owner_user_id"])
		tt.AssertEqual(t, "permissions", readKeyObj.Permissions, rqRead["permissions"])

		rqSend := tt.RequestAuthGet[gin.H](t, data.User[1].SendKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].SendKey))
		tt.AssertEqual(t, "keytoken_id", sendKeyObj.KeytokenId, rqSend["keytoken_id"])
		tt.AssertEqual(t, "name", sendKeyObj.Name, rqSend["name"])
		tt.AssertEqual(t, "owner_user_id", sendKeyObj.OwnerUserId, rqSend["owner_user_id"])
		tt.AssertEqual(t, "permissions", sendKeyObj.Permissions, rqSend["permissions"])
	}

	// Test with invalid token
	{
		tt.RequestAuthGetShouldFail(t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", "invalid-token-string"), 404, apierr.KEY_NOT_FOUND)
	}

	// Test without auth
	{
		tt.RequestGetShouldFail(t, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].SendKey), 401, apierr.USER_AUTH_FAILED)
	}

}

func TestGetChannelPreviewSubscriptionNone(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	// User[1] (who is not subscribed) requests preview of User[0]'s channel
	preview := tt.RequestAuthGet[gin.H](t, data.User[1].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", data.User[0].Channels[0].ChannelID))

	// Assert User[1] sees no subscription
	tt.AssertNil(t, "subscription", preview["subscription"])
}

func TestGetChannelPreviewSubscriptionUnconfirmed(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	chanReq := *langext.ArrFirstOrNil(data.User[15].Channels, func(v tt.ChanData) bool { return v.InternalName == "chan_other_request" })

	preview := tt.RequestAuthGet[gin.H](t, data.User[14].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chanReq.ChannelID))

	// Assert User[14] sees their unconfirmed subscription
	tt.AssertNotNil(t, "subscription", preview["subscription"])
	subscription, ok := preview["subscription"].(map[string]any)
	tt.AssertTrue(t, "subscription is map", ok)
	tt.AssertEqual(t, "subscription.user_id", data.User[14].UID, subscription["subscriber_user_id"])
	tt.AssertEqual(t, "subscription.user_id", data.User[15].UID, subscription["channel_owner_user_id"])
	tt.AssertEqual(t, "subscription.channel_id", chanReq.ChannelID, subscription["channel_id"])
	tt.AssertEqual(t, "subscription.confirmed", false, subscription["confirmed"])
}

func TestGetChannelPreviewSubscriptionOwnSubscription(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	preview := tt.RequestAuthGet[gin.H](t, data.User[4].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", data.User[4].Channels[0].ChannelID))

	// Assert User[4] sees their own subscription
	tt.AssertNotNil(t, "subscription", preview["subscription"])
	subscription, ok := preview["subscription"].(map[string]any)
	tt.AssertTrue(t, "subscription is map", ok)
	tt.AssertEqual(t, "subscription.user_id", data.User[4].UID, subscription["subscriber_user_id"])
	tt.AssertEqual(t, "subscription.user_id", data.User[4].UID, subscription["channel_owner_user_id"])
	tt.AssertEqual(t, "subscription.channel_id", data.User[4].Channels[0].ChannelID, subscription["channel_id"])
	tt.AssertEqual(t, "subscription.confirmed", true, subscription["confirmed"])
}

func TestGetChannelPreviewSubscriptionForeignSubscription(t *testing.T) {
	ws, baseUrl, stop := tt.StartSimpleWebserver(t)
	defer stop()

	data := tt.InitDefaultData(t, ws)

	chanReq := *langext.ArrFirstOrNil(data.User[15].Channels, func(v tt.ChanData) bool { return v.InternalName == "chan_other_accepted" })

	preview := tt.RequestAuthGet[gin.H](t, data.User[14].ReadKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", chanReq.ChannelID))

	// Assert User[14] sees their confirmed subscription
	tt.AssertNotNil(t, "subscription", preview["subscription"])
	subscription, ok := preview["subscription"].(map[string]any)
	tt.AssertTrue(t, "subscription is map", ok)
	tt.AssertEqual(t, "subscription.user_id", data.User[14].UID, subscription["subscriber_user_id"])
	tt.AssertEqual(t, "subscription.user_id", data.User[15].UID, subscription["channel_owner_user_id"])
	tt.AssertEqual(t, "subscription.channel_id", chanReq.ChannelID, subscription["channel_id"])
	tt.AssertEqual(t, "subscription.confirmed", true, subscription["confirmed"])
}