Exemplo n.º 1
0
 public static function setUpBeforeClass()
 {
     parent::setUpBeforeClass();
     API::userClear(self::$config['userID']);
     // Create test data
     $key = API::createItem("book", array("title" => "Title", "creators" => array(array("creatorType" => "author", "firstName" => "First", "lastName" => "Last"))), null, 'key');
     self::$items[$key] = '<content xmlns:zapi="http://zotero.org/ns/api" type="application/xml"><zapi:subcontent zapi:type="bib"><div xmlns="http://www.w3.org/1999/xhtml" class="csl-bib-body" style="line-height: 1.35; padding-left: 2em; text-indent:-2em;"><div class="csl-entry">Last, First. <i>Title</i>, n.d.</div></div></zapi:subcontent><zapi:subcontent zapi:type="json">' . \Zotero_Utilities::formatJSON(json_decode('{"itemKey":"","itemVersion":0,"itemType":"book","title":"Title","creators":[{"creatorType":"author","firstName":"First","lastName":"Last"}],"abstractNote":"","series":"","seriesNumber":"","volume":"","numberOfVolumes":"","edition":"","place":"","publisher":"","date":"","numPages":"","language":"","ISBN":"","shortTitle":"","url":"","accessDate":"","archive":"","archiveLocation":"","libraryCatalog":"","callNumber":"","rights":"","extra":"","tags":[],"collections":[],"relations":{}}')) . '</zapi:subcontent></content>';
     $key = API::createItem("book", array("title" => "Title 2", "creators" => array(array("creatorType" => "author", "firstName" => "First", "lastName" => "Last"), array("creatorType" => "editor", "firstName" => "Ed", "lastName" => "McEditor"))), null, 'key');
     self::$items[$key] = '<content xmlns:zapi="http://zotero.org/ns/api" type="application/xml"><zapi:subcontent zapi:type="bib"><div xmlns="http://www.w3.org/1999/xhtml" class="csl-bib-body" style="line-height: 1.35; padding-left: 2em; text-indent:-2em;"><div class="csl-entry">Last, First. <i>Title 2</i>. Edited by Ed McEditor, n.d.</div></div></zapi:subcontent><zapi:subcontent zapi:type="json">' . \Zotero_Utilities::formatJSON(json_decode('{"itemKey":"","itemVersion":0,"itemType":"book","title":"Title 2","creators":[{"creatorType":"author","firstName":"First","lastName":"Last"},{"creatorType":"editor","firstName":"Ed","lastName":"McEditor"}],"abstractNote":"","series":"","seriesNumber":"","volume":"","numberOfVolumes":"","edition":"","place":"","publisher":"","date":"","numPages":"","language":"","ISBN":"","shortTitle":"","url":"","accessDate":"","archive":"","archiveLocation":"","libraryCatalog":"","callNumber":"","rights":"","extra":"","tags":[],"collections":[],"relations":{}}')) . '</zapi:subcontent></content>';
 }
Exemplo n.º 2
0
 public function testInvalidCharacters()
 {
     $data = array('title' => "A" . chr(0) . "A", 'creators' => array(array('creatorType' => "author", 'name' => "B" . chr(1) . "B")), 'tags' => array(array('tag' => "C" . chr(2) . "C")));
     $xml = API::createItem("book", $data, $this, 'atom');
     $data = API::parseDataFromAtomEntry($xml);
     $json = json_decode($data['content']);
     $this->assertEquals("AA", $json->title);
     $this->assertEquals("BB", $json->creators[0]->name);
     $this->assertEquals("CC", $json->tags[0]->tag);
 }
