Skip to content

Commit 1a3e0ec

Browse files
committed
case-insensitive header key comparison
1 parent 9983829 commit 1a3e0ec

File tree

2 files changed

+104
-7
lines changed

2 files changed

+104
-7
lines changed

src/Model/Server/HeaderRule.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ public function __construct(Exception $exceptionFactory, Validated $validated)
2929
/**
3030
* @param non-empty-string $key
3131
*/
32-
public function key(string $key): StringRule
32+
public function key(string $key, bool $caseSensitive = false): StringRule
3333
{
34-
$value = $this->validated->value();
35-
$value = $value[$key] ?? [];
36-
$value = array_pop($value);
34+
$values = $this->headerValues($caseSensitive);
35+
$values = $values[$caseSensitive ? $key : strtolower($key)] ?? [];
36+
$value = array_pop($values);
3737
/** @var mixed $value */
3838
return new StringRule($this->exceptionFactory, new RuleChain(), new Validated($value), 'Request header: '.$key);
3939
}
@@ -44,10 +44,10 @@ public function key(string $key): StringRule
4444
* @param callable(StringRule): TMapped $callable
4545
* @return Collection<TMapped>
4646
*/
47-
public function keyOf(string $key, callable $callable): Collection
47+
public function keyOf(string $key, callable $callable, bool $caseSensitive = false): Collection
4848
{
49-
$value = $this->validated->value();
50-
$values = $value[$key] ?? null;
49+
$values = $this->headerValues($caseSensitive);
50+
$values = $values[$caseSensitive ? $key : strtolower($key)] ?? null;
5151
/** @var mixed $values */
5252
return new Collection(
5353
$this->exceptionFactory,
@@ -57,4 +57,17 @@ public function keyOf(string $key, callable $callable): Collection
5757
fn (TypedKey $index) => $callable($index->string())
5858
);
5959
}
60+
61+
/**
62+
* @return array<array<string>>|null
63+
*/
64+
private function headerValues(bool $caseSensitive): ?array
65+
{
66+
$values = $this->validated->value();
67+
if ($caseSensitive) {
68+
return $values;
69+
}
70+
71+
return $values !== null ? array_change_key_case($values, CASE_LOWER) : $values;
72+
}
6073
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PHPUnit\Framework\TestCase;
6+
use SimpleAsFuck\ApiToolkit\Model\Server\HeaderRule;
7+
use SimpleAsFuck\Validator\Factory\UnexpectedValueException;
8+
use SimpleAsFuck\Validator\Model\Validated;
9+
use SimpleAsFuck\Validator\Rule\String\StringRule;
10+
11+
/**
12+
* @covers \SimpleAsFuck\ApiToolkit\Model\Server\HeaderRule
13+
*/
14+
final class HeaderRuleTest extends TestCase
15+
{
16+
private HeaderRule $rule;
17+
18+
protected function setUp(): void
19+
{
20+
$testData = [
21+
'header' => ['test'],
22+
'Header1' => ['test1'],
23+
];
24+
/** @var array<array<string>> $testData */
25+
$this->rule = new HeaderRule(new UnexpectedValueException(), new Validated($testData));
26+
}
27+
28+
/**
29+
* @dataProvider dataProviderKeyOf
30+
*
31+
* @param non-empty-string $key
32+
* @param array<string>|null $expectedValue
33+
*/
34+
public function testKeyOf(?array $expectedValue, string $key, bool $caseSensitive): void
35+
{
36+
$headerValue = $this->rule->keyOf($key, fn (StringRule $rule): ?string => $rule->nullable(), $caseSensitive)->nullable();
37+
38+
self::assertSame($expectedValue, $headerValue);
39+
}
40+
41+
/**
42+
* @return non-empty-array<non-empty-array<mixed>>
43+
*/
44+
public function dataProviderKeyOf(): array
45+
{
46+
return [
47+
[null, 'notFound', false],
48+
[null, 'notFound', true],
49+
[['test'], 'header', false],
50+
[['test'], 'Header', false],
51+
[['test1'], 'header1', false],
52+
[null, 'Header', true],
53+
[['test1'], 'Header1', true],
54+
];
55+
}
56+
57+
/**
58+
* @dataProvider dataProviderKey
59+
*
60+
* @param non-empty-string $key
61+
*/
62+
public function testKey(?string $expectedValue, string $key, bool $caseSensitive): void
63+
{
64+
$headerValue = $this->rule->key($key, $caseSensitive)->nullable();
65+
66+
self::assertSame($expectedValue, $headerValue);
67+
}
68+
69+
/**
70+
* @return non-empty-array<non-empty-array<mixed>>
71+
*/
72+
public function dataProviderKey(): array
73+
{
74+
return [
75+
[null, 'notFound', false],
76+
[null, 'notFound', true],
77+
['test', 'header', false],
78+
['test', 'Header', false],
79+
['test1', 'header1', false],
80+
[null, 'Header', true],
81+
['test1', 'Header1', true],
82+
];
83+
}
84+
}

0 commit comments

Comments
 (0)