Passed
Push — 4 ( 9b9339...6b1c5e )
by Steve
06:47
created

SearchContextTest::testMatchAnySearch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\ORM\Tests\Search;
4
5
use SilverStripe\Dev\SapphireTest;
6
use SilverStripe\Forms\TextField;
7
use SilverStripe\Forms\TextareaField;
8
use SilverStripe\Forms\NumericField;
9
use SilverStripe\Forms\DropdownField;
10
use SilverStripe\Forms\CheckboxField;
11
use SilverStripe\Forms\FieldList;
12
use SilverStripe\ORM\DataList;
13
use SilverStripe\ORM\Filters\PartialMatchFilter;
14
use SilverStripe\ORM\Search\SearchContext;
15
16
class SearchContextTest extends SapphireTest
17
{
18
19
    protected static $fixture_file = 'SearchContextTest.yml';
20
21
    protected static $extra_dataobjects = [
22
        SearchContextTest\Person::class,
23
        SearchContextTest\Book::class,
24
        SearchContextTest\Company::class,
25
        SearchContextTest\Project::class,
26
        SearchContextTest\Deadline::class,
27
        SearchContextTest\Action::class,
28
        SearchContextTest\AllFilterTypes::class,
29
        SearchContextTest\Customer::class,
30
        SearchContextTest\Address::class,
31
        SearchContextTest\Order::class,
32
    ];
33
34
    public function testResultSetFilterReturnsExpectedCount()
35
    {
36
        $person = SearchContextTest\Person::singleton();
37
        $context = $person->getDefaultSearchContext();
38
        $results = $context->getResults(['Name' => '']);
39
        $this->assertEquals(5, $results->Count());
40
41
        $results = $context->getResults(['EyeColor' => 'green']);
42
        $this->assertEquals(2, $results->Count());
43
44
        $results = $context->getResults(['EyeColor' => 'green', 'HairColor' => 'black']);
45
        $this->assertEquals(1, $results->Count());
46
    }
47
48
    public function testSummaryIncludesDefaultFieldsIfNotDefined()
49
    {
50
        $person = SearchContextTest\Person::singleton();
51
        $this->assertContains('Name', $person->summaryFields());
52
53
        $book = SearchContextTest\Book::singleton();
54
        $this->assertContains('Title', $book->summaryFields());
55
    }
56
57
    public function testAccessDefinedSummaryFields()
58
    {
59
        $company = SearchContextTest\Company::singleton();
60
        $this->assertContains('Industry', $company->summaryFields());
61
    }
62
63
    public function testPartialMatchUsedByDefaultWhenNotExplicitlySet()
64
    {
65
        $person = SearchContextTest\Person::singleton();
66
        $context = $person->getDefaultSearchContext();
67
68
        $this->assertEquals(
69
            [
70
                "Name" => new PartialMatchFilter("Name"),
71
                "HairColor" => new PartialMatchFilter("HairColor"),
72
                "EyeColor" => new PartialMatchFilter("EyeColor")
73
            ],
74
            $context->getFilters()
75
        );
76
    }
77
78
    public function testDefaultFiltersDefinedWhenNotSetInDataObject()
79
    {
80
        $book = SearchContextTest\Book::singleton();
81
        $context = $book->getDefaultSearchContext();
82
83
        $this->assertEquals(
84
            [
85
                "Title" => new PartialMatchFilter("Title")
86
            ],
87
            $context->getFilters()
88
        );
89
    }
90
91
    public function testUserDefinedFiltersAppearInSearchContext()
92
    {
93
        $company = SearchContextTest\Company::singleton();
94
        $context = $company->getDefaultSearchContext();
95
96
        $this->assertEquals(
97
            [
98
                "Name" => new PartialMatchFilter("Name"),
99
                "Industry" => new PartialMatchFilter("Industry"),
100
                "AnnualProfit" => new PartialMatchFilter("AnnualProfit")
101
            ],
102
            $context->getFilters()
103
        );
104
    }
105
106
    public function testUserDefinedFieldsAppearInSearchContext()
107
    {
108
        $company = SearchContextTest\Company::singleton();
109
        $context = $company->getDefaultSearchContext();
110
        $this->assertEquals(
111
            new FieldList(
112
                (new TextField("Name", 'Name'))
113
                    ->setMaxLength(255),
114
                new TextareaField("Industry", 'Industry'),
115
                new NumericField("AnnualProfit", 'The Almighty Annual Profit')
116
            ),
117
            $context->getFields()
118
        );
119
    }
120
121
    public function testRelationshipObjectsLinkedInSearch()
122
    {
123
        $action3 = $this->objFromFixture(SearchContextTest\Action::class, 'action3');
124
125
        $project = SearchContextTest\Project::singleton();
126
        $context = $project->getDefaultSearchContext();
127
128
        $params = ["Name" => "Blog Website", "Actions__SolutionArea" => "technical"];
129
130
        /** @var DataList $results */
131
        $results = $context->getResults($params);
132
133
        $this->assertEquals(1, $results->count());
134
135
        /** @var SearchContextTest\Project $project */
136
        $project = $results->first();
137
138
        $this->assertInstanceOf(SearchContextTest\Project::class, $project);
139
        $this->assertEquals("Blog Website", $project->Name);
140
        $this->assertEquals(2, $project->Actions()->Count());
141
142
        $this->assertEquals(
143
            "Get RSS feeds working",
144
            $project->Actions()->find('ID', $action3->ID)->Description
0 ignored issues
show
Bug Best Practice introduced by
The property Description does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
145
        );
146
    }
147
148
    public function testCanGenerateQueryUsingAllFilterTypes()
149
    {
150
        $all = SearchContextTest\AllFilterTypes::singleton();
151
        $context = $all->getDefaultSearchContext();
152
        $params = [
153
            "ExactMatch" => "Match me exactly",
154
            "PartialMatch" => "partially",
155
            "CollectionMatch" => [
156
                "ExistingCollectionValue",
157
                "NonExistingCollectionValue",
158
                4,
159
                "Inline'Quotes'"
160
            ],
161
            "StartsWith" => "12345",
162
            "EndsWith" => "ijkl",
163
            "Fulltext" => "two"
164
        ];
165
166
        $results = $context->getResults($params);
167
        $this->assertEquals(1, $results->Count());
168
        $this->assertEquals("Filtered value", $results->First()->HiddenValue);
169
    }
170
171
    public function testStartsWithFilterCaseInsensitive()
172
    {
173
        $all = SearchContextTest\AllFilterTypes::singleton();
174
        $context = $all->getDefaultSearchContext();
175
        $params = [
176
            "StartsWith" => "12345-6789 camelcase", // spelled lowercase
177
        ];
178
179
        $results = $context->getResults($params);
180
        $this->assertEquals(1, $results->Count());
181
        $this->assertEquals("Filtered value", $results->First()->HiddenValue);
182
    }
183
184
    public function testEndsWithFilterCaseInsensitive()
185
    {
186
        $all = SearchContextTest\AllFilterTypes::singleton();
187
        $context = $all->getDefaultSearchContext();
188
        $params = [
189
            "EndsWith" => "IJKL", // spelled uppercase
190
        ];
191
192
        $results = $context->getResults($params);
193
        $this->assertEquals(1, $results->Count());
194
        $this->assertEquals("Filtered value", $results->First()->HiddenValue);
195
    }
196
197
    public function testSearchContextSummary()
198
    {
199
        $filters = [
200
            'KeywordSearch' => PartialMatchFilter::create('KeywordSearch'),
201
            'Country' => PartialMatchFilter::create('Country'),
202
            'CategoryID' => PartialMatchFilter::create('CategoryID'),
203
            'Featured' => PartialMatchFilter::create('Featured'),
204
            'Nothing' => PartialMatchFilter::create('Nothing'),
205
        ];
206
207
        $fields = FieldList::create(
208
            TextField::create('KeywordSearch', 'Keywords'),
209
            TextField::create('Country', 'Country'),
210
            DropdownField::create('CategoryID', 'Category', [
211
                1 => 'Category one',
212
                2 => 'Category two',
213
            ]),
214
            CheckboxField::create('Featured', 'Featured')
215
        );
216
217
        $context = SearchContext::create(
218
            SearchContextTest\Person::class,
219
            $fields,
220
            $filters
221
        );
222
223
        $context->setSearchParams([
224
            'KeywordSearch' => 'tester',
225
            'Country' => null,
226
            'CategoryID' => 2,
227
            'Featured' => 1,
228
            'Nothing' => 'empty',
229
        ]);
230
231
        $list = $context->getSummary();
232
233
        $this->assertEquals(3, $list->count());
234
        // KeywordSearch should be in the summary
235
        $keyword = $list->find('Field', 'Keywords');
236
        $this->assertNotNull($keyword);
237
        $this->assertEquals('tester', $keyword->Value);
238
239
        // Country should be skipped over
240
        $country = $list->find('Field', 'Country');
241
        $this->assertNull($country);
242
243
        // Category should be expressed as the label
244
        $category = $list->find('Field', 'Category');
245
        $this->assertNotNull($category);
246
        $this->assertEquals('Category two', $category->Value);
247
248
        // Featured should have no value, since it's binary
249
        $featured = $list->find('Field', 'Featured');
250
        $this->assertNotNull($featured);
251
        $this->assertNull($featured->Value);
252
253
        // "Nothing" should come back null since there's no field for it
254
        $nothing = $list->find('Field', 'Nothing');
255
        $this->assertNull($nothing);
256
    }
257
258
    public function testMatchAnySearch()
259
    {
260
        $order1 = $this->objFromFixture(SearchContextTest\Order::class, 'order1');
261
        $context = $order1->getDefaultSearchContext();
262
263
        // Search should match Order's customer FirstName
264
        $results = $context->getResults(['CustomFirstName' => 'Bill']);
265
        $this->assertEquals(1, $results->Count());
266
267
        // Search should match Order's shipping address FirstName
268
        $results = $context->getResults(['CustomFirstName' => 'Bob']);
269
        $this->assertEquals(1, $results->Count());
270
    }
271
}
272