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,80 @@
1
+ # Generated by Django 4.2.19 on 2025-02-12 22:26
2
+
3
+ # Django
4
+ import django.db.models.deletion
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ("aa_mumble_quick_connect", "0001_initial"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.CreateModel(
16
+ name="Section",
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
+ (
28
+ "name",
29
+ models.CharField(
30
+ help_text="Name of the section", max_length=255, unique=True
31
+ ),
32
+ ),
33
+ ],
34
+ options={
35
+ "verbose_name": "Section",
36
+ "verbose_name_plural": "Sections",
37
+ "default_permissions": (),
38
+ },
39
+ ),
40
+ migrations.CreateModel(
41
+ name="MumbleLink",
42
+ fields=[
43
+ (
44
+ "id",
45
+ models.AutoField(
46
+ auto_created=True,
47
+ primary_key=True,
48
+ serialize=False,
49
+ verbose_name="ID",
50
+ ),
51
+ ),
52
+ (
53
+ "name",
54
+ models.CharField(
55
+ help_text="Name of the Mumble server/channel", max_length=255
56
+ ),
57
+ ),
58
+ (
59
+ "url",
60
+ models.URLField(help_text="URL to the channel", max_length=255),
61
+ ),
62
+ (
63
+ "section",
64
+ models.ForeignKey(
65
+ blank=True,
66
+ null=True,
67
+ on_delete=django.db.models.deletion.SET_NULL,
68
+ related_name="mumble_links",
69
+ to="aa_mumble_quick_connect.section",
70
+ verbose_name="Section",
71
+ ),
72
+ ),
73
+ ],
74
+ options={
75
+ "verbose_name": "Mumble Link",
76
+ "verbose_name_plural": "Mumble Links",
77
+ "default_permissions": (),
78
+ },
79
+ ),
80
+ ]
@@ -0,0 +1,19 @@
1
+ # Generated by Django 4.2.19 on 2025-02-12 23:15
2
+
3
+ # Django
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ("aa_mumble_quick_connect", "0002_section_mumblelink"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name="mumblelink",
16
+ name="url",
17
+ field=models.CharField(help_text="URL to the channel", max_length=255),
18
+ ),
19
+ ]
@@ -0,0 +1,26 @@
1
+ # Generated by Django 4.2.19 on 2025-02-12 23:22
2
+
3
+ # Django
4
+ from django.db import migrations, models
5
+
6
+ # AA Mumble Quick Connect
7
+ import aa_mumble_quick_connect.models
8
+
9
+
10
+ class Migration(migrations.Migration):
11
+
12
+ dependencies = [
13
+ ("aa_mumble_quick_connect", "0003_alter_mumblelink_url"),
14
+ ]
15
+
16
+ operations = [
17
+ migrations.AlterField(
18
+ model_name="mumblelink",
19
+ name="url",
20
+ field=models.CharField(
21
+ help_text="URL to the channel",
22
+ max_length=255,
23
+ validators=[aa_mumble_quick_connect.models.validate_mumble_url],
24
+ ),
25
+ ),
26
+ ]
@@ -0,0 +1,35 @@
1
+ # Generated by Django 4.2.19 on 2025-02-13 11:22
2
+
3
+ # Django
4
+ import django.db.models.deletion
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ("aa_mumble_quick_connect", "0004_alter_mumblelink_url"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.AlterField(
16
+ model_name="mumblelink",
17
+ name="name",
18
+ field=models.CharField(
19
+ help_text="Name of the Mumble channel", max_length=255
20
+ ),
21
+ ),
22
+ migrations.AlterField(
23
+ model_name="mumblelink",
24
+ name="section",
25
+ field=models.ForeignKey(
26
+ blank=True,
27
+ help_text="Section the Mumble channel belongs to. (Optional)",
28
+ null=True,
29
+ on_delete=django.db.models.deletion.SET_NULL,
30
+ related_name="mumble_links",
31
+ to="aa_mumble_quick_connect.section",
32
+ verbose_name="Section",
33
+ ),
34
+ ),
35
+ ]
File without changes
@@ -0,0 +1,100 @@
1
+ """
2
+ App Models
3
+ """
4
+
5
+ # Django
6
+ from django.conf import settings
7
+ from django.core.exceptions import ValidationError
8
+ from django.db import models
9
+ from django.utils.translation import gettext_lazy as _
10
+
11
+
12
+ def validate_mumble_url(url: str):
13
+ """
14
+ Validate Mumble URL
15
+
16
+ :param url:
17
+ :type url:
18
+ :return:
19
+ :rtype:
20
+ """
21
+
22
+ mumble_base_url = f"mumble://{settings.MUMBLE_URL}"
23
+
24
+ if not url.startswith(mumble_base_url):
25
+ raise ValidationError(
26
+ _(f"The Mumble channel URL must start with '{mumble_base_url}'")
27
+ )
28
+
29
+ return url
30
+
31
+
32
+ class General(models.Model):
33
+ """
34
+ Meta model for app permissions
35
+ """
36
+
37
+ class Meta:
38
+ """
39
+ Meta definitions
40
+ """
41
+
42
+ managed = False
43
+ default_permissions = ()
44
+ permissions = (("basic_access", _("Can access this app")),)
45
+
46
+
47
+ class Section(models.Model):
48
+ """
49
+ Section model
50
+ """
51
+
52
+ name = models.CharField(
53
+ max_length=255, unique=True, help_text=_("Name of the section")
54
+ )
55
+
56
+ class Meta: # pylint: disable=too-few-public-methods
57
+ """
58
+ Meta definitions
59
+ """
60
+
61
+ default_permissions = ()
62
+ verbose_name = _("Section")
63
+ verbose_name_plural = _("Sections")
64
+
65
+ def __str__(self) -> str:
66
+ return self.name
67
+
68
+
69
+ class MumbleLink(models.Model):
70
+ """
71
+ Mumble link model
72
+ """
73
+
74
+ section = models.ForeignKey(
75
+ to=Section,
76
+ on_delete=models.SET_NULL,
77
+ related_name="mumble_links",
78
+ verbose_name=_("Section"),
79
+ null=True,
80
+ blank=True,
81
+ help_text=_("Section the Mumble channel belongs to. (Optional)"),
82
+ )
83
+ name = models.CharField(max_length=255, help_text=_("Name of the Mumble channel"))
84
+ url = models.CharField(
85
+ max_length=255,
86
+ validators=[validate_mumble_url],
87
+ help_text=_("URL to the channel"),
88
+ )
89
+
90
+ class Meta: # pylint: disable=too-few-public-methods
91
+ """
92
+ Meta definitions
93
+ """
94
+
95
+ default_permissions = ()
96
+ verbose_name = _("Mumble Link")
97
+ verbose_name_plural = _("Mumble Links")
98
+
99
+ def __str__(self) -> str:
100
+ return self.name
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * Masonry PACKAGED v4.2.2
3
+ * Cascading grid layout library
4
+ * https://masonry.desandro.com
5
+ * MIT License
6
+ * by David DeSandro
7
+ */
8
+
9
+ !function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(t,r),delete n[r]),r.apply(this,e)}return this}},e.allOff=function(){delete this._events,delete this._onceEvents},t}),function(t,e){"function"==typeof define&&define.amd?define("get-size/get-size",e):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s=200==Math.round(t(o.width)),r.isBoxSizeOuter=s,i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function(e,i){return e[t](i)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["desandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e};var n=Array.prototype.slice;i.makeArray=function(t){if(Array.isArray(t))return t;if(null===t||void 0===t)return[];var e="object"==typeof t&&"number"==typeof t.length;return e?n.call(t):[t]},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t.parentNode&&t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),r=0;r<i.length;r++)o.push(i[r])}}),o},i.debounceMethod=function(t,e,i){i=i||100;var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i)}},i.docReady=function(t){var e=document.readyState;"complete"==e||"interactive"==e?setTimeout(t):document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var o=t.console;return i.htmlInit=function(e,n){i.docReady(function(){var r=i.toDashed(n),s="data-"+r,a=document.querySelectorAll("["+s+"]"),h=document.querySelectorAll(".js-"+r),u=i.makeArray(a).concat(i.makeArray(h)),d=s+"-options",l=t.jQuery;u.forEach(function(t){var i,r=t.getAttribute(s)||t.getAttribute(d);try{i=r&&JSON.parse(r)}catch(a){return void(o&&o.error("Error parsing "+s+" on "+t.className+": "+a))}var h=new e(t,i);l&&l.data(t,n,h)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var r=document.documentElement.style,s="string"==typeof r.transition?"transition":"WebkitTransition",a="string"==typeof r.transform?"transform":"WebkitTransform",h={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[s],u={transform:a,transition:s,transitionDuration:s+"Duration",transitionProperty:s+"Property",transitionDelay:s+"Delay"},d=n.prototype=Object.create(t.prototype);d.constructor=n,d._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},d.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},d.getSize=function(){this.size=e(this.element)},d.css=function(t){var e=this.element.style;for(var i in t){var n=u[i]||i;e[n]=t[i]}},d.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],r=parseFloat(n),s=parseFloat(o),a=this.layout.size;-1!=n.indexOf("%")&&(r=r/100*a.width),-1!=o.indexOf("%")&&(s=s/100*a.height),r=isNaN(r)?0:r,s=isNaN(s)?0:s,r-=e?a.paddingLeft:a.paddingRight,s-=i?a.paddingTop:a.paddingBottom,this.position.x=r,this.position.y=s},d.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",r=i?"left":"right",s=i?"right":"left",a=this.position.x+t[o];e[r]=this.getXValue(a),e[s]="";var h=n?"paddingTop":"paddingBottom",u=n?"top":"bottom",d=n?"bottom":"top",l=this.position.y+t[h];e[u]=this.getYValue(l),e[d]="",this.css(e),this.emitEvent("layout",[this])},d.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},d.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},d._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=t==this.position.x&&e==this.position.y;if(this.setPosition(t,e),o&&!this.isTransitioning)return void this.layoutPosition();var r=t-i,s=e-n,a={};a.transform=this.getTranslate(r,s),this.transition({to:a,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},d.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},d.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},d.moveTo=d._transitionTo,d.setPosition=function(t,e){this.position.x=parseFloat(t),this.position.y=parseFloat(e)},d._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},d.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var l="opacity,"+o(a);d.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:l,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(h,this,!1)}},d.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},d.onotransitionend=function(t){this.ontransitionend(t)};var c={"-webkit-transform":"transform"};d.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=c[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},d.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(h,this,!1),this.isTransitioning=!1},d._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var f={transitionProperty:"",transitionDuration:"",transitionDelay:""};return d.removeTransitionStyles=function(){this.css(f)},d.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},d.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},d.remove=function(){return s&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},d.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},d.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},d.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},d.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},d.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},d.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function(t,e,i,n,o){"use strict";function r(t,e){var i=n.getQueryElement(t);if(!i)return void(h&&h.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,u&&(this.$element=u(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++l;this.element.outlayerGUID=o,c[o]=this,this._create();var r=this._getOption("initLayout");r&&this.layout()}function s(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=m[n]||1;return i*o}var h=t.console,u=t.jQuery,d=function(){},l=0,c={};r.namespace="outlayer",r.Item=o,r.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var f=r.prototype;n.extend(f,e.prototype),f.option=function(t){n.extend(this.options,t)},f._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},r.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},f._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},f.reloadItems=function(){this.items=this._itemize(this.element.children)},f._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var r=e[o],s=new i(r,this);n.push(s)}return n},f._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},f.getItemElements=function(){return this.items.map(function(t){return t.element})},f.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},f._init=f.layout,f._resetLayout=function(){this.getSize()},f.getSize=function(){this.size=i(this.element)},f._getMeasurement=function(t,e){var n,o=this.options[t];o?("string"==typeof o?n=this.element.querySelector(o):o instanceof HTMLElement&&(n=o),this[t]=n?i(n)[e]:o):this[t]=0},f.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},f._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},f._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},f._getItemLayoutPosition=function(){return{x:0,y:0}},f._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},f.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},f._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},f._postLayout=function(){this.resizeContainer()},f.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},f._getContainerSize=d,f._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},f._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s==r&&i()}var o=this,r=e.length;if(!e||!r)return void i();var s=0;e.forEach(function(e){e.once(t,n)})},f.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),u)if(this.$element=this.$element||u(this.element),e){var o=u.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},f.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},f.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},f.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},f.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},f._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},f._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},f._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},f._manageStamp=d,f._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),r={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return r},f.handleEvent=n.handleEvent,f.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},f.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},f.onresize=function(){this.resize()},n.debounceMethod(r,"onresize",100),f.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},f.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},f.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},f.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},f.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},f.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},f.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},f.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},f.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},f.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},f.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},f.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},f.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete c[e],delete this.element.outlayerGUID,u&&u.removeData(this.element,this.constructor.namespace)},r.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&c[e]},r.create=function(t,e){var i=s(r);return i.defaults=n.extend({},r.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},r.compatOptions),i.namespace=t,i.data=r.data,i.Item=s(o),n.htmlInit(i,t),u&&u.bridget&&u.bridget(t,i),i};var m={ms:1,s:1e3};return r.Item=o,r}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function(t,e){var i=t.create("masonry");i.compatOptions.fitWidth="isFitWidth";var n=i.prototype;return n._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0,this.horizontalColIndex=0},n.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i});
@@ -0,0 +1,17 @@
1
+ {% extends 'allianceauth/base-bs5.html' %}
2
+
3
+ {% load i18n %}
4
+
5
+ {% block page_title %}
6
+ {% translate "Mumble Quick Connect" %}
7
+ {% endblock %}
8
+
9
+ {% block header_nav_brand %}
10
+ {% translate "Mumble Quick Connect" %}
11
+ {% endblock header_nav_brand %}
12
+
13
+ {% block content %}
14
+ <div class="aa-mumble-quick-connect">
15
+ {% block details %}{% endblock %}
16
+ </div>
17
+ {% endblock %}
@@ -0,0 +1,7 @@
1
+ {% load static %}
2
+
3
+ <script
4
+ src="{% static 'aa_mumble_quick_connect/libs/masonry-layout/4.2.2/masonry.pkgd.min.js' %}"
5
+ integrity="sha512-JRlcvSZAXT8+5SQQAvklXGJuxXTouyq8oIMaYERZQasB8SBDHZaUbeASsJWpk0UUrf89DP3/aefPPrlMR1h1yQ=="
6
+ crossorigin="anonymous"
7
+ ></script>
@@ -0,0 +1,30 @@
1
+ {% extends 'aa_mumble_quick_connect/base.html' %}
2
+
3
+ {% load i18n %}
4
+ {% load humanize %}
5
+
6
+ {% block details %}
7
+ {% if mumble_service_installed %}
8
+ {% if request.user.mumble %}
9
+ <div class="row mb-3" data-masonry='{"percentPosition": true }'>
10
+ {% include "aa_mumble_quick_connect/partials/channels-in-sections.html" %}
11
+ {% include "aa_mumble_quick_connect/partials/channels-without-sections.html" %}
12
+ </div>
13
+ {% else %}
14
+ <div class="alert alert-warning">
15
+ {% translate "You don't have your Mumble service set up. Please go to the services page and activate the Mumble service." %}
16
+ </div>
17
+ {% endif %}
18
+ {% else %}
19
+ <div class="alert alert-warning">
20
+ {% translate "Mumble service is not installed!" %}
21
+ </div>
22
+ {% endif %}
23
+ {% endblock %}
24
+
25
+ {% block extra_javascript %}
26
+ {% include "aa_mumble_quick_connect/bundles/masonry-layout-js.html" %}
27
+ {% endblock %}
28
+
29
+ {% block extra_css %}
30
+ {% endblock %}
@@ -0,0 +1,36 @@
1
+ {% load static %}
2
+ {% load aa_mumble_quick_connect %}
3
+
4
+ {% if channels_in_sections %}
5
+ {% for section in channels_in_sections %}
6
+ {% if section.mumble_links.count %}
7
+ <div class="col-sm-6 col-lg-4 mb-3">
8
+ <div class="card card-primary">
9
+ <div class="card-header">
10
+ <div class="card-title">{{ section.name }}</div>
11
+ </div>
12
+
13
+ <div class="card-body">
14
+ <ul class="list-group">
15
+ {% for channel in section.mumble_links.all %}
16
+ <li class="list-group-item">
17
+ <a class="btn btn-secondary w-100" href="{% aa_mumble_quick_connect_link channel.url request.user.mumble.username %}">
18
+ <img
19
+ src="{% static 'aa_mumble_quick_connect/images/mumble-icon.png' %}"
20
+ alt="Mumble"
21
+ height="32"
22
+ width="32"
23
+ style="margin: 15px;"
24
+ >
25
+
26
+ <span>{{ channel.name }}</span>
27
+ </a>
28
+ </li>
29
+ {% endfor %}
30
+ </ul>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ {% endif %}
35
+ {% endfor %}
36
+ {% endif %}
@@ -0,0 +1,35 @@
1
+ {% load i18n %}
2
+ {% load static %}
3
+ {% load aa_mumble_quick_connect %}
4
+
5
+ {% if channels_without_sections %}
6
+ <div class="col-sm-6 col-lg-4 mb-3">
7
+ <div class="card card-primary">
8
+ <div class="card-header">
9
+ <div class="card-title">
10
+ {% translate "Uncategorized" %}
11
+ </div>
12
+ </div>
13
+
14
+ <div class="card-body">
15
+ <ul class="list-group">
16
+ {% for channel in channels_without_sections %}
17
+ <li class="list-group-item">
18
+ <a class="btn btn-secondary w-100" href="{% aa_mumble_quick_connect_link channel.url request.user.mumble.username %}">
19
+ <img
20
+ src="{% static 'aa_mumble_quick_connect/images/mumble-icon.png' %}"
21
+ alt="Mumble"
22
+ height="32"
23
+ width="32"
24
+ style="margin: 15px;"
25
+ >
26
+
27
+ <span>{{ channel.name }}</span>
28
+ </a>
29
+ </li>
30
+ {% endfor %}
31
+ </ul>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ {% endif %}
@@ -0,0 +1,24 @@
1
+ """
2
+ Template tags for the aa-mumble-quick-connect app.
3
+ """
4
+
5
+ # Django
6
+ from django import template
7
+
8
+ register = template.Library()
9
+
10
+
11
+ @register.simple_tag
12
+ def aa_mumble_quick_connect_link(channel_url=None, username=None):
13
+ """
14
+ Create a mumble quick connect link
15
+
16
+ :param channel_url: Mumble channel URL
17
+ :type channel_url: str
18
+ :param username: Username
19
+ :type username: str
20
+ :return: Mumble quick connect link
21
+ :rtype: str
22
+ """
23
+
24
+ return channel_url.replace("mumble://", f"mumble://{username}@")
@@ -0,0 +1,3 @@
1
+ """
2
+ Initialize the tests
3
+ """
@@ -0,0 +1,159 @@
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
+ # AA Mumble Quick Connect
16
+ from aa_mumble_quick_connect.tests.utils import response_content_to_str
17
+
18
+
19
+ class TestAccess(TestCase):
20
+ """
21
+ Test access
22
+ """
23
+
24
+ @classmethod
25
+ def setUpClass(cls) -> None:
26
+ """
27
+ Set up groups and users
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,
44
+ character_name="William Riker",
45
+ permissions=["mumble.access_mumble"],
46
+ )
47
+
48
+ cls.user_1003 = create_fake_user(
49
+ character_id=1003,
50
+ character_name="Worf",
51
+ permissions=["aa_mumble_quick_connect.basic_access"],
52
+ )
53
+
54
+ cls.user_1004 = create_fake_user(
55
+ character_id=1004, character_name="Wesley Crusher"
56
+ )
57
+
58
+ cls.html_menu = f"""
59
+ <li class="d-flex flex-wrap m-2 p-2 pt-0 pb-0 mt-0 mb-0 me-0 pe-0">
60
+ <i class="nav-link fa-solid fa-headphones-simple fa-fw align-self-center me-3 active"></i>
61
+ <a class="nav-link flex-fill align-self-center me-auto active" href="{reverse('aa_mumble_quick_connect:index')}">
62
+ Mumble Quick Connect
63
+ </a>
64
+ </li>
65
+ """
66
+
67
+ cls.header_top = '<div class="navbar-brand">Mumble Quick Connect</div>'
68
+
69
+ @modify_settings(INSTALLED_APPS={"append": "allianceauth.services.modules.mumble"})
70
+ def test_access_for_user_with_permission(self):
71
+ """
72
+ Test access for user with permission
73
+
74
+ :return:
75
+ :rtype:
76
+ """
77
+
78
+ self.client.force_login(user=self.user_1001)
79
+
80
+ response = self.client.get(
81
+ path=reverse(viewname="aa_mumble_quick_connect:index")
82
+ )
83
+
84
+ self.assertEqual(first=response.status_code, second=HTTPStatus.OK)
85
+ self.assertInHTML(
86
+ needle=self.html_menu, haystack=response_content_to_str(response)
87
+ )
88
+ self.assertInHTML(
89
+ needle=self.header_top, haystack=response_content_to_str(response)
90
+ )
91
+
92
+ @modify_settings(INSTALLED_APPS={"append": "allianceauth.services.modules.mumble"})
93
+ def test_access_for_user_with_just_mumble_permission(self):
94
+ """
95
+ Test access for user with just mumble permission
96
+
97
+ :return:
98
+ :rtype:
99
+ """
100
+
101
+ self.client.force_login(user=self.user_1002)
102
+
103
+ response = self.client.get(
104
+ path=reverse(viewname="aa_mumble_quick_connect:index")
105
+ )
106
+
107
+ self.assertEqual(first=response.status_code, second=HTTPStatus.FOUND)
108
+ self.assertNotIn(
109
+ member=self.html_menu, container=response_content_to_str(response)
110
+ )
111
+ self.assertNotIn(
112
+ member=self.header_top, container=response_content_to_str(response)
113
+ )
114
+
115
+ @modify_settings(INSTALLED_APPS={"append": "allianceauth.services.modules.mumble"})
116
+ def test_access_for_user_with_just_aa_mumble_quick_connect_permission(self):
117
+ """
118
+ Test access for user with just aa_mumble_quick_connect permission
119
+
120
+ :return:
121
+ :rtype:
122
+ """
123
+
124
+ self.client.force_login(user=self.user_1003)
125
+
126
+ response = self.client.get(
127
+ path=reverse(viewname="aa_mumble_quick_connect:index")
128
+ )
129
+
130
+ self.assertEqual(first=response.status_code, second=HTTPStatus.FOUND)
131
+ self.assertNotIn(
132
+ member=self.html_menu, container=response_content_to_str(response)
133
+ )
134
+ self.assertNotIn(
135
+ member=self.header_top, container=response_content_to_str(response)
136
+ )
137
+
138
+ @modify_settings(INSTALLED_APPS={"append": "allianceauth.services.modules.mumble"})
139
+ def test_access_for_user_without_permission(self):
140
+ """
141
+ Test access for user without permission
142
+
143
+ :return:
144
+ :rtype:
145
+ """
146
+
147
+ self.client.force_login(user=self.user_1004)
148
+
149
+ response = self.client.get(
150
+ path=reverse(viewname="aa_mumble_quick_connect:index")
151
+ )
152
+
153
+ self.assertEqual(first=response.status_code, second=HTTPStatus.FOUND)
154
+ self.assertNotIn(
155
+ member=self.html_menu, container=response_content_to_str(response)
156
+ )
157
+ self.assertNotIn(
158
+ member=self.header_top, container=response_content_to_str(response)
159
+ )