class TestSelect2Mixin: url = reverse("select2_widget") form = forms.AlbumSelect2WidgetForm() multiple_form = forms.AlbumSelect2MultipleWidgetForm() widget_cls = Select2Widget def test_initial_data(self, genres): genre = genres[0] form = self.form.__class__(initial={"primary_genre": genre.pk}) assert str(genre) in form.as_p() def test_initial_form_class(self): widget = self.widget_cls(attrs={"class": "my-class"}) assert "my-class" in widget.render("name", None) assert "django-select2" in widget.render("name", None) @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) def test_lang_attr(self, code, name): translation.activate(code) widget = self.widget_cls() assert f'lang="{name}"' in widget.render("name", None) def test_allow_clear(self, db): required_field = self.form.fields["artist"] assert required_field.required is True assert 'data-allow-clear="true"' not in required_field.widget.render( "artist", None) assert 'data-allow-clear="false"' in required_field.widget.render( "artist", None) assert '<option value=""></option>' not in required_field.widget.render( "artist", None) not_required_field = self.form.fields["primary_genre"] assert not_required_field.required is False assert 'data-allow-clear="true"' in not_required_field.widget.render( "primary_genre", None) assert 'data-allow-clear="false"' not in not_required_field.widget.render( "primary_genre", None) assert "data-placeholder" in not_required_field.widget.render( "primary_genre", None) assert '<option value=""></option>' in not_required_field.widget.render( "primary_genre", None) def test_no_js_error(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): error = driver.find_element_by_xpath("//body[@JSError]") pytest.fail(error.get_attribute("JSError")) def test_selecting(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): driver.find_element_by_css_selector(".select2-results") elem = driver.find_element_by_css_selector(".select2-selection") elem.click() results = driver.find_element_by_css_selector(".select2-results") assert results.is_displayed() is True elem = results.find_element_by_css_selector(".select2-results__option") elem.click() with pytest.raises(NoSuchElementException): error = driver.find_element_by_xpath("//body[@JSError]") pytest.fail(error.get_attribute("JSError")) def test_data_url(self): with pytest.raises(ValueError): HeavySelect2Widget() widget = HeavySelect2Widget(data_url="/foo/bar") assert widget.get_url() == "/foo/bar" def test_empty_option(self, db): # Empty options is only required for single selects # https://select2.github.io/options.html#allowClear single_select = self.form.fields["primary_genre"] assert single_select.required is False assert '<option value=""></option>' in single_select.widget.render( "primary_genre", None) multiple_select = self.multiple_form.fields["featured_artists"] assert multiple_select.required is False assert multiple_select.widget.allow_multiple_selected output = multiple_select.widget.render("featured_artists", None) assert '<option value=""></option>' not in output assert 'data-placeholder=""' in output def test_i18n(self): translation.activate("de") assert tuple(Select2Widget().media._js) == ( f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js", f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/i18n/de.js", "django_select2/django_select2.js", ) translation.activate("en") assert tuple(Select2Widget().media._js) == ( f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js", f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/i18n/en.js", "django_select2/django_select2.js", ) translation.activate("00") assert tuple(Select2Widget().media._js) == ( f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js", "django_select2/django_select2.js", ) translation.activate("sr-cyrl") assert tuple(Select2Widget().media._js) == ( f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js", f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/i18n/sr-Cyrl.js", "django_select2/django_select2.js", ) pytest.importorskip("django", minversion="2.0.4") translation.activate("zh-hans") assert tuple(Select2Widget().media._js) == ( f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js", f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/i18n/zh-CN.js", "django_select2/django_select2.js", ) translation.activate("zh-hant") assert tuple(Select2Widget().media._js) == ( f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js", f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/i18n/zh-TW.js", "django_select2/django_select2.js", ) def test_theme_setting(self, settings): settings.SELECT2_THEME = "classic" widget = self.widget_cls() assert 'data-theme="classic"' in widget.render("name", None)
class TestHeavySelect2Mixin(TestSelect2Mixin): url = reverse("heavy_select2_widget") form = forms.HeavySelect2WidgetForm(initial={"primary_genre": 1}) widget_cls = HeavySelect2Widget def test_initial_data(self): assert "One" in self.form.as_p() def test_initial_form_class(self): widget = self.widget_cls(data_view="heavy_data_1", attrs={"class": "my-class"}) assert "my-class" in widget.render("name", None) assert "django-select2" in widget.render("name", None) assert "django-select2-heavy" in widget.render("name", None), widget.render( "name", None) @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) def test_lang_attr(self, code, name): translation.activate(code) widget = self.widget_cls(data_view="heavy_data_1") assert f'lang="{name}"' in widget.render("name", None) def test_selected_option(self, db): not_required_field = self.form.fields["primary_genre"] assert not_required_field.required is False assert ('<option value="1" selected="selected">One</option>' in not_required_field.widget.render("primary_genre", 1) or '<option value="1" selected>One</option>' in not_required_field.widget.render( "primary_genre", 1)), (not_required_field.widget.render( "primary_genre", 1)) def test_many_selected_option(self, db, genres): field = HeavySelect2MultipleWidgetForm().fields["genres"] field.widget.choices = NUMBER_CHOICES widget_output = field.widget.render("genres", [1, 2]) selected_option = ( '<option value="{pk}" selected="selected">{value}</option>'.format( pk=1, value="One")) selected_option_a = '<option value="{pk}" selected>{value}</option>'.format( pk=1, value="One") selected_option2 = ( '<option value="{pk}" selected="selected">{value}</option>'.format( pk=2, value="Two")) selected_option2a = '<option value="{pk}" selected>{value}</option>'.format( pk=2, value="Two") assert (selected_option in widget_output or selected_option_a in widget_output), widget_output assert selected_option2 in widget_output or selected_option2a in widget_output def test_multiple_widgets(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): driver.find_element_by_css_selector(".select2-results") elem1, elem2 = driver.find_elements_by_css_selector( ".select2-selection") elem1.click() search1 = driver.find_element_by_css_selector(".select2-search__field") search1.send_keys("fo") result1 = (WebDriverWait(driver, 60).until( expected_conditions.presence_of_element_located( (By.CSS_SELECTOR, ".select2-results li:first-child"))).text) elem2.click() search2 = driver.find_element_by_css_selector(".select2-search__field") search2.send_keys("fo") result2 = (WebDriverWait(driver, 60).until( expected_conditions.presence_of_element_located( (By.CSS_SELECTOR, ".select2-results li:first-child"))).text) assert result1 != result2 with pytest.raises(NoSuchElementException): error = driver.find_element_by_xpath("//body[@JSError]") pytest.fail(error.get_attribute("JSError")) def test_get_url(self): widget = self.widget_cls(data_view="heavy_data_1", attrs={"class": "my-class"}) assert isinstance(widget.get_url(), str) def test_can_not_pickle(self): widget = self.widget_cls(data_view="heavy_data_1", attrs={"class": "my-class"}) class NoPickle: pass widget.no_pickle = NoPickle() with pytest.raises(NotImplementedError): widget.set_to_cache() def test_theme_setting(self, settings): settings.SELECT2_THEME = "classic" widget = self.widget_cls(data_view="heavy_data_1") assert 'data-theme="classic"' in widget.render("name", None)