예제 #1
0
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)
예제 #2
0
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)