. * * Created by PhpStorm. * User: benlo * Date: 25/03/19 * Time: 21:36 */ namespace Friendica\Test\src\Content; use Friendica\Content\Smilies; use Friendica\Core\Hook; use Friendica\DI; use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Test\FixtureTest; class SmiliesTest extends FixtureTest { protected function setUp(): void { parent::setUp(); DI::config()->set('system', 'no_smilies', false); Hook::register('smilie', 'tests/Util/SmileyWhitespaceAddon.php', 'add_test_unicode_smilies'); Hook::loadHooks(); } public function dataLinks() { return [ /** @see https://github.com/friendica/friendica/pull/6933 */ 'bug-6933-1' => [ 'data' => '/', 'smilies' => ['texts' => [], 'icons' => []], 'expected' => '/', ], 'bug-6933-2' => [ 'data' => 'code', 'smilies' => ['texts' => [], 'icons' => []], 'expected' => 'code', ], ]; } /** * Test replace smilies in different texts * * @dataProvider dataLinks * * @param string $text Test string * @param array $smilies List of smilies to replace * @param string $expected Expected result * * @throws InternalServerErrorException */ public function testReplaceFromArray(string $text, array $smilies, string $expected) { $output = Smilies::replaceFromArray($text, $smilies); self::assertEquals($expected, $output); } public function dataIsEmojiPost(): array { return [ 'emoji' => [ 'expected' => true, 'body' => '๐Ÿ‘€', ], 'emojis' => [ 'expected' => true, 'body' => '๐Ÿ‘€๐Ÿคท', ], 'emoji+whitespace' => [ 'expected' => true, 'body' => ' ๐Ÿ‘€ ', ], 'empty' => [ 'expected' => false, 'body' => '', ], 'whitespace' => [ 'expected' => false, 'body' => ' ', ], 'emoji+ASCII' => [ 'expected' => false, 'body' => '๐Ÿคทa', ], 'HTML entity whitespace' => [ 'expected' => false, 'body' => ' ', ], 'HTML entity else' => [ 'expected' => false, 'body' => '°', ], 'emojis+HTML whitespace' => [ 'expected' => true, 'body' => '๐Ÿ‘€ ๐Ÿคท', ], 'emojis+HTML else' => [ 'expected' => false, 'body' => '๐Ÿ‘€<๐Ÿคท', ], 'zwj' => [ 'expected' => true, 'body' => '๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€', ], 'zwj+whitespace' => [ 'expected' => true, 'body' => ' ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€ ', ], 'zwj+HTML whitespace' => [ 'expected' => true, 'body' => ' ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€ ', ], ]; } /** * @dataProvider dataIsEmojiPost * * @param bool $expected * @param string $body * @return void */ public function testIsEmojiPost(bool $expected, string $body) { $this->assertEquals($expected, Smilies::isEmojiPost($body)); } public function dataReplace(): array { $data = [ 'simple-1' => [ 'expected' => 'alt=":-p"', 'body' => ':-p', ], 'simple-1' => [ 'expected' => 'alt=":-p"', 'body' => ' :-p ', ], 'word-boundary-1' => [ 'expected' => ':-pppp', 'body' => ':-pppp', ], 'word-boundary-2' => [ 'expected' => '~friendicaca', 'body' => '~friendicaca', ], 'symbol-boundary-1' => [ 'expected' => 'alt=":-p"', 'body' => '(:-p)', ], 'hearts-1' => [ 'expected' => 'โค (โค) โค', 'body' => '<3 (<3) <3', ], 'hearts-8' => [ 'expected' => '(โคโคโคโคโคโคโคโค)', 'body' => '(<33333333)', ], 'no-hearts-1' => [ 'expected' => '(<30)', 'body' => '(<30)', ], 'no-hearts-2' => [ 'expected' => '(3<33)', 'body' => '(3<33)', ], 'space' => [ 'expected' => 'alt="smiley-heart"', 'body' => ':smiley heart 333:', ], 'substitution-1' => [ 'expected' => '🔥', 'body' => 'โฝ•', ], 'substitution-2' => [ 'expected' => '🤗', 'body' => ':hugging face:', ], 'substitution-3' => [ 'expected' => '🤭', 'body' => ':face with hand over mouth:', ], 'mixed' => [ 'expected' => '🔥 🤭 invalid:hugging face: 🤗', 'body' => 'โฝ• :face with hand over mouth: invalid:hugging face: :hugging face:', ], ]; foreach ([':-[', ':-D', 'o.O'] as $emoji) { foreach (['A', '_', ':', '-'] as $prefix) { foreach (['', ' ', 'A', ':', '-'] as $suffix) { $no_smile = ($prefix !== '' && ctype_alnum($prefix)) || ($suffix !== '' && ctype_alnum($suffix)); $s = $prefix . $emoji . $suffix; $data[] = [ 'expected' => $no_smile ? $s : 'alt="' . $emoji . '"', 'body' => $s, ]; } } } return $data; } /** * @dataProvider dataReplace * * @param string $expected * @param string $body */ public function testReplace(string $expected, string $body) { $result = Smilies::replace($body); $this->assertStringContainsString($expected, $result); } public function dataExtractUsedSmilies(): array { return [ 'symbols' => [ 'expected' => ['p', 'heart', 'embarrassed', 'kiss'], 'body' => ':-p <3 ":-[:-"', 'normalized' => ':p: :heart: ":embarrassed::kiss:', ], 'single-smiley' => [ 'expected' => ['like'], 'body' => ':like', 'normalized' => ':like:', ], 'multiple-smilies' => [ 'expected' => ['like', 'dislike'], 'body' => ':like :dislike', 'normalized' => ':like: :dislike:', ], 'nosmile' => [ 'expected' => [], 'body' => '[nosmile] :like :like', 'normalized' => '[nosmile] :like :like' ], 'in-code' => [ 'expected' => [], 'body' => '[code]:like :like :like[/code]', 'normalized' => '[code]:like :like :like[/code]' ], '~friendica' => [ 'expected' => ['friendica'], 'body' => '~friendica', 'normalized' => ':friendica:' ], 'space' => [ 'expected' => ['smileyheart333'], 'body' => ':smiley heart 333:', 'normalized' => ':smileyheart333:' ], 'substitution-1' => [ 'expected' => [], 'body' => 'โฝ•', 'normalized' => '🔥', ], 'substitution-2' => [ 'expected' => [], 'body' => ':hugging face:', 'normalized' => '🤗', ], 'substitution-3' => [ 'expected' => [], 'body' => ':face with hand over mouth:', 'normalized' => '🤭', ], 'mixed' => [ 'expected' => [], 'body' => 'โฝ• :face with hand over mouth: invalid:hugging face: :hugging face:', 'normalized' => '🔥 🤭 invalid:hugging face: 🤗', ], ]; } /** * @dataProvider dataExtractUsedSmilies * * @param array $expected * @param string $body * @param stirng $normalized */ public function testExtractUsedSmilies(array $expected, string $body, string $normalized) { $extracted = Smilies::extractUsedSmilies($body, $converted); $expected = array_fill_keys($expected, true); $this->assertEquals($normalized, $converted); foreach (array_keys($extracted) as $shortcode) { $this->assertArrayHasKey($shortcode, $expected); } $this->assertEquals(count($expected), count($extracted)); } }