File: D:/HostingSpaces/SBogers10/helder.komma.pro/tests/Unit/ComponentAreaTest.php
<?php
namespace Tests\Unit;
use App\Komma\Dynamic\Component\Component;
use App\Komma\Dynamic\Component\ComponentAttributeKey;
use App\Komma\Dynamic\Component\ComponentSaveState;
use App\Komma\Dynamic\ComponentArea\ComponentAreaSaveState;
use App\Komma\Dynamic\ComponentArea\ComponentAreaService;
use App\Komma\Dynamic\ComponentType\ComponentType;
use App\Komma\Dynamic\ComponentType\ComponentTypeBuilder;
use App\Komma\Dynamic\ComponentType\ComponentTypeResolver;
use App\Komma\Dynamic\SaveState\SaveState;
use App\Komma\Kms\Core\Attributes\Attribute;
use App\Komma\Kms\Core\Attributes\ComponentArea;
use App\Komma\Dynamic\ComponentArea\ComponentArea as ComponentAreaModel;
use App\Komma\Kms\Core\Attributes\Documents;
use App\Komma\Kms\Core\Attributes\Models\ImageProperty;
use App\Komma\Kms\Core\Attributes\TextArea;
use App\Komma\Pages\Models\Page;
use App\Komma\Pages\Models\PageTranslation;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Collection;
use Tests\TestCase;
class ComponentAreaTest extends TestCase
{
use DatabaseTransactions; //Automatically rolls back database actions after tests
/**
* @group DynamicAttributesSaveStateTest
* @test
*/
public function instanceCreationTest()
{
$ComponentAreaTypeBuilder = new ComponentTypeBuilder();
$this->assertInstanceOf(ComponentTypeBuilder::class, $ComponentAreaTypeBuilder);
}
/**
* Builds and resolves a componentType and tests its validity
* and afterwards it tries to save it to the database.
*
* @group ComponentAreaTest
* @test
*/
public function buildAndResolveComponentAreaTypesTest()
{
//Definition of a dynamic group:
//A class that groups configured instances of subclasses from the Attribute class.
//Created using a ComponentTypeBuilder, resolved by a ComponentAreaTypesResolver
//Build a group type that has two textarea's
$ComponentAreaTypeBuilder = (new ComponentTypeBuilder());
/** @var ComponentType $doubleText */
$doubleTextComponentType = $ComponentAreaTypeBuilder
->setName('phpunit-double-text')
->setIcon('dynamic-text-text.svg')
->addAttribute(
(new TextArea())
->enableTinymceEditor()
->setLabelText('Linker kolom')
->mapValueFrom(Attribute::ValueFromItself, 'Left') //Needed to sustain Attribute integrity.
)
->addAttribute(
(new TextArea())
->enableTinymceEditor()
->setLabelText('Rechter kolom')
->mapValueFrom(Attribute::ValueFromItself, 'Right') //Needed to sustain Attribute integrity.
)
->build();
$this->assertInstanceOf(ComponentType::class, $doubleTextComponentType);
$this->assertInternalType('string', $doubleTextComponentType->save_state);
$this->assertNotNull($doubleTextComponentType->id);
//Build a group type that has one text area and one image
$ComponentAreaTypeBuilder = (new ComponentTypeBuilder());
/** @var ComponentType $doubleText */
$textImageGroup = $ComponentAreaTypeBuilder
->setName('phpunit-text-image')
->setIcon('dynamic-phpunit-text-image.svg')
->addAttribute(
(new TextArea())
->enableTinymceEditor()
->setLabelText('Tekst')
->mapValueFrom(Attribute::ValueFromItself, 'Text') //Needed to sustain Attribute integrity.
)
->addAttribute(
(new Documents())
->setLabelText('Plaatje')
->onlyAllowImages()
->setMaxDocuments(1)
->setImageProperties([
(new ImageProperty())->setName('original')->setCropMethod(ImageProperty::Resize)->setWidth(2000),
(new ImageProperty())->setName('small')->setCropMethod(ImageProperty::Resize)->setWidth(300),
])
->mapValueFrom(Attribute::ValueFromItself, 'Image') //Needed to sustain Attribute integrity.
)->build();
//Resolve them. Does not only retrieve the ComponentType from the database, but also instantiates the attributes in it.
//Notice that the ComponentAreaTypes resolver returns new instances of ComponentType. Acting as templates for ComponentAreaTypes
$doubleTextComponentType = ComponentTypeResolver::resolve('phpunit-double-text');
$this->assertInstanceOf(ComponentType::class, $doubleTextComponentType); //The resolve method does give the ComponentType the group type so that the ComponentType can re-render itself when it is loaded from the database
$this->assertInstanceOf(SaveState::class, $doubleTextComponentType->save_state_instance);
/** @var SaveState $saveStateInstance */
$saveStateInstance = $doubleTextComponentType->save_state_instance;
$count = 0;
$saveStateInstance->getAttributeInstances()->each(function($attribute) use (&$count) {
$this->assertInstanceOf(Attribute::class, $attribute);
$count++;
});
$this->assertEquals(2, $count);
$this->assertInstanceOf(ComponentType::class, ComponentTypeResolver::resolve('phpunit-text-image'));
$this->assertEquals(0, ComponentTypeResolver::resolve('non-existing-group')->count());
$allComponentAreas = ComponentTypeResolver::resolveAll();
$this->assertInstanceOf(Collection::class, $allComponentAreas);
$this->assertTrue($allComponentAreas->count() >= 2);
}
/**
* @group ComponentAreaTest
* @test
*/
public function testComponentAreaSaveWithSingleComponent()
{
//Initialize the ComponentAreaService
$componentAreaService = new ComponentAreaService();
//Create a page for the component area so we can link the component area to it
/** @var PageTranslation $pageTranslation */
$pageTranslation = factory(PageTranslation::class)->create();
/** @var Page $page */
$page = $pageTranslation->translatable()->first();
//Create a json string that represents a component of type 1 (double text)
//Such json is provided by the frontend. The id of 0 means that a user pressed a button
//to add this component to the translation. If it was an existing one it would be a greater number.
$componentAreaJson =
'[{
"id":0,
"version":"0.9",
"componentTypeId":1,
"data":
{
"ComponentArea|dynamic_group_sections|C0|A1|nl":"Left text",
"ComponentArea|dynamic_group_sections|C0|A2|nl":"Right text"
},
"componentableData":{},
"sortOrder":0
}]';
//Check that we have that component type in the database
$type = ComponentTypeResolver::resolve(1);
$this->assertInstanceOf(ComponentType::class, $type);
//Simulate the generation of attributes in the most simple form
$componentArea = new ComponentArea();
$componentArea->setSubFolder('component_area_center_files');
$componentArea->mapValueFrom(Attribute::ValueFromDynamicGroups, 'component_area_center');
$componentArea->setAssociatedLanguage($pageTranslation->language);
//Simulate the fillAttributes with data method from the sectionService
$componentArea->setValue($componentAreaJson);
//The pageTranslation should have no componentArea yet.
$this->assertTrue($pageTranslation->componentAreas()->count() == 0);
//Save the json from the componentArea via the service.
$pageTranslation = $componentAreaService->saveOrUpdateComponentAreaForAttribute($page, $componentArea);
//ComponentAreas count should be 1 after saving the the componentArea attribute
$this->assertTrue($pageTranslation->componentAreas()->count() == 1);
/** @var ComponentAreaModel $componentArea */
$componentAreaModel = $pageTranslation->componentAreas()->first();
//There should be one component for the component area. It's the double text type (componentTypeId 1)
$this->assertTrue($componentAreaModel->components()->count() == 1);
}
/**
* @test
* @group ComponentAreaTest
* @depends testComponentAreaSaveWithSingleComponent
*/
public function testComponentAreaLoadWithSingleComponent()
{
//Save a component area that we can use later on
//Initialize the ComponentAreaService
$componentAreaService = new ComponentAreaService();
//Create a page for the component area so we can link the component area to it
/** @var PageTranslation $pageTranslation */
$pageTranslation = factory(PageTranslation::class)->create();
/** @var Page $page */
$page = $pageTranslation->translatable()->first();
//Create a json string that represents a component of type 1 (double text)
//Such json is provided by the frontend. The id of 0 means that a user pressed a button
//to add this component to the translation. If it was an existing one it would be a greater number.
$componentAreaJson =
'[{
"id":0,
"version":"0.9",
"componentTypeId":1,
"data":
{
"ComponentArea|component_area_center|C0|A1|nl":"Left text",
"ComponentArea|component_area_center|C0|A2|nl":"Right text"
},
"componentableData":{},
"sortOrder":0
}]';
$componentArea = new ComponentArea();
$componentArea->setSubFolder('component_area_center_files');
$componentArea->mapValueFrom(Attribute::ValueFromDynamicGroups, 'component_area_center');
$componentArea->setAssociatedLanguage($pageTranslation->language);
$componentArea->setValue($componentAreaJson);
$pageTranslation = $componentAreaService->saveOrUpdateComponentAreaForAttribute($page, $componentArea);
//Now try to load the component area and check that it is saved like it should.
//Load the component area save state json
$componentAreaJson = $componentAreaService->getComponentsSaveStateDataAsJsonFromModel($page, $componentArea);
//Check that we have a json string
$this->assertTrue(is_string($componentAreaJson));
$this->assertTrue(strlen($componentAreaJson) > 0);
$this->assertJson($componentAreaJson);
//Check if we can recreate the ComponentAreaSaveState
$componentAreaSaveState = ComponentAreaSaveState::fromJsonString($componentAreaJson);
$this->assertInstanceOf(ComponentAreaSaveState::class, $componentAreaSaveState);
/** @var ComponentAreaSaveState $componentAreaSaveState */
$this->assertTrue($componentAreaSaveState->getComponentsCount() === 1);
//Check that the component save state was saved correctly
$componentSaveState = $componentAreaSaveState->getComponentSaveStateAt(0);
//The id should no be 0 anymore because the component data is saved
$this->assertNotEquals(0, $componentSaveState->getId());
$this->assertEquals("0.9", $componentSaveState->getVersion());
$this->assertEquals(1, $componentSaveState->getComponentTypeId());
$data = $componentSaveState->getData();
$this->assertCount(2, $data);
$attributeKeysAsStrings = array_keys($data);
$leftTextAreaAttributeKey = ComponentAttributeKey::createInstanceFromString($attributeKeysAsStrings[0]);
$rightTextAreaAttributeKey = ComponentAttributeKey::createInstanceFromString($attributeKeysAsStrings[1]);
$this->assertInstanceOf(ComponentAttributeKey::class, $leftTextAreaAttributeKey);
$this->assertInstanceOf(ComponentAttributeKey::class, $rightTextAreaAttributeKey);
$this->assertEquals("ComponentArea", $leftTextAreaAttributeKey->getAttributeShortClassName());
$this->assertEquals("ComponentArea", $rightTextAreaAttributeKey->getAttributeShortClassName());
$this->assertEquals("component_area_center", $leftTextAreaAttributeKey->getValuePart());
$this->assertEquals("component_area_center", $rightTextAreaAttributeKey->getValuePart());
$this->assertNotEquals(0, $leftTextAreaAttributeKey->getComponentId());
$this->assertNotEquals(0, $rightTextAreaAttributeKey->getComponentId());
$this->assertEquals(1, $leftTextAreaAttributeKey->getAttributeNumber());
$this->assertEquals(2, $rightTextAreaAttributeKey->getAttributeNumber());
$this->assertEquals('nl', $leftTextAreaAttributeKey->getTranslationIso2());
$this->assertEquals('nl', $rightTextAreaAttributeKey->getTranslationIso2());
$this->assertEquals("Left text", $data[$attributeKeysAsStrings[0]]);
$this->assertEquals("Right text", $data[$attributeKeysAsStrings[1]]);
}
}