Merge pull request 'Kanban-Farbe verwaister Tickets nach Projekt-Entfernung zuruecksetzen' (#35) from fds2610-bot/monitor:main into main
Reviewed-on: https://codeberg.org/fds2610/monitor/pulls/35
This commit is contained in:
commit
58eb022113
4 changed files with 87 additions and 1 deletions
|
|
@ -170,6 +170,33 @@ final class TicketRepository
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loescht die Projektfarbe von Tickets, deren Quell-Projekt nicht (mehr) in $slugs steht
|
||||||
|
* (Issue #34: nach Entfernen/Umbenennen eines Projekts im Projekte-Modal blieben dessen
|
||||||
|
* Tickets dauerhaft in dessen alter Farbe eingefaerbt, weil CodebergSyncService sie ab
|
||||||
|
* dann gar nicht mehr anfasst). Tickets ohne Projektbezug (repo = NULL, z.B. per API
|
||||||
|
* angelegt) bleiben unberuehrt.
|
||||||
|
*
|
||||||
|
* @param string[] $slugs - aktuell konfigurierte "owner/repo"-Werte.
|
||||||
|
*/
|
||||||
|
public function clearColorForReposNotIn(array $slugs): void
|
||||||
|
{
|
||||||
|
if ($slugs === []) {
|
||||||
|
$this->db->pdo()->exec(
|
||||||
|
"UPDATE tickets SET color = NULL WHERE repo IS NOT NULL AND color IS NOT NULL"
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$placeholders = implode(', ', array_fill(0, count($slugs), '?'));
|
||||||
|
$stmt = $this->db->pdo()->prepare(
|
||||||
|
"UPDATE tickets SET color = NULL
|
||||||
|
WHERE repo IS NOT NULL AND color IS NOT NULL AND repo NOT IN ($placeholders)"
|
||||||
|
);
|
||||||
|
$stmt->execute($slugs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Billiger "Fingerabdruck" (Anzahl + juengster Aenderungszeitpunkt) fuer den SSE-Endpoint
|
* Billiger "Fingerabdruck" (Anzahl + juengster Aenderungszeitpunkt) fuer den SSE-Endpoint
|
||||||
* (Realtime\ChangeFeed, F13) - aendert sich bei jedem Anlegen/Verschieben eines Tickets.
|
* (Realtime\ChangeFeed, F13) - aendert sich bei jedem Anlegen/Verschieben eines Tickets.
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,19 @@ final class CodebergSyncService
|
||||||
*/
|
*/
|
||||||
public function sync(): void
|
public function sync(): void
|
||||||
{
|
{
|
||||||
foreach ($this->repoConfigs->all() as $repoConfig) {
|
$repoConfigs = $this->repoConfigs->all();
|
||||||
|
|
||||||
|
foreach ($repoConfigs as $repoConfig) {
|
||||||
$this->syncRepo($repoConfig['owner'], $repoConfig['repo'], $repoConfig['color']);
|
$this->syncRepo($repoConfig['owner'], $repoConfig['repo'], $repoConfig['color']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #34: Tickets aus zwischenzeitlich entfernten oder umbenannten Projekten werden
|
||||||
|
// oben nicht mehr angefasst und wuerden sonst dauerhaft in der alten, nicht mehr
|
||||||
|
// zutreffenden Projektfarbe angezeigt.
|
||||||
|
$this->tickets->clearColorForReposNotIn(array_map(
|
||||||
|
static fn (array $repoConfig): string => $repoConfig['owner'] . '/' . $repoConfig['repo'],
|
||||||
|
$repoConfigs
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function syncRepo(string $owner, string $repo, string $color): void
|
private function syncRepo(string $owner, string $repo, string $color): void
|
||||||
|
|
|
||||||
|
|
@ -164,4 +164,33 @@ final class TicketRepositoryTest extends TestCase
|
||||||
|
|
||||||
self::assertSame($this->repository->fingerprint(), $this->repository->fingerprint());
|
self::assertSame($this->repository->fingerprint(), $this->repository->fingerprint());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testClearColorForReposNotInRemovesColorFromOrphanedRepo(): void
|
||||||
|
{
|
||||||
|
$kept = $this->repository->create(['title' => 'A', 'repo' => 'fds2610/monitor', 'color' => '#fbca04']);
|
||||||
|
$orphaned = $this->repository->create(['title' => 'B', 'repo' => 'fds2610/altes-projekt', 'color' => '#3b82f6']);
|
||||||
|
|
||||||
|
$this->repository->clearColorForReposNotIn(['fds2610/monitor']);
|
||||||
|
|
||||||
|
self::assertSame('#fbca04', $this->repository->find((int) $kept['id'])['color']);
|
||||||
|
self::assertNull($this->repository->find((int) $orphaned['id'])['color']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClearColorForReposNotInIgnoresTicketsWithoutRepo(): void
|
||||||
|
{
|
||||||
|
$manual = $this->repository->create(['title' => 'API-Ticket', 'color' => '#ffffff']);
|
||||||
|
|
||||||
|
$this->repository->clearColorForReposNotIn(['fds2610/monitor']);
|
||||||
|
|
||||||
|
self::assertSame('#ffffff', $this->repository->find((int) $manual['id'])['color']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClearColorForReposNotInClearsAllColorsWhenNoRepoConfigured(): void
|
||||||
|
{
|
||||||
|
$ticket = $this->repository->create(['title' => 'B', 'repo' => 'fds2610/altes-projekt', 'color' => '#3b82f6']);
|
||||||
|
|
||||||
|
$this->repository->clearColorForReposNotIn([]);
|
||||||
|
|
||||||
|
self::assertNull($this->repository->find((int) $ticket['id'])['color']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,26 @@ final class CodebergSyncServiceTest extends TestCase
|
||||||
self::assertSame('#28a745', $steuerkramTicket['color']);
|
self::assertSame('#28a745', $steuerkramTicket['color']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSyncClearsColorOfTicketsFromRemovedProject(): void
|
||||||
|
{
|
||||||
|
$tickets = new TicketRepository(Database::inMemory());
|
||||||
|
$client = self::clientForMonitor([
|
||||||
|
'open' => [['number' => 1, 'title' => 'Issue', 'body' => null, 'labels' => []]],
|
||||||
|
'closed' => [],
|
||||||
|
]);
|
||||||
|
|
||||||
|
(new CodebergSyncService($client, $tickets, self::repoConfigsFor([self::MONITOR_REPO])))->sync();
|
||||||
|
self::assertSame('#fbca04', $tickets->findByExternalRef('1', self::MONITOR_SLUG)['color']);
|
||||||
|
|
||||||
|
// Projekt wurde im Projekte-Modal entfernt (Issue #34): der naechste Sync-Lauf sieht
|
||||||
|
// es nicht mehr in repoConfigsFor() und darf das verwaiste Ticket nicht laenger blau
|
||||||
|
// faerben, obwohl es kein Projekt mit dieser Farbe mehr gibt.
|
||||||
|
$client = new FakeCodebergClient([]);
|
||||||
|
(new CodebergSyncService($client, $tickets, self::repoConfigsFor([])))->sync();
|
||||||
|
|
||||||
|
self::assertNull($tickets->findByExternalRef('1', self::MONITOR_SLUG)['color']);
|
||||||
|
}
|
||||||
|
|
||||||
public function testSyncDoesNotResetManuallyMovedTicket(): void
|
public function testSyncDoesNotResetManuallyMovedTicket(): void
|
||||||
{
|
{
|
||||||
$tickets = new TicketRepository(Database::inMemory());
|
$tickets = new TicketRepository(Database::inMemory());
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue