This commit is contained in:
2026-05-13 17:11:09 +02:00
commit ea63897455
2785 changed files with 359868 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
<?php
use cPad\Plugins\Blocks\Components\Block;
it('constructs the block component with debug mode enabled', function () {
config()->set('app.debug', true);
$component = new Block('sample-block');
expect($component->debug)->toBeTrue();
});

View File

@@ -0,0 +1,54 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View;
use cPad\Plugins\Blocks\Components\Block as BlockComponent;
it('renders block html exactly as stored', function () {
View::addNamespace('plugin.block', base_path('packages/klevze/Plugins/Blocks/Resources/views'));
config()->set('app.debug', false);
app()->setLocale('en');
if (! Schema::hasTable('blocks')) {
Schema::create('blocks', function (Blueprint $table) {
$table->increments('block_id');
$table->string('keycode', 64)->unique();
$table->text('attributes')->nullable();
$table->text('notes')->nullable();
$table->boolean('active')->default(true);
$table->string('block_group', 16)->nullable();
$table->timestamps();
});
}
$keycode = 'test-block-render-html';
$html = '<section class="hero"><h1>Title</h1><p><strong>Bold</strong> <em>Italic</em></p><svg><path d="M0 0"></path></svg></section>';
DB::table('blocks')->where('keycode', $keycode)->delete();
DB::table('blocks')->insert([
'keycode' => $keycode,
'attributes' => json_encode([
app()->getLocale() => [
'content' => $html,
],
]),
'notes' => null,
'active' => true,
'block_group' => null,
'created_at' => now(),
'updated_at' => now(),
]);
try {
$output = (new BlockComponent($keycode))->render()->render();
expect(trim($output))->toBe($html);
expect($output)->not->toContain('&lt;');
expect($output)->not->toContain('&amp;');
} finally {
DB::table('blocks')->where('keycode', $keycode)->delete();
}
});

View File

