l10nSpec.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
  3. *
  4. * This file is licensed under the Affero General Public License version 3
  5. * or later.
  6. *
  7. * See the COPYING-README file.
  8. *
  9. */
  10. describe('OC.L10N tests', function() {
  11. var TEST_APP = 'jsunittestapp';
  12. beforeEach(function() {
  13. window._oc_appswebroots[TEST_APP] = OC.getRootPath() + '/apps3/jsunittestapp';
  14. window.OC = window.OC ?? {}
  15. window.OC.appswebroots = window.OC.appswebroots || {}
  16. window.OC.appswebroots[TEST_APP] = OC.getRootPath() + '/apps3/jsunittestapp'
  17. });
  18. afterEach(function() {
  19. OC.L10N._unregister(TEST_APP);
  20. delete window._oc_appswebroots[TEST_APP];
  21. delete window.OC.appswebroots[TEST_APP];
  22. });
  23. describe('text translation', function() {
  24. beforeEach(function() {
  25. spyOn(console, 'warn');
  26. OC.L10N.register(TEST_APP, {
  27. 'Hello world!': 'Hallo Welt!',
  28. 'Hello {name}, the weather is {weather}': 'Hallo {name}, das Wetter ist {weather}',
  29. 'sunny': 'sonnig'
  30. });
  31. });
  32. it('returns untranslated text when no bundle exists', function() {
  33. OC.L10N._unregister(TEST_APP);
  34. expect(t(TEST_APP, 'unknown text')).toEqual('unknown text');
  35. });
  36. it('returns untranslated text when no key exists', function() {
  37. expect(t(TEST_APP, 'unknown text')).toEqual('unknown text');
  38. });
  39. it('returns translated text when key exists', function() {
  40. expect(t(TEST_APP, 'Hello world!')).toEqual('Hallo Welt!');
  41. });
  42. it('returns translated text with placeholder', function() {
  43. expect(
  44. t(TEST_APP, 'Hello {name}, the weather is {weather}', {name: 'Steve', weather: t(TEST_APP, 'sunny')})
  45. ).toEqual('Hallo Steve, das Wetter ist sonnig');
  46. });
  47. it('returns text with escaped placeholder', function() {
  48. expect(
  49. t(TEST_APP, 'Hello {name}', {name: '<strong>Steve</strong>'})
  50. ).toEqual('Hello &lt;strong&gt;Steve&lt;/strong&gt;');
  51. });
  52. it('returns text with not escaped placeholder', function() {
  53. expect(
  54. t(TEST_APP, 'Hello {name}', {name: '<strong>Steve</strong>'}, null, {escape: false})
  55. ).toEqual('Hello <strong>Steve</strong>');
  56. });
  57. it('uses DOMPurify to escape the text', function() {
  58. expect(
  59. t(TEST_APP, '<strong>These are your search results<script>alert(1)</script></strong>', null, {escape: false})
  60. ).toEqual('<strong>These are your search results</strong>');
  61. });
  62. it('keeps old texts when registering existing bundle', function() {
  63. OC.L10N.register(TEST_APP, {
  64. 'sunny': 'sonnig',
  65. 'new': 'neu'
  66. });
  67. expect(t(TEST_APP, 'sunny')).toEqual('sonnig');
  68. expect(t(TEST_APP, 'new')).toEqual('neu');
  69. });
  70. });
  71. describe('plurals', function() {
  72. function checkPlurals() {
  73. expect(
  74. n(TEST_APP, 'download %n file', 'download %n files', 0)
  75. ).toEqual('0 Dateien herunterladen');
  76. expect(
  77. n(TEST_APP, 'download %n file', 'download %n files', 1)
  78. ).toEqual('1 Datei herunterladen');
  79. expect(
  80. n(TEST_APP, 'download %n file', 'download %n files', 2)
  81. ).toEqual('2 Dateien herunterladen');
  82. expect(
  83. n(TEST_APP, 'download %n file', 'download %n files', 1024)
  84. ).toEqual('1024 Dateien herunterladen');
  85. }
  86. it('generates plural for default text when translation does not exist', function() {
  87. spyOn(console, 'warn');
  88. OC.L10N.register(TEST_APP, {
  89. });
  90. expect(
  91. n(TEST_APP, 'download %n file', 'download %n files', 0)
  92. ).toEqual('download 0 files');
  93. expect(
  94. n(TEST_APP, 'download %n file', 'download %n files', 1)
  95. ).toEqual('download 1 file');
  96. expect(
  97. n(TEST_APP, 'download %n file', 'download %n files', 2)
  98. ).toEqual('download 2 files');
  99. expect(
  100. n(TEST_APP, 'download %n file', 'download %n files', 1024)
  101. ).toEqual('download 1024 files');
  102. });
  103. it('generates plural with default function when no forms specified', function() {
  104. spyOn(console, 'warn');
  105. OC.L10N.register(TEST_APP, {
  106. '_download %n file_::_download %n files_':
  107. ['%n Datei herunterladen', '%n Dateien herunterladen']
  108. });
  109. checkPlurals();
  110. });
  111. });
  112. describe('async loading of translations', function() {
  113. afterEach(() => {
  114. document.documentElement.removeAttribute('data-locale')
  115. })
  116. it('loads bundle for given app and calls callback', function(done) {
  117. document.documentElement.setAttribute('data-locale', 'zh_CN')
  118. var callbackStub = sinon.stub();
  119. var promiseStub = sinon.stub();
  120. var loading = OC.L10N.load(TEST_APP, callbackStub);
  121. expect(callbackStub.notCalled).toEqual(true);
  122. var req = fakeServer.requests[0];
  123. console.warn('fff-', window.OC.appswebroots)
  124. loading
  125. .then(promiseStub)
  126. .then(function() {
  127. expect(fakeServer.requests.length).toEqual(1);
  128. expect(req.url).toEqual(
  129. OC.getRootPath() + '/apps3/' + TEST_APP + '/l10n/zh_CN.json'
  130. );
  131. expect(callbackStub.calledOnce).toEqual(true);
  132. expect(promiseStub.calledOnce).toEqual(true);
  133. expect(t(TEST_APP, 'Hello world!')).toEqual('你好世界!');
  134. })
  135. .then(done)
  136. .catch(e => expect(e).toBe('No error expected!'));
  137. expect(promiseStub.notCalled).toEqual(true);
  138. req.respond(
  139. 200,
  140. { 'Content-Type': 'application/json' },
  141. JSON.stringify({
  142. translations: {'Hello world!': '你好世界!'},
  143. pluralForm: 'nplurals=2; plural=(n != 1);'
  144. })
  145. );
  146. });
  147. it('calls callback if translation already available', function(done) {
  148. var callbackStub = sinon.stub();
  149. spyOn(console, 'warn');
  150. OC.L10N.register(TEST_APP, {
  151. 'Hello world!': 'Hallo Welt!'
  152. });
  153. OC.L10N.load(TEST_APP, callbackStub)
  154. .then(function() {
  155. expect(callbackStub.calledOnce).toEqual(true);
  156. expect(fakeServer.requests.length).toEqual(0);
  157. })
  158. .then(done);
  159. });
  160. it('calls callback if locale is en', function(done) {
  161. var callbackStub = sinon.stub();
  162. OC.L10N.load(TEST_APP, callbackStub)
  163. .then(function() {
  164. expect(callbackStub.calledOnce).toEqual(true);
  165. expect(fakeServer.requests.length).toEqual(0);
  166. })
  167. .then(done)
  168. .catch(done);
  169. });
  170. });
  171. });