mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
385 lines
12 KiB
PHP
385 lines
12 KiB
PHP
<?php
|
|
|
|
use App\Models\Device;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Laravel\Sanctum\Sanctum;
|
|
|
|
uses(\Illuminate\Foundation\Testing\RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
Storage::fake('public');
|
|
});
|
|
|
|
test('device can fetch display data with valid credentials', function () {
|
|
$device = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'test-api-key',
|
|
'current_screen_image' => 'test-image',
|
|
]);
|
|
|
|
$response = $this->withHeaders([
|
|
'id' => $device->mac_address,
|
|
'access-token' => $device->api_key,
|
|
'rssi' => -70,
|
|
'battery_voltage' => 3.8,
|
|
'fw-version' => '1.0.0',
|
|
])->get('/api/display');
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'status' => '0',
|
|
'filename' => 'test-image.bmp',
|
|
'refresh_rate' => 900,
|
|
'reset_firmware' => false,
|
|
'update_firmware' => false,
|
|
'firmware_url' => null,
|
|
'special_function' => 'sleep',
|
|
]);
|
|
|
|
expect($device->fresh())
|
|
->last_rssi_level->toBe(-70)
|
|
->last_battery_voltage->toBe(3.8)
|
|
->last_firmware_version->toBe('1.0.0');
|
|
});
|
|
|
|
test('display endpoint includes image_url_timeout when configured', function () {
|
|
$device = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'test-api-key',
|
|
]);
|
|
|
|
config(['services.trmnl.image_url_timeout' => 300]);
|
|
|
|
$response = $this->withHeaders([
|
|
'id' => $device->mac_address,
|
|
'access-token' => $device->api_key,
|
|
'rssi' => -70,
|
|
'battery_voltage' => 3.8,
|
|
'fw-version' => '1.0.0',
|
|
])->get('/api/display');
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'image_url_timeout' => 300,
|
|
]);
|
|
});
|
|
|
|
test('display endpoint omits image_url_timeout when not configured', function () {
|
|
$device = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'test-api-key',
|
|
]);
|
|
|
|
config(['services.trmnl.image_url_timeout' => null]);
|
|
|
|
$response = $this->withHeaders([
|
|
'id' => $device->mac_address,
|
|
'access-token' => $device->api_key,
|
|
'rssi' => -70,
|
|
'battery_voltage' => 3.8,
|
|
'fw-version' => '1.0.0',
|
|
])->get('/api/display');
|
|
|
|
$response->assertOk()
|
|
->assertJsonMissing(['image_url_timeout']);
|
|
});
|
|
|
|
test('new device is auto-assigned to user with auto-assign enabled', function () {
|
|
$user = User::factory()->create(['assign_new_devices' => true]);
|
|
|
|
$response = $this->withHeaders([
|
|
'id' => '00:11:22:33:44:55',
|
|
'access-token' => 'new-device-key',
|
|
'rssi' => -70,
|
|
'battery_voltage' => 3.8,
|
|
'fw-version' => '1.0.0',
|
|
])->get('/api/display');
|
|
|
|
$response->assertOk();
|
|
|
|
$device = Device::where('mac_address', '00:11:22:33:44:55')->first();
|
|
expect($device)
|
|
->not->toBeNull()
|
|
->user_id->toBe($user->id)
|
|
->api_key->toBe('new-device-key');
|
|
});
|
|
|
|
test('device setup endpoint returns correct data', function () {
|
|
$device = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'test-api-key',
|
|
'friendly_id' => 'test-device',
|
|
]);
|
|
|
|
$response = $this->withHeaders([
|
|
'id' => $device->mac_address,
|
|
])->get('/api/setup');
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'api_key' => 'test-api-key',
|
|
'friendly_id' => 'test-device',
|
|
'message' => 'Welcome to TRMNL BYOS',
|
|
]);
|
|
});
|
|
|
|
test('device can submit logs', function () {
|
|
$device = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'test-api-key',
|
|
]);
|
|
|
|
$logData = [
|
|
'log' => [
|
|
'logs_array' => [
|
|
['message' => 'Test log message', 'level' => 'info'],
|
|
],
|
|
],
|
|
];
|
|
|
|
$response = $this->withHeaders([
|
|
'id' => $device->mac_address,
|
|
'access-token' => $device->api_key,
|
|
])->postJson('/api/log', $logData);
|
|
|
|
$response->assertOk()
|
|
->assertJson(['status' => '200']);
|
|
|
|
expect($device->fresh()->last_log_request)
|
|
->toBe($logData);
|
|
});
|
|
|
|
// test('authenticated user can update device display', function () {
|
|
// $user = User::factory()->create();
|
|
// $device = Device::factory()->create(['user_id' => $user->id]);
|
|
//
|
|
// Sanctum::actingAs($user, ['update-screen']);
|
|
//
|
|
// $response = $this->postJson('/api/display/update', [
|
|
// 'device_id' => $device->id,
|
|
// 'markup' => '<div>Test markup</div>'
|
|
// ]);
|
|
//
|
|
// $response->assertOk();
|
|
// });
|
|
|
|
test('user cannot update display for devices they do not own', function () {
|
|
$user = User::factory()->create();
|
|
$otherUser = User::factory()->create();
|
|
$device = Device::factory()->create(['user_id' => $otherUser->id]);
|
|
|
|
Sanctum::actingAs($user, ['update-screen']);
|
|
|
|
$response = $this->postJson('/api/display/update', [
|
|
'device_id' => $device->id,
|
|
'markup' => '<div>Test markup</div>',
|
|
]);
|
|
|
|
$response->assertForbidden();
|
|
});
|
|
|
|
test('invalid device credentials return error', function () {
|
|
$response = $this->withHeaders([
|
|
'id' => 'invalid-mac',
|
|
'access-token' => 'invalid-token',
|
|
])->get('/api/display');
|
|
|
|
$response->assertNotFound()
|
|
->assertJson(['message' => 'MAC Address not registered or invalid access token']);
|
|
});
|
|
|
|
test('log endpoint requires valid device credentials', function () {
|
|
$response = $this->withHeaders([
|
|
'id' => 'invalid-mac',
|
|
'access-token' => 'invalid-token',
|
|
])->postJson('/api/log', ['log' => []]);
|
|
|
|
$response->assertNotFound()
|
|
->assertJson(['message' => 'Device not found or invalid access token']);
|
|
});
|
|
|
|
test('update_firmware flag is only returned once', function () {
|
|
$device = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'test-api-key',
|
|
'proxy_cloud_response' => [
|
|
'update_firmware' => true,
|
|
'firmware_url' => 'https://example.com/firmware.bin',
|
|
],
|
|
]);
|
|
|
|
// First request should return update_firmware as true
|
|
$response = $this->withHeaders([
|
|
'id' => $device->mac_address,
|
|
'access-token' => $device->api_key,
|
|
'rssi' => -70,
|
|
'battery_voltage' => 3.8,
|
|
'fw-version' => '1.0.0',
|
|
])->get('/api/display');
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'update_firmware' => true,
|
|
'firmware_url' => 'https://example.com/firmware.bin',
|
|
]);
|
|
|
|
// Second request should return update_firmware as false
|
|
$response = $this->withHeaders([
|
|
'id' => $device->mac_address,
|
|
'access-token' => $device->api_key,
|
|
'rssi' => -70,
|
|
'battery_voltage' => 3.8,
|
|
'fw-version' => '1.0.0',
|
|
])->get('/api/display');
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'update_firmware' => false,
|
|
'firmware_url' => 'https://example.com/firmware.bin',
|
|
]);
|
|
|
|
// Verify the proxy_cloud_response was updated
|
|
$device->refresh();
|
|
expect($device->proxy_cloud_response['update_firmware'])->toBeFalse();
|
|
});
|
|
|
|
test('authenticated user can fetch device status', function () {
|
|
$user = User::factory()->create();
|
|
$device = Device::factory()->create([
|
|
'user_id' => $user->id,
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'name' => 'Test Device',
|
|
'friendly_id' => 'test-device',
|
|
'last_rssi_level' => -70,
|
|
'last_battery_voltage' => 3.8,
|
|
'last_firmware_version' => '1.0.0',
|
|
'current_screen_image' => 'test-image',
|
|
'default_refresh_interval' => 900,
|
|
]);
|
|
|
|
Sanctum::actingAs($user);
|
|
|
|
$response = $this->getJson('/api/display/status?device_id='.$device->id);
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'id' => $device->id,
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'name' => 'Test Device',
|
|
'friendly_id' => 'test-device',
|
|
'last_rssi_level' => -70,
|
|
'last_battery_voltage' => 3.8,
|
|
'last_firmware_version' => '1.0.0',
|
|
'battery_percent' => 67,
|
|
'wifi_strength' => 2,
|
|
'current_screen_image' => 'test-image',
|
|
'default_refresh_interval' => 900,
|
|
]);
|
|
});
|
|
|
|
test('user cannot fetch status for devices they do not own', function () {
|
|
$user = User::factory()->create();
|
|
$otherUser = User::factory()->create();
|
|
$device = Device::factory()->create(['user_id' => $otherUser->id]);
|
|
|
|
Sanctum::actingAs($user);
|
|
|
|
$response = $this->getJson('/api/display/status?device_id='.$device->id);
|
|
|
|
$response->assertForbidden();
|
|
});
|
|
|
|
test('display status endpoint requires device_id parameter', function () {
|
|
$user = User::factory()->create();
|
|
Sanctum::actingAs($user);
|
|
|
|
$response = $this->getJson('/api/display/status');
|
|
|
|
$response->assertStatus(422)
|
|
->assertJsonValidationErrors(['device_id']);
|
|
});
|
|
|
|
test('display status endpoint requires valid device_id', function () {
|
|
$user = User::factory()->create();
|
|
Sanctum::actingAs($user);
|
|
|
|
$response = $this->getJson('/api/display/status?device_id=999');
|
|
|
|
$response->assertStatus(422)
|
|
->assertJsonValidationErrors(['device_id']);
|
|
});
|
|
|
|
test('device can mirror another device', function () {
|
|
// Create source device with a playlist and image
|
|
$sourceDevice = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'source-api-key',
|
|
'current_screen_image' => 'source-image',
|
|
]);
|
|
|
|
// Create mirroring device
|
|
$mirrorDevice = Device::factory()->create([
|
|
'mac_address' => 'AA:BB:CC:DD:EE:FF',
|
|
'api_key' => 'mirror-api-key',
|
|
'mirror_device_id' => $sourceDevice->id,
|
|
]);
|
|
|
|
// Make request from mirror device
|
|
$response = $this->withHeaders([
|
|
'id' => $mirrorDevice->mac_address,
|
|
'access-token' => $mirrorDevice->api_key,
|
|
'rssi' => -70,
|
|
'battery_voltage' => 3.8,
|
|
'fw-version' => '1.0.0',
|
|
])->get('/api/display');
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'status' => '0',
|
|
'filename' => 'source-image.bmp',
|
|
'refresh_rate' => 900,
|
|
'reset_firmware' => false,
|
|
'update_firmware' => false,
|
|
'firmware_url' => null,
|
|
'special_function' => 'sleep',
|
|
]);
|
|
|
|
// Verify mirror device stats were updated
|
|
expect($mirrorDevice->fresh())
|
|
->last_rssi_level->toBe(-70)
|
|
->last_battery_voltage->toBe(3.8)
|
|
->last_firmware_version->toBe('1.0.0');
|
|
});
|
|
|
|
test('device can fetch current screen data', function () {
|
|
$device = Device::factory()->create([
|
|
'mac_address' => '00:11:22:33:44:55',
|
|
'api_key' => 'test-api-key',
|
|
'current_screen_image' => 'test-image',
|
|
]);
|
|
|
|
$response = $this->withHeaders([
|
|
'access-token' => $device->api_key,
|
|
])->get('/api/current_screen');
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'status' => '0',
|
|
'filename' => 'test-image.bmp',
|
|
'refresh_rate' => 900,
|
|
'reset_firmware' => false,
|
|
'update_firmware' => false,
|
|
'firmware_url' => null,
|
|
'special_function' => 'sleep',
|
|
]);
|
|
});
|
|
|
|
test('current_screen endpoint requires valid device credentials', function () {
|
|
$response = $this->withHeaders([
|
|
'access-token' => 'invalid-token',
|
|
])->get('/api/current_screen');
|
|
|
|
$response->assertNotFound()
|
|
->assertJson(['message' => 'Device not found or invalid access token']);
|
|
});
|