mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
This commit is contained in:
parent
a88e72b75e
commit
ba3bf31bb7
29 changed files with 2379 additions and 215 deletions
262
tests/Unit/Services/ImageGenerationServiceTest.php
Normal file
262
tests/Unit/Services/ImageGenerationServiceTest.php
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Enums\ImageFormat;
|
||||
use App\Models\Device;
|
||||
use App\Models\DeviceModel;
|
||||
use App\Services\ImageGenerationService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('get_image_settings returns device model settings when available', function (): void {
|
||||
// Create a DeviceModel
|
||||
$deviceModel = DeviceModel::factory()->create([
|
||||
'width' => 1024,
|
||||
'height' => 768,
|
||||
'colors' => 256,
|
||||
'bit_depth' => 8,
|
||||
'scale_factor' => 1.5,
|
||||
'rotation' => 90,
|
||||
'mime_type' => 'image/png',
|
||||
'offset_x' => 10,
|
||||
'offset_y' => 20,
|
||||
]);
|
||||
|
||||
// Create a device with the DeviceModel
|
||||
$device = Device::factory()->create([
|
||||
'device_model_id' => $deviceModel->id,
|
||||
]);
|
||||
|
||||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass(ImageGenerationService::class);
|
||||
$method = $reflection->getMethod('getImageSettings');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$settings = $method->invoke(null, $device);
|
||||
|
||||
// Assert DeviceModel settings are used
|
||||
expect($settings['width'])->toBe(1024);
|
||||
expect($settings['height'])->toBe(768);
|
||||
expect($settings['colors'])->toBe(256);
|
||||
expect($settings['bit_depth'])->toBe(8);
|
||||
expect($settings['scale_factor'])->toBe(1.5);
|
||||
expect($settings['rotation'])->toBe(90);
|
||||
expect($settings['mime_type'])->toBe('image/png');
|
||||
expect($settings['offset_x'])->toBe(10);
|
||||
expect($settings['offset_y'])->toBe(20);
|
||||
expect($settings['use_model_settings'])->toBe(true);
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('get_image_settings falls back to device settings when no device model', function (): void {
|
||||
// Create a device without DeviceModel
|
||||
$device = Device::factory()->create([
|
||||
'width' => 800,
|
||||
'height' => 480,
|
||||
'rotate' => 180,
|
||||
'image_format' => ImageFormat::PNG_8BIT_GRAYSCALE->value,
|
||||
]);
|
||||
|
||||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass(ImageGenerationService::class);
|
||||
$method = $reflection->getMethod('getImageSettings');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$settings = $method->invoke(null, $device);
|
||||
|
||||
// Assert device settings are used
|
||||
expect($settings['width'])->toBe(800);
|
||||
expect($settings['height'])->toBe(480);
|
||||
expect($settings['rotation'])->toBe(180);
|
||||
expect($settings['image_format'])->toBe(ImageFormat::PNG_8BIT_GRAYSCALE->value);
|
||||
expect($settings['use_model_settings'])->toBe(false);
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('get_image_settings uses defaults for missing device properties', function (): void {
|
||||
// Create a device without DeviceModel and missing properties
|
||||
$device = Device::factory()->create([
|
||||
'width' => null,
|
||||
'height' => null,
|
||||
'rotate' => null,
|
||||
// image_format has a default value of 'auto', so we can't set it to null
|
||||
]);
|
||||
|
||||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass(ImageGenerationService::class);
|
||||
$method = $reflection->getMethod('getImageSettings');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$settings = $method->invoke(null, $device);
|
||||
|
||||
// Assert default values are used
|
||||
expect($settings['width'])->toBe(800);
|
||||
expect($settings['height'])->toBe(480);
|
||||
expect($settings['rotation'])->toBe(0);
|
||||
expect($settings['colors'])->toBe(2);
|
||||
expect($settings['bit_depth'])->toBe(1);
|
||||
expect($settings['scale_factor'])->toBe(1.0);
|
||||
expect($settings['mime_type'])->toBe('image/png');
|
||||
expect($settings['offset_x'])->toBe(0);
|
||||
expect($settings['offset_y'])->toBe(0);
|
||||
// image_format will be null if the device doesn't have it set, which is the expected behavior
|
||||
expect($settings['image_format'])->toBeNull();
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('determine_image_format_from_model returns correct formats', function (): void {
|
||||
// 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([
|
||||
'mime_type' => 'image/bmp',
|
||||
'bit_depth' => 1,
|
||||
'colors' => 2,
|
||||
]);
|
||||
$format = $method->invoke(null, $bmpModel);
|
||||
expect($format)->toBe(ImageFormat::BMP3_1BIT_SRGB->value);
|
||||
|
||||
// Test PNG 8-bit grayscale format
|
||||
$pngGrayscaleModel = DeviceModel::factory()->create([
|
||||
'mime_type' => 'image/png',
|
||||
'bit_depth' => 8,
|
||||
'colors' => 2,
|
||||
]);
|
||||
$format = $method->invoke(null, $pngGrayscaleModel);
|
||||
expect($format)->toBe(ImageFormat::PNG_8BIT_GRAYSCALE->value);
|
||||
|
||||
// Test PNG 8-bit 256 color format
|
||||
$png256Model = DeviceModel::factory()->create([
|
||||
'mime_type' => 'image/png',
|
||||
'bit_depth' => 8,
|
||||
'colors' => 256,
|
||||
]);
|
||||
$format = $method->invoke(null, $png256Model);
|
||||
expect($format)->toBe(ImageFormat::PNG_8BIT_256C->value);
|
||||
|
||||
// Test PNG 2-bit 4 color format
|
||||
$png4ColorModel = DeviceModel::factory()->create([
|
||||
'mime_type' => 'image/png',
|
||||
'bit_depth' => 2,
|
||||
'colors' => 4,
|
||||
]);
|
||||
$format = $method->invoke(null, $png4ColorModel);
|
||||
expect($format)->toBe(ImageFormat::PNG_2BIT_4C->value);
|
||||
|
||||
// Test unknown format returns AUTO
|
||||
$unknownModel = DeviceModel::factory()->create([
|
||||
'mime_type' => 'image/jpeg',
|
||||
'bit_depth' => 16,
|
||||
'colors' => 65536,
|
||||
]);
|
||||
$format = $method->invoke(null, $unknownModel);
|
||||
expect($format)->toBe(ImageFormat::AUTO->value);
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('cleanup_folder identifies active images correctly', function (): void {
|
||||
// Create devices with images
|
||||
$device1 = Device::factory()->create(['current_screen_image' => 'active-uuid-1']);
|
||||
$device2 = Device::factory()->create(['current_screen_image' => 'active-uuid-2']);
|
||||
$device3 = Device::factory()->create(['current_screen_image' => null]);
|
||||
|
||||
// Create a plugin with image
|
||||
$plugin = App\Models\Plugin::factory()->create(['current_image' => 'plugin-uuid']);
|
||||
|
||||
// For unit testing, we could test the logic that determines active UUIDs
|
||||
$activeDeviceImageUuids = Device::pluck('current_screen_image')->filter()->toArray();
|
||||
$activePluginImageUuids = App\Models\Plugin::pluck('current_image')->filter()->toArray();
|
||||
$activeImageUuids = array_merge($activeDeviceImageUuids, $activePluginImageUuids);
|
||||
|
||||
expect($activeImageUuids)->toContain('active-uuid-1');
|
||||
expect($activeImageUuids)->toContain('active-uuid-2');
|
||||
expect($activeImageUuids)->toContain('plugin-uuid');
|
||||
expect($activeImageUuids)->not->toContain(null);
|
||||
});
|
||||
|
||||
it('reset_if_not_cacheable detects device models', function (): void {
|
||||
// Create a plugin
|
||||
$plugin = App\Models\Plugin::factory()->create(['current_image' => 'test-uuid']);
|
||||
|
||||
// Create a device with DeviceModel
|
||||
Device::factory()->create([
|
||||
'device_model_id' => DeviceModel::factory()->create()->id,
|
||||
]);
|
||||
|
||||
// Test that the method detects DeviceModels and resets cache
|
||||
ImageGenerationService::resetIfNotCacheable($plugin);
|
||||
|
||||
$plugin->refresh();
|
||||
expect($plugin->current_image)->toBeNull();
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('reset_if_not_cacheable detects custom dimensions', function (): void {
|
||||
// Create a plugin
|
||||
$plugin = App\Models\Plugin::factory()->create(['current_image' => 'test-uuid']);
|
||||
|
||||
// Create a device with custom dimensions
|
||||
Device::factory()->create([
|
||||
'width' => 1024, // Different from default 800
|
||||
'height' => 768, // Different from default 480
|
||||
]);
|
||||
|
||||
// Test that the method detects custom dimensions and resets cache
|
||||
ImageGenerationService::resetIfNotCacheable($plugin);
|
||||
|
||||
$plugin->refresh();
|
||||
expect($plugin->current_image)->toBeNull();
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('reset_if_not_cacheable preserves cache for standard devices', function (): void {
|
||||
// Create a plugin
|
||||
$plugin = App\Models\Plugin::factory()->create(['current_image' => 'test-uuid']);
|
||||
|
||||
// Create devices with standard dimensions
|
||||
Device::factory()->count(3)->create([
|
||||
'width' => 800,
|
||||
'height' => 480,
|
||||
'rotate' => 0,
|
||||
]);
|
||||
|
||||
// Test that the method preserves cache for standard devices
|
||||
ImageGenerationService::resetIfNotCacheable($plugin);
|
||||
|
||||
$plugin->refresh();
|
||||
expect($plugin->current_image)->toBe('test-uuid');
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('reset_if_not_cacheable handles null plugin', function (): void {
|
||||
// Test that the method handles null plugin gracefully
|
||||
expect(fn () => ImageGenerationService::resetIfNotCacheable(null))->not->toThrow(Exception::class);
|
||||
})->skipOnGitHubActions();
|
||||
|
||||
it('image_format enum includes new 2bit 4c format', function (): void {
|
||||
// Test that the new format is properly defined in the enum
|
||||
expect(ImageFormat::PNG_2BIT_4C->value)->toBe('png_2bit_4c');
|
||||
expect(ImageFormat::PNG_2BIT_4C->label())->toBe('PNG 2-bit Grayscale 4c');
|
||||
});
|
||||
|
||||
it('device model relationship works correctly', function (): void {
|
||||
// Create a DeviceModel
|
||||
$deviceModel = DeviceModel::factory()->create();
|
||||
|
||||
// Create a device with the DeviceModel
|
||||
$device = Device::factory()->create([
|
||||
'device_model_id' => $deviceModel->id,
|
||||
]);
|
||||
|
||||
// Test the relationship
|
||||
expect($device->deviceModel)->toBeInstanceOf(DeviceModel::class);
|
||||
expect($device->deviceModel->id)->toBe($deviceModel->id);
|
||||
});
|
||||
|
||||
it('device without device model returns null relationship', function (): void {
|
||||
// Create a device without DeviceModel
|
||||
$device = Device::factory()->create([
|
||||
'device_model_id' => null,
|
||||
]);
|
||||
|
||||
// Test the relationship returns null
|
||||
expect($device->deviceModel)->toBeNull();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue