]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8878 Add ut and it's for Language, Search and Sort filters
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Wed, 8 Mar 2017 13:43:43 +0000 (14:43 +0100)
committerGrégoire Aubert <gregaubert@users.noreply.github.com>
Mon, 13 Mar 2017 09:03:16 +0000 (10:03 +0100)
it/it-tests/src/test/java/it/projectSearch/ProjectsPageTest.java
it/it-tests/src/test/java/pageobjects/projects/FacetItem.java
it/it-tests/src/test/java/pageobjects/projects/ProjectsPage.java
server/sonar-web/src/main/js/apps/projects/filters/__tests__/LanguageFilterFooter-test.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchFilter-test.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/filters/__tests__/SortingFilter-test.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguageFilterFooter-test.js.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SearchFilter-test.js.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SortingFilter-test.js.snap [new file with mode: 0644]

index 70c9f708f4a24ce23cbb8e6730cd6764d6ecfe60..29128f155566b043ee1267287c5a08729b833dab 100644 (file)
@@ -101,4 +101,29 @@ public class ProjectsPageTest {
     page.shouldHaveTotal(2).shouldDisplayAllProjects();
   }
 
+  @Test
+  public void should_add_language() {
+    ProjectsPage page = nav.openProjects();
+    page.getFacetByProperty("languages")
+      .selectOptionItem("xoo2")
+      .shouldHaveValue("xoo2", "0");
+  }
+
+  @Test
+  public void should_sort_by_facet() {
+    ProjectsPage page = nav.openProjects();
+    page.getFacetByProperty("duplications")
+      .sortListDesc();
+    page.getProjectByIdx(0).shouldHaveMeasure("duplicated_lines_density", "63.7%");
+    page.getFacetByProperty("duplications")
+      .sortListAsc();
+    page.getProjectByIdx(0).shouldHaveMeasure("duplicated_lines_density", "0.0%");
+  }
+
+  @Test
+  public void should_search_for_project() {
+    ProjectsPage page = nav.openProjects();
+    page.searchProject("s").shouldHaveTotal(2);
+    page.searchProject("sam").shouldHaveTotal(1);
+  }
 }
index ec9e4c8f0e4fa172c4e5e122d653f4b74f4f3ecc..2d0adce7de4f2df130f618ca417ccd77f0552fef 100644 (file)
@@ -20,7 +20,9 @@
 package pageobjects.projects;
 
 import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.ElementsCollection;
 import com.codeborne.selenide.SelenideElement;
