Skip to content

Commit ec2e325

Browse files
committed
Merge branch 'fix/resource-extension' into test/unit
2 parents 6278319 + ad0adaf commit ec2e325

4 files changed

Lines changed: 59 additions & 42 deletions

File tree

.config/phpunit.xml.dist

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phpunit
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:noNamespaceSchemaLocation="../vendor/phpunit/phpunit/phpunit.xsd"
4+
xsi:noNamespaceSchemaLocation="../vendor/phpunit/phpunit/schema/9.5.xsd"
55

66
beStrictAboutCoversAnnotation="true"
77
beStrictAboutOutputDuringTests="true"
88
beStrictAboutTodoAnnotatedTests="true"
99
bootstrap="../vendor/autoload.php"
1010
cacheResultFile="../build/.phpunit.cache/test-results"
11+
colors="true"
1112
convertDeprecationsToExceptions="true"
1213
failOnRisky="true"
1314
failOnWarning="true"
1415
forceCoversAnnotation="true"
1516
verbose="true"
1617
>
1718
<testsuites>
18-
<testsuite name="all">
19-
<directory suffix=".php">../tests/</directory>
19+
<testsuite name="unit">
20+
<directory suffix=".php">../tests/unit/</directory>
2021
</testsuite>
2122
</testsuites>
2223

composer.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,27 @@
2020
"require": {
2121
"php": "^8.0",
2222
"ext-mbstring": "*",
23-
"laminas/laminas-diactoros": "^3.0",
23+
"laminas/laminas-diactoros": "^2.14",
2424
"league/flysystem": "^1.0",
2525
"mjrider/flysystem-factory": "^0.7",
26-
"pdsinterop/flysystem-rdf": "^0.5",
26+
"pdsinterop/flysystem-rdf": "^0.6",
2727
"pietercolpaert/hardf": "^0.3",
2828
"psr/http-factory": "^1.0",
2929
"psr/http-message": "^1.1 || ^2.0",
3030
"textalk/websocket": "^1.5"
3131
},
32+
"require-dev": {
33+
"ext-xdebug": "*",
34+
"ext-xml": "*",
35+
"phpunit/phpunit": "^9.5"
36+
},
3237
"scripts": {
3338
"dev:example": "php -S localhost:${PORT:-8080} -t ./src/ ./src/example.php",
34-
"tests:unit": "phpunit --configuration `.config/phpunit.xml.dist` ./tests/unit"
39+
"tests:unit": "phpunit --configuration '.config/phpunit.xml.dist' ./tests/unit"
3540
},
3641
"scripts-descriptions": {
3742
"dev:example": "Run internal PHP development server with example code",
3843
"tests:unit": "Run unit-test with PHPUnit"
3944
},
40-
"type": "library",
41-
"require-dev": {
42-
"phpunit/phpunit": "^9.0 | ^10.0"
43-
}
45+
"type": "library"
4446
}

src/Server.php

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Pdsinterop\Solid\Resources;
44

5+
use EasyRdf\Format;
56
use Pdsinterop\Solid\SolidNotifications\SolidNotificationsInterface;
67
use EasyRdf\Exception as RdfException;
78
use EasyRdf\Graph as Graph;
@@ -34,7 +35,7 @@ class Server
3435
public const ERROR_PUT_NON_EXISTING_RESOURCE = self::ERROR_PATH_DOES_NOT_EXIST . '. Can not "PUT" non-existing resource. Use "POST" instead';
3536
public const ERROR_UNKNOWN_HTTP_METHOD = 'Unknown or unsupported HTTP METHOD "%s"';
3637

37-
private const MIME_TYPE_DIRECTORY = 'directory';
38+
public const MIME_TYPE_DIRECTORY = 'directory';
3839
private const QUERY_PARAM_HTTP_METHOD = 'http-method';
3940

4041
private const NOTIFICATION_TYPE_CREATE = "Create";
@@ -55,6 +56,10 @@ class Server
5556
private $basePath;
5657
/** @var string */
5758
private $baseUrl;
59+
/** @var string */
60+
private $lockedPath;
61+
/** @var string */
62+
private $requestedPath;
5863
/** @var Filesystem */
5964
private $filesystem;
6065
/** @var Graph */
@@ -89,6 +94,11 @@ final public function setBaseUrl($url)
8994
$this->basePath = $serverRequest->getUri()->getPath();
9095
}
9196

