Projet

Général

Profil

0001-tests-add-tests-on-views-and-commands-41025.patch

Nicolas Roche, 26 mars 2020 18:23

Télécharger (15 ko)

Voir les différences:

Subject: [PATCH] tests: add tests on views and commands (#41025)

 tests/test_commands.py       | 149 +++++++++++++++++++++++++++++++++++
 tests/test_nanterre.py       |  15 ++++
 tests/test_nanterre_views.py | 105 ++++++++++++++++++++++++
 tests/test_zoo.py            |  38 ++++++++-
 4 files changed, 304 insertions(+), 3 deletions(-)
 create mode 100644 tests/test_commands.py
 create mode 100644 tests/test_nanterre_views.py
tests/test_commands.py
1
# -*- coding: utf-8 -*-
2

  
3
import mock
4
import pytest
5
import sys
6

  
7
from zoo.zoo_data.models import Entity, Transaction, Relation
8
from zoo.zoo_nanterre import utils
9

  
10
from django.core.management import call_command
11
from django.db.transaction import atomic
12
from django.utils.six import StringIO
13

  
14

  
15
def get_output_of_command(command, *args, **kwargs):
16
    old_stdout = sys.stdout
17
    output = sys.stdout = StringIO()
18
    call_command(command, *args, **kwargs)
19
    sys.stdout = old_stdout
20
    return output.getvalue()
21

  
22

  
23
def test_runjobs_command(db):
24
    call_command('runjobs')
25

  
26
    with mock.patch('zoo.zoo_data.management.commands.runjobs.Job.redo',
27
                    side_effect=Exception):
28
        with pytest.raises(Exception):
29
            call_command('runjobs')
30

  
31

  
32
def test_runscript_command(tmpdir):
33
    script_path = '%s/script.py' % str(tmpdir)
34
    open(script_path, 'w').write('# N/A')
35
    call_command('runscript', script_path)
36

  
37

  
38
def test_rsu_cron_command(settings, nanterre_classic_family):
39
    settings.ZOO_NANTERRE_PASSAGE_A_LA_MAJORITE = True
40
    call_command('rsu-cron', '-v2')
41

  
42

  
43
def test_rsu_dupplicate_command(nanterre_classic_family):
44
    call_command('rsu-duplicates', '-v2', 'list', '--dedup')
45
    call_command('rsu-duplicates', '-v2', 'list')
46

  
47
    with pytest.raises(AssertionError, match='Cannot filter a query once a slice has been taken'):
48
        call_command('rsu-duplicates', 'list', '--count', '2')
49
    with pytest.raises(TypeError, match="'datetime.datetime' object is not callable"):
50
        call_command('rsu-duplicates', '-v2', 'list', '--days', '2')
51

  
52
    call_command('rsu-duplicates', '-v2', 'find', '--limit', '0.1')
53
    call_command('rsu-duplicates', '-v2', 'delete', '--limit', '0.1')
54

  
55

  
56
def test_rsu_integrity_check_command(rsu_schema, nanterre_classic_family):
57
    output = get_output_of_command('rsu-integrity-check')
58
    assert output == ''
59

  
60
    jean = nanterre_classic_family['jean']
61
    marie = nanterre_classic_family['marie']
62
    lilou = nanterre_classic_family['lilou']
63
    kevin = nanterre_classic_family['kevin']
64
    with atomic():
65
        tr = Transaction.get_transaction()
66
    address2 = Entity.objects.create(
67
        created=tr,
68
        schema=rsu_schema[utils.ADRESSE_ENT],
69
        content={
70
            'at': '',
71
            'streetnumber': '169',
72
            'streetnumberext': '',
73
            'streetname': 'RUE DU CHATEAU',
74
            'ext1': '',
75
            'ext2': '',
76
            'streetmatriculation': '00169',
77
            'zipcode': '75014',
78
            'inseecode': '75014',
79
            'city': 'PARIS',
80
            'country': 'FRANCE',
81
        })
82
    address3 = Entity.objects.create(
83
        created=tr,
84
        schema=rsu_schema[utils.ADRESSE_ENT],
85
        content={
86
            'at': '',
87
            'streetnumber': '170',
88
            'streetnumberext': 'à côté',
89
            'streetname': 'RUE DU CHATEAU',
90
            'ext1': '',
91
            'ext2': '',
92
            'streetmatriculation': '00170',
93
            'zipcode': '75014',
94
            'inseecode': '75014',
95
            'city': 'PARIS',
96
            'country': 'FRANCE',
97
        })
98
    Relation.objects.create(
99
        created=tr,
100
        schema=rsu_schema[utils.HABITE_REL],
101
        content={'principale': False},
102
        left=jean,
103
        right=address2)
104
    Relation.objects.create(
105
        created=tr,
106
        schema=rsu_schema[utils.HABITE_REL],
107
        content={'principale': False},
108
        left=kevin,
109
        right=address2)
110
    Relation.objects.create(
111
        created=tr,
112
        schema=rsu_schema[utils.HABITE_REL],
113
        content={'principale': False},
114
        left=kevin,
115
        right=address3)
116
    Relation.objects.create(
117
        created=tr,
118
        schema=rsu_schema[utils.UNION_REL],
119
        content={'status': 'pacs/mariage'},
120
        left=jean,
121
        right=marie)
122
    Relation.objects.create(
123
        created=tr,
124
        schema=rsu_schema[utils.RESPONSABILITE_LEGALE_REL],
125
        content={'status': 'parent'},
126
        left=lilou,
127
        right=kevin)
128
    Relation.objects.filter(
129
        schema__slug='habite',
130
        left_id=marie.id
131
    ).delete()
132
    Relation.objects.filter(
133
        schema__slug='habite',
134
        left_id=lilou.id
135
    ).delete()
136
    output = get_output_of_command('rsu-integrity-check')
137

  
138
    assert "le couple %s / %s est en union plusieurs fois" % (jean.id, marie.id) in output
139
    assert "l'individu %s est en union avec plus d'une personne" % jean.id in output
140
    assert "l'adulte %s a plus d'une adresse" % jean.id in output
141
    assert "l'enfant %s a plus de deux parents" % kevin.id in output
142
    assert "l'enfant %s a plus de deux adresses" % kevin.id in output
143
    assert "l'adulte %s n'a pas d'adresse" % marie.id in output
144
    assert "l'enfant %s n'a pas d'adresse" % lilou.id in output
145

  
146

  
147
@mock.patch('zoo.zoo_nanterre.utils.psycopg2.connect')
148
def test_rsu_load_dump_command(mocked_connect, nanterre_classic_family):
149
    call_command('rsu-load-dump',  '-v3', 'pg_dsn=nanterre_rsu','authentic_fixture_path')
tests/test_nanterre.py
63 63
            assert individu['date_de_modification'] == individu['date_de_creation']
64 64

  
65 65
    birthdate = rsu[0].content['date_de_naissance']
66 66
    response = app.get(url + '?q=%s' % birthdate)
67 67
    assert response.json['err'] == 0
68 68
    assert len(response.json['data'])
69 69
    assert any(data['id'] == rsu[0].id for data in response.json['data'])
70 70

  
71
    response = app.get(url + '?nom=%s' % rsu[0].content['nom_de_naissance'])
72
    assert len(response.json['data']) > 0
73
    response = app.get(url + '?date_de_naissance=%s' % rsu[0].content['date_de_naissance'])
74
    assert len(response.json['data']) > 0
75
    response = app.get(url + '?cle=42', status=200)
76
    response = app.get(url + '?email=%s' % rsu[0].content['email'])
77
    assert len(response.json['data']) > 0
78
    response = app.get(url + '?NameID=my_a2_username', status=200)
79
    response = app.get(url + '?cle_?=*', status=200)
80

  
71 81

  
72 82
def test_create_individu(settings, transactional_db, app, app_noauth, rsu_schema):
73 83

  
74 84
    def get_reseau(identifier):
75 85
        reseau_url = reverse('rsu-api-reseau', kwargs={
76 86
            'identifier': identifier
77 87
        })
78 88
        response = app.get(reseau_url)
......
443 453
    # l'adresse du deuxième adulte a été supprimé
444 454
    assert Entity.objects.filter(id=second_adult_address.id).count() == 0
445 455

  
446 456
    # déclaration d'adresse principale pour le premier enfant
447 457
    declaration_adresse_principale_url = reverse('rsu-api-declaration-adresse-principale', kwargs={
448 458
        'identifier': enfant_id
449 459
    })
450 460

  
461
    # requette get
462
    response = app.get(declaration_adresse_principale_url)
463
    assert response.content_type == 'application/json'
464
    assert not response.json['err']
465

  
451 466
    data = get_reseau(enfant_id)
452 467
    assert len(data['adresses']) == 1
453 468
    assert data['adresses'][0]['principale'] is False
454 469

  
455 470
    # sur première adresse ok
456 471
    response = app.post_json(declaration_adresse_principale_url, params={
457 472
        'adresse_principale': 1,
458 473
    })
tests/test_nanterre_views.py
1
# -*- coding: utf-8 -*-
2

  
3
from zoo.zoo_data.models import Entity, Transaction, Relation
4
from zoo.zoo_nanterre import utils
5

  
6
from django.db.transaction import atomic
7

  
8

  
9
def test_rsu_demo_view(app, nanterre_classic_family):
10
    resp = app.get('/rsu/demo/', status=200)
11
    assert resp.html.find_all('h1')[1].text == u'Démo pour le RSU'
12
    assert resp.html.find('a', {'href': 'search/'}).text == 'Recherche'
13

  
14

  
15
def test_rsu_demo_search_view_limit(app, rsu):
16
    resp = app.get('/rsu/demo/search/', status=200)
17
    assert u'Aucune fiche trouvée' in resp.text
18

  
19
    # largest
20
    resp = app.get('/rsu/demo/search/', {'query': 'Léon', 'limit': 0.1}, status=200)
21
    nb_res_1 = len(resp.html.find_all('div', {'class': 'individu'}))
22

  
23
    # finer
24
    resp = app.get('/rsu/demo/search/', {'query': 'Léon', 'limit': 0.2}, status=200)
25
    nb_res_2 = len(resp.html.find_all('div', {'class': 'individu'}))
26
    assert nb_res_1 > nb_res_2 > 0
27

  
28

  
29
def test_rsu_demo_search_view(app, nanterre_classic_family):
30
    url = '/rsu/demo/search/'
31

  
32
    # name
33
    resp = app.get(url, {'query': 'Lou', 'limit': 0.1}, status=200)
34
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 1
35

  
36
    # email
37
    resp = app.get(url, {'query': 'marie.darmette@example.com', 'limit': 0.9}, status=200)
38
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 2
39

  
40
    # id
41
    resp = app.get(url, {'query': '#1', 'limit': 0.9}, status=200)
42

  
43
    # birthdate
44
    resp = app.get(url, {'query': '01/01/2008', 'limit': 0.9}, status=200)
45
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 1
46
    resp = app.get(url, {'query': '01/01/08', 'limit': 0.9}, status=200)
47
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 1
48
    resp = app.get(url, {'query': '01/01/82', 'limit': 0.9}, status=200)
49
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 2
50
    resp = app.get(url, {'query': '01/82', 'limit': 0.9}, status=200)
51
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 2
52
    resp = app.get(url, {'query': '82', 'limit': 0.9}, status=200)
53
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 2
54
    resp = app.get(url, {'query': '08 kev', 'limit': 0.1}, status=200)
55
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 1
56

  
57

  
58
def test_rsu_import_control_view(app, nanterre_classic_family):
59
    resp = app.get('/rsu/import_control/', status=200)
60
    assert resp.html.find_all('h1')[1].text == u"Contrôle de l'import"
61
    ints = [
62
        ("Nombre d'individus", 4),
63
        ("Nombre d'individus majeurs", 2),
64
        ("Nombre d'individus mineurs", 2),
65
        (u'Fédérations technocarte', 0),
66
    ]
67
    for i, (key, value) in enumerate(ints):
68
        assert resp.html.find_all('dt')[i].text == key
69
        assert int(resp.html.find_all('dd')[i].text) == value
70

  
71

  
72
def test_adresse(app, rsu_schema, nanterre_classic_family):
73
    with atomic():
74
        tr = Transaction.get_transaction()
75
    address = Entity.objects.create(
76
        created=tr,
77
        schema=rsu_schema[utils.ADRESSE_ENT],
78
        content={
79
            'at': '',
80
            'streetnumber': '169',
81
            'streetnumberext': '',
82
            'streetname': 'RUE DU CHATEAU',
83
            'ext1': '',
84
            'ext2': '',
85
            'streetmatriculation': '00169',
86
            'zipcode': '75014',
87
            'inseecode': '75014',
88
            'city': 'PARIS',
89
            'country': 'FRANCE',
90
        })
91
    assert utils.adresse(nanterre_classic_family['jean'])
92
    Relation.objects.create(
93
        created=tr,
94
        schema=rsu_schema[utils.HABITE_REL],
95
        content={'principale': False},
96
        left=nanterre_classic_family['jean'],
97
        right=address)
98
    assert not utils.adresse(nanterre_classic_family['jean'])
99

  
100

  
101
def test_add_age(app, nanterre_classic_family, freezer):
102
    freezer.move_to('2008-01-02T00:00:00')
103
    resp = app.get('/rsu/demo/search/', {'query': '2008-01-01', 'limit': 0.9}, status=200)
104
    assert len(resp.html.find_all('div', {'class': 'individu'})) == 1
105
    assert resp.html.find('span', {'class': 'individu-age'}).text == "moins d'un mois"
tests/test_zoo.py
32 32
                'bad_type_property': {
33 33
                    'type': 'not string type'
34 34
                }
35 35
            }
