getEm(); $em->getConnection()->executeStatement('DELETE FROM weighbridge_dsd_counter'); $em->createQuery('DELETE FROM '.User::class.' u WHERE u.username LIKE :p') ->setParameter('p', 'testuser_%')->execute(); $em->createQuery('DELETE FROM '.Role::class.' r WHERE r.code LIKE :p') ->setParameter('p', 'test_%')->execute(); parent::tearDown(); } public function testAutoWeighingReturnsWeightInBoundsAndDsd(): void { $client = $this->manageClientWithCurrentSite(); $response = $client->request('POST', '/api/weighbridge_readings', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => ['mode' => 'AUTO'], ]); self::assertResponseStatusCodeSame(200); $data = $response->toArray(); self::assertSame('AUTO', $data['mode']); self::assertIsInt($data['weight']); self::assertGreaterThanOrEqual(10000, $data['weight']); self::assertLessThanOrEqual(50000, $data['weight']); self::assertIsInt($data['dsd']); self::assertGreaterThanOrEqual(1, $data['dsd']); // manualNumber est null en mode bascule (cle potentiellement omise si // skip_null_values est actif — tolerant aux deux cas). self::assertNull($data['manualNumber'] ?? null); } public function testManualWeighingKeepsWeightAndAllocatesDsd(): void { $client = $this->manageClientWithCurrentSite(); $response = $client->request('POST', '/api/weighbridge_readings', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => ['mode' => 'MANUAL', 'weight' => 23187, 'manualNumber' => 'PAP-555'], ]); self::assertResponseStatusCodeSame(200); $data = $response->toArray(); self::assertSame('MANUAL', $data['mode']); self::assertSame(23187, $data['weight']); self::assertSame('PAP-555', $data['manualNumber']); self::assertGreaterThanOrEqual(1, $data['dsd']); } public function testManagePermissionIsRequired(): void { // Un user portant uniquement `view` ne peut pas declencher de pesee. $credentials = $this->createUserWithPermission('logistique.weighing_tickets.view'); $client = $this->authenticatedClient($credentials['username'], $credentials['password']); $client->request('POST', '/api/weighbridge_readings', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => ['mode' => 'AUTO'], ]); self::assertResponseStatusCodeSame(403); } public function testInvalidModeIsRejected(): void { $client = $this->manageClientWithCurrentSite(); $client->request('POST', '/api/weighbridge_readings', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => ['mode' => 'INVALID'], ]); self::assertResponseStatusCodeSame(422); } public function testManualWeighingRequiresWeight(): void { $client = $this->manageClientWithCurrentSite(); $client->request('POST', '/api/weighbridge_readings', [ 'headers' => ['Content-Type' => 'application/ld+json'], 'json' => ['mode' => 'MANUAL'], ]); self::assertResponseStatusCodeSame(422); } /** * Cree un user non-admin portant `logistique.weighing_tickets.manage`, lui * positionne un site courant (l'endpoint est cloisonne par site, § 2.3) et * renvoie un client authentifie. */ private function manageClientWithCurrentSite(): Client { $credentials = $this->createUserWithPermission('logistique.weighing_tickets.manage'); $em = $this->getEm(); $user = $em->getRepository(User::class)->findOneBy(['username' => $credentials['username']]); self::assertInstanceOf(User::class, $user); $site = $em->getRepository(Site::class)->findAll()[0]; $user->setCurrentSite($site); $em->flush(); return $this->authenticatedClient($credentials['username'], $credentials['password']); } }