// Copyright 2026 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package v1_26 import ( "testing" "gitea.dev/models/db" "gitea.dev/models/migrations/migrationtest" "gitea.dev/modules/setting" "gitea.dev/modules/test" _ "gitea.dev/models/actions" _ "gitea.dev/models/git" _ "gitea.dev/models/repo" "github.com/stretchr/testify/require" ) func Test_FixCommitStatusTargetURLToUseRunAndJobID(t *testing.T) { defer test.MockVariableValue(&setting.AppSubURL, "")() type Repository struct { ID int64 `xorm:"pk autoincr"` OwnerName string Name string } type ActionRun struct { ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"index"` Index int64 CommitSHA string `xorm:"commit_sha"` Event string TriggerEvent string EventPayload string `xorm:"LONGTEXT"` } type ActionRunJob struct { ID int64 `xorm:"pk autoincr"` RunID int64 `xorm:"index"` } type CommitStatus struct { ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"index"` SHA string TargetURL string } type CommitStatusSummary struct { ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"index"` SHA string `xorm:"VARCHAR(64) NOT NULL"` State string `xorm:"VARCHAR(7) NOT NULL"` TargetURL string } x, deferable := migrationtest.PrepareTestEnv(t, 0, new(Repository), new(ActionRun), new(ActionRunJob), new(CommitStatus), new(CommitStatusSummary), ) defer deferable() require.NoError(t, FixCommitStatusTargetURLToUseRunAndJobID(x)) cases := []struct { table string id int64 want string }{ // Legacy URLs for runs whose resolved run IDs are below the threshold should be rewritten. {table: "commit_status", id: 10010, want: "/testuser/repo1/actions/runs/990/jobs/997"}, {table: "commit_status", id: 10011, want: "/testuser/repo1/actions/runs/990/jobs/998"}, {table: "commit_status", id: 10012, want: "/testuser/repo1/actions/runs/991/jobs/1997"}, // Runs whose resolved IDs are above the threshold are intentionally left unchanged. {table: "commit_status", id: 10013, want: "/testuser/repo1/actions/runs/9/jobs/0"}, // URLs that do not resolve cleanly as legacy Actions URLs should remain untouched. {table: "commit_status", id: 10014, want: "/otheruser/badrepo/actions/runs/7/jobs/0"}, {table: "commit_status", id: 10015, want: "/testuser/repo1/actions/runs/10/jobs/0"}, {table: "commit_status", id: 10016, want: "/testuser/repo1/actions/runs/7/jobs/3"}, {table: "commit_status", id: 10017, want: "https://ci.example.com/build/123"}, // Already ID-based URLs are valid inputs and should not be rewritten again. {table: "commit_status", id: 10018, want: "/testuser/repo1/actions/runs/990/jobs/997"}, // The same rewrite rules apply to commit_status_summary rows. {table: "commit_status_summary", id: 10020, want: "/testuser/repo1/actions/runs/990/jobs/997"}, {table: "commit_status_summary", id: 10021, want: "/testuser/repo1/actions/runs/9/jobs/0"}, } for _, tc := range cases { assertTargetURL(t, x, tc.table, tc.id, tc.want) } } func assertTargetURL(t *testing.T, x db.EngineMigration, table string, id int64, want string) { t.Helper() var row struct { TargetURL string } has, err := x.Table(table).Where("id=?", id).Cols("target_url").Get(&row) require.NoError(t, err) require.Truef(t, has, "row not found: table=%s id=%d", table, id) require.Equal(t, want, row.TargetURL) }