public function testAddUserSettingMultiple() { $settingKey = "tagColors"; $value = array(array("name" => "_READ", "color" => "#990000")); // TODO: multiple, once more settings are supported $libraryVersion = API::getLibraryVersion(); $json = array($settingKey => array("value" => $value)); $response = API::userPost(self::$config['userID'], "settings", json_encode($json), array("Content-Type: application/json")); $this->assert204($response); // Multi-object GET $response = API::userGet(self::$config['userID'], "settings"); $this->assert200($response); $this->assertContentType("application/json", $response); $json = json_decode($response->getBody(), true); $this->assertNotNull($json); $this->assertArrayHasKey($settingKey, $json); $this->assertEquals($value, $json[$settingKey]['value']); $this->assertEquals($libraryVersion + 1, $json[$settingKey]['version']); // Single-object GET $response = API::userGet(self::$config['userID'], "settings/{$settingKey}"); $this->assert200($response); $this->assertContentType("application/json", $response); $json = json_decode($response->getBody(), true); $this->assertNotNull($json); $this->assertEquals($value, $json['value']); $this->assertEquals($libraryVersion + 1, $json['version']); }
public function testZoteroWriteToken() { $json = API::getItemTemplate("book"); $token = md5(uniqid()); $response = API::userPost(self::$config['userID'], "items", json_encode([$json]), array("Content-Type: application/json", "Zotero-Write-Token: {$token}")); $this->assert200ForObject($response); $response = API::userPost(self::$config['userID'], "items", json_encode([$json]), array("Content-Type: application/json", "Zotero-Write-Token: {$token}")); $this->assert412($response); }
public function testWebTranslationInvalidToken() { $response = API::userPost(self::$config['userID'], "items?key=" . self::$config['apiKey'], json_encode(["url" => "http://www.amazon.com/s/field-keywords=zotero+guide+librarians", "token" => md5(uniqid())]), ["Content-Type: application/json"]); $this->assert400($response, "'token' is valid only for item selection requests"); }
public function testAddFileLinkedAttachment() { $key = API::createAttachmentItem("linked_file", [], false, $this, 'key'); $file = "work/file"; $fileContents = self::getRandomUnicodeString(); file_put_contents($file, $fileContents); $hash = md5_file($file); $filename = "test_" . $fileContents; $mtime = filemtime($file) * 1000; $size = filesize($file); $contentType = "text/plain"; $charset = "utf-8"; // Get upload authorization $response = API::userPost( self::$config['userID'], "items/$key/file", $this->implodeParams(array( "md5" => $hash, "filename" => $filename, "filesize" => $size, "mtime" => $mtime, "contentType" => $contentType, "charset" => $charset )), array( "Content-Type: application/x-www-form-urlencoded", "If-None-Match: *" ) ); $this->assert400($response); }
public function testLinkedFileAttachment() { $msg = "Linked-file attachments cannot be added to publications libraries"; // Create top-level item API::useAPIKey(self::$config['apiKey']); $json = API::getItemTemplate("book"); $response = API::userPost(self::$config['userID'], "publications/items", json_encode([$json])); $this->assert200($response); $json = API::getJSONFromResponse($response); $itemKey = $json['success'][0]; $json = API::getItemTemplate("attachment&linkMode=linked_file"); $json->parentItem = $itemKey; API::useAPIKey(self::$config['apiKey']); $response = API::userPost(self::$config['userID'], "publications/items", json_encode([$json]), array("Content-Type: application/json")); $this->assert400ForObject($response, $msg, 0); }
public function testInvalidCollectionRelation() { $json = ["name" => "Test", "relations" => array("foo:unknown" => "http://zotero.org/groups/1/collections/AAAAAAAA")]; $response = API::userPost(self::$config['userID'], "collections", json_encode([$json])); $this->assert400ForObject($response, "Unsupported predicate 'foo:unknown'"); $json["relations"] = array("owl:sameAs" => "Not a URI"); $response = API::userPost(self::$config['userID'], "collections", json_encode([$json])); $this->assert400ForObject($response, "'relations' values currently must be Zotero collection URIs"); $json["relations"] = ["http://zotero.org/groups/1/collections/AAAAAAAA"]; $response = API::userPost(self::$config['userID'], "collections", json_encode([$json])); $this->assert400ForObject($response, "'relations' property must be an object"); }
public function testEditMultipleSearches() { $search1Name = "Test 1"; $search1Conditions = [["condition" => "title", "operator" => "contains", "value" => "test"]]; $search1Data = API::createSearch($search1Name, $search1Conditions, $this, 'jsonData'); $search1NewName = "Test 1 Modified"; $search2Name = "Test 2"; $search2Conditions = [["condition" => "title", "operator" => "is", "value" => "test2"]]; $search2Data = API::createSearch($search2Name, $search2Conditions, $this, 'jsonData'); $search2NewConditions = [["condition" => "title", "operator" => "isNot", "value" => "test1"]]; $response = API::userPost(self::$config['userID'], "searches", json_encode([['key' => $search1Data['key'], 'version' => $search1Data['version'], 'name' => $search1NewName], ['key' => $search2Data['key'], 'version' => $search2Data['version'], 'conditions' => $search2NewConditions]]), ["Content-Type: application/json"]); $this->assert200($response); $json = API::getJSONFromResponse($response); $this->assertCount(2, $json['success']); $response = API::getSearchResponse($json['success']); $this->assertTotalResults(2, $response); $json = API::getJSONFromResponse($response); // POST follows PATCH behavior, so unspecified values shouldn't change $this->assertEquals($search1NewName, $json[0]['data']['name']); $this->assertEquals($search1Conditions, $json[0]['data']['conditions']); $this->assertEquals($search2Name, $json[1]['data']['name']); $this->assertEquals($search2NewConditions, $json[1]['data']['conditions']); }
public function testEditMultipleCollections() { $collection1Data = API::createCollection("Test 1", false, $this, 'jsonData'); $collection2Name = "Test 2"; $collection2Data = API::createCollection($collection2Name, false, $this, 'jsonData'); $collection1NewName = "Test 1 Modified"; $collection2NewParentKey = API::createCollection("Test 3", false, $this, 'key'); $response = API::userPost(self::$config['userID'], "collections", json_encode([['key' => $collection1Data['key'], 'version' => $collection1Data['version'], 'name' => $collection1NewName], ['key' => $collection2Data['key'], 'version' => $collection2Data['version'], 'parentCollection' => $collection2NewParentKey]]), ["Content-Type: application/json"]); $this->assert200($response); $json = API::getJSONFromResponse($response); $this->assertCount(2, $json['success']); $response = API::getCollectionResponse($json['success']); $this->assertTotalResults(2, $response); $json = API::getJSONFromResponse($response); // POST follows PATCH behavior, so unspecified values shouldn't change $this->assertEquals($collection1NewName, $json[0]['data']['name']); $this->assertFalse($json[0]['data']['parentCollection']); $this->assertEquals($collection2Name, $json[1]['data']['name']); $this->assertEquals($collection2NewParentKey, $json[1]['data']['parentCollection']); }
public function testPatchItems() { // Create top-level item API::useAPIKey(self::$config['apiKey']); $json = API::getItemTemplate("book"); $response = API::userPost(self::$config['userID'], "publications/items", json_encode([$json])); $this->assert200($response); $key = API::getJSONFromResponse($response)['successful'][0]['key']; $version = $response->getHeader("Last-Modified-Version"); $json = ["key" => $key, "version" => $version, "title" => "Test"]; $response = API::userPost(self::$config['userID'], "publications/items", json_encode([$json]), ["Content-Type: application/json"]); $this->assert200ForObject($response); }
private function _testMultiObjectWriteInvalidObject($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); $response = API::userPost(self::$config['userID'], "{$objectTypePlural}", json_encode(["foo" => "bar"]), array("Content-Type: application/json")); $this->assert400($response, "Uploaded data must be a JSON array"); $response = API::userPost(self::$config['userID'], "{$objectTypePlural}", json_encode([[], ""]), array("Content-Type: application/json")); $this->assert400ForObject($response, "Invalid value for index 0 in uploaded data; expected JSON {$objectType} object"); $this->assert400ForObject($response, "Invalid value for index 1 in uploaded data; expected JSON {$objectType} object", 1); }
public function testEditMultipleSearches() { $search1Name = "Test 1"; $search1Conditions = [["condition" => "title", "operator" => "contains", "value" => "test"]]; $search1Data = API::createSearch($search1Name, $search1Conditions, $this, 'jsonData'); $search1NewName = "Test 1 Modified"; $search2Name = "Test 2"; $search2Conditions = [["condition" => "title", "operator" => "is", "value" => "test2"]]; $search2Data = API::createSearch($search2Name, $search2Conditions, $this, 'jsonData'); $search2NewConditions = [["condition" => "title", "operator" => "isNot", "value" => "test1"]]; $response = API::userPost(self::$config['userID'], "searches", json_encode([['key' => $search1Data['key'], 'version' => $search1Data['version'], 'name' => $search1NewName], ['key' => $search2Data['key'], 'version' => $search2Data['version'], 'conditions' => $search2NewConditions]]), ["Content-Type: application/json"]); $this->assert200($response); $libraryVersion = $response->getHeader("Last-Modified-Version"); $json = API::getJSONFromResponse($response); $this->assertCount(2, $json['successful']); // Deprecated $this->assertCount(2, $json['success']); // Check data in write response $this->assertEquals($json['successful'][0]['key'], $json['successful'][0]['data']['key']); $this->assertEquals($json['successful'][1]['key'], $json['successful'][1]['data']['key']); $this->assertEquals($libraryVersion, $json['successful'][0]['version']); $this->assertEquals($libraryVersion, $json['successful'][1]['version']); $this->assertEquals($libraryVersion, $json['successful'][0]['data']['version']); $this->assertEquals($libraryVersion, $json['successful'][1]['data']['version']); $this->assertEquals($search1NewName, $json['successful'][0]['data']['name']); $this->assertEquals($search2Name, $json['successful'][1]['data']['name']); $this->assertEquals($search1Conditions, $json['successful'][0]['data']['conditions']); $this->assertEquals($search2NewConditions, $json['successful'][1]['data']['conditions']); // Check in separate request, to be safe $keys = array_map(function ($o) { return $o['key']; }, $json['successful']); $response = API::getSearchResponse($keys); $this->assertTotalResults(2, $response); $json = API::getJSONFromResponse($response); // POST follows PATCH behavior, so unspecified values shouldn't change $this->assertEquals($search1NewName, $json[0]['data']['name']); $this->assertEquals($search1Conditions, $json[0]['data']['conditions']); $this->assertEquals($search2Name, $json[1]['data']['name']); $this->assertEquals($search2NewConditions, $json[1]['data']['conditions']); }
public function testNoteTooLongWithinHTMLTags() { $this->json->note = " \n<p><!-- " . $this->content . " --></p>"; $response = API::userPost(self::$config['userID'], "items", json_encode([$this->json]), array("Content-Type: application/json")); $this->assert400ForObject($response, "Note '<p><!-- 1234567890123456789012345678901234567890123456789012345678901234...' too long"); }
public function testKeyNoteAccess() { API::userClear(self::$config['userID']); API::setKeyOption(self::$config['userID'], self::$config['apiKey'], 'libraryNotes', 1); $keys = array(); $topLevelKeys = array(); $bookKeys = array(); $key = API::createItem('book', array("title" => "A"), $this, 'key'); $keys[] = $key; $topKeys[] = $key; $bookKeys[] = $key; $key = API::createNoteItem("B", false, $this, 'key'); $keys[] = $key; $topKeys[] = $key; $key = API::createNoteItem("C", false, $this, 'key'); $keys[] = $key; $topKeys[] = $key; $key = API::createNoteItem("D", false, $this, 'key'); $keys[] = $key; $topKeys[] = $key; $key = API::createNoteItem("E", false, $this, 'key'); $keys[] = $key; $topKeys[] = $key; $key = API::createItem('book', array("title" => "F"), $this, 'key'); $keys[] = $key; $topKeys[] = $key; $bookKeys[] = $key; $key = API::createNoteItem("G", $key, $this, 'key'); $keys[] = $key; // Create collection and add items to it $response = API::userPost(self::$config['userID'], "collections", json_encode([["name" => "Test", "parentCollection" => false]]), array("Content-Type: application/json")); $this->assert200ForObject($response); $collectionKey = API::getFirstSuccessKeyFromResponse($response); $response = API::userPost(self::$config['userID'], "collections/{$collectionKey}/items", implode(" ", $topKeys)); $this->assert204($response); // // format=atom // // Root $response = API::userGet(self::$config['userID'], "items"); $this->assertNumResults(sizeOf($keys), $response); $this->assertTotalResults(sizeOf($keys), $response); // Top $response = API::userGet(self::$config['userID'], "items/top"); $this->assertNumResults(sizeOf($topKeys), $response); $this->assertTotalResults(sizeOf($topKeys), $response); // Collection $response = API::userGet(self::$config['userID'], "collections/{$collectionKey}/items/top"); $this->assertNumResults(sizeOf($topKeys), $response); $this->assertTotalResults(sizeOf($topKeys), $response); // // format=keys // // Root $response = API::userGet(self::$config['userID'], "items?format=keys"); $this->assert200($response); $this->assertCount(sizeOf($keys), explode("\n", trim($response->getBody()))); // Top $response = API::userGet(self::$config['userID'], "items/top?format=keys"); $this->assert200($response); $this->assertCount(sizeOf($topKeys), explode("\n", trim($response->getBody()))); // Collection $response = API::userGet(self::$config['userID'], "collections/{$collectionKey}/items/top?format=keys"); $this->assert200($response); $this->assertCount(sizeOf($topKeys), explode("\n", trim($response->getBody()))); // Remove notes privilege from key API::setKeyOption(self::$config['userID'], self::$config['apiKey'], 'libraryNotes', 0); // // format=json // // totalResults with limit $response = API::userGet(self::$config['userID'], "items?limit=1"); $this->assertNumResults(1, $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // And without limit $response = API::userGet(self::$config['userID'], "items"); $this->assertNumResults(sizeOf($bookKeys), $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // Top $response = API::userGet(self::$config['userID'], "items/top"); $this->assertNumResults(sizeOf($bookKeys), $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // Collection $response = API::userGet(self::$config['userID'], "collections/{$collectionKey}/items"); $this->assertNumResults(sizeOf($bookKeys), $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // // format=atom // // totalResults with limit $response = API::userGet(self::$config['userID'], "items?format=atom&limit=1"); $this->assertNumResults(1, $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // And without limit $response = API::userGet(self::$config['userID'], "items?format=atom"); $this->assertNumResults(sizeOf($bookKeys), $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // Top $response = API::userGet(self::$config['userID'], "items/top?format=atom"); $this->assertNumResults(sizeOf($bookKeys), $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // Collection $response = API::userGet(self::$config['userID'], "collections/{$collectionKey}/items?format=atom"); $this->assertNumResults(sizeOf($bookKeys), $response); $this->assertTotalResults(sizeOf($bookKeys), $response); // // format=keys // $response = API::userGet(self::$config['userID'], "items?format=keys"); $keys = explode("\n", trim($response->getBody())); sort($keys); $this->assertEmpty(array_merge(array_diff($bookKeys, $keys), array_diff($keys, $bookKeys))); }
public function testEditMultipleCollections() { $collection1Data = API::createCollection("Test 1", false, $this, 'jsonData'); $collection2Name = "Test 2"; $collection2Data = API::createCollection($collection2Name, false, $this, 'jsonData'); $collection1NewName = "Test 1 Modified"; $collection2NewParentKey = API::createCollection("Test 3", false, $this, 'key'); $response = API::userPost(self::$config['userID'], "collections", json_encode([['key' => $collection1Data['key'], 'version' => $collection1Data['version'], 'name' => $collection1NewName], ['key' => $collection2Data['key'], 'version' => $collection2Data['version'], 'parentCollection' => $collection2NewParentKey]]), ["Content-Type: application/json"]); $this->assert200($response); $libraryVersion = $response->getHeader("Last-Modified-Version"); $json = API::getJSONFromResponse($response); $this->assertCount(2, $json['successful']); // Deprecated $this->assertCount(2, $json['success']); // Check data in write response $this->assertEquals($json['successful'][0]['key'], $json['successful'][0]['data']['key']); $this->assertEquals($json['successful'][1]['key'], $json['successful'][1]['data']['key']); $this->assertEquals($libraryVersion, $json['successful'][0]['version']); $this->assertEquals($libraryVersion, $json['successful'][1]['version']); $this->assertEquals($libraryVersion, $json['successful'][0]['data']['version']); $this->assertEquals($libraryVersion, $json['successful'][1]['data']['version']); $this->assertEquals($collection1NewName, $json['successful'][0]['data']['name']); $this->assertEquals($collection2Name, $json['successful'][1]['data']['name']); $this->assertFalse($json['successful'][0]['data']['parentCollection']); $this->assertEquals($collection2NewParentKey, $json['successful'][1]['data']['parentCollection']); // Check in separate request, to be safe $keys = array_map(function ($o) { return $o['key']; }, $json['successful']); $response = API::getCollectionResponse($keys); $this->assertTotalResults(2, $response); $json = API::getJSONFromResponse($response); // POST follows PATCH behavior, so unspecified values shouldn't change $this->assertEquals($collection1NewName, $json[0]['data']['name']); $this->assertFalse($json[0]['data']['parentCollection']); $this->assertEquals($collection2Name, $json[1]['data']['name']); $this->assertEquals($collection2NewParentKey, $json[1]['data']['parentCollection']); }
public function testMappedCreatorTypes() { $json = [ [ 'itemType' => 'presentation', 'title' => 'Test', 'creators' => [ [ "creatorType" => "author", "name" => "Foo" ] ] ], [ 'itemType' => 'presentation', 'title' => 'Test', 'creators' => [ [ "creatorType" => "editor", "name" => "Foo" ] ] ] ]; $response = API::userPost( self::$config['userID'], "items", json_encode($json) ); // 'author' gets mapped automatically $this->assert200ForObject($response); // Others don't $this->assert400ForObject($response, false, 1); }
public function testKeyCreateAndDelete() { API::useAPIKey(""); $name = "Test " . uniqid(); // Can't create as user $response = API::userPost(self::$config['userID'], 'keys', json_encode(['name' => $name, 'access' => ['user' => ['library' => true]]])); $this->assert403($response); // Create as root $response = API::userPost(self::$config['userID'], 'keys', json_encode(['name' => $name, 'access' => ['user' => ['library' => true]]]), [], ["username" => self::$config['rootUsername'], "password" => self::$config['rootPassword']]); $this->assert201($response); $json = API::getJSONFromResponse($response); $key = $json['key']; $this->assertEquals($json['name'], $name); $this->assertEquals(['user' => ['library' => true, 'files' => true]], $json['access']); // Delete anonymously (with embedded key) $response = API::userDelete(self::$config['userID'], "keys/{$key}"); $this->assert204($response); $response = API::userGet(self::$config['userID'], "keys/{$key}"); $this->assert404($response); }
private function _testPatchExistingObjectsWithOldVersionProperty($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); $key = API::createDataObject($objectType, 'key'); $json = API::createUnsavedDataObject($objectType); $json['key'] = $key; $json['version'] = 1; $response = API::userPost(self::$config['userID'], "{$objectTypePlural}", json_encode([$json]), array("Content-Type: application/json")); $this->assert412ForObject($response); }
public function testKeyCreateAndModifyWithCredentials() { API::useAPIKey(""); $name = "Test " . uniqid(); // Can't create on /users/:userID/keys with credentials $response = API::userPost(self::$config['userID'], 'keys', json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]])); $this->assert403($response); // Create with credentials $response = API::post('keys', json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]]), [], []); $this->assert201($response); $json = API::getJSONFromResponse($response); $key = $json['key']; $this->assertEquals($json['userID'], self::$config['userID']); $this->assertEquals($json['name'], $name); $this->assertEquals(['user' => ['library' => true, 'files' => true]], $json['access']); $name = "Test " . uniqid(); // Can't modify on /users/:userID/keys/:key with credentials $response = API::userPut(self::$config['userID'], "keys/{$key}", json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]])); $this->assert403($response); // Modify with credentials $response = API::put("keys/{$key}", json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]])); $this->assert200($response); $json = API::getJSONFromResponse($response); $key = $json['key']; $this->assertEquals($json['name'], $name); $response = API::userDelete(self::$config['userID'], "keys/{$key}"); $this->assert204($response); }