123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- # -*- coding: utf-8 -*-
- from __future__ import unicode_literals
- import datetime
- from decimal import Decimal
- from django.conf import settings
- from django.test import TestCase, Client
- from coin.members.tests import MemberTestsUtils
- from coin.members.models import Member, LdapUser
- from coin.billing.models import Invoice
- from coin.offers.models import Offer, OfferSubscription
- from coin.billing.create_subscriptions_invoices import create_member_invoice_for_a_period
- from coin.billing.create_subscriptions_invoices import create_all_members_invoices_for_a_period
- class BillingInvoiceCreationTests(TestCase):
- def setUp(self):
- # Créé une offre
- self.offer = Offer(name='Offre', billing_period=3, period_fees=30,
- initial_fees=50)
- self.offer.save()
- # Créé un membre
- self.username = MemberTestsUtils.get_random_username()
- self.member = Member(first_name='Balthazar', last_name='Picsou',
- username=self.username)
- self.member.save()
- # Créé un abonnement
- self.subscription = OfferSubscription(
- subscription_date=datetime.date(2014, 1, 10),
- member=self.member,
- offer=self.offer)
- self.subscription.save()
- def tearDown(self):
- # Supprime l'utilisateur LDAP créé
- if settings.LDAP_ACTIVATE:
- LdapUser.objects.get(pk=self.username).delete()
- def test_first_subscription_invoice_has_initial_fees(self):
- """
- Test que la première facture générée pour un abonnement possède les
- frais de mise en service
- """
- # Demande la création de la première facture
- invoice = create_member_invoice_for_a_period(
- self.member, datetime.date(2014, 1, 1))
- # La facture doit avoir les frais de mise en service
- # Pour tester cela on tri par montant d'item décroissant.
- # Comme dans l'offre créé, les initial_fees sont plus élevées que
- # les period_fees, il doit sortir en premier
- self.assertEqual(invoice.details.order_by('-amount').first().amount, 50)
- def test_prorata_for_first_month_subscription(self):
- """
- Test que la première facture d'un abonnement est facturée au prorata du
- nombre de jours restants
- """
- # Créé la facture pour le mois de janvier
- invoice = create_member_invoice_for_a_period(
- self.member, datetime.date(2014, 1, 1))
- # Comme l'abonnement a été souscris le 10/01 et que la période de
- # facturation est de 3 mois, alors le prorata doit être :
- # janvier : 22j (31-9)
- # fevrier : 28j
- # mars : 31j
- #22+28+31 / 31+28+31
- quantity = Decimal((22.0 + 28.0 + 31.0) / (31.0 + 28.0 + 31.0))
- for detail in invoice.details.all():
- if detail.amount != 50:
- self.assertEqual(detail.quantity.quantize(Decimal('0.01')),
- quantity.quantize(Decimal('0.01')))
- def test_subscription_cant_be_charged_twice(self):
- """
- Test qu'un abonnement ne peut pas être facturé deux fois
- (pas de chevauchement possible)
- """
- # Créé une facture
- invoice = Invoice(member=self.member)
- invoice.save()
- # Créé une facturation pour cet abonnement pour la première période
- # de janvier à mars
- invoice.details.create(label=self.offer.name,
- amount=self.offer.period_fees,
- offersubscription=self.subscription,
- period_from=datetime.date(2014, 1, 1),
- period_to=datetime.date(2014, 3, 31))
- # Créé une facturation pour cet abonnement pour une seconde période
- # de juin à aout
- invoice.details.create(label=self.offer.name,
- amount=self.offer.period_fees,
- offersubscription=self.subscription,
- period_from=datetime.date(2014, 6, 1),
- period_to=datetime.date(2014, 8, 31))
- # Demande la génération d'une facture pour février
- # Elle doit renvoyer None car l'offre est déjà facturée de
- # janvier à mars
- invoice_test_1 = create_member_invoice_for_a_period(
- self.member, datetime.date(2014, 2, 1))
- self.assertEqual(invoice_test_1, None)
- # Demande la création d'une facture pour avril
- # Elle doit fonctionner, mais devrait avoir une période de facturation
- # que de 2 mois, d'avril à mai car il y a déjà une facture pour
- # la période de juin à aout
- invoice_test_2 = create_member_invoice_for_a_period(
- self.member, datetime.date(2014, 4, 1))
- self.assertEqual(invoice_test_2.details.first().period_from,
- datetime.date(2014, 4, 1))
- self.assertEqual(invoice_test_2.details.first().period_to,
- datetime.date(2014, 5, 31))
- def test_non_billable_offer_isnt_charged(self):
- """
- Test qu'une offre non facturable n'est pas prise en compte
- """
- # Créé une offre non facturable
- offer = Offer(name='Offre', billing_period=3, period_fees=30,
- initial_fees=50, non_billable=True)
- offer.save()
- # Créé un abonnement
- self.subscription = OfferSubscription(
- subscription_date=datetime.date(2014, 1, 10),
- member=self.member,
- offer=offer)
- self.subscription.save()
- # Demande la création de la première facture
- invoice = create_member_invoice_for_a_period(
- self.member, datetime.date(2014, 1, 1))
- # Vérifie qu'il n'y a pas l'offre dans la facture, si c'est le cas génère une exception
- if invoice:
- for detail in invoice.details.all():
- if detail.offersubscription.offer == offer:
- raise Exception
- class BillingTests(TestCase):
- def test_download_invoice_pdf_return_a_pdf(self):
- """
- Test que le téléchargement d'une facture en format pdf retourne bien un
- pdf
- """
- # Créé un membre
- username = MemberTestsUtils.get_random_username()
- member = Member(first_name='A', last_name='A',
- username=username)
- member.set_password('1234')
- member.save()
- # Créé une facture
- invoice = Invoice(member=member)
- invoice.save()
- invoice.validate()
- # Se connect en tant que le membre
- client = Client()
- client.login(username=username, password='1234')
- # Tente de télécharger la facture
- response = client.get('/billing/invoice/%i/pdf' % invoice.id)
- # Vérifie return code 200 et contient chaine %PDF-1.
- self.assertContains(response, b'%PDF-1.', status_code=200, html=False)
- member.delete()
- def test_that_only_owner_of_invoice_can_access_it(self):
- """
- Test qu'une facture ne peut pas être téléchargée par quelqu'un qui n'en
- est pas le propriétaire.
- Test qu'une erreur 403 est bien retournée en cas de tentative
- infructueuse
- """
- # Créé un membre A
- member_a_login = MemberTestsUtils.get_random_username()
- member_a_pwd = '1234'
- member_a = Member(first_name='A', last_name='A', email='a@a.com',
- username=member_a_login)
- member_a.set_password(member_a_pwd)
- member_a.save()
- # Créé un membre B
- member_b_login = MemberTestsUtils.get_random_username()
- member_b_pwd = '1234'
- member_b = Member(first_name='B', last_name='B', email='b@b.com',
- username=member_b_login)
- member_b.set_password(member_b_pwd)
- member_b.save()
- # Créé une facture pour le membre A
- invoice_a = Invoice(member=member_a)
- invoice_a.save()
- invoice_a.validate()
- # Simule une connexion en tant que A
- client = Client()
- client.login(username=member_a_login, password=member_a_pwd)
- # Tente d'accéder à la facture en tant que A
- response = client.get(invoice_a.get_absolute_url())
- # Vérifie que A a reçu retour OK 200
- self.assertEqual(response.status_code, 200)
- # Tente de télécharger la facture pdf de A en tant que A
- response = client.get('/billing/invoice/%i/pdf' % invoice_a.id)
- # Vérifie que A a reçu retour OK 200
- self.assertEqual(response.status_code, 200)
- # Simule une connexion en tant que B
- client = Client()
- client.login(username=member_b_login, password=member_b_pwd)
- # Tente d'accéder à la facture de A en tant que B
- response = client.get(invoice_a.get_absolute_url())
- # Vérifie que B a reçu retour Forbissen 403
- self.assertEqual(response.status_code, 403)
- # Tente de télécharger la facture pdf de A en tant que B
- response = client.get('/billing/invoice/%i/pdf' % invoice_a.id)
- # Vérifie que B a reçu retour Forbidden 403
- self.assertEqual(response.status_code, 403)
- member_a.delete()
- member_b.delete()
|