mirror of
https://github.com/zotero/zotero.git
synced 2026-10-03 02:21:49 +00:00
move copy tests from file interface to quick copy
Tests in fileInterfaceTests were essentially just testing quickCopy behavior, so move those tests to quickCopyTest.js
This commit is contained in:
parent
e53e412504
commit
96623354fe
2 changed files with 272 additions and 320 deletions
|
|
@ -234,6 +234,15 @@ describe("Zotero_File_Interface", function () {
|
|||
assert.include(str, '<i>A</i>');
|
||||
assert.include(str, '<i>B</i>');
|
||||
});
|
||||
|
||||
it("should write text and html flavors directly to the clipboard", function () {
|
||||
win.Zotero_File_Interface.writeToClipboard({
|
||||
text: 'plain text',
|
||||
html: '<p>html text</p>'
|
||||
});
|
||||
assert.equal(getDataForFlavor('text/plain'), 'plain text');
|
||||
assert.equal(getDataForFlavor('text/html'), '<p>html text</p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Citavi annotations', () => {
|
||||
|
|
@ -306,184 +315,4 @@ describe("Zotero_File_Interface", function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe("Copy citations to clipboard", function () {
|
||||
var noteItem, itemOne, itemTwo;
|
||||
var styleID = 'http://www.zotero.org/styles/chicago-notes-bibliography';
|
||||
|
||||
before(async function () {
|
||||
await Zotero.Styles.init();
|
||||
await Zotero.Translators.init();
|
||||
|
||||
itemOne = createUnsavedDataObject('item', {
|
||||
itemType: 'book',
|
||||
title: 'Item One',
|
||||
creators: [
|
||||
{ firstName: 'firstOne', lastName: 'lastOne', creatorType: 'author' },
|
||||
{ firstName: 'firstTwo', lastName: 'lastTwo', creatorType: 'author' }
|
||||
]
|
||||
});
|
||||
await itemOne.saveTx();
|
||||
|
||||
itemTwo = createUnsavedDataObject('item', {
|
||||
itemType: 'book',
|
||||
title: 'Item Two',
|
||||
creators: [
|
||||
{ firstName: 'firstTwo', lastName: 'lastTwo', creatorType: 'author' },
|
||||
{ firstName: 'firstThree', lastName: 'lastThree', creatorType: 'author' }
|
||||
]
|
||||
});
|
||||
await itemTwo.saveTx();
|
||||
|
||||
var uriOne = Zotero.URI.getItemURI(itemOne);
|
||||
var uriTwo = Zotero.URI.getItemURI(itemTwo);
|
||||
var citationOne = {
|
||||
citationItems: [{ uris: [uriOne] }],
|
||||
properties: {}
|
||||
};
|
||||
var citationTwo = {
|
||||
citationItems: [{ uris: [uriTwo] }],
|
||||
properties: {}
|
||||
};
|
||||
var noteHTML = '<div data-schema-version="9">'
|
||||
+ '<p>Some text</p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationOne))
|
||||
+ '">(<span class="citation-item">lastOne and lastTwo</span>)</span></p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationTwo))
|
||||
+ '">(<span class="citation-item">lastTwo and lastThree</span>)</span></p>'
|
||||
+ '<p>Done</p>'
|
||||
+ '</div>';
|
||||
|
||||
noteItem = createUnsavedDataObject('item', {
|
||||
itemType: 'note',
|
||||
note: noteHTML
|
||||
});
|
||||
await noteItem.saveTx();
|
||||
|
||||
// Preload note translators
|
||||
let markdownTranslator = Zotero.Translators.get(Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN);
|
||||
markdownTranslator.cacheCode = true;
|
||||
await Zotero.Translators.getCodeForTranslator(markdownTranslator);
|
||||
let htmlTranslator = Zotero.Translators.get(Zotero.Translators.TRANSLATOR_ID_NOTE_HTML);
|
||||
htmlTranslator.cacheCode = true;
|
||||
await Zotero.Translators.getCodeForTranslator(htmlTranslator);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
Zotero.Prefs.clear('export.quickCopy.bibliographySetting');
|
||||
Zotero.Prefs.clear('export.noteQuickCopy.setting');
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await Zotero.Items.erase([noteItem.id, itemOne.id, itemTwo.id]);
|
||||
});
|
||||
|
||||
function getClipboardText() {
|
||||
let transferable = Components.classes['@mozilla.org/widget/transferable;1']
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
let clipboardService = Components.classes['@mozilla.org/widget/clipboard;1']
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
transferable.addDataFlavor('text/plain');
|
||||
clipboardService.getData(transferable, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
let str = {};
|
||||
transferable.getTransferData('text/plain', str);
|
||||
return str.value.QueryInterface(Components.interfaces.nsISupportsString).data;
|
||||
}
|
||||
|
||||
it(`should copy CSL-formatted citations to clipboard`, async function () {
|
||||
Zotero.Prefs.set('export.quickCopy.bibliographySetting', JSON.stringify({
|
||||
mode: 'bibliography', id: styleID, contentType: '', locale: ''
|
||||
}));
|
||||
Zotero.Prefs.set('export.noteQuickCopy.setting', JSON.stringify({
|
||||
mode: 'export',
|
||||
id: Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT,
|
||||
markdownOptions: { includeAppLinks: false },
|
||||
htmlOptions: { includeAppLinks: false }
|
||||
}));
|
||||
|
||||
await win.ZoteroPane.selectItem(noteItem.id);
|
||||
win.ZoteroPane.copySelectedItemsToClipboard(false, 'bibliography');
|
||||
await Zotero.Promise.delay();
|
||||
|
||||
var text = getClipboardText();
|
||||
var expected = 'Some text\n\n'
|
||||
+ '(firstOne lastOne and firstTwo lastTwo, Item One (n.d.).)\n\n'
|
||||
+ '(firstTwo lastTwo and firstThree lastThree, Item Two (n.d.).)\n\n'
|
||||
+ 'Done';
|
||||
assert.equal(text, expected);
|
||||
});
|
||||
|
||||
it("should use embedded item data for deleted items when copying to clipboard", async function () {
|
||||
var deletedItem = createUnsavedDataObject('item', {
|
||||
itemType: 'book',
|
||||
title: 'Deleted Item',
|
||||
creators: [
|
||||
{ firstName: 'firstDeleted', lastName: 'lastDeleted', creatorType: 'author' }
|
||||
]
|
||||
});
|
||||
await deletedItem.saveTx();
|
||||
|
||||
var uriOne = Zotero.URI.getItemURI(itemOne);
|
||||
var uriDeleted = Zotero.URI.getItemURI(deletedItem);
|
||||
var itemDataOne = Zotero.Utilities.Item.itemToCSLJSON(itemOne);
|
||||
var itemDataDeleted = Zotero.Utilities.Item.itemToCSLJSON(deletedItem);
|
||||
|
||||
var citationOne = {
|
||||
citationItems: [{ uris: [uriOne] }],
|
||||
properties: {}
|
||||
};
|
||||
var citationDeleted = {
|
||||
citationItems: [{ uris: [uriDeleted] }],
|
||||
properties: {}
|
||||
};
|
||||
|
||||
var storedCitationItems = [
|
||||
{ uris: [uriOne], itemData: itemDataOne },
|
||||
{ uris: [uriDeleted], itemData: itemDataDeleted }
|
||||
];
|
||||
var deletedNoteHTML = '<div data-citation-items="'
|
||||
+ encodeURIComponent(JSON.stringify(storedCitationItems))
|
||||
+ '" data-schema-version="9">'
|
||||
+ '<p>Before</p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationOne))
|
||||
+ '">(<span class="citation-item">lastOne and lastTwo</span>)</span></p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationDeleted))
|
||||
+ '">(<span class="citation-item">lastDeleted</span>)</span></p>'
|
||||
+ '<p>After</p>'
|
||||
+ '</div>';
|
||||
|
||||
var deletedNoteItem = createUnsavedDataObject('item', {
|
||||
itemType: 'note',
|
||||
note: deletedNoteHTML
|
||||
});
|
||||
await deletedNoteItem.saveTx();
|
||||
|
||||
await deletedItem.eraseTx();
|
||||
|
||||
Zotero.Prefs.set('export.quickCopy.bibliographySetting', JSON.stringify({ mode: 'bibliography', id: styleID, contentType: '', locale: '' }));
|
||||
|
||||
let items = Zotero.QuickCopy.reformatNoteCitations([deletedNoteItem]);
|
||||
let format = {
|
||||
mode: 'export',
|
||||
id: Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT,
|
||||
markdownOptions: { includeAppLinks: false },
|
||||
htmlOptions: { includeAppLinks: false }
|
||||
};
|
||||
let content = Zotero.QuickCopy.getContentFromItems(items, format);
|
||||
win.Zotero_File_Interface.writeToClipboard(content);
|
||||
await Zotero.Promise.delay();
|
||||
|
||||
var text = getClipboardText();
|
||||
var expected = 'Before\n\n'
|
||||
+ '(firstOne lastOne and firstTwo lastTwo, Item One (n.d.).)\n\n'
|
||||
+ '(firstDeleted lastDeleted, Deleted Item (n.d.).)\n\n'
|
||||
+ 'After';
|
||||
assert.equal(text, expected);
|
||||
|
||||
await deletedNoteItem.eraseTx();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
describe("Zotero.QuickCopy", function () {
|
||||
let domain = "test.org";
|
||||
var win, zp, doc;
|
||||
|
||||
const DEFAULT_BIB = {
|
||||
mode: 'bibliography',
|
||||
|
|
@ -16,7 +17,25 @@ describe("Zotero.QuickCopy", function () {
|
|||
const BIBTEX_TRANSLATOR_ID = '9cb70025-a888-4a29-a210-93ec52da40d4'; // BibTeX
|
||||
|
||||
before(async function () {
|
||||
win = await loadZoteroPane();
|
||||
zp = win.ZoteroPane;
|
||||
doc = win.document;
|
||||
await Zotero.Styles.init();
|
||||
await Zotero.Translators.init();
|
||||
await Zotero.QuickCopy.loadSiteSettings();
|
||||
|
||||
let translatorMarkdown = Zotero.Translators.get(Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN);
|
||||
translatorMarkdown.cacheCode = true;
|
||||
await Zotero.Translators.getCodeForTranslator(translatorMarkdown);
|
||||
|
||||
let translatorHTML = Zotero.Translators.get(Zotero.Translators.TRANSLATOR_ID_NOTE_HTML);
|
||||
translatorHTML.cacheCode = true;
|
||||
await Zotero.Translators.getCodeForTranslator(translatorHTML);
|
||||
});
|
||||
|
||||
after(function () {
|
||||
win.Zotero_Tabs.closeAll();
|
||||
win.close();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
|
|
@ -288,8 +307,6 @@ describe("Zotero.QuickCopy", function () {
|
|||
describe("#getContentFromItems()", function () {
|
||||
it("should generate BibTeX", async function () {
|
||||
var item = await createDataObject('item');
|
||||
|
||||
await Zotero.Translators.init();
|
||||
|
||||
var translatorID = '9cb70025-a888-4a29-a210-93ec52da40d4'; // BibTeX
|
||||
var format = 'export=' + translatorID;
|
||||
|
|
@ -305,7 +322,138 @@ describe("Zotero.QuickCopy", function () {
|
|||
assert.isTrue(content.text.trim().startsWith('@'));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("#reformatNoteCitations()", function () {
|
||||
var noteItem, itemOne, itemTwo;
|
||||
var styleID = 'http://www.zotero.org/styles/chicago-notes-bibliography';
|
||||
|
||||
before(async function () {
|
||||
itemOne = createUnsavedDataObject('item', {
|
||||
itemType: 'book',
|
||||
title: 'Item One',
|
||||
creators: [
|
||||
{ firstName: 'firstOne', lastName: 'lastOne', creatorType: 'author' },
|
||||
{ firstName: 'firstTwo', lastName: 'lastTwo', creatorType: 'author' }
|
||||
]
|
||||
});
|
||||
await itemOne.saveTx();
|
||||
|
||||
itemTwo = createUnsavedDataObject('item', {
|
||||
itemType: 'book',
|
||||
title: 'Item Two',
|
||||
creators: [
|
||||
{ firstName: 'firstTwo', lastName: 'lastTwo', creatorType: 'author' },
|
||||
{ firstName: 'firstThree', lastName: 'lastThree', creatorType: 'author' }
|
||||
]
|
||||
});
|
||||
await itemTwo.saveTx();
|
||||
|
||||
var uriOne = Zotero.URI.getItemURI(itemOne);
|
||||
var uriTwo = Zotero.URI.getItemURI(itemTwo);
|
||||
var citationOne = { citationItems: [{ uris: [uriOne] }], properties: {} };
|
||||
var citationTwo = { citationItems: [{ uris: [uriTwo] }], properties: {} };
|
||||
var noteHTML = '<div data-schema-version="9">'
|
||||
+ '<p>Some text</p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationOne))
|
||||
+ '">(<span class="citation-item">lastOne and lastTwo</span>)</span></p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationTwo))
|
||||
+ '">(<span class="citation-item">lastTwo and lastThree</span>)</span></p>'
|
||||
+ '<p>Done</p>'
|
||||
+ '</div>';
|
||||
|
||||
noteItem = createUnsavedDataObject('item', { itemType: 'note', note: noteHTML });
|
||||
await noteItem.saveTx();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await Zotero.Items.erase([noteItem.id, itemOne.id, itemTwo.id]);
|
||||
});
|
||||
|
||||
// getContentFromItems() calls reformatNoteCitations() internally when
|
||||
// items are notes, so we can read the reformatted output off content.text.
|
||||
function getNoteFormat() {
|
||||
return {
|
||||
mode: 'export',
|
||||
id: Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT,
|
||||
markdownOptions: { includeAppLinks: false },
|
||||
htmlOptions: { includeAppLinks: false }
|
||||
};
|
||||
}
|
||||
|
||||
it("should reformat note citations in the current CSL style", function () {
|
||||
Zotero.Prefs.set('export.quickCopy.bibliographySetting', JSON.stringify({
|
||||
mode: 'bibliography', id: styleID, contentType: '', locale: ''
|
||||
}));
|
||||
|
||||
let content = Zotero.QuickCopy.getContentFromItems([noteItem], getNoteFormat());
|
||||
var expected = 'Some text\n\n'
|
||||
+ '(firstOne lastOne and firstTwo lastTwo, Item One (n.d.).)\n\n'
|
||||
+ '(firstTwo lastTwo and firstThree lastThree, Item Two (n.d.).)\n\n'
|
||||
+ 'Done';
|
||||
assert.equal(content.text, expected);
|
||||
});
|
||||
|
||||
it("should use embedded item data for deleted items", async function () {
|
||||
var deletedItem = createUnsavedDataObject('item', {
|
||||
itemType: 'book',
|
||||
title: 'Deleted Item',
|
||||
creators: [
|
||||
{ firstName: 'firstDeleted', lastName: 'lastDeleted', creatorType: 'author' }
|
||||
]
|
||||
});
|
||||
await deletedItem.saveTx();
|
||||
|
||||
var uriOne = Zotero.URI.getItemURI(itemOne);
|
||||
var uriDeleted = Zotero.URI.getItemURI(deletedItem);
|
||||
var itemDataOne = Zotero.Utilities.Item.itemToCSLJSON(itemOne);
|
||||
var itemDataDeleted = Zotero.Utilities.Item.itemToCSLJSON(deletedItem);
|
||||
|
||||
var citationOne = { citationItems: [{ uris: [uriOne] }], properties: {} };
|
||||
var citationDeleted = { citationItems: [{ uris: [uriDeleted] }], properties: {} };
|
||||
|
||||
var storedCitationItems = [
|
||||
{ uris: [uriOne], itemData: itemDataOne },
|
||||
{ uris: [uriDeleted], itemData: itemDataDeleted }
|
||||
];
|
||||
var deletedNoteHTML = '<div data-citation-items="'
|
||||
+ encodeURIComponent(JSON.stringify(storedCitationItems))
|
||||
+ '" data-schema-version="9">'
|
||||
+ '<p>Before</p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationOne))
|
||||
+ '">(<span class="citation-item">lastOne and lastTwo</span>)</span></p>'
|
||||
+ '<p><span class="citation" data-citation="'
|
||||
+ encodeURIComponent(JSON.stringify(citationDeleted))
|
||||
+ '">(<span class="citation-item">lastDeleted</span>)</span></p>'
|
||||
+ '<p>After</p>'
|
||||
+ '</div>';
|
||||
|
||||
var deletedNoteItem = createUnsavedDataObject('item', {
|
||||
itemType: 'note',
|
||||
note: deletedNoteHTML
|
||||
});
|
||||
await deletedNoteItem.saveTx();
|
||||
// Delete the item so its URI no longer resolves -- forces the
|
||||
// fallback path through embedded data-citation-items JSON.
|
||||
await deletedItem.eraseTx();
|
||||
|
||||
Zotero.Prefs.set('export.quickCopy.bibliographySetting', JSON.stringify({
|
||||
mode: 'bibliography', id: styleID, contentType: '', locale: ''
|
||||
}));
|
||||
|
||||
let content = Zotero.QuickCopy.getContentFromItems([deletedNoteItem], getNoteFormat());
|
||||
var expected = 'Before\n\n'
|
||||
+ '(firstOne lastOne and firstTwo lastTwo, Item One (n.d.).)\n\n'
|
||||
+ '(firstDeleted lastDeleted, Deleted Item (n.d.).)\n\n'
|
||||
+ 'After';
|
||||
assert.equal(content.text, expected);
|
||||
|
||||
await deletedNoteItem.eraseTx();
|
||||
});
|
||||
});
|
||||
|
||||
it("should generate bibliography in default locale if Quick Copy locale not set", async function () {
|
||||
var item = createUnsavedDataObject('item', { itemType: 'webpage', title: 'Foo' });
|
||||
item.setField('date', '2020-03-11');
|
||||
|
|
@ -313,7 +461,6 @@ describe("Zotero.QuickCopy", function () {
|
|||
|
||||
// This shouldn't be used
|
||||
Zotero.Prefs.set('export.lastLocale', 'fr-FR');
|
||||
await Zotero.Styles.init();
|
||||
|
||||
var format = 'bibliography=http://www.zotero.org/styles/apa';
|
||||
Zotero.Prefs.set("export.quickCopy.bibliographySetting", format);
|
||||
|
|
@ -349,152 +496,128 @@ describe("Zotero.QuickCopy", function () {
|
|||
let content = Zotero.QuickCopy.getContentFromItems([item], format, { asCitations: true });
|
||||
assert.equal(content.text, '《新型数据财产的行为主义保护:基于财产权理论的分析》。');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("Smart copy", function () {
|
||||
var win, zp, doc;
|
||||
var regularItem, attachment, annotation, note;
|
||||
var clipboardService;
|
||||
const SMART_COPY_BIB = {
|
||||
mode: 'bibliography',
|
||||
id: 'http://www.zotero.org/styles/apa',
|
||||
contentType: '',
|
||||
locale: ''
|
||||
};
|
||||
|
||||
before(async function () {
|
||||
win = await loadZoteroPane();
|
||||
zp = win.ZoteroPane;
|
||||
doc = win.document;
|
||||
clipboardService = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
|
||||
await Zotero.Styles.init();
|
||||
await Zotero.Translators.init();
|
||||
|
||||
// Preload Note Markdown / Note HTML translators
|
||||
for (let id of [
|
||||
Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN,
|
||||
Zotero.Translators.TRANSLATOR_ID_NOTE_HTML,
|
||||
]) {
|
||||
let translator = Zotero.Translators.get(id);
|
||||
translator.cacheCode = true;
|
||||
await Zotero.Translators.getCodeForTranslator(translator);
|
||||
}
|
||||
|
||||
regularItem = createUnsavedDataObject('item', {
|
||||
itemType: 'journalArticle',
|
||||
title: 'My Smart Copy Paper'
|
||||
});
|
||||
regularItem.setField('date', '2020');
|
||||
regularItem.setCreators([
|
||||
{ firstName: 'Jane', lastName: 'Smartcopy', creatorType: 'author' }
|
||||
]);
|
||||
await regularItem.saveTx();
|
||||
|
||||
attachment = await importFileAttachment('test.pdf', { parentItemID: regularItem.id });
|
||||
annotation = await createAnnotation('highlight', attachment);
|
||||
|
||||
note = createUnsavedDataObject('item', { itemType: 'note' });
|
||||
note.setNote('<p>Test note content</p>');
|
||||
await note.saveTx();
|
||||
});
|
||||
|
||||
// The test runner has a root-level afterEach (test/content/runtests.js)
|
||||
// that clears any user-set pref after every test. Re-pin the bibliography
|
||||
// style here before each test.
|
||||
beforeEach(function () {
|
||||
Zotero.Prefs.set('export.quickCopy.bibliographySetting', JSON.stringify(SMART_COPY_BIB));
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
win.Zotero_Tabs.closeAll();
|
||||
win.close();
|
||||
});
|
||||
|
||||
function getClipboardText() {
|
||||
let transferable = Components.classes["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
transferable.init(null);
|
||||
transferable.addDataFlavor('text/plain');
|
||||
|
||||
clipboardService.getData(transferable, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
let str = {};
|
||||
transferable.getTransferData('text/plain', str, {});
|
||||
return str.value.QueryInterface(Components.interfaces.nsISupportsString).data;
|
||||
}
|
||||
|
||||
function clearClipboard() {
|
||||
clipboardService.emptyClipboard(Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
}
|
||||
|
||||
describe("Library tab", function () {
|
||||
beforeEach(async function () {
|
||||
await selectLibrary(win);
|
||||
doc.getElementById('item-tree-main').focus();
|
||||
});
|
||||
|
||||
it("should copy citation for a regular item", async function () {
|
||||
await zp.itemsView.selectItem(regularItem.id);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.equal(getClipboardText(), '(Smartcopy, 2020)');
|
||||
});
|
||||
|
||||
it("should copy annotation content when an annotation is selected", async function () {
|
||||
await zp.itemsView.selectItem(annotation.id);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.include(getClipboardText(), annotation.annotationText);
|
||||
});
|
||||
|
||||
it("should copy note content when a note is selected", async function () {
|
||||
await zp.itemsView.selectItem(note.id);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.include(getClipboardText(), 'Test note content');
|
||||
});
|
||||
});
|
||||
|
||||
describe("Reader tab", function () {
|
||||
var reader;
|
||||
// Use a local sandbox: sinon's default sandbox tracks every stub
|
||||
// forever, so a later `sinon.restore()` elsewhere would
|
||||
// re-invoke our stub's restore against the already dead reader.
|
||||
var sandbox;
|
||||
describe("Smart copy", function () {
|
||||
var regularItem, attachment, annotation, note;
|
||||
var clipboardService;
|
||||
const SMART_COPY_BIB = {
|
||||
mode: 'bibliography',
|
||||
id: 'http://www.zotero.org/styles/apa',
|
||||
contentType: '',
|
||||
locale: ''
|
||||
};
|
||||
|
||||
before(async function () {
|
||||
sandbox = sinon.createSandbox();
|
||||
reader = await Zotero.Reader.open(attachment.id);
|
||||
await reader._initPromise;
|
||||
await reader._internalReader._primaryView.initializedPromise;
|
||||
while (!reader._iframeWindow) {
|
||||
await Zotero.Promise.delay(50);
|
||||
}
|
||||
// Pretend that the reader is focused
|
||||
sandbox.stub(reader._iframeWindow.document, 'hasFocus').returns(true);
|
||||
clipboardService = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
|
||||
regularItem = createUnsavedDataObject('item', {
|
||||
itemType: 'journalArticle',
|
||||
title: 'My Smart Copy Paper'
|
||||
});
|
||||
regularItem.setField('date', '2020');
|
||||
regularItem.setCreators([
|
||||
{ firstName: 'Jane', lastName: 'Smartcopy', creatorType: 'author' }
|
||||
]);
|
||||
await regularItem.saveTx();
|
||||
|
||||
attachment = await importFileAttachment('test.pdf', { parentItemID: regularItem.id });
|
||||
annotation = await createAnnotation('highlight', attachment);
|
||||
|
||||
note = createUnsavedDataObject('item', { itemType: 'note' });
|
||||
note.setNote('<p>Test note content</p>');
|
||||
await note.saveTx();
|
||||
});
|
||||
|
||||
beforeEach(async function () {
|
||||
await win.Zotero_Tabs.select(reader.tabID);
|
||||
// The parent `beforeEach` re-pins prefs to the file's defaults, so
|
||||
// override the bibliography setting here for Smart copy assertions.
|
||||
beforeEach(function () {
|
||||
Zotero.Prefs.set('export.quickCopy.bibliographySetting', JSON.stringify(SMART_COPY_BIB));
|
||||
});
|
||||
|
||||
after(function () {
|
||||
sandbox.restore();
|
||||
function getClipboardText() {
|
||||
let transferable = Components.classes["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
transferable.init(null);
|
||||
transferable.addDataFlavor('text/plain');
|
||||
|
||||
clipboardService.getData(transferable, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
let str = {};
|
||||
transferable.getTransferData('text/plain', str, {});
|
||||
return str.value.QueryInterface(Components.interfaces.nsISupportsString).data;
|
||||
}
|
||||
|
||||
function clearClipboard() {
|
||||
clipboardService.emptyClipboard(Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
}
|
||||
|
||||
describe("Library tab", function () {
|
||||
beforeEach(async function () {
|
||||
await selectLibrary(win);
|
||||
doc.getElementById('item-tree-main').focus();
|
||||
});
|
||||
|
||||
it("should copy citation for a regular item", async function () {
|
||||
await zp.itemsView.selectItem(regularItem.id);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.equal(getClipboardText(), '(Smartcopy, 2020)');
|
||||
});
|
||||
|
||||
it("should copy annotation content when an annotation is selected", async function () {
|
||||
await zp.itemsView.selectItem(annotation.id);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.include(getClipboardText(), annotation.annotationText);
|
||||
});
|
||||
|
||||
it("should copy note content when a note is selected", async function () {
|
||||
await zp.itemsView.selectItem(note.id);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.include(getClipboardText(), 'Test note content');
|
||||
});
|
||||
});
|
||||
|
||||
it("should copy parent citation when nothing is selected in the reader", function () {
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.equal(getClipboardText(), '(Smartcopy, 2020)');
|
||||
});
|
||||
describe("Reader tab", function () {
|
||||
var reader;
|
||||
// Use a local sandbox: sinon's default sandbox tracks every stub
|
||||
// forever, so a later `sinon.restore()` elsewhere would
|
||||
// re-invoke our stub's restore against the already dead reader.
|
||||
var sandbox;
|
||||
|
||||
it("should copy selected annotation", function () {
|
||||
sandbox.stub(reader, 'getSelectedAnnotationIDs').returns([annotation.key]);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.include(getClipboardText(), annotation.annotationText);
|
||||
before(async function () {
|
||||
sandbox = sinon.createSandbox();
|
||||
reader = await Zotero.Reader.open(attachment.id);
|
||||
await reader._initPromise;
|
||||
await reader._internalReader._primaryView.initializedPromise;
|
||||
while (!reader._iframeWindow) {
|
||||
await Zotero.Promise.delay(50);
|
||||
}
|
||||
// Pretend that the reader is focused
|
||||
sandbox.stub(reader._iframeWindow.document, 'hasFocus').returns(true);
|
||||
});
|
||||
|
||||
beforeEach(async function () {
|
||||
await win.Zotero_Tabs.select(reader.tabID);
|
||||
});
|
||||
|
||||
after(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it("should copy parent citation when nothing is selected in the reader", function () {
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.equal(getClipboardText(), '(Smartcopy, 2020)');
|
||||
});
|
||||
|
||||
it("should copy selected annotation", function () {
|
||||
sandbox.stub(reader, 'getSelectedAnnotationIDs').returns([annotation.key]);
|
||||
clearClipboard();
|
||||
doc.getElementById('key_smartCopy').doCommand();
|
||||
assert.include(getClipboardText(), annotation.annotationText);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue