withoutMiddleware(EnsurePlatformSession::class); $this->withoutVite(); } private function user(): User { return User::create([ 'public_id' => 'u-'.uniqid(), 'name' => 'Owner', 'email' => uniqid().'@example.com', ]); } private function location(User $user): PosLocation { return PosLocation::create([ 'owner_ref' => $user->public_id, 'name' => 'Main register', 'currency' => 'GHS', ]); } public function test_can_register_register_device_without_token(): void { $user = $this->user(); $location = $this->location($user); $this->actingAs($user) ->post(route('pos.devices.store'), [ 'name' => 'Front till', 'type' => 'register', 'location_id' => $location->id, ]) ->assertRedirect(route('pos.devices.index')); $device = PosDevice::query()->where('owner_ref', $user->public_id)->first(); $this->assertNotNull($device); $this->assertSame('register', $device->type); $this->assertNull($device->device_token); } public function test_customer_display_device_reuses_branch_display_token(): void { $user = $this->user(); $location = $this->location($user); $this->actingAs($user) ->post(route('pos.devices.store'), [ 'name' => 'Counter screen', 'type' => 'customer_display', 'location_id' => $location->id, ]) ->assertRedirect(route('pos.devices.index')); $device = PosDevice::query()->where('owner_ref', $user->public_id)->firstOrFail(); $display = PosCustomerDisplay::query()->where('location_id', $location->id)->firstOrFail(); $this->assertNotEmpty($device->device_token); $this->assertSame($display->token, $device->device_token); } public function test_customer_display_device_requires_branch(): void { $user = $this->user(); $this->location($user); $this->actingAs($user) ->from(route('pos.devices.create')) ->post(route('pos.devices.store'), [ 'name' => 'Orphan screen', 'type' => 'customer_display', 'location_id' => '', ]) ->assertRedirect(route('pos.devices.create')) ->assertSessionHas('error'); } public function test_devices_index_lists_owned_devices(): void { $user = $this->user(); $location = $this->location($user); PosDevice::create([ 'owner_ref' => $user->public_id, 'location_id' => $location->id, 'name' => 'Kitchen pad', 'type' => 'tablet', 'status' => 'offline', ]); $this->actingAs($user) ->get(route('pos.devices.index')) ->assertOk() ->assertSee('Kitchen pad') ->assertSee('Devices'); } public function test_regenerate_token_updates_customer_display(): void { $user = $this->user(); $location = $this->location($user); $device = app(DeviceService::class)->register([ 'owner_ref' => $user->public_id, 'name' => 'Display', 'type' => 'customer_display', 'location_id' => $location->id, ]); $old = $device->device_token; $this->actingAs($user) ->post(route('pos.devices.regenerate-token', $device)) ->assertRedirect(); $device->refresh(); $display = PosCustomerDisplay::query()->where('location_id', $location->id)->firstOrFail(); $this->assertNotSame($old, $device->device_token); $this->assertSame($device->device_token, $display->token); } public function test_customer_display_poll_marks_device_online(): void { $user = $this->user(); $location = $this->location($user); $device = app(DeviceService::class)->register([ 'owner_ref' => $user->public_id, 'name' => 'Display', 'type' => 'customer_display', 'location_id' => $location->id, ]); $this->getJson(route('pos.customer-display.state', ['token' => $device->device_token])) ->assertOk(); $device->refresh(); $this->assertSame('online', $device->status); $this->assertNotNull($device->last_online_at); } }