mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
feat: add UI, add tests, refinements
This commit is contained in:
parent
56638b26e8
commit
ccba0f23f1
9 changed files with 446 additions and 25 deletions
|
|
@ -143,7 +143,13 @@ class PlaylistItem extends Model
|
|||
}
|
||||
|
||||
$pluginMarkups = [];
|
||||
$plugins = Plugin::whereIn('id', $this->getMashupPluginIds())->get();
|
||||
$pluginIds = $this->getMashupPluginIds();
|
||||
$plugins = Plugin::whereIn('id', $pluginIds)->get();
|
||||
|
||||
// Sort the collection to match plugin_ids order
|
||||
$plugins = $plugins->sortBy(function ($plugin) use ($pluginIds) {
|
||||
return array_search($plugin->id, $pluginIds);
|
||||
})->values();
|
||||
|
||||
foreach ($plugins as $index => $plugin) {
|
||||
$size = $this->getLayoutSize($index);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class DatabaseSeeder extends Seeder
|
|||
|
||||
$this->call([
|
||||
ExampleRecipesSeeder::class,
|
||||
MashupPocSeeder::class,
|
||||
// MashupPocSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
resources/views/flux/icon/mashup-1Tx2B.blade.php
Normal file
40
resources/views/flux/icon/mashup-1Tx2B.blade.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{{-- Credit: Lucide (https://lucide.dev) --}}
|
||||
|
||||
@props([
|
||||
'variant' => 'outline',
|
||||
])
|
||||
|
||||
@php
|
||||
$classes = Flux::classes('shrink-0')
|
||||
->add(match($variant) {
|
||||
'outline' => '[:where(&)]:size-6',
|
||||
'solid' => '[:where(&)]:size-6',
|
||||
'mini' => '[:where(&)]:size-5',
|
||||
'micro' => '[:where(&)]:size-4',
|
||||
});
|
||||
|
||||
$strokeWidth = match ($variant) {
|
||||
'outline' => 2,
|
||||
'mini' => 2.25,
|
||||
'micro' => 2.5,
|
||||
default => 2,
|
||||
};
|
||||
@endphp
|
||||
|
||||
<svg
|
||||
{{ $attributes->class($classes) }}
|
||||
data-flux-icon
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 76 44"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="{{ $strokeWidth }}"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
>
|
||||
<rect width="76" height="20.5" rx="3"/>
|
||||
<rect x="39.5" y="23.5" width="36.5" height="20.5" rx="3"/>
|
||||
<rect y="23.5" width="36.5" height="20.5" rx="3"/>
|
||||
</svg>
|
||||
40
resources/views/flux/icon/mashup-2Tx1B.blade.php
Normal file
40
resources/views/flux/icon/mashup-2Tx1B.blade.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{{-- Credit: Lucide (https://lucide.dev) --}}
|
||||
|
||||
@props([
|
||||
'variant' => 'outline',
|
||||
])
|
||||
|
||||
@php
|
||||
$classes = Flux::classes('shrink-0')
|
||||
->add(match($variant) {
|
||||
'outline' => '[:where(&)]:size-6',
|
||||
'solid' => '[:where(&)]:size-6',
|
||||
'mini' => '[:where(&)]:size-5',
|
||||
'micro' => '[:where(&)]:size-4',
|
||||
});
|
||||
|
||||
$strokeWidth = match ($variant) {
|
||||
'outline' => 2,
|
||||
'mini' => 2.25,
|
||||
'micro' => 2.5,
|
||||
default => 2,
|
||||
};
|
||||
@endphp
|
||||
|
||||
<svg
|
||||
{{ $attributes->class($classes) }}
|
||||
data-flux-icon
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 76 44"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="{{ $strokeWidth }}"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
>
|
||||
<rect y="23.5" width="76" height="20.5" rx="3"/>
|
||||
<rect x="39.5" width="36.5" height="20.5" rx="3"/>
|
||||
<rect width="36.5" height="20.5" rx="3"/>
|
||||
</svg>
|
||||
|
|
@ -580,7 +580,19 @@ new class extends Component {
|
|||
@foreach($playlist->items->sortBy('order') as $item)
|
||||
<tr data-flux-row>
|
||||
<td class="py-3 px-3 first:pl-0 last:pr-0 text-sm whitespace-nowrap text-zinc-500 dark:text-zinc-300">
|
||||
{{ $item->plugin->name }}
|
||||
@if($item->isMashup())
|
||||
<div class="flex items-center gap-2">
|
||||
<div>
|
||||
<div class="font-medium">{{ $item->getMashupName() }}</div>
|
||||
<div class="text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<flux:icon name="mashup-{{ $item->getMashupLayoutType() }}" class="inline-block pb-1" variant="mini" />
|
||||
{{ collect($item->getMashupPluginIds())->map(fn($id) => App\Models\Plugin::find($id)->name)->join(' | ') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="font-medium">{{ $item->plugin->name }}</div>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-3 px-3 first:pl-0 last:pr-0 text-sm whitespace-nowrap text-zinc-500 dark:text-zinc-300">
|
||||
<flux:switch wire:model.live="item.is_active"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ new class extends Component {
|
|||
public string $active_from = '';
|
||||
public string $active_until = '';
|
||||
public string $selected_playlist = '';
|
||||
public string $mashup_layout = 'full';
|
||||
public array $mashup_plugins = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
|
|
@ -117,11 +119,32 @@ new class extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
public function getAvailablePlugins()
|
||||
{
|
||||
return auth()->user()->plugins()->where('id', '!=', $this->plugin->id)->get();
|
||||
}
|
||||
|
||||
public function getRequiredPluginCount(): int
|
||||
{
|
||||
if ($this->mashup_layout === 'full') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return match ($this->mashup_layout) {
|
||||
'1Lx1R', '1Tx1B' => 2, // Left-Right or Top-Bottom split
|
||||
'1Lx2R', '2Lx1R', '2Tx1B', '1Tx2B' => 3, // Two on one side, one on other
|
||||
'2x2' => 4, // Quadrant
|
||||
default => 1,
|
||||
};
|
||||
}
|
||||
|
||||
public function addToPlaylist()
|
||||
{
|
||||
$this->validate([
|
||||
'checked_devices' => 'required|array|min:1',
|
||||
'selected_playlist' => 'required|string',
|
||||
'mashup_layout' => 'required|string',
|
||||
'mashup_plugins' => 'required_if:mashup_layout,1Lx1R,1Lx2R,2Lx1R,1Tx1B,2Tx1B,1Tx2B,2x2|array',
|
||||
]);
|
||||
|
||||
foreach ($this->checked_devices as $deviceId) {
|
||||
|
|
@ -146,14 +169,26 @@ new class extends Component {
|
|||
|
||||
// Add plugin to playlist
|
||||
$maxOrder = $playlist->items()->max('order') ?? 0;
|
||||
|
||||
if ($this->mashup_layout === 'full') {
|
||||
$playlist->items()->create([
|
||||
'plugin_id' => $this->plugin->id,
|
||||
'order' => $maxOrder + 1,
|
||||
]);
|
||||
|
||||
} else {
|
||||
// Create mashup
|
||||
$pluginIds = array_merge([$this->plugin->id], array_map('intval', $this->mashup_plugins));
|
||||
\App\Models\PlaylistItem::createMashup(
|
||||
$playlist,
|
||||
$this->mashup_layout,
|
||||
$pluginIds,
|
||||
$this->plugin->name . ' Mashup',
|
||||
$maxOrder + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->reset(['checked_devices', 'playlist_name', 'selected_weekdays', 'active_from', 'active_until', 'selected_playlist']);
|
||||
$this->reset(['checked_devices', 'playlist_name', 'selected_weekdays', 'active_from', 'active_until', 'selected_playlist', 'mashup_layout', 'mashup_plugins']);
|
||||
Flux::modal('add-to-playlist')->close();
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +216,8 @@ new class extends Component {
|
|||
public function renderLayoutWithTitleBar(): string
|
||||
{
|
||||
return <<<HTML
|
||||
<x-trmnl::view>
|
||||
@props(['size' => 'full'])
|
||||
<x-trmnl::view size="{{\$size}}">
|
||||
<x-trmnl::layout>
|
||||
<!-- ADD YOUR CONTENT HERE-->
|
||||
</x-trmnl::layout>
|
||||
|
|
@ -193,7 +229,8 @@ HTML;
|
|||
public function renderLayoutBlank(): string
|
||||
{
|
||||
return <<<HTML
|
||||
<x-trmnl::view>
|
||||
@props(['size' => 'full'])
|
||||
<x-trmnl::view size="{{\$size}}">
|
||||
<x-trmnl::layout>
|
||||
<!-- ADD YOUR CONTENT HERE-->
|
||||
</x-trmnl::layout>
|
||||
|
|
@ -270,15 +307,16 @@ HTML;
|
|||
</flux:button.group>
|
||||
</div>
|
||||
|
||||
<flux:modal name="add-to-playlist" class="md:w-96">
|
||||
<flux:modal name="add-to-playlist" class="min-w-2xl">
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<flux:heading size="lg">Add to Playlist</flux:heading>
|
||||
</div>
|
||||
|
||||
<form wire:submit="addToPlaylist">
|
||||
<div class="mb-4">
|
||||
<flux:checkbox.group wire:model.live="checked_devices" label="Select Devices">
|
||||
<flux:separator text="Device(s)" />
|
||||
<div class="mt-4 mb-4">
|
||||
<flux:checkbox.group wire:model.live="checked_devices">
|
||||
@foreach(auth()->user()->devices as $device)
|
||||
<flux:checkbox label="{{ $device->name }}" value="{{ $device->id }}"/>
|
||||
@endforeach
|
||||
|
|
@ -286,21 +324,22 @@ HTML;
|
|||
</div>
|
||||
|
||||
@if(count($checked_devices) === 1)
|
||||
<div class="mb-4">
|
||||
<flux:radio.group wire:model.live.debounce="selected_playlist" label="Select Playlist"
|
||||
variant="segmented">
|
||||
<flux:radio value="new" label="Create New"/>
|
||||
<flux:separator text="Playlist" />
|
||||
<div class="mt-4 mb-4">
|
||||
<flux:select wire:model.live.debounce="selected_playlist">
|
||||
<option value="">Select Playlist or Create New</option>
|
||||
@foreach($this->getDevicePlaylists($checked_devices[0]) as $playlist)
|
||||
<flux:radio value="{{ $playlist->id }}" label="{{ $playlist->name }}"/>
|
||||
<option value="{{ $playlist->id }}">{{ $playlist->name }}</option>
|
||||
@endforeach
|
||||
</flux:radio.group>
|
||||
<option value="new">Create New Playlist</option>
|
||||
</flux:select>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
@if($selected_playlist)
|
||||
@if($selected_playlist === 'new')
|
||||
<div class="mb-4">
|
||||
<div class="mt-4 mb-4">
|
||||
<flux:input label="Playlist Name" wire:model="playlist_name"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<flux:checkbox.group wire:model="selected_weekdays" label="Active Days (optional)">
|
||||
<flux:checkbox label="Monday" value="1"/>
|
||||
|
|
@ -321,6 +360,43 @@ HTML;
|
|||
<flux:input type="time" label="Active Until (optional)" wire:model="active_until"/>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<flux:separator text="Mashup" />
|
||||
<div class="mt-4 mb-4">
|
||||
<flux:radio.group wire:model.live="mashup_layout" variant="segmented">
|
||||
<flux:radio value="full" icon="mashup-1x1"/>
|
||||
<flux:radio value="1Lx1R" icon="mashup-1Lx1R"/>
|
||||
<flux:radio value="1Lx2R" icon="mashup-1Lx2R"/>
|
||||
<flux:radio value="2Lx1R" icon="mashup-2Lx1R"/>
|
||||
<flux:radio value="1Tx1B" icon="mashup-1Tx1B"/>
|
||||
<flux:radio value="2Tx1B" icon="mashup-2Tx1B"/>
|
||||
<flux:radio value="1Tx2B" icon="mashup-1Tx2B"/>
|
||||
<flux:radio value="2x2" icon="mashup-2x2"/>
|
||||
</flux:radio.group>
|
||||
</div>
|
||||
|
||||
@if($mashup_layout !== 'full')
|
||||
<div class="mb-4">
|
||||
<div class="text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Mashup Slots</div>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-24 text-sm text-zinc-500 dark:text-zinc-400">Main Plugin</div>
|
||||
<flux:input :value="$plugin->name" disabled class="flex-1"/>
|
||||
</div>
|
||||
@for($i = 0; $i < $this->getRequiredPluginCount() - 1; $i++)
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-24 text-sm text-zinc-500 dark:text-zinc-400">Plugin {{ $i + 2 }}:</div>
|
||||
<flux:select wire:model="mashup_plugins.{{ $i }}" class="flex-1">
|
||||
<option value="">Select a plugin...</option>
|
||||
@foreach($this->getAvailablePlugins() as $availablePlugin)
|
||||
<option value="{{ $availablePlugin->id }}">{{ $availablePlugin->name }}</option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
</div>
|
||||
@endfor
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<div class="flex">
|
||||
|
|
@ -462,8 +538,8 @@ HTML;
|
|||
</div>
|
||||
@else
|
||||
<div class="text-accent">
|
||||
<a href="#" wire:click="renderExample('layoutTitle')" class="text-xl">Layout with Title Bar</a> |
|
||||
<a href="#" wire:click="renderExample('layout')" class="text-xl">Blank Layout</a>
|
||||
<span class="pr-2">Getting started:</span><flux:button wire:click="renderExample('layoutTitle')" class="text-xl">Responsive Layout with Title Bar</flux:button>
|
||||
<flux:button wire:click="renderExample('layout')" class="text-xl">Responsive Layout</flux:button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<div class="item h--full">
|
||||
<div class="meta"></div>
|
||||
<div class="justify-center">
|
||||
<span class="value value--xxxlarge"
|
||||
<span class="value @if($size == 'full' || $size == 'half_horizontal') value--xxlarge @else value--medium @endif"
|
||||
data-fit-value="true">{{ $weatherEntity['attributes']['temperature'] }}</span>
|
||||
<span class="label">Temperature {{ $weatherEntity['attributes']['temperature_unit'] }}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -697,3 +697,63 @@ test('display endpoint updates last_refreshed_at timestamp for mirrored devices'
|
|||
expect($mirrorDevice->last_refreshed_at)->not->toBeNull()
|
||||
->and($mirrorDevice->last_refreshed_at->diffInSeconds(now()))->toBeLessThan(2);
|
||||
});
|
||||
|
||||
test('display endpoint handles mashup playlist items correctly', function () {
|
||||
// Create a device
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
'proxy_cloud' => false,
|
||||
]);
|
||||
|
||||
// Create a playlist
|
||||
$playlist = Playlist::factory()->create([
|
||||
'device_id' => $device->id,
|
||||
'name' => 'update_test',
|
||||
'is_active' => true,
|
||||
'weekdays' => null,
|
||||
'active_from' => null,
|
||||
'active_until' => null,
|
||||
]);
|
||||
|
||||
// Create three plugins for the mashup
|
||||
$plugin1 = Plugin::factory()->create([
|
||||
'name' => 'Plugin 1',
|
||||
'data_strategy' => 'webhook',
|
||||
'polling_url' => null,
|
||||
'data_stale_minutes' => 1,
|
||||
'render_markup_view' => 'trmnl',
|
||||
]);
|
||||
|
||||
$plugin2 = Plugin::factory()->create([
|
||||
'name' => 'Plugin 2',
|
||||
'data_strategy' => 'webhook',
|
||||
'polling_url' => null,
|
||||
'data_stale_minutes' => 1,
|
||||
'render_markup_view' => 'trmnl',
|
||||
]);
|
||||
|
||||
// Create a mashup playlist item with a 2Lx1R layout (2 plugins on left, 1 on right)
|
||||
$playlistItem = PlaylistItem::createMashup(
|
||||
$playlist,
|
||||
'1Lx1R',
|
||||
[$plugin1->id, $plugin2->id],
|
||||
'Test Mashup',
|
||||
1
|
||||
);
|
||||
|
||||
// Make request to display endpoint
|
||||
$response = $this->withHeaders([
|
||||
'id' => $device->mac_address,
|
||||
'access-token' => $device->api_key,
|
||||
'rssi' => -70,
|
||||
'battery_voltage' => 3.8,
|
||||
'fw-version' => '1.0.0',
|
||||
])->get('/api/display');
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
// Verify the playlist item was marked as displayed
|
||||
$playlistItem->refresh();
|
||||
expect($playlistItem->last_displayed_at)->not->toBeNull();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,3 +21,190 @@ test('playlist item belongs to plugin', function () {
|
|||
->toBeInstanceOf(Plugin::class)
|
||||
->id->toBe($plugin->id);
|
||||
});
|
||||
|
||||
test('playlist item can check if it is a mashup', function () {
|
||||
$plugin = Plugin::factory()->create();
|
||||
$regularItem = PlaylistItem::factory()->create([
|
||||
'mashup' => null,
|
||||
'plugin_id' => $plugin->id,
|
||||
]);
|
||||
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
'plugin_id' => $plugin1->id,
|
||||
'mashup' => [
|
||||
'mashup_layout' => '1Lx1R',
|
||||
'mashup_name' => 'Test Mashup',
|
||||
'plugin_ids' => [$plugin1->id, $plugin2->id],
|
||||
],
|
||||
]);
|
||||
|
||||
expect($regularItem->isMashup())->toBeFalse()
|
||||
->and($mashupItem->isMashup())->toBeTrue();
|
||||
});
|
||||
|
||||
test('playlist item can get mashup name', function () {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
'plugin_id' => $plugin1->id,
|
||||
'mashup' => [
|
||||
'mashup_layout' => '1Lx1R',
|
||||
'mashup_name' => 'Test Mashup',
|
||||
'plugin_ids' => [$plugin1->id, $plugin2->id],
|
||||
],
|
||||
]);
|
||||
|
||||
expect($mashupItem->getMashupName())->toBe('Test Mashup');
|
||||
});
|
||||
|
||||
test('playlist item can get mashup layout type', function () {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
'plugin_id' => $plugin1->id,
|
||||
'mashup' => [
|
||||
'mashup_layout' => '1Lx1R',
|
||||
'mashup_name' => 'Test Mashup',
|
||||
'plugin_ids' => [$plugin1->id, $plugin2->id],
|
||||
],
|
||||
]);
|
||||
|
||||
expect($mashupItem->getMashupLayoutType())->toBe('1Lx1R');
|
||||
});
|
||||
|
||||
test('playlist item can get mashup plugin ids', function () {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
'plugin_id' => $plugin1->id,
|
||||
'mashup' => [
|
||||
'mashup_layout' => '1Lx1R',
|
||||
'mashup_name' => 'Test Mashup',
|
||||
'plugin_ids' => [$plugin1->id, $plugin2->id],
|
||||
],
|
||||
]);
|
||||
|
||||
expect($mashupItem->getMashupPluginIds())->toBe([$plugin1->id, $plugin2->id]);
|
||||
});
|
||||
|
||||
test('playlist item can get required plugin count for different layouts', function () {
|
||||
$layouts = [
|
||||
'1Lx1R' => 2,
|
||||
'1Tx1B' => 2,
|
||||
'1Lx2R' => 3,
|
||||
'2Lx1R' => 3,
|
||||
'2Tx1B' => 3,
|
||||
'1Tx2B' => 3,
|
||||
'2x2' => 4,
|
||||
];
|
||||
|
||||
foreach ($layouts as $layout => $expectedCount) {
|
||||
$plugins = Plugin::factory()->count($expectedCount)->create();
|
||||
$pluginIds = $plugins->pluck('id')->toArray();
|
||||
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
'plugin_id' => $pluginIds[0],
|
||||
'mashup' => [
|
||||
'mashup_layout' => $layout,
|
||||
'mashup_name' => 'Test Mashup',
|
||||
'plugin_ids' => $pluginIds,
|
||||
],
|
||||
]);
|
||||
|
||||
expect($mashupItem->getRequiredPluginCount())->toBe($expectedCount);
|
||||
}
|
||||
});
|
||||
|
||||
test('playlist item can get layout type', function () {
|
||||
$layoutTypes = [
|
||||
'1Lx1R' => 'vertical',
|
||||
'1Lx2R' => 'vertical',
|
||||
'2Lx1R' => 'vertical',
|
||||
'1Tx1B' => 'horizontal',
|
||||
'2Tx1B' => 'horizontal',
|
||||
'1Tx2B' => 'horizontal',
|
||||
'2x2' => 'grid',
|
||||
];
|
||||
|
||||
foreach ($layoutTypes as $layout => $expectedType) {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
'plugin_id' => $plugin1->id,
|
||||
'mashup' => [
|
||||
'mashup_layout' => $layout,
|
||||
'mashup_name' => 'Test Mashup',
|
||||
'plugin_ids' => [$plugin1->id, $plugin2->id],
|
||||
],
|
||||
]);
|
||||
|
||||
expect($mashupItem->getLayoutType())->toBe($expectedType);
|
||||
}
|
||||
});
|
||||
|
||||
test('playlist item can get layout size for different positions', function () {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$plugin3 = Plugin::factory()->create();
|
||||
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
'plugin_id' => $plugin1->id,
|
||||
'mashup' => [
|
||||
'mashup_layout' => '2Lx1R',
|
||||
'mashup_name' => 'Test Mashup',
|
||||
'plugin_ids' => [$plugin1->id, $plugin2->id, $plugin3->id],
|
||||
],
|
||||
]);
|
||||
|
||||
expect($mashupItem->getLayoutSize(0))->toBe('quadrant')
|
||||
->and($mashupItem->getLayoutSize(1))->toBe('quadrant')
|
||||
->and($mashupItem->getLayoutSize(2))->toBe('half_vertical');
|
||||
});
|
||||
|
||||
test('playlist item can get available layouts', function () {
|
||||
$layouts = PlaylistItem::getAvailableLayouts();
|
||||
|
||||
expect($layouts)->toBeArray()
|
||||
->toHaveKeys(['1Lx1R', '1Lx2R', '2Lx1R', '1Tx1B', '2Tx1B', '1Tx2B', '2x2'])
|
||||
->and($layouts['1Lx1R'])->toBe('1 Left - 1 Right (2 plugins)');
|
||||
});
|
||||
|
||||
test('playlist item can get required plugin count for layout', function () {
|
||||
$layouts = [
|
||||
'1Lx1R' => 2,
|
||||
'1Tx1B' => 2,
|
||||
'1Lx2R' => 3,
|
||||
'2Lx1R' => 3,
|
||||
'2Tx1B' => 3,
|
||||
'1Tx2B' => 3,
|
||||
'2x2' => 4,
|
||||
];
|
||||
|
||||
foreach ($layouts as $layout => $expectedCount) {
|
||||
expect(PlaylistItem::getRequiredPluginCountForLayout($layout))->toBe($expectedCount);
|
||||
}
|
||||
});
|
||||
|
||||
test('playlist item can create mashup', function () {
|
||||
$playlist = Playlist::factory()->create();
|
||||
$plugins = Plugin::factory()->count(3)->create();
|
||||
$pluginIds = $plugins->pluck('id')->toArray();
|
||||
$layout = '2Lx1R';
|
||||
$name = 'Test Mashup';
|
||||
$order = 1;
|
||||
|
||||
$mashup = PlaylistItem::createMashup($playlist, $layout, $pluginIds, $name, $order);
|
||||
|
||||
expect($mashup)
|
||||
->toBeInstanceOf(PlaylistItem::class)
|
||||
->playlist_id->toBe($playlist->id)
|
||||
->plugin_id->toBe($pluginIds[0])
|
||||
->mashup->toHaveKeys(['mashup_layout', 'mashup_name', 'plugin_ids'])
|
||||
->mashup->mashup_layout->toBe($layout)
|
||||
->mashup->mashup_name->toBe($name)
|
||||
->mashup->plugin_ids->toBe($pluginIds)
|
||||
->is_active->toBeTrue()
|
||||
->order->toBe($order);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue