public function testUnlimited() { $quota = 'unlimited'; $expiration = time() + 86400 * 365; $response = API::post('users/' . self::$config['userID'] . '/storageadmin', "quota={$quota}&expiration={$expiration}", [], ["username" => self::$config['rootUsername'], "password" => self::$config['rootPassword']]); $this->assert200($response); $xml = API::getXMLFromResponse($response); $this->assertEquals($quota, (string) $xml->quota); $this->assertEquals($expiration, (int) $xml->expiration); }
public function testUserGroupsAnonymousAtom() { API::useAPIKey(false); $response = API::get("users/" . self::$config['userID'] . "/groups?content=json"); $this->assert200($response); $this->assertTotalResults(self::$config['numPublicGroups'], $response); // Make sure they're the right groups $xml = API::getXMLFromResponse($response); $groupIDs = array_map(function ($id) { return (int) $id; }, $xml->xpath('//atom:entry/zapi:groupID')); $this->assertContains(self::$config['ownedPublicGroupID'], $groupIDs); $this->assertContains(self::$config['ownedPublicNoAnonymousGroupID'], $groupIDs); }
public function testMultiContent() { $keys = array_keys(self::$items); $keyStr = implode(',', $keys); $response = API::userGet(self::$config['userID'], "items?itemKey={$keyStr}&content=bib,json"); $this->assert200($response); $xml = API::getXMLFromResponse($response); $this->assertTotalResults(sizeOf($keys), $response); $entries = $xml->xpath('//atom:entry'); foreach ($entries as $entry) { $key = (string) $entry->children("http://zotero.org/ns/api")->key; $content = $entry->content->asXML(); // Add namespace prefix (from <entry>) $content = str_replace('<content ', '<content xmlns:zapi="http://zotero.org/ns/api" ', $content); // Strip variable key and version $content = preg_replace('%"key": "[A-Z0-9]{8}",(\\s+)"version": [0-9]+%', '"key": "",$1"version": 0', $content); // Strip dateAdded/dateModified $iso8601Pattern = '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z'; $content = preg_replace('/"dateAdded": "' . $iso8601Pattern . '",(\\s+)"dateModified": "' . $iso8601Pattern . '"/', '"dateAdded": "",$1"dateModified": ""', $content); $this->assertXmlStringEqualsXmlString(self::$items[$key], $content); } }
private function _testSingleObjectLastModifiedVersion($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); $keyProp = $objectType . "Key"; $versionProp = $objectType . "Version"; switch ($objectType) { case 'collection': $objectKey = API::createCollection("Name", false, $this, 'key'); break; case 'item': $objectKey = API::createItem("book", array("title" => "Title"), $this, 'key'); break; case 'search': $objectKey = API::createSearch("Name", array(array("condition" => "title", "operator" => "contains", "value" => "test")), $this, 'key'); break; } // JSON: Make sure all three instances of the object version // (Last-Modified-Version, 'version', and data.version) // match the library version $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$objectKey}"); $this->assert200($response); $objectVersion = $response->getHeader("Last-Modified-Version"); $json = API::getJSONFromResponse($response); $this->assertEquals($objectVersion, $json['version']); $this->assertEquals($objectVersion, $json['data']['version']); // Atom: Make sure all three instances of the object version // (Last-Modified-Version, zapi:version, and the JSON // {$objectType}Version property match the library version $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?content=json"); $this->assert200($response); $objectVersion = $response->getHeader("Last-Modified-Version"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content'], true); $this->assertEquals($objectVersion, $json['version']); $this->assertEquals($objectVersion, $data['version']); $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?limit=1"); $this->assert200($response); $libraryVersion = $response->getHeader("Last-Modified-Version"); $this->assertEquals($libraryVersion, $objectVersion); $this->_modifyJSONObject($objectType, $json); // No If-Unmodified-Since-Version or JSON version property unset($json['version']); $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}", json_encode($json)); $this->assert428($response); // Out of date version $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}", json_encode($json), array("If-Unmodified-Since-Version: " . ($objectVersion - 1))); $this->assert412($response); // Update with version header $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}", json_encode($json), array("If-Unmodified-Since-Version: " . $objectVersion)); $this->assert204($response); $newObjectVersion = $response->getHeader("Last-Modified-Version"); $this->assertGreaterThan($objectVersion, $newObjectVersion); // Update object with JSON version property $this->_modifyJSONObject($objectType, $json); $json['version'] = $newObjectVersion; $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}", json_encode($json)); $this->assert204($response); $newObjectVersion2 = $response->getHeader("Last-Modified-Version"); $this->assertGreaterThan($newObjectVersion, $newObjectVersion2); // Make sure new library version matches new object version $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?limit=1"); $this->assert200($response); $newLibraryVersion = $response->getHeader("Last-Modified-Version"); $this->assertEquals($newObjectVersion2, $newLibraryVersion); return; // Create an item to increase the library version, and make sure // original object version stays the same API::createItem("book", array("title" => "Title"), $this, 'key'); $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?limit=1"); $this->assert200($response); $newObjectVersion2 = $response->getHeader("Last-Modified-Version"); $this->assertEquals($newLibraryVersion, $newObjectVersion2); // // Delete object // // No If-Unmodified-Since-Version $response = API::userDelete(self::$config['userID'], "{$objectTypePlural}/{$objectKey}"); $this->assert428($response); // Outdated If-Unmodified-Since-Version $response = API::userDelete(self::$config['userID'], "{$objectTypePlural}/{$objectKey}", array("If-Unmodified-Since-Version: " . $objectVersion)); $this->assert412($response); // Delete object $response = API::userDelete(self::$config['userID'], "{$objectTypePlural}/{$objectKey}", array("If-Unmodified-Since-Version: " . $newObjectVersion2)); $this->assert204($response); }
public function testTop() { API::userClear(self::$config['userID']); $collectionKey = API::createCollection('Test', false, $this, 'key'); $emptyCollectionKey = API::createCollection('Empty', false, $this, 'key'); $parentTitle1 = "Parent Title"; $childTitle1 = "This is a Test Title"; $parentTitle2 = "Another Parent Title"; $parentTitle3 = "Yet Another Parent Title"; $noteText = "This is a sample note."; $parentTitleSearch = "title"; $childTitleSearch = "test"; $dates = ["2013", "January 3, 2010", ""]; $orderedDates = [$dates[2], $dates[1], $dates[0]]; $itemTypes = ["journalArticle", "newspaperArticle", "book"]; $parentKeys = []; $childKeys = []; $parentKeys[] = API::createItem($itemTypes[0], [ 'title' => $parentTitle1, 'date' => $dates[0], 'collections' => [ $collectionKey ] ], $this, 'key'); $childKeys[] = API::createAttachmentItem("linked_url", [ 'title' => $childTitle1 ], $parentKeys[0], $this, 'key'); $parentKeys[] = API::createItem($itemTypes[1], [ 'title' => $parentTitle2, 'date' => $dates[1] ], $this, 'key'); $childKeys[] = API::createNoteItem($noteText, $parentKeys[1], $this, 'key'); // Create item with deleted child that matches child title search $parentKeys[] = API::createItem($itemTypes[2], [ 'title' => $parentTitle3 ], $this, 'key'); API::createAttachmentItem("linked_url", [ 'title' => $childTitle1, 'deleted' => true ], $parentKeys[sizeOf($parentKeys) - 1], $this, 'key'); // Add deleted item with non-deleted child $deletedKey = API::createItem("book", [ 'title' => "This is a deleted item", 'deleted' => true ], $this, 'key'); API::createNoteItem("This is a child note of a deleted item.", $deletedKey, $this, 'key'); // /top, JSON $response = API::userGet( self::$config['userID'], "items/top" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $json = API::getJSONFromResponse($response); $done = []; foreach ($json as $item) { $this->assertContains($item['key'], $parentKeys); $this->assertNotContains($item['key'], $done); $done[] = $item['key']; } // /top, Atom $response = API::userGet( self::$config['userID'], "items/top?content=json" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertCount(sizeOf($parentKeys), $xpath); foreach ($parentKeys as $parentKey) { $this->assertContains($parentKey, $xpath); } // /top, JSON, in collection $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top" ); $this->assert200($response); $this->assertNumResults(1, $response); $json = API::getJSONFromResponse($response); $this->assertCount(1, $json); $this->assertEquals($parentKeys[0], $json[0]['key']); // /top, Atom, in collection $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?content=json" ); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertCount(1, $xpath); $this->assertContains($parentKeys[0], $xpath); // /top, JSON, in empty collection $response = API::userGet( self::$config['userID'], "collections/$emptyCollectionKey/items/top" ); $this->assert200($response); $this->assertNumResults(0, $response); $this->assertTotalResults(0, $response); // /top, keys $response = API::userGet( self::$config['userID'], "items/top?format=keys" ); $this->assert200($response); $keys = explode("\n", trim($response->getBody())); $this->assertCount(sizeOf($parentKeys), $keys); foreach ($parentKeys as $parentKey) { $this->assertContains($parentKey, $keys); } // /top, keys, in collection $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?format=keys" ); $this->assert200($response); $this->assertEquals($parentKeys[0], trim($response->getBody())); // /top with itemKey for parent, JSON $response = API::userGet( self::$config['userID'], "items/top?itemKey=" . $parentKeys[0] ); $this->assert200($response); $this->assertNumResults(1, $response); $json = API::getJSONFromResponse($response); $this->assertEquals($parentKeys[0], $json[0]['key']); // /top with itemKey for parent, Atom $response = API::userGet( self::$config['userID'], "items/top?content=json&itemKey=" . $parentKeys[0] ); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertEquals($parentKeys[0], (string) array_shift($xpath)); // /top with itemKey for parent, JSON, in collection $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?itemKey=" . $parentKeys[0] ); $this->assert200($response); $this->assertNumResults(1, $response); $json = API::getJSONFromResponse($response); $this->assertEquals($parentKeys[0], $json[0]['key']); // /top with itemKey for parent, Atom, in collection $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?content=json&itemKey=" . $parentKeys[0] ); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertEquals($parentKeys[0], (string) array_shift($xpath)); // /top with itemKey for parent, keys $response = API::userGet( self::$config['userID'], "items/top?format=keys&itemKey=" . $parentKeys[0] ); $this->assert200($response); $this->assertEquals($parentKeys[0], trim($response->getBody())); // /top with itemKey for parent, keys, in collection $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?format=keys&itemKey=" . $parentKeys[0] ); $this->assert200($response); $this->assertEquals($parentKeys[0], trim($response->getBody())); // /top with itemKey for child, JSON $response = API::userGet( self::$config['userID'], "items/top?itemKey=" . $childKeys[0] ); $this->assert200($response); $this->assertNumResults(1, $response); $json = API::getJSONFromResponse($response); $this->assertEquals($parentKeys[0], $json[0]['key']); // /top with itemKey for child, Atom $response = API::userGet( self::$config['userID'], "items/top?content=json&itemKey=" . $childKeys[0] ); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertEquals($parentKeys[0], (string) array_shift($xpath)); // /top with itemKey for child, keys $response = API::userGet( self::$config['userID'], "items/top?format=keys&itemKey=" . $childKeys[0] ); $this->assert200($response); $this->assertEquals($parentKeys[0], trim($response->getBody())); // /top, Atom, with q for all items $response = API::userGet( self::$config['userID'], "items/top?q=$parentTitleSearch" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $json = API::getJSONFromResponse($response); $done = []; foreach ($json as $item) { $this->assertContains($item['key'], $parentKeys); $this->assertNotContains($item['key'], $done); $done[] = $item['key']; } // /top, Atom, with q for all items $response = API::userGet( self::$config['userID'], "items/top?content=json&q=$parentTitleSearch" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertCount(sizeOf($parentKeys), $xpath); foreach ($parentKeys as $parentKey) { $this->assertContains($parentKey, $xpath); } // /top, JSON, in collection, with q for all items $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?q=$parentTitleSearch" ); $this->assert200($response); $this->assertNumResults(1, $response); $json = API::getJSONFromResponse($response); $this->assertContains($parentKeys[0], $json[0]['key']); // /top, Atom, in collection, with q for all items $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?content=json&q=$parentTitleSearch" ); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertCount(1, $xpath); $this->assertContains($parentKeys[0], $xpath); // /top, JSON, with q for child item $response = API::userGet( self::$config['userID'], "items/top?q=$childTitleSearch" ); $this->assert200($response); $this->assertNumResults(1, $response); $json = API::getJSONFromResponse($response); $this->assertContains($parentKeys[0], $json[0]['key']); // /top, Atom, with q for child item $response = API::userGet( self::$config['userID'], "items/top?content=json&q=$childTitleSearch" ); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertCount(1, $xpath); $this->assertContains($parentKeys[0], $xpath); // /top, JSON, in collection, with q for child item $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?q=$childTitleSearch" ); $this->assert200($response); $this->assertNumResults(0, $response); // Not currently possible /*$this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertCount(1, $xpath); $this->assertContains($parentKeys[0], $xpath);*/ // /top, Atom, in collection, with q for child item $response = API::userGet( self::$config['userID'], "collections/$collectionKey/items/top?content=json&q=$childTitleSearch" ); $this->assert200($response); $this->assertNumResults(0, $response); // Not currently possible /*$this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $this->assertCount(1, $xpath); $this->assertContains($parentKeys[0], $xpath);*/ // /top, JSON, with q for all items, ordered by title $response = API::userGet( self::$config['userID'], "items/top?q=$parentTitleSearch" . "&order=title" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $json = API::getJSONFromResponse($response); $returnedTitles = []; foreach ($json as $item) { $returnedTitles[] = $item['data']['title']; } $orderedTitles = [$parentTitle1, $parentTitle2, $parentTitle3]; sort($orderedTitles); $this->assertEquals($orderedTitles, $returnedTitles); // /top, Atom, with q for all items, ordered by title $response = API::userGet( self::$config['userID'], "items/top?content=json&q=$parentTitleSearch" . "&order=title" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/atom:title'); $this->assertCount(sizeOf($parentKeys), $xpath); $orderedTitles = [$parentTitle1, $parentTitle2, $parentTitle3]; sort($orderedTitles); $orderedResults = array_map(function ($val) { return (string) $val; }, $xpath); $this->assertEquals($orderedTitles, $orderedResults); // /top, Atom, with q for all items, ordered by date asc $response = API::userGet( self::$config['userID'], "items/top?q=$parentTitleSearch" . "&order=date&sort=asc" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $json = API::getJSONFromResponse($response); $orderedResults = array_map(function ($val) { return $val['data']['date']; }, $json); $this->assertEquals($orderedDates, $orderedResults); // /top, Atom, with q for all items, ordered by date asc $response = API::userGet( self::$config['userID'], "items/top?content=json&q=$parentTitleSearch" . "&order=date&sort=asc" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/atom:content'); $this->assertCount(sizeOf($parentKeys), $xpath); $orderedResults = array_map(function ($val) { return json_decode($val)->date; }, $xpath); $this->assertEquals($orderedDates, $orderedResults); // /top, JSON, with q for all items, ordered by date desc $response = API::userGet( self::$config['userID'], "items/top?q=$parentTitleSearch" . "&order=date&sort=desc" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $json = API::getJSONFromResponse($response); $orderedDatesReverse = array_reverse($orderedDates); $orderedResults = array_map(function ($val) { return $val['data']['date']; }, $json); $this->assertEquals($orderedDatesReverse, $orderedResults); // /top, Atom, with q for all items, ordered by date desc $response = API::userGet( self::$config['userID'], "items/top?content=json&q=$parentTitleSearch" . "&order=date&sort=desc" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/atom:content'); $this->assertCount(sizeOf($parentKeys), $xpath); $orderedDatesReverse = array_reverse($orderedDates); $orderedResults = array_map(function ($val) { return json_decode($val)->date; }, $xpath); $this->assertEquals($orderedDatesReverse, $orderedResults); // /top, Atom, with q for all items, ordered by item type asc $response = API::userGet( self::$config['userID'], "items/top?q=$parentTitleSearch" . "&order=itemType" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $json = API::getJSONFromResponse($response); $orderedItemTypes = $itemTypes; sort($orderedItemTypes); $orderedResults = array_map(function ($val) { return $val['data']['itemType']; }, $json); $this->assertEquals($orderedItemTypes, $orderedResults); // /top, Atom, with q for all items, ordered by item type asc $response = API::userGet( self::$config['userID'], "items/top?content=json&q=$parentTitleSearch" . "&order=itemType" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:itemType'); $this->assertCount(sizeOf($parentKeys), $xpath); $orderedItemTypes = $itemTypes; sort($orderedItemTypes); $orderedResults = array_map(function ($val) { return (string) $val; }, $xpath); $this->assertEquals($orderedItemTypes, $orderedResults); // /top, Atom, with q for all items, ordered by item type desc $response = API::userGet( self::$config['userID'], "items/top?q=$parentTitleSearch" . "&order=itemType&sort=desc" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $json = API::getJSONFromResponse($response); $orderedItemTypes = $itemTypes; rsort($orderedItemTypes); $orderedResults = array_map(function ($val) { return $val['data']['itemType']; }, $json); $this->assertEquals($orderedItemTypes, $orderedResults); // /top, Atom, with q for all items, ordered by item type desc $response = API::userGet( self::$config['userID'], "items/top?content=json&q=$parentTitleSearch" . "&order=itemType&sort=desc" ); $this->assert200($response); $this->assertNumResults(sizeOf($parentKeys), $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:itemType'); $this->assertCount(sizeOf($parentKeys), $xpath); $orderedItemTypes = $itemTypes; rsort($orderedItemTypes); $orderedResults = array_map(function ($val) { return (string) $val; }, $xpath); $this->assertEquals($orderedItemTypes, $orderedResults); }
public function testTagNewer() { API::userClear(self::$config['userID']); // Create items with tags API::createItem("book", array("tags" => array(array("tag" => "a"), array("tag" => "b"))), $this); $version = API::getLibraryVersion(); // 'newer' shouldn't return any results $response = API::userGet(self::$config['userID'], "tags?newer={$version}"); $this->assert200($response); $this->assertNumResults(0, $response); // Create another item with tags API::createItem("book", array("tags" => array(array("tag" => "a"), array("tag" => "c"))), $this); // 'newer' should return new tag (Atom) $response = API::userGet(self::$config['userID'], "tags?content=json&newer={$version}"); $this->assert200($response); $this->assertNumResults(1, $response); $this->assertGreaterThan($version, $response->getHeader('Last-Modified-Version')); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $data = json_decode($data['content'], true); $this->assertEquals("c", $data['tag']); $this->assertEquals(0, $data['type']); // 'newer' should return new tag (JSON) $response = API::userGet(self::$config['userID'], "tags?newer={$version}"); $this->assert200($response); $this->assertNumResults(1, $response); $this->assertGreaterThan($version, $response->getHeader('Last-Modified-Version')); $json = API::getJSONFromResponse($response)[0]; $this->assertEquals("c", $json['tag']); $this->assertEquals(0, $json['meta']['type']); }
public function testCreateItemAndAnonymousRead() { // Create item API::useAPIKey(self::$config['apiKey']); $json = API::getItemTemplate("book"); $response = API::userPost(self::$config['userID'], "publications/items", json_encode([$json])); $this->assert200ForObject($response); // Test notifications (which we do here instead of in NotificationsTest.php because // we want to test library creation above (though we could delete the publications // library explicitly first)) $this->assertCountNotifications(1, $response); $this->assertHasNotification(['event' => 'topicUpdated', 'topic' => '/users/' . self::$config['userID'] . '/publications'], $response); $json = API::getJSONFromResponse($response); $itemKey = $json['success'][0]; // Read item anonymously API::useAPIKey(""); $libraryName = self::$config['username'] . '’s Publications'; // JSON $response = API::userGet(self::$config['userID'], "publications/items/{$itemKey}"); $this->assert200($response); $json = API::getJSONFromResponse($response); $this->assertEquals($libraryName, $json['library']['name']); $this->assertEquals("publications", $json['library']['type']); // Atom $response = API::userGet(self::$config['userID'], "publications/items/{$itemKey}?format=atom"); $this->assert200($response); $xml = API::getXMLFromResponse($response); $this->assertEquals($libraryName, (string) $xml->author->name); }
/** * Changing a group's metadata should change its ETag */ public function testUpdateMetadataAtom() { $response = API::userGet(self::$config['userID'], "groups?content=json&key=" . self::$config['apiKey']); $this->assert200($response); // Get group API URI and version $xml = API::getXMLFromResponse($response); $xml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom'); $xml->registerXPathNamespace('zapi', 'http://zotero.org/ns/api'); $groupID = (string) array_shift($xml->xpath("//atom:entry/zapi:groupID")); $url = (string) array_shift($xml->xpath("//atom:entry/atom:link[@rel='self']/@href")); $url = str_replace(self::$config['apiURLPrefix'], '', $url); $version = json_decode(API::parseDataFromAtomEntry($xml)['content'], true)['version']; // Make sure format=versions returns the same ETag $response = API::userGet(self::$config['userID'], "groups?format=versions&key=" . self::$config['apiKey']); $this->assert200($response); $json = json_decode($response->getBody()); $this->assertEquals($version, $json->{$groupID}); // Update group metadata $json = json_decode(array_shift($xml->xpath("//atom:entry/atom:content"))); $xml = new SimpleXMLElement("<group/>"); foreach ($json as $key => $val) { switch ($key) { case 'id': case 'members': continue; case 'name': $name = "My Test Group " . uniqid(); $xml['name'] = $name; break; case 'description': $description = "This is a test description " . uniqid(); $xml->{$key} = $description; break; case 'url': $urlField = "http://example.com/" . uniqid(); $xml->{$key} = $urlField; break; default: $xml[$key] = $val; } } $xml = trim(preg_replace('/^<\\?xml.+\\n/', "", $xml->asXML())); $response = API::put($url, $xml, array("Content-Type: text/xml"), array("username" => self::$config['rootUsername'], "password" => self::$config['rootPassword'])); $this->assert200($response); $xml = API::getXMLFromResponse($response); $xml->registerXPathNamespace('zxfer', 'http://zotero.org/ns/transfer'); $group = $xml->xpath('//atom:entry/atom:content/zxfer:group'); $this->assertCount(1, $group); $this->assertEquals($name, $group[0]['name']); $response = API::userGet(self::$config['userID'], "groups?format=versions&key=" . self::$config['apiKey']); $this->assert200($response); $json = json_decode($response->getBody()); $newVersion = $json->{$groupID}; $this->assertNotEquals($version, $newVersion); // Check ETag header on individual group request $response = API::groupGet($groupID, "?content=json&key=" . self::$config['apiKey']); $this->assert200($response); $this->assertEquals($newVersion, $response->getHeader('Last-Modified-Version')); $json = json_decode(API::getContentFromResponse($response)); $this->assertEquals($name, $json->name); $this->assertEquals($description, $json->description); $this->assertEquals($urlField, $json->url); }
public function testContentBibMulti() { $keys = array_keys(self::$items); $keyStr = implode(',', $keys); foreach (self::$styles as $style) { $response = API::userGet(self::$config['userID'], "items?itemKey={$keyStr}&content=bib" . ($style == "default" ? "" : "&style=" . urlencode($style))); $this->assert200($response); $xml = API::getXMLFromResponse($response); $this->assertTotalResults(sizeOf($keys), $response); $entries = $xml->xpath('//atom:entry'); foreach ($entries as $entry) { $key = (string) $entry->children("http://zotero.org/ns/api")->key; $content = $entry->content->asXML(); // Add zapi namespace $content = str_replace('<content ', '<content xmlns:zapi="http://zotero.org/ns/api" ', $content); $this->assertXmlStringEqualsXmlString(self::$items[$key]['atom']['bib'][$style], $content); } } }
public function testSortDirection() { API::userClear(self::$config['userID']); // Setup $dataArray = []; $dataArray[] = API::createItem("book", ['title' => "B", 'creators' => [["creatorType" => "author", "name" => "B"]], 'dateAdded' => '2014-02-05T00:00:00Z', 'dateModified' => '2014-04-05T01:00:00Z'], $this, 'jsonData'); $dataArray[] = API::createItem("journalArticle", ['title' => "A", 'creators' => [["creatorType" => "author", "name" => "A"]], 'dateAdded' => '2014-02-04T00:00:00Z', 'dateModified' => '2014-01-04T01:00:00Z'], $this, 'jsonData'); $dataArray[] = API::createItem("newspaperArticle", ['title' => "F", 'creators' => [["creatorType" => "author", "name" => "F"]], 'dateAdded' => '2014-02-03T00:00:00Z', 'dateModified' => '2014-02-03T01:00:00Z'], $this, 'jsonData'); $dataArray[] = API::createItem("book", ['title' => "C", 'creators' => [["creatorType" => "author", "name" => "C"]], 'dateAdded' => '2014-02-02T00:00:00Z', 'dateModified' => '2014-03-02T01:00:00Z'], $this, 'jsonData'); // Get sorted keys usort($dataArray, function ($a, $b) { return strcmp($a['dateAdded'], $b['dateAdded']); }); $keysByDateAddedAscending = array_map(function ($data) { return $data['key']; }, $dataArray); $keysByDateAddedDescending = array_reverse($keysByDateAddedAscending); // Ascending $response = API::userGet(self::$config['userID'], "items?format=keys&sort=dateAdded&direction=asc"); $this->assert200($response); $this->assertEquals($keysByDateAddedAscending, explode("\n", trim($response->getBody()))); $response = API::userGet(self::$config['userID'], "items?format=json&sort=dateAdded&direction=asc"); $this->assert200($response); $json = API::getJSONFromResponse($response); $keys = array_map(function ($val) { return $val['key']; }, $json); $this->assertEquals($keysByDateAddedAscending, $keys); $response = API::userGet(self::$config['userID'], "items?format=atom&sort=dateAdded&direction=asc"); $this->assert200($response); $xml = API::getXMLFromResponse($response); $keys = array_map(function ($val) { return (string) $val; }, $xml->xpath('//atom:entry/zapi:key')); $this->assertEquals($keysByDateAddedAscending, $keys); // Ascending using old 'order'/'sort' instead of 'sort'/'direction' $response = API::userGet(self::$config['userID'], "items?format=keys&order=dateAdded&sort=asc"); $this->assert200($response); $this->assertEquals($keysByDateAddedAscending, explode("\n", trim($response->getBody()))); $response = API::userGet(self::$config['userID'], "items?format=json&order=dateAdded&sort=asc"); $this->assert200($response); $json = API::getJSONFromResponse($response); $keys = array_map(function ($val) { return $val['key']; }, $json); $this->assertEquals($keysByDateAddedAscending, $keys); $response = API::userGet(self::$config['userID'], "items?format=atom&order=dateAdded&sort=asc"); $this->assert200($response); $xml = API::getXMLFromResponse($response); $keys = array_map(function ($val) { return (string) $val; }, $xml->xpath('//atom:entry/zapi:key')); $this->assertEquals($keysByDateAddedAscending, $keys); // Deprecated 'order'/'sort', but the wrong way $response = API::userGet(self::$config['userID'], "items?format=keys&sort=dateAdded&order=asc"); $this->assert200($response); $this->assertEquals($keysByDateAddedAscending, explode("\n", trim($response->getBody()))); // Descending $response = API::userGet(self::$config['userID'], "items?format=keys&sort=dateAdded&direction=desc"); $this->assert200($response); $this->assertEquals($keysByDateAddedDescending, explode("\n", trim($response->getBody()))); $response = API::userGet(self::$config['userID'], "items?format=json&sort=dateAdded&direction=desc"); $this->assert200($response); $json = API::getJSONFromResponse($response); $keys = array_map(function ($val) { return $val['key']; }, $json); $this->assertEquals($keysByDateAddedDescending, $keys); $response = API::userGet(self::$config['userID'], "items?format=atom&sort=dateAdded&direction=desc"); $this->assert200($response); $xml = API::getXMLFromResponse($response); $keys = array_map(function ($val) { return (string) $val; }, $xml->xpath('//atom:entry/zapi:key')); $this->assertEquals($keysByDateAddedDescending, $keys); // Descending $response = API::userGet(self::$config['userID'], "items?format=keys&order=dateAdded&sort=desc"); $this->assert200($response); $this->assertEquals($keysByDateAddedDescending, explode("\n", trim($response->getBody()))); $response = API::userGet(self::$config['userID'], "items?format=json&order=dateAdded&sort=desc"); $this->assert200($response); $json = API::getJSONFromResponse($response); $keys = array_map(function ($val) { return $val['key']; }, $json); $this->assertEquals($keysByDateAddedDescending, $keys); $response = API::userGet(self::$config['userID'], "items?format=atom&order=dateAdded&sort=desc"); $this->assert200($response); $xml = API::getXMLFromResponse($response); $keys = array_map(function ($val) { return (string) $val; }, $xml->xpath('//atom:entry/zapi:key')); $this->assertEquals($keysByDateAddedDescending, $keys); }
public function testAddRemoveGroupMemberNotification() { API::useAPIKey(""); $json = $this->createKeyWithAllGroupAccess(self::$config['userID']); $apiKey = $json['key']; try { // Get all keys with access to all groups $allGroupsKeys = $this->getKeysWithAllGroupAccess(self::$config['userID']); // Create group owned by another user $response = $this->createGroup(self::$config['userID2']); $xml = API::getXMLFromResponse($response); $groupID = (int) $xml->xpath("/atom:entry/zapi:groupID")[0]; try { // Add user to group $response = API::superPost("groups/{$groupID}/users", '<user id="' . self::$config['userID'] . '" role="member"/>'); $this->assert200($response); $this->assertCountNotifications(sizeOf($allGroupsKeys), $response); foreach ($allGroupsKeys as $key) { $this->assertHasNotification(['event' => 'topicAdded', 'apiKey' => $key, 'topic' => '/groups/' . $groupID], $response); } // Remove user from group $response = API::superDelete("groups/{$groupID}/users/" . self::$config['userID']); $this->assert204($response); $this->assertCountNotifications(sizeOf($allGroupsKeys), $response); foreach ($allGroupsKeys as $key) { $this->assertHasNotification(['event' => 'topicRemoved', 'apiKey' => $key, 'topic' => '/groups/' . $groupID], $response); } } finally { $response = API::superDelete("groups/{$groupID}"); $this->assert204($response); $this->assertCountNotifications(1, $response); $this->assertHasNotification(['event' => 'topicDeleted', 'topic' => '/groups/' . $groupID], $response); } } finally { $response = API::superDelete("keys/{$apiKey}"); try { $this->assert204($response); } catch (Exception $e) { var_dump($e); } } }