Skip to content

Commit b131d1c

Browse files
authored
Merge pull request #6 from softius/more-tests
More tests
2 parents 6dc81d4 + d53b5d4 commit b131d1c

11 files changed

+269
-31
lines changed

src/BooleanParamConverter.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
namespace ParamConverter;
44

5-
use Cake\Core\App;
65
use Cake\Http\Exception\BadRequestException;
7-
use Cake\ORM\Entity;
8-
use Cake\ORM\TableRegistry;
9-
use Cake\Utility\Inflector;
106

117
/**
128
* Class BooleanParamConverter

src/DateTimeParamConverter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace ParamConverter;
44

5+
use Cake\Http\Exception\BadRequestException;
56
use DateTime;
67

78
/**
@@ -26,6 +27,10 @@ public function supports(string $class): bool
2627
*/
2728
public function convertTo(string $value, string $class)
2829
{
30+
if (false === strtotime($value)) {
31+
throw new BadRequestException();
32+
}
33+
2934
return new DateTime($value);
3035
}
3136
}

src/FloatParamConverter.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
namespace ParamConverter;
44

5-
use Cake\Core\App;
65
use Cake\Http\Exception\BadRequestException;
7-
use Cake\ORM\Entity;
8-
use Cake\ORM\TableRegistry;
9-
use Cake\Utility\Inflector;
106