97+
final public function lockToPath($path)
98+
{
99+
$this->lockedPath = $path;
100+
}
101+
92102
final public function setNotifications(SolidNotificationsInterface $notifications)
93103
{
94104
$this->notifications = $notifications;
@@ -100,9 +110,14 @@ final public function __construct(Filesystem $filesystem, Response $response, ?G
100110
{
101111
$this->basePath = '';
102112
$this->baseUrl = '';
113+
$this->lockedPath = false;
103114
$this->filesystem = $filesystem;
104115
$this->graph = $graph ?? new Graph();
105116
$this->response = $response;
117+
118+
// Store and serve json-ld with '.json' extension instead of '.jsonld''
119+
Format::getFormat('jsonld')->setExtensions('json');
120+
106121
// @TODO: Mention \EasyRdf_Namespace::set('lm', 'https://purl.org/pdsinterop/link-metadata#');
107122
}
108123

@@ -121,6 +136,11 @@ final public function respondToRequest(Request $request): Response
121136
$path = reset($slugs);
122137
}
123138

139+
$this->requestedPath = $path;
140+
if ($this->lockedPath) {
141+
$path = $this->lockedPath;
142+
}
143+
124144
$method = $this->getRequestMethod($request);
125145

126146
$contents = $request->getBody()->getContents();
@@ -191,7 +211,8 @@ private function handle(string $method, string $path, $contents, $request): Resp
191211
$response = $response->withStatus(400);
192212
break;
193213
}
194-
break;
214+
break;
215+
195216
case 'POST':
196217
$pathExists = $filesystem->has($path);
197218
if ($pathExists) {
@@ -201,6 +222,7 @@ private function handle(string $method, string $path, $contents, $request): Resp
201222
$pathExists = true;
202223
$mimetype = self::MIME_TYPE_DIRECTORY;
203224
}
225+
204226
if ($pathExists === true) {
205227
if (isset($mimetype) && $mimetype === self::MIME_TYPE_DIRECTORY) {
206228
$contentType= explode(";", $request->getHeaderLine("Content-Type"))[0];
@@ -217,25 +239,18 @@ private function handle(string $method, string $path, $contents, $request): Resp
217239
$response = $this->handleCreateDirectoryRequest($response, $path . $filename);
218240
break;
219241
default:
220-
// FIXME: make this list complete for at least the things we'd expect (turtle, n3, jsonld, ntriples, rdf);
221-
switch ($contentType) {
222-
case '':
223-
// FIXME: if no content type was passed, we should reject the request according to the spec;
224-
break;
225-
case "text/plain":
226-
$filename .= ".txt";
227-
break;
228-
case "text/turtle":
229-
$filename .= ".ttl";
230-
break;
231-
case "text/html":
232-
$filename .= ".html";
233-
break;
234-
case "application/json":
235-
case "application/ld+json":
236-
$filename .= ".json";
237-
break;
242+
// FIXME: if no content type was passed, we should reject the request according to the spec;
243+
foreach (Format::getFormats() as $format) {
244+
$mimeTypes = array_keys($format->getMimeTypes());
245+
foreach ($mimeTypes as $mimeType) {
246+
$extensions[$mimeType] = '.'.$format->getDefaultExtension();
247+
}
248+
}
249+
250+
if (isset($extensions[$contentType]) && ! str_ends_with($filename, $extensions[$contentType])) {
251+
$filename .= $extensions[$contentType];
238252
}
253+
239254
$response = $this->handleCreateRequest($response, $path . $filename, $contents);
240255
break;
241256
}
@@ -245,7 +260,8 @@ private function handle(string $method, string $path, $contents, $request): Resp
245260
} else {
246261
$response = $this->handleCreateRequest($response, $path, $contents);
247262
}
248-
break;
263+
break;
264+
249265
case 'PUT':
250266
$link = $request->getHeaderLine("Link");
251267
switch ($link) {
@@ -260,7 +276,8 @@ private function handle(string $method, string $path, $contents, $request): Resp
260276
}
261277
break;
262278
}
263-
break;
279+
break;
280+
264281
default:
265282
throw Exception::create(self::ERROR_UNKNOWN_HTTP_METHOD, [$method]);
266283
break;
@@ -283,7 +300,7 @@ private function handleSparqlUpdate(Response $response, string $path, $contents)
283300

284301
try {
285302
// Assuming this is in our native format, turtle
286-
$graph->parse($data, "turtle", $this->baseUrl . $path);
303+
$graph->parse($data, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath);
287304
// FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'?
288305
289306
// parse query in contents
@@ -297,14 +314,14 @@ private function handleSparqlUpdate(Response $response, string $path, $contents)
297314
case "INSERT":
298315
// insert $triple(s) into $graph
299316
// @CHECKME: Does the Graph Parse here also need an URI?
300-
$graph->parse($triples, "turtle"); // FIXME: The triples here are in sparql format, not in turtle;
317+
$graph->parse($triples, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle;
301318

302319
break;
303320
case "DELETE":
304321
// delete $triples from $graph
305322
$deleteGraph = $this->getGraph();
306323
// @CHECKME: Does the Graph Parse here also need an URI?
307-
$deleteGraph->parse($triples, "turtle"); // FIXME: The triples here are in sparql format, not in turtle;
324+
$deleteGraph->parse($triples, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle;
308325
$resources = $deleteGraph->resources();
309326
foreach ($resources as $resource) {
310327
$properties = $resource->propertyUris();
@@ -440,25 +457,22 @@ private function handleN3Update(Response $response, string $path, $contents): Re
440457

441458
try {
442459
// Assuming this is in our native format, turtle
443-
// @CHECKME: Does the Graph Parse here also need an URI?
444-
$graph->parse($data, "turtle");
445-
// FIXME: Adding this base will allow us to parse <> entries; , $this->baseUrl . $this->basePath . $path), but that breaks the build.
460+
$graph->parse($data, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath);
446461
// FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'?
447462
$instructions = $this->n3Convert($contents);
448463
foreach ($instructions as $key => $value) {
449464
switch ($key) {
450465
case "insert":
451466
// error_log("INSERT");
452467
// error_log($instructions['insert']);
453-
$graph->parse($instructions['insert'], "turtle");
468+
$graph->parse($instructions['insert'], "turtle", $this->baseUrl . $this->basePath . $this->requestedPath);
454469
break;
455470
case "delete":
456471
$deleteGraph = $this->getGraph();
457472
// error_log("DELETE");
458473
// error_log($instructions['delete']);
459474

460-
// @CHECKME: Does the Graph Parse here also need an URI?
461-
$deleteGraph->parse($instructions['delete'], "turtle");
475+
$deleteGraph->parse($instructions['delete'], "turtle", $this->baseUrl . $this->basePath . $this->requestedPath);
462476
$resources = $deleteGraph->resources();
463477
foreach ($resources as $resource) {
464478
$properties = $resource->propertyUris();
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Unit;
3+
namespace unit;
44

55
use Pdsinterop\Solid\Resources\Exception;
66
use PHPUnit\Framework\TestCase;

0 commit comments

Comments
 (0)