Exemplo n.º 3
0
 public static function setUpBeforeClass()
 {
     parent::setUpBeforeClass();
     API::userClear(self::$config['userID']);
     // Create test data
     $key = API::createItem("book", array("title" => "Title", "creators" => array(array("creatorType" => "author", "firstName" => "First", "lastName" => "Last"))), null, 'key');
     self::$items[$key] = array("citation" => array("default" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="citation" type="xhtml"><span xmlns="http://www.w3.org/1999/xhtml">Last, <i>Title</i>.</span></content>', "apa" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="citation" type="xhtml"><span xmlns="http://www.w3.org/1999/xhtml">(Last, n.d.)</span></content>'), "bib" => array("default" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="bib" type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml" class="csl-bib-body" style="line-height: 1.35; padding-left: 2em; text-indent:-2em;"><div class="csl-entry">Last, First. <i>Title</i>, n.d.</div></div></content>', "apa" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="bib" type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml" class="csl-bib-body" style="line-height: 2; padding-left: 2em; text-indent:-2em;"><div class="csl-entry">Last, F. (n.d.). <i>Title</i>.</div></div></content>'));
     $key = API::createItem("book", array("title" => "Title 2", "creators" => array(array("creatorType" => "author", "firstName" => "First", "lastName" => "Last"), array("creatorType" => "editor", "firstName" => "Ed", "lastName" => "McEditor"))), null, 'key');
     self::$items[$key] = array("citation" => array("default" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="citation" type="xhtml"><span xmlns="http://www.w3.org/1999/xhtml">Last, <i>Title 2</i>.</span></content>', "apa" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="citation" type="xhtml"><span xmlns="http://www.w3.org/1999/xhtml">(Last, n.d.)</span></content>'), "bib" => array("default" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="bib" type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml" class="csl-bib-body" style="line-height: 1.35; padding-left: 2em; text-indent:-2em;"><div class="csl-entry">Last, First. <i>Title 2</i>. Edited by Ed McEditor, n.d.</div></div></content>', "apa" => '<content xmlns:zapi="http://zotero.org/ns/api" zapi:type="bib" type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml" class="csl-bib-body" style="line-height: 2; padding-left: 2em; text-indent:-2em;"><div class="csl-entry">Last, F. (n.d.). <i>Title 2</i>. (E. McEditor, Ed.).</div></div></content>'));
 }
Exemplo n.º 4
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.º 5
0
 public static function setUpBeforeClass()
 {
     parent::setUpBeforeClass();
     API::userClear(self::$config['userID']);
     //
     // Collections
     //
     /*for ($i=0; $i<5; $i++) {
     			self::$collectionKeys[] = API::createCollection("Test", false, null, 'key');
     		}*/
     //
     // Items
     //
     $titles = self::$titles;
     $names = self::$names;
     for ($i = 0; $i < sizeOf(self::$titles) - 2; $i++) {
         $key = API::createItem("book", ["title" => array_shift($titles), "creators" => [["creatorType" => "author", "name" => array_shift($names)]]], null, 'key');
         // Child attachments
         if (!is_null(self::$attachmentTitles[$i])) {
             self::$childAttachmentKeys[] = API::createAttachmentItem("imported_file", ["title" => self::$attachmentTitles[$i]], $key, null, 'key');
         }
         // Child notes
         if (!is_null(self::$notes[$i])) {
             self::$childNoteKeys[] = API::createNoteItem(self::$notes[$i], $key, null, 'key');
         }
         self::$itemKeys[] = $key;
     }
     // Top-level attachment
     self::$itemKeys[] = API::createAttachmentItem("imported_file", ["title" => array_shift($titles)], false, null, 'key');
     // Top-level note
     self::$itemKeys[] = API::createNoteItem(array_shift($titles), false, null, 'key');
     //
     // Searches
     //
     /*for ($i=0; $i<5; $i++) {
     			self::$searchKeys[] = API::createSearch("Test", 'default', null, 'key');
     		}*/
 }
Exemplo n.º 6
0
 public function testCreatorSummary()
 {
     $xml = API::createItem("book", array("creators" => array(array("creatorType" => "author", "name" => "Test"))), $this);
     $data = API::parseDataFromAtomEntry($xml);
     $itemKey = $data['key'];
     $json = json_decode($data['content'], true);
     $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary'));
     $this->assertEquals("Test", $creatorSummary);
     $json['creators'][] = array("creatorType" => "author", "firstName" => "Alice", "lastName" => "Foo");
     $response = API::userPut(self::$config['userID'], "items/{$itemKey}?key=" . self::$config['apiKey'], json_encode($json));
     $this->assert204($response);
     $xml = API::getItemXML($itemKey);
     $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary'));
     $this->assertEquals("Test and Foo", $creatorSummary);
     $data = API::parseDataFromAtomEntry($xml);
     $json = json_decode($data['content'], true);
     $json['creators'][] = array("creatorType" => "author", "firstName" => "Bob", "lastName" => "Bar");
     $response = API::userPut(self::$config['userID'], "items/{$itemKey}?key=" . self::$config['apiKey'], json_encode($json));
     $this->assert204($response);
     $xml = API::getItemXML($itemKey);
     $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary'));
     $this->assertEquals("Test et al.", $creatorSummary);
 }
Exemplo n.º 7
0
 public function testUnicodeTitle()
 {
     $title = "Tést";
     $xml = API::createItem("book", array("title" => $title), $this);
     $data = API::parseDataFromAtomEntry($xml);
     $key = $data['key'];
     // Test entry
     $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json");
     $this->assertContains('"title": "Tést"', $response->getBody());
     // Test feed
     $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&content=json");
     $this->assertContains('"title": "Tést"', $response->getBody());
 }
Exemplo n.º 8
0
 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);
 }
Exemplo n.º 9
0
 public function testSyncUploadUnchanged()
 {
     $data1 = API::createItem("audioRecording", array("title" => "Test", "relations" => array('owl:sameAs' => 'http://zotero.org/groups/1/items/AAAAAAAA')), null, 'data');
     // dc:relation already exists, so item shouldn't change
     $data2 = API::createItem("interview", array("relations" => array('dc:relation' => 'http://zotero.org/users/' . self::$config['userID'] . '/items/' . $data1['key'])), null, 'data');
     // Upload unchanged via sync
     $xml = Sync::updated(self::$sessionID);
     $updateKey = $xml['updateKey'];
     $lastSyncTimestamp = $xml['timestamp'];
     $itemXML1 = array_shift($xml->updated[0]->items[0]->xpath("item[@key='{$data1['key']}']"));
     $itemXML2 = array_shift($xml->updated[0]->items[0]->xpath("item[@key='{$data2['key']}']"));
     $itemXML1['libraryID'] = self::$config['libraryID'];
     $itemXML2['libraryID'] = self::$config['libraryID'];
     $xmlstr = '<data version="9">' . '<items>' . $itemXML1->asXML() . $itemXML2->asXML() . '</items>' . '</data>';
     $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr);
     Sync::waitForUpload(self::$sessionID, $response, $this);
     // Check via API to make sure they're the same
     $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&format=versions");
     $json = API::getJSONFromResponse($response);
     $this->assertEquals($data1['version'], $json[$data1['key']]);
     $this->assertEquals($data2['version'], $json[$data2['key']]);
 }
Exemplo n.º 10
0
 public function testCircularRelatedItems()
 {
     $parentKey = API::createItem("book", false, null, 'key');
     $noteKeys = [API::createNoteItem("Note 1", $parentKey, null, 'key'), API::createNoteItem("Note 2", $parentKey, null, 'key'), API::createNoteItem("Note 3", $parentKey, null, 'key'), API::createNoteItem("Note 4", $parentKey, null, 'key')];
     $xml = Sync::updated(self::$sessionID);
     $updateKey = $xml['updateKey'];
     $note1XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[0]}']"));
     $note2XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[1]}']"));
     $note3XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[2]}']"));
     $note4XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[3]}']"));
     $note1XML['libraryID'] = self::$config['libraryID'];
     $note2XML['libraryID'] = self::$config['libraryID'];
     $note3XML['libraryID'] = self::$config['libraryID'];
     $note4XML['libraryID'] = self::$config['libraryID'];
     $note1XML->related = implode(' ', [$parentKey, (string) $note2XML['key'], (string) $note3XML['key'], (string) $note4XML['key']]);
     $note2XML->related = implode(' ', [$parentKey, (string) $note1XML['key'], (string) $note3XML['key'], (string) $note4XML['key']]);
     $note3XML->related = implode(' ', [$parentKey, (string) $note1XML['key'], (string) $note2XML['key'], (string) $note4XML['key']]);
     $note4XML->related = implode(' ', [$parentKey, (string) $note1XML['key'], (string) $note2XML['key'], (string) $note3XML['key']]);
     $xmlstr = '<data version="9">' . '<items>' . $note1XML->asXML() . $note2XML->asXML() . $note3XML->asXML() . $note4XML->asXML() . '</items>' . '</data>';
     $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr);
     Sync::waitForUpload(self::$sessionID, $response, $this);
     $xml = Sync::updated(self::$sessionID);
     $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[0]}']"));
     $keys = split(' ', $noteXML->related);
     $this->assertCount(4, $keys);
     $this->assertContains($parentKey, $keys);
     $this->assertContains((string) $noteKeys[1], $keys);
     $this->assertContains((string) $noteKeys[2], $keys);
     $this->assertContains((string) $noteKeys[3], $keys);
     $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[1]}']"));
     $keys = split(' ', $noteXML->related);
     $this->assertCount(4, $keys);
     $this->assertContains($parentKey, $keys);
     $this->assertContains((string) $noteKeys[0], $keys);
     $this->assertContains((string) $noteKeys[2], $keys);
     $this->assertContains((string) $noteKeys[3], $keys);
     $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[2]}']"));
     $keys = split(' ', $noteXML->related);
     $this->assertCount(4, $keys);
     $this->assertContains($parentKey, $keys);
     $this->assertContains((string) $noteKeys[0], $keys);
     $this->assertContains((string) $noteKeys[1], $keys);
     $this->assertContains((string) $noteKeys[3], $keys);
     $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[3]}']"));
     $keys = split(' ', $noteXML->related);
     $this->assertCount(4, $keys);
     $this->assertContains($parentKey, $keys);
     $this->assertContains((string) $noteKeys[0], $keys);
     $this->assertContains((string) $noteKeys[1], $keys);
     $this->assertContains((string) $noteKeys[2], $keys);
 }
