From 0de352e07a62f93d8097528b080e91a28b7525c7 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Wed, 25 Mar 2020 15:22:07 +0100
Subject: [PATCH] tests: add tests on views and commands (#41025)

---
 tests/test_commands.py                        | 51 +++++++++++++++++++
 tests/test_nanterre_views.py                  | 36 +++++++++++++
 tests/test_zoo.py                             | 38 ++++++++++++--
 .../management/commands/rsu-duplicates.py     |  2 +-
 4 files changed, 123 insertions(+), 4 deletions(-)
 create mode 100644 tests/test_commands.py
 create mode 100644 tests/test_nanterre_views.py

diff --git a/tests/test_commands.py b/tests/test_commands.py
new file mode 100644
index 0000000..9d265d0
--- /dev/null
+++ b/tests/test_commands.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+
+import mock
+import pytest
+
+from django.core.management import call_command
+
+
+def test_runjobs_command(db):
+    call_command('runjobs')
+
+    with mock.patch('zoo.zoo_data.management.commands.runjobs.Job.redo',
+                    side_effect=Exception):
+        with pytest.raises(Exception):
+            call_command('runjobs')
+
+
+def test_runscript_command(tmpdir):
+    script_path = '%s/script.py' % str(tmpdir)
+    open(script_path, 'w').write('# N/A')
+    call_command('runscript', script_path)
+
+
+def test_rsu_cron_command(settings, rsu):
+    settings.ZOO_NANTERRE_PASSAGE_A_LA_MAJORITE = True
+    call_command('rsu-cron', '-v2')
+
+
+def test_rsu_dupplicate_command(rsu):
+    call_command('rsu-duplicates', '-v2', 'list', '--dedup')
+    call_command('rsu-duplicates', '-v2', 'list')
+
+    with pytest.raises(AssertionError, match='Cannot filter a query once a slice has been taken'):
+        call_command('rsu-duplicates', 'list', '--count', '2')
+    with pytest.raises(TypeError, match="'datetime.datetime' object is not callable"):
+        call_command('rsu-duplicates', '-v2', 'list', '--days', '2')
+
+    with pytest.raises(KeyError, match='nom_d_usage'):
+        call_command('rsu-duplicates', '-v2', 'find', '--limit', '0.1')
+
+    call_command('rsu-duplicates', '-v2', 'delete', '--limit', '0.1')
+
+
+def test_rsu_integrity_check_command():
+    with mock.patch('zoo.zoo_nanterre.utils.integrity_check',
+                    return_value=(x for x in ('an error',))):
+        call_command('rsu-integrity-check')
+
+@mock.patch('zoo.zoo_nanterre.utils.psycopg2.connect')
+def test_rsu_load_dump_command(mocked_connect, rsu):
+    call_command('rsu-load-dump', 'pg_dsn=nanterre_rsu','authentic_fixture_path')
diff --git a/tests/test_nanterre_views.py b/tests/test_nanterre_views.py
new file mode 100644
index 0000000..9da2b73
--- /dev/null
+++ b/tests/test_nanterre_views.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+
+def test_rsu_demo_view(app, rsu):
+    resp = app.get('/rsu/demo/', status=200)
+    assert resp.html.find_all('h1')[1].text == u'Démo pour le RSU'
+    assert resp.html.find('a', {'href': 'search/'}).text == 'Recherche'
+
+
+def test_rsu_demo_search_view(app, rsu):
+    resp = app.get('/rsu/demo/search/', status=200)
+    assert u'Aucune fiche trouvée' in resp.text
+
+    resp = app.get('/rsu/demo/search/', {'query': 'Léon', 'limit': 0.1}, status=200)
+    nb_res_1 = len(resp.html.find_all('div', {'class': 'individu'}))
+
+    resp = app.get('/rsu/demo/search/', {'query': 'Léon', 'limit': 0.2}, status=200)
+    nb_res_2 = len(resp.html.find_all('div', {'class': 'individu'}))
+    assert nb_res_1 > nb_res_2 > 0
+
+
+def test_rsu_import_control_view(app, rsu):
+    resp = app.get('/rsu/import_control/', status=200)
+    assert resp.html.find_all('h1')[1].text == u"Contrôle de l'import"
+    ints = [
+        "Nombre d'individus",
+        "Nombre d'individus majeurs",
+        "Nombre d'individus mineurs",
+        u'Fédérations technocarte',
+    ]
+    number = []
+    for i, value in enumerate(ints):
+        assert resp.html.find_all('dt')[i].text == value
+        number.append(int(resp.html.find_all('dd')[i].text))
+    assert number[0] == number[3] == 1000
+    assert number[1] + number[2] == 1000
diff --git a/tests/test_zoo.py b/tests/test_zoo.py
index b727532..4ceb765 100644
--- a/tests/test_zoo.py
+++ b/tests/test_zoo.py
@@ -32,28 +32,32 @@ def person_schema(db):
                 'bad_type_property': {
                     'type': 'not string type'
                 }
             }
         })
     return schema
 
 
