public function testWebTranslationSingle() { $response = API::userPost(self::$config['userID'], "items?key=" . self::$config['apiKey'], json_encode(["url" => "http://www.amazon.com/Zotero-Guide-Librarians-Researchers-Educators/dp/0838985890/"]), array("Content-Type: application/json")); $this->assert201($response); $xml = API::getXMLFromResponse($response); $json = json_decode(API::parseDataFromAtomEntry($xml)['content']); $this->assertEquals('Zotero: A Guide for Librarians, Researchers and Educators', $json->title); }
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 testCreateItemWithChildren() { $json = API::getItemTemplate("newspaperArticle"); $noteJSON = API::getItemTemplate("note"); $noteJSON->note = "<p>Here's a test note</p>"; $json->notes = array($noteJSON); $response = API::userPost(self::$config['userID'], "items?key=" . self::$config['apiKey'], json_encode(array("items" => array($json)))); $this->assert201($response); $xml = API::getXMLFromResponse($response); $this->assertNumResults(1, $response); $this->assertEquals(1, (int) array_shift($xml->xpath('//atom:entry/zapi:numChildren'))); }
public function testUserGroupsAnonymous() { $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); }
/** * @depends testNewCollection */ public function testNewSubcollection($data) { $name = "Test Subcollection"; $parent = $data['key']; $xml = API::createCollection($name, $parent, $this, 'atom'); $this->assertEquals(1, (int) array_shift($xml->xpath('/atom:feed/zapi:totalResults'))); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $this->assertEquals($name, (string) $json->name); $this->assertEquals($parent, (string) $json->parentCollection); $response = API::userGet(self::$config['userID'], "collections/{$parent}?key=" . self::$config['apiKey']); $this->assert200($response); $xml = API::getXMLFromResponse($response); $this->assertEquals(1, (int) array_shift($xml->xpath('/atom:entry/zapi:numCollections'))); }
public function testMultiContent() { $keys = array_keys(self::$items); $keyStr = implode(',', $keys); $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&itemKey={$keyStr}&content=bib,json"); $this->assert200($response); $xml = API::getXMLFromResponse($response); $this->assertEquals(sizeOf($keys), (int) array_shift($xml->xpath('/atom:feed/zapi:totalResults'))); $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('%"itemKey": "[A-Z0-9]{8}",(\\s+)"itemVersion": [0-9]+%', '"itemKey": "",$1"itemVersion": 0', $content); $this->assertXmlStringEqualsXmlString(self::$items[$key], $content); } }
public function testAddFileClientZip() { API::userClear(self::$config['userID']); $auth = array('username' => self::$config['username'], 'password' => self::$config['password']); // Get last storage sync $response = API::userGet(self::$config['userID'], "laststoragesync?auth=1", array(), $auth); $this->assert404($response); $xml = API::createItem("book", false, $this); $data = API::parseDataFromAtomEntry($xml); $key = $data['key']; $fileContentType = "text/html"; $fileCharset = "UTF-8"; $fileFilename = "file.html"; $fileModtime = time(); $xml = API::createAttachmentItem("imported_url", [], $key, $this); $data = API::parseDataFromAtomEntry($xml); $key = $data['key']; $version = $data['version']; $json = json_decode($data['content']); $json->contentType = $fileContentType; $json->charset = $fileCharset; $json->filename = $fileFilename; $response = API::userPut(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'], json_encode($json), array("Content-Type: application/json")); $this->assert204($response); // Get a sync timestamp from before the file is updated sleep(1); require_once 'include/sync.inc.php'; $sessionID = Sync::login(); $xml = Sync::updated($sessionID); $lastsync = (int) $xml['timestamp']; Sync::logout($sessionID); // Get file info $response = API::userGet(self::$config['userID'], "items/{$data['key']}/file?auth=1&iskey=1&version=1&info=1", array(), $auth); $this->assert404($response); $zip = new ZipArchive(); $file = "work/{$key}.zip"; if ($zip->open($file, ZIPARCHIVE::CREATE) !== TRUE) { throw new Exception("Cannot open ZIP file"); } $zip->addFromString($fileFilename, self::getRandomUnicodeString()); $zip->addFromString("file.css", self::getRandomUnicodeString()); $zip->close(); $hash = md5_file($file); $filename = $key . ".zip"; $size = filesize($file); $fileContents = file_get_contents($file); // Get upload authorization $response = API::userPost(self::$config['userID'], "items/{$data['key']}/file?auth=1&iskey=1&version=1", $this->implodeParams(array("md5" => $hash, "filename" => $filename, "filesize" => $size, "mtime" => $fileModtime, "zip" => 1)), array("Content-Type: application/x-www-form-urlencoded"), $auth); $this->assert200($response); $this->assertContentType("application/xml", $response); $xml = new SimpleXMLElement($response->getBody()); self::$toDelete[] = "{$hash}"; $boundary = "---------------------------" . rand(); $postData = ""; foreach ($xml->params->children() as $key => $val) { $postData .= "--" . $boundary . "\r\nContent-Disposition: form-data; " . "name=\"{$key}\"\r\n\r\n{$val}\r\n"; } $postData .= "--" . $boundary . "\r\nContent-Disposition: form-data; " . "name=\"file\"\r\n\r\n" . $fileContents . "\r\n"; $postData .= "--" . $boundary . "--"; // Upload to S3 $response = HTTP::post((string) $xml->url, $postData, array("Content-Type: multipart/form-data; boundary=" . $boundary)); $this->assert201($response); // // Register upload // $response = API::userPost(self::$config['userID'], "items/{$data['key']}/file?auth=1&iskey=1&version=1", "update=" . $xml->key . "&mtime=" . $fileModtime, array("Content-Type: application/x-www-form-urlencoded"), $auth); $this->assert204($response); // Verify attachment item metadata $response = API::userGet(self::$config['userID'], "items/{$data['key']}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $this->assertEquals($hash, $json->md5); $this->assertEquals($fileFilename, $json->filename); $this->assertEquals($fileModtime, $json->mtime); // Make sure attachment item wasn't updated (or else the client // will get a conflict when it tries to update the metadata) $sessionID = Sync::login(); $xml = Sync::updated($sessionID, $lastsync); Sync::logout($sessionID); $this->assertEquals(0, $xml->updated[0]->count()); $response = API::userGet(self::$config['userID'], "laststoragesync?auth=1", array(), array('username' => self::$config['username'], 'password' => self::$config['password'])); $this->assert200($response); $mtime = $response->getBody(); $this->assertRegExp('/^[0-9]{10}$/', $mtime); // File exists $response = API::userPost(self::$config['userID'], "items/{$data['key']}/file?auth=1&iskey=1&version=1", $this->implodeParams(array("md5" => $hash, "filename" => $filename, "filesize" => $size, "mtime" => $fileModtime + 1000, "zip" => 1)), array("Content-Type: application/x-www-form-urlencoded"), $auth); $this->assert200($response); $this->assertContentType("application/xml", $response); $this->assertEquals("<exists/>", $response->getBody()); // Make sure attachment item still wasn't updated $sessionID = Sync::login(); $xml = Sync::updated($sessionID, $lastsync); Sync::logout($sessionID); $this->assertEquals(0, $xml->updated[0]->count()); }
public function testDate() { $date = "Sept 18, 2012"; $xml = API::createItem("book", array("date" => $date), $this); $data = API::parseDataFromAtomEntry($xml); $key = $data['key']; $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $this->assertEquals($date, $json->date); $this->assertEquals('2012', array_shift($xml->xpath('/atom:entry/zapi:year'))); }
/** * Changing a group's metadata should change its ETag */ public function testUpdateMetadata() { $response = API::userGet(self::$config['userID'], "groups?content=json&key=" . self::$config['apiKey']); $this->assert200($response); // Get group API URI and ETag $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); $etag = (string) array_shift($xml->xpath("//atom:entry/atom:content/@etag")); // Make sure format=etags returns the same ETag $response = API::userGet(self::$config['userID'], "groups?format=etags&key=" . self::$config['apiKey']); $this->assert200($response); $json = json_decode($response->getBody()); $this->assertEquals($etag, $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=etags&key=" . self::$config['apiKey']); $this->assert200($response); $json = json_decode($response->getBody()); $newETag = $json->{$groupID}; $this->assertNotEquals($etag, $newETag); // Check ETag header on individual group request $response = API::groupGet($groupID, "?content=json&key=" . self::$config['apiKey']); $this->assert200($response); $this->assertEquals($newETag, $response->getHeader('ETag')); $json = json_decode(API::getContentFromResponse($response)); $this->assertEquals($name, $json->name); $this->assertEquals($description, $json->description); $this->assertEquals($urlField, $json->url); }
public function testItemQuickSearchOrderByDate() { $title1 = "Test Title"; $title2 = "Another Title"; $keys = []; $keys[] = API::createItem("book", ['title' => $title1, 'date' => "February 12, 2013"], $this, 'key'); $keys[] = API::createItem("journalArticle", ['title' => $title2, 'date' => "November 25, 2012"], $this, 'key'); // Search for one by title $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&content=json&q=" . urlencode($title1)); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $key = (string) array_shift($xpath); $this->assertEquals($keys[0], $key); // Search by both by title, date asc $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&content=json&q=title&order=date&sort=asc"); $this->assert200($response); $this->assertNumResults(2, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $key = (string) array_shift($xpath); $this->assertEquals($keys[1], $key); $key = (string) array_shift($xpath); $this->assertEquals($keys[0], $key); // Search by both by title, date desc $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&content=json&q=title&order=date&sort=desc"); $this->assert200($response); $this->assertNumResults(2, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $key = (string) array_shift($xpath); $this->assertEquals($keys[0], $key); $key = (string) array_shift($xpath); $this->assertEquals($keys[1], $key); }
public function testRelatedItems() { $itemKey1 = API::createItem("audioRecording", array("relations" => array('owl:sameAs' => 'http://zotero.org/groups/1/items/AAAAAAAA')), null, 'key'); $itemURI1 = 'http://zotero.org/users/' . self::$config['userID'] . '/items/' . $itemKey1; $itemKey2 = API::createItem("interview", array("relations" => array('dc:relation' => $itemURI1)), null, 'key'); $itemURI2 = 'http://zotero.org/users/' . self::$config['userID'] . '/items/' . $itemKey2; $itemKey3 = API::createItem("book", null, null, 'key'); $itemURI3 = 'http://zotero.org/users/' . self::$config['userID'] . '/items/' . $itemKey3; $libraryVersion = API::getLibraryVersion(); // Add related items via sync $xml = Sync::updated(self::$sessionID); $updateKey = $xml['updateKey']; $lastSyncTimestamp = $xml['timestamp']; $itemXML1 = array_shift($xml->updated[0]->items[0]->xpath("item[@key='{$itemKey1}']")); $itemXML2 = array_shift($xml->updated[0]->items[0]->xpath("item[@key='{$itemKey2}']")); $itemXML3 = array_shift($xml->updated[0]->items[0]->xpath("item[@key='{$itemKey3}']")); $itemXML1['libraryID'] = self::$config['libraryID']; $itemXML2['libraryID'] = self::$config['libraryID']; $itemXML3['libraryID'] = self::$config['libraryID']; $itemXML1->related = $itemKey2 . ' ' . $itemKey3; $itemXML2->related = $itemKey1; $itemXML3->related = $itemKey1; $xmlstr = '<data version="9">' . '<items>' . $itemXML1->asXML() . $itemXML2->asXML() . $itemXML3->asXML() . '</items>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr); Sync::waitForUpload(self::$sessionID, $response, $this); // Check via API $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&content=json&newer={$libraryVersion}"); $xml = API::getXMLFromResponse($response); // Item 2 already had the relation and shouldn't have been updated $this->assertEquals(2, (int) array_shift($xml->xpath('/atom:feed/zapi:totalResults'))); $itemJSON1 = json_decode(array_shift($xml->xpath("//atom:entry[atom:id='{$itemURI1}']"))->content, 1); $itemJSON3 = json_decode(array_shift($xml->xpath("//atom:entry[atom:id='{$itemURI3}']"))->content, 1); $this->assertInternalType('array', $itemJSON1['relations']['dc:relation']); $this->assertInternalType('string', $itemJSON3['relations']['dc:relation']); $this->assertCount(2, $itemJSON1['relations']['dc:relation']); $this->assertTrue(in_array($itemURI2, $itemJSON1['relations']['dc:relation'])); $this->assertTrue(in_array($itemURI3, $itemJSON1['relations']['dc:relation'])); $this->assertEquals($itemURI1, $itemJSON3['relations']['dc:relation']); }
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; } // 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}?key=" . self::$config['apiKey'] . "&content=json"); $this->assert200($response); $objectVersion = $response->getHeader("Last-Modified-Version"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $this->assertEquals($objectVersion, $json->{$versionProp}); $this->assertEquals($objectVersion, $data['version']); $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'] . "&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->{$versionProp}); $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], json_encode($json)); $this->assert428($response); // Out of date version $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], 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}?key=" . self::$config['apiKey'], 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->{$versionProp} = $newObjectVersion; $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], 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}?key=" . self::$config['apiKey'] . "&limit=1"); $this->assert200($response); $newLibraryVersion = $response->getHeader("Last-Modified-Version"); $this->assertEquals($newObjectVersion2, $newLibraryVersion); // 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}?key=" . self::$config['apiKey'] . "&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}?key=" . self::$config['apiKey']); $this->assert428($response); // Outdated If-Unmodified-Since-Version $response = API::userDelete(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], array("If-Unmodified-Since-Version: " . $objectVersion)); $this->assert412($response); // Delete object $response = API::userDelete(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], array("If-Unmodified-Since-Version: " . $newObjectVersion2)); $this->assert204($response); }
public function testTagDeleteUnmodifiedItemChange() { $key = 'AAAAAAAA'; $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; // Create item via sync $data = '<data version="9"><items><item libraryID="' . self::$config['libraryID'] . '" itemType="book" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="' . $key . '"/></items>' . '<tags><tag libraryID="' . self::$config['libraryID'] . '" name="Test" ' . 'dateAdded="2009-03-07 04:54:56" ' . 'dateModified="2009-03-07 04:54:56" ' . 'key="BBBBBBBB">' . '<items>' . $key . '</items>' . '</tag></tags></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Get item via API $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $originalVersion = $data['version']; $this->assertCount(1, $json->tags); $this->assertTrue(isset($json->tags[0]->tag)); $this->assertEquals("Test", $json->tags[0]->tag); // Get item via sync $xml = Sync::updated(self::$sessionID); $this->assertEquals(1, sizeOf($xml->updated->items->item)); $this->assertEquals(1, sizeOf($xml->updated->tags->tag)); $this->assertEquals(1, sizeOf($xml->updated->tags->tag[0]->items)); $lastsync = (int) $xml['timestamp']; usleep(1500000); // Increment the library version, since we're testing the // version below API::createItem('newspaperArticle', false, false, 'key'); $libraryVersion = API::getLibraryVersion(); $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; // Delete tag via sync, with unmodified item $data = '<data version="9"><items><item libraryID="' . self::$config['libraryID'] . '" itemType="book" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="' . $key . '"/></items>' . '<deleted><tags><tag libraryID="' . self::$config['libraryID'] . '" key="BBBBBBBB"/>' . '</tags></deleted></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Get item via sync $xml = Sync::updated(self::$sessionID); $this->assertEquals(1, sizeOf(isset($xml->updated->tags->tag))); $this->assertFalse(isset($xml->updated->tags->tag[0]->items)); // Get item version via API $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $this->assertEquals(0, (int) array_shift($xml->xpath('/atom:entry/zapi:numTags'))); $this->assertCount(0, $json->tags); // New item version should be greater than before $this->assertGreaterThan($originalVersion, $data['version']); // And should be one more than previous version $this->assertEquals($libraryVersion + 1, $data['version']); // Only the newspaperArticle should be updated $xml = Sync::updated(self::$sessionID, $lastsync); $this->assertEquals(1, $xml->updated[0]->items[0]->count()); }
public function testEditSingleCollection() { API::useAPIVersion(2); $xml = API::createCollection("Test", false, $this); $data = API::parseDataFromAtomEntry($xml); $key = $data['key']; $version = $data['version']; API::useAPIVersion(1); $xml = API::getCollectionXML($data['key']); $etag = (string) array_shift($xml->xpath('//atom:entry/atom:content/@etag')); $this->assertNotNull($etag); $newName = "Test 2"; $json = array("name" => $newName, "parent" => false); $response = API::userPut(self::$config['userID'], "collections/{$key}?key=" . self::$config['apiKey'], json_encode($json), array("Content-Type: application/json", "If-Match: {$etag}")); $this->assert200($response); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $this->assertEquals($newName, (string) $json->name); }
public function testContentBibMulti() { $keys = array_keys(self::$items); $keyStr = implode(',', $keys); foreach (self::$styles as $style) { $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&itemKey={$keyStr}&content=bib" . ($style == "default" ? "" : "&style={$style}")); $this->assert200($response); $xml = API::getXMLFromResponse($response); $this->assertEquals(sizeOf($keys), (int) array_shift($xml->xpath('/atom:feed/zapi:totalResults'))); $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]['bib'][$style], $content); } } }
public function testCreatorItemChangeViaAPI() { $key = 'AAAAAAAA'; $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; // Create item via sync $data = '<data version="9"><items><item libraryID="' . self::$config['libraryID'] . '" itemType="book" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="' . $key . '">' . '<creator key="BBBBBBBB" creatorType="author" index="0">' . '<creator libraryID="' . self::$config['libraryID'] . '" ' . 'key="BBBBBBBB" dateAdded="2009-03-07 04:53:20" dateModified="2009-03-07 04:54:09">' . '<firstName>First</firstName>' . '<lastName>Last</lastName>' . '<fieldMode>0</fieldMode>' . '</creator></creator></item></items></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Get item version via API and check creatorSummary API::useAPIVersion(1); $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary')); $this->assertEquals("Last", $creatorSummary); $data = API::parseDataFromAtomEntry($xml); $etag = (string) array_shift($xml->xpath('//atom:entry/atom:content/@zapi:etag')); $this->assertNotEquals("", $etag); // Modify creator $json = json_decode($data['content'], true); $json['creators'][0] = array("name" => "First Last", "creatorType" => "author"); // Modify via API $response = API::userPut(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'], json_encode($json), array("If-Match: {$etag}")); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary')); $this->assertEquals("First Last", $creatorSummary); $this->assertTrue(isset($json->creators[0]->name)); $this->assertEquals("First Last", $json->creators[0]->name); $newETag = (string) array_shift($xml->xpath('//atom:entry/zapi:etag')); $this->assertNotEquals($etag, $newETag); // Get item again via API $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary')); $this->assertEquals("First Last", $creatorSummary); $this->assertTrue(isset($json->creators[0]->name)); $this->assertEquals("First Last", $json->creators[0]->name); $newETag = (string) array_shift($xml->xpath('//atom:entry/zapi:etag')); $this->assertNotEquals($etag, $newETag); }