Taichi Masuyama 4 лет назад
Родитель
Сommit
08fa118dd8

+ 12 - 0
packages/app/src/server/models/obsolete-page.js

@@ -219,6 +219,18 @@ export class PageQueryBuilder {
     return this;
   }
 
+  addConditionAsRootOrHasParent() {
+    this.query = this.query
+      .and({ $or: [{ parent: null }, { path: '/' }] });
+
+    return this;
+  }
+
+  addConditionAsNotRootOrHasParent() {
+    this.query = this.query
+      .and({ $nor: [{ parent: null }, { path: '/' }] });
+  }
+
   /*
    * Add this condition when get any ancestor pages including the target's parent
    */

+ 2 - 1
packages/app/src/server/service/search-delegator/private-legacy-pages.ts

@@ -27,9 +27,10 @@ class PrivateLegacyPagesDelegator implements SearchDelegator<Data> {
     const Page = mongoose.model('Page') as PageModel;
     const { PageQueryBuilder } = Page;
 
-    const queryBuilder = new PageQueryBuilder(Page.find({ parent: null }));
+    const queryBuilder = new PageQueryBuilder(Page.find());
 
     const pages: PageDocument[] = await queryBuilder
+      .addConditionAsRootOrHasParent()
       .addConditionToFilteringByViewer(user, userGroups)
       .addConditionToPagenate(offset, limit)
       .query

+ 3 - 3
packages/app/src/server/service/search.ts

@@ -44,8 +44,9 @@ class SearchService implements SearchQueryParser, SearchResolver {
     this.isErrorOccuredOnSearching = null;
 
     try {
-      this.fullTextSearchDelegator = this.generateDelegator();
+      this.fullTextSearchDelegator = this.generateFullTextSearchDelegator();
       this.nqDelegators = this.generateNQDelegators(this.fullTextSearchDelegator);
+      logger.info('Succeeded to initialize search delegators');
     }
     catch (err) {
       logger.error(err);
@@ -70,7 +71,7 @@ class SearchService implements SearchQueryParser, SearchResolver {
     return uri != null && uri.length > 0;
   }
 
-  generateDelegator() {
+  generateFullTextSearchDelegator() {
     logger.info('Initializing search delegator');
 
     if (this.isElasticsearchEnabled) {
@@ -164,7 +165,6 @@ class SearchService implements SearchQueryParser, SearchResolver {
   }
 
   async parseSearchQuery(_queryString: string): Promise<ParsedQuery> {
-
     const regexp = new RE2(/^\[nq:.+\]$/g); // https://regex101.com/r/FzDUvT/1
     const replaceRegexp = new RE2(/\[nq:|\]/g);
 

+ 9 - 7
packages/app/src/test/integration/service/search/search-service.test.js

@@ -19,7 +19,7 @@ describe('SearchService test', () => {
   let namedQuery1;
   let namedQuery2;
 
-  const dummyDelegator = {
+  const dummyFullTextSearchDelegator = {
     search() {
       return;
     },
@@ -29,7 +29,8 @@ describe('SearchService test', () => {
     crowi = await getInstance();
     searchService = new SearchService(crowi);
     searchService.nqDelegators = {
-      FullTextSearch: dummyDelegator,
+      ...searchService.nqDelegators,
+      [DEFAULT]: dummyFullTextSearchDelegator, // override with dummy full-text search delegator
     };
 
     dummyAliasOf = 'match -notmatch "phrase" -"notphrase" prefix:/pre1 -prefix:/pre2 tag:Tag1 -tag:Tag2';
@@ -46,11 +47,11 @@ describe('SearchService test', () => {
 
   describe('parseQueryString()', () => {
     test('should parse queryString', async() => {
-      const queryString = 'match -notmatch "phrase" -"notphrase" [nq:named_query] prefix:/pre1 -prefix:/pre2 tag:Tag1 -tag:Tag2';
+      const queryString = 'match -notmatch "phrase" -"notphrase" prefix:/pre1 -prefix:/pre2 tag:Tag1 -tag:Tag2';
       const terms = await searchService.parseQueryString(queryString);
 
       const expected = { // QueryTerms
-        match: ['match', '[nq:named_query]'],
+        match: ['match'],
         not_match: ['notmatch'],
         phrase: ['"phrase"'],
         not_phrase: ['"notphrase"'],
@@ -163,9 +164,10 @@ describe('SearchService test', () => {
           grant: Page.GRANT_OWNER,
           creator: testUser1,
           lastUpdateUser: testUser1,
+          grantedUsers: [testUser1._id],
         },
         {
-          path: '/user2_notOwner',
+          path: '/user2_public',
           grant: Page.GRANT_PUBLIC,
           creator: testUser2,
           lastUpdateUser: testUser2,
@@ -192,10 +194,10 @@ describe('SearchService test', () => {
 
       const [delegator, data] = await searchService.resolve(parsedQuery);
 
-      const result = await delegator.search(data, testUser1, null, { limit: 10, offset: 0 });
+      const result = await delegator.search(data, testUser1, null, { limit: 0, offset: 0 });
 
       const resultPaths = result.data.pages.map(page => page.path).sort();
-      const expectedPaths = ['/user1', '/user1_owner'].sort();
+      const expectedPaths = ['/user1', '/user1_owner', '/user2_public'].sort();
 
       expect(resultPaths).toStrictEqual(expectedPaths);
     });