dbca-utils 2.0.3__tar.gz → 2.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +1,31 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: dbca-utils
3
- Version: 2.0.3
3
+ Version: 2.1.1
4
4
  Summary: Utilities for DBCA Django apps
5
- License: Apache-2.0
6
- Author: Rocky Chen
7
- Author-email: rocky.chen@dbca.wa.gov.au
8
- Requires-Python: >=3.9,<4.0
9
- Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: Environment :: Web Environment
5
+ Author-Email: Rocky Chen <rocky.chen@dbca.wa.gov.au>, Ashley Felton <ashley.felton@dbca.wa.gov.au>
6
+ License-Expression: Apache-2.0
11
7
  Classifier: Framework :: Django
12
- Classifier: Framework :: Django :: 3.2
13
8
  Classifier: Framework :: Django :: 4.0
14
9
  Classifier: Framework :: Django :: 4.2
15
10
  Classifier: Framework :: Django :: 5.0
11
+ Classifier: Framework :: Django :: 5.2
12
+ Classifier: Environment :: Web Environment
16
13
  Classifier: Intended Audience :: Developers
17
- Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Development Status :: 5 - Production/Stable
18
15
  Classifier: Programming Language :: Python
19
16
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.9
21
17
  Classifier: Programming Language :: Python :: 3.10
22
18
  Classifier: Programming Language :: Python :: 3.11
23
19
  Classifier: Programming Language :: Python :: 3.12
24
20
  Classifier: Programming Language :: Python :: 3.13
25
21
  Classifier: Topic :: Software Development :: Libraries
26
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
- Requires-Dist: django (>=3.2,<5.1)
23
+ Project-URL: Homepage, https://github.com/dbca-wa/dbca-utils
24
+ Project-URL: Repository, https://github.com/dbca-wa/dbca-utils.git
25
+ Project-URL: Changelog, https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md
26
+ Project-URL: GitHub, https://github.com/dbca-wa/dbca-utils
27
+ Requires-Python: <4.0,>=3.10
28
+ Requires-Dist: django<6,>=4
28
29
  Description-Content-Type: text/markdown
29
30
 
30
31
  # Overview
@@ -33,30 +34,43 @@ DBCA Django utility classes and functions.
33
34
 
34
35
  ## Development
35
36
 
