]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15391 Fix special caracter search in documentation
authorMathieu Suen <mathieu.suen@sonarsource.com>
Wed, 15 Sep 2021 07:40:35 +0000 (09:40 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 16 Sep 2021 20:03:30 +0000 (20:03 +0000)
server/sonar-docs/src/components/Search.tsx
server/sonar-docs/src/components/__tests__/Search-test.tsx [new file with mode: 0644]
server/sonar-docs/src/components/__tests__/__snapshots__/Search-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx
server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx
server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResults-test.tsx.snap

index 3733edb81d9fe7657e13a7204932dc9f676f53f3..f688447b3bce641278d06cb69fd5d69133cafba3 100644 (file)
@@ -146,6 +146,7 @@ export default class Search extends React.PureComponent<Props, State> {
         value,
         this.index.search(
           value
+            .replace(/[\^\-+:~*]/g, '')
             .split(/\s+/)
             .map(s => `${s}~1 ${s}*`)
             .join(' ')
diff --git a/server/sonar-docs/src/components/__tests__/Search-test.tsx b/server/sonar-docs/src/components/__tests__/Search-test.tsx
new file mode 100644 (file)
index 0000000..4101c0e
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
+import lunr from 'lunr';
+import * as React from 'react';
+import { MarkdownRemark } from '../../@types/graphql-types';
+import Search from '../Search';
+
+jest.mock('lunr', () => ({
+  __esModule: true,
+  default: jest.fn(() => ({
+    search: jest.fn(() => [
+      {
+        ref: 'lorem/origin',
+        matchData: {
+          metadata: {
+            simply: {
+              title: { position: [[19, 5]] },
+              text: {
+                position: [
+                  [15, 6],
+                  [28, 4]
+                ],
+                tokenContext: ['is simply dummy', 'simply dummy text']
+              }
+            }
+          }
+        }
+      },
+      {
+        ref: 'foobar',
+        matchData: {
+          metadata: {
+            simply: {
+              title: { position: [[23, 4]] },
+              text: {
+                position: [
+                  [111, 6],
+                  [118, 4]
+                ],
+                tokenContext: ['keywords simply text']
+              }
+            }
+          }
+        }
+      }
+    ])
+  }))
+}));
+
+function mockMarkdownRemark(override: Partial<MarkdownRemark>): MarkdownRemark {
+  return {
+    id: 'id',
+    parent: null,
+    children: null,
+    internal: null,
+    frontmatter: null,
+    rawMarkdownBody: null,
+    fileAbsolutePath: null,
+    fields: null,
+    html: null,
+    htmlAst: null,
+    excerpt: null,
+    headings: null,
+    timeToRead: null,
+    tableOfContents: null,
+    wordCount: null,
+    ...override
+  };
+}
+
+const pages = [
+  mockMarkdownRemark({
+    html:
+      'Lorem Ipsum is simply dummy text of the printing and typesetting ' +
+      "industry. Lorem Ipsum has been the industry's standard dummy text ever " +
+      'since the 1500s, when an unknown printer took a galley of type and ' +
+      'scrambled it to make a type specimen book.'
+  }),
+  mockMarkdownRemark({
+    html:
+      'Contrary to popular belief, Lorem Ipsum is not simply random text. ' +
+      'It has roots in a piece of classical Latin literature from 45 BC, making' +
+      ' it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney' +
+      ' College in Virginia, looked up one of the more obscure Latin words.'
+  }),
+  mockMarkdownRemark({
+    html:
+      'Foobar is a universal variable understood to represent whatever is ' +
+      'being discussed. Now we need some keywords: simply text.'
+  })
+];
+
+it('should search', () => {
+  const wrapper = shallow<Search>(
+    <Search
+      navigation={['lorem/index', 'lorem/origin', 'foobar']}
+      pages={pages}
+      onResultsChange={jest.fn()}
+    />
+  );
+  wrapper.instance().handleChange({ currentTarget: { value: 'simply text+:' } } as any);
+  expect(wrapper).toMatchSnapshot();
+  expect(lunr).toBeCalled();
+  expect(wrapper.instance().index).toBeDefined();
+  expect((wrapper.instance().index as any).search).toBeCalledWith('simply~1 simply* text~1 text*');
+});
diff --git a/server/sonar-docs/src/components/__tests__/__snapshots__/Search-test.tsx.snap b/server/sonar-docs/src/components/__tests__/__snapshots__/Search-test.tsx.snap
new file mode 100644 (file)
index 0000000..4a1bb57
--- /dev/null
@@ -0,0 +1,24 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should search 1`] = `
+<div
+  className="search-container"
+>
+  <input
+    aria-label="Search"
+    className="search-input"
+    onChange={[Function]}
+    placeholder="Search..."
+    type="search"
+    value="simply text+:"
+  />
+  <button
+    onClick={[Function]}
+    type="button"
+  >
+    <ClearIcon
+      size={8}
+    />
+  </button>
+</div>
+`;
index 4ec73f848d3c2441d609a7210cf8dab03766d21b..9640472b73cd64ca8e6eb803eca9ec1071b44902 100644 (file)
@@ -57,6 +57,7 @@ export default class SearchResults extends React.PureComponent<Props> {
     const results = this.index
       .search(
         query
+          .replace(/[\^\-+:~*]/g, '')
           .split(/\s+/)
           .map(s => `${s}~1 ${s}*`)
           .join(' ')
index 6c6764a97e256051496d074bacb904f4ec2c9add..88d5acffaa373de25e702742df1c5707ec638899 100644 (file)
@@ -90,7 +90,7 @@ it('should search', () => {
     <SearchResults
       navigation={['lorem/index', 'lorem/origin', 'foobar']}
       pages={pages}
-      query="simply text"
+      query="si:+mply text"
       splat="foobar"
     />
   );
index ae5779ca00ca2b612dec70f07be4726ed4242c82..65b92fef2341d9bfa021dc3462f0da849788e296 100644 (file)
@@ -3,76 +3,76 @@
 exports[`should search 1`] = `
 <Fragment>
   <SearchResultEntry
-    active={true}
-    key="foobar"
+    active={false}
+    key="lorem/origin"
     result={
       Object {
-        "exactMatch": true,
+        "exactMatch": false,
         "highlights": Object {
           "text": Array [
             Array [
-              111,
+              15,
               6,
             ],
             Array [
-              118,
+              28,
               4,
             ],
           ],
           "title": Array [
             Array [
-              23,
-              4,
+              19,
+              5,
             ],
           ],
         },
-        "longestTerm": "simply",
+        "longestTerm": "",
         "page": Object {
-          "content": "Foobar is a universal variable understood to represent whatever is being discussed. Now we need some keywords: simply text.",
+          "content": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.",
           "navTitle": undefined,
-          "relativeName": "foobar",
-          "text": "Foobar is a universal variable understood to represent whatever is being discussed. Now we need some keywords: simply text.",
-          "title": "Where does Foobar come from?",
-          "url": "/foobar",
+          "relativeName": "lorem/origin",
+          "text": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.",
+          "title": "Where does it come from?",
+          "url": "/lorem/origin",
         },
-        "query": "simply text",
+        "query": "si:+mply text",
       }
     }
   />
   <SearchResultEntry
-    active={false}
-    key="lorem/origin"
+    active={true}
+    key="foobar"
     result={
       Object {
         "exactMatch": false,
         "highlights": Object {
           "text": Array [
             Array [
-              15,
+              111,
               6,
             ],
             Array [
-              28,
+              118,
               4,
             ],
           ],
           "title": Array [
             Array [
-              19,
-              5,
+              23,
+              4,
             ],
           ],
         },
-        "longestTerm": "simply",
+        "longestTerm": "",
         "page": Object {
-          "content": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.",
+          "content": "Foobar is a universal variable understood to represent whatever is being discussed. Now we need some keywords: simply text.",
           "navTitle": undefined,
-          "relativeName": "lorem/origin",
-          "text": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.",
-          "title": "Where does it come from?",
-          "url": "/lorem/origin",
+          "relativeName": "foobar",
+          "text": "Foobar is a universal variable understood to represent whatever is being discussed. Now we need some keywords: simply text.",
+          "title": "Where does Foobar come from?",
+          "url": "/foobar",
         },
-        "query": "simply text",
+        "query": "si:+mply text",
       }
     }
   />