@@ -0,0 +1,80 @@
<?php
use Illuminate\Support\Facades\View;
use Klevze\ControlPanel\Facades\ActiveLanguage;
use cPad\Plugins\Blocks\Controllers\BlockController;
it('renders decoded html in the block editor form', function () {
View::addNamespace('plugin.block', base_path('packages/klevze/Plugins/Blocks/Resources/views'));
$decodeHtml = function ($value) {
$decoded = (string) $value;
while (true) {
$next = html_entity_decode($decoded, ENT_QUOTES | ENT_HTML5, 'UTF-8');
if ($next === $decoded) {
return $decoded;
}
$decoded = $next;
}
};
$defaultLanguageContent = $decodeHtml('&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Link&amp;lt;/a&amp;gt;');
$html = view('plugin.block::form.translation', [
'languages' => [(object) ['iso' => 'en']],
'attributes' => (object) [
'en' => (object) [
'content' => '&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Link&amp;lt;/a&amp;gt;',
'html_code' => null,
],
],
'decodeHtml' => $decodeHtml,
'defaultLanguageContent' => $defaultLanguageContent,
])->render();
expect($html)->toContain('&quot;#&quot;');
expect($html)->not->toContain('&amp;quot;#&amp;quot;');
});
it('normalizes encoded html before persisting a block', function () {
$controller = app(BlockController::class);
$reflection = new ReflectionMethod($controller, 'normalizePrevodPayload');
$reflection->setAccessible(true);
$normalized = $reflection->invoke($controller, [
'en' => [
'content' => '&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Link&amp;lt;/a&amp;gt;',
],
]);
expect($normalized['en']['content'])->toBe('<a href="#">Link</a>');
});
it('renders frontend language tabs in the block editor', function () {
View::addNamespace('plugin.block', base_path('packages/klevze/Plugins/Blocks/Resources/views'));
ActiveLanguage::shouldReceive('getList')
->once()
->with('fp')
->andReturn(collect([
(object) ['iso' => 'en', 'name' => 'English'],
(object) ['iso' => 'sl', 'name' => 'Slovenian'],
]));
$html = view('plugin.block::form.translation', [
'languages' => [(object) ['iso' => 'en']],
'attributes' => (object) [
'en' => (object) ['content' => '', 'html_code' => null],
],
'decodeHtml' => fn ($value) => (string) $value,
'defaultLanguageContent' => '',
])->render();
expect($html)->toContain('nav nav-tabs');
expect($html)->toContain('English');
expect($html)->toContain('Slovenian');
});

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Http\Request;
use Klevze\ControlPanel\Http\Middleware\InputValidationMiddleware;
use Klevze\ControlPanel\Services\Validation\InputValidationService;
use function Pest\Laravel\mock;
it('allows block insert html to bypass generic input validation', function () {
mock(InputValidationService::class, function ($mock) {
$mock->shouldNotReceive('validateSecurity');
});
$middleware = app(InputValidationMiddleware::class);
$request = Request::create('/cp/content/blocks/insert', 'POST', [
'keycode' => 'hero-block',
'notes' => 'Intro section',
'block_group' => 'home',
'active' => '1',
'prevod' => [
'en' => [
'name' => 'English',
'content' => '<script>alert(1)</script>',
],
],
'store_id' => 1,
'token_count' => 12,
]);
$request->setRouteResolver(fn () => new class {
public function getName(): string
{
return 'admin.plugin.block.insert';
}
});
$response = $middleware->handle($request, fn () => response('ok'));
expect($response->getContent())->toBe('ok');
});

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Http\Request;
use Klevze\ControlPanel\Http\Middleware\InputValidationMiddleware;
use Klevze\ControlPanel\Services\Validation\InputValidationService;
use function Pest\Laravel\mock;
it('skips generic input validation for block layout saves', function () {
mock(InputValidationService::class, function ($mock) {
$mock->shouldNotReceive('validateSecurity');
});
$middleware = app(InputValidationMiddleware::class);
$request = Request::create('/cp/content/blocks/layout', 'POST', [
'header' => '<script src="https://example.com/app.js"></script>',
'footer' => '<script>alert(1)</script>',
'layout' => 'main',
]);
$request->setRouteResolver(fn () => new class {
public function getName(): string
{
return 'admin.plugin.block.layout.update';
}
});
$response = $middleware->handle($request, fn () => response('ok'));
expect($response->getContent())->toBe('ok');
});

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Blade;
it('renders translated block names per language with an n-a fallback', function () {
$html = Blade::render(<<<'BLADE'
@php
$translations = is_array($row->attributes ?? null) ? $row->attributes : [];
@endphp
@foreach($languages as $lang)
@php
$translation = $translations[$lang->iso] ?? [];
$translatedName = trim((string) data_get($translation, 'name', ''));
@endphp
<span class="headlines lang-{{ $lang->iso }}">
{{ $translatedName !== '' ? $translatedName : 'N/A' }}
</span>
@endforeach
BLADE, [
'languages' => collect([
(object) ['iso' => 'en', 'name' => 'English'],
(object) ['iso' => 'sl', 'name' => 'Slovenian'],
]),
'row' => (object) [
'attributes' => [
'en' => ['name' => 'Hero title', 'content' => '<p>Hello</p>'],
'sl' => ['content' => '<p>Zivjo</p>'],
],
],
]);
expect($html)->toContain('Hero title');
expect($html)->toContain('N/A');
});

View File

@@ -0,0 +1,7 @@
<?php
test('the application returns a successful response', function () {
$response = $this->get('/');
$response->assertStatus(200);
});

View File

@@ -0,0 +1,16 @@
<?php
use function Pest\Laravel\get;
it('renders localized frontend links on locale prefixed pages', function () {
get('/sl')
->assertSuccessful()
->assertSee('/sl/contact', false)
->assertSee('/sl', false);
});
it('renders the localized terms page without falling through slug routing', function () {
get('/sl/terms')
->assertSuccessful()
->assertSee('Terms', false);
});

View File

