From a20a8b6cbe1000cdff4e2a7420d0709cd3c5732e Mon Sep 17 00:00:00 2001 From: Giuseppe De Marco Date: Fri, 1 May 2020 16:59:38 +0200 Subject: [PATCH 1/4] README and unit tests for humans --- .gitignore | 1 + README.rst | 11 +++- requirements-dev.txt | 2 + tests/settings.py | 4 +- tests/testprofiles/migrations/0001_initial.py | 60 +++++++++++++++++++ tests/testprofiles/migrations/__init__.py | 0 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 requirements-dev.txt create mode 100644 tests/testprofiles/migrations/0001_initial.py create mode 100644 tests/testprofiles/migrations/__init__.py diff --git a/.gitignore b/.gitignore index 1512d933..7049a276 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +db.sqlite3 .tox/ *.pyc *.egg-info diff --git a/README.rst b/README.rst index 45acb599..b4472220 100644 --- a/README.rst +++ b/README.rst @@ -545,9 +545,18 @@ following url:: Now if you go to the /test/ url you will see your SAML attributes and also a link to do a global logout. -You can also run the unit tests with the following command:: +Unit tests +========== +You can also run the unit tests as follows:: + + pip install -r requirements-dev.txt + python3 tests/manage.py migrate + python tests/run_tests.py + # or + pytest tests/* -x --pdb + If you have `tox`_ installed you can simply call tox inside the root directory and it will run the tests in multiple versions of Python. diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..125b4602 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,2 @@ +pytest +pytest-django diff --git a/tests/settings.py b/tests/settings.py index a42e19c1..9ef59280 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -25,6 +25,9 @@ ALLOWED_HOSTS = [] INSTALLED_APPS = ( + #'accounts', + 'testprofiles', + 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -33,7 +36,6 @@ 'django.contrib.staticfiles', 'djangosaml2', - 'testprofiles', ) MIDDLEWARE = ( diff --git a/tests/testprofiles/migrations/0001_initial.py b/tests/testprofiles/migrations/0001_initial.py new file mode 100644 index 00000000..fa7b4208 --- /dev/null +++ b/tests/testprofiles/migrations/0001_initial.py @@ -0,0 +1,60 @@ +# Generated by Django 3.0.5 on 2020-05-01 14:54 + +import django.contrib.auth.models +import django.contrib.auth.validators +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0011_update_proxy_permissions'), + ] + + operations = [ + migrations.CreateModel( + name='RequiredFieldUser', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('email', models.EmailField(max_length=254, unique=True)), + ('email_verified', models.BooleanField()), + ], + ), + migrations.CreateModel( + name='StandaloneUserModel', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('username', models.CharField(max_length=30, unique=True)), + ], + ), + migrations.CreateModel( + name='TestUser', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('age', models.CharField(blank=True, max_length=100)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + ] diff --git a/tests/testprofiles/migrations/__init__.py b/tests/testprofiles/migrations/__init__.py new file mode 100644 index 00000000..e69de29b From 00c48c504b64e3b54e592039550765e76631ea2f Mon Sep 17 00:00:00 2001 From: Mathieu Hinderyckx Date: Fri, 1 May 2020 17:41:45 +0200 Subject: [PATCH 2/4] testfix for python 3.8 --- djangosaml2/tests/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/djangosaml2/tests/__init__.py b/djangosaml2/tests/__init__.py index 2c210d27..bd84912b 100644 --- a/djangosaml2/tests/__init__.py +++ b/djangosaml2/tests/__init__.py @@ -129,7 +129,11 @@ def test_unsigned_post_authn_request(self): response_parser = SAMLPostFormParser() response_parser.feed(response.content.decode('utf-8')) saml_request = response_parser.saml_request_value - expected_request = """http://sp.example.com/saml2/metadata/""" + + if PY_VERSION < (3, 8): + expected_request = """http://sp.example.com/saml2/metadata/""" + else: + expected_request = """http://sp.example.com/saml2/metadata/""" self.assertIsNotNone(saml_request) self.assertSAMLRequestsEquals( From be4209292b29e14ac2675fe58d6ebc34a3d1d0e0 Mon Sep 17 00:00:00 2001 From: Mathieu Hinderyckx Date: Fri, 1 May 2020 17:45:45 +0200 Subject: [PATCH 3/4] tox fix --- tox.ini | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 921ab538..9c94d89e 100644 --- a/tox.ini +++ b/tox.ini @@ -7,9 +7,8 @@ commands = python tests/run_tests.py deps = - mock - django22: Django>=2.2,<3.0 - django30: Django>=3.0,<3.1 + django2.2: django~=2.2 + django3.0: django~=3.0 djangomaster: https://github.com/django/django/archive/master.tar.gz .[test] From 2c00b972bf1c0e639e40209e7166e6f758c14d35 Mon Sep 17 00:00:00 2001 From: Mathieu Hinderyckx Date: Fri, 1 May 2020 17:47:59 +0200 Subject: [PATCH 4/4] mock --- djangosaml2/tests/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/djangosaml2/tests/__init__.py b/djangosaml2/tests/__init__.py index bd84912b..663967bb 100644 --- a/djangosaml2/tests/__init__.py +++ b/djangosaml2/tests/__init__.py @@ -16,11 +16,9 @@ import base64 import datetime -import mock import re import sys - -from unittest import skip +from unittest import mock, skip from django.conf import settings from django.contrib.auth import SESSION_KEY, get_user_model @@ -29,16 +27,17 @@ from django.template import Context, Template from django.test import TestCase from django.test.client import RequestFactory +from saml2.config import SPConfig +from saml2.s_utils import decode_base64_and_inflate, deflate_and_base64_encode + from djangosaml2 import views from djangosaml2.cache import OutstandingQueriesCache from djangosaml2.conf import get_config from djangosaml2.signals import post_authenticated from djangosaml2.tests import conf -from djangosaml2.tests.utils import SAMLPostFormParser from djangosaml2.tests.auth_response import auth_response +from djangosaml2.tests.utils import SAMLPostFormParser from djangosaml2.views import finish_logout -from saml2.config import SPConfig -from saml2.s_utils import decode_base64_and_inflate, deflate_and_base64_encode try: from django.urls import reverse