diff --git a/CHANGELOG.md b/CHANGELOG.md index d5fcbb1..8447190 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,30 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. +## 0.5.3 - 2021-03-29 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#15](https://github.com/netglue/primo/pull/15) fixes [#14](https://github.com/netglue/primo/issues/14). + When a route provides a document type _and_ an identifier, use that identifier to narrow down the result set to + a single document. + ## 0.5.2 - 2021-03-25 ### Added diff --git a/src/Router/DocumentResolver.php b/src/Router/DocumentResolver.php index 3149236..632e4a8 100644 --- a/src/Router/DocumentResolver.php +++ b/src/Router/DocumentResolver.php @@ -63,6 +63,7 @@ private function resolveWithParams(RouteResult $routeResult): ?Document $params = $routeResult->getMatchedParams(); $type = $params[$this->routeParams->type()] ?? null; $uid = $params[$this->routeParams->uid()] ?? null; + $id = $params[$this->routeParams->id()] ?? null; $tags = $params[$this->routeParams->tag()] ?? null; // At least one of these must be present to attempt a match @@ -84,6 +85,10 @@ private function resolveWithParams(RouteResult $routeResult): ?Document $predicates[] = Predicate::at(sprintf('my.%s.uid', $type), $uid); } + if ($id) { + $predicates[] = Predicate::at('document.id', $id); + } + if (! empty($tags)) { $tags = is_string($tags) ? [$tags] : $tags; $predicates[] = Predicate::at('document.tags', $tags); diff --git a/test/Unit/Router/DocumentResolverTest.php b/test/Unit/Router/DocumentResolverTest.php index 53e67f9..48e8b79 100644 --- a/test/Unit/Router/DocumentResolverTest.php +++ b/test/Unit/Router/DocumentResolverTest.php @@ -14,6 +14,7 @@ use PrimoTest\Unit\TestCase; use Prismic\ApiClient; use Prismic\Document; +use Prismic\Predicate; use Prismic\Query; use Prismic\ResultSet; use Psr\Http\Message\ResponseInterface; @@ -218,4 +219,61 @@ public function testAnExceptionIsThrownWhenAResultSetContainsMultipleResults(): ); $this->resolver->resolve($result); } + + public function testThatWhenTheTypeAndIdentifierArePresentInRoutingParametersTheIsWillBeUsedToResolveADocument(): void + { + $document = $this->createMock(Document::class); + $query = $this->createMock(Query::class); + $resultSet = $this->createMock(ResultSet::class); + + $resultSet->expects(self::once()) + ->method('count') + ->willReturn(1); + + $resultSet->expects(self::once()) + ->method('first') + ->willReturn($document); + + $query->expects(self::once()) + ->method('query') + ->with(self::callback(static function ($arg): bool { + $expect = (string) Predicate::at('document.type', 'type'); + self::assertEquals($expect, (string) $arg); + + return true; + }), self::callback(static function ($arg): bool { + $expect = (string) Predicate::at('document.id', 'my-id'); + self::assertEquals($expect, (string) $arg); + + return true; + })) + ->willReturnSelf(); + + $query->expects(self::once()) + ->method('lang') + ->with('*') + ->willReturnSelf(); + + $this->api->expects(self::once()) + ->method('createQuery') + ->willReturn($query); + + $this->api->expects(self::once()) + ->method('query') + ->with($query) + ->willReturn($resultSet); + + $resultSet->method('count') + ->willReturn(1); + + $result = RouteResult::fromRoute( + new Route('/foo', $this->middleware, ['GET']), + [ + $this->params->id() => 'my-id', + $this->params->type() => 'type', + ] + ); + + self::assertSame($document, $this->resolver->resolve($result)); + } }