|
6 | 6 |
|
7 | 7 | use ArgumentCountError; |
8 | 8 | use EasyRdf\Graph; |
| 9 | +use Laminas\Diactoros\Response; |
9 | 10 | use League\Flysystem\FilesystemInterface; |
10 | 11 | use PHPUnit\Framework\TestCase; |
11 | 12 | use Psr\Http\Message\ResponseInterface; |
| 13 | +use Psr\Http\Message\ServerRequestInterface; |
12 | 14 |
|
13 | 15 | /** |
| 16 | + * @covers \Pdsinterop\Solid\Resources\Server |
14 | 17 | * @coversDefaultClass \Pdsinterop\Solid\Resources\Server |
15 | | - * @covers ::__construct |
| 18 | + * @uses \Pdsinterop\Solid\Resources\Server |
16 | 19 | */ |
17 | 20 | class ServerTest extends TestCase |
18 | 21 | { |
| 22 | + const MOCK_SLUG = 'Mock Slug'; |
| 23 | + |
19 | 24 | /** @testdox Server should complain when instantiated without File System */ |
20 | 25 | public function testInstatiationWithoutFileSystem() |
21 | 26 | { |
@@ -60,4 +65,169 @@ public function testInstatiationWithGraph() |
60 | 65 |
|
61 | 66 | $this->assertInstanceOf($expected, $actual); |
62 | 67 | } |
| 68 | + |
| 69 | + /** |
| 70 | + * @testdox Server should complain when asked to respond to a request without a Request |
| 71 | + * |
| 72 | + * @covers ::respondToRequest |
| 73 | + */ |
| 74 | + public function testRespondToRequestWithoutRequest() |
| 75 | + { |
| 76 | + // Arrange |
| 77 | + $mockFileSystem = $this->getMockBuilder(FilesystemInterface::class)->getMock(); |
| 78 | + $mockResponse = $this->getMockBuilder(ResponseInterface::class)->getMock(); |
| 79 | + $mockGraph = $this->getMockBuilder(Graph::class)->getMock(); |
| 80 | + |
| 81 | + $server = new Server($mockFileSystem, $mockResponse, $mockGraph); |
| 82 | + |
| 83 | + // Assert |
| 84 | + $this->expectException(ArgumentCountError::class); |
| 85 | + $this->expectExceptionMessageMatches('/Too few arguments .+ 0 passed/'); |
| 86 | + |
| 87 | + // Act |
| 88 | + $server->respondToRequest(); |
| 89 | + } |
| 90 | + |
| 91 | + /** |
| 92 | + * @testdox Server should complain when asked to respond to a Request with an unsupported HTTP METHOD |
| 93 | + * |
| 94 | + * @covers ::respondToRequest |
| 95 | + * |
| 96 | + * @uses \Pdsinterop\Solid\Resources\Exception |
| 97 | + * |
| 98 | + * @dataProvider provideUnsupportedHttpMethods |
| 99 | + */ |
| 100 | + public function testRespondToRequestWithUnsupportedHttpMethod($httpMethod) |
| 101 | + { |
| 102 | + // Arrange |
| 103 | + $mockFileSystem = $this->getMockBuilder(FilesystemInterface::class)->getMock(); |
| 104 | + $mockGraph = $this->getMockBuilder(Graph::class)->getMock(); |
| 105 | + $mockRequest = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); |
| 106 | + $mockResponse = $this->getMockBuilder(ResponseInterface::class)->getMock(); |
| 107 | + |
| 108 | + $mockRequest->method('getMethod')->willReturn($httpMethod); |
| 109 | + |
| 110 | + $server = new Server($mockFileSystem, $mockResponse, $mockGraph); |
| 111 | + |
| 112 | + // Assert |
| 113 | + $this->expectException(Exception::class); |
| 114 | + $this->expectExceptionMessage('Unknown or unsupported HTTP METHOD'); |
| 115 | + |
| 116 | + // Act |
| 117 | + $server->respondToRequest($mockRequest); |
| 118 | + } |
| 119 | + |
| 120 | + /** |
| 121 | + * @testdox Server should create a resource when asked to create a resource with Slug header present |
| 122 | + * |
| 123 | + * @covers ::respondToRequest |
| 124 | + * |
| 125 | + * @uses \Pdsinterop\Solid\Resources\Exception |
| 126 | + * |
| 127 | + * @dataProvider provideMimeTypes |
| 128 | + */ |
| 129 | + public function testRespondToPOSTCreateRequest($mimetype) |
| 130 | + { |
| 131 | + $expectedName = self::MOCK_SLUG . self::MOCK_SLUG; |
| 132 | + |
| 133 | + $extensions = [ |
| 134 | + 'application/json' => '.json', |
| 135 | + 'application/ld+json' => '.json', |
| 136 | + 'text/html' => '.html', |
| 137 | + 'text/plain' => '.txt', |
| 138 | + 'text/turtle' => '.ttl', |
| 139 | + ]; |
| 140 | + |
| 141 | + if ( |
| 142 | + $mimetype === 'application/ld+json' |
| 143 | + || $mimetype === 'text/turtle' |
| 144 | + || $mimetype === 'text/html' |
| 145 | + || $mimetype === 'text/plain' |
| 146 | + || $mimetype === 'application/json' |
| 147 | + ) { |
| 148 | + /*/ If the filename suggestion in the Slug contains a file extension, another file extension is appended for known/supported MIME types. This leads to a filename with two file extensions, like 'example.ttl.ttl'. |
| 149 | +
|
| 150 | + If the MIME type is not known or does not match the provided file extension, there are still two file extensions. They are merely not the same. |
| 151 | +
|
| 152 | + For instance 'example.json.ttl' or 'example.ttl.json'. |
| 153 | + /*/ |
| 154 | + $expectedName .= $extensions[$mimetype]; |
| 155 | + } |
| 156 | + |
| 157 | + // Arrange |
| 158 | + $expected = new Response(); //@CHECKME: Use mock? $this->getMockBuilder(ResponseInterface::class)->getMock(); |
| 159 | + $mockFileSystem = $this->getMockBuilder(FilesystemInterface::class)->getMock(); |
| 160 | + $mockGraph = $this->getMockBuilder(Graph::class)->getMock(); |
| 161 | + $mockRequest = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); |
| 162 | + |
| 163 | + $mockRequest->method('getMethod')->willReturn('POST'); |
| 164 | + |
| 165 | + $mockRequest->expects($this->exactly(3)) |
| 166 | + ->method('getHeaderLine') |
| 167 | + ->willReturnMap([ |
| 168 | + ['Content-Type', $mimetype], |
| 169 | + ['Link', ''], |
| 170 | + ['Slug', self::MOCK_SLUG], |
| 171 | + ]); |
| 172 | + |
| 173 | + $mockRequest->expects($this->exactly(1)) |
| 174 | + ->method('hasHeader') |
| 175 | + ->with('Slug') |
| 176 | + ->willReturn(true); |
| 177 | + |
| 178 | + $mockRequest->expects($this->exactly(1)) |
| 179 | + ->method('getHeader') |
| 180 | + ->with('Slug') |
| 181 | + ->willReturn([self::MOCK_SLUG, 'Second Mock Slug']); |
| 182 | + |
| 183 | + $mockFileSystem->expects($this->exactly(2)) |
| 184 | + ->method('has') |
| 185 | + ->withAnyParameters() |
| 186 | + ->willReturnMap([ |
| 187 | + [self::MOCK_SLUG, true], |
| 188 | + [$expectedName, false], |
| 189 | + ]); |
| 190 | + |
| 191 | + $mockFileSystem->expects($this->exactly(1)) |
| 192 | + ->method('write') |
| 193 | + ->with($expectedName, '', []) |
| 194 | + ->willReturn(true); |
| 195 | + |
| 196 | + $mockFileSystem->expects($this->exactly(1)) |
| 197 | + ->method('getMimetype') |
| 198 | + ->with(self::MOCK_SLUG) |
| 199 | + ->willReturn(Server::MIME_TYPE_DIRECTORY); |
| 200 | + |
| 201 | + $server = new Server($mockFileSystem, $expected, $mockGraph); |
| 202 | + |
| 203 | + // Act |
| 204 | + $response = $server->respondToRequest($mockRequest); |
| 205 | + |
| 206 | + $actual = $response->getHeaderLine('Location'); |
| 207 | + |
| 208 | + $this->assertEquals($expectedName, $actual); |
| 209 | + } |
| 210 | + |
| 211 | + public static function provideMimeTypes() |
| 212 | + { |
| 213 | + return [ |
| 214 | + 'mime: (empty)' => [''], |
| 215 | + 'mime: application/json' => ['application/json'], |
| 216 | + 'mime: application/ld+json' => ['application/ld+json'], |
| 217 | + 'mime: some/other' => ['some/other'], |
| 218 | + 'mime: text/html' => ['text/html'], |
| 219 | + 'mime: text/plain' => ['text/plain'], |
| 220 | + 'mime: text/turtle' => ['text/turtle'], |
| 221 | + ]; |
| 222 | + } |
| 223 | + |
| 224 | + public static function provideUnsupportedHttpMethods() |
| 225 | + { |
| 226 | + return [ |
| 227 | + 'string:(empty)' => [''], |
| 228 | + 'string:CONNECT' => ['CONNECT'], |
| 229 | + 'string:TRACE' => ['TRACE'], |
| 230 | + 'string:UNKNOWN' => ['UNKNOWN'], |
| 231 | + ]; |
| 232 | + } |
63 | 233 | } |
0 commit comments