]> BookStack Code Mirror - bookstack/commitdiff
Search: Prevented negated terms filling in UI inputs 5239/head
authorDan Brown <redacted>
Thu, 3 Oct 2024 18:38:07 +0000 (19:38 +0100)
committerDan Brown <redacted>
Thu, 3 Oct 2024 18:40:11 +0000 (19:40 +0100)
Added test to cover.

app/Search/SearchOptionSet.php
app/Search/SearchOptions.php
resources/views/search/all.blade.php
tests/Entity/EntitySearchTest.php
tests/Entity/SearchOptionsTest.php

index f421abe2c05d02418d3ee8951ced2d0bafb005f5..bd5e5a5b222671a737f620ba9513fdf219655c25 100644 (file)
@@ -63,10 +63,20 @@ class SearchOptionSet
     }
 
     /**
-     * @return T[]
+     * @return self<T>
+     */
+    public function negated(): self
+    {
+        $values = array_values(array_filter($this->options, fn (SearchOption $option) => $option->negated));
+        return new self($values);
+    }
+
+    /**
+     * @return self<T>
      */
-    public function negated(): array
+    public function nonNegated(): self
     {
-        return array_values(array_filter($this->options, fn (SearchOption $option) => $option->negated));
+        $values = array_values(array_filter($this->options, fn (SearchOption $option) => !$option->negated));
+        return new self($values);
     }
 }
index e362a8a015f476a4003dbe9c949156b436971dcd..7f9db2a64302b7dbea4f860a2919ec5b0dbd3de3 100644 (file)
@@ -244,9 +244,9 @@ class SearchOptions
         }
 
         // Negated items
-        array_push($options, ...$this->exacts->negated());
-        array_push($options, ...$this->tags->negated());
-        array_push($options, ...$this->filters->negated());
+        array_push($options, ...$this->exacts->negated()->all());
+        array_push($options, ...$this->tags->negated()->all());
+        array_push($options, ...$this->filters->negated()->all());
 
         return implode(' ', array_map(fn(SearchOption $o) => $o->toString(), $options));
     }
index 2a0d63a6ed6d0bf24cfbc3073ac255da2f5e2959..ad437604b1c47b0f46d57612593948b74c414395 100644 (file)
@@ -9,7 +9,7 @@
                     <h5>{{ trans('entities.search_advanced') }}</h5>
 
                     @php
-                        $filterMap = $options->filters->toValueMap();
+                        $filterMap = $options->filters->nonNegated()->toValueMap();
                     @endphp
                     <form method="get" action="{{ url('/search') }}">
                         <h6>{{ trans('entities.search_terms') }}</h6>
                         </div>
 
                         <h6>{{ trans('entities.search_exact_matches') }}</h6>
-                        @include('search.parts.term-list', ['type' => 'exact', 'currentList' => $options->exacts->toValueArray()])
+                        @include('search.parts.term-list', ['type' => 'exact', 'currentList' => $options->exacts->nonNegated()->toValueArray()])
 
                         <h6>{{ trans('entities.search_tags') }}</h6>
-                        @include('search.parts.term-list', ['type' => 'tags', 'currentList' => $options->tags->toValueArray()])
+                        @include('search.parts.term-list', ['type' => 'tags', 'currentList' => $options->tags->nonNegated()->toValueArray()])
 
                         @if(!user()->isGuest())
                             <h6>{{ trans('entities.search_options') }}</h6>
index bb1021a67915620bddf9c61694c1702ac092c23d..3a1a0a6620001d87121014c2c6ac1ace327eddcd 100644 (file)
@@ -577,6 +577,14 @@ class EntitySearchTest extends TestCase
         $this->withHtml($resp)->assertFieldHasValue('extras', '{updated_by:dan} {created_by:dan} -"dog" -[a=b] -{viewed_by_me}');
     }
 
+    public function test_negated_searches_dont_show_in_inputs()
+    {
+        $resp = $this->asEditor()->get('/search?term=' . urlencode('-{created_by:me} -[a=b] -"dog"'));
+        $this->withHtml($resp)->assertElementNotExists('input[name="tags[]"][value="a=b"]');
+        $this->withHtml($resp)->assertElementNotExists('input[name="exact[]"][value="dog"]');
+        $this->withHtml($resp)->assertElementNotExists('input[name="filters[created_by]"][value="me"][checked="checked"]');
+    }
+
     public function test_searches_with_user_filters_using_me_adds_them_into_advanced_search_form()
     {
         $resp = $this->asEditor()->get('/search?term=' . urlencode('test {updated_by:me} {created_by:me}'));
index 543badcef95b0cdd9eac0b839f8fb91431c0696f..ae0f1e56a9ecd6b7e513480b169743fca11c1d5c 100644 (file)
@@ -123,7 +123,7 @@ class SearchOptionsTest extends TestCase
 
         $options = SearchOptions::fromRequest($request);
         $this->assertCount(2, $options->tags->all());
-        $this->assertEquals('b=c', $options->tags->negated()[0]->value);
+        $this->assertEquals('b=c', $options->tags->negated()->all()[0]->value);
         $this->assertEquals('viewed_by_me', $options->filters->all()[0]->getKey());
         $this->assertTrue($options->filters->all()[0]->negated);
         $this->assertEquals('dino', $options->exacts->all()[0]->value);