service = static::getContainer()->get(DeviceService::class); } public function test_link_creates_new_device_with_correct_mac_and_user(): void { $user = $this->createUser('link1@example.com'); $device = $this->service->linkToUser('aa:bb:cc:dd:ee:01', $user); $this->assertNotNull($device->getId()); $this->assertSame('AA:BB:CC:DD:EE:01', $device->getMac()); $this->assertSame($user->getId(), $device->getUser()->getId()); } public function test_link_is_idempotent_for_same_user(): void { $user = $this->createUser('link2@example.com'); $d1 = $this->service->linkToUser('aa:bb:cc:dd:ee:02', $user); $d2 = $this->service->linkToUser('aa:bb:cc:dd:ee:02', $user); $this->assertSame($d1->getId(), $d2->getId()); $this->assertSame($user->getId(), $d2->getUser()->getId()); } public function test_link_purges_history_on_ownership_transfer(): void { $user1 = $this->createUser('owner1@example.com'); $user2 = $this->createUser('owner2@example.com'); // Create device owned by user1 with an image and history $device = $this->service->linkToUser('aa:bb:cc:dd:ee:03', $user1); $image = (new Image())->setUser($user1)->setOriginalFilename('x.jpg')->setStoragePath('x'); $image->approveForDevice($device); $this->em()->persist($image); $history = new DeviceImageHistory($device, $image); $this->em()->persist($history); $this->em()->flush(); // Transfer to user2 $this->service->linkToUser('aa:bb:cc:dd:ee:03', $user2); // History should be gone $count = $this->em()->createQueryBuilder() ->select('COUNT(h.id)') ->from(DeviceImageHistory::class, 'h') ->where('h.device = :device') ->setParameter('device', $device) ->getQuery() ->getSingleScalarResult(); $this->assertSame(0, (int) $count); // Approval should be revoked $this->em()->refresh($image); $this->assertFalse($image->isApprovedForDevice($device)); } }