barbacompta/tests/test_admin.py

168 lines
7.3 KiB
Python

# barbacompta - invoicing for dummies
# Copyright (C) 2022 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import io
import pypdf
import pytest
from django.contrib.auth import get_user_model
from webtest import Upload
from eo_gestion.eo_facture.models import Client, Contrat
from eo_gestion.eo_redmine.models import Project
User = get_user_model()
# https://stackoverflow.com/questions/2438800/what-is-the-smallest-legal-zip-jar-file
MINIMAL_ZIP_FILE = b'PK\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
class TestLoggedIn:
@pytest.fixture
def app(self, app):
# login
response = app.get('/').follow()
response.form['username'] = 'admin'
response.form['password'] = 'admin'
response.form.submit()
return app
def test_contrat_recurrent_no_debut(self, app):
response = app.get('/eo_facture/contrat/add/')
response.form['client'].force_value('1')
response.form['intitule'] = 'Contrat 1'
response.form['periodicite'] = 'annuelle'
response = response.form.submit('_continue')
assert len(response.pyquery('.errorlist'))
def test_contrat_recurrent_debut_changed(self, app):
response = app.get('/eo_facture/contrat/add/')
response.form['client'].force_value('1')
response.form['intitule'] = 'Contrat 1'
response.form['periodicite'] = 'annuelle'
response.form['periodicite_debut'] = '2018-12-01'
response = response.form.submit('_continue').follow()
response.forms['contrat_form']['periodicite_debut'] = '2018-12-02'
response = response.forms['contrat_form'].submit('_continue').follow()
# Créer la facture de première échéance
response = app.get('/')
assert 'facturer-echeance' in response.form.action
response = response.form.submit().follow()
def test_avoir_sur_contrat_recurrent(self, app):
response = app.get('/eo_facture/contrat/add/')
response.form['client'].force_value('1')
response.form['intitule'] = 'Contrat 1'
response.form['periodicite'] = 'annuelle'
response.form['periodicite_debut'] = '2018-12-01'
response = response.form.submit('_continue').follow()
# Créer la facture de première échéance
response = app.get('/')
assert 'facturer-echeance' in response.form.action
response = response.form.submit().follow()
response.form['lignes-0-intitule'] = 'Bricole 1'
response.form['lignes-0-prix_unitaire_ht'] = '200'
response = response.form.submit('_continue').follow()
assert response.html.find('label', {'for': 'id_numero_d_echeance'})
contrat = Contrat.objects.get(intitule='Contrat 1')
facture = contrat.factures.get()
assert facture.lignes.get().intitule == 'Bricole 1'
# Créer un avoir sur la première échéance
assert '/eo_facture/facture/%s/cancel/' % facture.id in response.text
response = app.get('/eo_facture/facture/%s/cancel/' % facture.id).follow()
assert not response.html.find('label', {'for': 'id_numero_d_echeance'})
response = response.form.submit('_save').follow()
assert contrat.factures.count() == 2
facture_avoir = facture.factures_avoir.get()
assert facture_avoir.intitule == 'AVOIR POUR LA FACTURE Contrat 1 du 01/12/2018 au 01/12/2019'
class TestFiltreClient:
@pytest.fixture(autouse=True)
def projects(self, db):
admin = User.objects.get(username='admin')
bd = User.objects.get(username='bdauvergne')
client1, client2 = Client.objects.all()[:2]
Project.objects.create(
name='projet 1',
client=client1,
).cpfs.set([admin, bd])
Project.objects.create(
name='projet 2',
client=client2,
).cpfs.set([admin, bd])
def test_mes_clients(self, app):
response = app.get('/eo_facture/client/')
assert response.pyquery('li.selected [title="mes clients"]')
assert len(response.pyquery('tbody tr')) == 2
Project.objects.all().delete()
response = app.get('/eo_facture/client/')
assert response.pyquery('li.selected [title="tous"]')
assert len(response.pyquery('tbody tr')) > 2
def test_derniere_facture(self, app):
response = app.get('/eo_facture/client/')
assert len(response.pyquery('tbody tr')) == 2
response = response.click('plus de 12 mois')
assert len(response.pyquery('tbody tr')) == 1
def test_facture_avec_piece_jointe_facturx(self, app):
response = app.get('/eo_facture/contrat/add/')
response.form['client'].force_value('1')
response.form['intitule'] = 'Contrat 1'
response = response.form.submit('_continue').follow()
response = response.click('Ajouter une facture', index=0)
response.form.set('proforma', False)
response.form.set('pieces_jointes-0-nom', 'x' * 50 + '.zip')
response.form.set('pieces_jointes-0-fichier', Upload('pj1.zip', MINIMAL_ZIP_FILE, 'application/zip'))
response.form.set('pieces_jointes-1-nom', 'pj2')
response.form.set('pieces_jointes-1-fichier', Upload('pj2.zip', MINIMAL_ZIP_FILE, 'application/zip'))
response = response.form.submit('_continue', status=200)
assert [
[et.text() for et in e.find('li').items()] for e in response.pyquery('.errorlist').items()
] == [
['Assurez-vous que cette valeur comporte au plus 50 caractères (actuellement 54).'],
[
'Le nom de la pièce jointe doit avoir une extension parmi .BMP, .GIF, .FAX, .ODT, .PPT, .TIFF, .XLS, .BZ2, .GZ, .JPEG, .P7S, .RTF, .TXT, .XML, .CSV, .GZIP, .JPG, .PDF, .SVG, .XHTML, .XLSX, .DOC, .HTM, .ODP, .PNG, .TGZ, .XLC, .ZIP, .DOCX, .HTML, .ODS, .PPS, .TIF, .XLM, .PPTX'
],
['Saisissez une valeur valide.'],
]
response.form.set('pieces_jointes-0-nom', 'pj1.zip')
response.form.set('pieces_jointes-0-fichier', Upload('pj1.zip', MINIMAL_ZIP_FILE, 'application/zip'))
response.form.set('pieces_jointes-1-nom', 'pj2.zip')
response.form.set('pieces_jointes-1-fichier', Upload('pj2.zip', MINIMAL_ZIP_FILE, 'application/zip'))
response = response.form.submit('_continue').follow()
facture = app.get(response.request.path.split('change')[0] + 'view_pdf/xxx.pdf?facturx')
pdf_reader = pypdf.PdfReader(io.BytesIO(facture.content))
assert [(k, v) for k, v in pdf_reader.attachments.items() if k != 'factur-x.xml'] == [
('pj1.zip', [MINIMAL_ZIP_FILE]),
('pj2.zip', [MINIMAL_ZIP_FILE]),
]