Browse Source

Replicate some unspecified NCNv1 behaviour, and document the rest

See #139 for list

Closes #139
Closes #140
Closes #141
J. King 1 month ago
parent
commit
3b3b810f10
3 changed files with 29 additions and 11 deletions
  1. 6
    9
      README.md
  2. 2
    2
      lib/REST/NextCloudNews/V1_2.php
  3. 21
    0
      tests/cases/REST/NextCloudNews/TestV1_2.php

+ 6
- 9
README.md View File

@@ -97,15 +97,12 @@ As a general rule, The Arsse should yield the same output as the reference imple
97 97
 - The API's "updater" routes do not require administrator priviledges as The Arsse has no concept of user classes
98 98
 - The "updater" console commands mentioned in the protocol specification are not implemented, as The Arsse does not implement the required NextCloud subsystems
99 99
 - The `lastLoginTimestamp` attribute of the user metadata is always the current time: The Arsse's implementation of the protocol is fully stateless
100
-
101
-#### Ambiguities
102
-
103
-- NCN specifies that GET parameters are treated "the same" as request body parameters; it does not specify what to do in cases where they conflict. The Arsse chooses to give GET parameters precedence
104
-- NCN does not define validity of folder and names other than to specify that the empty string is invalid. The Arsse further considers any string composed only of whitesapce to be invalid
105
-- NCN does not specify a return code for bulk-marking operations without a `newestItemId` provided; The Arsse returns `422`
106
-- NCN does not specify what should be done when creating a feed in a folder which does not exist; the Arsse adds the feed to the root folder
107
-- NCN does not specify what should be done when moving a feed to a folder which does not exist; The Arsse return `422`
108
-- NCN does not specify what should be done when renaming a feed to an invalid title, nor what constitutes an invalid title; The Arsse uses the same rules as it does for folders, and returns `422` in cases of rejection
100
+- Syntactically invalid JSON input will yield a `400 Bad Request` response instead of falling back to GET parameters
101
+- Folder names consisting only of whitespace are rejected along with the empty string
102
+- Feed titles consisting only of whitespace or the empty string are rejected with a `422 Unprocessable Entity` reponse instead of being accepted
103
+- Bulk-marking operations without a `newestItemId` argument result in a `422 Unprocessable Entity` reponse instead of silently failing
104
+- Creating a feed in a folder which does not exist places the feed in the root folder rather than suppressing the feed
105
+- Moving a feed to a folder which does not exist results in a `422 Unprocessable Entity` reponse rather than suppressing the feed
109 106
 
110 107
 ### Tiny Tiny RSS
111 108
 

+ 2
- 2
lib/REST/NextCloudNews/V1_2.php View File

@@ -111,8 +111,8 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
111 111
         } else {
112 112
             $data = [];
113 113
         }
114
-        // FIXME: Do query parameters take precedence in NextCloud? Is there a conflict error when values differ?
115
-        $data = $this->normalizeInput(array_merge($data, $req->getQueryParams()), $this->validInput, "unix");
114
+        // merge GET and POST data, and normalize it. POST parameters are preferred over GET parameters
115
+        $data = $this->normalizeInput(array_merge($req->getQueryParams(), $data), $this->validInput, "unix");
116 116
         // check to make sure the requested function is implemented
117 117
         try {
118 118
             $func = $this->chooseCall((string) $target, $req->getMethod());

+ 21
- 0
tests/cases/REST/NextCloudNews/TestV1_2.php View File

@@ -939,4 +939,25 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
939 939
         ]);
940 940
         $this->assertMessage($exp, $act);
941 941
     }
942
+    
943
+    public function testPreferJsonOverQueryParameters() {
944
+        $in = ['name' => "Software"];
945
+        $url = "/folders?name=Hardware";
946
+        $out1 = ['id' => 1, 'name' => "Software"];
947
+        $out2 = ['id' => 2, 'name' => "Hardware"];
948
+        Phake::when(Arsse::$db)->folderAdd($this->anything(), $this->anything())->thenReturn(2);
949
+        Phake::when(Arsse::$db)->folderAdd($this->anything(), $in)->thenReturn(1);
950
+        Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v($out1));
951
+        Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2)->thenReturn($this->v($out2));
952
+        $exp = new Response(['folders' => [$out1]]);
953
+        $this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in)));
954
+    }
955
+    
956
+    public function testMeldJsonAndQueryParameters() {
957
+        $in = ['oldestFirst' => true];
958
+        $url = "/items?type=2";
959
+        Phake::when(Arsse::$db)->articleList->thenReturn(new Result([]));
960
+        $this->req("GET", $url, json_encode($in));
961
+        Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->reverse(false)->starred(true), Database::LIST_TYPICAL);
962
+    }
942 963
 }

Loading…
Cancel
Save