-def test_new_schema(db, person_schema):
-
-    Entity.objects.create(
+@pytest.fixture
+def person_entity(person_schema):
+    entity = Entity.objects.create(
         schema=person_schema,
         meta={},
         content={
             'first_name': 'Leon',
             'last_name': 'Blum',
             'address': {
                 'street': 'Rue du Château',
             }
         })
+    return entity
+
+
+def test_new_schema(person_schema, person_entity):
     qs = Entity.objects.content_search(person_schema, address__street='chateau')
     assert qs.count() == 1
 
 
 class ActionExample(object):
     def __init__(self, tries=2, content=None):
         self.content = content or {
             'tries': tries,
@@ -110,8 +114,36 @@ def test_demo_schemas_view(app, person_schema):
 def test_demo_schema_view(app, person_schema):
     resp = app.get('/demo/schemas/person/', {'page': 'not a number'}, status=200)
     assert resp.html.find('h1').text == 'person'
     assert resp.html.find('label', {'for': 'id_first_name'}).name
     assert resp.html.find('label', {'for': 'id_last_name'}).name
     assert resp.html.find('label', {'for': 'id_address__street'}).name
     assert not resp.html.find('label', {'for': 'bad_type_property'})
     assert resp.html.find('input', {'type': 'submit'})['value'] == 'Recherche'
+    assert u'Aucune entité trouvée' in resp.text
+
+
+def test_demo_search_on_schema_view(app, person_entity):
+    resp = app.get('/demo/schemas/person/', {'first_name': 'Leo'}, status=200)
+    assert u'Aucune entité trouvée' not in resp.text
+    assert 'Blum' in resp.html.pre.text
+
+    resp = app.get('/demo/schemas/person/', {'limit': 'not a float'}, status=200)
+    assert u'Aucune entité trouvée' in resp.text
+
+
+def test_admin_zoo_data_entity_inactive_view(app, admin, rsu):
+    url = '/admin/zoo_data/entity/inactive/'
+    app.set_user(admin.username)
+    resp = app.get(url, status=200)
+    assert [x.text for x in resp.html.find_all('h1')] == [
+        'Administration technique du RSU', u'Fiches inactives à supprimer']
+
+    resp = app.get(url+'?recompute', status=302)
+    assert resp.location == url
+
+    # unavailable post query
+    resp = app.post(url+'?delete', status=403)
+
+    resp = app.get(url+'?csv', status=200)
+    assert resp.content_type == 'text/csv'
+    assert resp.text == 'id,prenoms,nom_d_usage,nom_de_naissance,date_de_naissance,statut_legal,age\r\n'
diff --git a/zoo/zoo_nanterre/management/commands/rsu-duplicates.py b/zoo/zoo_nanterre/management/commands/rsu-duplicates.py
index 4e085ba..7e6f081 100644
--- a/zoo/zoo_nanterre/management/commands/rsu-duplicates.py
+++ b/zoo/zoo_nanterre/management/commands/rsu-duplicates.py
@@ -121,17 +121,17 @@ class Command(BaseCommand):
                 qs = qs[:count]
             if days:
                 since = now() - datetime.timedelta(days=days)
                 self.stdout.write('Duplicates created after', since)
                 qs = qs.filter(created__gte=since)
             if false:
                 qs = qs.filter(state=Duplicate.STATE_FALSE_POSITIVE)
             elif dedup:
-                qs = qs.filter(state=Duplicate.SATE_DEDUP)
+                qs = qs.filter(state=Duplicate.STATE_DEDUP)
             else:
                 qs = qs.filter(state=Duplicate.STATE_NEW)
             column_size = 0
             for duplicate in qs:
                 column_size = max(column_size, len(individu_caption(duplicate.first)),
                                   len(individu_caption(duplicate.second)))
 
             self.stdout.write('%d duplicates\n' % qs.count())
-- 
2.25.1

