mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-17 03:04:47 -05:00
335 lines
16 KiB
PHP
335 lines
16 KiB
PHP
<?php
|
|
|
|
namespace Gazelle;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use Gazelle\Enum\AvatarDisplay;
|
|
use Gazelle\Enum\AvatarSynthetic;
|
|
use GazelleUnitTest\Helper;
|
|
|
|
class TwigTest extends TestCase {
|
|
protected User $user;
|
|
|
|
public function setUp(): void {
|
|
$this->user = Helper::makeUser('twig.' . randomString(6), 'twig');
|
|
$this->user->setField('PermissionID', SYSOP)->modify();
|
|
}
|
|
|
|
public function tearDown(): void {
|
|
$this->user->remove();
|
|
}
|
|
|
|
protected static function twig(string $template): \Twig\TemplateWrapper {
|
|
return Util\Twig::factory(new Manager\User())->createTemplate($template);
|
|
}
|
|
|
|
public function testDominator(): void {
|
|
new Util\Dominator()->flush(); // in case anything has already been set
|
|
$twig = Util\Twig::factory(new Manager\User());
|
|
$twig->createTemplate("{{ dom.click('#id', \"$('#id').frob(); return false;\") }}")->render();
|
|
$expected = <<<END
|
|
<script type="text/javascript">document.addEventListener('DOMContentLoaded', () => {
|
|
\$('#id').click(() => {\$('#id').frob(); return false;});
|
|
})</script>
|
|
END;
|
|
$this->assertEquals($expected, $twig->createTemplate('{{ dom.emit|raw }}')->render(), 'twig-dominator');
|
|
}
|
|
|
|
public function testFilter(): void {
|
|
$article = self::twig('{{ word|article }}');
|
|
$this->assertEquals('a', $article->render(['word' => 'consonant']), 'twig-article-a');
|
|
$this->assertEquals('an', $article->render(['word' => 'anticonsonant']), 'twig-article-an');
|
|
|
|
$this->assertEquals('YmxvYg', self::twig('{{ b|b64 }}')->render(['b' => 'blob']), 'twig-b64');
|
|
|
|
// badge_list is weird
|
|
|
|
$this->assertEquals(
|
|
'<strong>bold</strong>',
|
|
self::twig('{{ text|bb_format }}')->render(['text' => '[b]bold[/b]']),
|
|
'twig-bb-format'
|
|
);
|
|
|
|
if (IMAGE_CACHE_ENABLED) {
|
|
$this->assertStringStartsWith(
|
|
'<img loading="lazy" class="scale_image" onclick="lightbox.init(this, $(this).width());" alt="' . IMAGE_CACHE_HOST . '/f/full/',
|
|
self::twig('{{ text|bb_forum }}')->render(['text' => '[img=https://example.com/image.jpg]']),
|
|
'twig-bb-forum'
|
|
);
|
|
} else {
|
|
$this->assertStringStartsWith(
|
|
'<img loading="lazy" class="scale_image" onclick="lightbox.init(this, $(this).width());" alt="https://example.com/image.jpg"',
|
|
self::twig('{{ text|bb_forum }}')->render(['text' => '[img=https://example.com/image.jpg]']),
|
|
'twig-bb-forum'
|
|
);
|
|
}
|
|
|
|
$checked = self::twig('{%- from "macro/form.twig" import checked -%}<input type="checkbox" name="test"{{ checked(truth) }} />');
|
|
$this->assertEquals(
|
|
'<input type="checkbox" name="test" checked />',
|
|
$checked->render(['truth' => true]),
|
|
'twig-checked-true'
|
|
);
|
|
$this->assertEquals(
|
|
'<input type="checkbox" name="test" />',
|
|
$checked->render(['truth' => false]),
|
|
'twig-checked-false'
|
|
);
|
|
|
|
$sth = new Util\SortableTableHeader('alpha', [
|
|
'alpha' => ['dbColumn' => 'one', 'defaultSort' => 'desc', 'text' => 'First'],
|
|
'beta' => ['dbColumn' => 'two', 'defaultSort' => 'desc', 'text' => 'Second'],
|
|
]);
|
|
$heading = self::twig('{{ heading|column("alpha") }}');
|
|
$this->assertEquals(
|
|
'<a href="?order=alpha&sort=asc">First</a> ↑',
|
|
$heading->render(['heading' => $sth]),
|
|
'twig-heading'
|
|
);
|
|
|
|
$linkify = self::twig('{{ url|linkify }}');
|
|
$this->assertEquals(
|
|
'<a href="/index.php">/index.php</a>',
|
|
$linkify->render(['url' => '/index.php']),
|
|
'twig-linkify-index'
|
|
);
|
|
$this->assertEquals(
|
|
'<a href="' . SITE_URL . '/index.php">' . SITE_URL . '/index.php</a>',
|
|
$linkify->render(['url' => SITE_URL . '/index.php']),
|
|
'twig-linkify-site-index'
|
|
);
|
|
|
|
$this->assertEquals('3.00 MiB', self::twig('{{ size|octet_size }}')->render(['size' => 1024 * 1024 * 3]), 'twig-octet-3.00MiB');
|
|
$this->assertEquals('3 MiB', self::twig('{{ size|octet_size(0) }}')->render(['size' => 1024 * 1024 * 3]), 'twig-octet-3MiB');
|
|
$this->assertEquals('3.675 GiB', self::twig('{{ size|octet_size(3) }}')->render(['size' => 1024 * 1024 * 1024 * 3.675]), 'twig-octet-3.675GiB');
|
|
$this->assertEquals('3.68 GiB', self::twig('{{ size|octet_size(2) }}')->render(['size' => 1024 * 1024 * 1024 * 3.675]), 'twig-octet-3.68GiB');
|
|
$this->assertEquals('3.7 GiB', self::twig('{{ size|octet_size(1) }}')->render(['size' => 1024 * 1024 * 1024 * 3.675]), 'twig-octet-3.7GiB');
|
|
$this->assertEquals('4 GiB', self::twig('{{ size|octet_size(0) }}')->render(['size' => 1024 * 1024 * 1024 * 3.675]), 'twig-octet-4GiB');
|
|
|
|
$this->assertEquals('', self::twig('{{ number|plural }}')->render(['number' => 1]), 'twig-plural-1');
|
|
$this->assertEquals('s', self::twig('{{ number|plural }}')->render(['number' => 2]), 'twig-plural-2');
|
|
$this->assertEquals('es', self::twig('{{ number|plural("es") }}')->render(['number' => 3]), 'twig-plural-3');
|
|
|
|
$this->assertEquals('', self::twig('{{ value|repeat(0) }}')->render(['value' => 'go']), 'twig-repeat-0');
|
|
$this->assertEquals('gogo', self::twig('{{ value|repeat(2) }}')->render(['value' => 'go']), 'twig-repeat-2');
|
|
$this->assertEquals('gogogogogo', self::twig('{{ value|repeat(5) }}')->render(['value' => 'go']), 'twig-repeat-5');
|
|
$this->assertEquals('gogogo', self::twig('{{ value|repeat(n) }}')->render(['value' => 'go', 'n' => 3]), 'twig-repeat-3');
|
|
|
|
$this->assertEquals('abc "def"…', self::twig('{{ value|shorten(10) }}')->render(['value' => 'abc "def" ghi']), 'twig-shorten-10');
|
|
|
|
$this->assertEquals(
|
|
'2 hours and 7 mins',
|
|
self::twig('{{ value|time_interval }}')->render(['value' => 3600 * 2 + 7 * 60]),
|
|
'twig-time-ago'
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'30 mins',
|
|
self::twig('{{ value|time_interval }}')->render(['value' => 1800.125]),
|
|
'twig-time-float-ago'
|
|
);
|
|
|
|
$this->assertMatchesRegularExpression(
|
|
'@^<span class="time tooltip" title="[^"]+">1 hour ago</span>$@',
|
|
self::twig('{{ value|time_diff }}')->render(['value' => date("Y-m-d H:i:s", strtotime("-1 hour"))]),
|
|
'twig-time-diff'
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'2h7s',
|
|
self::twig('{{ value|time_compact }}')->render(['value' => 3600 * 2 + 7]),
|
|
'twig-time-interval'
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'2',
|
|
self::twig('{{ value|token_count }}')->render([
|
|
'value' => new Manager\SiteOption()->freeTokenSize() * 2 - 1
|
|
]),
|
|
'twig-token-count-2'
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'3',
|
|
self::twig('{{ value|token_count }}')->render([
|
|
'value' => new Manager\SiteOption()->freeTokenSize() * 2 + 1
|
|
]),
|
|
'twig-token-count-3'
|
|
);
|
|
|
|
$this->assertEquals('✅', self::twig('{{ value|truth }}')->render(['value' => true]), 'twig-truth-true');
|
|
$this->assertEquals('❌', self::twig('{{ value|truth }}')->render(['value' => false]), 'twig-truth-false');
|
|
|
|
$this->assertEquals('First time', self::twig('{{ value|ucfirst }}')->render(['value' => 'first time']), 'twig-ucfirst-1');
|
|
$this->assertEquals('A Day In The Life', self::twig('{{ value|ucfirstall }}')->render(['value' => 'a day in the life']), 'twig-ucfirstall');
|
|
|
|
Util\Twig::setViewer($this->user);
|
|
$this->assertEquals(
|
|
"<a href=\"user.php?id={$this->user->id}\">{$this->user->username()}</a>",
|
|
self::twig('{{ user_id|user_url }}')->render(['user_id' => $this->user->id]),
|
|
'twig-user-url'
|
|
);
|
|
$donor = new User\Donor($this->user);
|
|
$donor->donate(
|
|
amount: 20,
|
|
xbtRate: 0.05,
|
|
source: 'phpunit twig source',
|
|
reason: 'phpunit twig reason',
|
|
);
|
|
$this->assertMatchesRegularExpression(
|
|
"@^<a class=\"username\" href=\"user.php\?id={$this->user->id}\">{$this->user->username()}</a><a target=\"_blank\" href=\"[^\"]+\"><img class=\"donor_icon tooltip\" src=\"[^\"]+\" (?:alt=\"[^\"]+\" )?(?:title=\"[^\"]+\" )?/></a> \(Sysop\)$@",
|
|
self::twig('{{ user_id|user_full }}')->render(['user_id' => $this->user->id]),
|
|
'twig-user-full'
|
|
);
|
|
|
|
$status = self::twig('{{ user_id|user_status(viewer) }}');
|
|
$this->assertEquals(
|
|
"<a target=\"_blank\" href=\"donate.php\"><img class=\"donor_icon tooltip\" src=\"/static/common/symbols/donor_6.png\" title=\"Donor\" /></a>",
|
|
$status->render(['user_id' => $this->user->id, 'viewer' => $this->user]),
|
|
'twig-user-status'
|
|
);
|
|
$donor->remove();
|
|
Helper::flushDonationMonth(1);
|
|
}
|
|
|
|
public function testImageCache(): void {
|
|
$imageCache = self::twig('{{ image|image_cache }}');
|
|
$this->assertStringStartsWith(
|
|
IMAGE_CACHE_HOST . '/i/full/',
|
|
$imageCache->render(['image' => 'https://example.com/image.url']),
|
|
'twig-image-full-enabled'
|
|
);
|
|
|
|
$imageCache = self::twig('{{ image|image_cache(height, width) }}');
|
|
$this->assertStringStartsWith(
|
|
IMAGE_CACHE_HOST . '/i/64x96/',
|
|
$imageCache->render(['image' => 'https://example.com/image.url', 'height' => 64, 'width' => 96]),
|
|
'twig-image-64x96'
|
|
);
|
|
$this->assertStringStartsWith(
|
|
IMAGE_CACHE_HOST . '/i/256x/',
|
|
$imageCache->render(['image' => 'https://example.com/image.url', 'height' => 256]),
|
|
'twig-image-height-256'
|
|
);
|
|
$this->assertStringStartsWith(
|
|
IMAGE_CACHE_HOST . '/i/x480/',
|
|
$imageCache->render(['image' => 'https://example.com/image.url', 'width' => 480]),
|
|
'twig-image-width-480'
|
|
);
|
|
|
|
$this->assertStringStartsWith(
|
|
'<img loading="lazy" class="scale_image" onclick="lightbox.init(this, $(this).width());" alt="' . IMAGE_CACHE_HOST . '/f/full/',
|
|
self::twig('{{ text|bb_forum }}')->render(['text' => '[img=https://example.com/image.jpg]']),
|
|
'twig-bb-forum'
|
|
);
|
|
}
|
|
|
|
public function testImageProxy(): void {
|
|
$imageCache = self::twig('{{ image|image_proxy(active) }}');
|
|
$image = $imageCache->render(['image' => 'https://example.com/image.url', 'active' => true]);
|
|
$this->assertStringStartsWith(IMAGE_CACHE_HOST . '/i/full/', $image, 'twig-image-proxy-spec');
|
|
$this->assertStringEndsWith('/proxy', $image, 'twig-image-proxy-end');
|
|
|
|
$image = $imageCache->render(['image' => 'https://example.com/image.url', 'active' => false]);
|
|
$this->assertStringEndsNotWith('/proxy', $image, 'twig-image-no-proxy-end');
|
|
}
|
|
|
|
public function testFunction(): void {
|
|
Base::setRequestContext(new RequestContext('/index.php', '127.0.0.1', ''));
|
|
Util\Twig::setViewer($this->user);
|
|
$this->assertStringStartsWith('<!DOCTYPE html>', self::twig('{{ header("page") }}')->render(), 'twig-function-header');
|
|
|
|
$current = new User\Session($this->user)->create([
|
|
'keep-logged' => '0',
|
|
'browser' => [
|
|
'Browser' => 'phpunit',
|
|
'BrowserVersion' => '1.0',
|
|
'OperatingSystem' => 'phpunit/OS',
|
|
'OperatingSystemVersion' => '1.0',
|
|
],
|
|
'ipaddr' => '127.0.0.1',
|
|
'useragent' => 'phpunit',
|
|
]);
|
|
global $SessionID;
|
|
$SessionID = $current['SessionID'];
|
|
$this->assertStringEndsWith("</body>\n</html>\n", self::twig('{{ footer() }}')->render(), 'twig-function-footer');
|
|
|
|
$this->assertEquals(
|
|
'http://localhost/?arg=abc',
|
|
self::twig('{{ build_url("http://localhost/", {"arg": arg}) }}')
|
|
->render(['arg' => 'abc']),
|
|
'twig-function-build-url-1'
|
|
);
|
|
$this->assertEquals(
|
|
'http://localhost/?arg=abc&id=10',
|
|
self::twig('{{ build_url("http://localhost/", {"arg": arg, "id": id}) }}')
|
|
->render(['arg' => 'abc', 'id' => 10]),
|
|
'twig-function-build-url-2'
|
|
);
|
|
$this->assertEquals(
|
|
'http://localhost/index?x=123&arg=def',
|
|
self::twig('{{ build_url("http://localhost/index?x=123", {"arg": arg}) }}')
|
|
->render(['arg' => 'def']),
|
|
'twig-function-build-url-3'
|
|
);
|
|
$this->assertEquals(
|
|
'http://localhost/index?x=123&arg=def&id=20',
|
|
self::twig('{{ build_url("http://localhost/index?x=123", {"arg": arg, "id": id}) }}')
|
|
->render(['arg' => 'def', 'id' => 20]),
|
|
'twig-function-build-url-4'
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'127.0.0.1 <a href="user.php?action=search&ip_history=on&matchtype=strict&ip=127.0.0.1" title="Search" class="brackets tooltip">S</a>',
|
|
self::twig('{{ ipaddr(ip) }}')->render(['ip' => '127.0.0.1']),
|
|
'twig-function-ipaddr'
|
|
);
|
|
|
|
// these will fail many, many, many years from now
|
|
$this->assertEquals(6, strlen(self::twig('{{ mtime(asset) }}')->render(['asset' => 'blank.gif'])), 'twig-function-mtime-file');
|
|
$this->assertEquals(6, strlen(self::twig('{{ mtime_scss(asset) }}')->render(['asset' => 'global.scss'])), 'twig-function-mtime-scss');
|
|
|
|
$this->assertEquals(
|
|
'<span class="tooltip r20" title="2.00000">2.00</span>',
|
|
self::twig('{{ ratio(up, down) }}')->render(['up' => 100, 'down' => 50]),
|
|
'twig-function-ratio-2'
|
|
);
|
|
$this->assertEquals(
|
|
'<span class="tooltip r10" title="1.00000">1.00</span>',
|
|
self::twig('{{ ratio(up, down) }}')->render(['up' => 100, 'down' => 100]),
|
|
'twig-function-ratio-1'
|
|
);
|
|
$this->assertEquals(
|
|
'<span class="tooltip r05" title="0.50000">0.50</span>',
|
|
self::twig('{{ ratio(up, down) }}')->render(['up' => 50, 'down' => 100]),
|
|
'twig-function-ratio-0.5'
|
|
);
|
|
$this->assertEquals(
|
|
'<span class="tooltip r00" title="0.00000">0.00</span>',
|
|
self::twig('{{ ratio(up, down) }}')->render(['up' => 0, 'down' => 100]),
|
|
'twig-function-ratio-0'
|
|
);
|
|
$this->assertEquals(
|
|
'<span class="tooltip r99" title="Infinite">∞</span>',
|
|
self::twig('{{ ratio(up, down) }}')->render(['up' => 50, 'down' => 0]),
|
|
'twig-function-ratio-infin'
|
|
);
|
|
|
|
$this->assertEquals(120, self::twig('{{ upscale(value) }}')->render(['value' => 120]), 'twig-upscale-120');
|
|
$this->assertEquals(130, self::twig('{{ upscale(value) }}')->render(['value' => 121]), 'twig-upscale-121');
|
|
$this->assertEquals(130, self::twig('{{ upscale(value) }}')->render(['value' => 129]), 'twig-upscale-129');
|
|
|
|
$this->assertEquals(48000, self::twig('{{ upscale(value) }}')->render(['value' => 47133]), 'twig-upscale-47133');
|
|
}
|
|
|
|
public function testTest(): void {
|
|
$this->assertEquals('yes', self::twig('{% if value is nan %}yes{% endif %}')->render(['value' => sqrt(-1)]), 'twig-test-nan');
|
|
|
|
$this->assertEquals(
|
|
'yes',
|
|
self::twig('{% if value is request_fill %}yes{% endif %}')->render(['value' => new Contest\RequestFill(0, '', '')]),
|
|
'twig-test-contest-request-fill'
|
|
);
|
|
}
|
|
}
|