Skip to content

Commit a3f33ac

Browse files
committed
fixed cache support and refactored public API
1 parent d7d07fd commit a3f33ac

3 files changed

Lines changed: 86 additions & 30 deletions

File tree

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ It converts HttpFoundation request and response objects to PSR-7 messages using
3030
## Installation
3131

3232
> [!NOTE]
33-
> This package is mostly intended to be used as part of an API test suite.
33+
> This package supports PHP 8.0 and above.
3434
3535
Via Composer:
3636

@@ -40,6 +40,9 @@ composer require --dev osteel/openapi-httpfoundation-testing
4040

4141
## Usage
4242

43+
> [!NOTE]
44+
> This package is mostly intended to be used as part of an API test suite.
45+
4346
Import the builder class:
4447

4548
```php
@@ -49,7 +52,7 @@ use Osteel\OpenApi\Testing\ValidatorBuilder;
4952
Use the builder to create a [`\Osteel\OpenApi\Testing\Validator`](/src/Validator.php) object, using one of the available factory methods for YAML or JSON:
5053

5154
```php
52-
// From a local file or URL:
55+
// From a local file:
5356

5457
$validator = ValidatorBuilder::fromYamlFile($yamlFile)->getValidator();
5558
$validator = ValidatorBuilder::fromJsonFile($jsonFile)->getValidator();
@@ -59,10 +62,15 @@ $validator = ValidatorBuilder::fromJsonFile($jsonFile)->getValidator();
5962
$validator = ValidatorBuilder::fromYamlString($yamlString)->getValidator();
6063
$validator = ValidatorBuilder::fromJsonString($jsonString)->getValidator();
6164

65+
// From a URL:
66+
67+
$validator = ValidatorBuilder::fromYamlUrl($yamlUrl)->getValidator();
68+
$validator = ValidatorBuilder::fromJsonUrl($jsonUrl)->getValidator();
69+
6270
// Automatic detection (slower):
6371

