# (c) cavaliba.com - tests / data / task errors download

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

import app_home.cache as cache
from app_data.tasks import create_datatask, finish_task
from tests import helper

ERRORS = [f"row-{i:02d}: refused" for i in range(1, 30)]


@override_settings(CAVALIBA_AUTH_MODE="unittest")
class TaskErrorsDownloadTest(TestCase):
    def setUp(self):
        cache.clear()

    def _task(self, owner="unittest", errors=None, state="DONE"):
        """A finished task owned by `owner`, carrying `errors` in its output."""

        dt = create_datatask("Import csv - sites.csv", owner_id=owner)
        output = {"total": 30, "count_ok": 1, "count_ko": len(errors or [])}
        if errors is not None:
            output["errors"] = errors
        finish_task(str(dt.handle), state=state, output=output)
        return str(dt.handle)

    def _url(self, handle):
        return reverse("app_data:task_errors", args=[handle])

    def test_every_error_is_served_one_per_line(self):
        helper.add_user_with_perm(login="unittest", perms=[])
        handle = self._task(errors=ERRORS)

        response = self.client.get(self._url(handle))

        self.assertEqual(response.status_code, 200)
        self.assertIn("text/plain", response["Content-Type"])
        lines = response.content.decode().strip().splitlines()
        self.assertEqual(lines, ERRORS)

    def test_served_as_an_attachment_named_after_the_task(self):
        helper.add_user_with_perm(login="unittest", perms=[])
        handle = self._task(errors=ERRORS)

        response = self.client.get(self._url(handle))

        self.assertIn("attachment;", response["Content-Disposition"])
        self.assertIn(f"task-errors-{handle}.txt", response["Content-Disposition"])

    def test_no_permission_needed_for_your_own_task(self):
        helper.add_user_with_perm(login="unittest", perms=[])
        handle = self._task(errors=ERRORS)

        self.assertEqual(self.client.get(self._url(handle)).status_code, 200)

    def test_task_without_errors_is_404(self):
        helper.add_user_with_perm(login="unittest", perms=[])
        handle = self._task(errors=None)

        self.assertEqual(self.client.get(self._url(handle)).status_code, 404)

    def test_empty_error_list_is_404(self):
        helper.add_user_with_perm(login="unittest", perms=[])
        handle = self._task(errors=[])

        self.assertEqual(self.client.get(self._url(handle)).status_code, 404)

    def test_another_users_task_is_404(self):
        helper.add_user_with_perm(login="unittest", perms=[])
        handle = self._task(owner="someone_else", errors=ERRORS)

        self.assertEqual(self.client.get(self._url(handle)).status_code, 404)

    def test_p_task_all_widens_to_another_users_task(self):
        helper.add_user_with_perm(login="unittest", perms=["p_task_all"])
        handle = self._task(owner="someone_else", errors=ERRORS)

        self.assertEqual(self.client.get(self._url(handle)).status_code, 200)

    def test_unknown_handle_is_404(self):
        helper.add_user_with_perm(login="unittest", perms=[])

        url = self._url("8e2b2a1e-0000-4000-8000-000000000000")
        self.assertEqual(self.client.get(url).status_code, 404)

    def test_post_not_allowed(self):
        helper.add_user_with_perm(login="unittest", perms=[])
        handle = self._task(errors=ERRORS)

        self.assertEqual(self.client.post(self._url(handle)).status_code, 405)

    def test_anonymous_is_not_served(self):
        handle = self._task(errors=ERRORS)

        self.assertNotEqual(self.client.get(self._url(handle)).status_code, 200)
