• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NeoIsRecursive / inertia-tempest / 27938424188

22 Jun 2026 08:05AM UTC coverage: 92.754% (-6.1%) from 98.81%
27938424188

Pull #23

github

web-flow
Merge ae1c83b3e into 90d76d658
Pull Request #23: feat: inertia 3

221 of 245 new or added lines in 21 files covered. (90.2%)

8 existing lines in 1 file now uncovered.

320 of 345 relevant lines covered (92.75%)

18.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.37
/src/Http/Middleware.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace NeoIsRecursive\Inertia\Http;
6

7
use NeoIsRecursive\Inertia\Inertia;
8
use NeoIsRecursive\Inertia\Support\Header;
9
use Override;
10
use Tempest\Core\Priority;
11
use Tempest\Http\GenericResponse;
12
use Tempest\Http\Method;
13
use Tempest\Http\Request;
14
use Tempest\Http\Response;
15
use Tempest\Http\Session\Session;
16
use Tempest\Http\Status;
17
use Tempest\Router\HttpMiddleware;
18
use Tempest\Router\HttpMiddlewareCallable;
19

20
// @mago-expect lint:cyclomatic-complexity
21
#[Priority(Priority::HIGH)]
22
final class Middleware implements HttpMiddleware
23
{
24
    public function __construct(
25
        private Inertia $inertia,
26
        private Session $session,
27
    ) {}
15✔
28

29
    #[Override]
30
    public function __invoke(Request $request, HttpMiddlewareCallable $next): Response
31
    {
32
        $response = $next($request);
14✔
33

34
        $response = $response->addHeader(key: 'Vary', value: Header::INERTIA);
14✔
35

36
        $isRedirect = $response->status->isRedirect();
14✔
37

38
        if ($isRedirect) {
14✔
39
            $this->session->reflash();
4✔
40
        }
41

42
        if (!$request->headers->has(Header::INERTIA)) {
14✔
43
            return $response;
1✔
44
        }
45

46
        $clientVersion = $request->headers->get(Header::VERSION) ?? '';
13✔
47

48
        if ($request->method === Method::GET && $clientVersion !== $this->inertia->version) {
13✔
49
            $this->session->reflash();
1✔
50

51
            return $this->inertia->location($request->uri);
1✔
52
        }
53

54
        if (
55
            $response->status === Status::FOUND
12✔
56
            && in_array($request->method, [Method::DELETE, Method::PUT, Method::PATCH], strict: true)
12✔
57
        ) {
58
            return $response->setStatus(Status::SEE_OTHER);
3✔
59
        }
60

61
        if ($isRedirect && $this->redirectHasFragment($response) && !$this->prefetch($request)) {
9✔
62
            // TODO(neo): ensure this works the same as the laravel adapter
NEW
UNCOV
63
            return new GenericResponse(status: Status::CONFLICT, body: '', headers: [
×
NEW
UNCOV
64
                Header::LOCATION => $response->getHeader('location')?->first() ?? '',
×
NEW
UNCOV
65
            ]);
×
66
        }
67

68
        return $response;
9✔
69
    }
70

71
    /**
72
     * Determine if the redirect response contains a URL fragment.
73
     */
74
    private function redirectHasFragment(Response $response): bool
75
    {
76
        /** @var string */
77
        $location = $response->getHeader('location')?->first() ?? '';
1✔
78
        return str_contains($location, '#');
1✔
79
    }
80

81
    private function prefetch(Request $request)
82
    {
NEW
UNCOV
83
        return (
×
NEW
UNCOV
84
            strcasecmp($request->headers->get('HTTP_X_MOZ') ?? '', 'prefetch') === 0
×
NEW
UNCOV
85
            || strcasecmp($request->headers->get('Purpose') ?? '', 'prefetch') === 0
×
NEW
UNCOV
86
            || strcasecmp($request->headers->get('Sec-Purpose') ?? '', 'prefetch') === 0
×
NEW
UNCOV
87
        );
×
88
    }
89
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc