django-sqrl-2/sqrl/tests/test_views.py

195 lines
6.5 KiB
Python

# -*- coding: utf-8 -*-
import json
import unittest
import mock
from django import test
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core import serializers
from django.urls import reverse
from django.http import Http404, QueryDict
from django.views.generic import FormView
from ..models import SQRLIdentity, SQRLNut
from ..views import (
SQRL_IDENTITY_SESSION_KEY,
SQRLCompleteRegistrationView,
SQRLStatusView,
)
TESTING_MODULE = 'sqrl.views'
class TestSQRLStatusView(test.TestCase):
def setUp(self):
super(TestSQRLStatusView, self).setUp()
self.view = SQRLStatusView()
self.view.request = mock.MagicMock(GET={})
self.view.request.is_ajax.return_value = True
self.view.kwargs = {
'transaction': '123',
}
self.nut = SQRLNut.objects.create(
nonce='hello',
transaction_nonce='123',
ip_address='127.0.0.1',
is_transaction_complete=True,
)
def tearDown(self):
self.nut and self.nut.delete()
super(TestSQRLStatusView, self).tearDown()
def test_get_success_url(self):
self.assertEqual(
self.view.get_success_url(),
settings.LOGIN_REDIRECT_URL
)
def test_get_success_url_from_querystring(self):
self.view.request.GET['url'] = '?next={}'.format(reverse('sqrl:login'))
self.assertEqual(
self.view.get_success_url(),
reverse('sqrl:login'),
)
def test_get_success_url_complete_registration(self):
self.view.request.GET['url'] = '?next={}'.format(reverse('sqrl:login'))
self.view.request.user.is_authenticated = False
self.view.request.session = {SQRL_IDENTITY_SESSION_KEY: ''}
self.assertEqual(
self.view.get_success_url(),
reverse('sqrl:complete-registration') + '?next={}'.format(reverse('sqrl:login')),
)
def test_get_object_404(self):
self.nut.delete()
self.nut = None
with self.assertRaises(Http404):
self.view.get_object()
def test_get_object(self):
actual = self.view.get_object()
self.assertIsInstance(actual, SQRLNut)
self.assertEqual(actual.nonce, self.nut.nonce)
self.assertEqual(actual.transaction_nonce, self.nut.transaction_nonce)
def test_post(self):
response = self.view.post(self.view.request, self.nut.transaction_nonce)
self.assertEqual(response.status_code, 200)
self.assertEqual(response['content-type'], 'application/json')
self.assertEqual(json.loads(response.content.decode('utf-8')), {
'transaction_complete': True,
'redirect_to': settings.LOGIN_REDIRECT_URL,
})
def test_post_not_ajax(self):
self.view.request.is_ajax.return_value = False
response = self.view.post(self.view.request, self.nut.transaction_nonce)
self.assertEqual(response.status_code, 405)
class TestSQRLAuthView(test.TestCase):
pass
class TestCompleteRegistrationView(test.TestCase):
def setUp(self):
super(TestCompleteRegistrationView, self).setUp()
self.view = SQRLCompleteRegistrationView()
self.username = 'foobartest'
self.view.request = mock.MagicMock(
method='POST',
POST={
'username': self.username,
},
)
self.identity = SQRLIdentity(
public_key='a' * 43,
verify_unlock_key='b' * 43,
server_unlock_key='c' * 43,
is_enabled=True,
is_only_sqrl=False,
)
self.view.request.session = {
SQRL_IDENTITY_SESSION_KEY: serializers.serialize('json', [self.identity]),
}
def tearDown(self):
SQRLIdentity.objects.filter(public_key=self.identity.public_key).delete()
get_user_model().objects.filter(username=self.username).delete()
super(TestCompleteRegistrationView, self).tearDown()
def test_check_session_for_sqrl_identity_or_404(self):
self.assertIsNone(self.view.check_session_for_sqrl_identity_or_404())
def test_check_session_for_sqrl_identity_or_404_raises(self):
self.view.request.session = {}
with self.assertRaises(Http404):
self.view.check_session_for_sqrl_identity_or_404()
@mock.patch.object(SQRLCompleteRegistrationView, 'check_session_for_sqrl_identity_or_404')
@mock.patch.object(FormView, 'get')
def test_get(self, mock_super_get, mock_check_session_for_sqrl_identity_or_404):
response = self.view.get(self.view.request)
self.assertEqual(response, mock_super_get.return_value)
mock_check_session_for_sqrl_identity_or_404.assert_called_once_with()
@mock.patch.object(SQRLCompleteRegistrationView, 'check_session_for_sqrl_identity_or_404')
@mock.patch.object(FormView, 'post')
def test_post(self, mock_super_post, mock_check_session_for_sqrl_identity_or_404):
response = self.view.post(self.view.request)
self.assertEqual(response, mock_super_post.return_value)
mock_check_session_for_sqrl_identity_or_404.assert_called_once_with()
def test_get_success_url(self):
self.assertEqual(
self.view.get_success_url(),
settings.LOGIN_REDIRECT_URL
)
def test_get_success_url_from_querystring(self):
self.view.request.GET = {'next': reverse('sqrl:manage')}
self.assertEqual(
self.view.get_success_url(),
reverse('sqrl:manage'),
)
@mock.patch(TESTING_MODULE + '.login')
def test_form_valid(self, mock_login):
form = self.view.get_form(self.view.get_form_class())
form.is_valid()
# sanity checks
self.assertFalse(get_user_model().objects.filter(username=self.username).count())
self.assertFalse(SQRLIdentity.objects.filter(public_key=self.identity.public_key).count())
response = self.view.form_valid(form)
user = get_user_model().objects.filter(username=self.username).first()
self.assertIsNotNone(user)
self.assertEqual(user.username, self.username)
self.assertIsInstance(user.sqrl_identity, SQRLIdentity)
self.assertEqual(user.sqrl_identity.public_key, self.identity.public_key)
self.assertEqual(response.status_code, 302)
def test_form_valid_could_not_decode_identity(self):
self.view.request.session[SQRL_IDENTITY_SESSION_KEY] = ''
response = self.view.form_valid(self.view.get_form(self.view.get_form_class()))
self.assertEqual(response.status_code, 500)