-
Notifications
You must be signed in to change notification settings - Fork 634
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #332 from reduxionist/per-queue-staff-membership
Per queue staff membership
- Loading branch information
Showing
9 changed files
with
361 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
helpdesk/migrations/0004_add_per_queue_staff_membership.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# -*- coding: utf-8 -*- | ||
from __future__ import unicode_literals | ||
|
||
from django.db import models, migrations | ||
from django.conf import settings | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
('helpdesk', '0003_initial_data_import'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='QueueMembership', | ||
fields=[ | ||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | ||
('queues', models.ManyToManyField(to='helpdesk.Queue', verbose_name='Authorized Queues')), | ||
('user', models.OneToOneField(verbose_name='User', to=settings.AUTH_USER_MODEL)), | ||
], | ||
options={ | ||
'verbose_name': 'Queue Membership', | ||
'verbose_name_plural': 'Queue Memberships', | ||
}, | ||
bases=(models.Model,), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from helpdesk.tests.ticket_submission import * | ||
from helpdesk.tests.public_actions import * | ||
from helpdesk.tests.navigation import * | ||
from helpdesk.tests.navigation import * | ||
from helpdesk.tests.per_queue_staff_membership import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
from django.contrib.auth import get_user_model | ||
from django.core.urlresolvers import reverse | ||
from django.test import TestCase | ||
from django.test.client import Client | ||
|
||
from helpdesk.models import Queue, Ticket, QueueMembership | ||
from helpdesk import settings | ||
|
||
|
||
class PerQueueStaffMembershipTestCase(TestCase): | ||
|
||
IDENTIFIERS = (1, 2) | ||
|
||
def setUp(self): | ||
""" | ||
Create user_1 with access to queue_1 containing 1 ticket | ||
and user_2 with access to queue_2 containing 2 tickets | ||
and superuser who should be able to access both queues | ||
""" | ||
settings.HELPDESK_ENABLE_PER_QUEUE_STAFF_MEMBERSHIP = True | ||
self.client = Client() | ||
User = get_user_model() | ||
|
||
self.superuser = User.objects.create( | ||
username='superuser', | ||
is_staff=True, | ||
is_superuser=True, | ||
) | ||
self.superuser.set_password('superuser') | ||
self.superuser.save() | ||
|
||
for identifier in self.IDENTIFIERS: | ||
queue = self.__dict__['queue_%d' % identifier] = Queue.objects.create( | ||
title='Queue %d' % identifier, | ||
slug='q%d' % identifier, | ||
) | ||
|
||
user = self.__dict__['user_%d' % identifier] = User.objects.create( | ||
username='User_%d' % identifier, | ||
is_staff=True, | ||
) | ||
user.set_password(identifier) | ||
user.save() | ||
|
||
queue_membership = self.__dict__['queue_membership_%d' % identifier] = QueueMembership.objects.create( | ||
user=user, | ||
) | ||
queue_membership.queues = (queue,) | ||
queue_membership.save() | ||
|
||
for ticket_number in range(1, identifier + 1): | ||
Ticket.objects.create( | ||
title='Unassigned Ticket %d in Queue %d' % (ticket_number, identifier), | ||
queue=queue, | ||
) | ||
Ticket.objects.create( | ||
title='Ticket %d in Queue %d Assigned to User_%d' % (ticket_number, identifier, identifier), | ||
queue=queue, | ||
assigned_to=user, | ||
) | ||
|
||
def test_dashboard_ticket_counts(self): | ||
""" | ||
Check that the regular users' dashboard only shows 1 of the 2 queues, | ||
that user_1 only sees a total of 1 ticket, that user_2 sees a total of 2 | ||
tickets, but that the superuser's dashboard shows all queues and tickets. | ||
""" | ||
|
||
# Regular users | ||
for identifier in self.IDENTIFIERS: | ||
self.client.login(username='User_%d' % identifier, password=identifier) | ||
response = self.client.get(reverse('helpdesk_dashboard')) | ||
self.assertEqual( | ||
len(response.context['unassigned_tickets']), | ||
identifier, | ||
'Unassigned tickets were not properly limited by queue membership' | ||
) | ||
self.assertEqual( | ||
len(response.context['dash_tickets']), | ||
1, | ||
'The queues in dash_tickets were not properly limited by queue membership' | ||
) | ||
self.assertEqual( | ||
response.context['dash_tickets'][0]['open'], | ||
identifier * 2, | ||
'The tickets in dash_tickets were not properly limited by queue membership' | ||
) | ||
self.assertEqual( | ||
response.context['basic_ticket_stats']['open_ticket_stats'][0][1], | ||
identifier * 2, | ||
'Basic ticket stats were not properly limited by queue membership' | ||
) | ||
|
||
# Superuser | ||
self.client.login(username='superuser', password='superuser') | ||
response = self.client.get(reverse('helpdesk_dashboard')) | ||
self.assertEqual( | ||
len(response.context['unassigned_tickets']), | ||
3, | ||
'Unassigned tickets were limited by queue membership for a superuser' | ||
) | ||
self.assertEqual( | ||
len(response.context['dash_tickets']), | ||
2, | ||
'The queues in dash_tickets were limited by queue membership for a superuser' | ||
) | ||
self.assertEqual( | ||
response.context['dash_tickets'][0]['open'] + | ||
response.context['dash_tickets'][1]['open'], | ||
6, | ||
'The tickets in dash_tickets were limited by queue membership for a superuser' | ||
) | ||
self.assertEqual( | ||
response.context['basic_ticket_stats']['open_ticket_stats'][0][1] + | ||
response.context['basic_ticket_stats']['open_ticket_stats'][1][1], | ||
6, | ||
'Basic ticket stats were limited by queue membership for a superuser' | ||
) | ||
|
||
def test_ticket_list_per_queue_user_restrictions(self): | ||
""" | ||
Ensure that while the superuser can list all tickets, user_1 can only | ||
list the 1 ticket in his queue and user_2 can list only the 2 tickets | ||
in his queue. | ||
""" | ||
# Regular users | ||
for identifier in self.IDENTIFIERS: | ||
self.client.login(username='User_%d' % identifier, password=identifier) | ||
response = self.client.get(reverse('helpdesk_list')) | ||
self.assertEqual( | ||
len(response.context['tickets']), | ||
identifier * 2, | ||
'Ticket list was not properly limited by queue membership' | ||
) | ||
self.assertEqual( | ||
len(response.context['queue_choices']), | ||
1, | ||
'Queue choices were not properly limited by queue membership' | ||
) | ||
self.assertEqual( | ||
response.context['queue_choices'][0], | ||
Queue.objects.get(title="Queue %d" % identifier), | ||
'Queue choices were not properly limited by queue membership' | ||
) | ||
|
||
# Superuser | ||
self.client.login(username='superuser', password='superuser') | ||
response = self.client.get(reverse('helpdesk_list')) | ||
self.assertEqual( | ||
len(response.context['tickets']), | ||
6, | ||
'Ticket list was limited by queue membership for a superuser' | ||
) | ||
|
||
def test_ticket_reports_per_queue_user_restrictions(self): | ||
""" | ||
Ensure that while the superuser can generate reports on all queues and | ||
tickets, user_1 can only generate reports for queue 1 and user_2 can | ||
only do so for queue 2 | ||
""" | ||
# Regular users | ||
for identifier in self.IDENTIFIERS: | ||
self.client.login(username='User_%d' % identifier, password=identifier) | ||
response = self.client.get( | ||
reverse('helpdesk_run_report', kwargs={'report': 'userqueue'}) | ||
) | ||
# Only two columns of data should be present: ticket counts for | ||
# unassigned and this user only | ||
self.assertEqual( | ||
len(response.context['data']), | ||
2, | ||
'Queues in report were not properly limited by queue membership' | ||
) | ||
# Each user should see a total number of tickets equal to twice their ID | ||
self.assertEqual( | ||
sum([sum(user_tickets[1:]) for user_tickets in response.context['data']]), | ||
identifier * 2, | ||
'Tickets in report were not properly limited by queue membership' | ||
) | ||
# Each user should only be able to pick 1 queue | ||
self.assertEqual( | ||
len(response.context['headings']), | ||
2, | ||
'Queue choices were not properly limited by queue membership' | ||
) | ||
# The queue each user can pick should be the queue named after their ID | ||
self.assertEqual( | ||
response.context['headings'][1], | ||
"Queue %d" % identifier, | ||
'Queue choices were not properly limited by queue membership' | ||
) | ||
|
||
# Superuser | ||
self.client.login(username='superuser', password='superuser') | ||
response = self.client.get( | ||
reverse('helpdesk_run_report', kwargs={'report': 'userqueue'}) | ||
) | ||
# Superuser should see ticket counts for all two queues, which includes | ||
# three columns: unassigned and both user 1 and user 2 | ||
self.assertEqual( | ||
len(response.context['data'][0]), | ||
3, | ||
'Queues in report were improperly limited by queue membership for a superuser' | ||
) | ||
# Superuser should see the total ticket count of three tickets | ||
self.assertEqual( | ||
sum([sum(user_tickets[1:]) for user_tickets in response.context['data']]), | ||
6, | ||
'Tickets in report were improperly limited by queue membership for a superuser' | ||
) | ||
self.assertEqual( | ||
len(response.context['headings']), | ||
3, | ||
'Queue choices were improperly limited by queue membership for a superuser' | ||
) | ||
|
||
def tearDown(self): | ||
""" | ||
Don't interfere with subsequent tests that do not expect this setting | ||
""" | ||
settings.HELPDESK_ENABLE_PER_QUEUE_STAFF_MEMBERSHIP = False |
Oops, something went wrong.