36 36
        })
37 37
    return schema
38 38

  
39 39

  
40
def test_new_schema(db, person_schema):
41

  
42
    Entity.objects.create(
40
@pytest.fixture
41
def person_entity(person_schema):
42
    entity = Entity.objects.create(
43 43
        schema=person_schema,
44 44
        meta={},
45 45
        content={
46 46
            'first_name': 'Leon',
47 47
            'last_name': 'Blum',
48 48
            'address': {
49 49
                'street': 'Rue du Château',
50 50
            }
51 51
        })
52
    return entity
53

  
54

  
55
def test_new_schema(person_schema, person_entity):
52 56
    qs = Entity.objects.content_search(person_schema, address__street='chateau')
53 57
    assert qs.count() == 1
54 58

  
55 59

  
56 60
class ActionExample(object):
57 61
    def __init__(self, tries=2, content=None):
58 62
        self.content = content or {
59 63
            'tries': tries,
......
110 114
def test_demo_schema_view(app, person_schema):
111 115
    resp = app.get('/demo/schemas/person/', {'page': 'not a number'}, status=200)
112 116
    assert resp.html.find('h1').text == 'person'
113 117
    assert resp.html.find('label', {'for': 'id_first_name'}).name
114 118
    assert resp.html.find('label', {'for': 'id_last_name'}).name
115 119
    assert resp.html.find('label', {'for': 'id_address__street'}).name
116 120
    assert not resp.html.find('label', {'for': 'bad_type_property'})
117 121
    assert resp.html.find('input', {'type': 'submit'})['value'] == 'Recherche'
122
    assert u'Aucune entité trouvée' in resp.text
123

  
124

  
125
def test_demo_search_on_schema_view(app, person_entity):
126
    resp = app.get('/demo/schemas/person/', {'first_name': 'Leo'}, status=200)
127
    assert u'Aucune entité trouvée' not in resp.text
128
    assert 'Blum' in resp.html.pre.text
129

  
130
    resp = app.get('/demo/schemas/person/', {'limit': 'not a float'}, status=200)
131
    assert u'Aucune entité trouvée' in resp.text
132

  
133

  
134
def test_admin_zoo_data_entity_inactive_view(app, admin, nanterre_classic_family):
135
    url = '/admin/zoo_data/entity/inactive/'
136
    app.set_user(admin.username)
137
    resp = app.get(url, status=200)
138
    assert [x.text for x in resp.html.find_all('h1')] == [
139
        'Administration technique du RSU', u'Fiches inactives à supprimer']
140

  
141
    resp = app.get(url+'?recompute', status=302)
142
    assert resp.location == url
143

  
144
    # unavailable post query
145
    resp = app.post(url+'?delete', status=403)
146

  
147
    resp = app.get(url+'?csv', status=200)
148
    assert resp.content_type == 'text/csv'
149
    assert resp.text == 'id,prenoms,nom_d_usage,nom_de_naissance,date_de_naissance,statut_legal,age\r\n'
118
-