from tests.base import CoreTestCase

URL = "/api/v1/settings/"
LOGO = "/api/v1/settings/logo/"
PNG = b"\x89PNG\r\n\x1a\n" + b"\x00" * 32
JPEG = b"\xff\xd8\xff\xe0" + b"\x00" * 32


class OrganizationSettingsTests(CoreTestCase):
    def test_manager_sets_the_colour_for_everyone(self):
        r = self.api(self.manager_a, self.org_a).patch(URL, {"accent_color": "blue"}, format="json")
        self.assertEqual(r.status_code, 200, r.data)
        self.org_a.refresh_from_db()
        self.assertEqual(self.org_a.accent_color, "blue")
        # every member receives it with their session (/me/ carries the organization)
        context = self.api(self.employee_a, self.org_a).get("/api/v1/me/").data["context"]
        self.assertEqual(context["organization"]["accent_color"], "blue")

    def test_employee_cannot_change_it_and_other_organizations_are_untouched(self):
        self.assertEqual(self.api(self.employee_a, self.org_a).patch(URL, {"accent_color": "rose"}, format="json").status_code, 403)
        self.api(self.manager_a, self.org_a).patch(URL, {"accent_color": "teal"}, format="json")
        self.org_b.refresh_from_db()
        self.assertEqual(self.org_b.accent_color, "violet")
        self.assertEqual(self.api(self.manager_a, self.org_b).patch(URL, {"accent_color": "teal"}, format="json").status_code, 403)

    def test_unknown_colour_is_rejected(self):
        r = self.api(self.manager_a, self.org_a).patch(URL, {"accent_color": "#ff0000"}, format="json")
        self.assertEqual(r.status_code, 400)
        self.org_a.refresh_from_db()
        self.assertEqual(self.org_a.accent_color, "violet")

    def test_manager_renames_the_organization(self):
        r = self.api(self.manager_a, self.org_a).patch(URL, {"name": "  Acme  "}, format="json")
        self.assertEqual(r.status_code, 200, r.data)
        self.org_a.refresh_from_db()
        self.assertEqual(self.org_a.name, "Acme")
        self.assertEqual(self.api(self.manager_a, self.org_a).patch(URL, {"name": "x"}, format="json").status_code, 400)
        self.assertEqual(self.api(self.employee_a, self.org_a).patch(URL, {"name": "Hacked"}, format="json").status_code, 403)
        self.assertEqual(self.api(self.root, self.platform).patch(URL, {"name": "Renamed"}, format="json").status_code, 400)

    def upload(self, client, content, name="logo.png"):
        from django.core.files.uploadedfile import SimpleUploadedFile

        return client.post(LOGO, {"logo": SimpleUploadedFile(name, content)}, format="multipart")

    def test_logo_upload_replace_and_remove(self):
        import tempfile

        from django.test import override_settings

        with tempfile.TemporaryDirectory() as media, override_settings(MEDIA_ROOT=media):
            client = self.api(self.manager_a, self.org_a)
            r = self.upload(client, PNG)
            self.assertEqual(r.status_code, 200, r.data)
            first = r.data["logo_url"]
            self.assertTrue(first.endswith(".png"))
            self.assertNotIn("logo.png", first)  # the uploaded name is never used
            me = self.api(self.employee_a, self.org_a).get("/api/v1/me/").data["context"]["organization"]
            self.assertEqual(me["logo_url"], first)
            self.assertEqual(self.upload(client, JPEG, "x.jpg").status_code, 200)
            self.org_a.refresh_from_db()
            self.assertTrue(self.org_a.logo.name.endswith(".jpg"))
            self.assertEqual(client.delete(LOGO).data["logo_url"], None)
            self.org_a.refresh_from_db()
            self.assertFalse(self.org_a.logo)

    def test_logo_rejects_wrong_types_big_files_and_non_managers(self):
        import tempfile

        from django.test import override_settings

        with tempfile.TemporaryDirectory() as media, override_settings(MEDIA_ROOT=media):
            client = self.api(self.manager_a, self.org_a)
            self.assertEqual(self.upload(client, b"<svg onload=alert(1)></svg>", "a.png").status_code, 400)
            self.assertEqual(self.upload(client, b"hello", "a.png").status_code, 400)
            self.assertEqual(self.upload(client, PNG + b"0" * (1024 * 1024)).status_code, 400)
            self.assertEqual(self.api(self.employee_a, self.org_a).post(LOGO).status_code, 403)
            self.assertEqual(self.upload(self.api(self.manager_b, self.org_b), PNG).status_code, 200)
            self.assertEqual(self.upload(self.api(self.manager_b, self.org_a), PNG).status_code, 403)
            self.assertEqual(self.api(self.root, self.platform).post(LOGO).status_code, 400)

    def test_every_panel_has_a_settings_menu_entry(self):
        for user, org in ((self.employee_a, self.org_a), (self.manager_a, self.org_a), (self.root, self.platform)):
            nav = self.api(user, org).get("/api/v1/me/").data["context"]["navigation"]
            self.assertIn("settings", {i["key"] for i in nav})
