Skip to content

Commit d684135

Browse files
authored
Release/4.3.0 (#46)
1 parent 83aa7f0 commit d684135

File tree

6 files changed

+90
-12
lines changed

6 files changed

+90
-12
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ jobs:
2222
uses: shivammathur/setup-php@v2
2323
with:
2424
php-version: ${{ env.PHP_VERSION }}
25-
extensions: bcmath
2625
tools: composer:2
2726

2827
- name: Validate composer.json
@@ -52,7 +51,6 @@ jobs:
5251
uses: shivammathur/setup-php@v2
5352
with:
5453
php-version: ${{ env.PHP_VERSION }}
55-
extensions: bcmath
5654
tools: composer:2
5755

5856
- name: Download vendor artifact from build
@@ -77,7 +75,6 @@ jobs:
7775
uses: shivammathur/setup-php@v2
7876
with:
7977
php-version: ${{ env.PHP_VERSION }}
80-
extensions: bcmath
8178
tools: composer:2
8279

8380
- name: Download vendor artifact from build

infection.json.dist

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
"customPath": "./vendor/bin/phpunit"
1717
},
1818
"mutators": {
19-
"@default": true,
20-
"LogicalOr": false
19+
"@default": true
2120
},
2221
"minCoveredMsi": 100,
2322
"testFramework": "phpunit"

src/Internal/Response/Stream/Stream.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,7 @@ public function isWritable(): bool
132132
return false;
133133
}
134134

135-
$mode = $this->metaData->getMode();
136-
137-
return str_contains($mode, 'x')
138-
|| str_contains($mode, 'w')
139-
|| str_contains($mode, 'c')
140-
|| str_contains($mode, 'a')
141-
|| str_contains($mode, '+');
135+
return strpbrk($this->metaData->getMode(), 'xwca+') !== false;
142136
}
143137

144138
public function isSeekable(): bool

src/Response.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ public static function badRequest(mixed $body, Headers ...$headers): ResponseInt
3434
return InternalResponse::createWithBody($body, Code::BAD_REQUEST, ...$headers);
3535
}
3636

37+
public static function unauthorized(mixed $body, Headers ...$headers): ResponseInterface
38+
{
39+
return InternalResponse::createWithBody($body, Code::UNAUTHORIZED, ...$headers);
40+
}
41+
42+
public static function forbidden(mixed $body, Headers ...$headers): ResponseInterface
43+
{
44+
return InternalResponse::createWithBody($body, Code::FORBIDDEN, ...$headers);
45+
}
46+
3747
public static function notFound(mixed $body, Headers ...$headers): ResponseInterface
3848
{
3949
return InternalResponse::createWithBody($body, Code::NOT_FOUND, ...$headers);

src/Responses.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,24 @@ public static function noContent(Headers ...$headers): ResponseInterface;
5757
*/
5858
public static function badRequest(mixed $body, Headers ...$headers): ResponseInterface;
5959

60+
/**
61+
* Creates a response with a 401 Unauthorized status.
62+
*
63+
* @param mixed $body The body of the response.
64+
* @param Headers ...$headers Optional additional headers for the response.
65+
* @return ResponseInterface The generated 401 Unauthorized response.
66+
*/
67+
public static function unauthorized(mixed $body, Headers ...$headers): ResponseInterface;
68+
69+
/**
70+
* Creates a response with a 403 Forbidden status.
71+
*
72+
* @param mixed $body The body of the response.
73+
* @param Headers ...$headers Optional additional headers for the response.
74+
* @return ResponseInterface The generated 403 Forbidden response.
75+
*/
76+
public static function forbidden(mixed $body, Headers ...$headers): ResponseInterface;
77+
6078
/**
6179
* Creates a response with a 404 Not Found status.
6280
*

tests/ResponseTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,66 @@ public function testResponseBadRequest(): void
169169
self::assertSame(['Content-Type' => ['application/json; charset=utf-8']], $actual->getHeaders());
170170
}
171171

172+
public function testResponseUnauthorized(): void
173+
{
174+
/** @Given a body with error details */
175+
$body = [
176+
'error' => 'Unauthorized',
177+
'message' => 'Authentication is required to access this resource.'
178+
];
179+
180+
/** @When we create the HTTP response with this body */
181+
$actual = Response::unauthorized(body: $body);
182+
183+
/** @Then the protocol version should be "1.1" */
184+
self::assertSame('1.1', $actual->getProtocolVersion());
185+
186+
/** @And the body of the response should match the JSON-encoded body */
187+
self::assertSame(json_encode($body, JSON_PRESERVE_ZERO_FRACTION), $actual->getBody()->__toString());
188+
self::assertSame(json_encode($body, JSON_PRESERVE_ZERO_FRACTION), $actual->getBody()->getContents());
189+
190+
/** @And the status code should be 401 */
191+
self::assertSame(Code::UNAUTHORIZED->value, $actual->getStatusCode());
192+
self::assertTrue(Code::isValidCode(code: $actual->getStatusCode()));
193+
self::assertTrue(Code::isErrorCode(code: $actual->getStatusCode()));
194+
195+
/** @And the reason phrase should be "Unauthorized" */
196+
self::assertSame(Code::UNAUTHORIZED->message(), $actual->getReasonPhrase());
197+
198+
/** @And the headers should contain Content-Type as application/json with charset=utf-8 */
199+
self::assertSame(['Content-Type' => ['application/json; charset=utf-8']], $actual->getHeaders());
200+
}
201+
202+
public function testResponseForbidden(): void
203+
{
204+
/** @Given a body with error details */
205+
$body = [
206+
'error' => 'Forbidden',
207+
'message' => 'You do not have permission to access this resource.'
208+
];
209+
210+
/** @When we create the HTTP response with this body */
211+
$actual = Response::forbidden(body: $body);
212+
213+
/** @Then the protocol version should be "1.1" */
214+
self::assertSame('1.1', $actual->getProtocolVersion());
215+
216+
/** @And the body of the response should match the JSON-encoded body */
217+
self::assertSame(json_encode($body, JSON_PRESERVE_ZERO_FRACTION), $actual->getBody()->__toString());
218+
self::assertSame(json_encode($body, JSON_PRESERVE_ZERO_FRACTION), $actual->getBody()->getContents());
219+
220+
/** @And the status code should be 403 */
221+
self::assertSame(Code::FORBIDDEN->value, $actual->getStatusCode());
222+
self::assertTrue(Code::isValidCode(code: $actual->getStatusCode()));
223+
self::assertTrue(Code::isErrorCode(code: $actual->getStatusCode()));
224+
225+
/** @And the reason phrase should be "Forbidden" */
226+
self::assertSame(Code::FORBIDDEN->message(), $actual->getReasonPhrase());
227+
228+
/** @And the headers should contain Content-Type as application/json with charset=utf-8 */
229+
self::assertSame(['Content-Type' => ['application/json; charset=utf-8']], $actual->getHeaders());
230+
}
231+
172232
public function testResponseNotFound(): void
173233
{
174234
/** @Given a body with error details */

0 commit comments

Comments
 (0)