# (c) cavaliba.com - test_data_refs.py

import json

from django.test import TestCase
from django.urls import reverse

import app_home.cache as cache
from tests import helper

# ---------------------------------------------------------------------------
# API tests: ?refs= parameter on /api/assets/
# ---------------------------------------------------------------------------


class APIAssetRefsTest(TestCase):
    def setUp(self):
        cache.clear()
        self.header = helper.add_apikey_admin()

        helper.add_schema(
            classname="refstest",
            field_definition={
                "owner": {
                    "dataformat": "user",
                    "displayname": "Owner",
                    "cardinal_min": 0,
                    "cardinal_max": 1,
                },
                "linked": {
                    "dataformat": "schema",
                    "dataformat_ext": "refsother",
                    "displayname": "Linked",
                    "cardinal_min": 0,
                    "cardinal_max": 1,
                },
            },
        )
        helper.add_schema(classname="refsother")

        helper.add_instance(
            classname="refsother", keyname="other01", fields={"displayname": "Other 01"}
        )

        helper.add_instance(
            classname="refstest",
            keyname="obj01",
            fields={
                "owner": "testuser01",
                "linked": "other01",
            },
        )

        helper.add_user(login="testuser01", displayname="Test User 01")

        self.url = reverse("api:api_asset", kwargs={"skey": "refstest", "key": "obj01"})

    def test_api_no_refs_param(self):
        response = self.client.get(self.url, headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertNotIn("_refs", data)

    def test_api_refs_user(self):
        response = self.client.get(self.url + "?refs=user", headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertIn("_refs", data)
        self.assertIn("user", data["_refs"])

    def test_api_refs_user_login(self):
        response = self.client.get(self.url + "?refs=user", headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        logins = [u["keyname"] for u in data["_refs"]["user"]]
        self.assertIn("testuser01", logins)

    def test_api_refs_schema(self):
        response = self.client.get(self.url + "?refs=refsother", headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertIn("_refs", data)
        self.assertIn("refsother", data["_refs"])

    def test_api_refs_multiple_types(self):
        response = self.client.get(self.url + "?refs=user,refsother", headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertIn("_refs", data)
        self.assertIn("user", data["_refs"])
        self.assertIn("refsother", data["_refs"])

    def test_api_refs_star(self):
        response = self.client.get(self.url + "?refs=*", headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertIn("_refs", data)
        self.assertIn("refsother", data["_refs"])

    def test_api_refs_star_with_user(self):
        response = self.client.get(self.url + "?refs=*,user", headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertIn("_refs", data)
        self.assertIn("user", data["_refs"])
        self.assertIn("refsother", data["_refs"])

    def test_api_refs_unknown_no_refs_key(self):
        response = self.client.get(self.url + "?refs=nonexistent", headers=self.header)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertNotIn("_refs", data)