64-
$validator = ValidatorBuilder::fromYaml($yamlFileOrString)->getValidator();
65-
$validator = ValidatorBuilder::fromJson($jsonFileOrString)->getValidator();
72+
$validator = ValidatorBuilder::fromYaml($yamlFileOrStringOrUrl)->getValidator();
73+
$validator = ValidatorBuilder::fromJson($jsonFileOrStringOrUrl)->getValidator();
6674
```
6775

6876
> [!TIP]

src/ValidatorBuilder.php

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44

55
namespace Osteel\OpenApi\Testing;
66

7-
use cebe\openapi\Reader;
8-
use cebe\openapi\ReferenceContext;
97
use InvalidArgumentException;
108
use League\OpenAPIValidation\PSR7\ValidatorBuilder as BaseValidatorBuilder;
119
use Osteel\OpenApi\Testing\Adapters\HttpFoundationAdapter;
1210
use Osteel\OpenApi\Testing\Adapters\MessageAdapterInterface;
1311
use Osteel\OpenApi\Testing\Cache\CacheAdapterInterface;
1412
use Osteel\OpenApi\Testing\Cache\Psr16Adapter;
13+
use RuntimeException;
1514

1615
/**
1716
* This class creates Validator objects based on OpenAPI definitions.
@@ -35,9 +34,11 @@ public function __construct(private BaseValidatorBuilder $validatorBuilder)
3534
*/
3635
public static function fromYaml(string $definition): ValidatorBuilderInterface
3736
{
38-
return self::isUrl($definition) || is_file($definition)
39-
? self::fromYamlFile($definition)
40-
: self::fromYamlString($definition);
37+
return match (true) {
38+
self::isUrl($definition) => self::fromYamlUrl($definition),
39+
is_file($definition) => self::fromYamlFile($definition),
40+
default => self::fromYamlString($definition),
41+
};
4142
}
4243

4344
/**
@@ -47,9 +48,11 @@ public static function fromYaml(string $definition): ValidatorBuilderInterface
4748
*/
4849
public static function fromJson(string $definition): ValidatorBuilderInterface
4950
{
50-
return self::isUrl($definition) || is_file($definition)
51-
? self::fromJsonFile($definition)
52-
: self::fromJsonString($definition);
51+
return match (true) {
52+
self::isUrl($definition) => self::fromJsonUrl($definition),
53+
is_file($definition) => self::fromJsonFile($definition),
54+
default => self::fromJsonString($definition),
55+
};
5356
}
5457

5558
private static function isUrl(string $value): bool
@@ -70,7 +73,7 @@ private static function isUrl(string $value): bool
7073
*/
7174
public static function fromYamlFile(string $definition): ValidatorBuilderInterface
7275
{
73-
return self::fromMethod('readFromYamlFile', $definition);
76+
return self::fromMethod('fromYamlFile', $definition);
7477
}
7578

7679
/**
@@ -80,7 +83,7 @@ public static function fromYamlFile(string $definition): ValidatorBuilderInterfa
8083
*/
8184
public static function fromJsonFile(string $definition): ValidatorBuilderInterface
8285
{
83-
return self::fromMethod('readFromJsonFile', $definition);
86+
return self::fromMethod('fromJsonFile', $definition);
8487
}
8588

8689
/**
@@ -90,7 +93,7 @@ public static function fromJsonFile(string $definition): ValidatorBuilderInterfa
9093
*/
9194
public static function fromYamlString(string $definition): ValidatorBuilderInterface
9295
{
93-
return self::fromMethod('readFromYaml', $definition, resolveReferences: true);
96+
return self::fromMethod('fromYaml', $definition);
9497
}
9598

9699
/**
@@ -100,23 +103,59 @@ public static function fromYamlString(string $definition): ValidatorBuilderInter
100103
*/
101104
public static function fromJsonString(string $definition): ValidatorBuilderInterface
102105
{
103-
return self::fromMethod('readFromJson', $definition, resolveReferences: true);
106+
return self::fromMethod('fromJson', $definition);
104107
}
105108

106109
/**
107-
* Create a Validator object based on an OpenAPI definition.
110+
* @inheritDoc
108111
*
109-
* @param string $method the ValidatorBuilder object's method to use
110-
* @param string $definition the OpenAPI definition
111-
* @param bool $resolveReferences whether to resolve references in the definition
112+
* @param string $definition the OpenAPI definition's URL
113+
*
114+
* @throws InvalidArgumentException if the URL is invalid
115+
* @throws RuntimeException if the content of the URL cannot be read
112116
*/
113-
private static function fromMethod(string $method, string $definition, bool $resolveReferences = false): ValidatorBuilderInterface
117+
public static function fromYamlUrl(string $definition): ValidatorBuilderInterface
114118
{
115-
$specObject = Reader::{$method}($definition);
119+
return self::fromMethod('fromYaml', self::getUrlContent($definition));
120+
}
116121

117-
$resolveReferences && $specObject->resolveReferences(new ReferenceContext($specObject, '/'));
122+
/**
123+
* @inheritDoc
124+
*
125+
* @param string $definition the OpenAPI definition's URL
126+
*
127+
* @throws InvalidArgumentException if the URL is invalid
128+
* @throws RuntimeException if the content of the URL cannot be read
129+
*/
130+
public static function fromJsonUrl(string $definition): ValidatorBuilderInterface
131+
{
132+
return self::fromMethod('fromJson', self::getUrlContent($definition));
133+
}
118134

119-
$builder = (new BaseValidatorBuilder())->fromSchema($specObject);
135+
/**
136+
* @throws InvalidArgumentException if the URL is invalid
137+
* @throws RuntimeException if the content of the URL cannot be read
138+
*/
139+
private static function getUrlContent(string $url): string
140+
{
141+
self::isUrl($url) || throw new InvalidArgumentException(sprintf('Invalid URL: %s', $url));
142+
143+
if (($content = file_get_contents($url)) === false) {
144+
throw new RuntimeException(sprintf('Failed to read URL %s', $url));
145+
}
146+
147+
return $content;
148+
}
149+
150+
/**
151+
* Create a Validator object based on an OpenAPI definition.
152+
*
153+
* @param string $method the ValidatorBuilder object's method to use
154+
* @param string $definition the OpenAPI definition
155+
*/
156+
private static function fromMethod(string $method, string $definition): ValidatorBuilderInterface
157+
{
158+
$builder = (new BaseValidatorBuilder())->{$method}($definition);
120159

121160
return new ValidatorBuilder($builder);
122161
}

tests/ValidatorBuilderTest.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Osteel\OpenApi\Testing\Cache\CacheAdapterInterface;
1010
use Osteel\OpenApi\Testing\Validator;
1111
use Osteel\OpenApi\Testing\ValidatorBuilder;
12+
use Psr\SimpleCache\CacheInterface;
1213
use stdClass;
1314

1415
class ValidatorBuilderTest extends TestCase
@@ -17,17 +18,17 @@ public function definitionProvider(): array
1718
{
1819
return [
1920
['fromYaml', self::$yamlDefinition],
20-
['fromYaml', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.yaml'],
2121
['fromYaml', file_get_contents(self::$yamlDefinition)],
22+
['fromYaml', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.yaml'],
2223
['fromYamlFile', self::$yamlDefinition],
23-
['fromYamlFile', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.yaml'],
2424
['fromYamlString', file_get_contents(self::$yamlDefinition)],
25+
['fromYamlUrl', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.yaml'],
2526
['fromJson', self::$jsonDefinition],
26-
['fromJson', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.json'],
2727
['fromJson', file_get_contents(self::$jsonDefinition)],
28+
['fromJson', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.json'],
2829
['fromJsonFile', self::$jsonDefinition],
29-
['fromJsonFile', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.json'],
3030
['fromJsonString', file_get_contents(self::$jsonDefinition)],
31+
['fromJsonUrl', 'https://raw.githubusercontent.com/osteel/openapi-httpfoundation-testing/refs/heads/main/tests/stubs/example.json'],
3132
];
3233
}
3334

@@ -46,7 +47,15 @@ public function test_it_builds_a_validator(string $method, string $definition)
4647
$this->assertTrue($result->get($response, static::PATH));
4748
}
4849

49-
public function test_it_does_not_set_the_adapter_because_its_type_is_invalid()
50+
/** @dataProvider definitionProvider */
51+
public function test_it_sets_the_cache(string $method, string $definition)
52+
{
53+
ValidatorBuilder::$method($definition)->setCache($this->createMock(CacheInterface::class))->getValidator();
54+
55+
$this->addToAssertionCount(1);
56+
}
57+
58+
public function test_it_does_not_set_the_message_adapter_because_its_type_is_invalid()
5059
{
5160
$this->expectException(InvalidArgumentException::class);
5261
$this->expectExceptionMessage(sprintf(
@@ -58,7 +67,7 @@ public function test_it_does_not_set_the_adapter_because_its_type_is_invalid()
5867
ValidatorBuilder::fromYaml(self::$yamlDefinition)->setMessageAdapter(stdClass::class);
5968
}
6069

61-
public function test_it_sets_the_adapter()
70+
public function test_it_sets_the_message_adapter()
6271
{
6372
ValidatorBuilder::fromYaml(self::$yamlDefinition)
6473
->setMessageAdapter($this->createMock(MessageAdapterInterface::class)::class);

0 commit comments

Comments
 (0)