From 7608e127f1d3569accbc450e9af4d0bd3ca68246 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adomas=20Ven=C4=8Dkauskas?= <adomas.ven@gmail.com>
Date: Tue, 20 Sep 2016 16:10:26 +0300
Subject: [PATCH] Fix nested translators that rely on child translator tags

---
 .../zotero/xpcom/translation/translate.js     | 21 +++++----
 test/content/support.js                       |  7 +--
 test/tests/translateTest.js                   | 43 +++++++++++++++++++
 3 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
index 4b8e11fbe..eb1be0c14 100644
--- a/chrome/content/zotero/xpcom/translation/translate.js
+++ b/chrome/content/zotero/xpcom/translation/translate.js
@@ -127,8 +127,10 @@ Zotero.Translate.Sandbox = {
 				}
 			}
 
-			// Canonicalize tags
-			if(item.tags) item.tags = translate._cleanTags(item.tags);
+			// If we're not in a child translator, canonicalize tags
+			if (!translate._parentTranslator) {
+				if(item.tags) item.tags = translate._cleanTags(item.tags);
+			}
 			
 			// if we're not supposed to save the item or we're in a child translator,
 			// just return the item array
@@ -158,8 +160,10 @@ Zotero.Translate.Sandbox = {
 						delete attachment.document;
 					}
 
-					// Canonicalize tags
-					if(attachment.tags !== undefined) attachment.tags = translate._cleanTags(attachment.tags);
+					// If we're not in a child translator, canonicalize tags
+					if (!translate._parentTranslator) {
+						if(attachment.tags !== undefined) attachment.tags = translate._cleanTags(attachment.tags);
+					}
 				}
 			}
 
@@ -169,13 +173,14 @@ Zotero.Translate.Sandbox = {
 					var note = notes[j];
 					if(!note) {
 						notes.splice(j--, 1);
-					} else if(typeof(note) == "object") {
-						// Canonicalize tags
-						if(note.tags !== undefined) note.tags = translate._cleanTags(note.tags);
-					} else {
+					} else if(typeof(note) != "object") {
 						// Convert to object
 						notes[j] = {"note":note.toString()}
 					}
+					// If we're not in a child translator, canonicalize tags
+					if (!translate._parentTranslator) {
+						if(note.tags !== undefined) note.tags = translate._cleanTags(note.tags);
+					}
 				}
 			}
 
diff --git a/test/content/support.js b/test/content/support.js
index 5ecf1ff74..40c1f5ead 100644
--- a/test/content/support.js
+++ b/test/content/support.js
@@ -757,10 +757,10 @@ var generateTranslatorExportData = Zotero.Promise.coroutine(function* generateTr
 /**
  * Build a dummy translator that can be passed to Zotero.Translate
  */
-function buildDummyTranslator(translatorType, code) {
+function buildDummyTranslator(translatorType, code, translatorID="dummy-translator") {
 	let info = {
-		"translatorID":"dummy-translator",
-		"translatorType":1, // import
+		"translatorID":translatorID,
+		"translatorType":translatorType,
 		"label":"Dummy Translator",
 		"creator":"Simon Kornblith",
 		"target":"",
@@ -771,6 +771,7 @@ function buildDummyTranslator(translatorType, code) {
 	};
 	let translator = new Zotero.Translator(info);
 	translator.code = code;
+	translator.getCode = function() {return Promise.resolve(code)};
 	return translator;
 }
 
diff --git a/test/tests/translateTest.js b/test/tests/translateTest.js
index 74ac32433..c81cef081 100644
--- a/test/tests/translateTest.js
+++ b/test/tests/translateTest.js
@@ -551,6 +551,49 @@ describe("Zotero.Translate", function() {
 			assert.equal(pdf.attachmentLinkMode, Zotero.Attachments.LINK_MODE_IMPORTED_URL);
 			checkTestTags(pdf, true);
 		});
+		
+		it('should not convert tags to canonical form in child translators', function* () {
+			var childTranslator = buildDummyTranslator(1, 
+				`function detectWeb() {}
+				function doImport() {
+					var item = new Zotero.Item;
+					item.itemType = "book";
+					item.title = "The Definitive Guide of Owls";
+					item.tags = ['owl', 'tag'];
+					item.complete();
+				}`, 'child-dummy-translator'
+			);
+			sinon.stub(Zotero.Translators, 'get').withArgs('child-dummy-translator').returns(childTranslator);
+			
+			var parentTranslator = buildDummyTranslator(1,
+				`function detectWeb() {}
+				function doImport() {
+					var translator = Zotero.loadTranslator("import");
+					translator.setTranslator('child-dummy-translator');
+					translator.setHandler('itemDone', Zotero.childItemDone);
+					translator.translate();
+				}`
+			);
+			
+			function childItemDone(obj, item) {
+				// Non-canonical tags after child translator is done
+				assert.deepEqual(['owl', 'tag'], item.tags);
+				item.complete();
+			}
+			
+			var translate = new Zotero.Translate.Import();
+			translate.setTranslator(parentTranslator);
+			translate.setString("");
+			yield translate._loadTranslator(parentTranslator);
+			translate._sandboxManager.importObject({childItemDone});
+			
+			var items = yield translate.translate();
+			
+			// Canonicalized tags after parent translator
+			assert.deepEqual([{tag: 'owl'}, {tag: 'tag'}], items[0].getTags());
+			
+			Zotero.Translators.get.restore();
+		});
 	});
 });