# Copyright © 2022 Aravinth Manivannan # # 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 . import time from io import StringIO from django.contrib.auth import get_user_model from django.core import mail from django.core.management import call_command from django.urls import reverse from django.test import TestCase, Client, override_settings from django.utils.http import urlencode from django.contrib.auth import authenticate from django.core.management import call_command from django.conf import settings from payments import get_payment_model, RedirectNeeded, PaymentStatus from accounts.tests import register_util, login_util from dash.tests import create_configurations, create_instance_util, infra_custom_config from dash.models import Instance from .models import Payment from .utils import payment_fullfilled # class BillingTest(TestCase): # """ # Tests billing system # """ # # def setUp(self): # self.username = "billing_user" # register_util(t=self, username=self.username) # create_configurations(t=self) # # @override_settings(HOSTEA=infra_custom_config(test_name="test_payments")) # def test_payments(self): # c = Client() # login_util(self, c, "accounts.home") # instance_name = "test_payments" # create_instance_util( # t=self, c=c, instance_name=instance_name, config=self.instance_config[0] # ) # # instance = Instance.objects.get(name=instance_name) # # self.assertEqual(payment_fullfilled(instance=instance), True) # # payment = get_payment_model().objects.get(paid_by=self.user) # invoice_uri = reverse("billing.invoice.details", args=(payment.public_ref,)) # # # check if paid invoice is listed in paid invoice list view # resp = c.get(reverse("billing.invoice.paid")) # self.assertEqual(str.encode(invoice_uri) in resp.content, True) # # # check if the paid invoice is displayed in the pending invoice view, should not be displayed # resp = c.get(reverse("billing.invoice.pending")) # self.assertEqual(str.encode(invoice_uri) in resp.content, False) # # # check if the invoice details view is rendering paid invoice version # resp = c.get(invoice_uri) # self.assertEqual(str.encode(instance_name) in resp.content, True) # self.assertEqual( # str.encode(str(self.instance_config[0].rent)) in resp.content, True # ) # self.assertEqual(str.encode("Paid on") in resp.content, True) # # # try to generate an invoice for the second time on the same VM # # shouldn't be possible since payment is already made for the duration # payment_uri = reverse("billing.invoice.generate", args=(instance.name,)) # resp = c.get(payment_uri) # self.assertEqual(resp.status_code, 400) # # ## payment success page; no real functionality but user is redirected here # # by stripe if payment is successful # resp = c.get(reverse("billing.invoice.success", args=(payment.public_ref,))) # self.assertEqual( # resp.headers["Location"], # reverse("infra.create", args=(payment.instance_name,)), # ) # # # create_instance_util creates an instance and pays for it. An email is # # sent when the invoice is generated and one after payment is made # # # # So we are first checking for the last email that was sent(receipt) # # and then the Gitea instance credentials notification followed by the # # invoice generation email. # receipt_mail = mail.outbox.pop() # self.assertEqual( # all( # [ # receipt_mail.to[0] == self.email, # "This is a receipt for your latest Hostea payment" # in receipt_mail.body, # ] # ), # True, # ) # # instance_notificaiton = mail.outbox.pop() # self.assertEqual( # all( # [ # instance_notificaiton.to[0] == self.email, # "Congratulations on your new Gitea instance!" # in instance_notificaiton.body, # ] # ), # True, # ) # # invoice_generated_mail = mail.outbox.pop() # self.assertEqual( # all( # [ # invoice_generated_mail.to[0] == self.email, # "An invoice is generated" in invoice_generated_mail.body, # ] # ), # True, # ) # # ## payment failure page; no real functionality but user is redirected here # # by stripe if payment is successful # resp = c.get(reverse("billing.invoice.fail", args=(payment.public_ref,))) # self.assertEqual(b"failed" in resp.content, True) class GenerateInvoiceCommand(TestCase): """ Test command: manage.py generate_invoice """ def setUp(self): self.username = "test_generate_invoice_cmd_user" register_util(t=self, username=self.username) create_configurations(t=self) @override_settings( HOSTEA=infra_custom_config(test_name="test_generate_invoice_cmd") ) def test_cmd(self): c = Client() login_util(self, c, "accounts.home") instance_name = "test_generate_invoice_cmd" create_instance_util( t=self, c=c, instance_name=instance_name, config=self.instance_config[0] ) stdout = StringIO() stderr = StringIO() instance = Instance.objects.get(name=instance_name) self.assertEqual(payment_fullfilled(instance=instance), True) prev_len = len(mail.outbox) # username exists call_command( "generate_invoice", stdout=stdout, stderr=stderr, ) out = stdout.getvalue() print(out) self.assertEqual(instance_name in out, True) self.assertEqual(prev_len, len(mail.outbox)) # delete payment and re-generate with command get_payment_model().objects.get(instance_name=instance_name).delete() stdout = StringIO() stderr = StringIO() call_command( "generate_invoice", stdout=stdout, stderr=stderr, ) out = stdout.getvalue() print("out") print(out) self.assertEqual(instance_name in out, True) self.assertEqual(f"Payment not fulfilled for instance: {instance}" in out, True) self.assertEqual(prev_len + 1, len(mail.outbox))