aa-mumble-quick-connect 0.0.1__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.
- aa_mumble_quick_connect/__init__.py +6 -0
- aa_mumble_quick_connect/admin.py +29 -0
- aa_mumble_quick_connect/apps.py +19 -0
- aa_mumble_quick_connect/auth_hooks.py +67 -0
- aa_mumble_quick_connect/dependency_checks.py +17 -0
- aa_mumble_quick_connect/locale/cs_CZ/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/de/LC_MESSAGES/django.mo +0 -0
- aa_mumble_quick_connect/locale/de/LC_MESSAGES/django.po +77 -0
- aa_mumble_quick_connect/locale/django.pot +79 -0
- aa_mumble_quick_connect/locale/es/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/fr_FR/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/it_IT/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/ja/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/ko_KR/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/nl_NL/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/pl_PL/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/ru/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/sk/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/uk/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/locale/zh_Hans/LC_MESSAGES/django.po +78 -0
- aa_mumble_quick_connect/migrations/0001_initial.py +33 -0
- aa_mumble_quick_connect/migrations/0002_section_mumblelink.py +80 -0
- aa_mumble_quick_connect/migrations/0003_alter_mumblelink_url.py +19 -0
- aa_mumble_quick_connect/migrations/0004_alter_mumblelink_url.py +26 -0
- aa_mumble_quick_connect/migrations/0005_alter_mumblelink_name_alter_mumblelink_section.py +35 -0
- aa_mumble_quick_connect/migrations/__init__.py +0 -0
- aa_mumble_quick_connect/models.py +100 -0
- aa_mumble_quick_connect/static/aa_mumble_quick_connect/images/mumble-icon.png +0 -0
- aa_mumble_quick_connect/static/aa_mumble_quick_connect/libs/masonry-layout/4.2.2/masonry.pkgd.min.js +9 -0
- aa_mumble_quick_connect/templates/aa_mumble_quick_connect/base.html +17 -0
- aa_mumble_quick_connect/templates/aa_mumble_quick_connect/bundles/masonry-layout-js.html +7 -0
- aa_mumble_quick_connect/templates/aa_mumble_quick_connect/index.html +30 -0
- aa_mumble_quick_connect/templates/aa_mumble_quick_connect/partials/channels-in-sections.html +36 -0
- aa_mumble_quick_connect/templates/aa_mumble_quick_connect/partials/channels-without-sections.html +35 -0
- aa_mumble_quick_connect/templatetags/aa_mumble_quick_connect.py +24 -0
- aa_mumble_quick_connect/tests/__init__.py +3 -0
- aa_mumble_quick_connect/tests/test_access.py +159 -0
- aa_mumble_quick_connect/tests/test_auth_hooks.py +113 -0
- aa_mumble_quick_connect/tests/test_models.py +78 -0
- aa_mumble_quick_connect/tests/test_templatetags.py +35 -0
- aa_mumble_quick_connect/tests/utils.py +34 -0
- aa_mumble_quick_connect/urls.py +13 -0
- aa_mumble_quick_connect/views.py +37 -0
- aa_mumble_quick_connect-0.0.1.dist-info/METADATA +823 -0
- aa_mumble_quick_connect-0.0.1.dist-info/RECORD +47 -0
- aa_mumble_quick_connect-0.0.1.dist-info/WHEEL +4 -0
- aa_mumble_quick_connect-0.0.1.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test auth_hooks
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Standard Library
|
|
6
|
+
from http import HTTPStatus
|
|
7
|
+
|
|
8
|
+
# Django
|
|
9
|
+
from django.test import TestCase, modify_settings
|
|
10
|
+
from django.urls import reverse
|
|
11
|
+
|
|
12
|
+
# Alliance Auth (External Libs)
|
|
13
|
+
from app_utils.testing import create_fake_user
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestHooks(TestCase):
|
|
17
|
+
"""
|
|
18
|
+
Test the app hook into allianceauth
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def setUpClass(cls) -> None:
|
|
23
|
+
"""
|
|
24
|
+
Set up groups and users
|
|
25
|
+
|
|
26
|
+
:return:
|
|
27
|
+
:rtype:
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
super().setUpClass()
|
|
31
|
+
|
|
32
|
+
# User
|
|
33
|
+
cls.user_1001 = create_fake_user(
|
|
34
|
+
character_id=1001,
|
|
35
|
+
character_name="Jean Luc Picard",
|
|
36
|
+
permissions=[
|
|
37
|
+
"aa_mumble_quick_connect.basic_access",
|
|
38
|
+
"mumble.access_mumble",
|
|
39
|
+
],
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
cls.user_1002 = create_fake_user(
|
|
43
|
+
character_id=1002, character_name="Wesley Crusher"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
cls.html_menu = f"""
|
|
47
|
+
<li class="d-flex flex-wrap m-2 p-2 pt-0 pb-0 mt-0 mb-0 me-0 pe-0">
|
|
48
|
+
<i class="nav-link fa-solid fa-headphones-simple fa-fw align-self-center me-3 "></i>
|
|
49
|
+
<a class="nav-link flex-fill align-self-center me-auto" href="{reverse('aa_mumble_quick_connect:index')}">
|
|
50
|
+
Mumble Quick Connect
|
|
51
|
+
</a>
|
|
52
|
+
</li>
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def login(self, user):
|
|
56
|
+
"""
|
|
57
|
+
Login a test user
|
|
58
|
+
|
|
59
|
+
:param user:
|
|
60
|
+
:type user:
|
|
61
|
+
:return:
|
|
62
|
+
:rtype:
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
self.client.force_login(user=user)
|
|
66
|
+
|
|
67
|
+
@modify_settings(INSTALLED_APPS={"append": "allianceauth.services.modules.mumble"})
|
|
68
|
+
def test_render_hook_success(self):
|
|
69
|
+
"""
|
|
70
|
+
Test should show the link to the app for users with the correct permissions
|
|
71
|
+
|
|
72
|
+
:return:
|
|
73
|
+
:rtype:
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
self.login(user=self.user_1001)
|
|
77
|
+
|
|
78
|
+
response = self.client.get(path=reverse(viewname="authentication:dashboard"))
|
|
79
|
+
|
|
80
|
+
self.assertEqual(first=response.status_code, second=HTTPStatus.OK)
|
|
81
|
+
self.assertContains(response=response, text=self.html_menu, html=True)
|
|
82
|
+
|
|
83
|
+
@modify_settings(INSTALLED_APPS={"append": "allianceauth.services.modules.mumble"})
|
|
84
|
+
def test_render_hook_fail(self):
|
|
85
|
+
"""
|
|
86
|
+
Test should not show the link to the app for users without the correct permissions
|
|
87
|
+
|
|
88
|
+
:return:
|
|
89
|
+
:rtype:
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
self.login(user=self.user_1002)
|
|
93
|
+
|
|
94
|
+
response = self.client.get(path=reverse(viewname="authentication:dashboard"))
|
|
95
|
+
|
|
96
|
+
self.assertEqual(first=response.status_code, second=HTTPStatus.OK)
|
|
97
|
+
self.assertNotContains(response=response, text=self.html_menu, html=True)
|
|
98
|
+
|
|
99
|
+
@modify_settings(INSTALLED_APPS={"remove": "allianceauth.services.modules.mumble"})
|
|
100
|
+
def test_mumble_service_not_installed(self):
|
|
101
|
+
"""
|
|
102
|
+
Test should not show the link to the app when the Mumble service is not installed
|
|
103
|
+
|
|
104
|
+
:return:
|
|
105
|
+
:rtype:
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
self.login(user=self.user_1001)
|
|
109
|
+
|
|
110
|
+
response = self.client.get(path=reverse(viewname="authentication:dashboard"))
|
|
111
|
+
|
|
112
|
+
self.assertEqual(first=response.status_code, second=HTTPStatus.OK)
|
|
113
|
+
self.assertNotContains(response=response, text=self.html_menu, html=True)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Django
|
|
2
|
+
from django.conf import settings
|
|
3
|
+
from django.core.exceptions import ValidationError
|
|
4
|
+
from django.test import TestCase, override_settings
|
|
5
|
+
|
|
6
|
+
# AA Mumble Quick Connect
|
|
7
|
+
from aa_mumble_quick_connect.models import MumbleLink, Section, validate_mumble_url
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestSection(TestCase):
|
|
11
|
+
"""
|
|
12
|
+
Tests for the `Section` model
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def test_model_string_names(self):
|
|
16
|
+
"""
|
|
17
|
+
Test model string name
|
|
18
|
+
|
|
19
|
+
:return:
|
|
20
|
+
:rtype:
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
section = Section(name="Foobar")
|
|
24
|
+
section.save()
|
|
25
|
+
expected_name = section.name
|
|
26
|
+
self.assertEqual(first=str(section), second=expected_name)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TestMumbleLink(TestCase):
|
|
30
|
+
"""
|
|
31
|
+
Tests for the `MumbleLink` model
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def test_model_string_names(self):
|
|
35
|
+
"""
|
|
36
|
+
Test model string name
|
|
37
|
+
|
|
38
|
+
:return:
|
|
39
|
+
:rtype:
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
section = MumbleLink(name="Foobar")
|
|
43
|
+
section.save()
|
|
44
|
+
expected_name = section.name
|
|
45
|
+
self.assertEqual(first=str(section), second=expected_name)
|
|
46
|
+
|
|
47
|
+
@override_settings(MUMBLE_URL="mumble.example.com")
|
|
48
|
+
def test_validate_mumble_url_with_valid_url(self):
|
|
49
|
+
"""
|
|
50
|
+
Test validate Mumble URL with valid URL
|
|
51
|
+
|
|
52
|
+
:return:
|
|
53
|
+
:rtype:
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
expected_mumble_base_url = f"mumble://{settings.MUMBLE_URL}"
|
|
57
|
+
|
|
58
|
+
self.assertEqual(
|
|
59
|
+
first=validate_mumble_url(url=f"mumble://{settings.MUMBLE_URL}"),
|
|
60
|
+
second=expected_mumble_base_url,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@override_settings(MUMBLE_URL="mumble.example.com")
|
|
64
|
+
def test_validate_mumble_url_with_invalid_url(self):
|
|
65
|
+
"""
|
|
66
|
+
Test validate Mumble URL with invalid URL
|
|
67
|
+
|
|
68
|
+
:return:
|
|
69
|
+
:rtype:
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
expected_mumble_base_url = f"mumble://{settings.MUMBLE_URL}"
|
|
73
|
+
|
|
74
|
+
with self.assertRaisesMessage(
|
|
75
|
+
expected_exception=ValidationError,
|
|
76
|
+
expected_message=f"The Mumble channel URL must start with '{expected_mumble_base_url}'",
|
|
77
|
+
):
|
|
78
|
+
validate_mumble_url("http://example.com")
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test the apps' template tags
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Django
|
|
6
|
+
from django.template import Context, Template
|
|
7
|
+
from django.test import TestCase, override_settings
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestQuickConnectLinkTemplateTag(TestCase):
|
|
11
|
+
"""
|
|
12
|
+
Test aa_mumble_quick_connect template tag
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@override_settings(DEBUG=False)
|
|
16
|
+
def test_aa_mumble_quick_connect(self) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Test aa_mumble_quick_connect template tag
|
|
19
|
+
|
|
20
|
+
:return:
|
|
21
|
+
:rtype:
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
context = Context({"mumble_link": "mumble://example.com", "username": "foobar"})
|
|
25
|
+
template_to_render = Template(
|
|
26
|
+
template_string=(
|
|
27
|
+
"{% load aa_mumble_quick_connect %}"
|
|
28
|
+
"{% aa_mumble_quick_connect_link mumble_link username %}"
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
rendered_template = template_to_render.render(context=context)
|
|
33
|
+
expected = "mumble://foobar@example.com"
|
|
34
|
+
|
|
35
|
+
self.assertEqual(first=rendered_template, second=expected)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helper for our tests
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Django
|
|
6
|
+
from django.core.handlers.wsgi import WSGIRequest
|
|
7
|
+
from django.template import Context, Template
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def render_template(string, context=None):
|
|
11
|
+
"""
|
|
12
|
+
Helper to render templates
|
|
13
|
+
:param string:
|
|
14
|
+
:param context:
|
|
15
|
+
:return:
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
context = context or {}
|
|
19
|
+
context = Context(dict_=context)
|
|
20
|
+
|
|
21
|
+
return Template(template_string=string).render(context=context)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def response_content_to_str(response: WSGIRequest) -> str:
|
|
25
|
+
"""
|
|
26
|
+
Return the content of a WSGIRequest response as string
|
|
27
|
+
|
|
28
|
+
:param response:
|
|
29
|
+
:type response:
|
|
30
|
+
:return:
|
|
31
|
+
:rtype:
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
return response.content.decode(response.charset)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""App URLs"""
|
|
2
|
+
|
|
3
|
+
# Django
|
|
4
|
+
from django.urls import path
|
|
5
|
+
|
|
6
|
+
# AA Mumble Quick Connect
|
|
7
|
+
from aa_mumble_quick_connect import views
|
|
8
|
+
|
|
9
|
+
app_name: str = "aa_mumble_quick_connect"
|
|
10
|
+
|
|
11
|
+
urlpatterns = [
|
|
12
|
+
path(route="", view=views.index, name="index"),
|
|
13
|
+
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""App Views"""
|
|
2
|
+
|
|
3
|
+
# Django
|
|
4
|
+
from django.contrib.auth.decorators import login_required, permission_required
|
|
5
|
+
from django.core.handlers.wsgi import WSGIRequest
|
|
6
|
+
from django.http import HttpResponse
|
|
7
|
+
from django.shortcuts import render
|
|
8
|
+
|
|
9
|
+
# AA Mumble Quick Connect
|
|
10
|
+
from aa_mumble_quick_connect.dependency_checks import mumble_service_installed
|
|
11
|
+
from aa_mumble_quick_connect.models import MumbleLink, Section
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@login_required
|
|
15
|
+
@permission_required("aa_mumble_quick_connect.basic_access")
|
|
16
|
+
@permission_required("mumble.access_mumble")
|
|
17
|
+
def index(request: WSGIRequest) -> HttpResponse:
|
|
18
|
+
"""
|
|
19
|
+
Index view
|
|
20
|
+
:param request:
|
|
21
|
+
:return:
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
channels_in_sections = Section.objects.prefetch_related("mumble_links").all()
|
|
25
|
+
channels_without_sections = MumbleLink.objects.filter(section__isnull=True)
|
|
26
|
+
|
|
27
|
+
context = {
|
|
28
|
+
"mumble_service_installed": mumble_service_installed(),
|
|
29
|
+
"channels_in_sections": channels_in_sections,
|
|
30
|
+
"channels_without_sections": channels_without_sections,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return render(
|
|
34
|
+
request=request,
|
|
35
|
+
template_name="aa_mumble_quick_connect/index.html",
|
|
36
|
+
context=context,
|
|
37
|
+
)
|