205 lines
9.2 KiB
Python
205 lines
9.2 KiB
Python
import os.path
|
||
import subprocess
|
||
import tempfile
|
||
|
||
from datetime import date, timedelta
|
||
from pathlib import Path
|
||
|
||
from django.conf import settings
|
||
from django.contrib.auth.models import Group, Permission
|
||
from django.core.files import File
|
||
from django.test import TestCase, override_settings
|
||
from django.urls import reverse
|
||
from django.utils.text import slugify
|
||
|
||
from aemo.models import (
|
||
Bilan, Document, Famille, LibellePrestation, Personne, Role, Prestation,
|
||
Rapport, Utilisateur
|
||
)
|
||
from aemo.tests import InitialDataMixin, TempMediaRootMixin
|
||
from aemo.utils import format_d_m_Y
|
||
from ..models import Archive
|
||
|
||
public_key_path = os.path.join(settings.BASE_DIR, 'archive/tests/crne_rsa.pub')
|
||
|
||
|
||
@override_settings(CRNE_RSA_PUBLIC_KEY=public_key_path)
|
||
class ArchiveTests(InitialDataMixin, TempMediaRootMixin, TestCase):
|
||
|
||
def setUp(self) -> None:
|
||
self.user = Utilisateur.objects.create_user('user', 'user@example.org', sigle='XX')
|
||
self.create_kwargs = {
|
||
'nom': 'John Doe',
|
||
'unite': 'aemo',
|
||
'date_debut': date(2021, 1, 1),
|
||
'date_fin': date(2021, 12, 31),
|
||
'motif_fin': 'Autre',
|
||
'key': '',
|
||
'pdf': 'encrypted_data'
|
||
}
|
||
|
||
def _create_archive(self):
|
||
fam = Famille.objects.create_famille(nom='Haddock', equipe='aemo')
|
||
fam.suivi.date_fin_suivi = date(2019, 1, 1)
|
||
fam.suivi.motif_fin_suivi = 'autres'
|
||
fam.suivi.save()
|
||
for idx, doc_name in enumerate(['sample.docx', 'sample.doc', 'sample.pdf', 'sample.msg']):
|
||
doc = Document(famille=fam, titre=f"Test {idx}")
|
||
with (Path(__file__).parent / doc_name).open(mode='rb') as fh:
|
||
doc.fichier = File(fh, name=doc_name)
|
||
doc.save()
|
||
|
||
self.user.user_permissions.add(Permission.objects.get(codename='can_archive'))
|
||
self.client.force_login(self.user)
|
||
self.client.post(reverse('archive-add', args=['aemo', fam.pk]))
|
||
return Archive.objects.get(nom='Haddock', unite='aemo')
|
||
|
||
def test_model_creation(self):
|
||
arch = Archive.objects.create(**self.create_kwargs)
|
||
self.assertEqual(arch.nom, 'John Doe')
|
||
self.assertEqual(arch.unite, 'aemo')
|
||
self.assertEqual(arch.date_debut, date(2021, 1, 1))
|
||
self.assertEqual(arch.date_fin, date(2021, 12, 31))
|
||
self.assertEqual(arch.pdf, 'encrypted_data')
|
||
|
||
def test_sans_permission_d_archiver(self):
|
||
fam = Famille.objects.create_famille(nom='Haddock', equipe='aemo')
|
||
fam.suivi.date_fin_suivi = date(2019, 1, 1)
|
||
fam.suivi.motif_fin_suivi = 'autre'
|
||
fam.suivi.save()
|
||
self.assertEqual(fam.can_be_archived(self.user), False)
|
||
|
||
def test_avec_permission_d_archiver(self):
|
||
fam = Famille.objects.create_famille(nom='Haddock', equipe='aemo')
|
||
fam.suivi.date_fin_suivi = date(2019, 1, 1)
|
||
fam.suivi.motif_fin_suivi = 'autre'
|
||
fam.suivi.save()
|
||
self.user.user_permissions.add(Permission.objects.get(codename='can_archive'))
|
||
self.assertEqual(fam.can_be_archived(self.user), True)
|
||
|
||
def test_archivage_aemo(self):
|
||
famille = Famille.objects.create_famille(
|
||
nom='Doe', equipe='aemo', rue="Rue du lac", npa='2000', localite='Paris', telephone='012 345 67 89')
|
||
famille.suivi.date_fin_suivi = date.today() - timedelta(days=700)
|
||
famille.suivi.motif_fin_suivi = 'autre'
|
||
famille.suivi.save()
|
||
file_paths = []
|
||
for idx, doc_name in enumerate(['sample.docx', 'sample.doc', 'sample.pdf', 'sample.msg', 'sample-2.msg']):
|
||
doc = Document(famille=famille, titre=f"Test {idx}")
|
||
with (Path(__file__).parent / doc_name).open(mode='rb') as fh:
|
||
doc.fichier = File(fh, name=doc_name)
|
||
doc.save()
|
||
file_paths.append(doc.fichier.path)
|
||
Personne.objects.create_personne(
|
||
famille=famille, prenom='Archibald', nom='Doe', role=Role.objects.get(nom='Père')
|
||
)
|
||
enfant = Personne.objects.create_personne(
|
||
famille=famille, prenom='Gaston', nom='Doe', date_naissance=date.today() - timedelta(days=720),
|
||
role=Role.objects.get(nom='Enfant suivi')
|
||
)
|
||
enfant.formation.creche = 'Les Schtroumpfs'
|
||
enfant.formation.save()
|
||
Bilan.objects.create(famille=famille, date=date.today())
|
||
Rapport.objects.create(famille=famille, date=date.today(), auteur=self.user)
|
||
prest = Prestation.objects.create(
|
||
famille=famille, auteur=self.user, date_prestation=date.today(), duree=timedelta(hours=2),
|
||
lib_prestation=LibellePrestation.objects.first())
|
||
prest.intervenants.add(self.user, through_defaults={'role': Role.objects.get(nom='Référent')})
|
||
with (Path(__file__).parent / 'sample.pdf').open(mode='rb') as fh:
|
||
prest.fichier = File(fh, name=doc_name)
|
||
prest.save()
|
||
file_paths.append(prest.fichier.path)
|
||
|
||
grp = Group.objects.get(name='aemo')
|
||
self.user.groups.add(grp)
|
||
self.user.user_permissions.add(
|
||
*list(Permission.objects.filter(codename__in=['view_famille', 'change_famille', 'can_archive']))
|
||
)
|
||
self.assertTrue(famille.can_be_archived(self.user))
|
||
self.client.force_login(self.user)
|
||
response = self.client.post(reverse('archive-add', args=['aemo', famille.pk]))
|
||
self.assertRedirects(response, reverse('suivis-termines'))
|
||
|
||
famille.refresh_from_db()
|
||
self.assertNotEqual(famille.nom, 'Doe')
|
||
self.assertEqual(len(famille.nom), 10)
|
||
self.assertEqual(famille.rue, '')
|
||
self.assertEqual(famille.npa, '2000')
|
||
self.assertEqual(famille.localite, 'Paris'),
|
||
self.assertEqual(famille.telephone, '')
|
||
self.assertEqual(famille.parents(), [])
|
||
|
||
enfant.refresh_from_db()
|
||
self.assertNotEqual(enfant.nom, 'Doe')
|
||
self.assertEqual(len(famille.nom), 10)
|
||
self.assertNotEqual(enfant.prenom, 'Gaston')
|
||
self.assertEqual(len(famille.nom), 10)
|
||
self.assertEqual(enfant.formation.creche, '')
|
||
|
||
self.assertEqual(famille.documents.count(), 0)
|
||
self.assertEqual(famille.bilans.count(), 0)
|
||
self.assertEqual(famille.rapports.count(), 0)
|
||
for prest in famille.prestations.all():
|
||
self.assertEqual(prest.texte, '')
|
||
self.assertEqual(prest.duree, timedelta(hours=2))
|
||
self.assertEqual(bool(prest.fichier), False)
|
||
|
||
for path in file_paths:
|
||
self.assertFalse(Path(path).exists())
|
||
|
||
arch = Archive.objects.get(nom='Doe', unite='aemo')
|
||
self.assertTrue(os.path.exists(arch.pdf.path))
|
||
self.assertIn(f"aemo/doe-{famille.pk}", arch.pdf.name)
|
||
self.assertTrue(famille.prestations.exists())
|
||
|
||
# Cannot be archived a second time:
|
||
response = self.client.post(reverse('archive-add', args=['aemo', famille.pk]))
|
||
self.assertEqual(response.status_code, 404)
|
||
|
||
def test_decryptage_access(self):
|
||
arch = self._create_archive()
|
||
private_key = os.path.join(settings.BASE_DIR, 'archive/tests/crne_rsa')
|
||
anonymous = Utilisateur.objects.create_user('anonymous', email='anonymous@example.org')
|
||
self.client.force_login(anonymous)
|
||
with open(private_key, 'rb') as f:
|
||
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': f})
|
||
self.assertEqual(response.status_code, 403)
|
||
|
||
anonymous.user_permissions.add(Permission.objects.get(codename='can_archive'))
|
||
self.client.force_login(anonymous)
|
||
with open(private_key, 'rb') as f:
|
||
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': f})
|
||
self.assertEqual(response.status_code, 200)
|
||
|
||
def test_decryptage_aemo(self):
|
||
arch = self._create_archive()
|
||
private_key = os.path.join(settings.BASE_DIR, 'archive/tests/crne_rsa')
|
||
|
||
self.client.force_login(self.user)
|
||
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': ''})
|
||
self.assertEqual(response.context['form'].errors, {'file': ['Ce champ est obligatoire.']})
|
||
|
||
with open(private_key, 'rb') as f:
|
||
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': f})
|
||
self.assertEqual(
|
||
response.get('Content-Disposition'),
|
||
f"attachment; filename={slugify(arch.nom)}.pdf"
|
||
)
|
||
|
||
with tempfile.NamedTemporaryFile(delete=True, mode='wb') as fh:
|
||
fh.write(response.content)
|
||
subprocess.run(['pdftotext', fh.name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||
with open(f'{fh.name}.txt', 'r') as f:
|
||
content = f.read()
|
||
|
||
self.assertIn('Historique', content)
|
||
self.assertIn('Fin du suivi le :\n\n01.01.2019', content)
|
||
self.assertIn('Motif de fin de suivi :\n\nAutres', content)
|
||
self.assertIn(f"Date d'archivage :\n\n{format_d_m_Y(date.today())}", content)
|
||
self.assertIn('Famille Haddock', content)
|
||
self.assertIn('Informations', content)
|
||
self.assertIn("Fichier docx d’exemple", content)
|
||
self.assertIn("Exemple de fichier doc", content)
|
||
self.assertIn("Fichier pdf d’exemple", content)
|
||
self.assertIn("Kind regards", content)
|