1from django import forms
2from django.contrib.auth import get_user_model
3from django.contrib.auth.models import Group
4from django.test import TestCase
5
6from wagtail.admin.filters import FilteredModelChoiceField
7from wagtail.tests.utils import WagtailTestUtils
8
9
10User = get_user_model()
11
12
13class TestFilteredModelChoiceField(TestCase, WagtailTestUtils):
14    def setUp(self):
15        self.musicians = Group.objects.create(name="Musicians")
16        self.actors = Group.objects.create(name="Actors")
17
18        self.david = self.create_user(
19            'david', 'david@example.com', 'kn1ghtr1der', first_name="David", last_name="Hasselhoff"
20        )
21        self.david.groups.set([self.musicians, self.actors])
22
23        self.kevin = self.create_user(
24            'kevin', 'kevin@example.com', '6degrees', first_name="Kevin", last_name="Bacon"
25        )
26        self.kevin.groups.set([self.actors])
27
28        self.morten = self.create_user(
29            'morten', 'morten@example.com', 't4ke0nm3', first_name="Morten", last_name="Harket"
30        )
31        self.morten.groups.set([self.musicians])
32
33    def test_with_relation(self):
34
35        class UserForm(forms.Form):
36            users = FilteredModelChoiceField(
37                queryset=User.objects.order_by(User.USERNAME_FIELD), filter_field='id_group', filter_accessor='groups'
38            )
39
40        form = UserForm()
41        html = str(form['users'])
42        expected_html = """
43            <select name="users" data-widget="filtered-select" data-filter-field="id_group" required id="id_users">
44                <option value="" selected>---------</option>
45                <option value="%(david)s" data-filter-value="%(musicians)s,%(actors)s">%(david_username)s</option>
46                <option value="%(kevin)s" data-filter-value="%(actors)s">%(kevin_username)s</option>
47                <option value="%(morten)s" data-filter-value="%(musicians)s">%(morten_username)s</option>
48            </select>
49        """ % {
50            'david': self.david.pk, 'kevin': self.kevin.pk, 'morten': self.morten.pk,
51            'musicians': self.musicians.pk, 'actors': self.actors.pk,
52            'david_username': self.david.get_username(), 'kevin_username': self.kevin.get_username(),
53            'morten_username': self.morten.get_username(),
54        }
55        self.assertHTMLEqual(html, expected_html)
56
57    def test_with_callable(self):
58
59        class UserForm(forms.Form):
60            users = FilteredModelChoiceField(
61                queryset=User.objects.order_by(User.USERNAME_FIELD), filter_field='id_group',
62                filter_accessor=lambda user: user.groups.all()
63            )
64
65        form = UserForm()
66        html = str(form['users'])
67        expected_html = """
68            <select name="users" data-widget="filtered-select" data-filter-field="id_group" required id="id_users">
69                <option value="" selected>---------</option>
70                <option value="%(david)s" data-filter-value="%(musicians)s,%(actors)s">%(david_username)s</option>
71                <option value="%(kevin)s" data-filter-value="%(actors)s">%(kevin_username)s</option>
72                <option value="%(morten)s" data-filter-value="%(musicians)s">%(morten_username)s</option>
73            </select>
74        """ % {
75            'david': self.david.pk, 'kevin': self.kevin.pk, 'morten': self.morten.pk,
76            'musicians': self.musicians.pk, 'actors': self.actors.pk,
77            'david_username': self.david.get_username(), 'kevin_username': self.kevin.get_username(),
78            'morten_username': self.morten.get_username(),
79        }
80        self.assertHTMLEqual(html, expected_html)
81