|
|
@@ -20,6 +20,7 @@ use Cake\ORM\Behavior\Translate\TranslateTrait;
|
|
|
use Cake\ORM\Entity;
|
|
|
use Cake\ORM\TableRegistry;
|
|
|
use Cake\TestSuite\TestCase;
|
|
|
+use Cake\Validation\Validator;
|
|
|
|
|
|
/**
|
|
|
* Stub entity class
|
|
|
@@ -1092,4 +1093,311 @@ class TranslateBehaviorTest extends TestCase
|
|
|
$this->assertEquals('New Body', $result->body);
|
|
|
$this->assertSame($article->title, $result->title);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test save new entity with _translations field
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testSaveNewRecordWithTranslatesField()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', [
|
|
|
+ 'fields' => ['title'],
|
|
|
+ 'validator' => (new \Cake\Validation\Validator)->add('title', 'notBlank', ['rule' => 'notBlank'])
|
|
|
+ ]);
|
|
|
+ $table->entityClass(__NAMESPACE__ . '\Article');
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'published' => 'N',
|
|
|
+ '_translations' => [
|
|
|
+ 'en' => [
|
|
|
+ 'title' => 'Title EN',
|
|
|
+ 'body' => 'Body EN'
|
|
|
+ ],
|
|
|
+ 'es' => [
|
|
|
+ 'title' => 'Title ES'
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ $article = $table->patchEntity($table->newEntity(), $data);
|
|
|
+ $result = $table->save($article);
|
|
|
+
|
|
|
+ $this->assertNotFalse($result);
|
|
|
+
|
|
|
+ $expected = [
|
|
|
+ [
|
|
|
+ 'en' => [
|
|
|
+ 'title' => 'Title EN',
|
|
|
+ 'locale' => 'en'
|
|
|
+ ],
|
|
|
+ 'es' => [
|
|
|
+ 'title' => 'Title ES',
|
|
|
+ 'locale' => 'es'
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $result = $table->find('translations')->where(['id' => $result->id]);
|
|
|
+ $this->assertEquals($expected, $this->_extractTranslations($result)->toArray());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test update entity with _translations field.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testSaveExistingRecordWithTranslatesField()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
|
|
|
+ $table->entityClass(__NAMESPACE__ . '\Article');
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'published' => 'Y',
|
|
|
+ '_translations' => [
|
|
|
+ 'eng' => [
|
|
|
+ 'title' => 'First Article1',
|
|
|
+ 'body' => 'First Article content has been updated'
|
|
|
+ ],
|
|
|
+ 'spa' => [
|
|
|
+ 'title' => 'Mi nuevo titulo',
|
|
|
+ 'body' => 'Contenido Actualizado'
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ $article = $table->find()->first();
|
|
|
+ $article = $table->patchEntity($article, $data);
|
|
|
+
|
|
|
+ $this->assertNotFalse($table->save($article));
|
|
|
+
|
|
|
+ $results = $this->_extractTranslations(
|
|
|
+ $table->find('translations')->where(['id' => 1])
|
|
|
+ )->first();
|
|
|
+
|
|
|
+ $this->assertEquals('Mi nuevo titulo', $results['spa']['title']);
|
|
|
+ $this->assertEquals('Contenido Actualizado', $results['spa']['body']);
|
|
|
+
|
|
|
+ $this->assertEquals('First Article1', $results['eng']['title']);
|
|
|
+ $this->assertEquals('Description #1', $results['eng']['description']);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test that no properties are enabled when the translations
|
|
|
+ * option is off.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testBuildMarshalMapTranslationsOff()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
|
|
|
+
|
|
|
+ $marshaller = $table->marshaller();
|
|
|
+ $translate = $table->behaviors()->get('Translate');
|
|
|
+ $result = $translate->buildMarhshalMap($marshaller, [], ['translations' => false]);
|
|
|
+ $this->assertSame([], $result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test building a marshal map with translations on.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testBuildMarshalMapTranslationsOn()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
|
|
|
+ $marshaller = $table->marshaller();
|
|
|
+ $translate = $table->behaviors()->get('Translate');
|
|
|
+
|
|
|
+ $result = $translate->buildMarhshalMap($marshaller, [], ['translations' => true]);
|
|
|
+ $this->assertArrayHasKey('_translations', $result);
|
|
|
+ $this->assertInstanceOf('Closure', $result['_translations']);
|
|
|
+
|
|
|
+ $result = $translate->buildMarhshalMap($marshaller, [], []);
|
|
|
+ $this->assertArrayHasKey('_translations', $result);
|
|
|
+ $this->assertInstanceOf('Closure', $result['_translations']);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test marshalling non-array data
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testBuildMarshalMapNonArrayData()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
|
|
|
+ $translate = $table->behaviors()->get('Translate');
|
|
|
+
|
|
|
+ $map = $translate->buildMarhshalMap($table->marshaller(), [], []);
|
|
|
+ $entity = $table->newEntity();
|
|
|
+ $result = $map['_translations']('garbage', $entity);
|
|
|
+ $this->assertNull($result, 'Non-array should not error out.');
|
|
|
+ $this->assertEmpty($entity->errors());
|
|
|
+ $this->assertEmpty($entity->get('_translations'));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test buildMarshalMap() builds new entities.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testBuildMarshalMapBuildEntities()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
|
|
|
+ $translate = $table->behaviors()->get('Translate');
|
|
|
+
|
|
|
+ $map = $translate->buildMarhshalMap($table->marshaller(), [], []);
|
|
|
+ $entity = $table->newEntity();
|
|
|
+ $data = [
|
|
|
+ 'en' => [
|
|
|
+ 'title' => 'English Title',
|
|
|
+ 'body' => 'English Content'
|
|
|
+ ],
|
|
|
+ 'es' => [
|
|
|
+ 'title' => 'Titulo Español',
|
|
|
+ 'body' => 'Contenido Español'
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $result = $map['_translations']($data, $entity);
|
|
|
+ $this->assertEmpty($entity->errors(), 'No validation errors.');
|
|
|
+ $this->assertCount(2, $result);
|
|
|
+ $this->assertArrayHasKey('en', $result);
|
|
|
+ $this->assertArrayHasKey('es', $result);
|
|
|
+ $this->assertEquals('English Title', $result['en']->title);
|
|
|
+ $this->assertEquals('Titulo Español', $result['es']->title);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test that validation errors are added to the original entity.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testBuildMarshalMapBuildEntitiesValidationErrors()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', [
|
|
|
+ 'fields' => ['title', 'body'],
|
|
|
+ 'validator' => 'custom'
|
|
|
+ ]);
|
|
|
+ $validator = (new Validator)->add('title', 'notBlank', ['rule' => 'notBlank']);
|
|
|
+ $table->validator('custom', $validator);
|
|
|
+ $translate = $table->behaviors()->get('Translate');
|
|
|
+
|
|
|
+ $entity = $table->newEntity();
|
|
|
+ $map = $translate->buildMarhshalMap($table->marshaller(), [], []);
|
|
|
+ $data = [
|
|
|
+ 'en' => [
|
|
|
+ 'title' => 'English Title',
|
|
|
+ 'body' => 'English Content'
|
|
|
+ ],
|
|
|
+ 'es' => [
|
|
|
+ 'title' => '',
|
|
|
+ 'body' => 'Contenido Español'
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $result = $map['_translations']($data, $entity);
|
|
|
+ $this->assertNotEmpty($entity->errors(), 'Needs validation errors.');
|
|
|
+ $expected = [
|
|
|
+ 'title' => [
|
|
|
+ '_empty' => 'This field cannot be left empty'
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $this->assertEquals($expected, $entity->errors('es'));
|
|
|
+
|
|
|
+ $this->assertEquals('English Title', $result['en']->title);
|
|
|
+ $this->assertEquals('', $result['es']->title);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test that marshalling updates existing translation entities.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testBuildMarshalMapUpdateExistingEntities()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', [
|
|
|
+ 'fields' => ['title', 'body'],
|
|
|
+ ]);
|
|
|
+ $translate = $table->behaviors()->get('Translate');
|
|
|
+
|
|
|
+ $entity = $table->newEntity();
|
|
|
+ $es = $table->newEntity(['title' => 'Old title', 'body' => 'Old body']);
|
|
|
+ $en = $table->newEntity(['title' => 'Old title', 'body' => 'Old body']);
|
|
|
+ $entity->set('_translations', [
|
|
|
+ 'es' => $es,
|
|
|
+ 'en' => $en,
|
|
|
+ ]);
|
|
|
+ $map = $translate->buildMarhshalMap($table->marshaller(), [], []);
|
|
|
+ $data = [
|
|
|
+ 'en' => [
|
|
|
+ 'title' => 'English Title',
|
|
|
+ ],
|
|
|
+ 'es' => [
|
|
|
+ 'title' => 'Spanish Title',
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $result = $map['_translations']($data, $entity);
|
|
|
+ $this->assertEmpty($entity->errors(), 'No validation errors.');
|
|
|
+ $this->assertSame($en, $result['en']);
|
|
|
+ $this->assertSame($es, $result['es']);
|
|
|
+ $this->assertSame($en, $entity->get('_translations')['en']);
|
|
|
+ $this->assertSame($es, $entity->get('_translations')['es']);
|
|
|
+
|
|
|
+ $this->assertEquals('English Title', $result['en']->title);
|
|
|
+ $this->assertEquals('Spanish Title', $result['es']->title);
|
|
|
+ $this->assertEquals('Old body', $result['en']->body);
|
|
|
+ $this->assertEquals('Old body', $result['es']->body);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test that updating translation records works with validations.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testBuildMarshalMapUpdateEntitiesValidationErrors()
|
|
|
+ {
|
|
|
+ $table = TableRegistry::get('Articles');
|
|
|
+ $table->addBehavior('Translate', [
|
|
|
+ 'fields' => ['title', 'body'],
|
|
|
+ 'validator' => 'custom'
|
|
|
+ ]);
|
|
|
+ $validator = (new Validator)->add('title', 'notBlank', ['rule' => 'notBlank']);
|
|
|
+ $table->validator('custom', $validator);
|
|
|
+ $translate = $table->behaviors()->get('Translate');
|
|
|
+
|
|
|
+ $entity = $table->newEntity();
|
|
|
+ $es = $table->newEntity(['title' => 'Old title', 'body' => 'Old body']);
|
|
|
+ $en = $table->newEntity(['title' => 'Old title', 'body' => 'Old body']);
|
|
|
+ $entity->set('_translations', [
|
|
|
+ 'es' => $es,
|
|
|
+ 'en' => $en,
|
|
|
+ ]);
|
|
|
+ $map = $translate->buildMarhshalMap($table->marshaller(), [], []);
|
|
|
+ $data = [
|
|
|
+ 'en' => [
|
|
|
+ 'title' => 'English Title',
|
|
|
+ 'body' => 'English Content'
|
|
|
+ ],
|
|
|
+ 'es' => [
|
|
|
+ 'title' => '',
|
|
|
+ 'body' => 'Contenido Español'
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $result = $map['_translations']($data, $entity);
|
|
|
+ $this->assertNotEmpty($entity->errors(), 'Needs validation errors.');
|
|
|
+ $expected = [
|
|
|
+ 'title' => [
|
|
|
+ '_empty' => 'This field cannot be left empty'
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $this->assertEquals($expected, $entity->errors('es'));
|
|
|
+ }
|
|
|
}
|