diff --git a/.gitignore b/.gitignore index b60507f..ce1203c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ phpstan.neon testbench.yaml /docs /coverage + +# Ignore Mac DS_Store files +.DS_Store +**/.DS_Store diff --git a/routes/api.php b/routes/api.php index 4e41866..6799a28 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,13 +1,18 @@ all(), [ + $data = json_decode($request->getContent(), true); + + if (json_last_error() !== JSON_ERROR_NONE) { + return response()->json(['error' => 'Invalid JSON format'], 422); + } + + $validator = Validator::make($data, [ 'n' => 'required|string', 'u' => 'required|url', 'd' => 'required|string', @@ -20,7 +25,11 @@ Route::post('api/event', function (Request $request) { return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422); } - Concurrency::defer(fn () => Http::post(config('plausible-proxy.domain').'/api/event', $request->all())); + $headers = collect($request->headers->all()) + ->mapWithKeys(fn ($value, $key) => [$key => is_array($value) ? implode(', ', $value) : $value]) + ->all(); + + Http::withHeaders($headers)->post(config('plausible-proxy.domain').'/api/event', $data); return response()->json(['status' => 'queued']); }); diff --git a/tests/PlausibleProxyTest.php b/tests/PlausibleProxyTest.php index c715258..157d4cc 100644 --- a/tests/PlausibleProxyTest.php +++ b/tests/PlausibleProxyTest.php @@ -15,7 +15,7 @@ it('returns plausible script from cache', function () { it('fetches plausible script if not cached', function () { Http::fake([ - 'https://plausible.io/js/script.js' => Http::response('console.log("Plausible script");', 200), + config('plausible-proxy.domain').'/js/script.js' => Http::response('console.log("Plausible script");', 200), ]); $response = $this->get('/js/script.js'); @@ -29,7 +29,7 @@ it('fetches plausible script if not cached', function () { it('handles failed script fetch', function () { Http::fake([ - 'https://plausible.io/js/script.js' => Http::response('', 500), + config('plausible-proxy.domain').'/js/script.js' => Http::response('', 500), ]); $response = $this->get('/js/script.js'); @@ -49,26 +49,42 @@ it('rejects invalid event data', function () { ->assertJsonStructure(['status', 'errors']); }); -it('accepts valid event data and defers request', function () { - Http::fake(); +it('accepts valid event data and forwards headers', function () { + config()->set('plausible-proxy.domain', 'https://plausible.io'); - $concurrencyMock = Mockery::mock('alias:Illuminate\Support\Facades\Concurrency'); - $concurrencyMock->shouldReceive('defer')->once()->andReturnUsing(function ($callback) { - $callback(); - }); + Http::fake([ + 'https://plausible.io/api/event' => function ($request) { + dump($request->headers()); + dump($request->data()); + + return Http::response(['status' => 'queued'], 200); + }, + ]); + + $headers = [ + 'User-Agent' => 'TestAgent', + 'Accept' => 'application/json', + ]; $response = $this->postJson('/api/event', [ 'n' => 'pageview', 'u' => 'https://example.com/page', 'd' => 'example.com', - ]); + ], $headers); $response->assertStatus(200) ->assertJson(['status' => 'queued']); - Http::assertSent(fn ($request) => $request->url() === config('plausible-proxy.domain').'/api/event' && - $request['n'] === 'pageview' - ); + Http::assertSentCount(1); - Mockery::close(); + Http::assertSent(function ($request) { + dump($request->url()); + dump($request->headers()); + dump($request->data()); + + return $request->url() === 'https://plausible.io/api/event' + && isset($request['n']) && $request['n'] === 'pageview' + && isset($request['u']) && $request['u'] === 'https://example.com/page' + && isset($request['d']) && $request['d'] === 'example.com'; + }); });