+import org.openqa.selenium.WebElement;
 
 public class FacetItem {
 
@@ -38,4 +40,29 @@ public class FacetItem {
   public void selectValue(String key) {
     this.elt.$(".facet[data-key=\"" + key + "\"]").click();
   }
+
+  public FacetItem selectOptionItem(String value) {
+    this.elt.$(".Select-input input").val(value).pressEnter();
+    return this;
+  }
+
+  public FacetItem sortListDesc() {
+    this.getSortingButton("-").click();
+    return this;
+  }
+
+  public FacetItem sortListAsc() {
+    this.getSortingButton("[a-zA-Z ]").click();
+    return this;
+  }
+
+  public SelenideElement getSortingButton(String selector) {
+    ElementsCollection buttons = this.elt.$$(".projects-facet-sort a");
+    return buttons.find(new Condition("AttributeMatch") {
+      @Override
+      public boolean apply(WebElement webElement) {
+        return webElement.getAttribute("href").matches(".*sort=" + selector + ".*");
+      }
+    });
+  }
 }
index 0cc1b638a117a137348c7ee5f4f684ac9561935e..de3b50834faabf1424eb9f7fe7c9d31bff511482 100644 (file)
@@ -49,6 +49,10 @@ public class ProjectsPage {
     return new ProjectItem(element);
   }
 
+  public ProjectItem getProjectByIdx(Integer idx) {
+    return new ProjectItem(getProjects().get(idx));
+  }
+
   public FacetItem getFacetByProperty(String facetProperty) {
     SelenideElement element = getFacets().find(Condition.attribute("data-key", facetProperty));
     return new FacetItem(element);
@@ -79,4 +83,10 @@ public class ProjectsPage {
     $("#favorite-projects").click();
     return shouldDisplayFavoriteProjects();
   }
+
+  public ProjectsPage searchProject(String search) {
+    SelenideElement searchInput = $(".projects-facet-search input");
+    searchInput.setValue("").sendKeys(search);
+    return this;
+  }
 }
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/LanguageFilterFooter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/LanguageFilterFooter-test.js
new file mode 100644 (file)
index 0000000..1c90902
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import LanguageFilterFooter from '../LanguageFilterFooter';
+
+const languages = {
+  java: {
+    key: 'java',
+    name: 'Java'
+  },
+  cs: {
+    key: 'cs',
+    name: 'C#'
+  },
+  js: {
+    key: 'js',
+    name: 'JavaScript'
+  },
+  flex: {
+    key: 'flex',
+    name: 'Flex'
+  },
+  php: {
+    key: 'php',
+    name: 'PHP'
+  },
+  py: {
+    key: 'py',
+    name: 'Python'
+  }
+};
+const facet = { java: 39, cs: 4, js: 1 };
+
+it('should render the languages without the ones in the facet', () => {
+  const wrapper = shallow(
+    <LanguageFilterFooter
+      property="foo"
+      query={{ languages: null }}
+      facet={facet}
+      languages={languages}/>
+  );
+  expect(wrapper).toMatchSnapshot();
+  expect(wrapper.find('Select').props().options.length).toBe(3);
+});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchFilter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchFilter-test.js
new file mode 100644 (file)
index 0000000..c72c332
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import SearchFilter from '../SearchFilter';
+
+it('should render correctly without any search query', () => {
+  const wrapper = shallow(
+    <SearchFilter
+        handleSearch={() => {}}
+        query={{ search: null }}/>
+  );
+  expect(wrapper).toMatchSnapshot();
+});
+
+it('should render with a search query', () => {
+  const wrapper = shallow(
+    <SearchFilter
+        handleSearch={() => {}}
+        query={{ search: 'foo' }}/>
+  );
+  expect(wrapper).toMatchSnapshot();
+});
+
+it('should display a help message when there is less than 2 characters', () => {
+  const wrapper = shallow(
+    <SearchFilter
+        handleSearch={() => {}}
+        query={{ search: 'a' }}/>
+  );
+  expect(wrapper).toMatchSnapshot();
+  wrapper.setState({ userQuery: 'foo' });
+  expect(wrapper).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SortingFilter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SortingFilter-test.js
new file mode 100644 (file)
index 0000000..9813451
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import SortingFilter from '../SortingFilter';
+
+it('should render with default parameters and empty query', () => {
+  const wrapper = shallow(
+    <SortingFilter
+        property="foo"
+        query={{}}/>
+  );
+  expect(wrapper).toMatchSnapshot();
+  const sortingFilter = wrapper.instance();
+  expect(sortingFilter.isSortActive('left')).toBeFalsy();
+  expect(sortingFilter.isSortActive('right')).toBeFalsy();
+});
+
+it('should render with custom parameters', () => {
+  const wrapper = shallow(
+    <SortingFilter
+        property="foo"
+        query={{}}
+        sortDesc="right"
+        leftText="worst"
+        rightText="best"/>
+  );
+  expect(wrapper).toMatchSnapshot();
+});
+
+it('should render correctly with matching query', () => {
+  const wrapper = shallow(
+    <SortingFilter
+      property="foo"
+      query={{ sort: '-foo', languages: 'php,cpp' }}
+      sortDesc="right"/>
+  );
+  expect(wrapper).toMatchSnapshot();
+  const sortingFilter = wrapper.instance();
+  expect(sortingFilter.isSortActive('left')).toBeFalsy();
+  expect(sortingFilter.isSortActive('right')).toBeTruthy();
+});
+
+it('should render correctly with no matching query', () => {
+  const wrapper = shallow(
+    <SortingFilter
+      property="foo"
+      query={{ sort: 'bar' }}/>
+  );
+  expect(wrapper).toMatchSnapshot();
+  const sortingFilter = wrapper.instance();
+  expect(sortingFilter.isSortActive('left')).toBeFalsy();
+  expect(sortingFilter.isSortActive('right')).toBeFalsy();
+});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguageFilterFooter-test.js.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguageFilterFooter-test.js.snap
new file mode 100644 (file)
index 0000000..22d352f
--- /dev/null
@@ -0,0 +1,58 @@
+exports[`test should render the languages without the ones in the facet 1`] = `
+<Select
+  addLabelText="Add \"{label}\"?"
+  arrowRenderer={[Function]}
+  autosize={true}
+  backspaceRemoves={true}
+  backspaceToRemoveMessage="Press backspace to remove {label}"
+  className="input-super-large"
+  clearAllText="Clear all"
+  clearValueText="Clear value"
+  clearable={false}
+  delimiter=","
+  disabled={false}
+  escapeClearsValue={true}
+  filterOptions={[Function]}
+  ignoreAccents={true}
+  ignoreCase={true}
+  inputProps={Object {}}
+  isLoading={false}
+  joinValues={false}
+  labelKey="label"
+  matchPos="any"
+  matchProp="any"
+  menuBuffer={0}
+  menuRenderer={[Function]}
+  multi={false}
+  noResultsText="No results found"
+  onBlurResetsInput={true}
+  onChange={[Function]}
+  onCloseResetsInput={true}
+  openAfterFocus={false}
+  optionComponent={[Function]}
+  options={
+    Array [
+      Object {
+        "label": "Flex",
+        "value": "flex",
+      },
+      Object {
+        "label": "PHP",
+        "value": "php",
+      },
+      Object {
+        "label": "Python",
+        "value": "py",
+      },
+    ]
+  }
+  pageSize={5}
+  placeholder="search_verb"
+  required={false}
+  scrollMenuIntoView={true}
+  searchable={true}
+  simpleValue={false}
+  tabSelectsValue={true}
+  valueComponent={[Function]}
+  valueKey="value" />
+`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SearchFilter-test.js.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SearchFilter-test.js.snap
new file mode 100644 (file)
index 0000000..55bfe8e
--- /dev/null
@@ -0,0 +1,71 @@
+exports[`test should display a help message when there is less than 2 characters 1`] = `
+<div
+  className="projects-facet-search"
+  data-key="search">
+  <input
+    autoComplete="off"
+    className="input-super-large touched"
+    onChange={[Function]}
+    placeholder="projects.search"
+    type="search"
+    value="a" />
+  <span
+    className="note spacer-left">
+    select2.tooShort.2
+  </span>
+</div>
+`;
+
+exports[`test should display a help message when there is less than 2 characters 2`] = `
+<div
+  className="projects-facet-search"
+  data-key="search">
+  <input
+    autoComplete="off"
+    className="input-super-large"
+    onChange={[Function]}
+    placeholder="projects.search"
+    type="search"
+    value="foo" />
+  <span
+    className="note spacer-left">
+    select2.tooShort.2
+  </span>
+</div>
+`;
+
+exports[`test should render correctly without any search query 1`] = `
+<div
+  className="projects-facet-search"
+  data-key="search">
+  <input
+    autoComplete="off"
+    className="input-super-large"
+    onChange={[Function]}
+    placeholder="projects.search"
+    type="search"
+    value="" />
+  <span
+    className="note spacer-left">
+    select2.tooShort.2
+  </span>
+</div>
+`;
+
+exports[`test should render with a search query 1`] = `
+<div
+  className="projects-facet-search"
+  data-key="search">
+  <input
+    autoComplete="off"
+    className="input-super-large"
+    onChange={[Function]}
+    placeholder="projects.search"
+    type="search"
+    value="foo" />
+  <span
+    className="note spacer-left">
+    select2.tooShort.2
+  </span>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SortingFilter-test.js.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SortingFilter-test.js.snap
new file mode 100644 (file)
index 0000000..a7a70e6
--- /dev/null
@@ -0,0 +1,168 @@
+exports[`test should render correctly with matching query 1`] = `
+<div
+  className="projects-facet-sort">
+  <span>
+    projects.sort_list
+  </span>
+  <div
+    className="spacer-left button-group">
+    <Link
+      className="button button-small button-grey"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "languages": "php,cpp",
+            "sort": "foo",
+          },
+        }
+      }>
+      worst
+    </Link>
+    <Link
+      className="button button-small button-grey button-active"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "languages": "php,cpp",
+          },
+        }
+      }>
+      best
+    </Link>
+  </div>
+</div>
+`;
+
+exports[`test should render correctly with no matching query 1`] = `
+<div
+  className="projects-facet-sort">
+  <span>
+    projects.sort_list
+  </span>
+  <div
+    className="spacer-left button-group">
+    <Link
+      className="button button-small button-grey"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "sort": "-foo",
+          },
+        }
+      }>
+      worst
+    </Link>
+    <Link
+      className="button button-small button-grey"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "sort": "foo",
+          },
+        }
+      }>
+      best
+    </Link>
+  </div>
+</div>
+`;
+
+exports[`test should render with custom parameters 1`] = `
+<div
+  className="projects-facet-sort">
+  <span>
+    projects.sort_list
+  </span>
+  <div
+    className="spacer-left button-group">
+    <Link
+      className="button button-small button-grey"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "sort": "foo",
+          },
+        }
+      }>
+      worst
+    </Link>
+    <Link
+      className="button button-small button-grey"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "sort": "-foo",
+          },
+        }
+      }>
+      best
+    </Link>
+  </div>
+</div>
+`;
+
+exports[`test should render with default parameters and empty query 1`] = `
+<div
+  className="projects-facet-sort">
+  <span>
+    projects.sort_list
+  </span>
+  <div
+    className="spacer-left button-group">
+    <Link
+      className="button button-small button-grey"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "sort": "-foo",
+          },
+        }
+      }>
+      worst
+    </Link>
+    <Link
+      className="button button-small button-grey"
+      onClick={[Function]}
+      onlyActiveOnIndex={false}
+      style={Object {}}
+      to={
+        Object {
+          "pathname": "/projects",
+          "query": Object {
+            "sort": "foo",
+          },
+        }
+      }>
+      best
+    </Link>
+  </div>
+</div>
+`;