mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-23 15:33:45 +00:00
Merge branch '347-tests-are-broken' into 'dev'
Resolve "Tests are broken" See merge request re2o/re2o!635
This commit is contained in:
commit
cab6598d28
11 changed files with 330 additions and 161 deletions
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2024 Caroline Canebier
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from os.path import dirname, abspath
|
||||||
|
from django.conf import settings as django_settings
|
||||||
|
|
||||||
|
def load_tests(loader, tests, pattern):
|
||||||
|
"""
|
||||||
|
As this is an optional app, load its tests only if it is installed.
|
||||||
|
"""
|
||||||
|
if "api" in django_settings.INSTALLED_APPS:
|
||||||
|
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
|
51
api/tests.py
51
api/tests.py
|
@ -227,8 +227,6 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
# For more details, see
|
# For more details, see
|
||||||
# https://docs.djangoproject.com/en/1.10/topics/testing/tools/#testcase
|
# https://docs.djangoproject.com/en/1.10/topics/testing/tools/#testcase
|
||||||
|
|
||||||
super(APIEndpointsTestCase, cls).setUpClass()
|
|
||||||
|
|
||||||
# A user with no rights
|
# A user with no rights
|
||||||
cls.stduser = users.User.objects.create_user(
|
cls.stduser = users.User.objects.create_user(
|
||||||
"apistduser", "apistduser", "apistduser@example.net", "apistduser"
|
"apistduser", "apistduser", "apistduser@example.net", "apistduser"
|
||||||
|
@ -261,22 +259,22 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
registered=datetime.datetime.now(datetime.timezone.utc),
|
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||||
telephone="0123456789",
|
telephone="0123456789",
|
||||||
uid_number=21102,
|
uid_number=21102,
|
||||||
rezo_rez_uid=21102,
|
|
||||||
)
|
)
|
||||||
cls.users_user_1 = cls.users_adherent_1
|
cls.users_user_1 = cls.users_adherent_1
|
||||||
cls.cotisations_article_1 = cotisations.Article.objects.create(
|
cls.cotisations_article_1 = cotisations.Article.objects.create(
|
||||||
name="cotisations_article_1",
|
name="cotisations_article_1",
|
||||||
prix=10,
|
prix=10,
|
||||||
duration=1,
|
duration_days_membership=0,
|
||||||
|
duration_membership=1,
|
||||||
|
duration_days_connection=0,
|
||||||
|
duration_connection=1,
|
||||||
type_user=cotisations.Article.USER_TYPES[0][0],
|
type_user=cotisations.Article.USER_TYPES[0][0],
|
||||||
type_cotisation=cotisations.Article.COTISATION_TYPE[0][0],
|
|
||||||
)
|
)
|
||||||
cls.cotisations_banque_1 = cotisations.Banque.objects.create(
|
cls.cotisations_banque_1 = cotisations.Banque.objects.create(
|
||||||
name="cotisations_banque_1"
|
name="cotisations_banque_1"
|
||||||
)
|
)
|
||||||
cls.cotisations_paiement_1 = cotisations.Paiement.objects.create(
|
cls.cotisations_paiement_1 = cotisations.Paiement.objects.create(
|
||||||
moyen="cotisations_paiement_1",
|
moyen="cotisations_paiement_1",
|
||||||
type_paiement=cotisations.Paiement.PAYMENT_TYPES[0][0],
|
|
||||||
)
|
)
|
||||||
cls.cotisations_facture_1 = cotisations.Facture.objects.create(
|
cls.cotisations_facture_1 = cotisations.Facture.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
|
@ -292,8 +290,10 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
number=2,
|
number=2,
|
||||||
name="cotisations_vente_1",
|
name="cotisations_vente_1",
|
||||||
prix=10,
|
prix=10,
|
||||||
duration=1,
|
duration_days_membership=0,
|
||||||
type_cotisation=cotisations.Vente.COTISATION_TYPE[0][0],
|
duration_membership=1,
|
||||||
|
duration_days_connection=0,
|
||||||
|
duration_connection=1,
|
||||||
)
|
)
|
||||||
# A cotisation is automatically created by the Vente object and
|
# A cotisation is automatically created by the Vente object and
|
||||||
# trying to create another cotisation associated with this vente
|
# trying to create another cotisation associated with this vente
|
||||||
|
@ -328,7 +328,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
vlan_id=0, name="machines_vlan_1", comment="machines Vlan 1"
|
vlan_id=0, name="machines_vlan_1", comment="machines Vlan 1"
|
||||||
)
|
)
|
||||||
cls.machines_iptype_1 = machines.IpType.objects.create(
|
cls.machines_iptype_1 = machines.IpType.objects.create(
|
||||||
type="machines_iptype_1",
|
name="machines_iptype_1",
|
||||||
extension=cls.machines_extension_1, # Dep machines.Extension
|
extension=cls.machines_extension_1, # Dep machines.Extension
|
||||||
need_infra=False,
|
need_infra=False,
|
||||||
domaine_ip_start="10.0.0.1",
|
domaine_ip_start="10.0.0.1",
|
||||||
|
@ -343,14 +343,14 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
ipv4="10.0.0.1", ip_type=cls.machines_iptype_1 # Dep machines.IpType
|
ipv4="10.0.0.1", ip_type=cls.machines_iptype_1 # Dep machines.IpType
|
||||||
)
|
)
|
||||||
cls.machines_machinetype_1 = machines.MachineType.objects.create(
|
cls.machines_machinetype_1 = machines.MachineType.objects.create(
|
||||||
type="machines_machinetype_1",
|
name="machines_machinetype_1",
|
||||||
ip_type=cls.machines_iptype_1, # Dep machines.IpType
|
ip_type=cls.machines_iptype_1, # Dep machines.IpType
|
||||||
)
|
)
|
||||||
cls.machines_interface_1 = machines.Interface.objects.create(
|
cls.machines_interface_1 = machines.Interface.objects.create(
|
||||||
ipv4=cls.machines_iplist_1, # Dep machines.IpList
|
ipv4=cls.machines_iplist_1, # Dep machines.IpList
|
||||||
mac_address="00:00:00:00:00:00",
|
mac_address="00:00:00:00:00:00",
|
||||||
machine=cls.machines_machine_1, # Dep machines.Machine
|
machine=cls.machines_machine_1, # Dep machines.Machine
|
||||||
type=cls.machines_machinetype_1, # Dep machines.MachineType
|
machine_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
||||||
details="machines Interface 1",
|
details="machines Interface 1",
|
||||||
# port_lists=[cls.machines_ouvertureportlist_1] # Dep machines.OuverturePortList
|
# port_lists=[cls.machines_ouvertureportlist_1] # Dep machines.OuverturePortList
|
||||||
)
|
)
|
||||||
|
@ -438,8 +438,12 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
name="machines_machine_1",
|
name="machines_machine_1",
|
||||||
active=True,
|
active=True,
|
||||||
)
|
)
|
||||||
|
cls.topologie_dormitory_1 = topologie.Dormitory.objects.create(
|
||||||
|
name="topologie_dormitory_1"
|
||||||
|
)
|
||||||
cls.topologie_building_1 = topologie.Building.objects.create(
|
cls.topologie_building_1 = topologie.Building.objects.create(
|
||||||
name="topologie_building_1"
|
name="topologie_building_1",
|
||||||
|
dormitory=cls.topologie_dormitory_1, # Dep topologie.Dormitory
|
||||||
)
|
)
|
||||||
cls.topologie_switchbay_1 = topologie.SwitchBay.objects.create(
|
cls.topologie_switchbay_1 = topologie.SwitchBay.objects.create(
|
||||||
name="topologie_switchbay_1",
|
name="topologie_switchbay_1",
|
||||||
|
@ -464,29 +468,35 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
switchbay=cls.topologie_switchbay_1, # Dep topologie.SwitchBay
|
switchbay=cls.topologie_switchbay_1, # Dep topologie.SwitchBay
|
||||||
)
|
)
|
||||||
cls.topologie_room_1 = topologie.Room.objects.create(
|
cls.topologie_room_1 = topologie.Room.objects.create(
|
||||||
name="topologie_romm_1", details="topologie Room 1"
|
name="topologie_romm_1", details="topologie Room 1",
|
||||||
|
building=cls.topologie_building_1, # Dep topologie.Building
|
||||||
|
)
|
||||||
|
cls.topologie_port_profile_1 = topologie.PortProfile.objects.create(
|
||||||
|
name="topologie_port_profile_1",
|
||||||
|
profil_default=topologie.PortProfile.PROFIL_DEFAULT[0][0],
|
||||||
|
on_dormitory=cls.topologie_dormitory_1,
|
||||||
|
radius_type="inactive",
|
||||||
|
radius_mode="COMMON",
|
||||||
)
|
)
|
||||||
cls.topologie_port_1 = topologie.Port.objects.create(
|
cls.topologie_port_1 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
port=1,
|
port=1,
|
||||||
room=cls.topologie_room_1, # Dep topologie.Room
|
room=cls.topologie_room_1, # Dep topologie.Room
|
||||||
radius=topologie.Port.STATES[0][0],
|
custom_profile=cls.topologie_port_profile_1,
|
||||||
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
|
||||||
details="topologie_switch_1",
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.topologie_port_2 = topologie.Port.objects.create(
|
cls.topologie_port_2 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
port=2,
|
port=2,
|
||||||
machine_interface=cls.machines_interface_1, # Dep machines.Interface
|
machine_interface=cls.machines_interface_1, # Dep machines.Interface
|
||||||
radius=topologie.Port.STATES[0][0],
|
custom_profile=cls.topologie_port_profile_1,
|
||||||
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
|
||||||
details="topologie_switch_1",
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.topologie_port_3 = topologie.Port.objects.create(
|
cls.topologie_port_3 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
port=3,
|
port=3,
|
||||||
room=cls.topologie_room_1, # Dep topologie.Room
|
room=cls.topologie_room_1, # Dep topologie.Room
|
||||||
radius=topologie.Port.STATES[0][0],
|
custom_profile=cls.topologie_port_profile_1,
|
||||||
# Do not defines related because circular dependency # Dep machines.Vlan
|
# Do not defines related because circular dependency # Dep machines.Vlan
|
||||||
details="topologie_switch_1",
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
|
@ -512,7 +522,6 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
registered=datetime.datetime.now(datetime.timezone.utc),
|
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||||
telephone="0123456789",
|
telephone="0123456789",
|
||||||
uid_number=21103,
|
uid_number=21103,
|
||||||
rezo_rez_uid=21103,
|
|
||||||
)
|
)
|
||||||
# Need merge of MR145 to work
|
# Need merge of MR145 to work
|
||||||
# TODO: Merge !145
|
# TODO: Merge !145
|
||||||
|
@ -661,7 +670,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
|
|
||||||
def assert_more(response, url, format):
|
def assert_more(response, url, format):
|
||||||
"""Assert the response is valid json when format is json"""
|
"""Assert the response is valid json when format is json"""
|
||||||
if format is "json":
|
if format == "json":
|
||||||
json.loads(response.content.decode())
|
json.loads(response.content.decode())
|
||||||
|
|
||||||
self.check_responses_code(
|
self.check_responses_code(
|
||||||
|
@ -749,7 +758,7 @@ class APIPaginationTestCase(APITestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
cls.superuser.delete()
|
cls.superuser.delete()
|
||||||
super(APIPaginationTestCase, self).tearDownClass()
|
super().tearDownClass()
|
||||||
|
|
||||||
def test_pagination(self):
|
def test_pagination(self):
|
||||||
"""Tests that every endpoint is using the pagination correctly.
|
"""Tests that every endpoint is using the pagination correctly.
|
||||||
|
|
|
@ -100,34 +100,6 @@ class VenteModelTests(TestCase):
|
||||||
self.assertEqual(end_memb.month, expected_end.month)
|
self.assertEqual(end_memb.month, expected_end.month)
|
||||||
self.assertEqual(end_memb.year, expected_end.year)
|
self.assertEqual(end_memb.year, expected_end.year)
|
||||||
|
|
||||||
def test_date_start_cotisation(self):
|
|
||||||
"""
|
|
||||||
It should be possible to add a cotisation with a specific start date
|
|
||||||
"""
|
|
||||||
v = Vente(
|
|
||||||
facture=self.f,
|
|
||||||
number=1,
|
|
||||||
name="Test purchase",
|
|
||||||
duration_connection=0,
|
|
||||||
duration_days_connection=1,
|
|
||||||
duration_membership=0,
|
|
||||||
duration_deys_membership=1,
|
|
||||||
prix=0,
|
|
||||||
)
|
|
||||||
v.create_cotis(
|
|
||||||
date_start_con=timezone.make_aware(datetime.datetime(1998, 10, 16)),
|
|
||||||
date_start_memb=timezone.make_aware(datetime.datetime(1998, 10, 16)),
|
|
||||||
)
|
|
||||||
v.save()
|
|
||||||
self.assertEqual(
|
|
||||||
v.cotisation.date_end_con,
|
|
||||||
timezone.make_aware(datetime.datetime(1998, 10, 17)),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
v.cotisation.date_end_memb,
|
|
||||||
timezone.make_aware(datetime.datetime(1998, 10, 17)),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_one_day_cotisation_membership_only(self):
|
def test_one_day_cotisation_membership_only(self):
|
||||||
"""
|
"""
|
||||||
It should be possible to have one day membership without connection.
|
It should be possible to have one day membership without connection.
|
||||||
|
@ -145,9 +117,10 @@ class VenteModelTests(TestCase):
|
||||||
prix=0,
|
prix=0,
|
||||||
)
|
)
|
||||||
self.f.reorder_purchases()
|
self.f.reorder_purchases()
|
||||||
self.assertEqual(
|
self.assertAlmostEqual(
|
||||||
self.user.end_connexion(),
|
self.user.end_connexion(),
|
||||||
None,
|
date,
|
||||||
|
delta=datetime.timedelta(seconds=1),
|
||||||
)
|
)
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
self.user.end_adhesion() - date,
|
self.user.end_adhesion() - date,
|
||||||
|
@ -175,7 +148,11 @@ class VenteModelTests(TestCase):
|
||||||
end_con = self.user.end_connexion()
|
end_con = self.user.end_connexion()
|
||||||
end_memb = self.user.end_adhesion()
|
end_memb = self.user.end_adhesion()
|
||||||
expected_end = date + relativedelta(months=1)
|
expected_end = date + relativedelta(months=1)
|
||||||
self.assertEqual(end_con, None)
|
self.assertAlmostEqual(
|
||||||
|
end_con,
|
||||||
|
date,
|
||||||
|
delta=datetime.timedelta(seconds=1),
|
||||||
|
)
|
||||||
self.assertEqual(end_memb.day, expected_end.day)
|
self.assertEqual(end_memb.day, expected_end.day)
|
||||||
self.assertEqual(end_memb.month, expected_end.month)
|
self.assertEqual(end_memb.month, expected_end.month)
|
||||||
self.assertEqual(end_memb.year, expected_end.year)
|
self.assertEqual(end_memb.year, expected_end.year)
|
||||||
|
@ -200,39 +177,15 @@ class VenteModelTests(TestCase):
|
||||||
end_con = self.user.end_connexion()
|
end_con = self.user.end_connexion()
|
||||||
end_memb = self.user.end_adhesion()
|
end_memb = self.user.end_adhesion()
|
||||||
expected_end = date + relativedelta(months=1, days=7)
|
expected_end = date + relativedelta(months=1, days=7)
|
||||||
self.assertEqual(end_con, None)
|
self.assertAlmostEqual(
|
||||||
|
end_con,
|
||||||
|
date,
|
||||||
|
delta=datetime.timedelta(seconds=1),
|
||||||
|
)
|
||||||
self.assertEqual(end_memb.day, expected_end.day)
|
self.assertEqual(end_memb.day, expected_end.day)
|
||||||
self.assertEqual(end_memb.month, expected_end.month)
|
self.assertEqual(end_memb.month, expected_end.month)
|
||||||
self.assertEqual(end_memb.year, expected_end.year)
|
self.assertEqual(end_memb.year, expected_end.year)
|
||||||
|
|
||||||
def test_date_start_cotisation_membership_only(self):
|
|
||||||
"""
|
|
||||||
It should be possible to add a cotisation with a specific start date
|
|
||||||
"""
|
|
||||||
v = Vente(
|
|
||||||
facture=self.f,
|
|
||||||
number=1,
|
|
||||||
name="Test purchase",
|
|
||||||
duration_connection=0,
|
|
||||||
duration_days_connection=0,
|
|
||||||
duration_membership=0,
|
|
||||||
duration_days_membership=1,
|
|
||||||
prix=0,
|
|
||||||
)
|
|
||||||
v.create_cotis(
|
|
||||||
date_start_con=timezone.make_aware(datetime.datetime(1998, 10, 16)),
|
|
||||||
date_start_memb=timezone.make_aware(datetime.datetime(1998, 10, 16)),
|
|
||||||
)
|
|
||||||
v.save()
|
|
||||||
self.assertEqual(
|
|
||||||
v.cotisation.date_end_con,
|
|
||||||
timezone.make_aware(datetime.datetime(1998, 10, 17)),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
v.cotisation.date_end_memb,
|
|
||||||
timezone.make_aware(datetime.datetime(1998, 10, 16)),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_cotisation_membership_diff_connection(self):
|
def test_cotisation_membership_diff_connection(self):
|
||||||
"""
|
"""
|
||||||
It should be possible to have purchase a membership longer
|
It should be possible to have purchase a membership longer
|
||||||
|
|
|
@ -12,31 +12,10 @@ from .models import Article, Cotisation, Facture, Paiement, Vente
|
||||||
|
|
||||||
|
|
||||||
class NewFactureTests(TestCase):
|
class NewFactureTests(TestCase):
|
||||||
def tearDown(self):
|
@classmethod
|
||||||
self.user.facture_set.all().delete()
|
def setUpTestData(cls):
|
||||||
self.user.delete()
|
cls.paiement = Paiement.objects.create(moyen="test payment")
|
||||||
self.paiement.delete()
|
cls.article_one_day = Article.objects.create(
|
||||||
self.article_one_day.delete()
|
|
||||||
self.article_one_month.delete()
|
|
||||||
self.article_one_month_and_one_week.delete()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.user = Adherent.objects.create(pseudo="testUser", email="test@example.org")
|
|
||||||
self.user.set_password("plopiplop")
|
|
||||||
self.user.user_permissions.set(
|
|
||||||
[
|
|
||||||
Permission.objects.get_by_natural_key(
|
|
||||||
"add_facture", "cotisations", "Facture"
|
|
||||||
),
|
|
||||||
Permission.objects.get_by_natural_key(
|
|
||||||
"use_every_payment", "cotisations", "Paiement"
|
|
||||||
),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
self.user.save()
|
|
||||||
|
|
||||||
self.paiement = Paiement.objects.create(moyen="test payment")
|
|
||||||
self.article_one_day = Article.objects.create(
|
|
||||||
name="One day",
|
name="One day",
|
||||||
prix=0,
|
prix=0,
|
||||||
duration_connection=0,
|
duration_connection=0,
|
||||||
|
@ -45,7 +24,7 @@ class NewFactureTests(TestCase):
|
||||||
duration_days_membership=1,
|
duration_days_membership=1,
|
||||||
available_for_everyone=True,
|
available_for_everyone=True,
|
||||||
)
|
)
|
||||||
self.article_one_month = Article.objects.create(
|
cls.article_one_month = Article.objects.create(
|
||||||
name="One mounth",
|
name="One mounth",
|
||||||
prix=0,
|
prix=0,
|
||||||
duration_connection=1,
|
duration_connection=1,
|
||||||
|
@ -54,7 +33,7 @@ class NewFactureTests(TestCase):
|
||||||
duration_days_membership=0,
|
duration_days_membership=0,
|
||||||
available_for_everyone=True,
|
available_for_everyone=True,
|
||||||
)
|
)
|
||||||
self.article_one_month_and_one_week = Article.objects.create(
|
cls.article_one_month_and_one_week = Article.objects.create(
|
||||||
name="One mounth and one week",
|
name="One mounth and one week",
|
||||||
prix=0,
|
prix=0,
|
||||||
duration_connection=1,
|
duration_connection=1,
|
||||||
|
@ -63,6 +42,26 @@ class NewFactureTests(TestCase):
|
||||||
duration_days_membership=7,
|
duration_days_membership=7,
|
||||||
available_for_everyone=True,
|
available_for_everyone=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.user.facture_set.all().delete()
|
||||||
|
self.user.delete()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.user = Adherent.objects.create(pseudo="testUser", email="test@example.org")
|
||||||
|
self.user.set_password("plopiplop")
|
||||||
|
self.user.user_permissions.set(
|
||||||
|
[
|
||||||
|
Permission.objects.get_by_natural_key(
|
||||||
|
"add_facture", "cotisations", "facture"
|
||||||
|
),
|
||||||
|
Permission.objects.get_by_natural_key(
|
||||||
|
"use_every_payment", "cotisations", "paiement"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.user.save()
|
||||||
self.client.login(username="testUser", password="plopiplop")
|
self.client.login(username="testUser", password="plopiplop")
|
||||||
|
|
||||||
def test_invoice_with_one_day(self):
|
def test_invoice_with_one_day(self):
|
||||||
|
@ -72,7 +71,7 @@ class NewFactureTests(TestCase):
|
||||||
"form-INITIAL_FORMS": 0,
|
"form-INITIAL_FORMS": 0,
|
||||||
"form-MIN_NUM_FORMS": 0,
|
"form-MIN_NUM_FORMS": 0,
|
||||||
"form-MAX_NUM_FORMS": 1000,
|
"form-MAX_NUM_FORMS": 1000,
|
||||||
"form-0-article": 1,
|
"form-0-article": self.article_one_day.pk,
|
||||||
"form-0-quantity": 1,
|
"form-0-quantity": 1,
|
||||||
}
|
}
|
||||||
date = timezone.now()
|
date = timezone.now()
|
||||||
|
@ -94,7 +93,7 @@ class NewFactureTests(TestCase):
|
||||||
"form-INITIAL_FORMS": 0,
|
"form-INITIAL_FORMS": 0,
|
||||||
"form-MIN_NUM_FORMS": 0,
|
"form-MIN_NUM_FORMS": 0,
|
||||||
"form-MAX_NUM_FORMS": 1000,
|
"form-MAX_NUM_FORMS": 1000,
|
||||||
"form-0-article": 2,
|
"form-0-article": self.article_one_month.pk,
|
||||||
"form-0-quantity": 1,
|
"form-0-quantity": 1,
|
||||||
}
|
}
|
||||||
date = timezone.now()
|
date = timezone.now()
|
||||||
|
@ -114,9 +113,9 @@ class NewFactureTests(TestCase):
|
||||||
"form-INITIAL_FORMS": 0,
|
"form-INITIAL_FORMS": 0,
|
||||||
"form-MIN_NUM_FORMS": 0,
|
"form-MIN_NUM_FORMS": 0,
|
||||||
"form-MAX_NUM_FORMS": 1000,
|
"form-MAX_NUM_FORMS": 1000,
|
||||||
"form-0-article": 1,
|
"form-0-article": self.article_one_day.pk,
|
||||||
"form-0-quantity": 7,
|
"form-0-quantity": 7,
|
||||||
"form-1-article": 2,
|
"form-1-article": self.article_one_month.pk,
|
||||||
"form-1-quantity": 1,
|
"form-1-quantity": 1,
|
||||||
}
|
}
|
||||||
date = timezone.now()
|
date = timezone.now()
|
||||||
|
@ -137,13 +136,15 @@ class NewFactureTests(TestCase):
|
||||||
"form-INITIAL_FORMS": 0,
|
"form-INITIAL_FORMS": 0,
|
||||||
"form-MIN_NUM_FORMS": 0,
|
"form-MIN_NUM_FORMS": 0,
|
||||||
"form-MAX_NUM_FORMS": 1000,
|
"form-MAX_NUM_FORMS": 1000,
|
||||||
"form-0-article": 2,
|
"form-0-article": self.article_one_month.pk,
|
||||||
"form-0-quantity": 1,
|
"form-0-quantity": 1,
|
||||||
"form-1-article": 2,
|
"form-1-article": self.article_one_month.pk,
|
||||||
"form-1-quantity": 1,
|
"form-1-quantity": 1,
|
||||||
}
|
}
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||||
)
|
)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response.url, "/users/profil/%d" % self.user.pk)
|
||||||
f = self.user.facture_set.first()
|
f = self.user.facture_set.first()
|
||||||
self.assertEqual(f.vente_set.count(), 2)
|
self.assertEqual(f.vente_set.count(), 2)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2024 Caroline Canebier
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from os.path import dirname, abspath
|
||||||
|
from django.conf import settings as django_settings
|
||||||
|
|
||||||
|
def load_tests(loader, tests, pattern):
|
||||||
|
"""
|
||||||
|
As this is an optionnal app, loads its tests only if it is installed.
|
||||||
|
"""
|
||||||
|
if "api" in django_settings.INSTALLED_APPS:
|
||||||
|
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
|
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2024 Caroline Canebier
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from os.path import dirname, abspath
|
||||||
|
from django.conf import settings as django_settings
|
||||||
|
|
||||||
|
def load_tests(loader, tests, pattern):
|
||||||
|
"""
|
||||||
|
As this is an optional app, load its tests only if it is installed.
|
||||||
|
"""
|
||||||
|
if "ldap_sync" in django_settings.INSTALLED_APPS:
|
||||||
|
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
|
|
@ -1,3 +1,101 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Lara Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
"""users.tests
|
||||||
|
The tests for the Users module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import volatildap
|
||||||
|
from django.conf import settings
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
# Create your tests here.
|
from . import models
|
||||||
|
|
||||||
|
class LdapEnabledTestCase(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.ldap = volatildap.LdapServer(
|
||||||
|
# Load some initial data
|
||||||
|
initial={'ou=people': {
|
||||||
|
'ou': ['people'],
|
||||||
|
'objectClass': ['organizationalUnit'],
|
||||||
|
}},
|
||||||
|
# Enable more LDAP schemas
|
||||||
|
schemas=['core.schema', 'cosine.schema', 'inetorgperson.schema', 'nis.schema'],
|
||||||
|
)
|
||||||
|
# The volatildap server uses specific defaults, and listens on an arbitrary port.
|
||||||
|
# Copy the server-side values to Django settings
|
||||||
|
settings.DATABASES['ldap']['USER'] = cls.ldap.rootdn
|
||||||
|
settings.DATABASES['ldap']['PASSWORD'] = cls.ldap.rootpw
|
||||||
|
settings.DATABASES['ldap']['NAME'] = cls.ldap.uri
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
# Starting an already-started volatildap server performs a data reset
|
||||||
|
self.ldap.start()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
# Free up resources on teardown.
|
||||||
|
cls.ldap.stop()
|
||||||
|
super().tearDownClass()
|
||||||
|
|
||||||
|
class LdapUserTestCase(TestCase):
|
||||||
|
def test_create_ldap_user(self):
|
||||||
|
g = models.LdapUser.objects.create(
|
||||||
|
gid="500",
|
||||||
|
name="users_test_ldapuser",
|
||||||
|
uid="users_test_ldapuser",
|
||||||
|
uidNumber="21001",
|
||||||
|
sn="users_test_ldapuser",
|
||||||
|
login_shell="/bin/false",
|
||||||
|
mail="user@example.net",
|
||||||
|
given_name="users_test_ldapuser",
|
||||||
|
home_directory="/home/moamoak",
|
||||||
|
display_name="users_test_ldapuser",
|
||||||
|
dialupAccess="False",
|
||||||
|
sambaSID="21001",
|
||||||
|
user_password="{SSHA}aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
|
||||||
|
sambat_nt_password="0123456789ABCDEF0123456789ABCDEF",
|
||||||
|
macs=[],
|
||||||
|
shadowexpire="0",
|
||||||
|
)
|
||||||
|
self.assertEqual(g.name, "users_test_ldapuser")
|
||||||
|
|
||||||
|
|
||||||
|
class LdapUserGroupTestCase(TestCase):
|
||||||
|
def test_create_ldap_user_group(self):
|
||||||
|
g = models.LdapUserGroup.objects.create(
|
||||||
|
gid="501", members=[], name="users_test_ldapusergroup"
|
||||||
|
)
|
||||||
|
self.assertEqual(g.name, "users_test_ldapusergroup")
|
||||||
|
|
||||||
|
|
||||||
|
class LdapServiceUserTestCase(TestCase):
|
||||||
|
def test_create_ldap_service_user(self):
|
||||||
|
g = models.LdapServiceUser.objects.create(
|
||||||
|
name="users_test_ldapserviceuser",
|
||||||
|
user_password="{SSHA}AbCdEfGhIjKlMnOpQrStUvWxYz987654",
|
||||||
|
)
|
||||||
|
self.assertEqual(g.name, "users_test_ldapserviceuser")
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2024 Caroline Canebier
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from os.path import dirname, abspath
|
||||||
|
from django.conf import settings as django_settings
|
||||||
|
|
||||||
|
def load_tests(loader, tests, pattern):
|
||||||
|
"""
|
||||||
|
As this is an optional app, load its tests only if it is installed.
|
||||||
|
"""
|
||||||
|
if "api" in django_settings.INSTALLED_APPS:
|
||||||
|
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
|
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2024 Caroline Canebier
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from os.path import dirname, abspath
|
||||||
|
from django.conf import settings as django_settings
|
||||||
|
|
||||||
|
def load_tests(loader, tests, pattern):
|
||||||
|
"""
|
||||||
|
As this is an optional app, load its tests only if it is installed.
|
||||||
|
"""
|
||||||
|
if "api" in django_settings.INSTALLED_APPS:
|
||||||
|
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
|
|
@ -23,20 +23,23 @@ class UserModelTests(TestCase):
|
||||||
facture=invoice,
|
facture=invoice,
|
||||||
number=1,
|
number=1,
|
||||||
name="Test purchase",
|
name="Test purchase",
|
||||||
duration=0,
|
duration_days_membership=1,
|
||||||
duration_days=1,
|
duration_membership=0,
|
||||||
type_cotisation="All",
|
duration_days_connection=1,
|
||||||
|
duration_connection=0,
|
||||||
prix=0,
|
prix=0,
|
||||||
)
|
)
|
||||||
purchase2 = Vente.objects.create(
|
purchase2 = Vente.objects.create(
|
||||||
facture=invoice,
|
facture=invoice,
|
||||||
number=1,
|
number=1,
|
||||||
name="Test purchase",
|
name="Test purchase",
|
||||||
duration=0,
|
duration_days_membership=1,
|
||||||
duration_days=1,
|
duration_membership=0,
|
||||||
type_cotisation="All",
|
duration_days_connection=1,
|
||||||
|
duration_connection=0,
|
||||||
prix=0,
|
prix=0,
|
||||||
)
|
)
|
||||||
|
invoice.reorder_purchases()
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
self.user.end_connexion() - date,
|
self.user.end_connexion() - date,
|
||||||
datetime.timedelta(days=2),
|
datetime.timedelta(days=2),
|
||||||
|
|
|
@ -42,43 +42,3 @@ class ListShellTestCase(TestCase):
|
||||||
def test_shell_are_created(self):
|
def test_shell_are_created(self):
|
||||||
s = models.ListShell.objects.create(shell="/bin/zsh")
|
s = models.ListShell.objects.create(shell="/bin/zsh")
|
||||||
self.assertEqual(s.shell, "/bin/zsh")
|
self.assertEqual(s.shell, "/bin/zsh")
|
||||||
|
|
||||||
|
|
||||||
class LdapUserTestCase(TestCase):
|
|
||||||
def test_create_ldap_user(self):
|
|
||||||
g = models.LdapUser.objects.create(
|
|
||||||
gid="500",
|
|
||||||
name="users_test_ldapuser",
|
|
||||||
uid="users_test_ldapuser",
|
|
||||||
uidNumber="21001",
|
|
||||||
sn="users_test_ldapuser",
|
|
||||||
login_shell="/bin/false",
|
|
||||||
mail="user@example.net",
|
|
||||||
given_name="users_test_ldapuser",
|
|
||||||
home_directory="/home/moamoak",
|
|
||||||
display_name="users_test_ldapuser",
|
|
||||||
dialupAccess="False",
|
|
||||||
sambaSID="21001",
|
|
||||||
user_password="{SSHA}aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
|
|
||||||
sambat_nt_password="0123456789ABCDEF0123456789ABCDEF",
|
|
||||||
macs=[],
|
|
||||||
shadowexpire="0",
|
|
||||||
)
|
|
||||||
self.assertEqual(g.name, "users_test_ldapuser")
|
|
||||||
|
|
||||||
|
|
||||||
class LdapUserGroupTestCase(TestCase):
|
|
||||||
def test_create_ldap_user_group(self):
|
|
||||||
g = models.LdapUserGroup.objects.create(
|
|
||||||
gid="501", members=[], name="users_test_ldapusergroup"
|
|
||||||
)
|
|
||||||
self.assertEqual(g.name, "users_test_ldapusergroup")
|
|
||||||
|
|
||||||
|
|
||||||
class LdapServiceUserTestCase(TestCase):
|
|
||||||
def test_create_ldap_service_user(self):
|
|
||||||
g = models.LdapServiceUser.objects.create(
|
|
||||||
name="users_test_ldapserviceuser",
|
|
||||||
user_password="{SSHA}AbCdEfGhIjKlMnOpQrStUvWxYz987654",
|
|
||||||
)
|
|
||||||
self.assertEqual(g.name, "users_test_ldapserviceuser")
|
|
||||||
|
|
Loading…
Reference in a new issue