Exemplo n.º 11
0
 private function _testPartialWriteFailureWithUnchanged($objectType)
 {
     API::userClear(self::$config['userID']);
     $objectTypePlural = API::getPluralObjectType($objectType);
     switch ($objectType) {
         case 'collection':
             $data = API::createCollection("Test", false, $this, 'data');
             $json1 = json_decode($data['content']);
             $json2 = array("name" => str_repeat("1234567890", 6554));
             $json3 = array("name" => "Test");
             break;
         case 'item':
             $data = API::createItem("book", array("title" => "Title"), $this, 'data');
             $json1 = json_decode($data['content']);
             $json2 = API::getItemTemplate('book');
             $json3 = clone $json2;
             $json2->title = str_repeat("1234567890", 6554);
             break;
         case 'search':
             $conditions = array(array('condition' => 'title', 'operator' => 'contains', 'value' => 'value'));
             $data = API::createSearch("Name", $conditions, $this, 'data');
             $json1 = json_decode($data['content']);
             $json2 = array("name" => str_repeat("1234567890", 6554), "conditions" => $conditions);
             $json3 = array("name" => "Test", "conditions" => $conditions);
             break;
     }
     $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode(array("{$objectTypePlural}" => array($json1, $json2, $json3))), array("Content-Type: application/json"));
     $this->assert200($response);
     $json = API::getJSONFromResponse($response);
     $this->assertUnchangedForObject($response, false, 0);
     $this->assert400ForObject($response, false, 1);
     $this->assert200ForObject($response, false, 2);
     $json = API::getJSONFromResponse($response);
     $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?format=keys&key=" . self::$config['apiKey']);
     $this->assert200($response);
     $keys = explode("\n", trim($response->getBody()));
     $this->assertCount(2, $keys);
     foreach ($json['success'] as $key) {
         $this->assertContains($key, $keys);
     }
 }
