"""
We are using unittest for troggle.

Note that the database has not been parsed from the source files when these tests are run,
so any path that relies on data being in the database will fail.

https://docs.djangoproject.com/en/dev/topics/testing/tools/

We are not using 
https://github.com/FactoryBoy/factory_boy
because we are trying to minimise the number of 3rd-party packages because they expose us to update hell,
as experience in 2019-2020.
However we could use 
https://docs.python.org/dev/library/unittest.mock.html
as this is now part if python - if we can get our heads around it.

The tests in this file:

The code  {% url THING %}  or {% url THING PARAMETER %} appears a hundred times or more in the troggle/templates/ HTML template files.
This is the template synstax for 
reverse('THING')
or
reverse('THING', args=[PARAMETER])

It is the URLS which take parameters which need understanding and testing. The reverse() which take no
parameters should be fine as this is fundamental Django stuff which will have been tested to death.

But the reverse() function is purely syntactical, the PARAMETER is just a string which is applied to
the url. So this is not testing anything important really. See the test_url_threed() below.

These url lines all come from templates/*.html

1. No tests: No parameters

{% url "caveindex" %}
{% url "controlpanel" %}
{% url "dataissues" %}
{% url "dwgallfiles" %}
{% url "dwgupload" %}
{% url "stations" %}
{% url "exportlogbook" %}
{% url "newcave" %}
{% url "notablepersons" %}
{% url "photoupload" %}
{% url "walletedit" %}

Tests exist:
{% url "stats" %}
{% url "allscans" %}
{% url "survexcaveslist" %}

2. With parameter

{% url "caveQMs" "1623-290" %}
{% url "cave_openQMs" "1623-290" %}
{% url "cavewallets" cave_id %}
{% url "dwgfilesingle" drawing.dwgpath %}
{% url "edit_cave" cave.url_parent cave.slug %}
{% url "editentrance" cave.slug ent.entrance.slug %}
{% url "editexpopage" path %}
{% url "err" title %}
{% url "expedition" 2022 %}
{% url "newentrance" cave.slug %}
{% url "survexcavessingle" cavedir %}
{% url "survexcavessingle" cavefiles.0.1 %}
{% url "svx" cavepath %}
{% url "svx" survexfile.path %}
{% url "svxlog" title %}
{% url 'caveQMs' '1623-161' %}
{% url 'image_selector' path %}
{% url 'new_image_form' path %}

Tests exist:
{% url "threed" title %}
"""


todo = """These just do {% url THING %} with no parameter, we also need tests which take a parameter

- Read all this https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing

- Read all this https://realpython.com/testing-in-django-part-1-best-practices-and-examples/

- add 'coverage' to all tests

- statistics also needs test when we have put data into the database

"""

import re
from http import HTTPStatus

from django.test import Client, TestCase
from django.urls import path, reverse


# class SimplePageTest(unittest.TestCase):
class URLTests(TestCase):
    """These tests may appear to be redundant, but in fact they exercise different bits of code. The urls.py
    dispatcher is sending these URLs view via different 'view' handlers, and they all need verifying.
    """

    @classmethod
    def setUpTestData(cls):
        # Set up data for the whole TestCase
        # cls.foo = Foo.objects.create(bar="Test")
        # Some test using self.foo in tests below..
        # read in some SQL ?
        pass

    def setUp(self):
        # Every test needs a client.
        self.client = Client()

    def test_statistics(self):
        response = self.client.get("/statistics")
        self.assertEqual(response.status_code, HTTPStatus.OK)
        content = response.content.decode()
        with open('_test_response.html', 'w') as f:
            f.write(content)
        ph = r"0 expeditions: 0 people,  0 caves, 0 wallets and 0 logbook entries"
        phmatch = re.search(ph, content)
        self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'")

    def test_stats(self):
        # Needs another test with test data
        response = self.client.get("/stats")
        self.assertEqual(response.status_code, HTTPStatus.OK)
        content = response.content.decode()
        # with open('_test_response.html', 'w') as f:
            # f.write(content)
        ph = r"Total length: 0.0 km adding up the total for each year."
        phmatch = re.search(ph, content)
        self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'")

    def test_url_stats(self):
        """Test the {% url "stats" %} reverse resolution
        path('statistics',        statistics.stats,       name="stats"),
        path('stats',             statistics.stats,       name="stats"),
        """
        reversed_url = reverse('stats') # NB _ must be written as - if present in name
        self.assertEqual(reversed_url, "/stats")

    def test_url_allscans(self):
        """Test the {% url "allscans" %} reverse resolution
        path('survey_scans',                    allscans,    name="allscans"), # all the scans in all wallets
        """
        reversed_url = reverse('allscans') # NB _ must be written as - if present in name
        self.assertEqual(reversed_url, "/survey_scans")

    def test_url_survexcaveslist(self):
        """Test the {% url "allscans" %} reverse resolution
        path('survexfile/caves',              survex.survexcaveslist,     name="survexcaveslist"),
        """
        reversed_url = reverse('survexcaveslist') # NB _ must be written as - if present in name
        self.assertEqual(reversed_url, "/survexfile/caves")

    def test_url_threed(self):
        """Test the {% url "threed" %} reverse resolution
        path('survexfile/<path:survex_file>.3d',  survex.threed,     name="threed"), 
        """
        reversed_url = reverse('threed', args=['zilch']) # NB _ must be written as - if present in name
        self.assertEqual(reversed_url, "/survexfile/zilch.3d")

