Exemplo n.º 1
0
 /**
  * An object type's primary data cache for a library has to be created before
  * 
  */
 public function testCacheCreatorPrimaryData()
 {
     $data = array("title" => "Title", "creators" => array(array("creatorType" => "author", "firstName" => "First", "lastName" => "Last"), array("creatorType" => "editor", "firstName" => "Ed", "lastName" => "McEditor")));
     $key = API::createItem("book", $data, $this, 'key');
     $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=csljson");
     $json = json_decode(API::getContentFromResponse($response));
     $this->assertEquals("First", $json->author[0]->given);
     $this->assertEquals("Last", $json->author[0]->family);
     $this->assertEquals("Ed", $json->editor[0]->given);
     $this->assertEquals("McEditor", $json->editor[0]->family);
 }
Exemplo n.º 2
0
 /**
  * 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);
 }
Exemplo n.º 3
0
 public function testReverseSameAs()
 {
     $items = array();
     $item = ["key" => API::createItem("book", false, null, 'key'), "relations" => [["owl:sameAs", "http://zotero.org/groups/1/items/AAAAAAAA"]]];
     $xml = Sync::updated(self::$sessionID);
     $updateKey = $xml['updateKey'];
     $lastSyncTimestamp = $xml['timestamp'];
     $xmlstr = '<data version="9">' . '<relations>';
     $subject = 'http://zotero.org/users/' . self::$config['userID'] . '/items/' . $item['key'];
     // Insert backwards, as client does via classic sync
     // if group item is dragged to personal library
     foreach ($item['relations'] as $rel) {
         $xmlstr .= '<relation libraryID="' . self::$config['libraryID'] . '">' . "<subject>{$rel[1]}</subject>" . "<predicate>{$rel[0]}</predicate>" . "<object>{$subject}</object>" . '</relation>';
     }
     $xmlstr .= '</relations>' . '</data>';
     $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr);
     Sync::waitForUpload(self::$sessionID, $response, $this);
     // Check via API
     $response = API::userGet(self::$config['userID'], "items/{$item['key']}?key=" . self::$config['apiKey'] . "&content=json");
     $content = API::getContentFromResponse($response);
     $json = json_decode($content, true);
     $uniquePredicates = array_unique(array_map(function ($x) {
         return $x[0];
     }, $item['relations']));
     $this->assertCount(sizeOf($uniquePredicates), $json['relations']);
     foreach ($item['relations'] as $rel) {
         $this->assertArrayHasKey($rel[0], $json['relations']);
         $this->assertContains($rel[1], $json['relations'][$rel[0]]);
     }
     // PUT via API, which should be unchanged
     $response = API::userPost(self::$config['userID'], "items?key=" . self::$config['apiKey'], json_encode(["items" => [$json]]));
     $results = json_decode($response->getBody(), true);
     $this->assertArrayHasKey('unchanged', $results);
     $this->assertContains($item['key'], $results['unchanged']);
     // Add another owl:sameAs via API
     if (is_string($json['relations']['owl:sameAs'])) {
         $json['relations']['owl:sameAs'] = [$json['relations']['owl:sameAs']];
     }
     $newURI = "http://zotero.org/groups/1/items/BBBBBBBB";
     $json['relations']['owl:sameAs'][] = $newURI;
     $item['relations'][] = ['owl:sameAs', $newURI];
     $response = API::userPost(self::$config['userID'], "items?key=" . self::$config['apiKey'], json_encode(["items" => [$json]]));
     $this->assertEquals(200, $response->getStatus());
     $results = json_decode($response->getBody(), true);
     $this->assertArrayHasKey('success', $results);
     $this->assertContains($item['key'], $results['success']);
     // Check via API
     $response = API::userGet(self::$config['userID'], "items/{$item['key']}?key=" . self::$config['apiKey'] . "&content=json");
     $content = API::getContentFromResponse($response);
     $json = json_decode($content, true);
     $uniquePredicates = array_unique(array_map(function ($x) {
         return $x[0];
     }, $item['relations']));
     $this->assertCount(sizeOf($uniquePredicates), $json['relations']);
     foreach ($item['relations'] as $rel) {
         $this->assertArrayHasKey($rel[0], $json['relations']);
         $this->assertContains($rel[1], $json['relations'][$rel[0]]);
     }
     $this->assertArrayHasKey("owl:sameAs", $json['relations']);
     $this->assertContains($newURI, $json['relations']['owl:sameAs']);
     $xml = Sync::updated(self::$sessionID);
     $updateKey = $xml['updateKey'];
     // First URL should still be in reverse order
     $this->assertEquals(2, sizeOf($xml->updated[0]->relations->xpath("//relations/relation")));
     $subRel = $xml->updated[0]->relations->xpath("//relations/relation[subject/text() = '{$item['relations'][0][1]}']");
     $objRel = $xml->updated[0]->relations->xpath("//relations/relation[object/text() = '{$newURI}']");
     $this->assertEquals(1, sizeOf($subRel));
     $this->assertEquals($subject, $subRel[0]->object);
     $this->assertEquals(1, sizeOf($objRel));
     $this->assertEquals($subject, $objRel[0]->subject);
     // Resave second relation via classic sync in reverse order
     $xmlstr = '<data version="9"><relations>';
     $xmlstr .= '<relation libraryID="' . self::$config['libraryID'] . '">' . "<subject>{$newURI}</subject>" . "<predicate>owl:sameAs</predicate>" . "<object>{$subject}</object>" . "</relation></relations></data>";
     $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr);
     Sync::waitForUpload(self::$sessionID, $response, $this);
     $xml = Sync::updated(self::$sessionID);
     $this->assertEquals(2, sizeOf($xml->updated[0]->relations->xpath("//relations/relation")));
     // Delete reverse relation via API
     $response = API::userGet(self::$config['userID'], "items/{$item['key']}?key=" . self::$config['apiKey'] . "&content=json");
     $content = API::getContentFromResponse($response);
     $json = json_decode($content, true);
     // Leave just the relation that's entered in normal order
     $json['relations']['owl:sameAs'] = [$newURI];
     $item['relations'] = ['owl:sameAs', $newURI];
     $response = API::userPost(self::$config['userID'], "items?key=" . self::$config['apiKey'], json_encode(["items" => [$json]]));
     $this->assertEquals(200, $response->getStatus());
     $results = json_decode($response->getBody(), true);
     $this->assertArrayHasKey('success', $results);
     $this->assertContains($item['key'], $results['success']);
     $response = API::userGet(self::$config['userID'], "items/{$item['key']}?key=" . self::$config['apiKey'] . "&content=json");
     $content = API::getContentFromResponse($response);
     $json = json_decode($content, true);
     $this->assertArrayHasKey("owl:sameAs", $json['relations']);
     $this->assertContains($newURI, $json['relations']['owl:sameAs']);
     // Should only have one relation left
     $this->assertEquals(1, sizeOf($json['relations']['owl:sameAs']));
 }
Exemplo n.º 4
0
 private function _testMultiObjectLastModifiedVersion($objectType)
 {
     $objectTypePlural = API::getPluralObjectType($objectType);
     $objectKeyProp = $objectType . "Key";
     $objectVersionProp = $objectType . "Version";
     $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'] . "&limit=1");
     $version = $response->getHeader("Last-Modified-Version");
     $this->assertTrue(is_numeric($version));
     switch ($objectType) {
         case 'collection':
             $json = new \stdClass();
             $json->name = "Name";
             break;
         case 'item':
             $json = API::getItemTemplate("book");
             break;
         case 'search':
             $json = new \stdClass();
             $json->name = "Name";
             $json->conditions = array(array("condition" => "title", "operator" => "contains", "value" => "test"));
             break;
     }
     // Outdated library version
     $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode(array($objectTypePlural => array($json))), array("Content-Type: application/json", "If-Unmodified-Since-Version: " . ($version - 1)));
     $this->assert412($response);
     // Make sure version didn't change during failure
     $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'] . "&limit=1");
     $this->assertEquals($version, $response->getHeader("Last-Modified-Version"));
     // Create a new object, using library timestamp
     $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode(array($objectTypePlural => array($json))), array("Content-Type: application/json", "If-Unmodified-Since-Version: {$version}"));
     $this->assert200($response);
     $version2 = $response->getHeader("Last-Modified-Version");
     $this->assertTrue(is_numeric($version2));
     // Version should be incremented on new object
     $this->assertGreaterThan($version, $version2);
     $objectKey = API::getFirstSuccessKeyFromResponse($response);
     // Check single-object request
     $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'] . "&content=json");
     $this->assert200($response);
     $version = $response->getHeader("Last-Modified-Version");
     $this->assertTrue(is_numeric($version));
     $this->assertEquals($version, $version2);
     $json = json_decode(API::getContentFromResponse($response));
     // Modify object
     $json->{$objectKeyProp} = $objectKey;
     switch ($objectType) {
         case 'collection':
             $json->name = "New Name";
             break;
         case 'item':
             $json->title = "New Title";
             break;
         case 'search':
             $json->name = "New Name";
             break;
     }
     // No If-Unmodified-Since-Version or object version property
     unset($json->{$objectVersionProp});
     $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode(array($objectTypePlural => array($json))), array("Content-Type: application/json"));
     $this->assert428ForObject($response);
     // Outdated object version property
     $json->{$objectVersionProp} = $version - 1;
     $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode(array($objectTypePlural => array($json))), array("Content-Type: application/json"));
     $this->assert412ForObject($response, ucwords($objectType) . " has been modified since specified version " . "(expected {$json->{$objectVersionProp}}, found {$version})");
     // Modify object, using object version property
     $json->{$objectVersionProp} = $version;
     $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode(array($objectTypePlural => array($json))), array("Content-Type: application/json"));
     $this->assert200($response);
     // Version should be incremented on modified object
     $version3 = $response->getHeader("Last-Modified-Version");
     $this->assertTrue(is_numeric($version3));
     $this->assertGreaterThan($version2, $version3);
     // Check library version
     $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey']);
     $version = $response->getHeader("Last-Modified-Version");
     $this->assertTrue(is_numeric($version));
     $this->assertEquals($version, $version3);
     // Check single-object request
     $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey']);
     $version = $response->getHeader("Last-Modified-Version");
     $this->assertTrue(is_numeric($version));
     $this->assertEquals($version, $version3);
     // TODO: Version should be incremented on deleted item
 }
Exemplo n.º 5
0
 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?key=" . self::$config['apiKey'] . "&content=json&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
     $response = API::userGet(self::$config['userID'], "tags?key=" . self::$config['apiKey'] . "&content=json&newer={$version}");
     $this->assert200($response);
     $this->assertNumResults(1, $response);
     $this->assertGreaterThan($version, $response->getHeader('Last-Modified-Version'));
     $content = API::getContentFromResponse($response);
     $json = json_decode($content, true);
     $this->assertEquals("c", $json['tag']);
     $this->assertEquals(0, $json['type']);
 }
Exemplo n.º 6
0
 public function testContentBibSingle()
 {
     foreach (self::$styles as $style) {
         foreach (self::$items as $key => $expected) {
             $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=bib" . ($style == "default" ? "" : "&style={$style}"));
             $this->assert200($response);
             $content = API::getContentFromResponse($response);
             // Add zapi namespace
             $content = str_replace('<content ', '<content xmlns:zapi="http://zotero.org/ns/api" ', $content);
             $this->assertXmlStringEqualsXmlString($expected['bib'][$style], $content);
         }
     }
 }