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.
Files changed (47) hide show
  1. aa_mumble_quick_connect/__init__.py +6 -0
  2. aa_mumble_quick_connect/admin.py +29 -0
  3. aa_mumble_quick_connect/apps.py +19 -0
  4. aa_mumble_quick_connect/auth_hooks.py +67 -0
  5. aa_mumble_quick_connect/dependency_checks.py +17 -0
  6. aa_mumble_quick_connect/locale/cs_CZ/LC_MESSAGES/django.po +78 -0
  7. aa_mumble_quick_connect/locale/de/LC_MESSAGES/django.mo +0 -0
  8. aa_mumble_quick_connect/locale/de/LC_MESSAGES/django.po +77 -0
  9. aa_mumble_quick_connect/locale/django.pot +79 -0
  10. aa_mumble_quick_connect/locale/es/LC_MESSAGES/django.po +78 -0
  11. aa_mumble_quick_connect/locale/fr_FR/LC_MESSAGES/django.po +78 -0
  12. aa_mumble_quick_connect/locale/it_IT/LC_MESSAGES/django.po +78 -0
  13. aa_mumble_quick_connect/locale/ja/LC_MESSAGES/django.po +78 -0
  14. aa_mumble_quick_connect/locale/ko_KR/LC_MESSAGES/django.po +78 -0
  15. aa_mumble_quick_connect/locale/nl_NL/LC_MESSAGES/django.po +78 -0
  16. aa_mumble_quick_connect/locale/pl_PL/LC_MESSAGES/django.po +78 -0
  17. aa_mumble_quick_connect/locale/ru/LC_MESSAGES/django.po +78 -0
  18. aa_mumble_quick_connect/locale/sk/LC_MESSAGES/django.po +78 -0
  19. aa_mumble_quick_connect/locale/uk/LC_MESSAGES/django.po +78 -0
  20. aa_mumble_quick_connect/locale/zh_Hans/LC_MESSAGES/django.po +78 -0
  21. aa_mumble_quick_connect/migrations/0001_initial.py +33 -0
  22. aa_mumble_quick_connect/migrations/0002_section_mumblelink.py +80 -0
  23. aa_mumble_quick_connect/migrations/0003_alter_mumblelink_url.py +19 -0
  24. aa_mumble_quick_connect/migrations/0004_alter_mumblelink_url.py +26 -0
  25. aa_mumble_quick_connect/migrations/0005_alter_mumblelink_name_alter_mumblelink_section.py +35 -0
  26. aa_mumble_quick_connect/migrations/__init__.py +0 -0
  27. aa_mumble_quick_connect/models.py +100 -0
  28. aa_mumble_quick_connect/static/aa_mumble_quick_connect/images/mumble-icon.png +0 -0
  29. aa_mumble_quick_connect/static/aa_mumble_quick_connect/libs/masonry-layout/4.2.2/masonry.pkgd.min.js +9 -0
  30. aa_mumble_quick_connect/templates/aa_mumble_quick_connect/base.html +17 -0
  31. aa_mumble_quick_connect/templates/aa_mumble_quick_connect/bundles/masonry-layout-js.html +7 -0
  32. aa_mumble_quick_connect/templates/aa_mumble_quick_connect/index.html +30 -0
  33. aa_mumble_quick_connect/templates/aa_mumble_quick_connect/partials/channels-in-sections.html +36 -0
  34. aa_mumble_quick_connect/templates/aa_mumble_quick_connect/partials/channels-without-sections.html +35 -0
  35. aa_mumble_quick_connect/templatetags/aa_mumble_quick_connect.py +24 -0
  36. aa_mumble_quick_connect/tests/__init__.py +3 -0
  37. aa_mumble_quick_connect/tests/test_access.py +159 -0
  38. aa_mumble_quick_connect/tests/test_auth_hooks.py +113 -0
  39. aa_mumble_quick_connect/tests/test_models.py +78 -0
  40. aa_mumble_quick_connect/tests/test_templatetags.py +35 -0
  41. aa_mumble_quick_connect/tests/utils.py +34 -0
  42. aa_mumble_quick_connect/urls.py +13 -0
  43. aa_mumble_quick_connect/views.py +37 -0
  44. aa_mumble_quick_connect-0.0.1.dist-info/METADATA +823 -0
  45. aa_mumble_quick_connect-0.0.1.dist-info/RECORD +47 -0
  46. aa_mumble_quick_connect-0.0.1.dist-info/WHEEL +4 -0
  47. 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
+ )