Exemplo n.º 12
0
 /**
  * When modifying a tag on an item, only the item itself should have its
  * version updated, not other items that had (and still have) the same tag
  */
 public function testTagAddItemVersionChange()
 {
     $data1 = API::createItem("book", array("tags" => array(array("tag" => "a"), array("tag" => "b"))), $this, 'data');
     $json1 = json_decode($data1['content'], true);
     $version1 = $data1['version'];
     $data2 = API::createItem("book", array("tags" => array(array("tag" => "a"), array("tag" => "c"))), $this, 'data');
     $json2 = json_decode($data2['content'], true);
     $version2 = $data2['version'];
     // Remove tag 'a' from item 1
     $json1['tags'] = array(array("tag" => "d"), array("tag" => "c"));
     $response = API::postItem($json1);
     $this->assert200($response);
     // Item 1 version should be one greater than last update
     $xml1 = API::getItemXML($json1['itemKey']);
     $data1 = API::parseDataFromAtomEntry($xml1);
     $this->assertEquals($version2 + 1, $data1['version']);
     // Item 2 version shouldn't have changed
     $xml2 = API::getItemXML($json2['itemKey']);
     $data2 = API::parseDataFromAtomEntry($xml2);
     $this->assertEquals($version2, $data2['version']);
 }