117
/**
128
* Class FloatParamConverter
@@ -30,7 +26,7 @@ public function supports(string $class): bool
3026
*/
3127
public function convertTo(string $value, string $class)
3228
{
33-
if (preg_match('/^-?(?:\d+|\d*\.\d+)$/', $value)) {
29+
if (is_numeric($value)) {
3430
return (float)$value;
3531
}
3632
throw new BadRequestException();

src/IntegerParamConverter.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
namespace ParamConverter;
44

5-
use Cake\Core\App;
65
use Cake\Http\Exception\BadRequestException;
7-
use Cake\ORM\Entity;
8-
use Cake\ORM\TableRegistry;
9-
use Cake\Utility\Inflector;
106

117
/**
128
* Class EntityParamConverter

src/ParamConverterManager.php

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace ParamConverter;
44

5+
use Cake\Http\Exception\BadRequestException;
56
use Cake\Http\ServerRequest;
67
use ReflectionMethod;
8+
use ReflectionParameter;
79

810
class ParamConverterManager
911
{
@@ -61,19 +63,9 @@ public function apply(ServerRequest $request, string $controller, string $action
6163

6264
$stopAt = min(count($methodParams), count($requestParams));
6365
for ($i = 0; $i < $stopAt; $i++) {
64-
$methodParam = $methodParams[$i];
65-
$requestParam = $requestParams[$i];
66-
67-
if (!empty($methodParam->getClass())) {
68-
$requestParams[$i] = $this->convertParam($requestParam, $methodParam->getClass()->getName());
69-
} elseif ($methodParam->getType()) {
70-
$requestParams[$i] = $this->convertParam($requestParam, $methodParam->getType()->getName());
71-
}
72-
73-
$methodParamType = $methodParam->getType();
74-
if (!empty($methodParamType) && $methodParamType->isBuiltin()) {
75-
settype($requestParam, $methodParamType->getName());
76-
$requestParams[$i] = $requestParam;
66+
$classOrType = $this->getClassOrType($methodParams[$i]);
67+
if (!empty($classOrType)) {
68+
$requestParams[$i] = $this->convertParam($requestParams[$i], $classOrType);
7769
}
7870
}
7971

@@ -94,5 +86,27 @@ private function convertParam(string $value, string $class)
9486
return $converter->convertTo($value, $class);
9587
}
9688
}
89+
90+
throw new BadRequestException();
91+
}
92+
93+
/**
94+
* Returns the class or type defined (type-hint) for the specified parameter
95+
*
96+
* @param \ReflectionParameter $parameter Parameter to be checked
97+
* @return null|string
98+
*/
99+
private function getClassOrType(ReflectionParameter $parameter): ?string
100+
{
101+
$class = $parameter->getClass();
102+
if (!empty($class)) {
103+
return $class->getName();
104+
}
105+
106+
if (!empty($parameter->getType()) && $parameter->getType()->getName() !== 'string') {
107+
return $parameter->getType()->getName();
108+
}
109+
110+
return null;
97111
}
98112
}

tests/App/Controller/UsersController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ public function withNoParams(): void
3232
public function withNoTypehint($a, $b, $c): void
3333
{
3434
}
35+
36+
public function withOptional(int $a = 0): void
37+
{
38+
}
3539
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace ParamConverter\Test\TestCase;
4+
5+
use Cake\Http\Exception\BadRequestException;
6+
use Cake\TestSuite\TestCase;
7+
use ParamConverter\BooleanParamConverter;
8+
9+
class BooleanParamConverterTest extends TestCase
10+
{
11+
public function testSupports(): void
12+
{
13+
$converter = new BooleanParamConverter();
14+
$this->assertTrue($converter->supports('bool'));
15+
$this->assertFalse($converter->supports('int'));
16+
}
17+
18+
/**
19+
* @dataProvider conversionDataProvider
20+
* @param string $rawValue Raw value
21+
* @param string $expectedValue Expected value upon conversion
22+
*/
23+
public function testConvertTo(string $rawValue, string $expectedValue): void
24+
{
25+
$converter = new BooleanParamConverter();
26+
$convertedValue = $converter->convertTo($rawValue, "bool");
27+
$this->assertEquals($expectedValue, $convertedValue);
28+
$this->assertInternalType("bool", $convertedValue);
29+
}
30+
31+
public function testException(): void
32+
{
33+
$converter = new BooleanParamConverter();
34+
$this->expectException(BadRequestException::class);
35+
$converter->convertTo("not-a-bool", "bool");
36+
}
37+
38+
/**
39+
* @return array[]
40+
*/
41+
public function conversionDataProvider(): array
42+
{
43+
return [
44+
// raw value, converted value
45+
['1', true],
46+
['0', false],
47+
['true', true],
48+
['false', false],
49+
['yes', true],
50+
['no', false],
51+
['on', true],
52+
['off', false],
53+
];
54+
}
55+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace ParamConverter\Test\TestCase;
4+
5+
use Cake\Http\Exception\BadRequestException;
6+
use Cake\TestSuite\TestCase;
7+
use ParamConverter\DateTimeParamConverter;
8+
9+
class DateTimeParamConverterTest extends TestCase
10+
{
11+
public function testSupports(): void
12+
{
13+
$converter = new DateTimeParamConverter();
14+
$this->assertTrue($converter->supports(\DateTime::class));
15+
}
16+
17+
/**
18+
* @dataProvider conversionDataProvider
19+
* @param string $rawValue Raw value
20+
* @param string $expectedValue Expected value upon conversion
21+
* @param string $format Date format
22+
*/
23+
public function testConvertTo(string $rawValue, string $expectedValue, string $format): void
24+
{
25+
$converter = new DateTimeParamConverter();
26+
/** @var \DateTime $convertedValue */
27+
$convertedValue = $converter->convertTo($rawValue, \DateTime::class);
28+
$this->assertInstanceOf(\DateTime::class, $convertedValue);
29+
$this->assertEquals($expectedValue, $convertedValue->format($format));
30+
}
31+
32+
public function testException(): void
33+
{
34+
$converter = new DateTimeParamConverter();
35+
$this->expectException(BadRequestException::class);
36+
$converter->convertTo("not-a-valid-datetime", \DateTime::class);
37+
}
38+
39+
/**
40+
* @return array[]
41+
*/
42+
public function conversionDataProvider(): array
43+
{
44+
return [
45+
// raw value, converted value
46+
['now', date('Y-m-d'), 'Y-m-d'],
47+
['now', date('Y-m-d h:i:s'), 'Y-m-d h:i:s'],
48+
['2020-09-10', '2020-09-10', 'Y-m-d'],
49+
['2020-09-10 15:10:00', '2020-09-10 15:10:00', 'Y-m-d H:i:s'],
50+
];
51+
}
52+
}

tests/TestCase/DispatchListenerTest.php

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function testScalar(): void
3535
$event->setData('controller', new UsersController());
3636

3737
$request = (new ServerRequest())
38-
->withParam('pass', ["true", "10", "10.5", "foo"])
38+
->withParam('pass', ["false", "10", "10.5", "foo"])
3939
->withParam('action', 'withScalar');
4040
$response = new Response();
4141

@@ -44,10 +44,10 @@ public function testScalar(): void
4444

4545
/** @var ServerRequest $updatedRequest */
4646
$updatedRequest = $event->getData('request');
47-
$this->assertSame($updatedRequest->getParam('pass.0'), (bool)true);
48-
$this->assertSame($updatedRequest->getParam('pass.1'), (int)10);
49-
$this->assertSame($updatedRequest->getParam('pass.2'), (float)10.5);
50-
$this->assertSame($updatedRequest->getParam('pass.3'), (string)"foo");
47+
$this->assertSame(false, $updatedRequest->getParam('pass.0'));
48+
$this->assertSame(10, $updatedRequest->getParam('pass.1'));
49+
$this->assertSame(10.5, $updatedRequest->getParam('pass.2'));
50+
$this->assertSame("foo", $updatedRequest->getParam('pass.3'));
5151
}
5252

5353
public function testDatetime(): void
@@ -137,4 +137,22 @@ public function testUndefinedAction(): void
137137
$this->expectException(\ReflectionException::class);
138138
$listener->beforeDispatch($event, $request, $response);
139139
}
140+
141+
public function testOptional(): void
142+
{
143+
$event = new Event('beforeEvent');
144+
$event->setData('controller', new UsersController());
145+
146+
$request = (new ServerRequest())
147+
->withParam('pass', [])
148+
->withParam('action', 'withOptional');
149+
$response = new Response();
150+
151+
$listener = new DispatchListener();
152+
$listener->beforeDispatch($event, $request, $response);
153+
154+
/** @var ServerRequest $updatedRequest */
155+
$updatedRequest = $event->getData('request');
156+
$this->assertEquals([], $updatedRequest->getParam('pass'));
157+
}
140158
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace ParamConverter\Test\TestCase;
4+
5+
use Cake\Http\Exception\BadRequestException;
6+
use Cake\TestSuite\TestCase;
7+
use ParamConverter\FloatParamConverter;
8+
9+
class FloatParamConverterTest extends TestCase
10+
{
11+
public function testSupports(): void
12+
{
13+
$converter = new FloatParamConverter();
14+
$this->assertTrue($converter->supports('float'));
15+
$this->assertFalse($converter->supports('int'));
16+
}
17+
18+
/**
19+
* @dataProvider conversionDataProvider
20+
* @param string $rawValue Raw value
21+
* @param string $expectedValue Expected value upon conversion
22+
*/
23+
public function testConvertTo(string $rawValue, string $expectedValue): void
24+
{
25+
$converter = new FloatParamConverter();
26+
$convertedValue = $converter->convertTo($rawValue, "float");
27+
$this->assertEquals($expectedValue, $convertedValue);
28+
$this->assertInternalType("float", $convertedValue);
29+
}
30+
31+
public function testException(): void
32+
{
33+
$converter = new FloatParamConverter();
34+
$this->expectException(BadRequestException::class);
35+
$converter->convertTo("no-float-number", "float");
36+
}
37+
38+
/**
39+
* @return array[]
40+
*/
41+
public function conversionDataProvider(): array
42+
{
43+
return [
44+
// raw value, converted value
45+
['.1', 0.1],
46+
['.1E0', 0.1],
47+
['.1E-0', 0.1],
48+
['1.1', 1.1],
49+
['1', 1.0],
50+
['01', 1.0],
51+
];
52+
}
53+
}

0 commit comments

Comments
 (0)