HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/tests/Unit/SlugSavingTest.php
<?php

namespace Tests\Unit;

use App\Pages\Models\Page;
use App\Pages\Models\PageTranslation;
use App\Site\Site;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Komma\KMS\Core\Attributes\TextField;
use Komma\KMS\Core\TranslationService;
use Komma\KMS\Globalization\Languages\Models\Language;
use Komma\KMS\Sites\SiteServiceInterface;
use Tests\TestCase;

class SlugSavingTest extends TestCase
{
    /**
     * Test saving slugs for translations for a system with 1 site.
     *
     * @group AdvancedSlugSaving
     * @test
     */
    public function SingleSiteSlugOnTranslationModelTest()
    {
        //Seed the sqlite database. We need a sqlite because we dispose the database a couple of times very quickly. We do this to put it in a known "state".
        DB::setDefaultConnection('sqlite_testing');

        //Make sure the system is set for a single site and single language
        config()->set('app.multipleSites', false);
        config()->set('app.multipleLanguages', true);
        config()->set('languages.available', ['nl', 'en']);

        //Run the migrations
        $this->artisan('migrate:fresh --env=testing');
        $this->artisan('kms:seed --env=testing');
        $this->artisan('db:seed --env=testing');

        //Initialize services we are going to need
        /** @var $translationService */
        $translationService = new TranslationService();
        $translationService->setModelClassName(PageTranslation::class);

        //Get the languages we are going to test for
        $languages = Language::whereIn('iso_2', config('languages.available'))->get();

        //Retrieve languages we are going to use lateron
        $dutchLanguage = $languages->where('iso_2', '=', 'nl')->first();
        $englishLanguage = $languages->where('iso_2', '=', 'en')->first();
        $this->assertInstanceOf(Language::class, $dutchLanguage);
        $this->assertInstanceOf(Language::class, $englishLanguage);

        //Create a new Site
        $site = (new Site())->fill(['slug' => 'unit', 'name' => 'unit', 'default_language_id' => $dutchLanguage->id]);
        $site->save();

        /** @var SiteServiceInterface $siteService */
        $siteService = app(SiteServiceInterface::class);

        //Update the Site service internal "Site cache"
        $sites = $siteService->getSites(true);
        $this->assertCount(1, $sites->where('id', '=', $site->id)->where('slug', '=', 'unit'));

        //Set the current site to the new "unit" site
        $siteService->setCurrentSiteBySlug('unit');

        //Create a collection of "Section attributes". Just to simulate the result of a section.
        $dutchAttributes = [];
        $dutchAttributes[] = $dutchNameTextField = (new TextField(__('kms/global.title')))
            ->setPlaceholderText(__('kms/global.enterTitle'))
            ->setAssociatedLanguage($dutchLanguage)
            ->setReference( 'name');
        $dutchAttributes = collect($dutchAttributes);

        $englishAttributes = [];
        $englishAttributes[] = $englishNameTextField = (new TextField(__('kms/global.title')))
            ->setPlaceholderText(__('kms/global.enterTitle'))
            ->setAssociatedLanguage($englishLanguage)
            ->setReference( 'name');
        $englishAttributes = collect($englishAttributes);

        //Set the name textfield to the desired slug. So the translation will be set to a sluggified version of it by the translation service.
        $dutchNameTextField->setValue('My awesome page');
        $englishNameTextField->setValue('My awesome page');

        //Create 3 pages
        /** @var Page $page */
        $pages = factory(Page::class, 3)->make();
        $pages->map(function(Page $page) use($site, $translationService) {
            $page->site()->associate($site);
            $page->save();
            //Make sure that the page has empty translations. This is how the section controller does it too. Because of that we need too.
            $page = $translationService->makeAndInjectEmptyTranslationsIntoTranslatableIfNeeded($page);
            return $page;
        });

        //Save the first page's translation using the translation service. In there we have the CanSaveSlugsTrait we are trying to test here.
        $translationService->save($pages[0], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $pages[0]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page', $translation->slug);


        //Save the second page's translation using the translation service. This translation must have a different slug to avoid conflict of the other page's translation
        $translationService->save($pages[1], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $pages[1]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page-1', $translation->slug);


        //Save the Third page's translation using the translation service. This translation must have a different slug to avoid conflict of the other page's translation
        $translationService->save($pages[2], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $pages[2]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page-2', $translation->slug);

        //Save the fourth page's translation using the translation service, but with english attributes (name Textfield). This translation must have the same as the suggested one.
        $translationService->save($pages[2], $englishAttributes);
        //Check that it has the expected slug:
        $translation = $pages[2]->translations()->whereHas('language', function(Builder $query) use($englishLanguage) {
            $query->where('id', '=', $englishLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page', $translation->slug); //Must be allowed since translation belongs to another language. Resulting in a unique url eventually.
    }

    /**
     * Test saving slugs for non translation models for a system with 1 site.
     *
     * @group AdvancedSlugSaving
     * @test
     */
//    public function SingleSiteSlugOnNonTranslationModelTest() {
//        //Note. We cannot test this yet since we don't have a non AbstractTranslation model that has a slug.
//    }

    /**
     * Test saving slugs for translations for a system with more then 1 site.
     *
     * @group AdvancedSlugSaving
     * @test
     */
    public function MultipleSiteSlugOnTranslationModelTest()
    {
        //Seed the sqlite database. We need a sqlite because we dispose the database a couple of times very quickly. We do this to put it in a known "state".
        DB::setDefaultConnection('sqlite_testing');

        //Make sure the system is set for a single site and single language
        config()->set('app.multipleSites', true);
        config()->set('app.multipleLanguages', true);
        config()->set('languages.available', ['nl', 'en']);

        //Run the migrations
        $this->artisan('migrate:fresh --env=testing');
        $this->artisan('kms:seed --env=testing');
        $this->artisan('db:seed --env=testing');

        //Initialize services we are going to need
        /** @var $translationService */
        $translationService = new TranslationService();
        $translationService->setModelClassName(PageTranslation::class);

        //Get the languages we are going to test for
        $languages = Language::whereIn('iso_2', config('languages.available'))->get();

        //Retrieve languages we are going to use lateron
        $dutchLanguage = $languages->where('iso_2', '=', 'nl')->first();
        $englishLanguage = $languages->where('iso_2', '=', 'en')->first();
        $this->assertInstanceOf(Language::class, $dutchLanguage);
        $this->assertInstanceOf(Language::class, $englishLanguage);

        //Create a new Site
        $site = (new Site())->fill(['slug' => 'unit', 'name' => 'unit', 'default_language_id' => $dutchLanguage->id]);
        $site->save();

        $secondSite = (new Site())->fill(['slug' => 'unit_2', 'name' => 'unit_2', 'default_language_id' => $englishLanguage->id]);
        $secondSite->save();

        /** @var SiteServiceInterface $siteService */
        $siteService = app(SiteServiceInterface::class);

        //Update the Site service internal "Site cache"
        $sites = $siteService->getSites(true);
        $this->assertCount(2, $sites->filter(function(Site $site) {
                return substr($site->slug, 0, 4) === 'unit';
            })
        );

        //Set the current site to the new "unit" site
        $siteService->setCurrentSiteBySlug('unit');

        //Create a collection of "Section attributes". Just to simulate the result of a section.
        $dutchAttributes = [];
        $dutchAttributes[] = $dutchNameTextField = (new TextField(__('kms/global.title')))
            ->setPlaceholderText(__('kms/global.enterTitle'))
            ->setAssociatedLanguage($dutchLanguage)
            ->setReference( 'name');
        $dutchAttributes = collect($dutchAttributes);

        $englishAttributes = [];
        $englishAttributes[] = $englishNameTextField = (new TextField(__('kms/global.title')))
            ->setPlaceholderText(__('kms/global.enterTitle'))
            ->setAssociatedLanguage($englishLanguage)
            ->setReference( 'name');
        $englishAttributes = collect($englishAttributes);

        //Set the name textfield to the desired slug. So the translation will be set to a sluggified version of it by the translation service.
        $dutchNameTextField->setValue('My awesome page');
        $englishNameTextField->setValue('My awesome page');

        //Create 6 pages. 3 for the first site. 3 for the second
        /** @var Page $page */
        $pages = factory(Page::class, 3)->make();
        $pages->map(function(Page $page) use($site, $translationService) {
            $page->site()->associate($site);
            $page->save();
            //Make sure that the page has empty translations. This is how the section controller does it too. Because of that we need too.
            $page = $translationService->makeAndInjectEmptyTranslationsIntoTranslatableIfNeeded($page);
            return $page;
        });

        $secondSitePages = factory(Page::class, 3)->make();
        $secondSitePages->map(function(Page $page) use($secondSite, $translationService) {
            $page->site()->associate($secondSite);
            $page->save();
            //Make sure that the page has empty translations. This is how the section controller does it too. Because of that we need too.
            $page = $translationService->makeAndInjectEmptyTranslationsIntoTranslatableIfNeeded($page);
            return $page;
        });

        //Verify that both sites have 3 pages
        $this->assertEquals(3, $site->pages()->count());
        $this->assertEquals(3, $secondSite->pages()->count());

        //TESTS FOR THE FIRST SITE
        //Save the first page's translation using the translation service. In there we have the CanSaveSlugsTrait we are trying to test here.
        $translationService->save($pages[0], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $pages[0]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page', $translation->slug);


        //Save the second page's translation using the translation service. This translation must have a different slug to avoid conflict of the other page's translation
        $translationService->save($pages[1], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $pages[1]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page-1', $translation->slug);


        //Save the Third page's translation using the translation service. This translation must have a different slug to avoid conflict of the other page's translation
        $translationService->save($pages[2], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $pages[2]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page-2', $translation->slug);

        //Save the fourth page's translation using the translation service, but with english attributes (name Textfield). This translation must have the same as the suggested one.
        $translationService->save($pages[2], $englishAttributes);
        //Check that it has the expected slug:
        $translation = $pages[2]->translations()->whereHas('language', function(Builder $query) use($englishLanguage) {
            $query->where('id', '=', $englishLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page', $translation->slug); //Must be allowed since translation belongs to another language. Resulting in a unique url eventually.

        //TESTS FOR THE SECOND SITE
        //Save the first page's translation using the translation service. In there we have the CanSaveSlugsTrait we are trying to test here.
        $translationService->save($secondSitePages[0], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $secondSitePages[0]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page', $translation->slug);


        //Save the second page's translation using the translation service. This translation must have a different slug to avoid conflict of the other page's translation
        $translationService->save($secondSitePages[1], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $secondSitePages[1]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page-1', $translation->slug);


        //Save the Third page's translation using the translation service. This translation must have a different slug to avoid conflict of the other page's translation
        $translationService->save($secondSitePages[2], $dutchAttributes);
        //Check that it has the expected slug:
        $translation = $secondSitePages[2]->translations()->whereHas('language', function(Builder $query) use($dutchLanguage) {
            $query->where('id', '=', $dutchLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page-2', $translation->slug);

        //Save the fourth page's translation using the translation service, but with english attributes (name Textfield). This translation must have the same as the suggested one.
        $translationService->save($secondSitePages[2], $englishAttributes);
        //Check that it has the expected slug:
        $translation = $secondSitePages[2]->translations()->whereHas('language', function(Builder $query) use($englishLanguage) {
            $query->where('id', '=', $englishLanguage->id);
        })->first();
        $this->assertEquals('my-awesome-page', $translation->slug); //Must be allowed since translation belongs to another language. Resulting in a unique url eventually.
    }

    /**
     * Test saving slugs for non translation models for a system with more then one site.
     *
     * @group AdvancedSlugSaving
     * @test
     */
//    public function MultiSiteSlugOnNonTranslationModelTest() {
//        //Note. We cannot test this yet since we don't have a non AbstractTranslation model that has a slug.
//    }
}