Exemplo n.º 13
0
 public function testDeleteItemContent()
 {
     $key = API::createItem("book", false, $this, 'key');
     $xml = API::createAttachmentItem("imported_file", [], $key, $this, 'atom');
     $data = API::parseDataFromAtomEntry($xml);
     $content = "Ыюм мютат дэбетиз конвынёры эю, ку мэль жкрипта трактатоз.\nПро ут чтэт эрепюят граэкйж, дуо нэ выро рыкючабо пырикюлёз.";
     // Store content
     $response = API::userPut(self::$config['userID'], "items/{$data['key']}/fulltext?key=" . self::$config['apiKey'], json_encode(["content" => $content, "indexedPages" => 50]), array("Content-Type: application/json"));
     $this->assert204($response);
     $contentVersion = $response->getHeader("Last-Modified-Version");
     // Retrieve it
     $response = API::userGet(self::$config['userID'], "items/{$data['key']}/fulltext?key=" . self::$config['apiKey']);
     $this->assert200($response);
     $json = json_decode($response->getBody(), true);
     $this->assertEquals($content, $json['content']);
     $this->assertEquals(50, $json['indexedPages']);
     // Set to empty string
     $response = API::userPut(self::$config['userID'], "items/{$data['key']}/fulltext?key=" . self::$config['apiKey'], json_encode(["content" => ""]), array("Content-Type: application/json"));
     $this->assert204($response);
     $this->assertGreaterThan($contentVersion, $response->getHeader("Last-Modified-Version"));
     // Make sure it's gone
     $response = API::userGet(self::$config['userID'], "items/{$data['key']}/fulltext?key=" . self::$config['apiKey']);
     $this->assert200($response);
     $json = json_decode($response->getBody(), true);
     $this->assertEquals("", $json['content']);
     $this->assertArrayNotHasKey("indexedPages", $json);
 }
Exemplo n.º 14
0
 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());
 }
Exemplo n.º 15
0
 public function testDownloadCache()
 {
     $keys = [];
     $keys[] = API::createItem("book", false, false, 'key');
     $keys[] = API::createItem("journalArticle", false, false, 'key');
     $keys[] = API::createItem("newspaperArticle", false, false, 'key');
     $keys[] = API::createItem("magazineArticle", false, false, 'key');
     $keys[] = API::createItem("bookSection", false, false, 'key');
     $keys[] = API::createItem("audioRecording", false, false, 'key');
     $xml1 = Sync::updated(self::$sessionID);
     $xml2 = Sync::updated(self::$sessionID);
     $this->assertEquals(preg_replace('/timestamp="\\d+"/', 'timestamp="--"', $xml1->asXML()), preg_replace('/timestamp="\\d+"/', 'timestamp="--"', $xml2->asXML()));
 }
Exemplo n.º 16
0
 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());
 }
Exemplo n.º 17
0
 public function testDeleteItemRelation()
 {
     $relations = array("owl:sameAs" => ["http://zotero.org/groups/1/items/AAAAAAAA", "http://zotero.org/groups/1/items/BBBBBBBB"], "dc:relation" => "http://zotero.org/users/" . self::$config['userID'] . "/items/AAAAAAAA");
     $data = API::createItem("book", array("relations" => $relations), $this, 'data');
     $json = json_decode($data['content'], true);
     // Remove a relation
     $json['relations']['owl:sameAs'] = $relations['owl:sameAs'] = $relations['owl:sameAs'][0];
     $response = API::userPut(self::$config['userID'], "items/{$data['key']}?key=" . self::$config['apiKey'], json_encode($json));
     $this->assert204($response);
     // Make sure it's gone
     $xml = API::getItemXML($data['key']);
     $data = API::parseDataFromAtomEntry($xml);
     $json = json_decode($data['content'], true);
     $this->assertCount(sizeOf($relations), $json['relations']);
     foreach ($relations as $predicate => $object) {
         $this->assertEquals($object, $json['relations'][$predicate]);
     }
     // Delete all
     $json['relations'] = new \stdClass();
     $response = API::userPut(self::$config['userID'], "items/{$data['key']}?key=" . self::$config['apiKey'], json_encode($json));
     $this->assert204($response);
     // Make sure they're gone
     $xml = API::getItemXML($data['key']);
     $data = API::parseDataFromAtomEntry($xml);
     $json = json_decode($data['content'], true);
     $this->assertCount(0, $json['relations']);
 }
