Completed
Push — 4.8 ( 9ccdb8...12cffe )
by Daniel
34s queued 22s
created

DBTextTest::testSummary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 4
dl 0
loc 5
rs 10
1
<?php
2
3
namespace SilverStripe\ORM\Tests;
4
5
use SilverStripe\ORM\FieldType\DBField;
6
use SilverStripe\Dev\SapphireTest;
7
use SilverStripe\ORM\FieldType\DBText;
8
9
/**
10
 * Tests parsing and summary methods on DBText
11
 */
12
class DBTextTest extends SapphireTest
13
{
14
15
    private $previousLocaleSetting = null;
16
17
    public function setUp()
18
    {
19
        parent::setUp();
20
        // clear the previous locale setting
21
        $this->previousLocaleSetting = null;
22
    }
23
24
    public function tearDown()
25
    {
26
        parent::tearDown();
27
        // If a test sets the locale, reset it on teardown
28
        if ($this->previousLocaleSetting) {
29
            setlocale(LC_CTYPE, $this->previousLocaleSetting);
30
        }
31
    }
32
33
    /**
34
     * Test {@link Text->LimitCharacters()}
35
     */
36
    public function providerLimitCharacters()
37
    {
38
        // Plain text values always encoded safely
39
        // HTML stored in non-html fields is treated literally.
40
        return [
41
            ['The little brown fox jumped over the lazy cow.', 'The little brown fox…'],
42
            ['<p>Short & Sweet</p>', '&lt;p&gt;Short &amp; Sweet&lt;/p&gt;'],
43
            ['This text contains &amp; in it', 'This text contains &amp;…'],
44
            ['Is an umault in schön?', 'Is an umault in schö…'],
45
        ];
46
    }
47
48
    /**
49
     * Test {@link Text->LimitCharacters()}
50
     *
51
     * @dataProvider providerLimitCharacters
52
     * @param        string $originalValue
53
     * @param        string $expectedValue
54
     */
55
    public function testLimitCharacters($originalValue, $expectedValue)
56
    {
57
        $textObj = DBField::create_field('Text', $originalValue);
58
        $result = $textObj->obj('LimitCharacters')->forTemplate();
59
        $this->assertEquals($expectedValue, $result);
60
    }
61
62
    /**
63
     * @return array
64
     */
65
    public function providerLimitCharactersToClosestWord()
66
    {
67
        return [
68
            // Standard words limited, ellipsis added if truncated
69
            ['Lorem ipsum dolor sit amet', 24, 'Lorem ipsum dolor sit…'],
70
71
            // Complete words less than the character limit don't get truncated, ellipsis not added
72
            ['Lorem ipsum', 24, 'Lorem ipsum'],
73
            ['Lorem', 24, 'Lorem'],
74
            ['', 24, ''],    // No words produces nothing!
75
76
            // Special characters are encoded safely
77
            ['Nice & Easy', 24, 'Nice &amp; Easy'],
78
79
            // HTML stored in non-html fields is treated literally.
80
            // If storing HTML you should use DBHTMLText instead
81
            ['<p>Lorem ipsum dolor sit amet</p>', 24, '&lt;p&gt;Lorem ipsum dolor…'],
82
            ['<p><span>Lorem ipsum dolor sit amet</span></p>', 24, '&lt;p&gt;&lt;span&gt;Lorem ipsum…'],
83
            ['<p>Lorem ipsum</p>', 24, '&lt;p&gt;Lorem ipsum&lt;/p&gt;'],
84
            ['Lorem &amp; ipsum dolor sit amet', 24, 'Lorem &amp;amp; ipsum dolor…'],
85
86
            ['Is an umault in schön or not?', 22, 'Is an umault in schön…'],
87
88
        ];
89
    }
90
91
    /**
92
     * Test {@link Text->LimitCharactersToClosestWord()}
93
     *
94
     * @dataProvider providerLimitCharactersToClosestWord
95
     *
96
     * @param string $originalValue Raw string input
97
     * @param int    $limit
98
     * @param string $expectedValue Expected template value
99
     */
100
    public function testLimitCharactersToClosestWord($originalValue, $limit, $expectedValue)
101
    {
102
        $textObj = DBField::create_field('Text', $originalValue);
103
        $result = $textObj->obj('LimitCharactersToClosestWord', [$limit])->forTemplate();
104
        $this->assertEquals($expectedValue, $result);
105
    }
106
107
    /**
108
     * Test {@link Text->LimitWordCount()}
109
     */
110
    public function providerLimitWordCount()
111
    {
112
        return [
113
            // Standard words limited, ellipsis added if truncated
114
            ['The little brown fox jumped over the lazy cow.', 3, 'The little brown…'],
115
            [' This text has white space around the ends ', 3, 'This text has…'],
116
117
            // Words less than the limit word count don't get truncated, ellipsis not added
118
            ['Two words', 3, 'Two words'],  // Two words shouldn't have an ellipsis
119
            ['These three words', 3, 'These three words'], // Three words shouldn't have an ellipsis
120
            ['One', 3, 'One'],  // Neither should one word
121
            ['', 3, ''],    // No words produces nothing!
122
123
            // Text with special characters
124
            ['Nice & Easy', 3, 'Nice &amp; Easy'],
125
            ['One & Two & Three', 3, 'One &amp; Two…'],
126
127
            // HTML stored in non-html fields is treated literally.
128
            // If storing HTML you should use DBHTMLText instead
129
            ['<p>Text inside a paragraph tag should also work</p>', 3, '&lt;p&gt;Text inside a…'],
130
            ['<p>Two words</p>', 3, '&lt;p&gt;Two words&lt;/p&gt;'],
131
132
            // Check UTF8
133
            ['Is an umault in schön or not?', 5, 'Is an umault in schön…'],
134
        ];
135
    }
136
137
    /**
138
     * Test {@link DBText->LimitWordCount()}
139
     *
140
     * @dataProvider providerLimitWordCount
141
     *
142
     * @param string $originalValue Raw string input
143
     * @param int    $limit         Number of words
144
     * @param string $expectedValue Expected template value
145
     */
146
    public function testLimitWordCount($originalValue, $limit, $expectedValue)
147
    {
148
        $textObj = DBField::create_field('Text', $originalValue);
149
        $result = $textObj->obj('LimitWordCount', [$limit])->forTemplate();
150
        $this->assertEquals($expectedValue, $result);
151
    }
152
153
    /**
154
     */
155
    public function providerLimitSentences()
156
    {
157
        return [
158
            ['', 2, ''],
159
            ['First sentence.', 2, 'First sentence.'],
160
            ['First sentence. Second sentence.', 2, 'First sentence. Second sentence.'],
161
162
            // HTML stored in non-html fields is treated literally.
163
            // If storing HTML you should use DBHTMLText instead
164
            ['<p>First sentence.</p>', 2, '&lt;p&gt;First sentence.&lt;/p&gt;'],
165
            ['<p>First sentence. Second sentence. Third sentence</p>', 2, '&lt;p&gt;First sentence. Second sentence.'],
166
167
            // Check UTF8
168
            ['Is schön. Isn\'t schön.', 1, 'Is schön.'],
169
        ];
170
    }
171
172
    /**
173
     * Test {@link DBText->LimitSentences()}
174
     *
175
     * @dataProvider providerLimitSentences
176
     * @param        string $originalValue
177
     * @param        int    $limit         Number of sentences
178
     * @param        string $expectedValue Expected template value
179
     */
180
    public function testLimitSentences($originalValue, $limit, $expectedValue)
181
    {
182
        $textObj = DBField::create_field('Text', $originalValue);
183
        $result = $textObj->obj('LimitSentences', [$limit])->forTemplate();
184
        $this->assertEquals($expectedValue, $result);
185
    }
186
187
    public function providerFirstSentence()
188
    {
189
        return [
190
            ['', ''],
191
            ['First sentence.', 'First sentence.'],
192
            ['First sentence. Second sentence', 'First sentence.'],
193
            ['First sentence? Second sentence', 'First sentence?'],
194
            ['First sentence! Second sentence', 'First sentence!'],
195
196
            // HTML stored in non-html fields is treated literally.
197
            // If storing HTML you should use DBHTMLText instead
198
            ['<br />First sentence.', '&lt;br /&gt;First sentence.'],
199
            ['<p>First sentence. Second sentence. Third sentence</p>', '&lt;p&gt;First sentence.'],
200
201
            // Check UTF8
202
            ['Is schön. Isn\'t schön.', 'Is schön.'],
203
        ];
204
    }
205
206
    /**
207
     * @dataProvider providerFirstSentence
208
     * @param string $originalValue
209
     * @param string $expectedValue
210
     */
211
    public function testFirstSentence($originalValue, $expectedValue)
212
    {
213
        $textObj = DBField::create_field('Text', $originalValue);
214
        $result = $textObj->obj('FirstSentence')->forTemplate();
215
        $this->assertEquals($expectedValue, $result);
216
    }
217
218
    /**
219
     * each test is in the format input, character limit, highlight, expected output
220
     *
221
     * @return array
222
     */
223
    public function providerContextSummary()
224
    {
225
        return [
226
            [
227
                'This is some text. It is a test',
228
                20,
229
                'test',
230
                '… text. It is a <mark>test</mark>'
231
            ],
232
            [
233
                // Retains case of original string
234
                'This is some test text. Test test what if you have multiple keywords.',
235
                50,
236
                'some test',
237
                'This is <mark>some</mark> <mark>test</mark> text.'
238
                . ' <mark>Test</mark> <mark>test</mark> what if you have…'
239
            ],
240
            [
241
                'Here is some text & HTML included',
242
                20,
243
                'html',
244
                '… text &amp; <mark>HTML</mark> inc…'
245
            ],
246
            [
247
                'A dog ate a cat while looking at a Foobar',
248
                100,
249
                'a',
250
                // test that it does not highlight too much (eg every a)
251
                'A dog ate a cat while looking at a Foobar',
252
            ],
253
            [
254
                'A dog ate a cat while looking at a Foobar',
255
                100,
256
                'ate',
257
                // it should highlight 3 letters or more.
258
                'A dog <mark>ate</mark> a cat while looking at a Foobar',
259
            ],
260
            [
261
                'both schön and können have umlauts',
262
                21,
263
                'schön',
264
                // check UTF8 support
265
                'both <mark>schön</mark> and können…',
266
            ],
267
            [
268
                'both schön and können have umlauts',
269
                21,
270
                '',
271
                // check non-existent search term
272
                'both schön and können…',
273
            ]
274
        ];
275
    }
276
277
    /**
278
     * each test is in the format input, word limit, add ellipsis (false or string), expected output
279
     *
280
     * @return array
281
     */
282
    public function providerSummary()
283
    {
284
        return [
285
            [
286
                'This is some text. It is a test',
287
                3,
288
                false,
289
                'This is some…',
290
            ],
291
            [
292
                // check custom ellipsis
293
                'This is a test text in a longer sentence and a custom ellipsis.',
294
                8,
295
                '...', // regular dots instead of the ellipsis character
296
                'This is a test text in a longer...',
297
            ],
298
            [
299
                'both schön and können have umlauts',
300
                5,
301
                false,
302
                'both schön and können have…',
303
            ],
304
            [
305
                // check invalid UTF8 handling — input is an invalid UTF sequence, output should be empty string
306
                "\xf0\x28\x8c\xbc",
307
                50,
308
                false,
309
                '',
310
            ],
311
        ];
312
    }
313
314
    /**
315
     * @dataProvider providerContextSummary
316
     * @param string $originalValue Input
317
     * @param int    $limit         Number of characters
318
     * @param string $keywords      Keywords to highlight
319
     * @param string $expectedValue Expected output (XML encoded safely)
320
     */
321
    public function testContextSummary($originalValue, $limit, $keywords, $expectedValue)
322
    {
323
        $text = DBField::create_field('Text', $originalValue);
324
        $result = $text->obj('ContextSummary', [$limit, $keywords])->forTemplate();
325
        // it should highlight 3 letters or more.
326
        $this->assertEquals($expectedValue, $result);
327
    }
328
329
    public function testRAW()
330
    {
331
        $data = DBField::create_field('Text', 'This &amp; This');
332
        $this->assertEquals($data->RAW(), 'This &amp; This');
333
    }
334
335
    public function testXML()
336
    {
337
        $data = DBField::create_field('Text', 'This & This');
338
        $this->assertEquals($data->XML(), 'This &amp; This');
339
    }
340
341
    public function testHTML()
342
    {
343
        $data = DBField::create_field('Text', 'This & This');
344
        $this->assertEquals($data->HTML(), 'This &amp; This');
345
    }
346
347
    public function testJS()
348
    {
349
        $data = DBField::create_field('Text', '"this is a test"');
350
        $this->assertEquals($data->JS(), '\"this is a test\"');
351
    }
352
353
    public function testATT()
354
    {
355
        $data = DBField::create_field('Text', '"this is a test"');
356
        $this->assertEquals($data->ATT(), '&quot;this is a test&quot;');
357
    }
358
359
    public function testValidUtf8()
360
    {
361
        // Install a UTF-8 locale
362
        $this->previousLocaleSetting = setlocale(LC_CTYPE, 0);
363
        $locales = ['en_US.UTF-8', 'en_NZ.UTF-8', 'de_DE.UTF-8'];
364
        $localeInstalled = false;
365
        foreach ($locales as $locale) {
366
            if ($localeInstalled = setlocale(LC_CTYPE, $locale)) {
367
                break;
368
            }
369
        }
370
371
        // If the system doesn't have any of the UTF-8 locales, exit early
372
        if ($localeInstalled === false) {
373
            $this->markTestIncomplete('Unable to run this test because of missing locale!');
374
            return;
375
        }
376
377
        $problematicText = html_entity_decode('This is a&nbsp;Test with non-breaking&nbsp;space!', ENT_COMPAT, 'UTF-8');
378
379
        $textObj = new DBText('Test');
380
        $textObj->setValue($problematicText);
381
382
        $this->assertTrue(mb_check_encoding($textObj->FirstSentence(), 'UTF-8'));
383
    }
384
385
    public function testDefaultEllipsis()
386
    {
387
        $textObj = new DBText('Test');
388
        $this->assertEquals('…', $textObj->defaultEllipsis());
389
    }
390
391
    /**
392
     * @dataProvider providerSummary
393
     * @param string $originalValue Input
394
     * @param int    $words         Number of words
395
     * @param mixed  $add           Ellipsis (false for default or string for custom text)
396
     * @param string $expectedValue Expected output (XML encoded safely)
397
     */
398
    public function testSummary($originalValue, $words, $add, $expectedValue)
399
    {
400
        $text = DBField::create_field(DBText::class, $originalValue);
401
        $result = $text->obj('Summary', [$words, $add])->forTemplate();
402
        $this->assertEquals($expectedValue, $result);
403
    }
404
}
405