with band a foreignkey with featuring a manytomanyfield empty option is present if the field isn t required form notrequiredbandform output form astable self assertinself emptyoption output def testrenderoptionsnotrequiredfieldself language file is inserted here subsequent language codes are used when the language code is not supported language with code 00 does not exist language files are case sensitive with band a foreignkey with featuring a manytomanyfield empty option is present if the field isn t required empty option isn t present if the field isn t required language file is inserted here subsequent language codes are used when the language code is not supported language with code 00 does not exist language files are case sensitive
from django import forms
from django.contrib import admin
from django.contrib.admin.widgets import AutocompleteSelect
from django.forms import ModelChoiceField
from django.test import TestCase, override_settings
from django.utils import translation

from .models import Album, Band, ReleaseEvent, VideoStream


class AlbumForm(forms.ModelForm):
    class Meta:
        model = Album
        fields = ["band", "featuring"]
        widgets = {
            "band": AutocompleteSelect(
                Album._meta.get_field("band"),
                admin.site,
                attrs={"class": "my-class"},
            ),
            "featuring": AutocompleteSelect(
                Album._meta.get_field("featuring"),
                admin.site,
            ),
        }


class NotRequiredBandForm(forms.Form):
    band = ModelChoiceField(
        queryset=Album.objects.all(),
        widget=AutocompleteSelect(
            Album._meta.get_field("band").remote_field, admin.site
        ),
        required=False,
    )


class RequiredBandForm(forms.Form):
    band = ModelChoiceField(
        queryset=Album.objects.all(),
        widget=AutocompleteSelect(
            Album._meta.get_field("band").remote_field, admin.site
        ),
        required=True,
    )


class VideoStreamForm(forms.ModelForm):
    class Meta:
        model = VideoStream
        fields = ["release_event"]
        widgets = {
            "release_event": AutocompleteSelect(
                VideoStream._meta.get_field("release_event"),
                admin.site,
            ),
        }


@override_settings(ROOT_URLCONF="admin_widgets.urls")
class AutocompleteMixinTests(TestCase):
    empty_option = '<option value=""></option>'
    maxDiff = 1000

    def test_build_attrs(self):
        form = AlbumForm()
        attrs = form["band"].field.widget.get_context(
            name="my_field", value=None, attrs={}
        )["widget"]["attrs"]
        self.assertEqual(
            attrs,
            {
                "class": "my-class admin-autocomplete",
                "data-ajax--cache": "true",
                "data-ajax--delay": 250,
                "data-ajax--type": "GET",
                "data-ajax--url": "/autocomplete/",
                "data-theme": "admin-autocomplete",
                "data-allow-clear": "false",
                "data-app-label": "admin_widgets",
                "data-field-name": "band",
                "data-model-name": "album",
                "data-placeholder": "",
                "lang": "en",
            },
        )

    def test_build_attrs_no_custom_class(self):
        form = AlbumForm()
        attrs = form["featuring"].field.widget.get_context(
            name="name", value=None, attrs={}
        )["widget"]["attrs"]
        self.assertEqual(attrs["class"], "admin-autocomplete")

    def test_build_attrs_not_required_field(self):
        form = NotRequiredBandForm()
        attrs = form["band"].field.widget.build_attrs({})
        self.assertJSONEqual(attrs["data-allow-clear"], True)

    def test_build_attrs_required_field(self):
        form = RequiredBandForm()
        attrs = form["band"].field.widget.build_attrs({})
        self.assertJSONEqual(attrs["data-allow-clear"], False)

    def test_get_url(self):
        rel = Album._meta.get_field("band")
        w = AutocompleteSelect(rel, admin.site)
        url = w.get_url()
        self.assertEqual(url, "/autocomplete/")

    def test_render_options(self):
        beatles = Band.objects.create(name="The Beatles", style="rock")
        who = Band.objects.create(name="The Who", style="rock")
        
        form = AlbumForm(initial={"band": beatles.uuid})
        output = form.as_table()
        selected_option = (
            '<option value="%s" selected>The Beatles</option>' % beatles.uuid
        )
        option = '<option value="%s">The Who</option>' % who.uuid
        self.assertIn(selected_option, output)
        self.assertNotIn(option, output)
        
        form = AlbumForm(initial={"featuring": [beatles.pk, who.pk]})
        output = form.as_table()
        selected_option = (
            '<option value="%s" selected>The Beatles</option>' % beatles.pk
        )
        option = '<option value="%s" selected>The Who</option>' % who.pk
        self.assertIn(selected_option, output)
        self.assertIn(option, output)

    def test_render_options_required_field(self):
        
        form = NotRequiredBandForm()
        output = form.as_table()
        self.assertIn(self.empty_option, output)

    def test_render_options_not_required_field(self):
        
        form = RequiredBandForm()
        output = form.as_table()
        self.assertNotIn(self.empty_option, output)

    def test_render_options_fk_as_pk(self):
        beatles = Band.objects.create(name="The Beatles", style="rock")
        rubber_soul = Album.objects.create(name="Rubber Soul", band=beatles)
        release_event = ReleaseEvent.objects.create(
            name="Test Target", album=rubber_soul
        )
        form = VideoStreamForm(initial={"release_event": release_event.pk})
        output = form.as_table()
        selected_option = (
            '<option value="%s" selected>Test Target</option>' % release_event.pk
        )
        self.assertIn(selected_option, output)

    def test_media(self):
        rel = Album._meta.get_field("band").remote_field
        base_files = (
            "admin/js/vendor/jquery/jquery.min.js",
            "admin/js/vendor/select2/select2.full.min.js",
            
            "admin/js/jquery.init.js",
            "admin/js/autocomplete.js",
        )
        languages = (
            ("de", "de"),
            
            
            ("de-at", "de"),
            ("de-ch-1901", "de"),
            ("en-latn-us", "en"),
            ("nl-nl-x-informal", "nl"),
            ("zh-hans-HK", "zh-CN"),
            
            ("00", None),
            
            ("sr-cyrl", "sr-Cyrl"),
            ("zh-hans", "zh-CN"),
            ("zh-hant", "zh-TW"),
            (None, None),
        )
        for lang, select_lang in languages:
            with self.subTest(lang=lang):
                if select_lang:
                    expected_files = (
                        base_files[:2]
                        + (("admin/js/vendor/select2/i18n/%s.js" % select_lang),)
                        + base_files[2:]
                    )
                else:
                    expected_files = base_files
                with translation.override(lang):
                    self.assertEqual(
                        AutocompleteSelect(rel, admin.site).media._js,
                        list(expected_files),
                    )