Skip to content

Commit 12054a2

Browse files
committed
Fixed bug where collections were prematurely matched resulting in 404s and fixes for point release API versions. Closes #16.
Signed-off-by: Jason Lewis <jason.lewis1991@gmail.com>
1 parent 28c9225 commit 12054a2

File tree

3 files changed

+81
-11
lines changed

3 files changed

+81
-11
lines changed

src/Routing/ApiRouteCollection.php

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,38 @@ public function option($key, $default = null)
5353
*/
5454
public function matchesRequest($request)
5555
{
56-
if ($this->matchDomain($request))
56+
if ($this->matchesCollectionVersion($request))
5757
{
58-
return true;
58+
if ($this->matchDomain($request))
59+
{
60+
return true;
61+
}
62+
elseif ($this->matchPrefix($request))
63+
{
64+
return true;
65+
}
66+
elseif ( ! $this->option('prefix') and ! $this->option('domain'))
67+
{
68+
return true;
69+
}
5970
}
60-
elseif ($this->matchPrefix($request))
61-
{
62-
return true;
63-
}
64-
elseif ( ! $this->option('prefix') and ! $this->option('domain'))
71+
72+
return false;
73+
}
74+
75+
/**
76+
* Determine if the requested version matches the collection version.
77+
*
78+
* @param \Illuminate\Http\Request $request
79+
* @return bool
80+
*/
81+
protected function matchesCollectionVersion($request)
82+
{
83+
if (preg_match('#application/vnd\.\w+.(v[\d\.]+)\+\w+#', $request->header('accept'), $matches))
6584
{
66-
return true;
85+
list ($accept, $version) = $matches;
86+
87+
return $version == $this->version;
6788
}
6889

6990
return false;

src/Routing/Router.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ public function requestTargettingApi($request = null)
431431
*/
432432
protected function parseAcceptHeader($request)
433433
{
434-
if (preg_match('#application/vnd\.'.$this->vendor.'.(v\d)\+(json)#', $request->header('accept'), $matches))
434+
if (preg_match('#application/vnd\.'.$this->vendor.'.(v[\d\.]+)\+(\w+)#', $request->header('accept'), $matches))
435435
{
436436
list ($accept, $this->requestedVersion, $this->requestedFormat) = $matches;
437437
}

tests/RoutingRouterTest.php

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ public function testRouterDispatchesInternalRequests()
121121
$this->router->get('foo', function() { return 'bar'; });
122122
});
123123

124-
$this->assertEquals('{"message":"bar"}', $this->router->dispatch(InternalRequest::create('foo', 'GET'))->getContent());
124+
$request = InternalRequest::create('foo', 'GET');
125+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
126+
127+
$this->assertEquals('{"message":"bar"}', $this->router->dispatch($request)->getContent());
125128
}
126129

127130

@@ -253,7 +256,10 @@ public function testRouterCatchesHttpExceptionsAndCreatesResponse()
253256
$this->router->get('foo', function() use ($exception) { throw $exception; });
254257
});
255258

256-
$response = $this->router->dispatch(Request::create('foo', 'GET'));
259+
$request = Request::create('foo', 'GET');
260+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
261+
262+
$response = $this->router->dispatch($request);
257263

258264
$this->assertEquals(404, $response->getStatusCode());
259265
$this->assertEquals('{"message":"404 Not Found"}', $response->getContent());
@@ -355,4 +361,47 @@ public function testRequestTargettingAnApiWithNoPrefixOrDomain()
355361
}
356362

357363

364+
public function testRequestWithMultipleApisFindsTheCorrectApiRouteCollection()
365+
{
366+
$this->router->api(['version' => 'v1', 'prefix' => 'api'], function()
367+
{
368+
$this->router->get('foo', function() { return 'bar'; });
369+
});
370+
371+
$this->router->api(['version' => 'v2', 'prefix' => 'api'], function()
372+
{
373+
$this->router->get('bar', function() { return 'baz'; });
374+
});
375+
376+
$request = Request::create('api/bar', 'GET');
377+
$request->headers->set('accept', 'application/vnd.testing.v2+json');
378+
379+
$this->assertEquals('{"message":"baz"}', $this->router->dispatch($request)->getContent());
380+
}
381+
382+
383+
public function testApiCollectionsWithPointReleaseVersions()
384+
{
385+
$this->router->api(['version' => 'v1.1', 'prefix' => 'api'], function()
386+
{
387+
$this->router->get('foo', function() { return 'bar'; });
388+
});
389+
390+
$this->router->api(['version' => 'v2.0.1', 'prefix' => 'api'], function()
391+
{
392+
$this->router->get('bar', function() { return 'baz'; });
393+
});
394+
395+
$request = Request::create('api/foo', 'GET');
396+
$request->headers->set('accept', 'application/vnd.testing.v1.1+json');
397+
398+
$this->assertEquals('{"message":"bar"}', $this->router->dispatch($request)->getContent());
399+
400+
$request = Request::create('api/bar', 'GET');
401+
$request->headers->set('accept', 'application/vnd.testing.v2.0.1+json');
402+
403+
$this->assertEquals('{"message":"baz"}', $this->router->dispatch($request)->getContent());
404+
}
405+
406+
358407
}

0 commit comments

Comments
 (0)