from datetime import timedelta from django.test import TestCase from django.utils import timezone from django.core.management import call_command from django.core import mail from io import StringIO from constance import config as site_config from constance.test import override_config from lambdainst.forms import SignupForm from lambdainst.models import VPNUser, User from payments.models import Payment, Subscription class UserTestMixin: def assertRemaining(self, vpnuser, time, delta=5): """ Check that the vpnuser will expire in time (+/- 5 seconds) """ exp = vpnuser.expiration or timezone.now() seconds = (exp - timezone.now() - time).total_seconds() self.assertAlmostEqual(seconds, 0, delta=delta) class UserModelReferrerTest(TestCase, UserTestMixin): def setUp(self): self.referrer = User.objects.create_user('ref') self.without_ref = User.objects.create_user('aaaa') self.with_ref = User.objects.create_user('bbbb') self.with_ref.vpnuser.referrer = self.referrer self.payment = Payment.objects.create( user=self.with_ref, status='confirmed', amount=300, time=timedelta(days=30)) def test_no_ref(self): self.without_ref.vpnuser.on_payment_confirmed(self.payment) def test_ref(self): self.with_ref.vpnuser.on_payment_confirmed(self.payment) self.assertTrue(self.with_ref.vpnuser.referrer_used) self.assertEqual(self.with_ref.vpnuser.referrer, self.referrer) self.assertRemaining(self.referrer.vpnuser, timedelta(days=30), delta=24*3600*3) class SignupViewTest(TestCase): def test_form(self): response = self.client.get('/account/signup') self.assertEqual(response.status_code, 200) self.assertIsInstance(response.context['form'], SignupForm) def test_post(self): response = self.client.post('/account/signup', { 'username': 'test_un', 'password': 'test_pw', 'password2': 'test_pw'}) self.assertRedirects(response, '/account/') user = User.objects.get(username='test_un') self.assertTrue(user.check_password('test_pw')) def test_post_error(self): response = self.client.post('/account/signup', { 'username': 'test_un', 'password': 'test_pw', 'password2': 'qsdf'}) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.context['form'], SignupForm) self.assertFormError(response, 'form', 'password', 'Passwords are not the same') def test_post_referrer(self): ref = User.objects.create_user('referrer') response = self.client.post('/account/signup?ref=%d' % ref.id, { 'username': 'test_un', 'password': 'test_pw', 'password2': 'test_pw'}) self.assertRedirects(response, '/account/') user = User.objects.get(username='test_un') self.assertTrue(user.check_password('test_pw')) self.assertEqual(user.vpnuser.referrer, ref) class AccountViewsTest(TestCase, UserTestMixin): def setUp(self): User.objects.create_user('test', None, 'test_pw') self.client.login(username='test', password='test_pw') def test_account(self): response = self.client.get('/account/') self.assertEqual(response.status_code, 200) def test_settings_form(self): response = self.client.get('/account/settings') self.assertEqual(response.status_code, 200) def print_message(self, response): from django.contrib.messages import get_messages messages = list(get_messages(response.wsgi_request)) for m in messages: print(f"[message: {m.message!r} level={m.level} tags={m.tags!r}]") def test_settings_post_email(self): response = self.client.post('/account/settings', { 'action': 'email', 'current_password': 'test_pw', 'email': 'new_email@example.com'}) self.assertEqual(response.status_code, 302) user = User.objects.get(username='test') self.assertEqual(user.email, 'new_email@example.com') def test_settings_post_email_fail(self): response = self.client.post('/account/settings', { 'action': 'email', 'current_password': 'not_test_pw', 'email': 'new_email@example.com'}) self.assertEqual(response.status_code, 302) user = User.objects.get(username='test') self.assertNotEqual(user.email, 'new_email@example.com') def test_settings_post_pw(self): response = self.client.post('/account/settings', { 'action': 'password', 'current_password': 'test_pw', 'password': 'new_test_pw', 'password2': 'new_test_pw'}) self.assertEqual(response.status_code, 302) user = User.objects.get(username='test') self.assertTrue(user.check_password('new_test_pw')) def test_settings_post_pw_fail(self): response = self.client.post('/account/settings', { 'action': 'password', 'current_password': 'oops', 'password': 'new_test_pw', 'password2': 'new_test_pw'}) self.assertEqual(response.status_code, 302) response = self.client.post('/account/settings', { 'action': 'password', 'current_password': 'test_pw', 'password': 'new_test_pw2', 'password2': 'new_test_pw_qsdfg'}) self.assertEqual(response.status_code, 302) user = User.objects.get(username='test') self.assertFalse(user.check_password('new_test_pw')) self.assertFalse(user.check_password('new_test_pw2')) self.assertTrue(user.check_password('test_pw')) class CACrtViewTest(TestCase): def test_ca_crt(self): with self.settings(OPENVPN_CA='test ca'): response = self.client.get('/ca.crt') self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'application/x-x509-ca-cert') self.assertEqual(response.content, b'test ca') def email_text(body): return body.replace('\n', ' ') \ .replace('\xa0', ' ') # nbsp class ExpireNotifyTest(TestCase): def setUp(self): pass def test_notify_first(self): out = StringIO() u = User.objects.create_user('test_username', 'test@example.com', 'testpw') u.vpnuser.add_paid_time(timedelta(days=2), 'initial') u.vpnuser.save() call_command('expire_notify', stdout=out) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].to, ['test@example.com']) self.assertIn('expire in 1 day', email_text(mail.outbox[0].body)) u = User.objects.get(username='test_username') self.assertAlmostEqual(u.vpnuser.last_expiry_notice, timezone.now(), delta=timedelta(minutes=1)) def test_notify_second(self): out = StringIO() u = User.objects.create_user('test_username', 'test@example.com', 'testpw') u.vpnuser.last_expiry_notice = timezone.now() - timedelta(days=2) u.vpnuser.add_paid_time(timedelta(days=1), 'initial') u.vpnuser.save() call_command('expire_notify', stdout=out) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].to, ['test@example.com']) self.assertIn('expire in 23 hours, 59 minutes', email_text(mail.outbox[0].body)) u = User.objects.get(username='test_username') self.assertAlmostEqual(u.vpnuser.last_expiry_notice, timezone.now(), delta=timedelta(minutes=1)) def test_notify_subscription(self): out = StringIO() u = User.objects.create_user('test_username', 'test@example.com', 'testpw') u.vpnuser.add_paid_time(timedelta(days=2), 'initial') u.vpnuser.save() s = Subscription(user=u, backend_id='paypal', status='active') s.save() call_command('expire_notify', stdout=out) self.assertEqual(len(mail.outbox), 0) u = User.objects.get(username='test_username') # FIXME: # self.assertNotAlmostEqual(u.vpnuser.last_expiry_notice, timezone.now(), # delta=timedelta(minutes=1)) def test_notify_subscription_new(self): out = StringIO() u = User.objects.create_user('test_username', 'test@example.com', 'testpw') u.vpnuser.add_paid_time(timedelta(days=2), 'initial') u.vpnuser.last_expiry_notice = timezone.now() - timedelta(days=5) u.vpnuser.save() s = Subscription(user=u, backend_id='paypal', status='new') s.save() call_command('expire_notify', stdout=out) self.assertEqual(len(mail.outbox), 1) u = User.objects.get(username='test_username') # FIXME: # self.assertNotAlmostEqual(u.vpnuser.last_expiry_notice, timezone.now(), # delta=timedelta(minutes=1))