TranslateBehaviorTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since CakePHP(tm) v 3.0.0
  13. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  14. */
  15. namespace Cake\Test\TestCase\Model\Behavior;
  16. use Cake\Collection\Collection;
  17. use Cake\Event\Event;
  18. use Cake\Model\Behavior\TranslateBehavior;
  19. use Cake\ORM\Entity;
  20. use Cake\ORM\TableRegistry;
  21. use Cake\TestSuite\TestCase;
  22. /**
  23. * Translate behavior test case
  24. */
  25. class TranslateBehaviorTest extends TestCase {
  26. /**
  27. * fixtures
  28. *
  29. * @var array
  30. */
  31. public $fixtures = [
  32. 'core.translate',
  33. 'core.article',
  34. 'core.comment',
  35. 'core.author'
  36. ];
  37. public function tearDown() {
  38. parent::tearDown();
  39. TableRegistry::clear();
  40. }
  41. /**
  42. * Returns an array with all the translations found for a set of records
  43. *
  44. * @return Collection
  45. */
  46. protected function _extractTranslations($data) {
  47. return (new Collection($data))->map(function($row) {
  48. $translations = $row->get('_translations');
  49. if (!$translations) {
  50. return [];
  51. }
  52. return array_map(function($t) {
  53. return $t->toArray();
  54. }, $translations);
  55. });
  56. }
  57. /**
  58. * Tests that fields from a translated model are overriden
  59. *
  60. * @return void
  61. */
  62. public function testFindSingleLocale() {
  63. $table = TableRegistry::get('Articles');
  64. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  65. $table->locale('eng');
  66. $results = $table->find()->combine('title', 'body', 'id')->toArray();
  67. $expected = [
  68. 1 => ['Title #1' => 'Content #1'],
  69. 2 => ['Title #2' => 'Content #2'],
  70. 3 => ['Title #3' => 'Content #3'],
  71. ];
  72. $this->assertSame($expected, $results);
  73. }
  74. /**
  75. * Tests that fields from a translated model are not overriden if translation
  76. * is null
  77. *
  78. * @return void
  79. */
  80. public function testFindSingleLocaleWithNullTranslation() {
  81. $table = TableRegistry::get('Comments');
  82. $table->addBehavior('Translate', ['fields' => ['comment']]);
  83. $table->locale('spa');
  84. $results = $table->find()
  85. ->where(['Comments.id' => 6])
  86. ->combine('id', 'comment')->toArray();
  87. $expected = [6 => 'Second Comment for Second Article'];
  88. $this->assertSame($expected, $results);
  89. }
  90. /**
  91. * Tests that overriding fields with the translate behavior works when
  92. * using conditions and that all other columns are preserved
  93. *
  94. * @return void
  95. */
  96. public function testFindSingleLocaleWithConditions() {
  97. $table = TableRegistry::get('Articles');
  98. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  99. $table->locale('eng');
  100. $results = $table->find()
  101. ->where(['Articles.id' => 2])
  102. ->all();
  103. $this->assertCount(1, $results);
  104. $row = $results->first();
  105. $expected = [
  106. 'id' => 2,
  107. 'title' => 'Title #2',
  108. 'body' => 'Content #2',
  109. 'author_id' => 3,
  110. 'published' => 'Y',
  111. '_locale' => 'eng'
  112. ];
  113. $this->assertEquals($expected, $row->toArray());
  114. }
  115. /**
  116. * Tests that translating fields work when other formatters are used
  117. *
  118. * @return void
  119. */
  120. public function testFindList() {
  121. $table = TableRegistry::get('Articles');
  122. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  123. $table->locale('eng');
  124. $results = $table->find('list')->toArray();
  125. $expected = [1 => 'Title #1', 2 => 'Title #2', 3 => 'Title #3'];
  126. $this->assertSame($expected, $results);
  127. }
  128. /**
  129. * Tests that the query count return the correct results
  130. *
  131. * @return void
  132. */
  133. public function testFindCount() {
  134. $table = TableRegistry::get('Articles');
  135. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  136. $table->locale('eng');
  137. $this->assertEquals(3, $table->find()->count());
  138. }
  139. /**
  140. * Tests that it is possible to get all translated fields at once
  141. *
  142. * @return void
  143. */
  144. public function testFindTranslations() {
  145. $table = TableRegistry::get('Articles');
  146. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  147. $results = $table->find('translations');
  148. $expected = [
  149. [
  150. 'eng' => ['title' => 'Title #1', 'body' => 'Content #1', 'locale' => 'eng'],
  151. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  152. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  153. ],
  154. [
  155. 'eng' => ['title' => 'Title #2', 'body' => 'Content #2', 'locale' => 'eng'],
  156. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  157. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  158. ],
  159. [
  160. 'eng' => ['title' => 'Title #3', 'body' => 'Content #3', 'locale' => 'eng'],
  161. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  162. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  163. ]
  164. ];
  165. $translations = $this->_extractTranslations($results);
  166. $this->assertEquals($expected, $translations->toArray());
  167. $expected = [
  168. 1 => ['First Article' => 'First Article Body'],
  169. 2 => ['Second Article' => 'Second Article Body'],
  170. 3 => ['Third Article' => 'Third Article Body']
  171. ];
  172. $grouped = $results->combine('title', 'body', 'id');
  173. $this->assertEquals($expected, $grouped->toArray());
  174. }
  175. /**
  176. * Tests that it is possible to request just a few translations
  177. *
  178. * @return void
  179. */
  180. public function testFindFilteredTranslations() {
  181. $table = TableRegistry::get('Articles');
  182. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  183. $results = $table->find('translations', ['locales' => ['deu', 'cze']]);
  184. $expected = [
  185. [
  186. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  187. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  188. ],
  189. [
  190. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  191. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  192. ],
  193. [
  194. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  195. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  196. ]
  197. ];
  198. $translations = $this->_extractTranslations($results);
  199. $this->assertEquals($expected, $translations->toArray());
  200. $expected = [
  201. 1 => ['First Article' => 'First Article Body'],
  202. 2 => ['Second Article' => 'Second Article Body'],
  203. 3 => ['Third Article' => 'Third Article Body']
  204. ];
  205. $grouped = $results->combine('title', 'body', 'id');
  206. $this->assertEquals($expected, $grouped->toArray());
  207. }
  208. /**
  209. * Tests that it is possible to combine find('list') and find('translations')
  210. *
  211. * @return void
  212. */
  213. public function testFindTranslationsList() {
  214. $table = TableRegistry::get('Articles');
  215. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  216. $results = $table
  217. ->find('list', [
  218. 'idField' => 'title',
  219. 'valueField' => '_translations.deu.title',
  220. 'groupField' => 'id'
  221. ])
  222. ->find('translations', ['locales' => ['deu']]);
  223. $expected = [
  224. 1 => ['First Article' => 'Titel #1'],
  225. 2 => ['Second Article' => 'Titel #2'],
  226. 3 => ['Third Article' => 'Titel #3']
  227. ];
  228. $this->assertEquals($expected, $results->toArray());
  229. }
  230. /**
  231. * Tests that you can both override fields and find all translations
  232. *
  233. * @return void
  234. */
  235. public function testFindTranslationsWithFieldOverriding() {
  236. $table = TableRegistry::get('Articles');
  237. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  238. $table->locale('cze');
  239. $results = $table->find('translations', ['locales' => ['deu', 'cze']]);
  240. $expected = [
  241. [
  242. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  243. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  244. ],
  245. [
  246. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  247. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  248. ],
  249. [
  250. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  251. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  252. ]
  253. ];
  254. $translations = $this->_extractTranslations($results);
  255. $this->assertEquals($expected, $translations->toArray());
  256. $expected = [
  257. 1 => ['Titulek #1' => 'Obsah #1'],
  258. 2 => ['Titulek #2' => 'Obsah #2'],
  259. 3 => ['Titulek #3' => 'Obsah #3']
  260. ];
  261. $grouped = $results->combine('title', 'body', 'id');
  262. $this->assertEquals($expected, $grouped->toArray());
  263. }
  264. /**
  265. * Tests that fields can be overriden in a hasMany association
  266. *
  267. * @return void
  268. */
  269. public function testFindSingleLocaleHasMany() {
  270. $table = TableRegistry::get('Articles');
  271. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  272. $table->hasMany('Comments');
  273. $comments = $table->hasMany('Comments')->target();
  274. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  275. $table->locale('eng');
  276. $comments->locale('eng');
  277. $results = $table->find()->contain(['Comments' => function($q) {
  278. return $q->select(['id', 'comment', 'article_id']);
  279. }]);
  280. $list = new Collection($results->first()->comments);
  281. $expected = [
  282. 1 => 'Comment #1',
  283. 2 => 'Comment #2',
  284. 3 => 'Comment #3',
  285. 4 => 'Comment #4'
  286. ];
  287. $this->assertEquals($expected, $list->combine('id', 'comment')->toArray());
  288. }
  289. /**
  290. * Test that it is possible to bring translations from hasMany relations
  291. *
  292. * @return void
  293. */
  294. public function testTranslationsHasMany() {
  295. $table = TableRegistry::get('Articles');
  296. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  297. $table->hasMany('Comments');
  298. $comments = $table->hasMany('Comments')->target();
  299. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  300. $results = $table->find('translations')->contain([
  301. 'Comments' => function($q) {
  302. return $q->find('translations')->select(['id', 'comment', 'article_id']);
  303. }
  304. ]);
  305. $comments = $results->first()->comments;
  306. $expected = [
  307. [
  308. 'eng' => ['comment' => 'Comment #1', 'locale' => 'eng']
  309. ],
  310. [
  311. 'eng' => ['comment' => 'Comment #2', 'locale' => 'eng']
  312. ],
  313. [
  314. 'eng' => ['comment' => 'Comment #3', 'locale' => 'eng']
  315. ],
  316. [
  317. 'eng' => ['comment' => 'Comment #4', 'locale' => 'eng'],
  318. 'spa' => ['comment' => 'Comentario #4', 'locale' => 'spa']
  319. ]
  320. ];
  321. $translations = $this->_extractTranslations($comments);
  322. $this->assertEquals($expected, $translations->toArray());
  323. }
  324. /**
  325. * Tests that it is possible to both override fields with a translation and
  326. * also find separately other translations
  327. *
  328. * @return void
  329. */
  330. public function testTranslationsHasManyWithOverride() {
  331. $table = TableRegistry::get('Articles');
  332. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  333. $table->hasMany('Comments');
  334. $comments = $table->hasMany('Comments')->target();
  335. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  336. $table->locale('cze');
  337. $comments->locale('eng');
  338. $results = $table->find('translations')->contain([
  339. 'Comments' => function($q) {
  340. return $q->find('translations')->select(['id', 'comment', 'article_id']);
  341. }
  342. ]);
  343. $comments = $results->first()->comments;
  344. $expected = [
  345. 1 => 'Comment #1',
  346. 2 => 'Comment #2',
  347. 3 => 'Comment #3',
  348. 4 => 'Comment #4'
  349. ];
  350. $list = new Collection($comments);
  351. $this->assertEquals($expected, $list->combine('id', 'comment')->toArray());
  352. $expected = [
  353. [
  354. 'eng' => ['comment' => 'Comment #1', 'locale' => 'eng']
  355. ],
  356. [
  357. 'eng' => ['comment' => 'Comment #2', 'locale' => 'eng']
  358. ],
  359. [
  360. 'eng' => ['comment' => 'Comment #3', 'locale' => 'eng']
  361. ],
  362. [
  363. 'eng' => ['comment' => 'Comment #4', 'locale' => 'eng'],
  364. 'spa' => ['comment' => 'Comentario #4', 'locale' => 'spa']
  365. ]
  366. ];
  367. $translations = $this->_extractTranslations($comments);
  368. $this->assertEquals($expected, $translations->toArray());
  369. $this->assertEquals('Titulek #1', $results->first()->title);
  370. $this->assertEquals('Obsah #1', $results->first()->body);
  371. }
  372. /**
  373. * Tests that it is possible to translate belongsTo associations
  374. *
  375. * @return void
  376. */
  377. public function testFindSingleLocaleBelongsto() {
  378. $table = TableRegistry::get('Articles');
  379. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  380. $authors = $table->belongsTo('Authors')->target();
  381. $authors->addBehavior('Translate', ['fields' => ['name']]);
  382. $table->locale('eng');
  383. $authors->locale('eng');
  384. $results = $table->find()
  385. ->select(['title', 'body'])
  386. ->order(['title' => 'asc'])
  387. ->contain(['Authors' => function($q) {
  388. return $q->select(['id', 'name']);
  389. }]);
  390. $expected = [
  391. [
  392. 'title' => 'Title #1',
  393. 'body' => 'Content #1',
  394. 'author' => ['id' => 1, 'name' => 'May-rianoh', '_locale' => 'eng'],
  395. '_locale' => 'eng'
  396. ],
  397. [
  398. 'title' => 'Title #2',
  399. 'body' => 'Content #2',
  400. 'author' => ['id' => 3, 'name' => 'larry', '_locale' => 'eng'],
  401. '_locale' => 'eng'
  402. ],
  403. [
  404. 'title' => 'Title #3',
  405. 'body' => 'Content #3',
  406. 'author' => ['id' => 1, 'name' => 'May-rianoh', '_locale' => 'eng'],
  407. '_locale' => 'eng'
  408. ]
  409. ];
  410. $results = array_map(function($r) {
  411. return $r->toArray();
  412. }, $results->toArray());
  413. $this->assertEquals($expected, $results);
  414. }
  415. /**
  416. * Tests that updating an existing record translations work
  417. *
  418. * @return void
  419. */
  420. public function testUpdateSingleLocale() {
  421. $table = TableRegistry::get('Articles');
  422. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  423. $table->locale('eng');
  424. $article = $table->find()->first();
  425. $this->assertEquals(1, $article->get('id'));
  426. $article->set('title', 'New translated article');
  427. $table->save($article);
  428. $article = $table->find()->first();
  429. $this->assertEquals(1, $article->get('id'));
  430. $this->assertEquals('New translated article', $article->get('title'));
  431. $this->assertEquals('Content #1', $article->get('body'));
  432. $table->locale(false);
  433. $article = $table->find()->first();
  434. $this->assertEquals(1, $article->get('id'));
  435. $this->assertEquals('First Article', $article->get('title'));
  436. $table->locale('eng');
  437. $article->set('title', 'Wow, such translated article');
  438. $article->set('body', 'A translated body');
  439. $table->save($article);
  440. $article = $table->find()->first();
  441. $this->assertEquals(1, $article->get('id'));
  442. $this->assertEquals('Wow, such translated article', $article->get('title'));
  443. $this->assertEquals('A translated body', $article->get('body'));
  444. }
  445. /**
  446. * Tests adding new translation to a record
  447. *
  448. * @return void
  449. */
  450. public function testInsertNewTranslations() {
  451. $table = TableRegistry::get('Articles');
  452. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  453. $table->locale('fra');
  454. $article = $table->find()->first();
  455. $this->assertEquals(1, $article->get('id'));
  456. $article->set('title', 'Le titre');
  457. $table->save($article);
  458. $this->assertEquals('fra', $article->get('_locale'));
  459. $article = $table->find()->first();
  460. $this->assertEquals(1, $article->get('id'));
  461. $this->assertEquals('Le titre', $article->get('title'));
  462. $this->assertEquals('First Article Body', $article->get('body'));
  463. $article->set('title', 'Un autre titre');
  464. $article->set('body', 'Le contenu');
  465. $table->save($article);
  466. $article = $table->find()->first();
  467. $this->assertEquals('Un autre titre', $article->get('title'));
  468. $this->assertEquals('Le contenu', $article->get('body'));
  469. }
  470. /**
  471. * Tests that it is possible to use the _locale property to specify the language
  472. * to use for saving an entity
  473. *
  474. * @return void
  475. */
  476. public function testUpdateTranslationWithLocaleInEntity() {
  477. $table = TableRegistry::get('Articles');
  478. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  479. $article = $table->find()->first();
  480. $this->assertEquals(1, $article->get('id'));
  481. $article->set('_locale', 'fra');
  482. $article->set('title', 'Le titre');
  483. $table->save($article);
  484. $article = $table->find()->first();
  485. $this->assertEquals(1, $article->get('id'));
  486. $this->assertEquals('First Article', $article->get('title'));
  487. $this->assertEquals('First Article Body', $article->get('body'));
  488. $table->locale('fra');
  489. $article = $table->find()->first();
  490. $this->assertEquals(1, $article->get('id'));
  491. $this->assertEquals('Le titre', $article->get('title'));
  492. $this->assertEquals('First Article Body', $article->get('body'));
  493. }
  494. /**
  495. * Tests that translations are added to the whitelist of associations to be
  496. * saved
  497. *
  498. * @return void
  499. */
  500. public function testSaveTranslationWithAssociationWhitelist() {
  501. $table = TableRegistry::get('Articles');
  502. $table->hasMany('Comments');
  503. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  504. $table->locale('fra');
  505. $article = $table->find()->first();
  506. $this->assertEquals(1, $article->get('id'));
  507. $article->set('title', 'Le titre');
  508. $table->save($article, ['associated' => ['Comments']]);
  509. $article = $table->find()->first();
  510. $this->assertEquals('Le titre', $article->get('title'));
  511. }
  512. /**
  513. * Tests that after deleting a translated entity, all translations are also removed
  514. *
  515. * @return void
  516. */
  517. public function testDelete() {
  518. $table = TableRegistry::get('Articles');
  519. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  520. $article = $table->find()->first();
  521. $this->assertTrue($table->delete($article));
  522. $translations = TableRegistry::get('I18n')->find()
  523. ->where(['model' => 'Articles', 'foreign_key' => $article->id])
  524. ->count();
  525. $this->assertEquals(0, $translations);
  526. }
  527. /**
  528. * Tests saving multiple translations at once when the translations already
  529. * exist in the database
  530. *
  531. * @return void
  532. */
  533. public function testSaveMultipleTranslations() {
  534. $table = TableRegistry::get('Articles');
  535. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  536. $article = $results = $table->find('translations')->first();
  537. $translations = $article->get('_translations');
  538. $translations['deu']->set('title', 'Another title');
  539. $translations['eng']->set('body', 'Another body');
  540. $article->set('_translations', $translations);
  541. $table->save($article);
  542. $article = $results = $table->find('translations')->first();
  543. $translations = $article->get('_translations');
  544. $this->assertEquals('Another title', $translations['deu']->get('title'));
  545. $this->assertEquals('Another body', $translations['eng']->get('body'));
  546. }
  547. /**
  548. * Tests saving multiple existing translations and adding new ones
  549. *
  550. * @return void
  551. */
  552. public function testSaveMultipleNewTranslations() {
  553. $table = TableRegistry::get('Articles');
  554. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  555. $article = $results = $table->find('translations')->first();
  556. $translations = $article->get('_translations');
  557. $translations['deu']->set('title', 'Another title');
  558. $translations['eng']->set('body', 'Another body');
  559. $translations['spa'] = new Entity(['title' => 'Titulo']);
  560. $translations['fre'] = new Entity(['title' => 'Titre']);
  561. $article->set('_translations', $translations);
  562. $table->save($article);
  563. $article = $results = $table->find('translations')->first();
  564. $translations = $article->get('_translations');
  565. $this->assertEquals('Another title', $translations['deu']->get('title'));
  566. $this->assertEquals('Another body', $translations['eng']->get('body'));
  567. $this->assertEquals('Titulo', $translations['spa']->get('title'));
  568. $this->assertEquals('Titre', $translations['fre']->get('title'));
  569. }
  570. }