# (c) cavaliba.com - tests / views_importer - first/last row range

from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase, override_settings
from django.urls import reverse

import app_home.cache as cache
from app_data.data import Instance
from tests import helper

CSV_5_ROWS = (
    "classname,keyname,mystring\n"
    "rrtest,row1,a\n"
    "rrtest,row2,b\n"
    "rrtest,row3,c\n"
    "rrtest,row4,d\n"
    "rrtest,row5,e\n"
)


@override_settings(CAVALIBA_AUTH_MODE="unittest", CELERY_TASK_ALWAYS_EAGER=True)
class ViewImporterRowRangeTest(TestCase):
    def setUp(self):
        cache.clear()
        helper.add_admin_user(login="unittest")
        helper.add_schema(
            classname="rrtest",
            field_definition={"mystring": {"dataformat": "string", "displayname": "MyString"}},
        )

    def _post(self, extra):
        data = {
            "file": SimpleUploadedFile(
                "data.csv", CSV_5_ROWS.encode("utf-8"), content_type="text/csv"
            ),
            "pipeline": "",
            "encoding": "utf-8",
            "separator": ",",
            "split_multivalue": "on",
            "submit": "import",
        }
        data.update(extra)
        return self.client.post(reverse("app_data:data_import"), data)

    def _imported(self):
        return [
            keyname
            for keyname in ("row1", "row2", "row3", "row4", "row5")
            if Instance.from_keyname(classname="rrtest", keyname=keyname, expand=False)
        ]

    def test_no_range_imports_every_row(self):
        self._post({})
        self.assertEqual(self._imported(), ["row1", "row2", "row3", "row4", "row5"])

    def test_last_alone_stops_after_that_row(self):
        self._post({"last": "2"})
        self.assertEqual(self._imported(), ["row1", "row2"])

    def test_first_alone_skips_the_rows_before_it(self):
        self._post({"first": "4"})
        self.assertEqual(self._imported(), ["row4", "row5"])

    def test_both_bounds_are_included(self):
        self._post({"first": "2", "last": "4"})
        self.assertEqual(self._imported(), ["row2", "row3", "row4"])

    def test_row_1_is_the_first_data_row_not_the_csv_header(self):
        self._post({"first": "1", "last": "1"})
        self.assertEqual(self._imported(), ["row1"])

    def test_inverted_range_is_rejected(self):
        response = self._post({"first": "4", "last": "2"})
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.context["form"].errors.get("last"))
        self.assertIsNone(response.context["task_handle"])
        self.assertEqual(self._imported(), [])
