fulltextTest.js (8244B)
1 describe("Zotero.Fulltext", function () { 2 var win; 3 4 before(function* () { 5 // Hidden browser, which requires a browser window, needed for charset detection 6 // (until we figure out a better way) 7 win = yield loadBrowserWindow(); 8 }); 9 after(function () { 10 if (win) { 11 win.close(); 12 } 13 }); 14 15 describe("Indexing", function () { 16 beforeEach(function () { 17 Zotero.Prefs.clear('fulltext.textMaxLength'); 18 Zotero.Prefs.clear('fulltext.pdfMaxPages'); 19 }); 20 after(function () { 21 Zotero.Prefs.clear('fulltext.textMaxLength'); 22 Zotero.Prefs.clear('fulltext.pdfMaxPages'); 23 }); 24 25 describe("#indexItems()", function () { 26 it("should index a text file by default", function* () { 27 var item = yield importFileAttachment('test.txt'); 28 assert.equal( 29 (yield Zotero.Fulltext.getIndexedState(item)), 30 Zotero.Fulltext.INDEX_STATE_INDEXED 31 ); 32 }) 33 34 it("should skip indexing of a text file if fulltext.textMaxLength is 0", function* () { 35 Zotero.Prefs.set('fulltext.textMaxLength', 0); 36 var item = yield importFileAttachment('test.txt'); 37 assert.equal( 38 (yield Zotero.Fulltext.getIndexedState(item)), 39 Zotero.Fulltext.INDEX_STATE_UNINDEXED 40 ); 41 }) 42 43 it("should index a PDF by default", function* () { 44 var item = yield importFileAttachment('test.pdf'); 45 assert.equal( 46 (yield Zotero.Fulltext.getIndexedState(item)), 47 Zotero.Fulltext.INDEX_STATE_INDEXED 48 ); 49 }) 50 51 it("should skip indexing of a PDF if fulltext.textMaxLength is 0", function* () { 52 Zotero.Prefs.set('fulltext.textMaxLength', 0); 53 var item = yield importFileAttachment('test.pdf'); 54 assert.equal( 55 (yield Zotero.Fulltext.getIndexedState(item)), 56 Zotero.Fulltext.INDEX_STATE_UNINDEXED 57 ); 58 }) 59 60 it("should skip indexing of a PDF if fulltext.pdfMaxPages is 0", function* () { 61 Zotero.Prefs.set('fulltext.pdfMaxPages', 0); 62 var item = yield importFileAttachment('test.pdf'); 63 assert.equal( 64 (yield Zotero.Fulltext.getIndexedState(item)), 65 Zotero.Fulltext.INDEX_STATE_UNINDEXED 66 ); 67 }) 68 }); 69 70 describe("#indexPDF()", function () { 71 it("should create cache files for linked attachments in storage directory", function* () { 72 var filename = 'test.pdf'; 73 var file = OS.Path.join(getTestDataDirectory().path, filename); 74 var tempDir = yield getTempDirectory(); 75 var linkedFile = OS.Path.join(tempDir, filename); 76 yield OS.File.copy(file, linkedFile); 77 78 var item = yield Zotero.Attachments.linkFromFile({ file: linkedFile }); 79 var storageDir = Zotero.Attachments.getStorageDirectory(item).path; 80 assert.isTrue(yield OS.File.exists(storageDir)); 81 assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, '.zotero-ft-info'))); 82 assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, '.zotero-ft-cache'))); 83 assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, filename))); 84 }); 85 }); 86 }); 87 88 describe("#getUnsyncedContent()", function () { 89 it("should get content that hasn't been uploaded", function* () { 90 var toSync = []; 91 var group = yield getGroup(); 92 93 var add = Zotero.Promise.coroutine(function* (options = {}) { 94 let item = yield createDataObject('item', { libraryID: options.libraryID }); 95 let attachment = new Zotero.Item('attachment'); 96 if (options.libraryID) { 97 attachment.libraryID = options.libraryID; 98 } 99 attachment.parentItemID = item.id; 100 attachment.attachmentLinkMode = 'imported_file'; 101 attachment.attachmentContentType = 'text/plain'; 102 attachment.attachmentCharset = 'utf-8'; 103 attachment.attachmentFilename = 'test.txt'; 104 if (options.synced) { 105 attachment.synced = true; 106 } 107 yield attachment.saveTx(); 108 yield Zotero.Attachments.createDirectoryForItem(attachment); 109 110 let path = attachment.getFilePath(); 111 let content = new Array(10).fill("").map(x => Zotero.Utilities.randomString()).join(" "); 112 yield Zotero.File.putContentsAsync(path, content); 113 114 if (!options.skip) { 115 toSync.push({ 116 item: attachment, 117 content, 118 indexedChars: content.length, 119 indexedPages: 0 120 }); 121 } 122 }); 123 yield add({ synced: true }); 124 yield add({ synced: true }); 125 // Unsynced attachment shouldn't uploaded 126 yield add({ skip: true }); 127 // Attachment in another library shouldn't be uploaded 128 yield add({ libraryID: group.libraryID, synced: true, skip: true }); 129 // PDF attachment 130 var pdfAttachment = yield importFileAttachment('test.pdf'); 131 pdfAttachment.synced = true; 132 yield pdfAttachment.saveTx(); 133 toSync.push({ 134 item: pdfAttachment, 135 content: "Zotero [zoh-TAIR-oh] is a free, easy-to-use tool to help you collect, " 136 + "organize, cite, and share your research sources.\n\n", 137 indexedChars: 0, 138 indexedPages: 1 139 }); 140 141 yield Zotero.Fulltext.indexItems(toSync.map(x => x.item.id)); 142 143 var data = yield Zotero.FullText.getUnsyncedContent(Zotero.Libraries.userLibraryID); 144 assert.lengthOf(data, 3); 145 let contents = toSync.map(x => x.content); 146 for (let d of data) { 147 let pos = contents.indexOf(d.content); 148 assert.isAbove(pos, -1); 149 assert.equal(d.indexedChars, toSync[pos].indexedChars); 150 assert.equal(d.indexedPages, toSync[pos].indexedPages); 151 } 152 }); 153 154 it("should mark PDF attachment content as missing if cache file doesn't exist", function* () { 155 var item = yield importFileAttachment('test.pdf'); 156 item.synced = true; 157 yield item.saveTx(); 158 159 yield Zotero.Fulltext.indexItems([item.id]); 160 yield OS.File.remove(Zotero.Fulltext.getItemCacheFile(item).path); 161 162 var sql = "SELECT synced FROM fulltextItems WHERE itemID=?"; 163 var synced = yield Zotero.DB.valueQueryAsync(sql, item.id); 164 assert.equal(synced, Zotero.Fulltext.SYNC_STATE_UNSYNCED); 165 var indexed = yield Zotero.Fulltext.getIndexedState(item); 166 assert.equal(indexed, Zotero.Fulltext.INDEX_STATE_INDEXED); 167 168 yield Zotero.Fulltext.getUnsyncedContent(item.libraryID); 169 170 synced = yield Zotero.DB.valueQueryAsync(sql, item.id); 171 assert.equal(synced, Zotero.Fulltext.SYNC_STATE_MISSING); 172 indexed = yield Zotero.Fulltext.getIndexedState(item); 173 assert.equal(indexed, Zotero.Fulltext.INDEX_STATE_UNINDEXED); 174 }); 175 }) 176 177 describe("#setItemContent()", function () { 178 before(() => { 179 // Disable PDF indexing 180 Zotero.Prefs.set('fulltext.pdfMaxPages', 0); 181 }); 182 183 after(() => { 184 // Re-enable PDF indexing 185 Zotero.Prefs.clear('fulltext.pdfMaxPages'); 186 }); 187 188 it("should store data in .zotero-ft-unprocessed file", function* () { 189 var item = yield importFileAttachment('test.pdf'); 190 191 var processorCacheFile = Zotero.Fulltext.getItemProcessorCacheFile(item).path; 192 var itemCacheFile = Zotero.Fulltext.getItemCacheFile(item).path; 193 yield Zotero.File.putContentsAsync(itemCacheFile, "Test"); 194 195 yield Zotero.Fulltext.setItemContent( 196 item.libraryID, 197 item.key, 198 { 199 content: "Test", 200 indexedChars: 4, 201 totalChars: 4 202 }, 203 5 204 ); 205 206 assert.equal((yield Zotero.Fulltext.getItemVersion(item.id)), 0); 207 assert.equal( 208 yield Zotero.DB. valueQueryAsync("SELECT synced FROM fulltextItems WHERE itemID=?", item.id), 209 2 // to process 210 ); 211 assert.isTrue(yield OS.File.exists(processorCacheFile)); 212 }); 213 214 215 it("should update the version if the local version is 0 but the text matches", function* () { 216 var item = yield importFileAttachment('test.pdf'); 217 218 yield Zotero.DB.queryAsync( 219 "REPLACE INTO fulltextItems (itemID, version, synced) VALUES (?, 0, ?)", 220 [item.id, 0] // to process 221 ); 222 223 var processorCacheFile = Zotero.Fulltext.getItemProcessorCacheFile(item).path; 224 var itemCacheFile = Zotero.Fulltext.getItemCacheFile(item).path; 225 yield Zotero.File.putContentsAsync(itemCacheFile, "Test"); 226 227 yield Zotero.Fulltext.setItemContent( 228 item.libraryID, 229 item.key, 230 { 231 content: "Test", 232 indexedChars: 4, 233 totalChars: 4 234 }, 235 5 236 ); 237 238 assert.equal((yield Zotero.Fulltext.getItemVersion(item.id)), 5); 239 assert.equal( 240 yield Zotero.DB. valueQueryAsync("SELECT synced FROM fulltextItems WHERE itemID=?", item.id), 241 1 // in sync 242 ); 243 assert.isFalse(yield OS.File.exists(processorCacheFile)); 244 }); 245 }); 246 })