@@ -0,0 +1,99 @@
<?php
use cPad\Plugins\Pages\Controllers\PagesController;
use cPad\Plugins\Pages\Services\Content;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View;
use Klevze\ControlPanel\Facades\ActiveLanguage;
use Klevze\ControlPanel\Models\Content\ActiveLanguage as ActiveLanguageModel;
use Klevze\ControlPanel\Models\Content\Language;
use Klevze\ControlPanel\Services\Config;
beforeEach(function () {
View::addNamespace('plugin.page', base_path('packages/klevze/Plugins/Pages/Resources/views'));
Schema::dropIfExists('cpad');
Schema::dropIfExists('active_languages');
Schema::dropIfExists('languages');
Schema::create('languages', function (Blueprint $table) {
$table->char('iso', 2)->primary();
$table->string('name', 50);
$table->string('native', 50);
});
Schema::create('active_languages', function (Blueprint $table) {
$table->id('language_id');
$table->char('iso', 2)->unique();
$table->boolean('active')->default(false);
$table->unsignedTinyInteger('num');
$table->char('type', 16);
});
Schema::create('cpad', function (Blueprint $table) {
$table->string('keycode')->primary();
$table->text('value')->nullable();
});
Language::create(['iso' => 'sl', 'name' => 'Slovenian', 'native' => 'Slovenščina']);
Language::create(['iso' => 'en', 'name' => 'English', 'native' => 'English']);
ActiveLanguageModel::create(['iso' => 'sl', 'active' => true, 'num' => 1, 'type' => 'fp']);
ActiveLanguageModel::create(['iso' => 'en', 'active' => true, 'num' => 2, 'type' => 'fp']);
ActiveLanguage::clearCache();
\Klevze\ControlPanel\Models\System\Cpad::create([
'keycode' => 'plugin.pages.config',
'value' => '{}',
]);
});
it('loads fp languages for the pages create form', function () {
$controller = new class(app(Content::class), app(Config::class)) extends PagesController {
public function getFontIcons()
{
return [];
}
protected function getCategories()
{
return [];
}
protected function getCategoryTree()
{
return [];
}
protected function getPagesList()
{
return [];
}
public function getGalleryList(?int $id)
{
return [];
}
protected function getTranslation($content_id)
{
return [];
}
};
$view = $controller->Create();
$data = $view->getData();
expect($data['languages'])
->toHaveCount(2)
->and(collect($data['languages'])->pluck('iso')->all())
->toBe(['sl', 'en'])
->and($data['translationForm'])
->toBeArray()
->and($data['translationForm'])
->not->toBeEmpty()
->and($data['translationForm'][0]->name)
->toBe('title');
});

View File

@@ -0,0 +1,73 @@
<?php
use cPad\Plugins\Pages\Controllers\SetupController;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View;
use Klevze\ControlPanel\Models\System\Cpad;
use Klevze\ControlPanel\Services\Config;
beforeEach(function () {
View::addNamespace('plugin.page', base_path('packages/klevze/Plugins/Pages/Resources/views'));
Schema::dropIfExists('cpad');
Schema::create('cpad', function (Blueprint $table) {
$table->string('keycode')->primary();
$table->text('value')->nullable();
});
});
it('decodes stored pages setup config before rendering the setup view', function () {
Cpad::create([
'keycode' => 'plugin.pages.fields',
'value' => '[{&quot;type&quot;:&quot;text&quot;,&quot;name&quot;:&quot;title&quot;,&quot;label&quot;:&quot;Title&quot;,&quot;required&quot;:true,&quot;store&quot;:&quot;title&quot;}]',
]);
Cpad::create([
'keycode' => 'plugin.pages.config',
'value' => '{"folderDivider":150,"localeLinks":"Y"}',
]);
$view = app(SetupController::class)->Setup(Request::create('/cp/content/pages/setup', 'GET'));
expect($view->getData()['form'])
->toBeArray()
->and($view->getData()['form'][0]->name)
->toBe('title')
->and($view->getData()['setup'])
->toBeObject()
->and($view->getData()['setup']->folderDivider)
->toBe(150);
});
it('flushes and repopulates cached pages settings after saving setup', function () {
Cpad::create([
'keycode' => 'plugin.pages.fields',
'value' => '[{&quot;type&quot;:&quot;text&quot;,&quot;name&quot;:&quot;title&quot;,&quot;label&quot;:&quot;Title&quot;,&quot;required&quot;:true,&quot;store&quot;:&quot;title&quot;}]',
]);
Cpad::create([
'keycode' => 'plugin.pages.config',
'value' => '{"folderDivider":100,"localeLinks":"N"}',
]);
$controller = app(SetupController::class);
$response = $controller->Update(Request::create('/cp/content/pages/setup', 'POST', [
'setup' => [
'folderDivider' => 200,
'localeLinks' => 'Y',
],
'fields' => '[{&quot;type&quot;:&quot;text&quot;,&quot;name&quot;:&quot;title&quot;,&quot;label&quot;:&quot;Updated Title&quot;,&quot;required&quot;:true,&quot;store&quot;:&quot;title&quot;}]',
]));
expect($response->getStatusCode())->toBe(302);
$config = app(Config::class);
expect($config->checkConfig('plugin.pages.config'))
->toBeTrue()
->and($config->checkConfig('plugin.pages.fields'))
->toBeTrue();
});

View File