Exemplo n.º 18
0
 public function testCollectionItems()
 {
     $collectionKey = API::createCollection('Test', false, $this, 'key');
     $xml = API::createItem("book", array('collections' => array($collectionKey)), $this);
     $data = API::parseDataFromAtomEntry($xml);
     $itemKey1 = $data['key'];
     $itemVersion1 = $data['version'];
     $json = json_decode($data['content']);
     $this->assertEquals(array($collectionKey), $json->collections);
     $xml = API::createItem("journalArticle", array('collections' => array($collectionKey)), $this);
     $data = API::parseDataFromAtomEntry($xml);
     $itemKey2 = $data['key'];
     $itemVersion2 = $data['version'];
     $json = json_decode($data['content']);
     $this->assertEquals(array($collectionKey), $json->collections);
     $childItemKey1 = API::createAttachmentItem("linked_url", [], $itemKey1, $this, 'key');
     $childItemKey2 = API::createAttachmentItem("linked_url", [], $itemKey2, $this, 'key');
     $response = API::userGet(self::$config['userID'], "collections/{$collectionKey}/items?key=" . self::$config['apiKey'] . "&format=keys");
     $this->assert200($response);
     $keys = explode("\n", trim($response->getBody()));
     $this->assertCount(4, $keys);
     $this->assertContains($itemKey1, $keys);
     $this->assertContains($itemKey2, $keys);
     $this->assertContains($childItemKey1, $keys);
     $this->assertContains($childItemKey2, $keys);
     $response = API::userGet(self::$config['userID'], "collections/{$collectionKey}/items/top?key=" . self::$config['apiKey'] . "&format=keys");
     $this->assert200($response);
     $keys = explode("\n", trim($response->getBody()));
     $this->assertCount(2, $keys);
     $this->assertContains($itemKey1, $keys);
     $this->assertContains($itemKey2, $keys);
 }
Exemplo n.º 19
0
 public function testTagDeletePermissions()
 {
     API::userClear(self::$config['userID']);
     $xml = API::createItem('book', array("tags" => array(array("tag" => "A"))), $this);
     $libraryVersion = API::getLibraryVersion();
     API::setKeyOption(self::$config['userID'], self::$config['apiKey'], 'libraryWrite', 0);
     $response = API::userDelete(self::$config['userID'], "tags?tag=A&key=" . self::$config['apiKey']);
     $this->assert403($response);
     API::setKeyOption(self::$config['userID'], self::$config['apiKey'], 'libraryWrite', 1);
     $response = API::userDelete(self::$config['userID'], "tags?tag=A&key=" . self::$config['apiKey'], array("If-Unmodified-Since-Version: {$libraryVersion}"));
     $this->assert204($response);
 }
Exemplo n.º 20
0
 private function _testUploadUnmodified($objectType)
 {
     $objectTypePlural = API::getPluralObjectType($objectType);
     switch ($objectType) {
         case 'collection':
             $xml = API::createCollection("Name", false, $this);
             break;
         case 'item':
             $xml = API::createItem("book", array("title" => "Title"), $this);
             break;
         case 'search':
             $xml = API::createSearch("Name", 'default', $this);
             break;
     }
     $version = (int) array_shift($xml->xpath('//atom:entry/zapi:version'));
     $this->assertNotEquals(0, $version);
     $data = API::parseDataFromAtomEntry($xml);
     $json = json_decode($data['content']);
     $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$data['key']}?key=" . self::$config['apiKey'], json_encode($json));
     $this->assert204($response);
     $this->assertEquals($version, $response->getHeader("Last-Modified-Version"));
     switch ($objectType) {
         case 'collection':
             $xml = API::getCollectionXML($data['key']);
             break;
         case 'item':
             $xml = API::getItemXML($data['key']);
             break;
         case 'search':
             $xml = API::getSearchXML($data['key']);
             break;
     }
     $data = API::parseDataFromAtomEntry($xml);
     $this->assertEquals($version, $data['version']);
 }