mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
This commit is contained in:
parent
c67a182cf2
commit
b4b6286172
89 changed files with 672 additions and 666 deletions
|
|
@ -23,7 +23,7 @@ class FirmwareCheckCommand extends Command
|
|||
);
|
||||
|
||||
$latestFirmware = Firmware::getLatest();
|
||||
if ($latestFirmware) {
|
||||
if ($latestFirmware instanceof Firmware) {
|
||||
table(
|
||||
rows: [
|
||||
['Latest Version', $latestFirmware->version_tag],
|
||||
|
|
|
|||
|
|
@ -42,15 +42,14 @@ class FirmwareUpdateCommand extends Command
|
|||
label: 'Which devices should be updated?',
|
||||
options: [
|
||||
'all' => 'ALL Devices',
|
||||
...Device::all()->mapWithKeys(function ($device) {
|
||||
...Device::all()->mapWithKeys(fn ($device): array =>
|
||||
// without _ returns index
|
||||
return ["_$device->id" => "$device->name (Current version: $device->last_firmware_version)"];
|
||||
})->toArray(),
|
||||
["_$device->id" => "$device->name (Current version: $device->last_firmware_version)"])->toArray(),
|
||||
],
|
||||
scroll: 10
|
||||
);
|
||||
|
||||
if (empty($devices)) {
|
||||
if ($devices === []) {
|
||||
$this->error('No devices selected. Aborting.');
|
||||
|
||||
return;
|
||||
|
|
@ -59,9 +58,7 @@ class FirmwareUpdateCommand extends Command
|
|||
if (in_array('all', $devices)) {
|
||||
$devices = Device::pluck('id')->toArray();
|
||||
} else {
|
||||
$devices = array_map(function ($selected) {
|
||||
return (int) str_replace('_', '', $selected);
|
||||
}, $devices);
|
||||
$devices = array_map(fn ($selected): int => (int) str_replace('_', '', $selected), $devices);
|
||||
}
|
||||
|
||||
foreach ($devices as $deviceId) {
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@ class MashupCreateCommand extends Command
|
|||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
// Select device
|
||||
$device = $this->selectDevice();
|
||||
if (! $device) {
|
||||
if (! $device instanceof Device) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Select playlist
|
||||
$playlist = $this->selectPlaylist($device);
|
||||
if (! $playlist) {
|
||||
if (! $playlist instanceof Playlist) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ class MashupCreateCommand extends Command
|
|||
|
||||
$deviceId = $this->choice(
|
||||
'Select a device',
|
||||
$devices->mapWithKeys(fn ($device) => [$device->id => $device->name])->toArray()
|
||||
$devices->mapWithKeys(fn ($device): array => [$device->id => $device->name])->toArray()
|
||||
);
|
||||
|
||||
return $devices->firstWhere('id', $deviceId);
|
||||
|
|
@ -105,7 +105,7 @@ class MashupCreateCommand extends Command
|
|||
|
||||
$playlistId = $this->choice(
|
||||
'Select a playlist',
|
||||
$playlists->mapWithKeys(fn (Playlist $playlist) => [$playlist->id => $playlist->name])->toArray()
|
||||
$playlists->mapWithKeys(fn (Playlist $playlist): array => [$playlist->id => $playlist->name])->toArray()
|
||||
);
|
||||
|
||||
return $playlists->firstWhere('id', $playlistId);
|
||||
|
|
@ -123,13 +123,13 @@ class MashupCreateCommand extends Command
|
|||
{
|
||||
$name = $this->ask('Enter a name for this mashup', 'Mashup');
|
||||
|
||||
if (mb_strlen($name) < 2) {
|
||||
if (mb_strlen((string) $name) < 2) {
|
||||
$this->error('The name must be at least 2 characters.');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mb_strlen($name) > 50) {
|
||||
if (mb_strlen((string) $name) > 50) {
|
||||
$this->error('The name must not exceed 50 characters.');
|
||||
|
||||
return null;
|
||||
|
|
@ -150,7 +150,7 @@ class MashupCreateCommand extends Command
|
|||
}
|
||||
|
||||
$selectedPlugins = collect();
|
||||
$availablePlugins = $plugins->mapWithKeys(fn ($plugin) => [$plugin->id => $plugin->name])->toArray();
|
||||
$availablePlugins = $plugins->mapWithKeys(fn ($plugin): array => [$plugin->id => $plugin->name])->toArray();
|
||||
|
||||
for ($i = 0; $i < $requiredCount; ++$i) {
|
||||
$position = match ($i) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class OidcTestCommand extends Command
|
|||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
$this->info('Testing OIDC Configuration...');
|
||||
$this->newLine();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class ScreenGeneratorCommand extends Command
|
|||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
$deviceId = $this->argument('deviceId');
|
||||
$view = $this->argument('view');
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class CleanupDeviceLogsJob implements ShouldQueue
|
|||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
Device::each(function ($device) {
|
||||
Device::each(function ($device): void {
|
||||
$keepIds = $device->logs()->latest('device_timestamp')->take(50)->pluck('id');
|
||||
|
||||
// Delete all other logs for this device
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class FetchProxyCloudResponses implements ShouldQueue
|
|||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
Device::where('proxy_cloud', true)->each(function ($device) {
|
||||
Device::where('proxy_cloud', true)->each(function ($device): void {
|
||||
if (! $device->getNextPlaylistItem()) {
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
|
|
|
|||
|
|
@ -18,12 +18,7 @@ class FirmwareDownloadJob implements ShouldQueue
|
|||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
private Firmware $firmware;
|
||||
|
||||
public function __construct(Firmware $firmware)
|
||||
{
|
||||
$this->firmware = $firmware;
|
||||
}
|
||||
public function __construct(private Firmware $firmware) {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,12 +17,7 @@ class FirmwarePollJob implements ShouldQueue
|
|||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
private bool $download;
|
||||
|
||||
public function __construct(bool $download = false)
|
||||
{
|
||||
$this->download = $download;
|
||||
}
|
||||
public function __construct(private bool $download = false) {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ class NotifyDeviceBatteryLowJob implements ShouldQueue
|
|||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public function __construct() {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$devices = Device::all();
|
||||
|
|
@ -32,9 +30,11 @@ class NotifyDeviceBatteryLowJob implements ShouldQueue
|
|||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if battery is not low or notification was already sent
|
||||
if ($batteryPercent > $batteryThreshold || $device->battery_notification_sent) {
|
||||
if ($batteryPercent > $batteryThreshold) {
|
||||
continue;
|
||||
}
|
||||
if ($device->battery_notification_sent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class Data extends FiltersProvider
|
|||
*/
|
||||
public function sample(array $array): mixed
|
||||
{
|
||||
if (empty($array)) {
|
||||
if ($array === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,15 +40,11 @@ class Numbers extends FiltersProvider
|
|||
$currency = 'GBP';
|
||||
}
|
||||
|
||||
if ($delimiter === '.' && $separator === ',') {
|
||||
$locale = 'de';
|
||||
} else {
|
||||
$locale = 'en';
|
||||
}
|
||||
$locale = $delimiter === '.' && $separator === ',' ? 'de' : 'en';
|
||||
|
||||
// 2 decimal places for floats, 0 for integers
|
||||
$decimal = is_float($value + 0) ? 2 : 0;
|
||||
|
||||
return Number::currency($value, in: $currency, precision: $decimal, locale: $locale);
|
||||
return Number::currency($value, in: $currency, locale: $locale, precision: $decimal);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class Uniqueness extends FiltersProvider
|
|||
$randomString = '';
|
||||
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$randomString .= $characters[rand(0, mb_strlen($characters) - 1)];
|
||||
$randomString .= $characters[random_int(0, mb_strlen($characters) - 1)];
|
||||
}
|
||||
|
||||
return $randomString;
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ class DeviceAutoJoin extends Component
|
|||
|
||||
public bool $isFirstUser = false;
|
||||
|
||||
public function mount()
|
||||
public function mount(): void
|
||||
{
|
||||
$this->deviceAutojoin = auth()->user()->assign_new_devices;
|
||||
$this->isFirstUser = auth()->user()->id === 1;
|
||||
|
||||
}
|
||||
|
||||
public function updating($name, $value)
|
||||
public function updating($name, $value): void
|
||||
{
|
||||
$this->validate([
|
||||
'deviceAutojoin' => 'boolean',
|
||||
|
|
@ -30,7 +30,7 @@ class DeviceAutoJoin extends Component
|
|||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
public function render(): \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
{
|
||||
return view('livewire.actions.device-auto-join');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class Logout
|
|||
/**
|
||||
* Log the current user out of the application.
|
||||
*/
|
||||
public function __invoke()
|
||||
public function __invoke(): \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use Livewire\Component;
|
|||
|
||||
class DeviceDashboard extends Component
|
||||
{
|
||||
public function render()
|
||||
public function render(): \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
{
|
||||
return view('livewire.device-dashboard', ['devices' => auth()->user()->devices()->paginate(10)]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class Device extends Model
|
|||
'pause_until' => 'datetime',
|
||||
];
|
||||
|
||||
public function getBatteryPercentAttribute()
|
||||
public function getBatteryPercentAttribute(): int|float
|
||||
{
|
||||
$volts = $this->last_battery_voltage;
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ class Device extends Model
|
|||
return round($voltage, 2);
|
||||
}
|
||||
|
||||
public function getWifiStrengthAttribute()
|
||||
public function getWifiStrengthAttribute(): int
|
||||
{
|
||||
$rssi = $this->last_rssi_level;
|
||||
if ($rssi >= 0) {
|
||||
|
|
@ -106,11 +106,7 @@ class Device extends Model
|
|||
return true;
|
||||
}
|
||||
|
||||
if ($this->proxy_cloud_response && $this->proxy_cloud_response['update_firmware']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $this->proxy_cloud_response && $this->proxy_cloud_response['update_firmware'];
|
||||
}
|
||||
|
||||
public function getFirmwareUrlAttribute(): ?string
|
||||
|
|
@ -231,7 +227,7 @@ class Device extends Model
|
|||
return false;
|
||||
}
|
||||
|
||||
$now = $now ? Carbon::instance($now) : now();
|
||||
$now = $now instanceof DateTimeInterface ? Carbon::instance($now) : now();
|
||||
|
||||
// Handle overnight ranges (e.g. 22:00 to 06:00)
|
||||
return $this->sleep_mode_from < $this->sleep_mode_to
|
||||
|
|
@ -245,7 +241,7 @@ class Device extends Model
|
|||
return null;
|
||||
}
|
||||
|
||||
$now = $now ? Carbon::instance($now) : now();
|
||||
$now = $now instanceof DateTimeInterface ? Carbon::instance($now) : now();
|
||||
$from = $this->sleep_mode_from;
|
||||
$to = $this->sleep_mode_to;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,11 +38,9 @@ class Playlist extends Model
|
|||
}
|
||||
|
||||
// Check weekday
|
||||
if ($this->weekdays !== null) {
|
||||
if (! in_array(now()->dayOfWeek, $this->weekdays)) {
|
||||
if ($this->weekdays !== null && ! in_array(now()->dayOfWeek, $this->weekdays)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->active_from !== null && $this->active_until !== null) {
|
||||
$now = now();
|
||||
|
|
@ -53,11 +51,9 @@ class Playlist extends Model
|
|||
if ($now >= $this->active_from || $now <= $this->active_until) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($now >= $this->active_from && $now <= $this->active_until) {
|
||||
} elseif ($now >= $this->active_from && $now <= $this->active_until) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,9 +153,7 @@ class PlaylistItem extends Model
|
|||
$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();
|
||||
$plugins = $plugins->sortBy(fn ($plugin): int|string|false => array_search($plugin->id, $pluginIds))->values();
|
||||
|
||||
foreach ($plugins as $index => $plugin) {
|
||||
$size = $this->getLayoutSize($index);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class Plugin extends Model
|
|||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($model) {
|
||||
static::creating(function ($model): void {
|
||||
if (empty($model->uuid)) {
|
||||
$model->uuid = Str::uuid();
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ class Plugin extends Model
|
|||
$currentValue = $this->configuration[$fieldKey] ?? null;
|
||||
|
||||
// If the field has a default value and no current value is set, it's not missing
|
||||
if (($currentValue === null || $currentValue === '' || (is_array($currentValue) && empty($currentValue))) && ! isset($field['default'])) {
|
||||
if (($currentValue === null || $currentValue === '' || ($currentValue === [])) && ! isset($field['default'])) {
|
||||
return true; // Found a required field that is not set and has no default
|
||||
}
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ class Plugin extends Model
|
|||
// Split URLs by newline and filter out empty lines
|
||||
$urls = array_filter(
|
||||
array_map('trim', explode("\n", $this->polling_url)),
|
||||
fn ($url) => ! empty($url)
|
||||
fn ($url): bool => ! empty($url)
|
||||
);
|
||||
|
||||
// If only one URL, use the original logic without nesting
|
||||
|
|
@ -237,7 +237,7 @@ class Plugin extends Model
|
|||
// Converts to: {% assign temp_filtered = collection | filter: "key", "value" %}{% for item in temp_filtered %}
|
||||
$template = preg_replace_callback(
|
||||
'/{%\s*for\s+(\w+)\s+in\s+([^|%}]+)\s*\|\s*([^%}]+)%}/',
|
||||
function ($matches) {
|
||||
function ($matches): string {
|
||||
$variableName = mb_trim($matches[1]);
|
||||
$collection = mb_trim($matches[2]);
|
||||
$filter = mb_trim($matches[3]);
|
||||
|
|
@ -245,7 +245,7 @@ class Plugin extends Model
|
|||
|
||||
return "{% assign {$tempVarName} = {$collection} | {$filter} %}{% for {$variableName} in {$tempVarName} %}";
|
||||
},
|
||||
$template
|
||||
(string) $template
|
||||
);
|
||||
|
||||
return $template;
|
||||
|
|
|
|||
|
|
@ -13,15 +13,10 @@ class BatteryLow extends Notification
|
|||
{
|
||||
use Queueable;
|
||||
|
||||
private Device $device;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*/
|
||||
public function __construct(Device $device)
|
||||
{
|
||||
$this->device = $device;
|
||||
}
|
||||
public function __construct(private Device $device) {}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
|
|
|
|||
|
|
@ -11,13 +11,7 @@ use Illuminate\Support\Arr;
|
|||
|
||||
class WebhookChannel extends Notification
|
||||
{
|
||||
/** @var Client */
|
||||
protected $client;
|
||||
|
||||
public function __construct(Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
public function __construct(protected Client $client) {}
|
||||
|
||||
/**
|
||||
* Send the given notification.
|
||||
|
|
|
|||
|
|
@ -13,13 +13,6 @@ final class WebhookMessage extends Notification
|
|||
*/
|
||||
private $query;
|
||||
|
||||
/**
|
||||
* The POST data of the Webhook request.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* The headers to send with the request.
|
||||
*
|
||||
|
|
@ -36,9 +29,8 @@ final class WebhookMessage extends Notification
|
|||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @return static
|
||||
*/
|
||||
public static function create($data = '')
|
||||
public static function create($data = ''): self
|
||||
{
|
||||
return new self($data);
|
||||
}
|
||||
|
|
@ -46,10 +38,12 @@ final class WebhookMessage extends Notification
|
|||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function __construct($data = '')
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
public function __construct(
|
||||
/**
|
||||
* The POST data of the Webhook request.
|
||||
*/
|
||||
private $data = ''
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Set the Webhook parameters to be URL encoded.
|
||||
|
|
@ -57,7 +51,7 @@ final class WebhookMessage extends Notification
|
|||
* @param mixed $query
|
||||
* @return $this
|
||||
*/
|
||||
public function query($query)
|
||||
public function query($query): self
|
||||
{
|
||||
$this->query = $query;
|
||||
|
||||
|
|
@ -70,7 +64,7 @@ final class WebhookMessage extends Notification
|
|||
* @param mixed $data
|
||||
* @return $this
|
||||
*/
|
||||
public function data($data)
|
||||
public function data($data): self
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
|
|
@ -84,7 +78,7 @@ final class WebhookMessage extends Notification
|
|||
* @param string $value
|
||||
* @return $this
|
||||
*/
|
||||
public function header($name, $value)
|
||||
public function header($name, $value): self
|
||||
{
|
||||
$this->headers[$name] = $value;
|
||||
|
||||
|
|
@ -97,7 +91,7 @@ final class WebhookMessage extends Notification
|
|||
* @param string $userAgent
|
||||
* @return $this
|
||||
*/
|
||||
public function userAgent($userAgent)
|
||||
public function userAgent($userAgent): self
|
||||
{
|
||||
$this->headers['User-Agent'] = $userAgent;
|
||||
|
||||
|
|
@ -109,17 +103,14 @@ final class WebhookMessage extends Notification
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function verify($value = true)
|
||||
public function verify($value = true): self
|
||||
{
|
||||
$this->verify = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'query' => $this->query,
|
||||
|
|
|
|||
|
|
@ -33,17 +33,19 @@ class AppServiceProvider extends ServiceProvider
|
|||
|
||||
$http = clone $this;
|
||||
$http->server->set('HTTPS', 'off');
|
||||
if (URL::hasValidSignature($https, $absolute, $ignoreQuery)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return URL::hasValidSignature($https, $absolute, $ignoreQuery)
|
||||
|| URL::hasValidSignature($http, $absolute, $ignoreQuery);
|
||||
return URL::hasValidSignature($http, $absolute, $ignoreQuery);
|
||||
});
|
||||
|
||||
// Register OIDC provider with Socialite
|
||||
Socialite::extend('oidc', function ($app) {
|
||||
$config = $app['config']['services.oidc'] ?? [];
|
||||
Socialite::extend('oidc', function (\Illuminate\Contracts\Foundation\Application $app): OidcProvider {
|
||||
$config = $app->make('config')->get('services.oidc', []);
|
||||
|
||||
return new OidcProvider(
|
||||
$app['request'],
|
||||
$app->make(Request::class),
|
||||
$config['client_id'] ?? null,
|
||||
$config['client_secret'] ?? null,
|
||||
$config['redirect'] ?? null,
|
||||
|
|
|
|||
|
|
@ -233,14 +233,14 @@ class ImageGenerationService
|
|||
if ($plugin?->id) {
|
||||
// Check if any devices have custom dimensions or use non-standard DeviceModels
|
||||
$hasCustomDimensions = Device::query()
|
||||
->where(function ($query) {
|
||||
->where(function ($query): void {
|
||||
$query->where('width', '!=', 800)
|
||||
->orWhere('height', '!=', 480)
|
||||
->orWhere('rotate', '!=', 0);
|
||||
})
|
||||
->orWhereHas('deviceModel', function ($query) {
|
||||
->orWhereHas('deviceModel', function ($query): void {
|
||||
// Only allow caching if all device models have standard dimensions (800x480, rotation=0)
|
||||
$query->where(function ($subQuery) {
|
||||
$query->where(function ($subQuery): void {
|
||||
$subQuery->where('width', '!=', 800)
|
||||
->orWhere('height', '!=', 480)
|
||||
->orWhere('rotation', '!=', 0);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class OidcProvider extends AbstractProvider implements ProviderInterface
|
|||
/**
|
||||
* Create a new provider instance.
|
||||
*/
|
||||
public function __construct($request, $clientId, $clientSecret, $redirectUrl, $scopes = [], $guzzle = [])
|
||||
public function __construct(\Illuminate\Http\Request $request, $clientId, $clientSecret, $redirectUrl, $scopes = [], $guzzle = [])
|
||||
{
|
||||
parent::__construct($request, $clientId, $clientSecret, $redirectUrl, $guzzle);
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ class OidcProvider extends AbstractProvider implements ProviderInterface
|
|||
}
|
||||
|
||||
// Handle both full well-known URL and base URL
|
||||
if (str_ends_with($endpoint, '/.well-known/openid-configuration')) {
|
||||
if (str_ends_with((string) $endpoint, '/.well-known/openid-configuration')) {
|
||||
$this->baseUrl = str_replace('/.well-known/openid-configuration', '', $endpoint);
|
||||
} else {
|
||||
$this->baseUrl = mb_rtrim($endpoint, '/');
|
||||
|
|
@ -73,7 +73,7 @@ class OidcProvider extends AbstractProvider implements ProviderInterface
|
|||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Failed to load OIDC configuration: '.$e->getMessage());
|
||||
throw new Exception('Failed to load OIDC configuration: '.$e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,44 +47,33 @@ class PluginExportService
|
|||
$tempDirName = 'temp/'.uniqid('plugin_export_', true);
|
||||
Storage::makeDirectory($tempDirName);
|
||||
$tempDir = Storage::path($tempDirName);
|
||||
|
||||
try {
|
||||
// Generate settings.yml content
|
||||
$settings = $this->generateSettingsYaml($plugin);
|
||||
$settingsYaml = Yaml::dump($settings, 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
|
||||
File::put($tempDir.'/settings.yml', $settingsYaml);
|
||||
|
||||
// Generate full template content
|
||||
$fullTemplate = $this->generateFullTemplate($plugin);
|
||||
$extension = $plugin->markup_language === 'liquid' ? 'liquid' : 'blade.php';
|
||||
File::put($tempDir.'/full.'.$extension, $fullTemplate);
|
||||
|
||||
// Generate shared.liquid if needed (for liquid templates)
|
||||
if ($plugin->markup_language === 'liquid') {
|
||||
$sharedTemplate = $this->generateSharedTemplate($plugin);
|
||||
$sharedTemplate = $this->generateSharedTemplate();
|
||||
if ($sharedTemplate) {
|
||||
File::put($tempDir.'/shared.liquid', $sharedTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
// Create ZIP file
|
||||
$zipPath = $tempDir.'/plugin_'.$plugin->trmnlp_id.'.zip';
|
||||
$zip = new ZipArchive();
|
||||
|
||||
if ($zip->open($zipPath, ZipArchive::CREATE) !== true) {
|
||||
throw new Exception('Could not create ZIP file.');
|
||||
}
|
||||
|
||||
// Add files directly to ZIP root
|
||||
$this->addDirectoryToZip($zip, $tempDir, '');
|
||||
$zip->close();
|
||||
|
||||
// Return the ZIP file as a download response
|
||||
return response()->download($zipPath, 'plugin_'.$plugin->trmnlp_id.'.zip');
|
||||
|
||||
} catch (Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -150,7 +139,7 @@ class PluginExportService
|
|||
/**
|
||||
* Generate the shared template content (for liquid templates)
|
||||
*/
|
||||
private function generateSharedTemplate(Plugin $plugin)
|
||||
private function generateSharedTemplate(): null
|
||||
{
|
||||
// For now, we don't have a way to store shared templates separately
|
||||
// TODO - add support for shared templates
|
||||
|
|
@ -170,14 +159,10 @@ class PluginExportService
|
|||
foreach ($files as $file) {
|
||||
if (! $file->isDir()) {
|
||||
$filePath = $file->getRealPath();
|
||||
$fileName = basename($filePath);
|
||||
$fileName = basename((string) $filePath);
|
||||
|
||||
// For root directory, just use the filename
|
||||
if ($zipPath === '') {
|
||||
$relativePath = $fileName;
|
||||
} else {
|
||||
$relativePath = $zipPath.'/'.mb_substr($filePath, mb_strlen($dirPath) + 1);
|
||||
}
|
||||
$relativePath = $zipPath === '' ? $fileName : $zipPath.'/'.mb_substr((string) $filePath, mb_strlen($dirPath) + 1);
|
||||
|
||||
$zip->addFile($filePath, $relativePath);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class PluginImportService
|
|||
|
||||
// Check if the file ends with .liquid to set markup language
|
||||
$markupLanguage = 'blade';
|
||||
if (pathinfo($filePaths['fullLiquidPath'], PATHINFO_EXTENSION) === 'liquid') {
|
||||
if (pathinfo((string) $filePaths['fullLiquidPath'], PATHINFO_EXTENSION) === 'liquid') {
|
||||
$markupLanguage = 'liquid';
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ class PluginImportService
|
|||
|
||||
// Check if the file ends with .liquid to set markup language
|
||||
$markupLanguage = 'blade';
|
||||
if (pathinfo($filePaths['fullLiquidPath'], PATHINFO_EXTENSION) === 'liquid') {
|
||||
if (pathinfo((string) $filePaths['fullLiquidPath'], PATHINFO_EXTENSION) === 'liquid') {
|
||||
$markupLanguage = 'liquid';
|
||||
}
|
||||
|
||||
|
|
@ -352,7 +352,7 @@ class PluginImportService
|
|||
// check if they're in the root of the ZIP or in a subfolder
|
||||
if ($settingsYamlPath && $fullLiquidPath) {
|
||||
// If the files are in the root of the ZIP, create a src folder and move them there
|
||||
$srcDir = dirname($settingsYamlPath);
|
||||
$srcDir = dirname((string) $settingsYamlPath);
|
||||
|
||||
// If the parent directory is not named 'src', create a src directory
|
||||
if (basename($srcDir) !== 'src') {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@
|
|||
"nunomaduro/collision": "^8.6",
|
||||
"pestphp/pest": "^4.0",
|
||||
"pestphp/pest-plugin-drift": "^4.0",
|
||||
"pestphp/pest-plugin-laravel": "^4.0"
|
||||
"pestphp/pest-plugin-laravel": "^4.0",
|
||||
"rector/rector": "^2.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
@ -75,7 +76,8 @@
|
|||
"test-coverage": "vendor/bin/pest --coverage",
|
||||
"format": "vendor/bin/pint",
|
||||
"analyse": "vendor/bin/phpstan analyse",
|
||||
"analyze": "vendor/bin/phpstan analyse"
|
||||
"analyze": "vendor/bin/phpstan analyse",
|
||||
"rector": "vendor/bin/rector process"
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
|
|
|
|||
62
composer.lock
generated
62
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "7d12a2e6d66b2e82c6d96d6a0c5366f0",
|
||||
"content-hash": "9122624c0df3b24bc94c7c866aa4e17c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-crt-php",
|
||||
|
|
@ -10546,6 +10546,66 @@
|
|||
],
|
||||
"time": "2025-09-03T06:25:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rector/rector",
|
||||
"version": "2.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rectorphp/rector.git",
|
||||
"reference": "c34cc07c4698f007a20dc5c99ff820089ae413ce"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/c34cc07c4698f007a20dc5c99ff820089ae413ce",
|
||||
"reference": "c34cc07c4698f007a20dc5c99ff820089ae413ce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"phpstan/phpstan": "^2.1.18"
|
||||
},
|
||||
"conflict": {
|
||||
"rector/rector-doctrine": "*",
|
||||
"rector/rector-downgrade-php": "*",
|
||||
"rector/rector-phpunit": "*",
|
||||
"rector/rector-symfony": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "To manipulate phpunit.xml via the custom-rule command"
|
||||
},
|
||||
"bin": [
|
||||
"bin/rector"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Instant Upgrade and Automated Refactoring of any PHP code",
|
||||
"homepage": "https://getrector.com/",
|
||||
"keywords": [
|
||||
"automation",
|
||||
"dev",
|
||||
"migration",
|
||||
"refactoring"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/rectorphp/rector/issues",
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.1.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/tomasvotruba",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-10T11:13:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
"version": "4.2.0",
|
||||
|
|
|
|||
26
rector.php
Normal file
26
rector.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Set\ValueObject\LevelSetList;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
|
||||
return static function (RectorConfig $rectorConfig): void {
|
||||
$rectorConfig->paths([
|
||||
__DIR__.'/app',
|
||||
__DIR__.'/tests',
|
||||
]);
|
||||
|
||||
$rectorConfig->sets([
|
||||
LevelSetList::UP_TO_PHP_82,
|
||||
SetList::CODE_QUALITY,
|
||||
SetList::DEAD_CODE,
|
||||
SetList::EARLY_RETURN,
|
||||
SetList::TYPE_DECLARATION,
|
||||
]);
|
||||
|
||||
$rectorConfig->skip([
|
||||
// Skip any specific rules if needed
|
||||
]);
|
||||
};
|
||||
|
|
@ -14,13 +14,13 @@ use Laravel\Sanctum\Sanctum;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
TrmnlPipeline::fake();
|
||||
Storage::fake('public');
|
||||
Storage::disk('public')->makeDirectory('/images/generated');
|
||||
});
|
||||
|
||||
test('device can fetch display data with valid credentials', function () {
|
||||
test('device can fetch display data with valid credentials', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -52,7 +52,7 @@ test('device can fetch display data with valid credentials', function () {
|
|||
->last_firmware_version->toBe('1.0.0');
|
||||
});
|
||||
|
||||
test('display endpoint includes image_url_timeout when configured', function () {
|
||||
test('display endpoint includes image_url_timeout when configured', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -74,7 +74,7 @@ test('display endpoint includes image_url_timeout when configured', function ()
|
|||
]);
|
||||
});
|
||||
|
||||
test('display endpoint omits image_url_timeout when not configured', function () {
|
||||
test('display endpoint omits image_url_timeout when not configured', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -94,7 +94,7 @@ test('display endpoint omits image_url_timeout when not configured', function ()
|
|||
->assertJsonMissing(['image_url_timeout']);
|
||||
});
|
||||
|
||||
test('new device is auto-assigned to user with auto-assign enabled', function () {
|
||||
test('new device is auto-assigned to user with auto-assign enabled', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => true]);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
|
|
@ -114,7 +114,7 @@ test('new device is auto-assigned to user with auto-assign enabled', function ()
|
|||
->api_key->toBe('new-device-key');
|
||||
});
|
||||
|
||||
test('new device is auto-assigned and mirrors specified device', function () {
|
||||
test('new device is auto-assigned and mirrors specified device', function (): void {
|
||||
// Create a source device that will be mirrored
|
||||
$sourceDevice = Device::factory()->create([
|
||||
'mac_address' => 'AA:BB:CC:DD:EE:FF',
|
||||
|
|
@ -153,7 +153,7 @@ test('new device is auto-assigned and mirrors specified device', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('device setup endpoint returns correct data', function () {
|
||||
test('device setup endpoint returns correct data', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -172,7 +172,7 @@ test('device setup endpoint returns correct data', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('device can submit logs', function () {
|
||||
test('device can submit logs', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -200,7 +200,7 @@ test('device can submit logs', function () {
|
|||
expect($device->logs()->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('device can submit logs in revised format', function () {
|
||||
test('device can submit logs in revised format', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -240,7 +240,7 @@ test('device can submit logs in revised format', function () {
|
|||
// $response->assertOk();
|
||||
// });
|
||||
|
||||
test('user cannot update display for devices they do not own', function () {
|
||||
test('user cannot update display for devices they do not own', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$otherUser = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $otherUser->id]);
|
||||
|
|
@ -255,7 +255,7 @@ test('user cannot update display for devices they do not own', function () {
|
|||
$response->assertForbidden();
|
||||
});
|
||||
|
||||
test('invalid device credentials return error', function () {
|
||||
test('invalid device credentials return error', function (): void {
|
||||
$response = $this->withHeaders([
|
||||
'id' => 'invalid-mac',
|
||||
'access-token' => 'invalid-token',
|
||||
|
|
@ -265,7 +265,7 @@ test('invalid device credentials return error', function () {
|
|||
->assertJson(['message' => 'MAC Address not registered or invalid access token']);
|
||||
});
|
||||
|
||||
test('log endpoint requires valid device credentials', function () {
|
||||
test('log endpoint requires valid device credentials', function (): void {
|
||||
$response = $this->withHeaders([
|
||||
'id' => 'invalid-mac',
|
||||
'access-token' => 'invalid-token',
|
||||
|
|
@ -275,7 +275,7 @@ test('log endpoint requires valid device credentials', function () {
|
|||
->assertJson(['message' => 'Device not found or invalid access token']);
|
||||
});
|
||||
|
||||
test('update_firmware flag is only returned once', function () {
|
||||
test('update_firmware flag is only returned once', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -320,7 +320,7 @@ test('update_firmware flag is only returned once', function () {
|
|||
expect($device->proxy_cloud_response['update_firmware'])->toBeFalse();
|
||||
});
|
||||
|
||||
test('authenticated user can fetch device status', function () {
|
||||
test('authenticated user can fetch device status', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -354,7 +354,7 @@ test('authenticated user can fetch device status', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('user cannot fetch status for devices they do not own', function () {
|
||||
test('user cannot fetch status for devices they do not own', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$otherUser = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $otherUser->id]);
|
||||
|
|
@ -366,7 +366,7 @@ test('user cannot fetch status for devices they do not own', function () {
|
|||
$response->assertForbidden();
|
||||
});
|
||||
|
||||
test('display status endpoint requires device_id parameter', function () {
|
||||
test('display status endpoint requires device_id parameter', function (): void {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
|
|
@ -376,7 +376,7 @@ test('display status endpoint requires device_id parameter', function () {
|
|||
->assertJsonValidationErrors(['device_id']);
|
||||
});
|
||||
|
||||
test('display status endpoint requires valid device_id', function () {
|
||||
test('display status endpoint requires valid device_id', function (): void {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
|
|
@ -386,7 +386,7 @@ test('display status endpoint requires valid device_id', function () {
|
|||
->assertJsonValidationErrors(['device_id']);
|
||||
});
|
||||
|
||||
test('device can mirror another device', function () {
|
||||
test('device can mirror another device', function (): void {
|
||||
// Create source device with a playlist and image
|
||||
$sourceDevice = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
|
|
@ -428,7 +428,7 @@ test('device can mirror another device', function () {
|
|||
->last_firmware_version->toBe('1.0.0');
|
||||
});
|
||||
|
||||
test('device can fetch current screen data', function () {
|
||||
test('device can fetch current screen data', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -451,7 +451,7 @@ test('device can fetch current screen data', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('current_screen endpoint requires valid device credentials', function () {
|
||||
test('current_screen endpoint requires valid device credentials', function (): void {
|
||||
$response = $this->withHeaders([
|
||||
'access-token' => 'invalid-token',
|
||||
])->get('/api/current_screen');
|
||||
|
|
@ -460,7 +460,7 @@ test('current_screen endpoint requires valid device credentials', function () {
|
|||
->assertJson(['message' => 'Device not found or invalid access token']);
|
||||
});
|
||||
|
||||
test('authenticated user can fetch their devices', function () {
|
||||
test('authenticated user can fetch their devices', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$devices = Device::factory()->count(2)->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -502,7 +502,7 @@ test('authenticated user can fetch their devices', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('plugin caches image until data is stale', function () {
|
||||
test('plugin caches image until data is stale', function (): void {
|
||||
// Create source device with a playlist
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '55:11:22:33:44:55',
|
||||
|
|
@ -577,7 +577,7 @@ test('plugin caches image until data is stale', function () {
|
|||
->not->toBe($firstResponse['filename']);
|
||||
});
|
||||
|
||||
test('plugins in playlist are rendered in order', function () {
|
||||
test('plugins in playlist are rendered in order', function (): void {
|
||||
// Create source device with a playlist
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '55:11:22:33:44:55',
|
||||
|
|
@ -681,7 +681,7 @@ test('plugins in playlist are rendered in order', function () {
|
|||
->not->toBe($secondResponse['filename']);
|
||||
});
|
||||
|
||||
test('display endpoint updates last_refreshed_at timestamp', function () {
|
||||
test('display endpoint updates last_refreshed_at timestamp', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -702,7 +702,7 @@ test('display endpoint updates last_refreshed_at timestamp', function () {
|
|||
->and($device->last_refreshed_at->diffInSeconds(now()))->toBeLessThan(2);
|
||||
});
|
||||
|
||||
test('display endpoint updates last_refreshed_at timestamp for mirrored devices', function () {
|
||||
test('display endpoint updates last_refreshed_at timestamp for mirrored devices', function (): void {
|
||||
// Create source device
|
||||
$sourceDevice = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
|
|
@ -731,7 +731,7 @@ test('display endpoint updates last_refreshed_at timestamp for mirrored devices'
|
|||
->and($mirrorDevice->last_refreshed_at->diffInSeconds(now()))->toBeLessThan(2);
|
||||
});
|
||||
|
||||
test('display endpoint handles mashup playlist items correctly', function () {
|
||||
test('display endpoint handles mashup playlist items correctly', function (): void {
|
||||
// Create a device
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
|
|
@ -791,7 +791,7 @@ test('display endpoint handles mashup playlist items correctly', function () {
|
|||
expect($playlistItem->last_displayed_at)->not->toBeNull();
|
||||
});
|
||||
|
||||
test('device in sleep mode returns sleep image and correct refresh rate', function () {
|
||||
test('device in sleep mode returns sleep image and correct refresh rate', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -821,7 +821,7 @@ test('device in sleep mode returns sleep image and correct refresh rate', functi
|
|||
Carbon\Carbon::setTestNow(); // Clear test time
|
||||
});
|
||||
|
||||
test('device not in sleep mode returns normal image', function () {
|
||||
test('device not in sleep mode returns normal image', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -850,7 +850,7 @@ test('device not in sleep mode returns normal image', function () {
|
|||
Carbon\Carbon::setTestNow(); // Clear test time
|
||||
});
|
||||
|
||||
test('device returns sleep.png and correct refresh time when paused', function () {
|
||||
test('device returns sleep.png and correct refresh time when paused', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -872,7 +872,7 @@ test('device returns sleep.png and correct refresh time when paused', function (
|
|||
expect($json['refresh_rate'])->toBeLessThanOrEqual(3600); // ~60 min
|
||||
});
|
||||
|
||||
test('screens endpoint accepts nullable file_name', function () {
|
||||
test('screens endpoint accepts nullable file_name', function (): void {
|
||||
Queue::fake();
|
||||
|
||||
$device = Device::factory()->create([
|
||||
|
|
@ -894,7 +894,7 @@ test('screens endpoint accepts nullable file_name', function () {
|
|||
Queue::assertPushed(GenerateScreenJob::class);
|
||||
});
|
||||
|
||||
test('screens endpoint returns 404 for invalid device credentials', function () {
|
||||
test('screens endpoint returns 404 for invalid device credentials', function (): void {
|
||||
$response = $this->withHeaders([
|
||||
'id' => 'invalid-mac',
|
||||
'access-token' => 'invalid-key',
|
||||
|
|
@ -911,7 +911,7 @@ test('screens endpoint returns 404 for invalid device credentials', function ()
|
|||
]);
|
||||
});
|
||||
|
||||
test('setup endpoint assigns device model when model-id header is provided', function () {
|
||||
test('setup endpoint assigns device model when model-id header is provided', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => true]);
|
||||
$deviceModel = DeviceModel::factory()->create([
|
||||
'name' => 'test-model',
|
||||
|
|
@ -934,7 +934,7 @@ test('setup endpoint assigns device model when model-id header is provided', fun
|
|||
->and($device->device_model_id)->toBe($deviceModel->id);
|
||||
});
|
||||
|
||||
test('setup endpoint handles non-existent device model gracefully', function () {
|
||||
test('setup endpoint handles non-existent device model gracefully', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => true]);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ use Illuminate\Support\Facades\Storage;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
Storage::fake('public');
|
||||
Storage::disk('public')->makeDirectory('/images/generated');
|
||||
});
|
||||
|
||||
test('device with firmware version 1.5.1 gets bmp format', function () {
|
||||
test('device with firmware version 1.5.1 gets bmp format', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -52,7 +52,7 @@ test('device with firmware version 1.5.1 gets bmp format', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('device with firmware version 1.5.2 gets png format', function () {
|
||||
test('device with firmware version 1.5.2 gets png format', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -88,7 +88,7 @@ test('device with firmware version 1.5.2 gets png format', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('device falls back to bmp when png does not exist', function () {
|
||||
test('device falls back to bmp when png does not exist', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
'api_key' => 'test-api-key',
|
||||
|
|
@ -124,7 +124,7 @@ test('device falls back to bmp when png does not exist', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('device without device_model_id and image_format bmp3_1bit_srgb returns bmp when plugin is rendered', function () {
|
||||
test('device without device_model_id and image_format bmp3_1bit_srgb returns bmp when plugin is rendered', function (): void {
|
||||
// Create a user with auto-assign enabled
|
||||
$user = User::factory()->create([
|
||||
'assign_new_devices' => true,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use Illuminate\Http\UploadedFile;
|
|||
use Illuminate\Support\Str;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
it('accepts a plugin settings archive and updates the plugin', function () {
|
||||
it('accepts a plugin settings archive and updates the plugin', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ use Livewire\Volt\Volt as LivewireVolt;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('login screen can be rendered', function () {
|
||||
test('login screen can be rendered', function (): void {
|
||||
$response = $this->get('/login');
|
||||
|
||||
$response->assertStatus(200);
|
||||
});
|
||||
|
||||
test('users can authenticate using the login screen', function () {
|
||||
test('users can authenticate using the login screen', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = LivewireVolt::test('auth.login')
|
||||
|
|
@ -26,7 +26,7 @@ test('users can authenticate using the login screen', function () {
|
|||
$this->assertAuthenticated();
|
||||
});
|
||||
|
||||
test('users can not authenticate with invalid password', function () {
|
||||
test('users can not authenticate with invalid password', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->post('/login', [
|
||||
|
|
@ -37,7 +37,7 @@ test('users can not authenticate with invalid password', function () {
|
|||
$this->assertGuest();
|
||||
});
|
||||
|
||||
test('users can logout', function () {
|
||||
test('users can logout', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this->actingAs($user)->post('/logout');
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use Illuminate\Support\Facades\URL;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('email verification screen can be rendered', function () {
|
||||
test('email verification screen can be rendered', function (): void {
|
||||
$user = User::factory()->unverified()->create();
|
||||
|
||||
$response = $this->actingAs($user)->get('/verify-email');
|
||||
|
|
@ -15,7 +15,7 @@ test('email verification screen can be rendered', function () {
|
|||
$response->assertStatus(200);
|
||||
});
|
||||
|
||||
test('email can be verified', function () {
|
||||
test('email can be verified', function (): void {
|
||||
$user = User::factory()->unverified()->create();
|
||||
|
||||
Event::fake();
|
||||
|
|
@ -23,7 +23,7 @@ test('email can be verified', function () {
|
|||
$verificationUrl = URL::temporarySignedRoute(
|
||||
'verification.verify',
|
||||
now()->addMinutes(60),
|
||||
['id' => $user->id, 'hash' => sha1($user->email)]
|
||||
['id' => $user->id, 'hash' => sha1((string) $user->email)]
|
||||
);
|
||||
|
||||
$response = $this->actingAs($user)->get($verificationUrl);
|
||||
|
|
@ -34,7 +34,7 @@ test('email can be verified', function () {
|
|||
$response->assertRedirect(route('dashboard', absolute: false).'?verified=1');
|
||||
});
|
||||
|
||||
test('email is not verified with invalid hash', function () {
|
||||
test('email is not verified with invalid hash', function (): void {
|
||||
$user = User::factory()->unverified()->create();
|
||||
|
||||
$verificationUrl = URL::temporarySignedRoute(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use Livewire\Volt\Volt;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('confirm password screen can be rendered', function () {
|
||||
test('confirm password screen can be rendered', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this->actingAs($user)->get('/confirm-password');
|
||||
|
|
@ -13,7 +13,7 @@ test('confirm password screen can be rendered', function () {
|
|||
$response->assertStatus(200);
|
||||
});
|
||||
|
||||
test('password can be confirmed', function () {
|
||||
test('password can be confirmed', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user);
|
||||
|
|
@ -27,7 +27,7 @@ test('password can be confirmed', function () {
|
|||
->assertRedirect(route('dashboard', absolute: false));
|
||||
});
|
||||
|
||||
test('password is not confirmed with invalid password', function () {
|
||||
test('password is not confirmed with invalid password', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user);
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ use Livewire\Volt\Volt;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('reset password link screen can be rendered', function () {
|
||||
test('reset password link screen can be rendered', function (): void {
|
||||
$response = $this->get('/forgot-password');
|
||||
|
||||
$response->assertStatus(200);
|
||||
});
|
||||
|
||||
test('reset password link can be requested', function () {
|
||||
test('reset password link can be requested', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
$user = User::factory()->create();
|
||||
|
|
@ -25,7 +25,7 @@ test('reset password link can be requested', function () {
|
|||
Notification::assertSentTo($user, ResetPassword::class);
|
||||
});
|
||||
|
||||
test('reset password screen can be rendered', function () {
|
||||
test('reset password screen can be rendered', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
$user = User::factory()->create();
|
||||
|
|
@ -34,7 +34,7 @@ test('reset password screen can be rendered', function () {
|
|||
->set('email', $user->email)
|
||||
->call('sendPasswordResetLink');
|
||||
|
||||
Notification::assertSentTo($user, ResetPassword::class, function ($notification) {
|
||||
Notification::assertSentTo($user, ResetPassword::class, function ($notification): true {
|
||||
$response = $this->get('/reset-password/'.$notification->token);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
|
@ -43,7 +43,7 @@ test('reset password screen can be rendered', function () {
|
|||
});
|
||||
});
|
||||
|
||||
test('password can be reset with valid token', function () {
|
||||
test('password can be reset with valid token', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
$user = User::factory()->create();
|
||||
|
|
@ -52,7 +52,7 @@ test('password can be reset with valid token', function () {
|
|||
->set('email', $user->email)
|
||||
->call('sendPasswordResetLink');
|
||||
|
||||
Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) {
|
||||
Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user): true {
|
||||
$response = Volt::test('auth.reset-password', ['token' => $notification->token])
|
||||
->set('email', $user->email)
|
||||
->set('password', 'password')
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ use Livewire\Volt\Volt;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('registration screen can be rendered', function () {
|
||||
test('registration screen can be rendered', function (): void {
|
||||
$response = $this->get('/register');
|
||||
|
||||
$response->assertStatus(200);
|
||||
});
|
||||
|
||||
test('new users can register', function () {
|
||||
test('new users can register', function (): void {
|
||||
$response = Volt::test('auth.register')
|
||||
->set('name', 'Test User')
|
||||
->set('email', 'test@example.com')
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('example recipes seeder command calls seeder with correct user id', function () {
|
||||
test('example recipes seeder command calls seeder with correct user id', function (): void {
|
||||
$seeder = Mockery::mock(ExampleRecipesSeeder::class);
|
||||
$seeder->shouldReceive('run')
|
||||
->once()
|
||||
|
|
@ -19,14 +19,14 @@ test('example recipes seeder command calls seeder with correct user id', functio
|
|||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('example recipes seeder command has correct signature', function () {
|
||||
test('example recipes seeder command has correct signature', function (): void {
|
||||
$command = $this->app->make(App\Console\Commands\ExampleRecipesSeederCommand::class);
|
||||
|
||||
expect($command->getName())->toBe('recipes:seed');
|
||||
expect($command->getDescription())->toBe('Seed example recipes');
|
||||
});
|
||||
|
||||
test('example recipes seeder command prompts for missing input', function () {
|
||||
test('example recipes seeder command prompts for missing input', function (): void {
|
||||
$seeder = Mockery::mock(ExampleRecipesSeeder::class);
|
||||
$seeder->shouldReceive('run')
|
||||
->once()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use App\Jobs\FetchProxyCloudResponses;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
|
||||
test('it dispatches fetch proxy cloud responses job', function () {
|
||||
test('it dispatches fetch proxy cloud responses job', function (): void {
|
||||
// Prevent the job from actually running
|
||||
Bus::fake();
|
||||
|
||||
|
|
|
|||
|
|
@ -6,24 +6,24 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('firmware check command has correct signature', function () {
|
||||
test('firmware check command has correct signature', function (): void {
|
||||
$command = $this->app->make(App\Console\Commands\FirmwareCheckCommand::class);
|
||||
|
||||
expect($command->getName())->toBe('trmnl:firmware:check');
|
||||
expect($command->getDescription())->toBe('Checks for the latest firmware and downloads it if flag --download is passed.');
|
||||
});
|
||||
|
||||
test('firmware check command runs without errors', function () {
|
||||
test('firmware check command runs without errors', function (): void {
|
||||
$this->artisan('trmnl:firmware:check')
|
||||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('firmware check command runs with download flag', function () {
|
||||
test('firmware check command runs with download flag', function (): void {
|
||||
$this->artisan('trmnl:firmware:check', ['--download' => true])
|
||||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('firmware check command can run successfully', function () {
|
||||
test('firmware check command can run successfully', function (): void {
|
||||
$this->artisan('trmnl:firmware:check')
|
||||
->assertExitCode(0);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ use App\Models\Device;
|
|||
use App\Models\Firmware;
|
||||
use App\Models\User;
|
||||
|
||||
test('firmware update command has correct signature', function () {
|
||||
test('firmware update command has correct signature', function (): void {
|
||||
$this->artisan('trmnl:firmware:update --help')
|
||||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('firmware update command can be called', function () {
|
||||
test('firmware update command can be called', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$firmware = Firmware::factory()->create(['version_tag' => '1.0.0']);
|
||||
|
|
@ -26,7 +26,7 @@ test('firmware update command can be called', function () {
|
|||
expect($device->update_firmware_id)->toBe($firmware->id);
|
||||
});
|
||||
|
||||
test('firmware update command updates all devices when all is selected', function () {
|
||||
test('firmware update command updates all devices when all is selected', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device1 = Device::factory()->create(['user_id' => $user->id]);
|
||||
$device2 = Device::factory()->create(['user_id' => $user->id]);
|
||||
|
|
@ -44,7 +44,7 @@ test('firmware update command updates all devices when all is selected', functio
|
|||
expect($device2->update_firmware_id)->toBe($firmware->id);
|
||||
});
|
||||
|
||||
test('firmware update command aborts when no devices selected', function () {
|
||||
test('firmware update command aborts when no devices selected', function (): void {
|
||||
$firmware = Firmware::factory()->create(['version_tag' => '1.0.0']);
|
||||
|
||||
$this->artisan('trmnl:firmware:update')
|
||||
|
|
@ -55,7 +55,7 @@ test('firmware update command aborts when no devices selected', function () {
|
|||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('firmware update command calls firmware check when check is selected', function () {
|
||||
test('firmware update command calls firmware check when check is selected', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$firmware = Firmware::factory()->create(['version_tag' => '1.0.0']);
|
||||
|
|
@ -70,7 +70,7 @@ test('firmware update command calls firmware check when check is selected', func
|
|||
expect($device->update_firmware_id)->toBe($firmware->id);
|
||||
});
|
||||
|
||||
test('firmware update command calls firmware check with download when download is selected', function () {
|
||||
test('firmware update command calls firmware check with download when download is selected', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$firmware = Firmware::factory()->create(['version_tag' => '1.0.0']);
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ use App\Models\PlaylistItem;
|
|||
use App\Models\Plugin;
|
||||
use App\Models\User;
|
||||
|
||||
test('mashup create command has correct signature', function () {
|
||||
test('mashup create command has correct signature', function (): void {
|
||||
$this->artisan('mashup:create --help')
|
||||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('mashup create command creates mashup successfully', function () {
|
||||
test('mashup create command creates mashup successfully', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$playlist = Playlist::factory()->create(['device_id' => $device->id]);
|
||||
|
|
@ -40,13 +40,13 @@ test('mashup create command creates mashup successfully', function () {
|
|||
expect($playlistItem->getMashupPluginIds())->toContain($plugin1->id, $plugin2->id);
|
||||
});
|
||||
|
||||
test('mashup create command exits when no devices found', function () {
|
||||
test('mashup create command exits when no devices found', function (): void {
|
||||
$this->artisan('mashup:create')
|
||||
->expectsOutput('No devices found. Please create a device first.')
|
||||
->assertExitCode(1);
|
||||
});
|
||||
|
||||
test('mashup create command exits when no playlists found for device', function () {
|
||||
test('mashup create command exits when no playlists found for device', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ test('mashup create command exits when no playlists found for device', function
|
|||
->assertExitCode(1);
|
||||
});
|
||||
|
||||
test('mashup create command exits when no plugins found', function () {
|
||||
test('mashup create command exits when no plugins found', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$playlist = Playlist::factory()->create(['device_id' => $device->id]);
|
||||
|
|
@ -70,7 +70,7 @@ test('mashup create command exits when no plugins found', function () {
|
|||
->assertExitCode(1);
|
||||
});
|
||||
|
||||
test('mashup create command validates mashup name length', function () {
|
||||
test('mashup create command validates mashup name length', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$playlist = Playlist::factory()->create(['device_id' => $device->id]);
|
||||
|
|
@ -86,7 +86,7 @@ test('mashup create command validates mashup name length', function () {
|
|||
->assertExitCode(1);
|
||||
});
|
||||
|
||||
test('mashup create command validates mashup name maximum length', function () {
|
||||
test('mashup create command validates mashup name maximum length', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$playlist = Playlist::factory()->create(['device_id' => $device->id]);
|
||||
|
|
@ -104,7 +104,7 @@ test('mashup create command validates mashup name maximum length', function () {
|
|||
->assertExitCode(1);
|
||||
});
|
||||
|
||||
test('mashup create command uses default name when provided', function () {
|
||||
test('mashup create command uses default name when provided', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$playlist = Playlist::factory()->create(['device_id' => $device->id]);
|
||||
|
|
@ -128,7 +128,7 @@ test('mashup create command uses default name when provided', function () {
|
|||
expect($playlistItem)->not->toBeNull();
|
||||
});
|
||||
|
||||
test('mashup create command handles 1x1 layout with single plugin', function () {
|
||||
test('mashup create command handles 1x1 layout with single plugin', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
$playlist = Playlist::factory()->create(['device_id' => $device->id]);
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ declare(strict_types=1);
|
|||
|
||||
use function Pest\Laravel\mock;
|
||||
|
||||
test('oidc test command has correct signature', function () {
|
||||
test('oidc test command has correct signature', function (): void {
|
||||
$this->artisan('oidc:test --help')
|
||||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('oidc test command runs successfully with disabled oidc', function () {
|
||||
test('oidc test command runs successfully with disabled oidc', function (): void {
|
||||
config([
|
||||
'app.url' => 'http://localhost',
|
||||
'services.oidc.enabled' => false,
|
||||
|
|
@ -40,7 +40,7 @@ test('oidc test command runs successfully with disabled oidc', function () {
|
|||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('oidc test command runs successfully with enabled oidc but missing config', function () {
|
||||
test('oidc test command runs successfully with enabled oidc but missing config', function (): void {
|
||||
config([
|
||||
'app.url' => 'http://localhost',
|
||||
'services.oidc.enabled' => true,
|
||||
|
|
@ -70,7 +70,7 @@ test('oidc test command runs successfully with enabled oidc but missing config',
|
|||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('oidc test command runs successfully with partial config', function () {
|
||||
test('oidc test command runs successfully with partial config', function (): void {
|
||||
config([
|
||||
'services.oidc.enabled' => true,
|
||||
'services.oidc.endpoint' => 'https://example.com',
|
||||
|
|
@ -95,9 +95,9 @@ test('oidc test command runs successfully with partial config', function () {
|
|||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('oidc test command runs successfully with full config but disabled', function () {
|
||||
test('oidc test command runs successfully with full config but disabled', function (): void {
|
||||
// Mock the HTTP client to return fake OIDC configuration
|
||||
mock(GuzzleHttp\Client::class, function ($mock) {
|
||||
mock(GuzzleHttp\Client::class, function ($mock): void {
|
||||
$mock->shouldReceive('get')
|
||||
->with('https://example.com/.well-known/openid-configuration')
|
||||
->andReturn(new GuzzleHttp\Psr7\Response(200, [], json_encode([
|
||||
|
|
@ -129,9 +129,9 @@ test('oidc test command runs successfully with full config but disabled', functi
|
|||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('oidc test command runs successfully with full config and enabled', function () {
|
||||
test('oidc test command runs successfully with full config and enabled', function (): void {
|
||||
// Mock the HTTP client to return fake OIDC configuration
|
||||
mock(GuzzleHttp\Client::class, function ($mock) {
|
||||
mock(GuzzleHttp\Client::class, function ($mock): void {
|
||||
$mock->shouldReceive('get')
|
||||
->with('https://example.com/.well-known/openid-configuration')
|
||||
->andReturn(new GuzzleHttp\Psr7\Response(200, [], json_encode([
|
||||
|
|
@ -164,9 +164,9 @@ test('oidc test command runs successfully with full config and enabled', functio
|
|||
->assertExitCode(0);
|
||||
});
|
||||
|
||||
test('oidc test command handles empty scopes', function () {
|
||||
test('oidc test command handles empty scopes', function (): void {
|
||||
// Mock the HTTP client to return fake OIDC configuration
|
||||
mock(GuzzleHttp\Client::class, function ($mock) {
|
||||
mock(GuzzleHttp\Client::class, function ($mock): void {
|
||||
$mock->shouldReceive('get')
|
||||
->with('https://example.com/.well-known/openid-configuration')
|
||||
->andReturn(new GuzzleHttp\Psr7\Response(200, [], json_encode([
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use App\Jobs\GenerateScreenJob;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
|
||||
test('it generates screen with default parameters', function () {
|
||||
test('it generates screen with default parameters', function (): void {
|
||||
Bus::fake();
|
||||
|
||||
$this->artisan('trmnl:screen:generate')
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ use App\Models\User;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('guests are redirected to the login page', function () {
|
||||
test('guests are redirected to the login page', function (): void {
|
||||
$response = $this->get('/dashboard');
|
||||
$response->assertRedirect('/login');
|
||||
});
|
||||
|
||||
test('authenticated users can visit the dashboard', function () {
|
||||
test('authenticated users can visit the dashboard', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use function Pest\Laravel\actingAs;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('configure view displays last_refreshed_at timestamp', function () {
|
||||
test('configure view displays last_refreshed_at timestamp', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('dashboard shows device image with correct rotation', function () {
|
||||
test('dashboard shows device image with correct rotation', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -28,7 +28,7 @@ test('dashboard shows device image with correct rotation', function () {
|
|||
$response->assertSee('origin-center');
|
||||
});
|
||||
|
||||
test('device configure page shows device image with correct rotation', function () {
|
||||
test('device configure page shows device image with correct rotation', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -48,7 +48,7 @@ test('device configure page shows device image with correct rotation', function
|
|||
$response->assertSee('origin-center');
|
||||
});
|
||||
|
||||
test('device with no rotation shows no transform style', function () {
|
||||
test('device with no rotation shows no transform style', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -67,7 +67,7 @@ test('device with no rotation shows no transform style', function () {
|
|||
$response->assertSee('-rotate-[0deg]');
|
||||
});
|
||||
|
||||
test('device with null rotation defaults to 0', function () {
|
||||
test('device with null rotation defaults to 0', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use Illuminate\Support\Carbon;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('device can be created with basic attributes', function () {
|
||||
test('device can be created with basic attributes', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'name' => 'Test Device',
|
||||
]);
|
||||
|
|
@ -14,7 +14,7 @@ test('device can be created with basic attributes', function () {
|
|||
->and($device->name)->toBe('Test Device');
|
||||
});
|
||||
|
||||
test('battery percentage is calculated correctly', function () {
|
||||
test('battery percentage is calculated correctly', function (): void {
|
||||
$cases = [
|
||||
['voltage' => 3.0, 'expected' => 0], // Min voltage
|
||||
['voltage' => 4.2, 'expected' => 100], // Max voltage
|
||||
|
|
@ -34,7 +34,7 @@ test('battery percentage is calculated correctly', function () {
|
|||
}
|
||||
});
|
||||
|
||||
test('wifi strength is determined correctly', function () {
|
||||
test('wifi strength is determined correctly', function (): void {
|
||||
$cases = [
|
||||
['rssi' => 0, 'expected' => 0], // No signal
|
||||
['rssi' => -90, 'expected' => 1], // Weak signal
|
||||
|
|
@ -52,7 +52,7 @@ test('wifi strength is determined correctly', function () {
|
|||
}
|
||||
});
|
||||
|
||||
test('proxy cloud attribute is properly cast to boolean', function () {
|
||||
test('proxy cloud attribute is properly cast to boolean', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'proxy_cloud' => true,
|
||||
]);
|
||||
|
|
@ -63,7 +63,7 @@ test('proxy cloud attribute is properly cast to boolean', function () {
|
|||
expect($device->proxy_cloud)->toBeFalse();
|
||||
});
|
||||
|
||||
test('last log request is properly cast to json', function () {
|
||||
test('last log request is properly cast to json', function (): void {
|
||||
$logData = ['status' => 'success', 'timestamp' => '2024-03-04 12:00:00'];
|
||||
|
||||
$device = Device::factory()->create([
|
||||
|
|
@ -76,7 +76,7 @@ test('last log request is properly cast to json', function () {
|
|||
->toHaveKey('timestamp');
|
||||
});
|
||||
|
||||
test('getSleepModeEndsInSeconds returns correct value for overnight sleep window', function () {
|
||||
test('getSleepModeEndsInSeconds returns correct value for overnight sleep window', function (): void {
|
||||
// Set the current time to 12:13
|
||||
Carbon::setTestNow(Carbon::create(2024, 1, 1, 12, 13, 0));
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use Livewire\Volt\Volt;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('device management page can be rendered', function () {
|
||||
test('device management page can be rendered', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this->actingAs($user)
|
||||
|
|
@ -15,7 +15,7 @@ test('device management page can be rendered', function () {
|
|||
$response->assertOk();
|
||||
});
|
||||
|
||||
test('user can create a new device', function () {
|
||||
test('user can create a new device', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ test('user can create a new device', function () {
|
|||
expect($device->user_id)->toBe($user->id);
|
||||
});
|
||||
|
||||
test('device creation requires required fields', function () {
|
||||
test('device creation requires required fields', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ test('device creation requires required fields', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('user can toggle proxy cloud for their device', function () {
|
||||
test('user can toggle proxy cloud for their device', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
$device = Device::factory()->create([
|
||||
|
|
@ -88,7 +88,7 @@ test('user can toggle proxy cloud for their device', function () {
|
|||
expect($device->fresh()->proxy_cloud)->toBeFalse();
|
||||
});
|
||||
|
||||
test('user cannot toggle proxy cloud for other users devices', function () {
|
||||
test('user cannot toggle proxy cloud for other users devices', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
it('returns a successful response', function () {
|
||||
it('returns a successful response', function (): void {
|
||||
$response = $this->get('/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Queue;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('command dispatches fetch device models job', function () {
|
||||
test('command dispatches fetch device models job', function (): void {
|
||||
Queue::fake();
|
||||
|
||||
$this->artisan('device-models:fetch')
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use Illuminate\Support\Facades\Storage;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
Storage::fake('public');
|
||||
Storage::disk('public')->makeDirectory('/images/generated');
|
||||
Http::preventStrayRequests();
|
||||
|
|
@ -18,7 +18,7 @@ beforeEach(function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('it fetches and processes proxy cloud responses for devices', function () {
|
||||
test('it fetches and processes proxy cloud responses for devices', function (): void {
|
||||
config(['services.trmnl.proxy_base_url' => 'https://example.com']);
|
||||
|
||||
// Create a test device with proxy cloud enabled
|
||||
|
|
@ -59,16 +59,14 @@ test('it fetches and processes proxy cloud responses for devices', function () {
|
|||
$job->handle();
|
||||
|
||||
// Assert HTTP requests were made with correct headers
|
||||
Http::assertSent(function ($request) use ($device) {
|
||||
return $request->hasHeader('id', $device->mac_address) &&
|
||||
Http::assertSent(fn ($request): bool => $request->hasHeader('id', $device->mac_address) &&
|
||||
$request->hasHeader('access-token', $device->api_key) &&
|
||||
$request->hasHeader('width', 800) &&
|
||||
$request->hasHeader('height', 480) &&
|
||||
$request->hasHeader('rssi', $device->last_rssi_level) &&
|
||||
$request->hasHeader('battery_voltage', $device->last_battery_voltage) &&
|
||||
$request->hasHeader('refresh-rate', $device->default_refresh_interval) &&
|
||||
$request->hasHeader('fw-version', $device->last_firmware_version);
|
||||
});
|
||||
$request->hasHeader('fw-version', $device->last_firmware_version));
|
||||
// Assert the device was updated
|
||||
$device->refresh();
|
||||
|
||||
|
|
@ -82,7 +80,7 @@ test('it fetches and processes proxy cloud responses for devices', function () {
|
|||
Storage::disk('public')->assertExists('images/generated/test-image.bmp');
|
||||
});
|
||||
|
||||
test('it handles log requests when present', function () {
|
||||
test('it handles log requests when present', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'proxy_cloud' => true,
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
|
|
@ -103,18 +101,16 @@ test('it handles log requests when present', function () {
|
|||
$job->handle();
|
||||
|
||||
// Assert log request was sent
|
||||
Http::assertSent(function ($request) use ($device) {
|
||||
return $request->url() === config('services.trmnl.proxy_base_url').'/api/log' &&
|
||||
Http::assertSent(fn ($request): bool => $request->url() === config('services.trmnl.proxy_base_url').'/api/log' &&
|
||||
$request->hasHeader('id', $device->mac_address) &&
|
||||
$request->body() === json_encode(['message' => 'test log']);
|
||||
});
|
||||
$request->body() === json_encode(['message' => 'test log']));
|
||||
|
||||
// Assert log request was cleared
|
||||
$device->refresh();
|
||||
expect($device->last_log_request)->toBeNull();
|
||||
});
|
||||
|
||||
test('it handles API errors gracefully', function () {
|
||||
test('it handles API errors gracefully', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'proxy_cloud' => true,
|
||||
'mac_address' => '00:11:22:33:44:55',
|
||||
|
|
@ -130,7 +126,7 @@ test('it handles API errors gracefully', function () {
|
|||
expect(fn () => $job->handle())->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
test('it only processes proxy cloud enabled devices', function () {
|
||||
test('it only processes proxy cloud enabled devices', function (): void {
|
||||
Http::fake();
|
||||
$enabledDevice = Device::factory()->create(['proxy_cloud' => true]);
|
||||
$disabledDevice = Device::factory()->create(['proxy_cloud' => false]);
|
||||
|
|
@ -139,16 +135,12 @@ test('it only processes proxy cloud enabled devices', function () {
|
|||
$job->handle();
|
||||
|
||||
// Assert request was only made for enabled device
|
||||
Http::assertSent(function ($request) use ($enabledDevice) {
|
||||
return $request->hasHeader('id', $enabledDevice->mac_address);
|
||||
});
|
||||
Http::assertSent(fn ($request) => $request->hasHeader('id', $enabledDevice->mac_address));
|
||||
|
||||
Http::assertNotSent(function ($request) use ($disabledDevice) {
|
||||
return $request->hasHeader('id', $disabledDevice->mac_address);
|
||||
});
|
||||
Http::assertNotSent(fn ($request) => $request->hasHeader('id', $disabledDevice->mac_address));
|
||||
});
|
||||
|
||||
test('it fetches and processes proxy cloud responses for devices with BMP images', function () {
|
||||
test('it fetches and processes proxy cloud responses for devices with BMP images', function (): void {
|
||||
config(['services.trmnl.proxy_base_url' => 'https://example.com']);
|
||||
|
||||
// Create a test device with proxy cloud enabled
|
||||
|
|
@ -176,16 +168,14 @@ test('it fetches and processes proxy cloud responses for devices with BMP images
|
|||
$job->handle();
|
||||
|
||||
// Assert HTTP requests were made with correct headers
|
||||
Http::assertSent(function ($request) use ($device) {
|
||||
return $request->hasHeader('id', $device->mac_address) &&
|
||||
Http::assertSent(fn ($request): bool => $request->hasHeader('id', $device->mac_address) &&
|
||||
$request->hasHeader('access-token', $device->api_key) &&
|
||||
$request->hasHeader('width', 800) &&
|
||||
$request->hasHeader('height', 480) &&
|
||||
$request->hasHeader('rssi', $device->last_rssi_level) &&
|
||||
$request->hasHeader('battery_voltage', $device->last_battery_voltage) &&
|
||||
$request->hasHeader('refresh-rate', $device->default_refresh_interval) &&
|
||||
$request->hasHeader('fw-version', $device->last_firmware_version);
|
||||
});
|
||||
$request->hasHeader('fw-version', $device->last_firmware_version));
|
||||
|
||||
// Assert the device was updated
|
||||
$device->refresh();
|
||||
|
|
@ -201,7 +191,7 @@ test('it fetches and processes proxy cloud responses for devices with BMP images
|
|||
expect(Storage::disk('public')->exists('images/generated/test-image.png'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('it fetches and processes proxy cloud responses for devices with PNG images', function () {
|
||||
test('it fetches and processes proxy cloud responses for devices with PNG images', function (): void {
|
||||
config(['services.trmnl.proxy_base_url' => 'https://example.com']);
|
||||
|
||||
// Create a test device with proxy cloud enabled
|
||||
|
|
@ -229,16 +219,14 @@ test('it fetches and processes proxy cloud responses for devices with PNG images
|
|||
$job->handle();
|
||||
|
||||
// Assert HTTP requests were made with correct headers
|
||||
Http::assertSent(function ($request) use ($device) {
|
||||
return $request->hasHeader('id', $device->mac_address) &&
|
||||
Http::assertSent(fn ($request): bool => $request->hasHeader('id', $device->mac_address) &&
|
||||
$request->hasHeader('access-token', $device->api_key) &&
|
||||
$request->hasHeader('width', 800) &&
|
||||
$request->hasHeader('height', 480) &&
|
||||
$request->hasHeader('rssi', $device->last_rssi_level) &&
|
||||
$request->hasHeader('battery_voltage', $device->last_battery_voltage) &&
|
||||
$request->hasHeader('refresh-rate', $device->default_refresh_interval) &&
|
||||
$request->hasHeader('fw-version', $device->last_firmware_version);
|
||||
});
|
||||
$request->hasHeader('fw-version', $device->last_firmware_version));
|
||||
|
||||
// Assert the device was updated
|
||||
$device->refresh();
|
||||
|
|
@ -254,7 +242,7 @@ test('it fetches and processes proxy cloud responses for devices with PNG images
|
|||
expect(Storage::disk('public')->exists('images/generated/test-image.bmp'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('it handles missing content type in image URL gracefully', function () {
|
||||
test('it handles missing content type in image URL gracefully', function (): void {
|
||||
config(['services.trmnl.proxy_base_url' => 'https://example.com']);
|
||||
|
||||
// Create a test device with proxy cloud enabled
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ use Illuminate\Support\Facades\Storage;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
TrmnlPipeline::fake();
|
||||
Storage::fake('public');
|
||||
Storage::disk('public')->makeDirectory('/images/generated');
|
||||
});
|
||||
|
||||
test('it generates screen images and updates device', function () {
|
||||
test('it generates screen images and updates device', function (): void {
|
||||
$device = Device::factory()->create();
|
||||
$job = new GenerateScreenJob($device->id, null, view('trmnl')->render());
|
||||
$job->handle();
|
||||
|
|
@ -27,7 +27,7 @@ test('it generates screen images and updates device', function () {
|
|||
Storage::disk('public')->assertExists("/images/generated/{$uuid}.png");
|
||||
});
|
||||
|
||||
test('it cleans up unused images', function () {
|
||||
test('it cleans up unused images', function (): void {
|
||||
// Create some test devices with images
|
||||
$activeDevice = Device::factory()->create([
|
||||
'current_screen_image' => 'uuid-to-be-replaced',
|
||||
|
|
@ -49,7 +49,7 @@ test('it cleans up unused images', function () {
|
|||
Storage::disk('public')->assertMissing('/images/generated/inactive-uuid.bmp');
|
||||
});
|
||||
|
||||
test('it preserves gitignore file during cleanup', function () {
|
||||
test('it preserves gitignore file during cleanup', function (): void {
|
||||
Storage::disk('public')->put('/images/generated/.gitignore', '*');
|
||||
|
||||
$device = Device::factory()->create();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('it keeps only the 50 most recent logs per device', function () {
|
||||
test('it keeps only the 50 most recent logs per device', function (): void {
|
||||
// Create two devices
|
||||
$device1 = Device::factory()->create();
|
||||
$device2 = Device::factory()->create();
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ beforeEach(function (): void {
|
|||
DeviceModel::truncate();
|
||||
});
|
||||
|
||||
test('fetch device models job can be dispatched', function () {
|
||||
test('fetch device models job can be dispatched', function (): void {
|
||||
$job = new FetchDeviceModelsJob();
|
||||
expect($job)->toBeInstanceOf(FetchDeviceModelsJob::class);
|
||||
});
|
||||
|
||||
test('fetch device models job handles successful api response', function () {
|
||||
test('fetch device models job handles successful api response', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'data' => [
|
||||
|
|
@ -65,7 +65,7 @@ test('fetch device models job handles successful api response', function () {
|
|||
expect($deviceModel->source)->toBe('api');
|
||||
});
|
||||
|
||||
test('fetch device models job handles multiple device models', function () {
|
||||
test('fetch device models job handles multiple device models', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'data' => [
|
||||
|
|
@ -114,7 +114,7 @@ test('fetch device models job handles multiple device models', function () {
|
|||
expect(DeviceModel::where('name', 'model-2')->exists())->toBeTrue();
|
||||
});
|
||||
|
||||
test('fetch device models job handles empty data array', function () {
|
||||
test('fetch device models job handles empty data array', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'data' => [],
|
||||
|
|
@ -131,7 +131,7 @@ test('fetch device models job handles empty data array', function () {
|
|||
expect(DeviceModel::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('fetch device models job handles missing data field', function () {
|
||||
test('fetch device models job handles missing data field', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'message' => 'No data available',
|
||||
|
|
@ -148,7 +148,7 @@ test('fetch device models job handles missing data field', function () {
|
|||
expect(DeviceModel::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('fetch device models job handles non-array data', function () {
|
||||
test('fetch device models job handles non-array data', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'data' => 'invalid-data',
|
||||
|
|
@ -165,7 +165,7 @@ test('fetch device models job handles non-array data', function () {
|
|||
expect(DeviceModel::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('fetch device models job handles api failure', function () {
|
||||
test('fetch device models job handles api failure', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'error' => 'Internal Server Error',
|
||||
|
|
@ -185,9 +185,9 @@ test('fetch device models job handles api failure', function () {
|
|||
expect(DeviceModel::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('fetch device models job handles network exception', function () {
|
||||
test('fetch device models job handles network exception', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => function () {
|
||||
'usetrmnl.com/api/models' => function (): void {
|
||||
throw new Exception('Network connection failed');
|
||||
},
|
||||
]);
|
||||
|
|
@ -202,7 +202,7 @@ test('fetch device models job handles network exception', function () {
|
|||
expect(DeviceModel::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('fetch device models job handles device model with missing name', function () {
|
||||
test('fetch device models job handles device model with missing name', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'data' => [
|
||||
|
|
@ -228,7 +228,7 @@ test('fetch device models job handles device model with missing name', function
|
|||
expect(DeviceModel::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('fetch device models job handles device model with partial data', function () {
|
||||
test('fetch device models job handles device model with partial data', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'data' => [
|
||||
|
|
@ -263,7 +263,7 @@ test('fetch device models job handles device model with partial data', function
|
|||
expect($deviceModel->source)->toBe('api');
|
||||
});
|
||||
|
||||
test('fetch device models job updates existing device model', function () {
|
||||
test('fetch device models job updates existing device model', function (): void {
|
||||
// Create an existing device model
|
||||
$existingModel = DeviceModel::factory()->create([
|
||||
'name' => 'existing-model',
|
||||
|
|
@ -309,7 +309,7 @@ test('fetch device models job updates existing device model', function () {
|
|||
expect($existingModel->source)->toBe('api');
|
||||
});
|
||||
|
||||
test('fetch device models job handles processing exception for individual model', function () {
|
||||
test('fetch device models job handles processing exception for individual model', function (): void {
|
||||
Http::fake([
|
||||
'usetrmnl.com/api/models' => Http::response([
|
||||
'data' => [
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ use App\Models\Firmware;
|
|||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
Storage::fake('public');
|
||||
Storage::disk('public')->makeDirectory('/firmwares');
|
||||
});
|
||||
|
||||
test('it creates firmwares directory if it does not exist', function () {
|
||||
test('it creates firmwares directory if it does not exist', function (): void {
|
||||
$firmware = Firmware::factory()->create([
|
||||
'url' => 'https://example.com/firmware.bin',
|
||||
'version_tag' => '1.0.0',
|
||||
|
|
@ -26,7 +26,7 @@ test('it creates firmwares directory if it does not exist', function () {
|
|||
expect(Storage::disk('public')->exists('firmwares'))->toBeTrue();
|
||||
});
|
||||
|
||||
test('it downloads firmware and updates storage location', function () {
|
||||
test('it downloads firmware and updates storage location', function (): void {
|
||||
Http::fake([
|
||||
'https://example.com/firmware.bin' => Http::response('fake firmware content', 200),
|
||||
]);
|
||||
|
|
@ -42,7 +42,7 @@ test('it downloads firmware and updates storage location', function () {
|
|||
expect($firmware->fresh()->storage_location)->toBe('firmwares/FW1.0.0.bin');
|
||||
});
|
||||
|
||||
test('it handles connection exception gracefully', function () {
|
||||
test('it handles connection exception gracefully', function (): void {
|
||||
$firmware = Firmware::factory()->create([
|
||||
'url' => 'https://example.com/firmware.bin',
|
||||
'version_tag' => '1.0.0',
|
||||
|
|
@ -50,7 +50,7 @@ test('it handles connection exception gracefully', function () {
|
|||
]);
|
||||
|
||||
Http::fake([
|
||||
'https://example.com/firmware.bin' => function () {
|
||||
'https://example.com/firmware.bin' => function (): void {
|
||||
throw new Illuminate\Http\Client\ConnectionException('Connection failed');
|
||||
},
|
||||
]);
|
||||
|
|
@ -65,7 +65,7 @@ test('it handles connection exception gracefully', function () {
|
|||
expect($firmware->fresh()->storage_location)->toBeNull();
|
||||
});
|
||||
|
||||
test('it handles general exception gracefully', function () {
|
||||
test('it handles general exception gracefully', function (): void {
|
||||
$firmware = Firmware::factory()->create([
|
||||
'url' => 'https://example.com/firmware.bin',
|
||||
'version_tag' => '1.0.0',
|
||||
|
|
@ -73,7 +73,7 @@ test('it handles general exception gracefully', function () {
|
|||
]);
|
||||
|
||||
Http::fake([
|
||||
'https://example.com/firmware.bin' => function () {
|
||||
'https://example.com/firmware.bin' => function (): void {
|
||||
throw new Exception('Unexpected error');
|
||||
},
|
||||
]);
|
||||
|
|
@ -88,7 +88,7 @@ test('it handles general exception gracefully', function () {
|
|||
expect($firmware->fresh()->storage_location)->toBeNull();
|
||||
});
|
||||
|
||||
test('it handles firmware with special characters in version tag', function () {
|
||||
test('it handles firmware with special characters in version tag', function (): void {
|
||||
Http::fake([
|
||||
'https://example.com/firmware.bin' => Http::response('fake firmware content', 200),
|
||||
]);
|
||||
|
|
@ -103,7 +103,7 @@ test('it handles firmware with special characters in version tag', function () {
|
|||
expect($firmware->fresh()->storage_location)->toBe('firmwares/FW1.0.0-beta.bin');
|
||||
});
|
||||
|
||||
test('it handles firmware with long version tag', function () {
|
||||
test('it handles firmware with long version tag', function (): void {
|
||||
Http::fake([
|
||||
'https://example.com/firmware.bin' => Http::response('fake firmware content', 200),
|
||||
]);
|
||||
|
|
@ -118,7 +118,7 @@ test('it handles firmware with long version tag', function () {
|
|||
expect($firmware->fresh()->storage_location)->toBe('firmwares/FW1.0.0.1234.5678.90.bin');
|
||||
});
|
||||
|
||||
test('it creates firmwares directory even when it already exists', function () {
|
||||
test('it creates firmwares directory even when it already exists', function (): void {
|
||||
$firmware = Firmware::factory()->create([
|
||||
'url' => 'https://example.com/firmware.bin',
|
||||
'version_tag' => '1.0.0',
|
||||
|
|
@ -138,7 +138,7 @@ test('it creates firmwares directory even when it already exists', function () {
|
|||
expect($firmware->fresh()->storage_location)->toBe('firmwares/FW1.0.0.bin');
|
||||
});
|
||||
|
||||
test('it handles http error response', function () {
|
||||
test('it handles http error response', function (): void {
|
||||
$firmware = Firmware::factory()->create([
|
||||
'url' => 'https://example.com/firmware.bin',
|
||||
'version_tag' => '1.0.0',
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ use App\Models\Firmware;
|
|||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
Http::preventStrayRequests();
|
||||
});
|
||||
|
||||
test('it creates new firmware record when polling', function () {
|
||||
test('it creates new firmware record when polling', function (): void {
|
||||
Http::fake([
|
||||
'https://usetrmnl.com/api/firmware/latest' => Http::response([
|
||||
'version' => '1.0.0',
|
||||
|
|
@ -25,7 +25,7 @@ test('it creates new firmware record when polling', function () {
|
|||
->latest->toBeTrue();
|
||||
});
|
||||
|
||||
test('it updates existing firmware record when polling', function () {
|
||||
test('it updates existing firmware record when polling', function (): void {
|
||||
$existingFirmware = Firmware::factory()->create([
|
||||
'version_tag' => '1.0.0',
|
||||
'url' => 'https://old-url.com/firmware.bin',
|
||||
|
|
@ -46,7 +46,7 @@ test('it updates existing firmware record when polling', function () {
|
|||
->latest->toBeTrue();
|
||||
});
|
||||
|
||||
test('it marks previous firmware as not latest when new version is found', function () {
|
||||
test('it marks previous firmware as not latest when new version is found', function (): void {
|
||||
$oldFirmware = Firmware::factory()->create([
|
||||
'version_tag' => '1.0.0',
|
||||
'latest' => true,
|
||||
|
|
@ -65,9 +65,9 @@ test('it marks previous firmware as not latest when new version is found', funct
|
|||
->and(Firmware::where('version_tag', '1.1.0')->first()->latest)->toBeTrue();
|
||||
});
|
||||
|
||||
test('it handles connection exception gracefully', function () {
|
||||
test('it handles connection exception gracefully', function (): void {
|
||||
Http::fake([
|
||||
'https://usetrmnl.com/api/firmware/latest' => function () {
|
||||
'https://usetrmnl.com/api/firmware/latest' => function (): void {
|
||||
throw new ConnectionException('Connection failed');
|
||||
},
|
||||
]);
|
||||
|
|
@ -78,7 +78,7 @@ test('it handles connection exception gracefully', function () {
|
|||
expect(Firmware::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('it handles invalid response gracefully', function () {
|
||||
test('it handles invalid response gracefully', function (): void {
|
||||
Http::fake([
|
||||
'https://usetrmnl.com/api/firmware/latest' => Http::response(null, 200),
|
||||
]);
|
||||
|
|
@ -89,7 +89,7 @@ test('it handles invalid response gracefully', function () {
|
|||
expect(Firmware::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('it handles missing version in response gracefully', function () {
|
||||
test('it handles missing version in response gracefully', function (): void {
|
||||
Http::fake([
|
||||
'https://usetrmnl.com/api/firmware/latest' => Http::response([
|
||||
'url' => 'https://example.com/firmware.bin',
|
||||
|
|
@ -102,7 +102,7 @@ test('it handles missing version in response gracefully', function () {
|
|||
expect(Firmware::count())->toBe(0);
|
||||
});
|
||||
|
||||
test('it handles missing url in response gracefully', function () {
|
||||
test('it handles missing url in response gracefully', function (): void {
|
||||
Http::fake([
|
||||
'https://usetrmnl.com/api/firmware/latest' => Http::response([
|
||||
'version' => '1.0.0',
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use App\Models\User;
|
|||
use App\Notifications\BatteryLow;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
test('it sends battery low notification when battery is below threshold', function () {
|
||||
test('it sends battery low notification when battery is below threshold', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
config(['app.notifications.battery_low.warn_at_percent' => 20]);
|
||||
|
|
@ -29,7 +29,7 @@ test('it sends battery low notification when battery is below threshold', functi
|
|||
expect($device->battery_notification_sent)->toBeTrue();
|
||||
});
|
||||
|
||||
test('it does not send notification when battery is above threshold', function () {
|
||||
test('it does not send notification when battery is above threshold', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
config(['app.notifications.battery_low.warn_at_percent' => 20]);
|
||||
|
|
@ -50,7 +50,7 @@ test('it does not send notification when battery is above threshold', function (
|
|||
expect($device->battery_notification_sent)->toBeFalse();
|
||||
});
|
||||
|
||||
test('it does not send notification when already sent', function () {
|
||||
test('it does not send notification when already sent', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
config(['app.notifications.battery_low.warn_at_percent' => 20]);
|
||||
|
|
@ -68,7 +68,7 @@ test('it does not send notification when already sent', function () {
|
|||
Notification::assertNotSentTo($user, BatteryLow::class);
|
||||
});
|
||||
|
||||
test('it resets notification flag when battery is above threshold', function () {
|
||||
test('it resets notification flag when battery is above threshold', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
config(['app.notifications.battery_low.warn_at_percent' => 20]);
|
||||
|
|
@ -89,7 +89,7 @@ test('it resets notification flag when battery is above threshold', function ()
|
|||
expect($device->battery_notification_sent)->toBeFalse();
|
||||
});
|
||||
|
||||
test('it skips devices without associated user', function () {
|
||||
test('it skips devices without associated user', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
config(['app.notifications.battery_low.warn_at_percent' => 20]);
|
||||
|
|
@ -106,7 +106,7 @@ test('it skips devices without associated user', function () {
|
|||
Notification::assertNothingSent();
|
||||
});
|
||||
|
||||
test('it processes multiple devices correctly', function () {
|
||||
test('it processes multiple devices correctly', function (): void {
|
||||
Notification::fake();
|
||||
|
||||
config(['app.notifications.battery_low.warn_at_percent' => 20]);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use Livewire\Livewire;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('device auto join component can be rendered', function () {
|
||||
test('device auto join component can be rendered', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => false]);
|
||||
|
||||
Livewire::actingAs($user)
|
||||
|
|
@ -19,7 +19,7 @@ test('device auto join component can be rendered', function () {
|
|||
->assertSet('isFirstUser', true);
|
||||
});
|
||||
|
||||
test('device auto join component initializes with user settings', function () {
|
||||
test('device auto join component initializes with user settings', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => true]);
|
||||
|
||||
Livewire::actingAs($user)
|
||||
|
|
@ -28,7 +28,7 @@ test('device auto join component initializes with user settings', function () {
|
|||
->assertSet('isFirstUser', true);
|
||||
});
|
||||
|
||||
test('device auto join component identifies first user correctly', function () {
|
||||
test('device auto join component identifies first user correctly', function (): void {
|
||||
$firstUser = User::factory()->create(['id' => 1, 'assign_new_devices' => false]);
|
||||
$otherUser = User::factory()->create(['id' => 2, 'assign_new_devices' => false]);
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ test('device auto join component identifies first user correctly', function () {
|
|||
->assertSet('isFirstUser', false);
|
||||
});
|
||||
|
||||
test('device auto join component updates user setting when toggled', function () {
|
||||
test('device auto join component updates user setting when toggled', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => false]);
|
||||
|
||||
Livewire::actingAs($user)
|
||||
|
|
@ -55,7 +55,7 @@ test('device auto join component updates user setting when toggled', function ()
|
|||
|
||||
// Validation test removed - Livewire automatically handles boolean conversion
|
||||
|
||||
test('device auto join component handles false value correctly', function () {
|
||||
test('device auto join component handles false value correctly', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => true]);
|
||||
|
||||
Livewire::actingAs($user)
|
||||
|
|
@ -67,7 +67,7 @@ test('device auto join component handles false value correctly', function () {
|
|||
expect($user->assign_new_devices)->toBeFalse();
|
||||
});
|
||||
|
||||
test('device auto join component only updates when deviceAutojoin property changes', function () {
|
||||
test('device auto join component only updates when deviceAutojoin property changes', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => false]);
|
||||
|
||||
$component = Livewire::actingAs($user)
|
||||
|
|
@ -80,7 +80,7 @@ test('device auto join component only updates when deviceAutojoin property chang
|
|||
expect($user->assign_new_devices)->toBeFalse();
|
||||
});
|
||||
|
||||
test('device auto join component renders correct view', function () {
|
||||
test('device auto join component renders correct view', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
Livewire::actingAs($user)
|
||||
|
|
@ -88,7 +88,7 @@ test('device auto join component renders correct view', function () {
|
|||
->assertViewIs('livewire.actions.device-auto-join');
|
||||
});
|
||||
|
||||
test('device auto join component works with authenticated user', function () {
|
||||
test('device auto join component works with authenticated user', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => true]);
|
||||
|
||||
$component = Livewire::actingAs($user)
|
||||
|
|
@ -98,7 +98,7 @@ test('device auto join component works with authenticated user', function () {
|
|||
expect($component->instance()->isFirstUser)->toBe($user->id === 1);
|
||||
});
|
||||
|
||||
test('device auto join component handles multiple updates correctly', function () {
|
||||
test('device auto join component handles multiple updates correctly', function (): void {
|
||||
$user = User::factory()->create(['assign_new_devices' => false]);
|
||||
|
||||
$component = Livewire::actingAs($user)
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ use Illuminate\Support\Facades\Http;
|
|||
use Livewire\Volt\Volt;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
Cache::flush();
|
||||
});
|
||||
|
||||
it('can render catalog component', function () {
|
||||
it('can render catalog component', function (): void {
|
||||
// Mock empty catalog response
|
||||
Http::fake([
|
||||
config('app.catalog_url') => Http::response('', 200),
|
||||
|
|
@ -21,7 +21,7 @@ it('can render catalog component', function () {
|
|||
$component->assertSee('No plugins available');
|
||||
});
|
||||
|
||||
it('loads plugins from catalog URL', function () {
|
||||
it('loads plugins from catalog URL', function (): void {
|
||||
// Clear cache first to ensure fresh data
|
||||
Cache::forget('catalog_plugins');
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ it('loads plugins from catalog URL', function () {
|
|||
$component->assertSee('MIT');
|
||||
});
|
||||
|
||||
it('shows error when plugin not found', function () {
|
||||
it('shows error when plugin not found', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user);
|
||||
|
|
@ -75,7 +75,7 @@ it('shows error when plugin not found', function () {
|
|||
$component->assertHasErrors();
|
||||
});
|
||||
|
||||
it('shows error when zip_url is missing', function () {
|
||||
it('shows error when zip_url is missing', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Mock the HTTP response for the catalog URL without zip_url
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use Illuminate\Support\Carbon;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('playlist scheduling works correctly for time ranges spanning midnight', function () {
|
||||
test('playlist scheduling works correctly for time ranges spanning midnight', function (): void {
|
||||
// Create a user and device
|
||||
$user = User::factory()->create();
|
||||
$device = Device::factory()->create(['user_id' => $user->id]);
|
||||
|
|
@ -85,7 +85,7 @@ test('playlist scheduling works correctly for time ranges spanning midnight', fu
|
|||
expect($nextItem->playlist->name)->toBe('Day until Deep Night Playlist');
|
||||
});
|
||||
|
||||
test('playlist isActiveNow handles midnight spanning correctly', function () {
|
||||
test('playlist isActiveNow handles midnight spanning correctly', function (): void {
|
||||
$playlist = Playlist::factory()->create([
|
||||
'is_active' => true,
|
||||
'active_from' => '09:01',
|
||||
|
|
@ -110,7 +110,7 @@ test('playlist isActiveNow handles midnight spanning correctly', function () {
|
|||
expect($playlist->isActiveNow())->toBeFalse();
|
||||
});
|
||||
|
||||
test('playlist isActiveNow handles normal time ranges correctly', function () {
|
||||
test('playlist isActiveNow handles normal time ranges correctly', function (): void {
|
||||
$playlist = Playlist::factory()->create([
|
||||
'is_active' => true,
|
||||
'active_from' => '09:00',
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ use App\Services\PluginImportService;
|
|||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
Storage::fake('local');
|
||||
});
|
||||
|
||||
it('exports plugin to zip file in correct format', function () {
|
||||
it('exports plugin to zip file in correct format', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -42,7 +42,7 @@ it('exports plugin to zip file in correct format', function () {
|
|||
expect($response->getFile()->getFilename())->toContain('test-plugin-123.zip');
|
||||
});
|
||||
|
||||
it('exports plugin with polling configuration', function () {
|
||||
it('exports plugin with polling configuration', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -63,7 +63,7 @@ it('exports plugin with polling configuration', function () {
|
|||
expect($response)->toBeInstanceOf(Symfony\Component\HttpFoundation\BinaryFileResponse::class);
|
||||
});
|
||||
|
||||
it('exports and imports plugin maintaining all data', function () {
|
||||
it('exports and imports plugin maintaining all data', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$originalPlugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -122,7 +122,7 @@ it('exports and imports plugin maintaining all data', function () {
|
|||
expect($importedPlugin->data_payload)->toBe(['items' => [1, 2, 3]]);
|
||||
});
|
||||
|
||||
it('handles blade templates correctly', function () {
|
||||
it('handles blade templates correctly', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -138,7 +138,7 @@ it('handles blade templates correctly', function () {
|
|||
expect($response)->toBeInstanceOf(Symfony\Component\HttpFoundation\BinaryFileResponse::class);
|
||||
});
|
||||
|
||||
it('removes wrapper div from exported markup', function () {
|
||||
it('removes wrapper div from exported markup', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -154,7 +154,7 @@ it('removes wrapper div from exported markup', function () {
|
|||
expect($response)->toBeInstanceOf(Symfony\Component\HttpFoundation\BinaryFileResponse::class);
|
||||
});
|
||||
|
||||
it('converts polling headers correctly', function () {
|
||||
it('converts polling headers correctly', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -170,7 +170,7 @@ it('converts polling headers correctly', function () {
|
|||
expect($response)->toBeInstanceOf(Symfony\Component\HttpFoundation\BinaryFileResponse::class);
|
||||
});
|
||||
|
||||
it('api route returns zip file for authenticated user', function () {
|
||||
it('api route returns zip file for authenticated user', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -188,7 +188,7 @@ it('api route returns zip file for authenticated user', function () {
|
|||
$response->assertHeader('Content-Disposition', 'attachment; filename=plugin_api-test-404.zip');
|
||||
});
|
||||
|
||||
it('api route returns 404 for non-existent plugin', function () {
|
||||
it('api route returns 404 for non-existent plugin', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this->actingAs($user)
|
||||
|
|
@ -197,13 +197,13 @@ it('api route returns 404 for non-existent plugin', function () {
|
|||
$response->assertStatus(404);
|
||||
});
|
||||
|
||||
it('api route returns 401 for unauthenticated user', function () {
|
||||
it('api route returns 401 for unauthenticated user', function (): void {
|
||||
$response = $this->getJson('/api/plugin_settings/test-id/archive');
|
||||
|
||||
$response->assertStatus(401);
|
||||
});
|
||||
|
||||
it('api route returns 404 for plugin belonging to different user', function () {
|
||||
it('api route returns 404 for plugin belonging to different user', function (): void {
|
||||
$user1 = User::factory()->create();
|
||||
$user2 = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
|
|
@ -217,7 +217,7 @@ it('api route returns 404 for plugin belonging to different user', function () {
|
|||
$response->assertStatus(404);
|
||||
});
|
||||
|
||||
it('exports zip with files in root directory', function () {
|
||||
it('exports zip with files in root directory', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -243,7 +243,7 @@ it('exports zip with files in root directory', function () {
|
|||
$zip->close();
|
||||
});
|
||||
|
||||
it('maintains correct yaml field order', function () {
|
||||
it('maintains correct yaml field order', function (): void {
|
||||
$user = User::factory()->create();
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('plugin import extracts default values from custom_fields and stores in configuration', function () {
|
||||
test('plugin import extracts default values from custom_fields and stores in configuration', function (): void {
|
||||
// Create a user
|
||||
$user = User::factory()->create();
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ test('plugin import extracts default values from custom_fields and stores in con
|
|||
expect($plugin->configuration_template['custom_fields'])->toHaveCount(3);
|
||||
});
|
||||
|
||||
test('plugin import handles custom_fields without default values', function () {
|
||||
test('plugin import handles custom_fields without default values', function (): void {
|
||||
// Create a user
|
||||
$user = User::factory()->create();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ use Illuminate\Http\UploadedFile;
|
|||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
Storage::fake('local');
|
||||
});
|
||||
|
||||
it('imports plugin from valid zip file', function () {
|
||||
it('imports plugin from valid zip file', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file with the required structure
|
||||
|
|
@ -38,7 +38,7 @@ it('imports plugin from valid zip file', function () {
|
|||
->and($plugin->configuration['api_key'])->toBe('default-api-key');
|
||||
});
|
||||
|
||||
it('imports plugin with shared.liquid file', function () {
|
||||
it('imports plugin with shared.liquid file', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$zipContent = createMockZipFile([
|
||||
|
|
@ -56,7 +56,7 @@ it('imports plugin with shared.liquid file', function () {
|
|||
->and($plugin->render_markup)->toContain('<div class="view view--{{ size }}">');
|
||||
});
|
||||
|
||||
it('imports plugin with files in root directory', function () {
|
||||
it('imports plugin with files in root directory', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$zipContent = createMockZipFile([
|
||||
|
|
@ -73,17 +73,17 @@ it('imports plugin with files in root directory', function () {
|
|||
->and($plugin->name)->toBe('Test Plugin');
|
||||
});
|
||||
|
||||
it('throws exception for invalid zip file', function () {
|
||||
it('throws exception for invalid zip file', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$zipFile = UploadedFile::fake()->createWithContent('invalid.zip', 'not a zip file');
|
||||
|
||||
$pluginImportService = new PluginImportService();
|
||||
expect(fn () => $pluginImportService->importFromZip($zipFile, $user))
|
||||
expect(fn (): Plugin => $pluginImportService->importFromZip($zipFile, $user))
|
||||
->toThrow(Exception::class, 'Could not open the ZIP file.');
|
||||
});
|
||||
|
||||
it('throws exception for missing required files', function () {
|
||||
it('throws exception for missing required files', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$zipContent = createMockZipFile([
|
||||
|
|
@ -94,11 +94,11 @@ it('throws exception for missing required files', function () {
|
|||
$zipFile = UploadedFile::fake()->createWithContent('test-plugin.zip', $zipContent);
|
||||
|
||||
$pluginImportService = new PluginImportService();
|
||||
expect(fn () => $pluginImportService->importFromZip($zipFile, $user))
|
||||
expect(fn (): Plugin => $pluginImportService->importFromZip($zipFile, $user))
|
||||
->toThrow(Exception::class, 'Invalid ZIP structure. Required files settings.yml and full.liquid are missing.');
|
||||
});
|
||||
|
||||
it('sets default values when settings are missing', function () {
|
||||
it('sets default values when settings are missing', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$zipContent = createMockZipFile([
|
||||
|
|
@ -117,7 +117,7 @@ it('sets default values when settings are missing', function () {
|
|||
->and($plugin->polling_verb)->toBe('get'); // default value
|
||||
});
|
||||
|
||||
it('handles blade markup language correctly', function () {
|
||||
it('handles blade markup language correctly', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$zipContent = createMockZipFile([
|
||||
|
|
@ -133,7 +133,7 @@ it('handles blade markup language correctly', function () {
|
|||
expect($plugin->markup_language)->toBe('blade');
|
||||
});
|
||||
|
||||
it('imports plugin from monorepo with zip_entry_path parameter', function () {
|
||||
it('imports plugin from monorepo with zip_entry_path parameter', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file with plugin in a subdirectory
|
||||
|
|
@ -152,7 +152,7 @@ it('imports plugin from monorepo with zip_entry_path parameter', function () {
|
|||
->and($plugin->name)->toBe('Test Plugin');
|
||||
});
|
||||
|
||||
it('imports plugin from monorepo with src subdirectory', function () {
|
||||
it('imports plugin from monorepo with src subdirectory', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file with plugin in a subdirectory with src folder
|
||||
|
|
@ -171,7 +171,7 @@ it('imports plugin from monorepo with src subdirectory', function () {
|
|||
->and($plugin->name)->toBe('Test Plugin');
|
||||
});
|
||||
|
||||
it('imports plugin from monorepo with shared.liquid in subdirectory', function () {
|
||||
it('imports plugin from monorepo with shared.liquid in subdirectory', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$zipContent = createMockZipFile([
|
||||
|
|
@ -189,7 +189,7 @@ it('imports plugin from monorepo with shared.liquid in subdirectory', function (
|
|||
->and($plugin->render_markup)->toContain('<div class="view view--{{ size }}">');
|
||||
});
|
||||
|
||||
it('imports plugin from URL with zip_entry_path parameter', function () {
|
||||
it('imports plugin from URL with zip_entry_path parameter', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file with plugin in a subdirectory
|
||||
|
|
@ -214,12 +214,10 @@ it('imports plugin from URL with zip_entry_path parameter', function () {
|
|||
->and($plugin->user_id)->toBe($user->id)
|
||||
->and($plugin->name)->toBe('Test Plugin');
|
||||
|
||||
Http::assertSent(function ($request) {
|
||||
return $request->url() === 'https://github.com/example/repo/archive/refs/heads/main.zip';
|
||||
});
|
||||
Http::assertSent(fn ($request): bool => $request->url() === 'https://github.com/example/repo/archive/refs/heads/main.zip');
|
||||
});
|
||||
|
||||
it('imports plugin from URL with zip_entry_path and src subdirectory', function () {
|
||||
it('imports plugin from URL with zip_entry_path and src subdirectory', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file with plugin in a subdirectory with src folder
|
||||
|
|
@ -245,7 +243,7 @@ it('imports plugin from URL with zip_entry_path and src subdirectory', function
|
|||
->and($plugin->name)->toBe('Test Plugin');
|
||||
});
|
||||
|
||||
it('imports plugin from GitHub monorepo with repository-named directory', function () {
|
||||
it('imports plugin from GitHub monorepo with repository-named directory', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file that simulates GitHub's ZIP structure with repository-named directory
|
||||
|
|
@ -273,7 +271,7 @@ it('imports plugin from GitHub monorepo with repository-named directory', functi
|
|||
->and($plugin->name)->toBe('Test Plugin'); // Should be from example-plugin, not other-plugin
|
||||
});
|
||||
|
||||
it('finds required files in simple ZIP structure', function () {
|
||||
it('finds required files in simple ZIP structure', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a simple ZIP file with just one plugin
|
||||
|
|
@ -292,7 +290,7 @@ it('finds required files in simple ZIP structure', function () {
|
|||
->and($plugin->name)->toBe('Test Plugin');
|
||||
});
|
||||
|
||||
it('finds required files in GitHub monorepo structure with zip_entry_path', function () {
|
||||
it('finds required files in GitHub monorepo structure with zip_entry_path', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file that simulates GitHub's ZIP structure
|
||||
|
|
@ -313,7 +311,7 @@ it('finds required files in GitHub monorepo structure with zip_entry_path', func
|
|||
->and($plugin->name)->toBe('Test Plugin'); // Should be from example-plugin, not other-plugin
|
||||
});
|
||||
|
||||
it('imports specific plugin from monorepo zip with zip_entry_path parameter', function () {
|
||||
it('imports specific plugin from monorepo zip with zip_entry_path parameter', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
// Create a mock ZIP file with 2 plugins in a monorepo structure
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('renders plugin with inline templates', function () {
|
||||
test('renders plugin with inline templates', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'name' => 'Test Plugin',
|
||||
'markup_language' => 'liquid',
|
||||
|
|
@ -61,16 +61,16 @@ LIQUID
|
|||
// Should render both templates
|
||||
// Check for any of the facts (since random number generation is non-deterministic)
|
||||
$this->assertTrue(
|
||||
str_contains($result, 'Fact 1') ||
|
||||
str_contains($result, 'Fact 2') ||
|
||||
str_contains($result, 'Fact 3')
|
||||
str_contains((string) $result, 'Fact 1') ||
|
||||
str_contains((string) $result, 'Fact 2') ||
|
||||
str_contains((string) $result, 'Fact 3')
|
||||
);
|
||||
$this->assertStringContainsString('Test Plugin', $result);
|
||||
$this->assertStringContainsString('Please try to enjoy each fact equally', $result);
|
||||
$this->assertStringContainsString('class="view view--full"', $result);
|
||||
});
|
||||
|
||||
test('renders plugin with inline templates using with syntax', function () {
|
||||
test('renders plugin with inline templates using with syntax', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'name' => 'Test Plugin',
|
||||
'markup_language' => 'liquid',
|
||||
|
|
@ -127,16 +127,16 @@ LIQUID
|
|||
// Should render both templates
|
||||
// Check for any of the facts (since random number generation is non-deterministic)
|
||||
$this->assertTrue(
|
||||
str_contains($result, 'Fact 1') ||
|
||||
str_contains($result, 'Fact 2') ||
|
||||
str_contains($result, 'Fact 3')
|
||||
str_contains((string) $result, 'Fact 1') ||
|
||||
str_contains((string) $result, 'Fact 2') ||
|
||||
str_contains((string) $result, 'Fact 3')
|
||||
);
|
||||
$this->assertStringContainsString('Test Plugin', $result);
|
||||
$this->assertStringContainsString('Please try to enjoy each fact equally', $result);
|
||||
$this->assertStringContainsString('class="view view--full"', $result);
|
||||
});
|
||||
|
||||
test('renders plugin with simple inline template', function () {
|
||||
test('renders plugin with simple inline template', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
|
|
@ -162,7 +162,7 @@ LIQUID
|
|||
$this->assertStringContainsString('class="simple"', $result);
|
||||
});
|
||||
|
||||
test('renders plugin with liquid filter find_by', function () {
|
||||
test('renders plugin with liquid filter find_by', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
|
|
@ -194,7 +194,7 @@ LIQUID
|
|||
$this->assertStringContainsString('class="user"', $result);
|
||||
});
|
||||
|
||||
test('renders plugin with liquid filter find_by and fallback', function () {
|
||||
test('renders plugin with liquid filter find_by and fallback', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
|
|
@ -216,7 +216,7 @@ LIQUID
|
|||
$this->assertStringContainsString('Not Found', $result);
|
||||
});
|
||||
|
||||
test('renders plugin with liquid filter group_by', function () {
|
||||
test('renders plugin with liquid filter group_by', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use Keepsuit\Liquid\Environment;
|
|||
* to:
|
||||
* {% assign _temp_xxx = collection | filter: "key", "value" %}{% for item in _temp_xxx %}
|
||||
*/
|
||||
test('where filter works when assigned to variable first', function () {
|
||||
test('where filter works when assigned to variable first', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
|
|
@ -42,7 +42,7 @@ LIQUID
|
|||
$this->assertStringNotContainsString('"type":"L"', $result);
|
||||
});
|
||||
|
||||
test('where filter works directly in for loop with preprocessing', function () {
|
||||
test('where filter works directly in for loop with preprocessing', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
|
|
@ -68,7 +68,7 @@ LIQUID
|
|||
$this->assertStringNotContainsString('"type":"L"', $result);
|
||||
});
|
||||
|
||||
test('where filter works directly in for loop with multiple matches', function () {
|
||||
test('where filter works directly in for loop with multiple matches', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
|
|
@ -95,7 +95,7 @@ LIQUID
|
|||
$this->assertStringNotContainsString('"type":"L"', $result);
|
||||
});
|
||||
|
||||
it('encodes arrays for url_encode as JSON with spaces after commas and then percent-encodes', function () {
|
||||
it('encodes arrays for url_encode as JSON with spaces after commas and then percent-encodes', function (): void {
|
||||
/** @var Environment $env */
|
||||
$env = app('liquid.environment');
|
||||
$env->filterRegistry->register(StandardFilters::class);
|
||||
|
|
@ -109,7 +109,7 @@ it('encodes arrays for url_encode as JSON with spaces after commas and then perc
|
|||
expect($output)->toBe('%5B%22common%22%2C%22obscure%22%5D');
|
||||
});
|
||||
|
||||
it('keeps scalar url_encode behavior intact', function () {
|
||||
it('keeps scalar url_encode behavior intact', function (): void {
|
||||
/** @var Environment $env */
|
||||
$env = app('liquid.environment');
|
||||
$env->filterRegistry->register(StandardFilters::class);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns true when required field is null', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns true when required field is null', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -39,7 +39,7 @@ test('hasMissingRequiredConfigurationFields returns true when required field is
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns false when all required fields are set', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns false when all required fields are set', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -73,7 +73,7 @@ test('hasMissingRequiredConfigurationFields returns false when all required fiel
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns false when no custom fields exist', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns false when no custom fields exist', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
|
|
@ -85,7 +85,7 @@ test('hasMissingRequiredConfigurationFields returns false when no custom fields
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns true when explicitly required field is null', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns true when explicitly required field is null', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -111,7 +111,7 @@ test('hasMissingRequiredConfigurationFields returns true when explicitly require
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns true when required field is empty string', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns true when required field is empty string', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -137,7 +137,7 @@ test('hasMissingRequiredConfigurationFields returns true when required field is
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns true when required array field is empty', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns true when required array field is empty', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -164,7 +164,7 @@ test('hasMissingRequiredConfigurationFields returns true when required array fie
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns false when author_bio field is present but other required field is set', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns false when author_bio field is present but other required field is set', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -193,7 +193,7 @@ test('hasMissingRequiredConfigurationFields returns false when author_bio field
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns false when field has default value', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns false when field has default value', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -217,7 +217,7 @@ test('hasMissingRequiredConfigurationFields returns false when field has default
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns true when required xhrSelect field is missing', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns true when required xhrSelect field is missing', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
@ -242,7 +242,7 @@ test('hasMissingRequiredConfigurationFields returns true when required xhrSelect
|
|||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns false when required xhrSelect field is set', function () {
|
||||
test('hasMissingRequiredConfigurationFields returns false when required xhrSelect field is set', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use App\Models\Plugin;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
test('webhook updates plugin data for webhook strategy', function () {
|
||||
test('webhook updates plugin data for webhook strategy', function (): void {
|
||||
// Create a plugin with webhook strategy
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'webhook',
|
||||
|
|
@ -26,7 +26,7 @@ test('webhook updates plugin data for webhook strategy', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('webhook returns 400 for non-webhook strategy plugins', function () {
|
||||
test('webhook returns 400 for non-webhook strategy plugins', function (): void {
|
||||
// Create a plugin with non-webhook strategy
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'polling',
|
||||
|
|
@ -43,7 +43,7 @@ test('webhook returns 400 for non-webhook strategy plugins', function () {
|
|||
->assertJson(['error' => 'Plugin does not use webhook strategy']);
|
||||
});
|
||||
|
||||
test('webhook returns 400 when merge_variables is missing', function () {
|
||||
test('webhook returns 400 when merge_variables is missing', function (): void {
|
||||
// Create a plugin with webhook strategy
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'webhook',
|
||||
|
|
@ -58,7 +58,7 @@ test('webhook returns 400 when merge_variables is missing', function () {
|
|||
->assertJson(['error' => 'Request must contain merge_variables key']);
|
||||
});
|
||||
|
||||
test('webhook returns 404 for non-existent plugin', function () {
|
||||
test('webhook returns 404 for non-existent plugin', function (): void {
|
||||
// Make request with non-existent plugin UUID
|
||||
$response = $this->postJson('/api/custom_plugins/'.Str::uuid(), [
|
||||
'merge_variables' => ['new' => 'data'],
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use Livewire\Volt\Volt;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('password can be updated', function () {
|
||||
test('password can be updated', function (): void {
|
||||
$user = User::factory()->create([
|
||||
'password' => Hash::make('password'),
|
||||
]);
|
||||
|
|
@ -24,7 +24,7 @@ test('password can be updated', function () {
|
|||
expect(Hash::check('new-password', $user->refresh()->password))->toBeTrue();
|
||||
});
|
||||
|
||||
test('correct password must be provided to update password', function () {
|
||||
test('correct password must be provided to update password', function (): void {
|
||||
$user = User::factory()->create([
|
||||
'password' => Hash::make('password'),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ use Livewire\Volt\Volt;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('profile page is displayed', function () {
|
||||
test('profile page is displayed', function (): void {
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
$this->get('/settings/profile')->assertOk();
|
||||
});
|
||||
|
||||
test('profile information can be updated', function () {
|
||||
test('profile information can be updated', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user);
|
||||
|
|
@ -30,7 +30,7 @@ test('profile information can be updated', function () {
|
|||
expect($user->email_verified_at)->toBeNull();
|
||||
});
|
||||
|
||||
test('email verification status is unchanged when email address is unchanged', function () {
|
||||
test('email verification status is unchanged when email address is unchanged', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user);
|
||||
|
|
@ -45,7 +45,7 @@ test('email verification status is unchanged when email address is unchanged', f
|
|||
expect($user->refresh()->email_verified_at)->not->toBeNull();
|
||||
});
|
||||
|
||||
test('user can delete their account', function () {
|
||||
test('user can delete their account', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user);
|
||||
|
|
@ -62,7 +62,7 @@ test('user can delete their account', function () {
|
|||
expect(auth()->check())->toBeFalse();
|
||||
});
|
||||
|
||||
test('correct password must be provided to delete account', function () {
|
||||
test('correct password must be provided to delete account', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
test('that true is true', function () {
|
||||
test('that true is true', function (): void {
|
||||
expect(true)->toBeTrue();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
use App\Liquid\Filters\Data;
|
||||
|
||||
test('json filter converts arrays to JSON', function () {
|
||||
test('json filter converts arrays to JSON', function (): void {
|
||||
$filter = new Data();
|
||||
$array = ['foo' => 'bar', 'baz' => 'qux'];
|
||||
|
||||
expect($filter->json($array))->toBe('{"foo":"bar","baz":"qux"}');
|
||||
});
|
||||
|
||||
test('json filter converts objects to JSON', function () {
|
||||
test('json filter converts objects to JSON', function (): void {
|
||||
$filter = new Data();
|
||||
$object = new stdClass();
|
||||
$object->foo = 'bar';
|
||||
|
|
@ -18,7 +18,7 @@ test('json filter converts objects to JSON', function () {
|
|||
expect($filter->json($object))->toBe('{"foo":"bar","baz":"qux"}');
|
||||
});
|
||||
|
||||
test('json filter handles nested structures', function () {
|
||||
test('json filter handles nested structures', function (): void {
|
||||
$filter = new Data();
|
||||
$nested = [
|
||||
'foo' => 'bar',
|
||||
|
|
@ -31,7 +31,7 @@ test('json filter handles nested structures', function () {
|
|||
expect($filter->json($nested))->toBe('{"foo":"bar","nested":{"baz":"qux","items":[1,2,3]}}');
|
||||
});
|
||||
|
||||
test('json filter handles scalar values', function () {
|
||||
test('json filter handles scalar values', function (): void {
|
||||
$filter = new Data();
|
||||
|
||||
expect($filter->json('string'))->toBe('"string"');
|
||||
|
|
@ -40,21 +40,21 @@ test('json filter handles scalar values', function () {
|
|||
expect($filter->json(null))->toBe('null');
|
||||
});
|
||||
|
||||
test('json filter preserves unicode characters', function () {
|
||||
test('json filter preserves unicode characters', function (): void {
|
||||
$filter = new Data();
|
||||
$data = ['message' => 'Hello, 世界'];
|
||||
|
||||
expect($filter->json($data))->toBe('{"message":"Hello, 世界"}');
|
||||
});
|
||||
|
||||
test('json filter does not escape slashes', function () {
|
||||
test('json filter does not escape slashes', function (): void {
|
||||
$filter = new Data();
|
||||
$data = ['url' => 'https://example.com/path'];
|
||||
|
||||
expect($filter->json($data))->toBe('{"url":"https://example.com/path"}');
|
||||
});
|
||||
|
||||
test('find_by filter finds object by key-value pair', function () {
|
||||
test('find_by filter finds object by key-value pair', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
|
|
@ -66,7 +66,7 @@ test('find_by filter finds object by key-value pair', function () {
|
|||
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
|
||||
});
|
||||
|
||||
test('find_by filter returns null when no match found', function () {
|
||||
test('find_by filter returns null when no match found', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
|
|
@ -78,7 +78,7 @@ test('find_by filter returns null when no match found', function () {
|
|||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
test('find_by filter returns fallback when no match found', function () {
|
||||
test('find_by filter returns fallback when no match found', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
|
|
@ -90,7 +90,7 @@ test('find_by filter returns fallback when no match found', function () {
|
|||
expect($result)->toBe('Not Found');
|
||||
});
|
||||
|
||||
test('find_by filter finds by age', function () {
|
||||
test('find_by filter finds by age', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
|
|
@ -102,7 +102,7 @@ test('find_by filter finds by age', function () {
|
|||
expect($result)->toBe(['name' => 'Sara', 'age' => 29]);
|
||||
});
|
||||
|
||||
test('find_by filter handles empty collection', function () {
|
||||
test('find_by filter handles empty collection', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [];
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ test('find_by filter handles empty collection', function () {
|
|||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
test('find_by filter handles collection with non-array items', function () {
|
||||
test('find_by filter handles collection with non-array items', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
'not an array',
|
||||
|
|
@ -122,7 +122,7 @@ test('find_by filter handles collection with non-array items', function () {
|
|||
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
|
||||
});
|
||||
|
||||
test('find_by filter handles items without the specified key', function () {
|
||||
test('find_by filter handles items without the specified key', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['age' => 35],
|
||||
|
|
@ -134,7 +134,7 @@ test('find_by filter handles items without the specified key', function () {
|
|||
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
|
||||
});
|
||||
|
||||
test('group_by filter groups collection by age', function () {
|
||||
test('group_by filter groups collection by age', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
|
|
@ -153,7 +153,7 @@ test('group_by filter groups collection by age', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('group_by filter groups collection by name', function () {
|
||||
test('group_by filter groups collection by name', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
|
|
@ -172,7 +172,7 @@ test('group_by filter groups collection by name', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('group_by filter handles empty collection', function () {
|
||||
test('group_by filter handles empty collection', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [];
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ test('group_by filter handles empty collection', function () {
|
|||
expect($result)->toBe([]);
|
||||
});
|
||||
|
||||
test('group_by filter handles collection with non-array items', function () {
|
||||
test('group_by filter handles collection with non-array items', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
'not an array',
|
||||
|
|
@ -197,7 +197,7 @@ test('group_by filter handles collection with non-array items', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('group_by filter handles items without the specified key', function () {
|
||||
test('group_by filter handles items without the specified key', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['age' => 35],
|
||||
|
|
@ -217,7 +217,7 @@ test('group_by filter handles items without the specified key', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('group_by filter handles mixed data types as keys', function () {
|
||||
test('group_by filter handles mixed data types as keys', function (): void {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'active' => true],
|
||||
|
|
@ -238,7 +238,7 @@ test('group_by filter handles mixed data types as keys', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('sample filter returns a random element from array', function () {
|
||||
test('sample filter returns a random element from array', function (): void {
|
||||
$filter = new Data();
|
||||
$array = ['1', '2', '3', '4', '5'];
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ test('sample filter returns a random element from array', function () {
|
|||
expect($result)->toBeIn($array);
|
||||
});
|
||||
|
||||
test('sample filter returns a random element from string array', function () {
|
||||
test('sample filter returns a random element from string array', function (): void {
|
||||
$filter = new Data();
|
||||
$array = ['cat', 'dog'];
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ test('sample filter returns a random element from string array', function () {
|
|||
expect($result)->toBeIn($array);
|
||||
});
|
||||
|
||||
test('sample filter returns null for empty array', function () {
|
||||
test('sample filter returns null for empty array', function (): void {
|
||||
$filter = new Data();
|
||||
$array = [];
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ test('sample filter returns null for empty array', function () {
|
|||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
test('sample filter returns the only element from single element array', function () {
|
||||
test('sample filter returns the only element from single element array', function (): void {
|
||||
$filter = new Data();
|
||||
$array = ['single'];
|
||||
|
||||
|
|
@ -270,7 +270,7 @@ test('sample filter returns the only element from single element array', functio
|
|||
expect($result)->toBe('single');
|
||||
});
|
||||
|
||||
test('sample filter works with mixed data types', function () {
|
||||
test('sample filter works with mixed data types', function (): void {
|
||||
$filter = new Data();
|
||||
$array = [1, 'string', true, null, ['nested']];
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ test('sample filter works with mixed data types', function () {
|
|||
expect($result)->toBeIn($array);
|
||||
});
|
||||
|
||||
test('parse_json filter parses JSON string to array', function () {
|
||||
test('parse_json filter parses JSON string to array', function (): void {
|
||||
$filter = new Data();
|
||||
$jsonString = '[{"a":1,"b":"c"},"d"]';
|
||||
|
||||
|
|
@ -286,7 +286,7 @@ test('parse_json filter parses JSON string to array', function () {
|
|||
expect($result)->toBe([['a' => 1, 'b' => 'c'], 'd']);
|
||||
});
|
||||
|
||||
test('parse_json filter parses simple JSON object', function () {
|
||||
test('parse_json filter parses simple JSON object', function (): void {
|
||||
$filter = new Data();
|
||||
$jsonString = '{"name":"John","age":30,"city":"New York"}';
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ test('parse_json filter parses simple JSON object', function () {
|
|||
expect($result)->toBe(['name' => 'John', 'age' => 30, 'city' => 'New York']);
|
||||
});
|
||||
|
||||
test('parse_json filter parses JSON array', function () {
|
||||
test('parse_json filter parses JSON array', function (): void {
|
||||
$filter = new Data();
|
||||
$jsonString = '["apple","banana","cherry"]';
|
||||
|
||||
|
|
@ -302,7 +302,7 @@ test('parse_json filter parses JSON array', function () {
|
|||
expect($result)->toBe(['apple', 'banana', 'cherry']);
|
||||
});
|
||||
|
||||
test('parse_json filter parses nested JSON structure', function () {
|
||||
test('parse_json filter parses nested JSON structure', function (): void {
|
||||
$filter = new Data();
|
||||
$jsonString = '{"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}],"total":2}';
|
||||
|
||||
|
|
@ -316,7 +316,7 @@ test('parse_json filter parses nested JSON structure', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('parse_json filter handles primitive values', function () {
|
||||
test('parse_json filter handles primitive values', function (): void {
|
||||
$filter = new Data();
|
||||
|
||||
expect($filter->parse_json('"hello"'))->toBe('hello');
|
||||
|
|
|
|||
|
|
@ -3,28 +3,28 @@
|
|||
use App\Liquid\Filters\Date;
|
||||
use Carbon\Carbon;
|
||||
|
||||
test('days_ago filter returns correct date', function () {
|
||||
test('days_ago filter returns correct date', function (): void {
|
||||
$filter = new Date();
|
||||
$threeDaysAgo = Carbon::now()->subDays(3)->toDateString();
|
||||
|
||||
expect($filter->days_ago(3))->toBe($threeDaysAgo);
|
||||
});
|
||||
|
||||
test('days_ago filter handles string input', function () {
|
||||
test('days_ago filter handles string input', function (): void {
|
||||
$filter = new Date();
|
||||
$fiveDaysAgo = Carbon::now()->subDays(5)->toDateString();
|
||||
|
||||
expect($filter->days_ago('5'))->toBe($fiveDaysAgo);
|
||||
});
|
||||
|
||||
test('days_ago filter with zero days returns today', function () {
|
||||
test('days_ago filter with zero days returns today', function (): void {
|
||||
$filter = new Date();
|
||||
$today = Carbon::now()->toDateString();
|
||||
|
||||
expect($filter->days_ago(0))->toBe($today);
|
||||
});
|
||||
|
||||
test('days_ago filter with large number works correctly', function () {
|
||||
test('days_ago filter with large number works correctly', function (): void {
|
||||
$filter = new Date();
|
||||
$hundredDaysAgo = Carbon::now()->subDays(100)->toDateString();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use App\Liquid\Filters\Localization;
|
||||
|
||||
test('l_date formats date with default format', function () {
|
||||
test('l_date formats date with default format', function (): void {
|
||||
$filter = new Localization();
|
||||
$date = '2025-01-11';
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ test('l_date formats date with default format', function () {
|
|||
expect($result)->toContain('11');
|
||||
});
|
||||
|
||||
test('l_date formats date with custom format', function () {
|
||||
test('l_date formats date with custom format', function (): void {
|
||||
$filter = new Localization();
|
||||
$date = '2025-01-11';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ test('l_date formats date with custom format', function () {
|
|||
// We can't check for 'Jan' specifically as it might be localized
|
||||
});
|
||||
|
||||
test('l_date handles DateTime objects', function () {
|
||||
test('l_date handles DateTime objects', function (): void {
|
||||
$filter = new Localization();
|
||||
$date = new DateTimeImmutable('2025-01-11');
|
||||
|
||||
|
|
@ -36,32 +36,32 @@ test('l_date handles DateTime objects', function () {
|
|||
expect($result)->toContain('2025-01-11');
|
||||
});
|
||||
|
||||
test('l_word translates common words', function () {
|
||||
test('l_word translates common words', function (): void {
|
||||
$filter = new Localization();
|
||||
|
||||
expect($filter->l_word('today', 'de'))->toBe('heute');
|
||||
});
|
||||
|
||||
test('l_word returns original word if no translation exists', function () {
|
||||
test('l_word returns original word if no translation exists', function (): void {
|
||||
$filter = new Localization();
|
||||
|
||||
expect($filter->l_word('hello', 'es-ES'))->toBe('hello');
|
||||
expect($filter->l_word('world', 'ko'))->toBe('world');
|
||||
});
|
||||
|
||||
test('l_word is case-insensitive', function () {
|
||||
test('l_word is case-insensitive', function (): void {
|
||||
$filter = new Localization();
|
||||
|
||||
expect($filter->l_word('TODAY', 'de'))->toBe('heute');
|
||||
});
|
||||
|
||||
test('l_word returns original word for unknown locales', function () {
|
||||
test('l_word returns original word for unknown locales', function (): void {
|
||||
$filter = new Localization();
|
||||
|
||||
expect($filter->l_word('today', 'unknown-locale'))->toBe('today');
|
||||
});
|
||||
|
||||
test('l_date handles locale parameter', function () {
|
||||
test('l_date handles locale parameter', function (): void {
|
||||
$filter = new Localization();
|
||||
$date = '2025-01-11';
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ test('l_date handles locale parameter', function () {
|
|||
expect($result)->toContain('11');
|
||||
});
|
||||
|
||||
test('l_date handles null locale parameter', function () {
|
||||
test('l_date handles null locale parameter', function (): void {
|
||||
$filter = new Localization();
|
||||
$date = '2025-01-11';
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ test('l_date handles null locale parameter', function () {
|
|||
expect($result)->toContain('11');
|
||||
});
|
||||
|
||||
test('l_date handles different date formats with locale', function () {
|
||||
test('l_date handles different date formats with locale', function (): void {
|
||||
$filter = new Localization();
|
||||
$date = '2025-01-11';
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ test('l_date handles different date formats with locale', function () {
|
|||
expect($result)->toContain('11');
|
||||
});
|
||||
|
||||
test('l_date handles DateTimeInterface objects with locale', function () {
|
||||
test('l_date handles DateTimeInterface objects with locale', function (): void {
|
||||
$filter = new Localization();
|
||||
$date = new DateTimeImmutable('2025-01-11');
|
||||
|
||||
|
|
@ -108,29 +108,29 @@ test('l_date handles DateTimeInterface objects with locale', function () {
|
|||
expect($result)->toContain('11');
|
||||
});
|
||||
|
||||
test('l_date handles invalid date gracefully', function () {
|
||||
test('l_date handles invalid date gracefully', function (): void {
|
||||
$filter = new Localization();
|
||||
$invalidDate = 'invalid-date';
|
||||
|
||||
// This should throw an exception or return a default value
|
||||
// The exact behavior depends on Carbon's implementation
|
||||
expect(fn () => $filter->l_date($invalidDate))->toThrow(Exception::class);
|
||||
expect(fn (): string => $filter->l_date($invalidDate))->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
test('l_word handles empty string', function () {
|
||||
test('l_word handles empty string', function (): void {
|
||||
$filter = new Localization();
|
||||
|
||||
expect($filter->l_word('', 'de'))->toBe('');
|
||||
});
|
||||
|
||||
test('l_word handles special characters', function () {
|
||||
test('l_word handles special characters', function (): void {
|
||||
$filter = new Localization();
|
||||
|
||||
// Test with a word that has special characters
|
||||
expect($filter->l_word('café', 'de'))->toBe('café');
|
||||
});
|
||||
|
||||
test('l_word handles numeric strings', function () {
|
||||
test('l_word handles numeric strings', function (): void {
|
||||
$filter = new Localization();
|
||||
|
||||
expect($filter->l_word('123', 'de'))->toBe('123');
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use App\Liquid\Filters\Numbers;
|
||||
|
||||
test('number_with_delimiter formats numbers with commas by default', function () {
|
||||
test('number_with_delimiter formats numbers with commas by default', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(1234))->toBe('1,234');
|
||||
|
|
@ -10,21 +10,21 @@ test('number_with_delimiter formats numbers with commas by default', function ()
|
|||
expect($filter->number_with_delimiter(0))->toBe('0');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles custom delimiters', function () {
|
||||
test('number_with_delimiter handles custom delimiters', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(1234, '.'))->toBe('1.234');
|
||||
expect($filter->number_with_delimiter(1000000, ' '))->toBe('1 000 000');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles decimal values with custom separators', function () {
|
||||
test('number_with_delimiter handles decimal values with custom separators', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(1234.57, ' ', ','))->toBe('1 234,57');
|
||||
expect($filter->number_with_delimiter(1234.5, '.', ','))->toBe('1.234,50');
|
||||
});
|
||||
|
||||
test('number_to_currency formats numbers with dollar sign by default', function () {
|
||||
test('number_to_currency formats numbers with dollar sign by default', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_to_currency(1234))->toBe('$1,234');
|
||||
|
|
@ -32,14 +32,14 @@ test('number_to_currency formats numbers with dollar sign by default', function
|
|||
expect($filter->number_to_currency(0))->toBe('$0');
|
||||
});
|
||||
|
||||
test('number_to_currency handles custom currency symbols', function () {
|
||||
test('number_to_currency handles custom currency symbols', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_to_currency(1234, '£'))->toBe('£1,234');
|
||||
expect($filter->number_to_currency(152350.69, '€'))->toBe('€152,350.69');
|
||||
});
|
||||
|
||||
test('number_to_currency handles custom delimiters and separators', function () {
|
||||
test('number_to_currency handles custom delimiters and separators', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
$result1 = $filter->number_to_currency(1234.57, '£', '.', ',');
|
||||
|
|
@ -51,56 +51,56 @@ test('number_to_currency handles custom delimiters and separators', function ()
|
|||
expect($result2)->toContain('€');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles string numbers', function () {
|
||||
test('number_with_delimiter handles string numbers', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter('1234'))->toBe('1,234');
|
||||
expect($filter->number_with_delimiter('1234.56'))->toBe('1,234.56');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles negative numbers', function () {
|
||||
test('number_with_delimiter handles negative numbers', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(-1234))->toBe('-1,234');
|
||||
expect($filter->number_with_delimiter(-1234.56))->toBe('-1,234.56');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles zero', function () {
|
||||
test('number_with_delimiter handles zero', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(0))->toBe('0');
|
||||
expect($filter->number_with_delimiter(0.0))->toBe('0.00');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles very small numbers', function () {
|
||||
test('number_with_delimiter handles very small numbers', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(0.01))->toBe('0.01');
|
||||
expect($filter->number_with_delimiter(0.001))->toBe('0.00');
|
||||
});
|
||||
|
||||
test('number_to_currency handles string numbers', function () {
|
||||
test('number_to_currency handles string numbers', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_to_currency('1234'))->toBe('$1,234');
|
||||
expect($filter->number_to_currency('1234.56'))->toBe('$1,234.56');
|
||||
});
|
||||
|
||||
test('number_to_currency handles negative numbers', function () {
|
||||
test('number_to_currency handles negative numbers', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_to_currency(-1234))->toBe('-$1,234');
|
||||
expect($filter->number_to_currency(-1234.56))->toBe('-$1,234.56');
|
||||
});
|
||||
|
||||
test('number_to_currency handles zero', function () {
|
||||
test('number_to_currency handles zero', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_to_currency(0))->toBe('$0');
|
||||
expect($filter->number_to_currency(0.0))->toBe('$0.00');
|
||||
});
|
||||
|
||||
test('number_to_currency handles currency code conversion', function () {
|
||||
test('number_to_currency handles currency code conversion', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_to_currency(1234, '$'))->toBe('$1,234');
|
||||
|
|
@ -108,7 +108,7 @@ test('number_to_currency handles currency code conversion', function () {
|
|||
expect($filter->number_to_currency(1234, '£'))->toBe('£1,234');
|
||||
});
|
||||
|
||||
test('number_to_currency handles German locale formatting', function () {
|
||||
test('number_to_currency handles German locale formatting', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
// When delimiter is '.' and separator is ',', it should use German locale
|
||||
|
|
@ -116,21 +116,21 @@ test('number_to_currency handles German locale formatting', function () {
|
|||
expect($result)->toContain('1.234,56');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles different decimal separators', function () {
|
||||
test('number_with_delimiter handles different decimal separators', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(1234.56, ',', ','))->toBe('1,234,56');
|
||||
expect($filter->number_with_delimiter(1234.56, ' ', ','))->toBe('1 234,56');
|
||||
});
|
||||
|
||||
test('number_to_currency handles very large numbers', function () {
|
||||
test('number_to_currency handles very large numbers', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_to_currency(1000000))->toBe('$1,000,000');
|
||||
expect($filter->number_to_currency(1000000.50))->toBe('$1,000,000.50');
|
||||
});
|
||||
|
||||
test('number_with_delimiter handles very large numbers', function () {
|
||||
test('number_with_delimiter handles very large numbers', function (): void {
|
||||
$filter = new Numbers();
|
||||
|
||||
expect($filter->number_with_delimiter(1000000))->toBe('1,000,000');
|
||||
|
|
|
|||
|
|
@ -2,35 +2,35 @@
|
|||
|
||||
use App\Liquid\Filters\StringMarkup;
|
||||
|
||||
test('pluralize returns singular form with count 1', function () {
|
||||
test('pluralize returns singular form with count 1', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
expect($filter->pluralize('book', 1))->toBe('1 book');
|
||||
expect($filter->pluralize('person', 1))->toBe('1 person');
|
||||
});
|
||||
|
||||
test('pluralize returns plural form with count greater than 1', function () {
|
||||
test('pluralize returns plural form with count greater than 1', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
expect($filter->pluralize('book', 2))->toBe('2 books');
|
||||
expect($filter->pluralize('person', 4))->toBe('4 people');
|
||||
});
|
||||
|
||||
test('pluralize handles irregular plurals correctly', function () {
|
||||
test('pluralize handles irregular plurals correctly', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
expect($filter->pluralize('child', 3))->toBe('3 children');
|
||||
expect($filter->pluralize('sheep', 5))->toBe('5 sheep');
|
||||
});
|
||||
|
||||
test('pluralize uses default count of 2 when not specified', function () {
|
||||
test('pluralize uses default count of 2 when not specified', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
expect($filter->pluralize('book'))->toBe('2 books');
|
||||
expect($filter->pluralize('person'))->toBe('2 people');
|
||||
});
|
||||
|
||||
test('markdown_to_html converts basic markdown to HTML', function () {
|
||||
test('markdown_to_html converts basic markdown to HTML', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$markdown = 'This is *italic* and **bold**.';
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ test('markdown_to_html converts basic markdown to HTML', function () {
|
|||
expect($result)->toContain('<strong>bold</strong>');
|
||||
});
|
||||
|
||||
test('markdown_to_html converts links correctly', function () {
|
||||
test('markdown_to_html converts links correctly', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$markdown = 'This is [a link](https://example.com).';
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ test('markdown_to_html converts links correctly', function () {
|
|||
expect($result)->toContain('<a href="https://example.com">a link</a>');
|
||||
});
|
||||
|
||||
test('markdown_to_html handles fallback when Parsedown is not available', function () {
|
||||
test('markdown_to_html handles fallback when Parsedown is not available', function (): void {
|
||||
// Create a mock that simulates Parsedown not being available
|
||||
$filter = new class extends StringMarkup
|
||||
{
|
||||
|
|
@ -68,28 +68,28 @@ test('markdown_to_html handles fallback when Parsedown is not available', functi
|
|||
expect($result)->toBe('This is *italic* and [a link](https://example.com).');
|
||||
});
|
||||
|
||||
test('strip_html removes HTML tags', function () {
|
||||
test('strip_html removes HTML tags', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$html = '<p>This is <strong>bold</strong> and <em>italic</em>.</p>';
|
||||
|
||||
expect($filter->strip_html($html))->toBe('This is bold and italic.');
|
||||
});
|
||||
|
||||
test('strip_html preserves text content', function () {
|
||||
test('strip_html preserves text content', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$html = '<div>Hello, <span>world</span>!</div>';
|
||||
|
||||
expect($filter->strip_html($html))->toBe('Hello, world!');
|
||||
});
|
||||
|
||||
test('strip_html handles nested tags', function () {
|
||||
test('strip_html handles nested tags', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$html = '<div><p>Paragraph <strong>with <em>nested</em> tags</strong>.</p></div>';
|
||||
|
||||
expect($filter->strip_html($html))->toBe('Paragraph with nested tags.');
|
||||
});
|
||||
|
||||
test('markdown_to_html handles CommonMarkException gracefully', function () {
|
||||
test('markdown_to_html handles CommonMarkException gracefully', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
// Create a mock that throws CommonMarkException
|
||||
|
|
@ -113,7 +113,7 @@ test('markdown_to_html handles CommonMarkException gracefully', function () {
|
|||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
test('markdown_to_html handles empty string', function () {
|
||||
test('markdown_to_html handles empty string', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
$result = $filter->markdown_to_html('');
|
||||
|
|
@ -121,7 +121,7 @@ test('markdown_to_html handles empty string', function () {
|
|||
expect($result)->toBe('');
|
||||
});
|
||||
|
||||
test('markdown_to_html handles complex markdown', function () {
|
||||
test('markdown_to_html handles complex markdown', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$markdown = "# Heading\n\nThis is a paragraph with **bold** and *italic* text.\n\n- List item 1\n- List item 2\n\n[Link](https://example.com)";
|
||||
|
||||
|
|
@ -135,34 +135,34 @@ test('markdown_to_html handles complex markdown', function () {
|
|||
expect($result)->toContain('<a href="https://example.com">Link</a>');
|
||||
});
|
||||
|
||||
test('strip_html handles empty string', function () {
|
||||
test('strip_html handles empty string', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
expect($filter->strip_html(''))->toBe('');
|
||||
});
|
||||
|
||||
test('strip_html handles string without HTML tags', function () {
|
||||
test('strip_html handles string without HTML tags', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$text = 'This is plain text without any HTML tags.';
|
||||
|
||||
expect($filter->strip_html($text))->toBe($text);
|
||||
});
|
||||
|
||||
test('strip_html handles self-closing tags', function () {
|
||||
test('strip_html handles self-closing tags', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
$html = '<p>Text with <br/> line break and <hr/> horizontal rule.</p>';
|
||||
|
||||
expect($filter->strip_html($html))->toBe('Text with line break and horizontal rule.');
|
||||
});
|
||||
|
||||
test('pluralize handles zero count', function () {
|
||||
test('pluralize handles zero count', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
expect($filter->pluralize('book', 0))->toBe('0 books');
|
||||
expect($filter->pluralize('person', 0))->toBe('0 people');
|
||||
});
|
||||
|
||||
test('pluralize handles negative count', function () {
|
||||
test('pluralize handles negative count', function (): void {
|
||||
$filter = new StringMarkup();
|
||||
|
||||
expect($filter->pluralize('book', -1))->toBe('-1 book');
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use App\Liquid\Filters\Uniqueness;
|
||||
|
||||
test('append_random appends a random string with 4 characters', function () {
|
||||
test('append_random appends a random string with 4 characters', function (): void {
|
||||
$filter = new Uniqueness();
|
||||
$result = $filter->append_random('chart-');
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('device log belongs to a device', function () {
|
||||
test('device log belongs to a device', function (): void {
|
||||
$device = Device::factory()->create();
|
||||
$log = DeviceLog::factory()->create(['device_id' => $device->id]);
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ test('device log belongs to a device', function () {
|
|||
->and($log->device->id)->toBe($device->id);
|
||||
});
|
||||
|
||||
test('device log casts log_entry to array', function () {
|
||||
test('device log casts log_entry to array', function (): void {
|
||||
Device::factory()->create();
|
||||
$log = DeviceLog::factory()->create([
|
||||
'log_entry' => [
|
||||
|
|
@ -29,7 +29,7 @@ test('device log casts log_entry to array', function () {
|
|||
->and($log->log_entry['level'])->toBe('info');
|
||||
});
|
||||
|
||||
test('device log casts device_timestamp to datetime', function () {
|
||||
test('device log casts device_timestamp to datetime', function (): void {
|
||||
Device::factory()->create();
|
||||
$timestamp = now();
|
||||
$log = DeviceLog::factory()->create([
|
||||
|
|
@ -40,7 +40,7 @@ test('device log casts device_timestamp to datetime', function () {
|
|||
->and($log->device_timestamp->timestamp)->toBe($timestamp->timestamp);
|
||||
});
|
||||
|
||||
test('device log factory creates valid data', function () {
|
||||
test('device log factory creates valid data', function (): void {
|
||||
Device::factory()->create();
|
||||
$log = DeviceLog::factory()->create();
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ test('device log factory creates valid data', function () {
|
|||
->and($log->log_entry)->toHaveKeys(['creation_timestamp', 'device_status_stamp', 'log_id', 'log_message', 'log_codeline', 'log_sourcefile', 'additional_info']);
|
||||
});
|
||||
|
||||
test('device log can be created with minimal required fields', function () {
|
||||
test('device log can be created with minimal required fields', function (): void {
|
||||
$device = Device::factory()->create();
|
||||
$log = DeviceLog::create([
|
||||
'device_id' => $device->id,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
use App\Models\DeviceModel;
|
||||
|
||||
test('device model has required attributes', function () {
|
||||
test('device model has required attributes', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create([
|
||||
'name' => 'Test Model',
|
||||
'width' => 800,
|
||||
|
|
@ -28,7 +28,7 @@ test('device model has required attributes', function () {
|
|||
expect($deviceModel->offset_y)->toBe(0);
|
||||
});
|
||||
|
||||
test('device model casts attributes correctly', function () {
|
||||
test('device model casts attributes correctly', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create([
|
||||
'width' => '800',
|
||||
'height' => '480',
|
||||
|
|
@ -50,61 +50,61 @@ test('device model casts attributes correctly', function () {
|
|||
expect($deviceModel->offset_y)->toBeInt();
|
||||
});
|
||||
|
||||
test('get color depth attribute returns correct format for bit depth 2', function () {
|
||||
test('get color depth attribute returns correct format for bit depth 2', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create(['bit_depth' => 2]);
|
||||
|
||||
expect($deviceModel->getColorDepthAttribute())->toBe('2bit');
|
||||
});
|
||||
|
||||
test('get color depth attribute returns correct format for bit depth 4', function () {
|
||||
test('get color depth attribute returns correct format for bit depth 4', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create(['bit_depth' => 4]);
|
||||
|
||||
expect($deviceModel->getColorDepthAttribute())->toBe('4bit');
|
||||
});
|
||||
|
||||
test('get color depth attribute returns 4bit for bit depth greater than 4', function () {
|
||||
test('get color depth attribute returns 4bit for bit depth greater than 4', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create(['bit_depth' => 8]);
|
||||
|
||||
expect($deviceModel->getColorDepthAttribute())->toBe('4bit');
|
||||
});
|
||||
|
||||
test('get color depth attribute returns null when bit depth is null', function () {
|
||||
test('get color depth attribute returns null when bit depth is null', function (): void {
|
||||
$deviceModel = new DeviceModel(['bit_depth' => null]);
|
||||
|
||||
expect($deviceModel->getColorDepthAttribute())->toBeNull();
|
||||
});
|
||||
|
||||
test('get scale level attribute returns null for width 800 or less', function () {
|
||||
test('get scale level attribute returns null for width 800 or less', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create(['width' => 800]);
|
||||
|
||||
expect($deviceModel->getScaleLevelAttribute())->toBeNull();
|
||||
});
|
||||
|
||||
test('get scale level attribute returns large for width between 801 and 1000', function () {
|
||||
test('get scale level attribute returns large for width between 801 and 1000', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create(['width' => 900]);
|
||||
|
||||
expect($deviceModel->getScaleLevelAttribute())->toBe('large');
|
||||
});
|
||||
|
||||
test('get scale level attribute returns xlarge for width between 1001 and 1400', function () {
|
||||
test('get scale level attribute returns xlarge for width between 1001 and 1400', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create(['width' => 1200]);
|
||||
|
||||
expect($deviceModel->getScaleLevelAttribute())->toBe('xlarge');
|
||||
});
|
||||
|
||||
test('get scale level attribute returns xxlarge for width greater than 1400', function () {
|
||||
test('get scale level attribute returns xxlarge for width greater than 1400', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create(['width' => 1500]);
|
||||
|
||||
expect($deviceModel->getScaleLevelAttribute())->toBe('xxlarge');
|
||||
});
|
||||
|
||||
test('get scale level attribute returns null when width is null', function () {
|
||||
test('get scale level attribute returns null when width is null', function (): void {
|
||||
$deviceModel = new DeviceModel(['width' => null]);
|
||||
|
||||
expect($deviceModel->getScaleLevelAttribute())->toBeNull();
|
||||
});
|
||||
|
||||
test('device model factory creates valid data', function () {
|
||||
test('device model factory creates valid data', function (): void {
|
||||
$deviceModel = DeviceModel::factory()->create();
|
||||
|
||||
expect($deviceModel->name)->not->toBeEmpty();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use App\Models\Playlist;
|
|||
use App\Models\PlaylistItem;
|
||||
use App\Models\Plugin;
|
||||
|
||||
test('playlist item belongs to playlist', function () {
|
||||
test('playlist item belongs to playlist', function (): void {
|
||||
$playlist = Playlist::factory()->create();
|
||||
$playlistItem = PlaylistItem::factory()->create(['playlist_id' => $playlist->id]);
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ test('playlist item belongs to playlist', function () {
|
|||
->id->toBe($playlist->id);
|
||||
});
|
||||
|
||||
test('playlist item belongs to plugin', function () {
|
||||
test('playlist item belongs to plugin', function (): void {
|
||||
$plugin = Plugin::factory()->create();
|
||||
$playlistItem = PlaylistItem::factory()->create(['plugin_id' => $plugin->id]);
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ test('playlist item belongs to plugin', function () {
|
|||
->id->toBe($plugin->id);
|
||||
});
|
||||
|
||||
test('playlist item can check if it is a mashup', function () {
|
||||
test('playlist item can check if it is a mashup', function (): void {
|
||||
$plugin = Plugin::factory()->create();
|
||||
$regularItem = PlaylistItem::factory()->create([
|
||||
'mashup' => null,
|
||||
|
|
@ -44,7 +44,7 @@ test('playlist item can check if it is a mashup', function () {
|
|||
->and($mashupItem->isMashup())->toBeTrue();
|
||||
});
|
||||
|
||||
test('playlist item can get mashup name', function () {
|
||||
test('playlist item can get mashup name', function (): void {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
|
|
@ -59,7 +59,7 @@ test('playlist item can get mashup name', function () {
|
|||
expect($mashupItem->getMashupName())->toBe('Test Mashup');
|
||||
});
|
||||
|
||||
test('playlist item can get mashup layout type', function () {
|
||||
test('playlist item can get mashup layout type', function (): void {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
|
|
@ -74,7 +74,7 @@ test('playlist item can get mashup layout type', function () {
|
|||
expect($mashupItem->getMashupLayoutType())->toBe('1Lx1R');
|
||||
});
|
||||
|
||||
test('playlist item can get mashup plugin ids', function () {
|
||||
test('playlist item can get mashup plugin ids', function (): void {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$mashupItem = PlaylistItem::factory()->create([
|
||||
|
|
@ -89,7 +89,7 @@ test('playlist item can get mashup plugin ids', function () {
|
|||
expect($mashupItem->getMashupPluginIds())->toBe([$plugin1->id, $plugin2->id]);
|
||||
});
|
||||
|
||||
test('playlist item can get required plugin count for different layouts', function () {
|
||||
test('playlist item can get required plugin count for different layouts', function (): void {
|
||||
$layouts = [
|
||||
'1Lx1R' => 2,
|
||||
'1Tx1B' => 2,
|
||||
|
|
@ -117,7 +117,7 @@ test('playlist item can get required plugin count for different layouts', functi
|
|||
}
|
||||
});
|
||||
|
||||
test('playlist item can get layout type', function () {
|
||||
test('playlist item can get layout type', function (): void {
|
||||
$layoutTypes = [
|
||||
'1Lx1R' => 'vertical',
|
||||
'1Lx2R' => 'vertical',
|
||||
|
|
@ -144,7 +144,7 @@ test('playlist item can get layout type', function () {
|
|||
}
|
||||
});
|
||||
|
||||
test('playlist item can get layout size for different positions', function () {
|
||||
test('playlist item can get layout size for different positions', function (): void {
|
||||
$plugin1 = Plugin::factory()->create();
|
||||
$plugin2 = Plugin::factory()->create();
|
||||
$plugin3 = Plugin::factory()->create();
|
||||
|
|
@ -163,7 +163,7 @@ test('playlist item can get layout size for different positions', function () {
|
|||
->and($mashupItem->getLayoutSize(2))->toBe('half_vertical');
|
||||
});
|
||||
|
||||
test('playlist item can get available layouts', function () {
|
||||
test('playlist item can get available layouts', function (): void {
|
||||
$layouts = PlaylistItem::getAvailableLayouts();
|
||||
|
||||
expect($layouts)->toBeArray()
|
||||
|
|
@ -171,7 +171,7 @@ test('playlist item can get available layouts', function () {
|
|||
->and($layouts['1Lx1R'])->toBe('1 Left - 1 Right (2 plugins)');
|
||||
});
|
||||
|
||||
test('playlist item can get required plugin count for layout', function () {
|
||||
test('playlist item can get required plugin count for layout', function (): void {
|
||||
$layouts = [
|
||||
'1Lx1R' => 2,
|
||||
'1Tx1B' => 2,
|
||||
|
|
@ -187,7 +187,7 @@ test('playlist item can get required plugin count for layout', function () {
|
|||
}
|
||||
});
|
||||
|
||||
test('playlist item can create mashup', function () {
|
||||
test('playlist item can create mashup', function (): void {
|
||||
$playlist = Playlist::factory()->create();
|
||||
$plugins = Plugin::factory()->count(3)->create();
|
||||
$pluginIds = $plugins->pluck('id')->toArray();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use App\Models\Device;
|
|||
use App\Models\Playlist;
|
||||
use App\Models\PlaylistItem;
|
||||
|
||||
test('playlist has required attributes', function () {
|
||||
test('playlist has required attributes', function (): void {
|
||||
$playlist = Playlist::factory()->create([
|
||||
'name' => 'Test Playlist',
|
||||
'is_active' => true,
|
||||
|
|
@ -21,7 +21,7 @@ test('playlist has required attributes', function () {
|
|||
->active_until->format('H:i')->toBe('17:00');
|
||||
});
|
||||
|
||||
test('playlist belongs to device', function () {
|
||||
test('playlist belongs to device', function (): void {
|
||||
$device = Device::factory()->create();
|
||||
$playlist = Playlist::factory()->create(['device_id' => $device->id]);
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ test('playlist belongs to device', function () {
|
|||
->id->toBe($device->id);
|
||||
});
|
||||
|
||||
test('playlist has many items', function () {
|
||||
test('playlist has many items', function (): void {
|
||||
$playlist = Playlist::factory()->create();
|
||||
$items = PlaylistItem::factory()->count(3)->create(['playlist_id' => $playlist->id]);
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ test('playlist has many items', function () {
|
|||
->each->toBeInstanceOf(PlaylistItem::class);
|
||||
});
|
||||
|
||||
test('getNextPlaylistItem returns null when playlist is inactive', function () {
|
||||
test('getNextPlaylistItem returns null when playlist is inactive', function (): void {
|
||||
$playlist = Playlist::factory()->create(['is_active' => false]);
|
||||
|
||||
expect($playlist->getNextPlaylistItem())->toBeNull();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use Illuminate\Support\Facades\Http;
|
|||
|
||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||
|
||||
test('plugin has required attributes', function () {
|
||||
test('plugin has required attributes', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'name' => 'Test Plugin',
|
||||
'data_payload' => ['key' => 'value'],
|
||||
|
|
@ -18,7 +18,7 @@ test('plugin has required attributes', function () {
|
|||
->uuid->toMatch('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/');
|
||||
});
|
||||
|
||||
test('plugin automatically generates uuid on creation', function () {
|
||||
test('plugin automatically generates uuid on creation', function (): void {
|
||||
$plugin = Plugin::factory()->create();
|
||||
|
||||
expect($plugin->uuid)
|
||||
|
|
@ -26,14 +26,14 @@ test('plugin automatically generates uuid on creation', function () {
|
|||
->toMatch('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/');
|
||||
});
|
||||
|
||||
test('plugin can have custom uuid', function () {
|
||||
test('plugin can have custom uuid', function (): void {
|
||||
$uuid = Illuminate\Support\Str::uuid();
|
||||
$plugin = Plugin::factory()->create(['uuid' => $uuid]);
|
||||
|
||||
expect($plugin->uuid)->toBe($uuid);
|
||||
});
|
||||
|
||||
test('plugin data_payload is cast to array', function () {
|
||||
test('plugin data_payload is cast to array', function (): void {
|
||||
$data = ['key' => 'value'];
|
||||
$plugin = Plugin::factory()->create(['data_payload' => $data]);
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ test('plugin data_payload is cast to array', function () {
|
|||
->toBe($data);
|
||||
});
|
||||
|
||||
test('plugin can have polling body for POST requests', function () {
|
||||
test('plugin can have polling body for POST requests', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'polling_verb' => 'post',
|
||||
'polling_body' => '{"query": "query { user { id name } }"}',
|
||||
|
|
@ -51,7 +51,7 @@ test('plugin can have polling body for POST requests', function () {
|
|||
expect($plugin->polling_body)->toBe('{"query": "query { user { id name } }"}');
|
||||
});
|
||||
|
||||
test('updateDataPayload sends POST request with body when polling_verb is post', function () {
|
||||
test('updateDataPayload sends POST request with body when polling_verb is post', function (): void {
|
||||
Http::fake([
|
||||
'https://example.com/api' => Http::response(['success' => true], 200),
|
||||
]);
|
||||
|
|
@ -65,14 +65,12 @@ test('updateDataPayload sends POST request with body when polling_verb is post',
|
|||
|
||||
$plugin->updateDataPayload();
|
||||
|
||||
Http::assertSent(function ($request) {
|
||||
return $request->url() === 'https://example.com/api' &&
|
||||
Http::assertSent(fn ($request): bool => $request->url() === 'https://example.com/api' &&
|
||||
$request->method() === 'POST' &&
|
||||
$request->body() === '{"query": "query { user { id name } }"}';
|
||||
});
|
||||
$request->body() === '{"query": "query { user { id name } }"}');
|
||||
});
|
||||
|
||||
test('updateDataPayload handles multiple URLs with IDX_ prefixes', function () {
|
||||
test('updateDataPayload handles multiple URLs with IDX_ prefixes', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'polling',
|
||||
'polling_url' => "https://api1.example.com/data\nhttps://api2.example.com/weather\nhttps://api3.example.com/news",
|
||||
|
|
@ -99,7 +97,7 @@ test('updateDataPayload handles multiple URLs with IDX_ prefixes', function () {
|
|||
expect($plugin->data_payload['IDX_2'])->toBe(['headline' => 'test']);
|
||||
});
|
||||
|
||||
test('updateDataPayload handles single URL without nesting', function () {
|
||||
test('updateDataPayload handles single URL without nesting', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'polling',
|
||||
'polling_url' => 'https://api.example.com/data',
|
||||
|
|
@ -120,7 +118,7 @@ test('updateDataPayload handles single URL without nesting', function () {
|
|||
expect($plugin->data_payload)->not->toHaveKey('IDX_0');
|
||||
});
|
||||
|
||||
test('updateDataPayload resolves Liquid variables in polling_header', function () {
|
||||
test('updateDataPayload resolves Liquid variables in polling_header', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'polling',
|
||||
'polling_url' => 'https://api.example.com/data',
|
||||
|
|
@ -139,15 +137,13 @@ test('updateDataPayload resolves Liquid variables in polling_header', function (
|
|||
|
||||
$plugin->updateDataPayload();
|
||||
|
||||
Http::assertSent(function ($request) {
|
||||
return $request->url() === 'https://api.example.com/data' &&
|
||||
Http::assertSent(fn ($request): bool => $request->url() === 'https://api.example.com/data' &&
|
||||
$request->method() === 'GET' &&
|
||||
$request->header('Authorization')[0] === 'Bearer test123' &&
|
||||
$request->header('X-Custom-Header')[0] === 'custom_header_value';
|
||||
});
|
||||
$request->header('X-Custom-Header')[0] === 'custom_header_value');
|
||||
});
|
||||
|
||||
test('updateDataPayload resolves Liquid variables in polling_body', function () {
|
||||
test('updateDataPayload resolves Liquid variables in polling_body', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'polling',
|
||||
'polling_url' => 'https://api.example.com/data',
|
||||
|
|
@ -166,7 +162,7 @@ test('updateDataPayload resolves Liquid variables in polling_body', function ()
|
|||
|
||||
$plugin->updateDataPayload();
|
||||
|
||||
Http::assertSent(function ($request) {
|
||||
Http::assertSent(function ($request): bool {
|
||||
$expectedBody = '{"query": "query { user { id name } }", "api_key": "test123", "user_id": "456"}';
|
||||
|
||||
return $request->url() === 'https://api.example.com/data' &&
|
||||
|
|
@ -175,7 +171,7 @@ test('updateDataPayload resolves Liquid variables in polling_body', function ()
|
|||
});
|
||||
});
|
||||
|
||||
test('webhook plugin is stale if webhook event occurred', function () {
|
||||
test('webhook plugin is stale if webhook event occurred', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'webhook',
|
||||
'data_payload_updated_at' => now()->subMinutes(10),
|
||||
|
|
@ -186,7 +182,7 @@ test('webhook plugin is stale if webhook event occurred', function () {
|
|||
|
||||
});
|
||||
|
||||
test('webhook plugin data not stale if no webhook event occurred for 1 hour', function () {
|
||||
test('webhook plugin data not stale if no webhook event occurred for 1 hour', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'webhook',
|
||||
'data_payload_updated_at' => now()->subMinutes(60),
|
||||
|
|
@ -197,7 +193,7 @@ test('webhook plugin data not stale if no webhook event occurred for 1 hour', fu
|
|||
|
||||
});
|
||||
|
||||
test('plugin configuration is cast to array', function () {
|
||||
test('plugin configuration is cast to array', function (): void {
|
||||
$config = ['timezone' => 'UTC', 'refresh_interval' => 30];
|
||||
$plugin = Plugin::factory()->create(['configuration' => $config]);
|
||||
|
||||
|
|
@ -206,7 +202,7 @@ test('plugin configuration is cast to array', function () {
|
|||
->toBe($config);
|
||||
});
|
||||
|
||||
test('plugin can get configuration value by key', function () {
|
||||
test('plugin can get configuration value by key', function (): void {
|
||||
$config = ['timezone' => 'UTC', 'refresh_interval' => 30];
|
||||
$plugin = Plugin::factory()->create(['configuration' => $config]);
|
||||
|
||||
|
|
@ -215,7 +211,7 @@ test('plugin can get configuration value by key', function () {
|
|||
expect($plugin->getConfiguration('nonexistent', 'default'))->toBe('default');
|
||||
});
|
||||
|
||||
test('plugin configuration template is cast to array', function () {
|
||||
test('plugin configuration template is cast to array', function (): void {
|
||||
$template = [
|
||||
'custom_fields' => [
|
||||
[
|
||||
|
|
@ -233,7 +229,7 @@ test('plugin configuration template is cast to array', function () {
|
|||
->toBe($template);
|
||||
});
|
||||
|
||||
test('resolveLiquidVariables resolves variables from configuration', function () {
|
||||
test('resolveLiquidVariables resolves variables from configuration', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'configuration' => [
|
||||
'api_key' => '12345',
|
||||
|
|
@ -263,7 +259,7 @@ test('resolveLiquidVariables resolves variables from configuration', function ()
|
|||
expect($result)->toBe('High');
|
||||
});
|
||||
|
||||
test('resolveLiquidVariables handles invalid Liquid syntax gracefully', function () {
|
||||
test('resolveLiquidVariables handles invalid Liquid syntax gracefully', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'configuration' => [
|
||||
'api_key' => '12345',
|
||||
|
|
@ -277,7 +273,7 @@ test('resolveLiquidVariables handles invalid Liquid syntax gracefully', function
|
|||
->toThrow(Keepsuit\Liquid\Exceptions\SyntaxException::class);
|
||||
});
|
||||
|
||||
test('plugin can extract default values from custom fields configuration template', function () {
|
||||
test('plugin can extract default values from custom fields configuration template', function (): void {
|
||||
$configurationTemplate = [
|
||||
'custom_fields' => [
|
||||
[
|
||||
|
|
@ -323,7 +319,7 @@ test('plugin can extract default values from custom fields configuration templat
|
|||
expect($plugin->getConfiguration('timezone'))->toBeNull();
|
||||
});
|
||||
|
||||
test('resolveLiquidVariables resolves configuration variables correctly', function () {
|
||||
test('resolveLiquidVariables resolves configuration variables correctly', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'configuration' => [
|
||||
'Latitude' => '48.2083',
|
||||
|
|
@ -338,7 +334,7 @@ test('resolveLiquidVariables resolves configuration variables correctly', functi
|
|||
expect($plugin->resolveLiquidVariables($template))->toBe($expected);
|
||||
});
|
||||
|
||||
test('resolveLiquidVariables handles missing variables gracefully', function () {
|
||||
test('resolveLiquidVariables handles missing variables gracefully', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'configuration' => [
|
||||
'Latitude' => '48.2083',
|
||||
|
|
@ -351,7 +347,7 @@ test('resolveLiquidVariables handles missing variables gracefully', function ()
|
|||
expect($plugin->resolveLiquidVariables($template))->toBe($expected);
|
||||
});
|
||||
|
||||
test('resolveLiquidVariables handles empty configuration', function () {
|
||||
test('resolveLiquidVariables handles empty configuration', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'configuration' => [],
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ use App\Notifications\BatteryLow;
|
|||
use App\Notifications\Channels\WebhookChannel;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
test('battery low notification has correct via channels', function () {
|
||||
test('battery low notification has correct via channels', function (): void {
|
||||
$device = Device::factory()->create();
|
||||
$notification = new BatteryLow($device);
|
||||
|
||||
expect($notification->via(new User()))->toBe(['mail', WebhookChannel::class]);
|
||||
});
|
||||
|
||||
test('battery low notification creates correct mail message', function () {
|
||||
test('battery low notification creates correct mail message', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'name' => 'Test Device',
|
||||
'last_battery_voltage' => 3.0,
|
||||
|
|
@ -29,7 +29,7 @@ test('battery low notification creates correct mail message', function () {
|
|||
expect($mailMessage->viewData['device'])->toBe($device);
|
||||
});
|
||||
|
||||
test('battery low notification creates correct webhook message', function () {
|
||||
test('battery low notification creates correct webhook message', function (): void {
|
||||
config([
|
||||
'services.webhook.notifications.topic' => 'battery.low',
|
||||
'app.name' => 'Test App',
|
||||
|
|
@ -60,7 +60,7 @@ test('battery low notification creates correct webhook message', function () {
|
|||
]);
|
||||
});
|
||||
|
||||
test('battery low notification creates correct array representation', function () {
|
||||
test('battery low notification creates correct array representation', function (): void {
|
||||
$device = Device::factory()->create([
|
||||
'name' => 'Test Device',
|
||||
'last_battery_voltage' => 3.0,
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ use GuzzleHttp\Exception\GuzzleException;
|
|||
use GuzzleHttp\Psr7\Response;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
test('webhook channel returns null when no webhook url is configured', function () {
|
||||
test('webhook channel returns null when no webhook url is configured', function (): void {
|
||||
$client = Mockery::mock(Client::class);
|
||||
$channel = new WebhookChannel($client);
|
||||
|
||||
$user = new class extends User
|
||||
{
|
||||
public function routeNotificationFor($driver, $notification = null)
|
||||
public function routeNotificationFor($driver, $notification = null): null
|
||||
{
|
||||
return null; // No webhook URL configured
|
||||
}
|
||||
|
|
@ -30,13 +30,13 @@ test('webhook channel returns null when no webhook url is configured', function
|
|||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
test('webhook channel throws exception when notification does not implement toWebhook', function () {
|
||||
test('webhook channel throws exception when notification does not implement toWebhook', function (): void {
|
||||
$client = Mockery::mock(Client::class);
|
||||
$channel = new WebhookChannel($client);
|
||||
|
||||
$user = new class extends User
|
||||
{
|
||||
public function routeNotificationFor($driver, $notification = null)
|
||||
public function routeNotificationFor($driver, $notification = null): string
|
||||
{
|
||||
return 'https://example.com/webhook';
|
||||
}
|
||||
|
|
@ -44,23 +44,23 @@ test('webhook channel throws exception when notification does not implement toWe
|
|||
|
||||
$notification = new class extends Notification
|
||||
{
|
||||
public function via($notifiable)
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
expect(fn () => $channel->send($user, $notification))
|
||||
expect(fn (): ?\GuzzleHttp\Psr7\Response => $channel->send($user, $notification))
|
||||
->toThrow(Exception::class, 'Notification does not implement toWebhook method.');
|
||||
});
|
||||
|
||||
test('webhook channel sends successful webhook request', function () {
|
||||
test('webhook channel sends successful webhook request', function (): void {
|
||||
$client = Mockery::mock(Client::class);
|
||||
$channel = new WebhookChannel($client);
|
||||
|
||||
$user = new class extends User
|
||||
{
|
||||
public function routeNotificationFor($driver, $notification = null)
|
||||
public function routeNotificationFor($driver, $notification = null): string
|
||||
{
|
||||
return 'https://example.com/webhook';
|
||||
}
|
||||
|
|
@ -86,13 +86,13 @@ test('webhook channel sends successful webhook request', function () {
|
|||
expect($result)->toBe($expectedResponse);
|
||||
});
|
||||
|
||||
test('webhook channel throws exception when response status is not successful', function () {
|
||||
test('webhook channel throws exception when response status is not successful', function (): void {
|
||||
$client = Mockery::mock(Client::class);
|
||||
$channel = new WebhookChannel($client);
|
||||
|
||||
$user = new class extends User
|
||||
{
|
||||
public function routeNotificationFor($driver, $notification = null)
|
||||
public function routeNotificationFor($driver, $notification = null): string
|
||||
{
|
||||
return 'https://example.com/webhook';
|
||||
}
|
||||
|
|
@ -107,17 +107,17 @@ test('webhook channel throws exception when response status is not successful',
|
|||
->once()
|
||||
->andReturn($errorResponse);
|
||||
|
||||
expect(fn () => $channel->send($user, $notification))
|
||||
expect(fn (): ?\GuzzleHttp\Psr7\Response => $channel->send($user, $notification))
|
||||
->toThrow(Exception::class, 'Webhook request failed with status code: 400');
|
||||
});
|
||||
|
||||
test('webhook channel handles guzzle exceptions', function () {
|
||||
test('webhook channel handles guzzle exceptions', function (): void {
|
||||
$client = Mockery::mock(Client::class);
|
||||
$channel = new WebhookChannel($client);
|
||||
|
||||
$user = new class extends User
|
||||
{
|
||||
public function routeNotificationFor($driver, $notification = null)
|
||||
public function routeNotificationFor($driver, $notification = null): string
|
||||
{
|
||||
return 'https://example.com/webhook';
|
||||
}
|
||||
|
|
@ -130,6 +130,6 @@ test('webhook channel handles guzzle exceptions', function () {
|
|||
->once()
|
||||
->andThrow(new class extends Exception implements GuzzleException {});
|
||||
|
||||
expect(fn () => $channel->send($user, $notification))
|
||||
expect(fn (): ?\GuzzleHttp\Psr7\Response => $channel->send($user, $notification))
|
||||
->toThrow(Exception::class);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,26 +4,26 @@ declare(strict_types=1);
|
|||
|
||||
use App\Notifications\Messages\WebhookMessage;
|
||||
|
||||
test('webhook message can be created with static method', function () {
|
||||
test('webhook message can be created with static method', function (): void {
|
||||
$message = WebhookMessage::create('test data');
|
||||
|
||||
expect($message)->toBeInstanceOf(WebhookMessage::class);
|
||||
});
|
||||
|
||||
test('webhook message can be created with constructor', function () {
|
||||
test('webhook message can be created with constructor', function (): void {
|
||||
$message = new WebhookMessage('test data');
|
||||
|
||||
expect($message)->toBeInstanceOf(WebhookMessage::class);
|
||||
});
|
||||
|
||||
test('webhook message can set query parameters', function () {
|
||||
test('webhook message can set query parameters', function (): void {
|
||||
$message = WebhookMessage::create()
|
||||
->query(['param1' => 'value1', 'param2' => 'value2']);
|
||||
|
||||
expect($message->toArray()['query'])->toBe(['param1' => 'value1', 'param2' => 'value2']);
|
||||
});
|
||||
|
||||
test('webhook message can set data', function () {
|
||||
test('webhook message can set data', function (): void {
|
||||
$data = ['key' => 'value', 'nested' => ['array' => 'data']];
|
||||
$message = WebhookMessage::create()
|
||||
->data($data);
|
||||
|
|
@ -31,7 +31,7 @@ test('webhook message can set data', function () {
|
|||
expect($message->toArray()['data'])->toBe($data);
|
||||
});
|
||||
|
||||
test('webhook message can add headers', function () {
|
||||
test('webhook message can add headers', function (): void {
|
||||
$message = WebhookMessage::create()
|
||||
->header('X-Custom-Header', 'custom-value')
|
||||
->header('Authorization', 'Bearer token');
|
||||
|
|
@ -41,7 +41,7 @@ test('webhook message can add headers', function () {
|
|||
expect($headers['Authorization'])->toBe('Bearer token');
|
||||
});
|
||||
|
||||
test('webhook message can set user agent', function () {
|
||||
test('webhook message can set user agent', function (): void {
|
||||
$message = WebhookMessage::create()
|
||||
->userAgent('Test App/1.0');
|
||||
|
||||
|
|
@ -49,20 +49,20 @@ test('webhook message can set user agent', function () {
|
|||
expect($headers['User-Agent'])->toBe('Test App/1.0');
|
||||
});
|
||||
|
||||
test('webhook message can set verify option', function () {
|
||||
test('webhook message can set verify option', function (): void {
|
||||
$message = WebhookMessage::create()
|
||||
->verify(true);
|
||||
|
||||
expect($message->toArray()['verify'])->toBeTrue();
|
||||
});
|
||||
|
||||
test('webhook message verify defaults to false', function () {
|
||||
test('webhook message verify defaults to false', function (): void {
|
||||
$message = WebhookMessage::create();
|
||||
|
||||
expect($message->toArray()['verify'])->toBeFalse();
|
||||
});
|
||||
|
||||
test('webhook message can chain methods', function () {
|
||||
test('webhook message can chain methods', function (): void {
|
||||
$message = WebhookMessage::create(['initial' => 'data'])
|
||||
->query(['param' => 'value'])
|
||||
->data(['updated' => 'data'])
|
||||
|
|
@ -79,7 +79,7 @@ test('webhook message can chain methods', function () {
|
|||
expect($array['verify'])->toBeTrue();
|
||||
});
|
||||
|
||||
test('webhook message toArray returns correct structure', function () {
|
||||
test('webhook message toArray returns correct structure', function (): void {
|
||||
$message = WebhookMessage::create(['test' => 'data']);
|
||||
|
||||
$array = $message->toArray();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function (): void {
|
||||
TrmnlPipeline::fake();
|
||||
});
|
||||
|
||||
|
|
@ -37,7 +37,6 @@ it('get_image_settings returns device model settings when available', function (
|
|||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass(ImageGenerationService::class);
|
||||
$method = $reflection->getMethod('getImageSettings');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$settings = $method->invoke(null, $device);
|
||||
|
||||
|
|
@ -66,7 +65,6 @@ it('get_image_settings falls back to device settings when no device model', func
|
|||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass(ImageGenerationService::class);
|
||||
$method = $reflection->getMethod('getImageSettings');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$settings = $method->invoke(null, $device);
|
||||
|
||||
|
|
@ -90,7 +88,6 @@ it('get_image_settings uses defaults for missing device properties', function ()
|
|||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass(ImageGenerationService::class);
|
||||
$method = $reflection->getMethod('getImageSettings');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$settings = $method->invoke(null, $device);
|
||||
|
||||
|
|
@ -112,7 +109,6 @@ it('determine_image_format_from_model returns correct formats', function (): voi
|
|||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass(ImageGenerationService::class);
|
||||
$method = $reflection->getMethod('determineImageFormatFromModel');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// Test BMP format
|
||||
$bmpModel = DeviceModel::factory()->create([
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ use GuzzleHttp\Psr7\Response;
|
|||
use Illuminate\Http\Request;
|
||||
use Laravel\Socialite\Two\User;
|
||||
|
||||
test('oidc provider throws exception when endpoint is not configured', function () {
|
||||
test('oidc provider throws exception when endpoint is not configured', function (): void {
|
||||
config(['services.oidc.endpoint' => null]);
|
||||
|
||||
expect(fn () => new OidcProvider(
|
||||
expect(fn (): OidcProvider => new OidcProvider(
|
||||
new Request(),
|
||||
'client-id',
|
||||
'client-secret',
|
||||
|
|
@ -20,7 +20,7 @@ test('oidc provider throws exception when endpoint is not configured', function
|
|||
))->toThrow(Exception::class, 'OIDC endpoint is not configured');
|
||||
});
|
||||
|
||||
test('oidc provider handles well-known endpoint url', function () {
|
||||
test('oidc provider handles well-known endpoint url', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com/.well-known/openid-configuration']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -48,7 +48,7 @@ test('oidc provider handles well-known endpoint url', function () {
|
|||
expect($provider)->toBeInstanceOf(OidcProvider::class);
|
||||
});
|
||||
|
||||
test('oidc provider handles base url endpoint', function () {
|
||||
test('oidc provider handles base url endpoint', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -76,7 +76,7 @@ test('oidc provider handles base url endpoint', function () {
|
|||
expect($provider)->toBeInstanceOf(OidcProvider::class);
|
||||
});
|
||||
|
||||
test('oidc provider throws exception when configuration is empty', function () {
|
||||
test('oidc provider throws exception when configuration is empty', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -90,7 +90,7 @@ test('oidc provider throws exception when configuration is empty', function () {
|
|||
|
||||
$this->app->instance(Client::class, $mockClient);
|
||||
|
||||
expect(fn () => new OidcProvider(
|
||||
expect(fn (): OidcProvider => new OidcProvider(
|
||||
new Request(),
|
||||
'client-id',
|
||||
'client-secret',
|
||||
|
|
@ -98,7 +98,7 @@ test('oidc provider throws exception when configuration is empty', function () {
|
|||
))->toThrow(Exception::class, 'OIDC configuration is empty or invalid JSON');
|
||||
});
|
||||
|
||||
test('oidc provider throws exception when authorization endpoint is missing', function () {
|
||||
test('oidc provider throws exception when authorization endpoint is missing', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -115,7 +115,7 @@ test('oidc provider throws exception when authorization endpoint is missing', fu
|
|||
|
||||
$this->app->instance(Client::class, $mockClient);
|
||||
|
||||
expect(fn () => new OidcProvider(
|
||||
expect(fn (): OidcProvider => new OidcProvider(
|
||||
new Request(),
|
||||
'client-id',
|
||||
'client-secret',
|
||||
|
|
@ -123,7 +123,7 @@ test('oidc provider throws exception when authorization endpoint is missing', fu
|
|||
))->toThrow(Exception::class, 'authorization_endpoint not found in OIDC configuration');
|
||||
});
|
||||
|
||||
test('oidc provider throws exception when configuration request fails', function () {
|
||||
test('oidc provider throws exception when configuration request fails', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -133,7 +133,7 @@ test('oidc provider throws exception when configuration request fails', function
|
|||
|
||||
$this->app->instance(Client::class, $mockClient);
|
||||
|
||||
expect(fn () => new OidcProvider(
|
||||
expect(fn (): OidcProvider => new OidcProvider(
|
||||
new Request(),
|
||||
'client-id',
|
||||
'client-secret',
|
||||
|
|
@ -141,7 +141,7 @@ test('oidc provider throws exception when configuration request fails', function
|
|||
))->toThrow(Exception::class, 'Failed to load OIDC configuration');
|
||||
});
|
||||
|
||||
test('oidc provider uses default scopes when none provided', function () {
|
||||
test('oidc provider uses default scopes when none provided', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -169,7 +169,7 @@ test('oidc provider uses default scopes when none provided', function () {
|
|||
expect($provider)->toBeInstanceOf(OidcProvider::class);
|
||||
});
|
||||
|
||||
test('oidc provider uses custom scopes when provided', function () {
|
||||
test('oidc provider uses custom scopes when provided', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -198,7 +198,7 @@ test('oidc provider uses custom scopes when provided', function () {
|
|||
expect($provider)->toBeInstanceOf(OidcProvider::class);
|
||||
});
|
||||
|
||||
test('oidc provider maps user data correctly', function () {
|
||||
test('oidc provider maps user data correctly', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
@ -241,7 +241,7 @@ test('oidc provider maps user data correctly', function () {
|
|||
expect($user->getAvatar())->toBe('https://example.com/avatar.jpg');
|
||||
});
|
||||
|
||||
test('oidc provider handles missing user fields gracefully', function () {
|
||||
test('oidc provider handles missing user fields gracefully', function (): void {
|
||||
config(['services.oidc.endpoint' => 'https://example.com']);
|
||||
|
||||
$mockClient = Mockery::mock(Client::class);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue