+ $pageTestResp = $this->asEditor()->get('/search/book/' . $book->id . '?term=' . urlencode($page->name));
+ $pageTestResp->assertSee($page->name);
+
+ $chapterTestResp = $this->asEditor()->get('/search/book/' . $book->id . '?term=' . urlencode($chapter->name));
+ $chapterTestResp->assertSee($chapter->name);
+ }
+
+ public function test_chapter_search()
+ {
+ $chapter = $this->entities->chapterHasPages();
+ $page = $chapter->pages[0];
+
+ $pageTestResp = $this->asEditor()->get('/search/chapter/' . $chapter->id . '?term=' . urlencode($page->name));
+ $pageTestResp->assertSee($page->name);
+ }
+
+ public function test_tag_search()
+ {
+ $newTags = [
+ new Tag([
+ 'name' => 'animal',
+ 'value' => 'cat',
+ ]),
+ new Tag([
+ 'name' => 'color',
+ 'value' => 'red',
+ ]),
+ ];
+
+ $pageA = $this->entities->page();
+ $pageA->tags()->saveMany($newTags);
+
+ $pageB = $this->entities->page();
+ $pageB->tags()->create(['name' => 'animal', 'value' => 'dog']);
+
+ $this->asEditor();
+ $tNameSearch = $this->get('/search?term=%5Banimal%5D');
+ $tNameSearch->assertSee($pageA->name)->assertSee($pageB->name);
+
+ $tNameSearch2 = $this->get('/search?term=%5Bcolor%5D');
+ $tNameSearch2->assertSee($pageA->name)->assertDontSee($pageB->name);
+
+ $tNameValSearch = $this->get('/search?term=%5Banimal%3Dcat%5D');
+ $tNameValSearch->assertSee($pageA->name)->assertDontSee($pageB->name);
+ }
+
+ public function test_exact_searches()
+ {
+ $page = $this->entities->newPage(['name' => 'My new test page', 'html' => 'this is a story about an orange donkey']);
+
+ $exactSearchA = $this->asEditor()->get('/search?term=' . urlencode('"story about an orange"'));
+ $exactSearchA->assertStatus(200)->assertSee($page->name);
+
+ $exactSearchB = $this->asEditor()->get('/search?term=' . urlencode('"story not about an orange"'));
+ $exactSearchB->assertStatus(200)->assertDontSee($page->name);
+ }
+
+ public function test_negated_searches()
+ {
+ $page = $this->entities->newPage(['name' => 'My new test negation page', 'html' => '<p>An angry tortoise wore trumpeted plimsoles</p>']);
+ $page->tags()->saveMany([new Tag(['name' => 'DonkCount', 'value' => '500'])]);
+ $page->created_by = $this->users->admin()->id;
+ $page->save();
+
+ $editor = $this->users->editor();
+ $this->actingAs($editor);
+
+ $exactSearch = $this->get('/search?term=' . urlencode('negation -"tortoise"'));
+ $exactSearch->assertStatus(200)->assertDontSeeText($page->name);
+
+ $tagSearchA = $this->get('/search?term=' . urlencode('negation [DonkCount=500]'));
+ $tagSearchA->assertStatus(200)->assertSeeText($page->name);
+ $tagSearchB = $this->get('/search?term=' . urlencode('negation -[DonkCount=500]'));
+ $tagSearchB->assertStatus(200)->assertDontSeeText($page->name);
+
+ $filterSearchA = $this->get('/search?term=' . urlencode('negation -{created_by:me}'));
+ $filterSearchA->assertStatus(200)->assertSeeText($page->name);
+ $page->created_by = $editor->id;
+ $page->save();
+ $filterSearchB = $this->get('/search?term=' . urlencode('negation -{created_by:me}'));
+ $filterSearchB->assertStatus(200)->assertDontSeeText($page->name);
+ }
+
+ public function test_search_terms_with_delimiters_are_converted_to_exact_matches()
+ {
+ $this->asEditor();
+ $page = $this->entities->newPage(['name' => 'Delimiter test', 'html' => '<p>1.1 2,2 3?3 4:4 5;5 (8) <9> "10" \'11\' `12`</p>']);
+ $terms = explode(' ', '1.1 2,2 3?3 4:4 5;5 (8) <9> "10" \'11\' `12`');
+
+ foreach ($terms as $term) {
+ $search = $this->get('/search?term=' . urlencode($term));
+ $search->assertSee($page->name);
+ }
+ }
+
+ public function test_search_filters()
+ {
+ $page = $this->entities->newPage(['name' => 'My new test quaffleachits', 'html' => 'this is about an orange donkey danzorbhsing']);
+ $editor = $this->users->editor();
+ $this->actingAs($editor);
+
+ // Viewed filter searches
+ $this->get('/search?term=' . urlencode('danzorbhsing {not_viewed_by_me}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {viewed_by_me}'))->assertDontSee($page->name);
+ $this->get($page->getUrl());
+ $this->get('/search?term=' . urlencode('danzorbhsing {not_viewed_by_me}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {viewed_by_me}'))->assertSee($page->name);
+
+ // User filters
+ $this->get('/search?term=' . urlencode('danzorbhsing {created_by:me}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_by:me}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {owned_by:me}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_by:' . $editor->slug . '}'))->assertDontSee($page->name);
+ $page->created_by = $editor->id;
+ $page->save();
+ $this->get('/search?term=' . urlencode('danzorbhsing {created_by:me}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {created_by: ' . $editor->slug . '}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_by:me}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {owned_by:me}'))->assertDontSee($page->name);
+ $page->updated_by = $editor->id;
+ $page->save();
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_by:me}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_by:' . $editor->slug . '}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {owned_by:me}'))->assertDontSee($page->name);
+ $page->owned_by = $editor->id;
+ $page->save();
+ $this->get('/search?term=' . urlencode('danzorbhsing {owned_by:me}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {owned_by:' . $editor->slug . '}'))->assertSee($page->name);
+
+ // Content filters
+ $this->get('/search?term=' . urlencode('{in_name:danzorbhsing}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('{in_body:danzorbhsing}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('{in_name:test quaffleachits}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('{in_body:test quaffleachits}'))->assertDontSee($page->name);
+
+ // Restricted filter
+ $this->get('/search?term=' . urlencode('danzorbhsing {is_restricted}'))->assertDontSee($page->name);
+ $this->permissions->setEntityPermissions($page, ['view'], [$editor->roles->first()]);
+ $this->get('/search?term=' . urlencode('danzorbhsing {is_restricted}'))->assertSee($page->name);
+
+ // Date filters
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_after:2037-01-01}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_before:2037-01-01}'))->assertSee($page->name);
+ $page->updated_at = '2037-02-01';
+ $page->save();
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_after:2037-01-01}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {updated_before:2037-01-01}'))->assertDontSee($page->name);
+
+ $this->get('/search?term=' . urlencode('danzorbhsing {created_after:2037-01-01}'))->assertDontSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {created_before:2037-01-01}'))->assertSee($page->name);
+ $page->created_at = '2037-02-01';
+ $page->save();
+ $this->get('/search?term=' . urlencode('danzorbhsing {created_after:2037-01-01}'))->assertSee($page->name);
+ $this->get('/search?term=' . urlencode('danzorbhsing {created_before:2037-01-01}'))->assertDontSee($page->name);
+ }
+
+ public function test_entity_selector_search()
+ {
+ $page = $this->entities->newPage(['name' => 'my ajax search test', 'html' => 'ajax test']);
+ $notVisitedPage = $this->entities->page();
+
+ // Visit the page to make popular
+ $this->asEditor()->get($page->getUrl());
+
+ $normalSearch = $this->get('/search/entity-selector?term=' . urlencode($page->name));
+ $normalSearch->assertSee($page->name);
+
+ $bookSearch = $this->get('/search/entity-selector?types=book&term=' . urlencode($page->name));
+ $bookSearch->assertDontSee($page->name);
+
+ $defaultListTest = $this->get('/search/entity-selector');
+ $defaultListTest->assertSee($page->name);
+ $defaultListTest->assertDontSee($notVisitedPage->name);
+ }
+
+ public function test_entity_selector_search_shows_breadcrumbs()
+ {
+ $chapter = $this->entities->chapter();
+ $page = $chapter->pages->first();
+ $this->asEditor();
+
+ $pageSearch = $this->get('/search/entity-selector?term=' . urlencode($page->name));
+ $pageSearch->assertSee($page->name);
+ $pageSearch->assertSee($chapter->getShortName(42));
+ $pageSearch->assertSee($page->book->getShortName(42));
+
+ $chapterSearch = $this->get('/search/entity-selector?term=' . urlencode($chapter->name));
+ $chapterSearch->assertSee($chapter->name);
+ $chapterSearch->assertSee($chapter->book->getShortName(42));
+ }
+
+ public function test_entity_selector_shows_breadcrumbs_on_default_view()
+ {
+ $page = $this->entities->pageWithinChapter();
+ $this->asEditor()->get($page->chapter->getUrl());
+
+ $resp = $this->asEditor()->get('/search/entity-selector?types=book,chapter&permission=page-create');
+ $html = $this->withHtml($resp);
+ $html->assertElementContains('.chapter.entity-list-item', $page->chapter->name);
+ $html->assertElementContains('.chapter.entity-list-item .entity-item-snippet', $page->book->getShortName(42));
+ }
+
+ public function test_entity_selector_search_reflects_items_without_permission()
+ {
+ $page = $this->entities->page();
+ $baseSelector = 'a[data-entity-type="page"][data-entity-id="' . $page->id . '"]';
+ $searchUrl = '/search/entity-selector?permission=update&term=' . urlencode($page->name);
+
+ $resp = $this->asEditor()->get($searchUrl);
+ $this->withHtml($resp)->assertElementContains($baseSelector, $page->name);
+ $this->withHtml($resp)->assertElementNotContains($baseSelector, "You don't have the required permissions to select this item");
+
+ $resp = $this->actingAs($this->users->viewer())->get($searchUrl);
+ $this->withHtml($resp)->assertElementContains($baseSelector, $page->name);
+ $this->withHtml($resp)->assertElementContains($baseSelector, "You don't have the required permissions to select this item");
+ }
+
+ public function test_entity_template_selector_search()
+ {
+ $templatePage = $this->entities->newPage(['name' => 'Template search test', 'html' => 'template test']);
+ $templatePage->template = true;
+ $templatePage->save();
+
+ $nonTemplatePage = $this->entities->newPage(['name' => 'Nontemplate page', 'html' => 'nontemplate', 'template' => false]);
+
+ // Visit both to make popular
+ $this->asEditor()->get($templatePage->getUrl());
+ $this->get($nonTemplatePage->getUrl());
+
+ $normalSearch = $this->get('/search/entity-selector-templates?term=test');
+ $normalSearch->assertSee($templatePage->name);
+ $normalSearch->assertDontSee($nonTemplatePage->name);
+
+ $normalSearch = $this->get('/search/entity-selector-templates?term=beans');
+ $normalSearch->assertDontSee($templatePage->name);
+ $normalSearch->assertDontSee($nonTemplatePage->name);
+
+ $defaultListTest = $this->get('/search/entity-selector-templates');
+ $defaultListTest->assertSee($templatePage->name);
+ $defaultListTest->assertDontSee($nonTemplatePage->name);
+
+ $this->permissions->disableEntityInheritedPermissions($templatePage);
+
+ $normalSearch = $this->get('/search/entity-selector-templates?term=test');
+ $normalSearch->assertDontSee($templatePage->name);
+
+ $defaultListTest = $this->get('/search/entity-selector-templates');
+ $defaultListTest->assertDontSee($templatePage->name);
+ }
+
+ public function test_sibling_search_for_pages()
+ {
+ $chapter = $this->entities->chapterHasPages();
+ $this->assertGreaterThan(2, count($chapter->pages), 'Ensure we\'re testing with at least 1 sibling');
+ $page = $chapter->pages->first();