django-spire 0.19.3__py3-none-any.whl → 0.19.5__py3-none-any.whl
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.
- django_spire/consts.py +1 -1
- django_spire/core/management/commands/spire_startapp_pkg/maps.py +14 -7
- django_spire/core/management/commands/spire_startapp_pkg/user_input.py +10 -7
- django_spire/core/static/django_spire/css/app-background.css +6 -0
- django_spire/core/static/django_spire/css/app-import.css +1 -0
- django_spire/core/static/django_spire/css/app-navigation.css +4 -0
- django_spire/core/static/django_spire/css/app-override.css +0 -0
- django_spire/core/static/django_spire/css/themes/ayu/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/ayu/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/catppuccin/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/catppuccin/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/default/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/default/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/gruvbox/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/gruvbox/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/material/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/material/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/nord/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/nord/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/one-dark/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/one-dark/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/palenight/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/palenight/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/rose-pine/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/rose-pine/app-light.css +2 -0
- django_spire/core/static/django_spire/css/themes/tokyo-night/app-dark.css +2 -0
- django_spire/core/static/django_spire/css/themes/tokyo-night/app-light.css +2 -0
- django_spire/core/templatetags/spire_core_tags.py +11 -0
- django_spire/theme/enums.py +0 -3
- django_spire/theme/models.py +0 -3
- django_spire/theme/tests/test_context_processor.py +6 -6
- django_spire/theme/tests/test_enums.py +0 -3
- django_spire/theme/tests/test_integration.py +2 -2
- django_spire/theme/tests/test_model.py +23 -24
- django_spire/theme/tests/test_views/test_json_views.py +4 -4
- {django_spire-0.19.3.dist-info → django_spire-0.19.5.dist-info}/METADATA +1 -1
- {django_spire-0.19.3.dist-info → django_spire-0.19.5.dist-info}/RECORD +40 -45
- django_spire/core/static/django_spire/css/themes/dracula/app-dark.css +0 -71
- django_spire/core/static/django_spire/css/themes/dracula/app-light.css +0 -66
- django_spire/core/static/django_spire/css/themes/oceanic-next/app-dark.css +0 -71
- django_spire/core/static/django_spire/css/themes/oceanic-next/app-light.css +0 -66
- django_spire/core/static/django_spire/css/themes/synthwave/app-dark.css +0 -71
- django_spire/core/static/django_spire/css/themes/synthwave/app-light.css +0 -66
- {django_spire-0.19.3.dist-info → django_spire-0.19.5.dist-info}/WHEEL +0 -0
- {django_spire-0.19.3.dist-info → django_spire-0.19.5.dist-info}/licenses/LICENSE.md +0 -0
- {django_spire-0.19.3.dist-info → django_spire-0.19.5.dist-info}/top_level.txt +0 -0
django_spire/consts.py
CHANGED
|
@@ -29,6 +29,7 @@ class AppConfiguration:
|
|
|
29
29
|
components: list[str],
|
|
30
30
|
user_inputs: dict[str, str] | None = None
|
|
31
31
|
) -> AppConfiguration:
|
|
32
|
+
immediate_parent = components[-2] if len(components) > 2 else None
|
|
32
33
|
parent_parts = components[1:-1] if len(components) > 1 else []
|
|
33
34
|
|
|
34
35
|
app_name = (
|
|
@@ -49,8 +50,8 @@ class AppConfiguration:
|
|
|
49
50
|
)
|
|
50
51
|
|
|
51
52
|
default_label = (
|
|
52
|
-
|
|
53
|
-
if
|
|
53
|
+
immediate_parent.lower() + '_' + app_name.lower()
|
|
54
|
+
if immediate_parent
|
|
54
55
|
else app_name.lower()
|
|
55
56
|
)
|
|
56
57
|
|
|
@@ -60,10 +61,16 @@ class AppConfiguration:
|
|
|
60
61
|
else default_label
|
|
61
62
|
)
|
|
62
63
|
|
|
64
|
+
default_db_table = (
|
|
65
|
+
'_'.join(parent_parts).lower() + '_' + app_name.lower()
|
|
66
|
+
if parent_parts
|
|
67
|
+
else app_name.lower()
|
|
68
|
+
)
|
|
69
|
+
|
|
63
70
|
db_table = (
|
|
64
|
-
user_inputs.get('db_table_name',
|
|
71
|
+
user_inputs.get('db_table_name', default_db_table)
|
|
65
72
|
if user_inputs
|
|
66
|
-
else
|
|
73
|
+
else default_db_table
|
|
67
74
|
)
|
|
68
75
|
|
|
69
76
|
inherit_permissions = (
|
|
@@ -324,7 +331,7 @@ class ModelPermissions:
|
|
|
324
331
|
user_inputs: dict[str, str] | None = None
|
|
325
332
|
) -> ModelPermissions:
|
|
326
333
|
module = '.'.join(components)
|
|
327
|
-
|
|
334
|
+
immediate_parent = components[-2] if len(components) > 2 else None
|
|
328
335
|
|
|
329
336
|
app_name = (
|
|
330
337
|
user_inputs.get('app_name', components[-1])
|
|
@@ -344,8 +351,8 @@ class ModelPermissions:
|
|
|
344
351
|
)
|
|
345
352
|
|
|
346
353
|
default_permission_name = (
|
|
347
|
-
|
|
348
|
-
if
|
|
354
|
+
immediate_parent.lower() + '_' + app_name.lower()
|
|
355
|
+
if immediate_parent
|
|
349
356
|
else app_name.lower()
|
|
350
357
|
)
|
|
351
358
|
|
|
@@ -49,7 +49,7 @@ class UserInputCollector:
|
|
|
49
49
|
app_label = self._collect_app_label(components, app_name)
|
|
50
50
|
model_name = self._collect_model_name(app_name)
|
|
51
51
|
model_name_plural = self._collect_model_name_plural(model_name)
|
|
52
|
-
db_table_name = self._collect_db_table_name(app_label
|
|
52
|
+
db_table_name = self._collect_db_table_name(components, app_name) # Changed from app_label to components, app_name
|
|
53
53
|
model_permission_path = self._collect_model_permission_path(app_path, model_name)
|
|
54
54
|
|
|
55
55
|
permission_data = self._collect_permission_inheritance(components)
|
|
@@ -78,8 +78,8 @@ class UserInputCollector:
|
|
|
78
78
|
:return: User-provided or default app label.
|
|
79
79
|
"""
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
default =
|
|
81
|
+
immediate_parent = components[-2] if len(components) > 2 else None
|
|
82
|
+
default = immediate_parent.lower() + '_' + app_name.lower() if immediate_parent else app_name.lower()
|
|
83
83
|
return self._collect_input('Enter the app label', default, '3/8')
|
|
84
84
|
|
|
85
85
|
def _collect_app_name(self, components: list[str]) -> str:
|
|
@@ -114,15 +114,18 @@ class UserInputCollector:
|
|
|
114
114
|
|
|
115
115
|
return app_path
|
|
116
116
|
|
|
117
|
-
def _collect_db_table_name(self,
|
|
117
|
+
def _collect_db_table_name(self, components: list[str], app_name: str) -> str:
|
|
118
118
|
"""
|
|
119
119
|
Prompts the user for the database table name.
|
|
120
120
|
|
|
121
|
-
:param
|
|
121
|
+
:param components: List of app path components.
|
|
122
|
+
:param app_name: Name of the app.
|
|
122
123
|
:return: User-provided or default database table name.
|
|
123
124
|
"""
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
parent_parts = components[1:-1] if len(components) > 1 else []
|
|
127
|
+
default = '_'.join(parent_parts).lower() + '_' + app_name.lower() if parent_parts else app_name.lower()
|
|
128
|
+
return self._collect_input('Enter the database table name', default, '6/8')
|
|
126
129
|
|
|
127
130
|
def _collect_input(self, prompt: str, default: str, step_number: str) -> str:
|
|
128
131
|
"""
|
|
@@ -183,7 +186,7 @@ class UserInputCollector:
|
|
|
183
186
|
:return: Dictionary containing permission inheritance settings.
|
|
184
187
|
"""
|
|
185
188
|
|
|
186
|
-
if len(components) <=
|
|
189
|
+
if len(components) <= 1:
|
|
187
190
|
return {'inherit_permissions': False, 'parent_permission_prefix': '', 'parent_model_instance_name': ''}
|
|
188
191
|
|
|
189
192
|
if not self._should_inherit_permissions():
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
--app-bg-alt-layer-three: var(--app-alt-layer-three);
|
|
34
34
|
--app-bg-alt-layer-four: var(--app-alt-layer-four);
|
|
35
35
|
|
|
36
|
+
--app-bg-card-header: var(--app-card-header);
|
|
37
|
+
|
|
36
38
|
--app-bg-side-navigation: var(--app-side-navigation-bg-color);
|
|
37
39
|
|
|
38
40
|
--app-bg-top-navigation: var(--app-top-navigation-bg-color);
|
|
@@ -151,6 +153,10 @@
|
|
|
151
153
|
background-color: var(--app-bg-alt-layer-four) !important;
|
|
152
154
|
}
|
|
153
155
|
|
|
156
|
+
.bg-app-card-header {
|
|
157
|
+
background-color: var(--app-bg-card-header) !important;
|
|
158
|
+
}
|
|
159
|
+
|
|
154
160
|
.bg-app-side-navigation, .bg-app-side-navigation-hover:hover {
|
|
155
161
|
background-color: var(--app-bg-side-navigation) !important;
|
|
156
162
|
}
|
|
@@ -73,6 +73,10 @@
|
|
|
73
73
|
transition: background-color 0.2s ease, color 0.2s ease;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
.side-navigation a.active {
|
|
77
|
+
color: var(--app-side-navigation-link-color) !important;
|
|
78
|
+
}
|
|
79
|
+
|
|
76
80
|
.side-navigation a:hover {
|
|
77
81
|
color: var(--app-side-navigation-link-hover-color) !important;
|
|
78
82
|
}
|
|
File without changes
|
|
@@ -79,6 +79,17 @@ def index(indexable: Sequence[U], index_value: int) -> U | Sequence[U]:
|
|
|
79
79
|
return indexable
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
@register.filter(name='is_path')
|
|
83
|
+
def is_path(current: str, url: str) -> bool:
|
|
84
|
+
if not current or not url:
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
if current == url:
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
return url != '/' and current.startswith(url)
|
|
91
|
+
|
|
92
|
+
|
|
82
93
|
@register.simple_tag()
|
|
83
94
|
def generate_id() -> str:
|
|
84
95
|
"""
|
django_spire/theme/enums.py
CHANGED
|
@@ -7,15 +7,12 @@ class ThemeFamily(StrEnum):
|
|
|
7
7
|
AYU = 'ayu'
|
|
8
8
|
CATPPUCCIN = 'catppuccin'
|
|
9
9
|
DEFAULT = 'default'
|
|
10
|
-
DRACULA = 'dracula'
|
|
11
10
|
GRUVBOX = 'gruvbox'
|
|
12
11
|
MATERIAL = 'material'
|
|
13
12
|
NORD = 'nord'
|
|
14
|
-
OCEANIC_NEXT = 'oceanic-next'
|
|
15
13
|
ONE_DARK = 'one-dark'
|
|
16
14
|
PALENIGHT = 'palenight'
|
|
17
15
|
ROSE_PINE = 'rose-pine'
|
|
18
|
-
SYNTHWAVE = 'synthwave'
|
|
19
16
|
TOKYO_NIGHT = 'tokyo-night'
|
|
20
17
|
|
|
21
18
|
|
django_spire/theme/models.py
CHANGED
|
@@ -19,15 +19,12 @@ class Theme:
|
|
|
19
19
|
ThemeFamily.AYU: 'Ayu',
|
|
20
20
|
ThemeFamily.CATPPUCCIN: 'Catppuccin',
|
|
21
21
|
ThemeFamily.DEFAULT: 'Default',
|
|
22
|
-
ThemeFamily.DRACULA: 'Dracula',
|
|
23
22
|
ThemeFamily.GRUVBOX: 'Gruvbox',
|
|
24
23
|
ThemeFamily.MATERIAL: 'Material',
|
|
25
24
|
ThemeFamily.NORD: 'Nord',
|
|
26
|
-
ThemeFamily.OCEANIC_NEXT: 'Oceanic Next',
|
|
27
25
|
ThemeFamily.ONE_DARK: 'One Dark Pro',
|
|
28
26
|
ThemeFamily.PALENIGHT: 'Palenight',
|
|
29
27
|
ThemeFamily.ROSE_PINE: 'Rose Pine',
|
|
30
|
-
ThemeFamily.SYNTHWAVE: 'Synthwave',
|
|
31
28
|
ThemeFamily.TOKYO_NIGHT: 'Tokyo Night',
|
|
32
29
|
}
|
|
33
30
|
|
|
@@ -18,14 +18,14 @@ class ThemeContextProcessorTests(TestCase):
|
|
|
18
18
|
request = self.factory.get('/')
|
|
19
19
|
request.COOKIES = {}
|
|
20
20
|
|
|
21
|
-
with patch('django_spire.conf.settings.DJANGO_SPIRE_DEFAULT_THEME', '
|
|
21
|
+
with patch('django_spire.conf.settings.DJANGO_SPIRE_DEFAULT_THEME', 'gruvbox-dark'):
|
|
22
22
|
context = theme_context(request)
|
|
23
23
|
|
|
24
|
-
self.assertEqual(context['DJANGO_SPIRE_DEFAULT_THEME'], '
|
|
24
|
+
self.assertEqual(context['DJANGO_SPIRE_DEFAULT_THEME'], 'gruvbox-dark')
|
|
25
25
|
self.assertIn('theme', context)
|
|
26
26
|
|
|
27
27
|
data = context['theme']
|
|
28
|
-
self.assertEqual(data['family'], '
|
|
28
|
+
self.assertEqual(data['family'], 'gruvbox')
|
|
29
29
|
self.assertEqual(data['mode'], 'dark')
|
|
30
30
|
|
|
31
31
|
def test_theme_context_with_cookie(self) -> None:
|
|
@@ -45,11 +45,11 @@ class ThemeContextProcessorTests(TestCase):
|
|
|
45
45
|
cookie_name = get_theme_cookie_name()
|
|
46
46
|
request.COOKIES = {cookie_name: 'invalid-theme'}
|
|
47
47
|
|
|
48
|
-
with patch('django_spire.conf.settings.DJANGO_SPIRE_DEFAULT_THEME', '
|
|
48
|
+
with patch('django_spire.conf.settings.DJANGO_SPIRE_DEFAULT_THEME', 'gruvbox-dark'):
|
|
49
49
|
context = theme_context(request)
|
|
50
50
|
|
|
51
51
|
data = context['theme']
|
|
52
|
-
self.assertEqual(data['family'], '
|
|
52
|
+
self.assertEqual(data['family'], 'gruvbox')
|
|
53
53
|
self.assertEqual(data['mode'], 'dark')
|
|
54
54
|
|
|
55
55
|
def test_theme_context_path_setting(self) -> None:
|
|
@@ -70,7 +70,7 @@ class ThemeContextProcessorIntegrationTests(BaseTestCase):
|
|
|
70
70
|
|
|
71
71
|
def test_theme_context_with_authenticated_client(self) -> None:
|
|
72
72
|
cookie_name = get_theme_cookie_name()
|
|
73
|
-
self.client.cookies[cookie_name] = '
|
|
73
|
+
self.client.cookies[cookie_name] = 'gruvbox-dark'
|
|
74
74
|
response = self.client.get('/')
|
|
75
75
|
self.assertEqual(response.status_code, 200)
|
|
76
76
|
|
|
@@ -40,9 +40,9 @@ class ThemeIntegrationTests(BaseTestCase):
|
|
|
40
40
|
self.assertEqual(response.status_code, 200)
|
|
41
41
|
|
|
42
42
|
def test_theme_media_integration(self) -> None:
|
|
43
|
-
theme = Theme(family=ThemeFamily.
|
|
43
|
+
theme = Theme(family=ThemeFamily.GRUVBOX, mode='dark')
|
|
44
44
|
stylesheet = theme.stylesheet
|
|
45
45
|
|
|
46
46
|
self.assertIn('django_spire/css/themes/', stylesheet)
|
|
47
|
-
self.assertIn('
|
|
47
|
+
self.assertIn('gruvbox', stylesheet)
|
|
48
48
|
self.assertIn('app-dark.css', stylesheet)
|
|
@@ -27,13 +27,13 @@ class ThemeModelTests(TestCase):
|
|
|
27
27
|
self.assertIn(family, Theme.FAMILY_DISPLAY_NAMES)
|
|
28
28
|
|
|
29
29
|
def test_theme_initialization_with_enums(self) -> None:
|
|
30
|
-
theme = Theme(family=ThemeFamily.
|
|
31
|
-
self.assertEqual(theme.family, ThemeFamily.
|
|
30
|
+
theme = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.DARK)
|
|
31
|
+
self.assertEqual(theme.family, ThemeFamily.GRUVBOX)
|
|
32
32
|
self.assertEqual(theme.mode, ThemeMode.DARK)
|
|
33
33
|
|
|
34
34
|
def test_theme_initialization_with_strings(self) -> None:
|
|
35
|
-
theme = Theme(family='
|
|
36
|
-
self.assertEqual(theme.family, ThemeFamily.
|
|
35
|
+
theme = Theme(family='gruvbox', mode='dark')
|
|
36
|
+
self.assertEqual(theme.family, ThemeFamily.GRUVBOX)
|
|
37
37
|
self.assertEqual(theme.mode, ThemeMode.DARK)
|
|
38
38
|
|
|
39
39
|
def test_theme_initialization_invalid_family(self) -> None:
|
|
@@ -43,16 +43,15 @@ class ThemeModelTests(TestCase):
|
|
|
43
43
|
|
|
44
44
|
def test_theme_initialization_invalid_mode(self) -> None:
|
|
45
45
|
with pytest.raises(ValueError) as ctx:
|
|
46
|
-
Theme(family='
|
|
46
|
+
Theme(family='gruvbox', mode='invalid-mode')
|
|
47
47
|
self.assertIn('Invalid theme mode', str(ctx.value))
|
|
48
48
|
|
|
49
49
|
def test_from_string_valid(self) -> None:
|
|
50
50
|
cases = [
|
|
51
51
|
('default-light', ThemeFamily.DEFAULT, ThemeMode.LIGHT),
|
|
52
|
-
('
|
|
52
|
+
('gruvbox-dark', ThemeFamily.GRUVBOX, ThemeMode.DARK),
|
|
53
53
|
('one-dark-light', ThemeFamily.ONE_DARK, ThemeMode.LIGHT),
|
|
54
54
|
('tokyo-night-dark', ThemeFamily.TOKYO_NIGHT, ThemeMode.DARK),
|
|
55
|
-
('oceanic-next-light', ThemeFamily.OCEANIC_NEXT, ThemeMode.LIGHT),
|
|
56
55
|
]
|
|
57
56
|
|
|
58
57
|
for string, family, mode in cases:
|
|
@@ -62,7 +61,7 @@ class ThemeModelTests(TestCase):
|
|
|
62
61
|
self.assertEqual(theme.mode, mode)
|
|
63
62
|
|
|
64
63
|
def test_from_string_empty_with_default(self) -> None:
|
|
65
|
-
default = Theme(family=ThemeFamily.
|
|
64
|
+
default = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.DARK)
|
|
66
65
|
theme = Theme.from_string('', default=default)
|
|
67
66
|
self.assertEqual(theme, default)
|
|
68
67
|
|
|
@@ -72,7 +71,7 @@ class ThemeModelTests(TestCase):
|
|
|
72
71
|
self.assertEqual(theme.mode, Theme.DEFAULT_MODE)
|
|
73
72
|
|
|
74
73
|
def test_from_string_invalid_with_default(self) -> None:
|
|
75
|
-
default = Theme(family=ThemeFamily.
|
|
74
|
+
default = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.DARK)
|
|
76
75
|
theme = Theme.from_string('invalid', default=default)
|
|
77
76
|
self.assertEqual(theme, default)
|
|
78
77
|
|
|
@@ -97,27 +96,27 @@ class ThemeModelTests(TestCase):
|
|
|
97
96
|
self.assertEqual(default.mode, Theme.DEFAULT_MODE)
|
|
98
97
|
|
|
99
98
|
def test_display_property(self) -> None:
|
|
100
|
-
theme = Theme(family=ThemeFamily.
|
|
101
|
-
self.assertEqual(theme.display, '
|
|
99
|
+
theme = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.DARK)
|
|
100
|
+
self.assertEqual(theme.display, 'Gruvbox - Dark')
|
|
102
101
|
|
|
103
102
|
theme = Theme(family=ThemeFamily.ONE_DARK, mode=ThemeMode.LIGHT)
|
|
104
103
|
self.assertEqual(theme.display, 'One Dark Pro - Light')
|
|
105
104
|
|
|
106
105
|
def test_family_display_property(self) -> None:
|
|
107
|
-
theme = Theme(family=ThemeFamily.
|
|
108
|
-
self.assertEqual(theme.family_display, '
|
|
106
|
+
theme = Theme(family=ThemeFamily.ONE_DARK, mode=ThemeMode.DARK)
|
|
107
|
+
self.assertEqual(theme.family_display, 'One Dark Pro')
|
|
109
108
|
|
|
110
109
|
def test_is_dark_property(self) -> None:
|
|
111
|
-
dark = Theme(family=ThemeFamily.
|
|
110
|
+
dark = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.DARK)
|
|
112
111
|
self.assertTrue(dark.is_dark)
|
|
113
112
|
|
|
114
|
-
light = Theme(family=ThemeFamily.
|
|
113
|
+
light = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.LIGHT)
|
|
115
114
|
self.assertFalse(light.is_dark)
|
|
116
115
|
|
|
117
116
|
def test_stylesheet_property(self) -> None:
|
|
118
117
|
cases = [
|
|
119
118
|
(ThemeFamily.DEFAULT, ThemeMode.LIGHT, 'django_spire/css/themes/default/app-light.css'),
|
|
120
|
-
(ThemeFamily.
|
|
119
|
+
(ThemeFamily.GRUVBOX, ThemeMode.DARK, 'django_spire/css/themes/gruvbox/app-dark.css'),
|
|
121
120
|
(ThemeFamily.ONE_DARK, ThemeMode.LIGHT, 'django_spire/css/themes/one-dark/app-light.css'),
|
|
122
121
|
(ThemeFamily.TOKYO_NIGHT, ThemeMode.DARK, 'django_spire/css/themes/tokyo-night/app-dark.css'),
|
|
123
122
|
]
|
|
@@ -130,7 +129,7 @@ class ThemeModelTests(TestCase):
|
|
|
130
129
|
def test_value_property(self) -> None:
|
|
131
130
|
cases = [
|
|
132
131
|
(ThemeFamily.DEFAULT, ThemeMode.LIGHT, 'default-light'),
|
|
133
|
-
(ThemeFamily.
|
|
132
|
+
(ThemeFamily.GRUVBOX, ThemeMode.DARK, 'gruvbox-dark'),
|
|
134
133
|
(ThemeFamily.ONE_DARK, ThemeMode.LIGHT, 'one-dark-light'),
|
|
135
134
|
(ThemeFamily.TOKYO_NIGHT, ThemeMode.DARK, 'tokyo-night-dark'),
|
|
136
135
|
]
|
|
@@ -141,7 +140,7 @@ class ThemeModelTests(TestCase):
|
|
|
141
140
|
self.assertEqual(theme.value, value)
|
|
142
141
|
|
|
143
142
|
def test_to_dict(self) -> None:
|
|
144
|
-
theme = Theme(family=ThemeFamily.
|
|
143
|
+
theme = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.DARK)
|
|
145
144
|
result = theme.to_dict()
|
|
146
145
|
|
|
147
146
|
keys = {
|
|
@@ -156,16 +155,16 @@ class ThemeModelTests(TestCase):
|
|
|
156
155
|
|
|
157
156
|
self.assertEqual(set(result.keys()), keys)
|
|
158
157
|
|
|
159
|
-
self.assertEqual(result['display'], '
|
|
160
|
-
self.assertEqual(result['family'], '
|
|
161
|
-
self.assertEqual(result['family_display'], '
|
|
162
|
-
self.assertEqual(result['full'], '
|
|
158
|
+
self.assertEqual(result['display'], 'Gruvbox - Dark')
|
|
159
|
+
self.assertEqual(result['family'], 'gruvbox')
|
|
160
|
+
self.assertEqual(result['family_display'], 'Gruvbox')
|
|
161
|
+
self.assertEqual(result['full'], 'gruvbox-dark')
|
|
163
162
|
self.assertTrue(result['is_dark'])
|
|
164
163
|
self.assertEqual(result['mode'], 'dark')
|
|
165
|
-
self.assertEqual(result['stylesheet'], 'django_spire/css/themes/
|
|
164
|
+
self.assertEqual(result['stylesheet'], 'django_spire/css/themes/gruvbox/app-dark.css')
|
|
166
165
|
|
|
167
166
|
def test_theme_immutability(self) -> None:
|
|
168
|
-
theme = Theme(family=ThemeFamily.
|
|
167
|
+
theme = Theme(family=ThemeFamily.GRUVBOX, mode=ThemeMode.DARK)
|
|
169
168
|
|
|
170
169
|
with pytest.raises(AttributeError):
|
|
171
170
|
theme.family = ThemeFamily.DEFAULT
|
|
@@ -50,7 +50,7 @@ class ThemeViewTests(TestCase):
|
|
|
50
50
|
def test_set_theme_success(self) -> None:
|
|
51
51
|
request = self.factory.post(
|
|
52
52
|
'/django_spire/theme/json/set_theme/',
|
|
53
|
-
data=json.dumps({'theme': '
|
|
53
|
+
data=json.dumps({'theme': 'gruvbox-dark'}),
|
|
54
54
|
content_type='application/json'
|
|
55
55
|
)
|
|
56
56
|
response = json_views.set_theme(request)
|
|
@@ -63,12 +63,12 @@ class ThemeViewTests(TestCase):
|
|
|
63
63
|
self.assertIn('theme', data)
|
|
64
64
|
|
|
65
65
|
data = data['theme']
|
|
66
|
-
self.assertEqual(data['family'], '
|
|
66
|
+
self.assertEqual(data['family'], 'gruvbox')
|
|
67
67
|
self.assertEqual(data['mode'], 'dark')
|
|
68
68
|
|
|
69
69
|
cookie_name = get_theme_cookie_name()
|
|
70
70
|
self.assertIn(cookie_name, response.cookies)
|
|
71
|
-
self.assertEqual(response.cookies[cookie_name].value, '
|
|
71
|
+
self.assertEqual(response.cookies[cookie_name].value, 'gruvbox-dark')
|
|
72
72
|
|
|
73
73
|
def test_set_theme_missing_theme(self) -> None:
|
|
74
74
|
request = self.factory.post(
|
|
@@ -103,7 +103,7 @@ class ThemeViewIntegrationTests(BaseTestCase):
|
|
|
103
103
|
def test_set_theme_with_authenticated_client(self) -> None:
|
|
104
104
|
response = self.client.post(
|
|
105
105
|
'/django_spire/theme/json/set_theme/',
|
|
106
|
-
data=json.dumps({'theme': '
|
|
106
|
+
data=json.dumps({'theme': 'gruvbox-dark'}),
|
|
107
107
|
content_type='application/json'
|
|
108
108
|
)
|
|
109
109
|
|