36
- This project for development is using
37
- [Poetry](https://python-poetry.org/docs/) to install and manage a virtual Python
38
- environment. With Poetry installed, change into the project directory and run:
37
+ The recommended way to set up this project for development is using
38
+ [uv](https://docs.astral.sh/uv/)
39
+ to install and manage a Python virtual environment.
40
+ With uv installed, install the required Python version (see `pyproject.toml`). Example:
41
+
42
+ uv python install 3.12
39
43
 
40
- poetry install
44
+ Change into the project directory and run:
45
+
46
+ uv python pin 3.12
47
+ uv sync
41
48
 
42
49
  Activate the virtualenv like so:
43
50
 
44
- poetry shell
51
+ source .venv/bin/activate
45
52
 
46
53
  Run unit tests using `pytest` (or `tox`, to test against multiple Python versions):
47
54
 
48
- pytest -v
55
+ pytest -sv
49
56
  tox -v
50
57
 
51
58
  ## Releases
52
59
 
53
60
  Tagged releases are built and pushed to PyPI automatically using a GitHub
54
61
  workflow in the project. Update the project version in `pyproject.toml` and
55
- tag the required commit with the same value to trigger a release.
62
+ tag the required commit with the same value to trigger a release. Packages
63
+ can also be built and uploaded manually, if desired.
64
+
65
+ Build the project locally using uv, [publish to the PyPI registry](https://docs.astral.sh/uv/guides/publish/#publishing-your-package)
66
+ using the same tool if you require:
67
+
68
+ uv build
69
+ uv publish
56
70
 
57
71
  ## Installation
58
72
 
59
- 1. Install via pip/Poetry/etc.: `pip install dbca-utils`
73
+ 1. Install via pip/etc.: `pip install dbca-utils`
60
74
 
61
75
  ## SSO Login Middleware
62
76
 
@@ -89,8 +103,7 @@ MIDDLEWARE = [
89
103
 
90
104
  `AuditMixin` is an extension of `Django.db.model.Model` that adds a number of additional fields:
91
105
 
92
- - creator - FK to `AUTH_USER_MODEL`, used to record the object creator
93
- - modifier - FK to `AUTH_USER_MODEL`, used to record who the object was last modified by
94
- - created - a timestamp that is set on initial object save
95
- - modified - an auto-updating timestamp (on each object save)
96
-
106
+ - `creator` - FK to `AUTH_USER_MODEL`, used to record the object creator
107
+ - `modifier` - FK to `AUTH_USER_MODEL`, used to record who the object was last modified by
108
+ - `created` - a timestamp that is set on initial object save
109
+ - `modified` - an auto-updating timestamp (on each object save)
@@ -4,30 +4,43 @@ DBCA Django utility classes and functions.
4
4
 
5
5
  ## Development
6
6
 
7
- This project for development is using
8
- [Poetry](https://python-poetry.org/docs/) to install and manage a virtual Python
9
- environment. With Poetry installed, change into the project directory and run:
7
+ The recommended way to set up this project for development is using
8
+ [uv](https://docs.astral.sh/uv/)
9
+ to install and manage a Python virtual environment.
10
+ With uv installed, install the required Python version (see `pyproject.toml`). Example:
10
11
 
11
- poetry install
12
+ uv python install 3.12
13
+
14
+ Change into the project directory and run:
15
+
16
+ uv python pin 3.12
17
+ uv sync
12
18
 
13
19
  Activate the virtualenv like so:
14
20
 
15
- poetry shell
21
+ source .venv/bin/activate
16
22
 
17
23
  Run unit tests using `pytest` (or `tox`, to test against multiple Python versions):
18
24
 
19
- pytest -v
25
+ pytest -sv
20
26
  tox -v
21
27
 
22
28
  ## Releases
23
29
 
24
30
  Tagged releases are built and pushed to PyPI automatically using a GitHub
25
31
  workflow in the project. Update the project version in `pyproject.toml` and
26
- tag the required commit with the same value to trigger a release.
32
+ tag the required commit with the same value to trigger a release. Packages
33
+ can also be built and uploaded manually, if desired.
34
+
35
+ Build the project locally using uv, [publish to the PyPI registry](https://docs.astral.sh/uv/guides/publish/#publishing-your-package)
36
+ using the same tool if you require:
37
+
38
+ uv build
39
+ uv publish
27
40
 
28
41
  ## Installation
29
42
 
30
- 1. Install via pip/Poetry/etc.: `pip install dbca-utils`
43
+ 1. Install via pip/etc.: `pip install dbca-utils`
31
44
 
32
45
  ## SSO Login Middleware
33
46
 
@@ -60,7 +73,7 @@ MIDDLEWARE = [
60
73
 
61
74
  `AuditMixin` is an extension of `Django.db.model.Model` that adds a number of additional fields:
62
75
 
63
- - creator - FK to `AUTH_USER_MODEL`, used to record the object creator
64
- - modifier - FK to `AUTH_USER_MODEL`, used to record who the object was last modified by
65
- - created - a timestamp that is set on initial object save
66
- - modified - an auto-updating timestamp (on each object save)
76
+ - `creator` - FK to `AUTH_USER_MODEL`, used to record the object creator
77
+ - `modifier` - FK to `AUTH_USER_MODEL`, used to record who the object was last modified by
78
+ - `created` - a timestamp that is set on initial object save
79
+ - `modified` - an auto-updating timestamp (on each object save)
@@ -0,0 +1,60 @@
1
+ [project]
2
+ name = "dbca-utils"
3
+ version = "2.1.1"
4
+ description = "Utilities for DBCA Django apps"
5
+ authors = [
6
+ { name = "Rocky Chen", email = "rocky.chen@dbca.wa.gov.au" },
7
+ { name = "Ashley Felton", email = "ashley.felton@dbca.wa.gov.au" },
8
+ ]
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ classifiers = [
12
+ "Framework :: Django",
13
+ "Framework :: Django :: 4.0",
14
+ "Framework :: Django :: 4.2",
15
+ "Framework :: Django :: 5.0",
16
+ "Framework :: Django :: 5.2",
17
+ "Environment :: Web Environment",
18
+ "Intended Audience :: Developers",
19
+ "Development Status :: 5 - Production/Stable",
20
+ "Programming Language :: Python",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Software Development :: Libraries",
27
+ "Topic :: Software Development :: Libraries :: Python Modules",
28
+ ]
29
+ requires-python = ">=3.10,<4.0"
30
+ dependencies = [
31
+ "django>=4,<6",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/dbca-wa/dbca-utils"
36
+ Repository = "https://github.com/dbca-wa/dbca-utils.git"
37
+ Changelog = "https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md"
38
+ GitHub = "https://github.com/dbca-wa/dbca-utils"
39
+
40
+ [dependency-groups]
41
+ dev = [
42
+ "pytest-django>=4.11.0",
43
+ "pytest-sugar>=1.0.0",
44
+ "tox>=4.25.0",
45
+ "tox-uv>=1.25.0",
46
+ ]
47
+
48
+ [build-system]
49
+ requires = [
50
+ "pdm-backend",
51
+ ]
52
+ build-backend = "pdm.backend"
53
+
54
+ [tool.uv]
55
+ package = true
56
+
57
+ [tool.pytest.ini_options]
58
+ DJANGO_SETTINGS_MODULE = "tests.settings"
59
+ pythonpath = ". src"
60
+ python_files = "tests.py test_*.py"
@@ -1,10 +1,10 @@
1
- from django import http, VERSION
1
+ from django import http
2
2
  from django.conf import settings
3
- from django.contrib.auth import login, logout, get_user_model
3
+ from django.contrib.auth import get_user_model, login, logout
4
+ from django.contrib.auth.middleware import AuthenticationMiddleware, get_user
5
+ from django.utils import timezone
4
6
  from django.utils.deprecation import MiddlewareMixin
5
7
  from django.utils.functional import SimpleLazyObject
6
- from django.utils import timezone
7
- from django.contrib.auth.middleware import AuthenticationMiddleware, get_user
8
8
 
9
9
  from dbca_utils.utils import env
10
10
 
@@ -17,10 +17,14 @@ def sync_usergroups(user, groups):
17
17
  from django.contrib.auth.models import Group
18
18
 
19
19
  usergroups = (
20
- [Group.objects.get_or_create(name=name)[0] for name in groups.split(",")] if groups else []
20
+ [Group.objects.get_or_create(name=name)[0] for name in groups.split(",")]
21
+ if groups
22
+ else []
21
23
  )
22
24
  usergroups.sort(key=lambda o: o.id)
23
- existing_usergroups = list(user.groups.exclude(name__in=LOCAL_USERGROUPS).order_by("id"))
25
+ existing_usergroups = list(
26
+ user.groups.exclude(name__in=LOCAL_USERGROUPS).order_by("id")
27
+ )
24
28
  index1 = 0
25
29
  index2 = 0
26
30
  len1 = len(usergroups)
@@ -96,7 +100,6 @@ class SSOLoginMiddleware(MiddlewareMixin):
96
100
  """
97
101
 
98
102
  def process_request(self, request):
99
-
100
103
  # Logout headers included with request.
101
104
  if (
102
105
  (
@@ -118,10 +121,7 @@ class SSOLoginMiddleware(MiddlewareMixin):
118
121
  # auth2 not enabled
119
122
  return
120
123
 
121
- if VERSION < (2, 0):
122
- user_authenticated = request.user.is_authenticated()
123
- else:
124
- user_authenticated = request.user.is_authenticated
124
+ user_authenticated = request.user.is_authenticated
125
125
 
126
126
  # Auth2 is enabled.
127
127
  # Request user is not authenticated.
@@ -158,7 +158,9 @@ class SSOLoginMiddleware(MiddlewareMixin):
158
158
  user = User.objects.filter(email__iexact=attributemap["email"])[0]
159
159
  elif (
160
160
  User.__name__ != "EmailUser"
161
- and User.objects.filter(username__iexact=attributemap["username"]).exists()
161
+ and User.objects.filter(
162
+ username__iexact=attributemap["username"]
163
+ ).exists()
162
164
  ):
163
165
  user = User.objects.filter(username__iexact=attributemap["username"])[0]
164
166
  else:
@@ -1,15 +1,23 @@
1
- import ast
2
1
  import os
2
+ from ast import literal_eval
3
3
 
4
4
 
5
5
  def env(key, default=None, required=False, value_type=None):
6
6
  """
7
7
  Retrieves environment variables and returns Python natives. The (optional)
8
- default will be returned if the environment variable does not exist.
8
+ `default` value will be returned if the environment variable does not exist.
9
+ Setting `required` will cause an Exception to be thrown if the variable does
10
+ not exist.
11
+ Setting `value_type` will try to ensure that the returned value is of the
12
+ nominated type (within reason).
13
+ Supported Python object types: str, list, tuple, bool, int, float.
9
14
  """
15
+ value = None
16
+
10
17
  try:
11
18
  value = os.environ[key]
12
- value = ast.literal_eval(value)
19
+ # Evaluate the environment variable value as a Python object.
20
+ value = literal_eval(value)
13
21
  except (SyntaxError, ValueError):
14
22
  pass
15
23
  except KeyError:
@@ -17,14 +25,17 @@ def env(key, default=None, required=False, value_type=None):
17
25
  return default
18
26
  raise Exception(f"Missing required environment variable {key}")
19
27
 
20
- if value_type is None:
21
- if default is not None:
22
- value_type = default.__class__
28
+ if value_type is None and default is not None:
29
+ # If we've passed a default return value but not set a value_type, use the
30
+ # default's type.
31
+ value_type = default.__class__
23
32
 
24
33
  if value_type is None:
25
34
  return value
26
35
  elif isinstance(value, value_type):
27
36
  return value
37
+ elif issubclass(value_type, str):
38
+ return str(value)
28
39
  elif issubclass(value_type, list):
29
40
  if isinstance(value, tuple):
30
41
  return list(value)
@@ -53,7 +64,7 @@ def env(key, default=None, required=False, value_type=None):
53
64
  return False
54
65
  else:
55
66
  raise Exception(
56
- f"{key} is a boolean environment variable and only accepts 'true' ,'false' and '' (case-insensitive), but the configured value is '{value}'"
67
+ f"{key} is a boolean environment variable and only accepts 'true', 'false' or '' (case-insensitive), but the configured value is '{value}'"
57
68
  )
58
69
  elif issubclass(value_type, int):
59
70
  return int(value)
@@ -61,5 +72,5 @@ def env(key, default=None, required=False, value_type=None):
61
72
  return float(value)
62
73
  else:
63
74
  raise Exception(
64
- f"{key} is a {value_type} environment variable, but {value_type} is not supported now"
75
+ f"{key} is a {value_type} environment variable, but {value_type} is not supported"
65
76
  )
File without changes
@@ -0,0 +1,6 @@
1
+ from django.apps import AppConfig
2
+
3
+
4
+ class TestsConfig(AppConfig):
5
+ default_auto_field = "django.db.models.AutoField"
6
+ name = "tests"
@@ -0,0 +1,63 @@
1
+ import django.db.models.deletion
2
+ import django.utils.timezone
3
+ from django.conf import settings
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ initial = True
9
+
10
+ dependencies = [
11
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.CreateModel(
16
+ name="TestModel",
17
+ fields=[
18
+ (
19
+ "id",
20
+ models.AutoField(
21
+ auto_created=True,
22
+ primary_key=True,
23
+ serialize=False,
24
+ verbose_name="ID",
25
+ ),
26
+ ),
27
+ ("effective_to", models.DateTimeField(blank=True, null=True)),
28
+ (
29
+ "created",
30
+ models.DateTimeField(
31
+ default=django.utils.timezone.now, editable=False
32
+ ),
33
+ ),
34
+ ("modified", models.DateTimeField(auto_now=True)),
35
+ ("name", models.CharField(max_length=64)),
36
+ (
37
+ "creator",
38
+ models.ForeignKey(
39
+ blank=True,
40
+ editable=False,
41
+ null=True,
42
+ on_delete=django.db.models.deletion.PROTECT,
43
+ related_name="%(app_label)s_%(class)s_created",
44
+ to=settings.AUTH_USER_MODEL,
45
+ ),
46
+ ),
47
+ (
48
+ "modifier",
49
+ models.ForeignKey(
50
+ blank=True,
51
+ editable=False,
52
+ null=True,
53
+ on_delete=django.db.models.deletion.PROTECT,
54
+ related_name="%(app_label)s_%(class)s_modified",
55
+ to=settings.AUTH_USER_MODEL,
56
+ ),
57
+ ),
58
+ ],
59
+ options={
60
+ "abstract": False,
61
+ },
62
+ ),
63
+ ]
File without changes
@@ -0,0 +1,11 @@
1
+ from django.db import models
2
+
3
+ from dbca_utils.models import ActiveMixin, ActiveMixinManager, AuditMixin
4
+
5
+
6
+ class TestModel(ActiveMixin, AuditMixin):
7
+ name = models.CharField(max_length=64)
8
+ objects = ActiveMixinManager()
9
+
10
+ def __str__(self):
11
+ return self.name
@@ -0,0 +1,46 @@
1
+ SECRET_KEY = "secretkey"
2
+
3
+ INSTALLED_APPS = [
4
+ "django.contrib.auth",
5
+ "django.contrib.contenttypes",
6
+ "django.contrib.sessions",
7
+ "django.contrib.messages",
8
+ "django.contrib.staticfiles",
9
+ "tests",
10
+ ]
11
+
12
+ MIDDLEWARE = [
13
+ "django.middleware.security.SecurityMiddleware",
14
+ "django.contrib.sessions.middleware.SessionMiddleware",
15
+ "django.middleware.common.CommonMiddleware",
16
+ "django.middleware.csrf.CsrfViewMiddleware",
17
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
18
+ "django.contrib.messages.middleware.MessageMiddleware",
19
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
20
+ "dbca_utils.middleware.SSOLoginMiddleware",
21
+ ]
22
+
23
+ ROOT_URLCONF = "tests.urls"
24
+
25
+ TEMPLATES = [
26
+ {
27
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
28
+ "APP_DIRS": True,
29
+ "OPTIONS": {
30
+ "context_processors": [
31
+ "django.template.context_processors.debug",
32
+ "django.template.context_processors.request",
33
+ "django.contrib.auth.context_processors.auth",
34
+ "django.contrib.messages.context_processors.messages",
35
+ ]
36
+ },
37
+ }
38
+ ]
39
+
40
+ DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}
41
+
42
+ STATIC_URL = "/static/"
43
+
44
+ DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
45
+
46
+ USE_TZ = True
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>{{ TITLE }}</title>
6
+ </head>
7
+ <body>
8
+ <ul>
9
+ {% for object in object_list %}<li>{{ object.name }}, {{ object.created|date:"r" }}</li>{% endfor %}
10
+ </ul>
11
+ </body>
12
+ </html>
@@ -0,0 +1,111 @@
1
+ import os
2
+ import random
3
+ import string
4
+
5
+ import pytest
6
+ from django.contrib.auth.models import User
7
+ from django.test import TestCase
8
+ from django.test.client import Client
9
+ from django.urls import reverse
10
+
11
+ from dbca_utils.utils import env
12
+
13
+ from .models import TestModel
14
+
15
+ # Define an environment variable for testing.
16
+ letters = string.ascii_letters
17
+ TEST_VAR = "".join(random.choice(letters) for _ in range(128))
18
+ TEST_NAME = "".join(random.choice(letters) for _ in range(128))
19
+ os.environ["TEST_ENVIRONMENT_VAR"] = TEST_VAR
20
+
21
+ os.environ["TEST_STR"] = "string"
22
+ os.environ["TEST_INT"] = "42"
23
+ os.environ["TEST_FLOAT"] = "3.14159"
24
+ os.environ["TEST_LIST"] = "[1,2,3,4,5]"
25
+ os.environ["TEST_TUPLE"] = "('a', 'b', 'c')"
26
+ os.environ["TEST_BOOL"] = "False"
27
+
28
+
29
+ class TestUtils(TestCase):
30
+ def test_env_returns_str(self):
31
+ test_str = env("TEST_STR")
32
+ self.assertTrue(isinstance(test_str, str))
33
+
34
+ def test_env_returns_int(self):
35
+ test_int = env("TEST_INT")
36
+ self.assertTrue(isinstance(test_int, int))
37
+
38
+ def test_env_returns_float(self):
39
+ test_float = env("TEST_FLOAT")
40
+ self.assertTrue(isinstance(test_float, float))
41
+
42
+ def test_env_returns_list(self):
43
+ test_list = env("TEST_LIST")
44
+ self.assertTrue(isinstance(test_list, list))
45
+
46
+ def test_env_returns_tuple(self):
47
+ test_tuple = env("TEST_TUPLE")
48
+ self.assertTrue(isinstance(test_tuple, tuple))
49
+
50
+ def test_env_returns_bool(self):
51
+ test_bool = env("TEST_BOOL")
52
+ self.assertTrue(isinstance(test_bool, bool))
53
+
54
+ def test_env_returns_default(self):
55
+ test_str = env("TEST_MISSING", "foo")
56
+ self.assertTrue(isinstance(test_str, str))
57
+
58
+ def test_env_missing_not_required_no_default(self):
59
+ test_env = env("TEST_MISSING")
60
+ self.assertIsNone(test_env)
61
+
62
+ def test_env_required_throws_exception(self):
63
+ with pytest.raises(Exception):
64
+ env("TEST_MISSING_REQUIRED", required=True)
65
+
66
+ def test_env_returns_other_as_str(self):
67
+ test_str = env("TEST_FLOAT", value_type=str)
68
+ self.assertTrue(isinstance(test_str, str))
69
+
70
+
71
+ class TestModelTests(TestCase):
72
+ client = Client()
73
+ model = TestModel
74
+
75
+ def setUp(self):
76
+ self.user = User.objects.create_user(
77
+ username="test", email="test@email.com", password="secret"
78
+ )
79
+ self.test_model = TestModel.objects.create(name=TEST_NAME)
80
+ self.client.login(username="test", password="secret")
81
+
82
+ def tearDown(self):
83
+ self.user.delete()
84
+
85
+ def test_model_fields(self):
86
+ """Test a model inheriting from mixins has the required fields."""
87
+ self.assertTrue(hasattr(self.test_model, "effective_to"))
88
+ self.assertTrue(hasattr(self.test_model, "creator"))
89
+ self.assertTrue(hasattr(self.test_model, "modifier"))
90
+ self.assertTrue(hasattr(self.test_model, "created"))
91
+ self.assertTrue(hasattr(self.test_model, "modified"))
92
+
93
+ def test_active_mixin(self):
94
+ """Test the ActiveMixin manager methods."""
95
+ obj_del = TestModel.objects.create(name="Deleted object")
96
+ obj_del.delete()
97
+ all_pks = [i.pk for i in TestModel.objects.all()]
98
+ current_pks = [i.pk for i in TestModel.objects.current()]
99
+ del_pks = [i.pk for i in TestModel.objects.deleted()]
100
+ self.assertTrue(obj_del.pk in all_pks)
101
+ self.assertFalse(obj_del.pk in current_pks)
102
+ self.assertTrue(obj_del.pk in del_pks)
103
+ self.assertFalse(self.test_model.pk in del_pks)
104
+
105
+ def test_url_request_returns_view(self):
106
+ """Test the env() utility method works as expected."""
107
+ url = reverse("test_model_list")
108
+ response = self.client.get(url)
109
+ self.assertEqual(response.status_code, 200)
110
+ self.assertContains(response, TEST_VAR)
111
+ self.assertContains(response, TEST_NAME)
@@ -0,0 +1,7 @@
1
+ from django.urls import path
2
+
3
+ from .views import TestModelListView
4
+
5
+ urlpatterns = [
6
+ path("test-models/", TestModelListView.as_view(), name="test_model_list"),
7
+ ]
@@ -0,0 +1,16 @@
1
+ from django.contrib.auth.mixins import LoginRequiredMixin
2
+ from django.views.generic.list import ListView
3
+
4
+ from dbca_utils.utils import env
5
+
6
+ from .models import TestModel
7
+
8
+
9
+ class TestModelListView(LoginRequiredMixin, ListView):
10
+ model = TestModel
11
+ template_name = "tests/test_model_list.html"
12
+
13
+ def get_context_data(self, **kwargs):
14
+ context = super().get_context_data(**kwargs)
15
+ context["TITLE"] = env("TEST_ENVIRONMENT_VAR")
16
+ return context
@@ -1,56 +0,0 @@
1
- [tool.poetry]
2
- name = "dbca-utils"
3
- version = "2.0.3"
4
- description = "Utilities for DBCA Django apps"
5
- authors = [
6
- "Rocky Chen <rocky.chen@dbca.wa.gov.au>",
7
- "Ashley Felton <ashley.felton@dbca.wa.gov.au>",
8
- ]
9
- license = "Apache-2.0"
10
- readme = "README.md"
11
- classifiers = [
12
- "Framework :: Django",
13
- "Framework :: Django :: 3.2",
14
- "Framework :: Django :: 4.0",
15
- "Framework :: Django :: 4.2",
16
- "Framework :: Django :: 5.0",
17
- "Environment :: Web Environment",
18
- "Intended Audience :: Developers",
19
- "Development Status :: 5 - Production/Stable",
20
- "License :: OSI Approved :: Apache Software License",
21
- "Programming Language :: Python",
22
- "Programming Language :: Python :: 3",
23
- "Programming Language :: Python :: 3.9",
24
- "Programming Language :: Python :: 3.10",
25
- "Programming Language :: Python :: 3.11",
26
- "Programming Language :: Python :: 3.12",
27
- "Topic :: Software Development :: Libraries",
28
- "Topic :: Software Development :: Libraries :: Python Modules",
29
- ]
30
-
31
-
32
- [tool.poetry.group.dev.dependencies]
33
- pytest-django = "^4.9.0"
34
- pytest-sugar = "^1.0.0"
35
- tox = "^4.23.2"
36
-
37
- [project.urls]
38
- homepage = "https://github.com/dbca-wa/dbca-utils"
39
- source = "https://github.com/dbca-wa/dbca-utils.git"
40
- changelog = "https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md"
41
-
42
- [tool.poetry.dependencies]
43
- python = "^3.9"
44
- django = ">=3.2,<5.1"
45
-
46
- [build-system]
47
- requires = ["poetry-core"]
48
- build-backend = "poetry.core.masonry.api"
49
-
50
- [tool.pytest.ini_options]
51
- # https://pytest-django.readthedocs.io/en/latest/configuring_django.html#pyproject-toml-settings
52
- DJANGO_SETTINGS_MODULE = "tests.settings"
53
- # https://pytest-django.readthedocs.io/en/latest/managing_python_path.html#using-pytest-s-pythonpath-option
54
- pythonpath = ". src"
55
- # https://pytest-django.readthedocs.io/en/latest/faq.html#my-tests-are-not-being-found-why
56
- python_files = "tests.py test_*.py"
File without changes