db = new TestDb(); $this->db->exec( 'CREATE TABLE bouquets (id INTEGER PRIMARY KEY, bouquet_channels TEXT, bouquet_movies TEXT, bouquet_radios TEXT, bouquet_series TEXT);' ); $this->db->query( 'INSERT INTO bouquets (id, bouquet_channels, bouquet_movies, bouquet_radios, bouquet_series) VALUES (1, ?, ?, "[]", "[]");', '[10,20,30]', '[5,6]' ); BouquetService::setDb($this->db); } private function channels(): array { $this->db->query('SELECT `bouquet_channels` FROM `bouquets` WHERE `id` = 1;'); return json_decode($this->db->get_col(), true); } private function movies(): array { $this->db->query('SELECT `bouquet_movies` FROM `bouquets` WHERE `id` = 1;'); return json_decode($this->db->get_col(), true); } public function testRemovesTheLastElementNotIndexOne(): void { // id 30 is at index 2 — the broken variant would unset index 1 (=> 20). BouquetService::removeItems('stream', 1, [30]); $this->assertSame([10, 20], $this->channels()); } public function testRemovesTheFirstElement(): void { // id 10 is at index 0 — the broken variant would unset index 1 (=> 20). BouquetService::removeItems('stream', 1, [10]); $this->assertSame([20, 30], $this->channels()); } public function testRemovesMultipleIds(): void { BouquetService::removeItems('stream', 1, [10, 30]); $this->assertSame([20], $this->channels()); } public function testRemovingAbsentIdLeavesListUnchanged(): void { BouquetService::removeItems('stream', 1, [999]); $this->assertSame([10, 20, 30], $this->channels()); } public function testAcceptsAScalarId(): void { // array|int|string param: a single scalar is wrapped, not fatal. BouquetService::removeItems('stream', 1, 20); $this->assertSame([10, 30], $this->channels()); } public function testTypeSelectsTheMoviesColumn(): void { BouquetService::removeItems('movie', 1, [5]); $this->assertSame([6], $this->movies()); $this->assertSame([10, 20, 30], $this->channels(), 'channels untouched'); } }