@@ -0,0 +1,118 @@
<?php
use cPad\Plugins\Projects\Controllers\ProductsController;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
beforeEach(function () {
Schema::dropIfExists('projects_description');
Schema::dropIfExists('projects');
Schema::create('projects', function (Blueprint $table) {
$table->increments('project_id');
$table->unsignedTinyInteger('active')->default(1);
$table->json('categories')->nullable();
$table->text('category_notes')->nullable();
$table->text('structure')->nullable();
$table->timestamps();
});
Schema::create('projects_description', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('project_id');
$table->char('iso', 3);
$table->string('headline')->nullable();
});
});
it('keeps existing categories when the settings panel is not submitted', function () {
DB::table('projects')->insert([
'project_id' => 18,
'active' => 1,
'categories' => json_encode(['1', '2']),
'category_notes' => json_encode(['1' => 'Existing note']),
'structure' => null,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('projects_description')->insert([
'project_id' => 18,
'iso' => 'sl',
'headline' => 'Before',
]);
try {
app(ProductsController::class)->update(18, Request::create('/cp/projects/edit/18', 'POST', [
'active' => '1',
'categories_touched' => '0',
]));
} catch (\Throwable) {
// The admin redirect route is not loaded in this isolated feature test.
}
expect(DB::table('projects')->where('project_id', 18)->value('categories'))->toBe(json_encode(['1', '2']));
expect(DB::table('projects')->where('project_id', 18)->value('category_notes'))->toBe(json_encode(['1' => 'Existing note']));
});
it('clears categories when the settings panel is submitted without any selected categories', function () {
DB::table('projects')->insert([
'project_id' => 18,
'active' => 1,
'categories' => json_encode(['1', '2']),
'category_notes' => json_encode(['1' => 'Existing note']),
'structure' => null,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('projects_description')->insert([
'project_id' => 18,
'iso' => 'sl',
'headline' => 'Before',
]);
try {
app(ProductsController::class)->update(18, Request::create('/cp/projects/edit/18', 'POST', [
'active' => '1',
'categories_touched' => '1',
]));
} catch (\Throwable) {
// The admin redirect route is not loaded in this isolated feature test.
}
expect(DB::table('projects')->where('project_id', 18)->value('categories'))->toBe(json_encode([]));
expect(DB::table('projects')->where('project_id', 18)->value('category_notes'))->toBe(json_encode(['1' => 'Existing note']));
});
it('deduplicates categories when the settings panel submits repeated values', function () {
DB::table('projects')->insert([
'project_id' => 18,
'active' => 1,
'categories' => json_encode(['1']),
'category_notes' => null,
'structure' => null,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('projects_description')->insert([
'project_id' => 18,
'iso' => 'sl',
'headline' => 'Before',
]);
try {
app(ProductsController::class)->update(18, Request::create('/cp/projects/edit/18', 'POST', [
'active' => '1',
'categories_touched' => '1',
'categories' => ['4', '4', '2', '2'],
]));
} catch (\Throwable) {
// The admin redirect route is not loaded in this isolated feature test.
}
expect(DB::table('projects')->where('project_id', 18)->value('categories'))->toBe(json_encode(['4', '2']));
});

View File

@@ -0,0 +1,297 @@
<?php
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View;
use Illuminate\Database\Schema\Blueprint;
use Tests\Fixtures\View\Components\Block as TestBlockComponent;
use function Pest\Laravel\get;
beforeEach(function () {
Schema::dropIfExists('blocks');
Schema::dropIfExists('projects_gallery');
Schema::dropIfExists('projects_description');
Schema::dropIfExists('projects');
Schema::dropIfExists('projects_categories_description');
Schema::dropIfExists('projects_categories');
Blade::component('block', TestBlockComponent::class);
View::addNamespace('plugin.block', base_path('packages/klevze/Plugins/Blocks/Resources/views'));
Schema::create('projects_categories', function (Blueprint $table) {
$table->increments('category_id');
$table->unsignedInteger('parent_id')->default(0);
$table->unsignedTinyInteger('active')->default(1);
$table->integer('num')->default(0);
});
Schema::create('projects_categories_description', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('category_id');
$table->char('iso', 3);
$table->string('title');
});
Schema::create('projects', function (Blueprint $table) {
$table->increments('project_id');
$table->unsignedInteger('category_id')->nullable()->default(0);
$table->unsignedTinyInteger('active')->default(1);
$table->string('picture_cover')->nullable();
$table->string('picture_catalog')->nullable();
$table->string('picture_catalog_full')->nullable();
$table->string('video')->nullable();
$table->json('categories')->nullable();
$table->text('structure')->nullable();
$table->string('bgColor')->nullable();
$table->timestamps();
});
Schema::create('projects_description', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('project_id');
$table->char('iso', 3);
$table->string('headline');
$table->string('subline')->nullable();
$table->string('name')->nullable();
$table->integer('year')->nullable();
$table->text('preview')->nullable();
$table->longText('content')->nullable();
$table->string('tag1')->nullable();
$table->string('tag2')->nullable();
$table->string('tag3')->nullable();
$table->string('youtube')->nullable();
$table->string('page_title')->nullable();
$table->string('meta_title')->nullable();
$table->string('meta_description')->nullable();
$table->string('og_title')->nullable();
$table->string('og_description')->nullable();
});
Schema::create('projects_gallery', function (Blueprint $table) {
$table->increments('photo_id');
$table->unsignedInteger('project_id');
$table->integer('num')->default(0);
$table->string('diskname');
$table->string('name')->nullable();
});
Schema::create('blocks', function (Blueprint $table) {
$table->increments('block_id');
$table->string('keycode', 64)->unique();
$table->json('attributes')->nullable();
$table->string('notes')->nullable();
$table->boolean('active')->default(true);
$table->string('block_group', 16)->nullable();
$table->softDeletes();
$table->timestamps();
});
DB::table('blocks')->insert([
[
'keycode' => 'WORK-HEADER',
'attributes' => json_encode(['sl' => ['content' => '']]),
'active' => true,
'created_at' => now(),
'updated_at' => now(),
],
[
'keycode' => 'FOOTER-BLOCK',
'attributes' => json_encode(['sl' => ['content' => '']]),
'active' => true,
'created_at' => now(),
'updated_at' => now(),
],
[
'keycode' => 'FOOTER-HOME-BLOCK',
'attributes' => json_encode(['sl' => ['content' => '']]),
'active' => true,
'created_at' => now(),
'updated_at' => now(),
],
]);
});
function seedPublicProject(int $id, string $headline, int $categoryId, ?array $structure = null): void
{
DB::table('projects')->insert([
'project_id' => $id,
'category_id' => $categoryId,
'active' => 1,
'categories' => json_encode([$categoryId]),
'structure' => $structure ? json_encode($structure) : null,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('projects_description')->insert([
'project_id' => $id,
'iso' => 'sl',
'headline' => $headline,
'name' => 'Client ' . $id,
'preview' => 'Preview ' . $id,
'content' => 'Content ' . $id,
'tag1' => 'Award ' . $id,
'youtube' => 'https://www.youtube.com/watch?v=ScMzIvxBSi4',
]);
}
it('renders public work cards from projects records', function () {
DB::table('projects_categories')->insert([
'category_id' => 1,
'parent_id' => 0,
'active' => 1,
'num' => 1,
]);
DB::table('projects_categories_description')->insert([
'category_id' => 1,
'iso' => 'sl',
'title' => 'Branding',
]);
seedPublicProject(10, 'Golden Drum', 1);
get('/sl/work')
->assertSuccessful()
->assertSee('Golden Drum', false)
->assertSee('/sl/project/10/golden-drum', false)
->assertSee('Branding', false);
});
it('renders bunny video thumbnails on the work page when configured in project settings', function () {
DB::table('projects_categories')->insert([
'category_id' => 1,
'parent_id' => 0,
'active' => 1,
'num' => 1,
]);
DB::table('projects_categories_description')->insert([
'category_id' => 1,
'iso' => 'sl',
'title' => 'Branding',
]);
seedPublicProject(18, 'Video Thumb Project', 1, [
'header' => ['headline' => 'Video Thumb Project'],
'thumbnailMedia' => [
'type' => 'bunny',
'url' => 'https://player.mediadelivery.net/embed/12345/abcde',
'autoplay' => true,
'loop' => true,
'muted' => true,
],
'heroMedia' => ['type' => 'image', 'url' => ''],
'metadata' => ['clientName' => 'Client 18', 'awarded' => [], 'description' => 'Preview 18'],
'contentBlocks' => [],
]);
get('/sl/work')
->assertSuccessful()
->assertSee('Video Thumb Project', false)
->assertSee('player.mediadelivery.net/embed/12345/abcde', false)
->assertSee('autoplay=true', false)
->assertSee('loop=true', false)
->assertSee('muted=true', false);
});
it('falls back to the bunny hero video on the work page when the thumbnail is set to bunny without its own url', function () {
DB::table('projects_categories')->insert([
'category_id' => 1,
'parent_id' => 0,
'active' => 1,
'num' => 1,
]);
DB::table('projects_categories_description')->insert([
'category_id' => 1,
'iso' => 'sl',
'title' => 'Branding',
]);
seedPublicProject(18, 'Haloško srce', 1, [
'header' => ['headline' => 'Haloško srce'],
'thumbnailMedia' => [
'type' => 'bunny',
'url' => '',
'autoplay' => true,
'loop' => true,
'muted' => true,
],
'heroMedia' => [
'type' => 'bunny',
'url' => 'https://player.mediadelivery.net/embed/98765/hero-video',
'autoplay' => true,
'loop' => true,
'muted' => true,
],
'metadata' => ['clientName' => 'Client 18', 'awarded' => [], 'description' => 'Preview 18'],
'contentBlocks' => [],
]);
get('/sl/work')
->assertSuccessful()
->assertSee('Haloško srce', false)
->assertSee('player.mediadelivery.net/embed/98765/hero-video', false)
->assertSee('autoplay=true', false)
->assertSee('loop=true', false)
->assertSee('muted=true', false);
});
it('renders the selected project and the next project navigation', function () {
DB::table('projects_categories')->insert([
['category_id' => 1, 'parent_id' => 0, 'active' => 1, 'num' => 1],
['category_id' => 2, 'parent_id' => 0, 'active' => 1, 'num' => 2],
]);
DB::table('projects_categories_description')->insert([
['category_id' => 1, 'iso' => 'sl', 'title' => 'Branding'],
['category_id' => 2, 'iso' => 'sl', 'title' => 'Campaign'],
]);
seedPublicProject(11, 'First Project', 1, [
'header' => ['headline' => 'First Project'],
'heroMedia' => ['type' => 'youtube', 'url' => 'https://www.youtube.com/watch?v=ScMzIvxBSi4'],
'metadata' => ['clientName' => 'SOZ', 'awarded' => ['Award 1'], 'description' => 'Desc'],
'contentBlocks' => [],
]);
seedPublicProject(9, 'Second Project', 2);
get('/sl/project/11/first-project')
->assertSuccessful()
->assertSee('First Project', false)
->assertSee('/sl/project/9/second-project', false)
->assertSee('Next project', false);
});
it('prefers the translated project description over the schema sample', function () {
DB::table('projects_categories')->insert([
'category_id' => 1,
'parent_id' => 0,
'active' => 1,
'num' => 1,
]);
DB::table('projects_categories_description')->insert([
'category_id' => 1,
'iso' => 'sl',
'title' => 'Branding',
]);
seedPublicProject(12, 'Project Twelve', 1, [
'header' => ['headline' => ''],
'heroMedia' => ['type' => 'image', 'url' => ''],
'metadata' => ['clientName' => 'SOZ', 'awarded' => [], 'description' => 'A modular project schema that can drive both the public page and the cPad editor preview.'],
'contentBlocks' => [],
]);
DB::table('projects_description')->where('project_id', 12)->update([
'preview' => 'Ne za kogarkoli, ampak za Golden Drum. Festival, ki vstopa v četrto desetletje in še vedno premika meje.',
]);
get('/sl/project/12/project-twelve')
->assertSuccessful()
->assertSee('Ne za kogarkoli, ampak za Golden Drum. Festival, ki vstopa v četrto desetletje in še vedno premika meje.', false)
->assertDontSee('A modular project schema that can drive both the public page and the cPad editor preview.', false);
});

View File

@@ -0,0 +1,15 @@
<?php
namespace Tests\Fixtures\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class Block extends Component
{
public function render(): Closure|View|string
{
return static fn () => '';
}
}

49
tests/Pest.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
use Tests\TestCase;
/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "pest()" function to bind a different classes or traits.
|
*/
pest()->extend(TestCase::class)
// ->use(Illuminate\Foundation\Testing\RefreshDatabase::class)
->in('Feature');
/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| When you're writing tests, you often need to check that values meet certain conditions. The
| "expect()" function gives you access to a set of "expectations" methods that you can use
| to assert different things. Of course, you may extend the Expectation API at any time.
|
*/
expect()->extend('toBeOne', function () {
return $this->toBe(1);
});
/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/
function something()
{
// ..
}

10
tests/TestCase.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
//
}

View File

@@ -0,0 +1,5 @@
<?php
test('that true is true', function () {
expect(true)->toBeTrue();
});