Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions tests/Feature/MarkdownOutputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,61 @@
->and($response['headers']['content-type'])
->toContain('text/markdown');
});

test('html is served when Accept prefers html over markdown via q-values', function () {
$response = makeRequest('/hello-world/', [
'Accept' => 'text/html, text/markdown;q=0.5',
]);

expect($response['status'])->toBe(200)
->and($response['headers']['content-type'])->toContain('text/html');
});

test('markdown is served when Accept prefers markdown over html via q-values', function () {
$response = makeRequest('/hello-world/', [
'Accept' => 'text/html;q=0.5, text/markdown;q=0.9',
]);

expect($response['status'])->toBe(200)
->and($response['headers']['content-type'])->toContain('text/markdown');
});

test('html is served when Accept is */* (default representation wins)', function () {
$response = makeRequest('/hello-world/', [
'Accept' => '*/*',
]);

expect($response['headers']['content-type'])->toContain('text/html');
});

test('406 is returned when Accept rules out every supported representation', function () {
$response = makeRequest('/hello-world/', [
'Accept' => 'application/x-content-negotiation-probe',
]);

expect($response['status'])->toBe(406);
});

test('406 is returned for application/json on a page that does not serve json', function () {
$response = makeRequest('/hello-world/', [
'Accept' => 'application/json',
]);

expect($response['status'])->toBe(406);
});

test('html response advertises Vary: Accept for cache correctness', function () {
$response = makeRequest('/hello-world/');

expect($response['headers'])->toHaveKey('vary')
->and($response['headers']['vary'])->toContain('Accept');
});

test('markdown response advertises Vary: Accept', function () {
$response = makeRequest('/hello-world/', [
'Accept' => 'text/markdown',
]);

expect($response['headers'])->toHaveKey('vary')
->and($response['headers']['vary'])->toContain('Accept');
});
16 changes: 14 additions & 2 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,31 @@ function makeRequest(string $path, array $headers = []): array
$context = stream_context_create($context_options);
$response = @file_get_contents($url, false, $context);

// Parse response headers
// Parse status line and response headers. Repeated headers (e.g. Vary) are
// concatenated with ", " so assertions can inspect the combined value.
$status = 0;
$responseHeaders = [];
if (isset($http_response_header)) {
foreach ($http_response_header as $header) {
if (preg_match('#^HTTP/\S+\s+(\d{3})#', $header, $m)) {
$status = (int) $m[1];

continue;
}
if (str_contains($header, ':')) {
[$key, $value] = explode(':', $header, 2);
$responseHeaders[strtolower(trim($key))] = trim($value);
$key = strtolower(trim($key));
$value = trim($value);
$responseHeaders[$key] = isset($responseHeaders[$key])
? $responseHeaders[$key].', '.$value
: $value;
}
}
}

return [
'body' => $response !== false ? $response : '',
'headers' => $responseHeaders,
'status' => $status,
];
}
Loading