refactor: consolidate JS toggle components, grid query parsers, and add tests

JS components: migrate app-custom-field-options-toggle, app-color-default-toggle,
and app-settings-telemetry to shared conditional-controls factory/utility,
removing duplicated syncControlState logic and init boilerplate.

grid.php: extract gridQueryCsvInput() to DRY up 3 CSV parsers, simplify
multi_csv handler via gridNormalizeLabelList, delegate order type to gridQueryEnum.

Tests: add 23 SearchQueryNormalizer tests (LIKE escaping, wildcards, Unicode)
and 7 additional Crypto edge-case tests (empty input, missing fields, special
chars, binary content, truncation).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 22:22:15 +02:00
parent 7496903544
commit 99f8b55d49
6 changed files with 297 additions and 180 deletions

View File

@@ -0,0 +1,137 @@
<?php
namespace MintyPHP\Tests\Unit\Support;
use MintyPHP\Support\Search\SearchQueryNormalizer;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
final class SearchQueryNormalizerTest extends TestCase
{
// ── normalizeLikeQuery ──
public function testNormalizeLikeQueryReturnsEmptyForBlankInput(): void
{
self::assertSame('', SearchQueryNormalizer::normalizeLikeQuery(''));
self::assertSame('', SearchQueryNormalizer::normalizeLikeQuery(' '));
}
public function testNormalizeLikeQueryWrapsWithWildcards(): void
{
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('hello'));
}
public function testNormalizeLikeQueryDoesNotDoubleWrapLeadingWildcard(): void
{
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('*hello'));
}
public function testNormalizeLikeQueryDoesNotDoubleWrapTrailingWildcard(): void
{
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('hello*'));
}
public function testNormalizeLikeQueryDoesNotDoubleWrapBothWildcards(): void
{
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('*hello*'));
}
public function testNormalizeLikeQueryEscapesBackslash(): void
{
self::assertSame('%foo\\\\bar%', SearchQueryNormalizer::normalizeLikeQuery('foo\\bar'));
}
public function testNormalizeLikeQueryEscapesUnderscore(): void
{
self::assertSame('%foo\\_bar%', SearchQueryNormalizer::normalizeLikeQuery('foo_bar'));
}
public function testNormalizeLikeQueryConvertsAsterisksToPercent(): void
{
self::assertSame('%foo%bar%', SearchQueryNormalizer::normalizeLikeQuery('foo*bar'));
}
public function testNormalizeLikeQueryCombinesEscapingAndWildcards(): void
{
// Input: "a_b*c\d" → underscores escaped, * becomes %, backslash escaped, wrapped
self::assertSame('%a\\_b%c\\\\d%', SearchQueryNormalizer::normalizeLikeQuery('a_b*c\\d'));
}
public function testNormalizeLikeQueryTrimsWhitespace(): void
{
self::assertSame('%search%', SearchQueryNormalizer::normalizeLikeQuery(' search '));
}
public function testNormalizeLikeQuerySingleCharacter(): void
{
self::assertSame('%x%', SearchQueryNormalizer::normalizeLikeQuery('x'));
}
public function testNormalizeLikeQueryOnlyWildcard(): void
{
self::assertSame('%', SearchQueryNormalizer::normalizeLikeQuery('*'));
}
public function testNormalizeLikeQueryMultipleConsecutiveWildcards(): void
{
self::assertSame('%a%%%b%', SearchQueryNormalizer::normalizeLikeQuery('a***b'));
}
public function testNormalizeLikeQueryUnicodeInput(): void
{
self::assertSame('%Ünterström%', SearchQueryNormalizer::normalizeLikeQuery('Ünterström'));
}
// ── normalizeScoreQuery ──
public function testNormalizeScoreQueryReturnsEmptyForBlankInput(): void
{
self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery(''));
self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery(' '));
}
public function testNormalizeScoreQueryStripsAsterisks(): void
{
self::assertSame('hello', SearchQueryNormalizer::normalizeScoreQuery('*hello*'));
}
public function testNormalizeScoreQueryStripsPercent(): void
{
self::assertSame('hello', SearchQueryNormalizer::normalizeScoreQuery('%hello%'));
}
public function testNormalizeScoreQueryStripsUnderscore(): void
{
self::assertSame('foobar', SearchQueryNormalizer::normalizeScoreQuery('foo_bar'));
}
public function testNormalizeScoreQueryStripsAllWildcardTypes(): void
{
self::assertSame('abc', SearchQueryNormalizer::normalizeScoreQuery('*a%b_c*'));
}
public function testNormalizeScoreQueryPreservesNormalText(): void
{
self::assertSame('search term', SearchQueryNormalizer::normalizeScoreQuery('search term'));
}
public function testNormalizeScoreQueryTrimsWhitespace(): void
{
self::assertSame('query', SearchQueryNormalizer::normalizeScoreQuery(' query '));
}
public function testNormalizeScoreQueryOnlyWildcards(): void
{
self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery('*%_'));
}
public function testNormalizeScoreQueryPreservesBackslash(): void
{
self::assertSame('a\\b', SearchQueryNormalizer::normalizeScoreQuery('a\\b'));
}
public function testNormalizeScoreQueryUnicodeInput(): void
{
self::assertSame('Müller', SearchQueryNormalizer::normalizeScoreQuery('Müller'));
}
}