Files
Gitea/modelmigration/v1_28/v346_test.go
T
TheFox0x7 e23fe79e5e feat(licenses): support REUSE specification in licenses (#38720)
extends the current license detection to support two modes:
- legacy which is using classification and was expanded to handle more
paths (extensions, different spelling or GNU copying file)
- REUSE which avoids classification by relying on the spec dictating
that license must be named as SPDX-ID.extension. Newly created
repositories will default to REUSE based paths

Use of styles at the same time is not allowed by design.

Extends the UI to show all the detected licenses and paths to them,
deduplicating them per SPDX-ID in database as is in github

closes: https://github.com/go-gitea/gitea/issues/28672


---------

Assisted-By: omp:glm5.2
Assisted-By: omp:mimo-v2.5-pro
Assisted-By: omp:mimimax-m3
Assisted-By: omp:kimi-k3
Assisted-By: omp:deepseek-v4-flash
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-03 07:34:53 +00:00

81 lines
3.2 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_28
import (
"context"
"testing"
"gitea.dev/modelmigration/migrationtest"
"gitea.dev/modules/timeutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"xorm.io/xorm/schemas"
)
// repoLicenseBeforeV345 mirrors the pre-migration repo_license table: no
// license_path column and a 2-column UNIQUE(s) index on (repo_id, license).
type repoLicenseBeforeV345 struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s) NOT NULL"`
CommitID string
License string `xorm:"VARCHAR(255) UNIQUE(s) NOT NULL"`
CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
}
func (repoLicenseBeforeV345) TableName() string { return "repo_license" }
func Test_AddLicensePathToRepoLicense(t *testing.T) {
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(repoLicenseBeforeV345))
defer deferable()
_, err := x.Insert(&repoLicenseBeforeV345{RepoID: 1, CommitID: "c1", License: "MIT"})
require.NoError(t, err)
_, err = x.Insert(&repoLicenseBeforeV345{RepoID: 1, CommitID: "c1", License: "Apache-2.0"})
require.NoError(t, err)
_, err = x.Insert(&repoLicenseBeforeV345{RepoID: 2, CommitID: "c2", License: "MIT"})
require.NoError(t, err)
indexes, err := x.Dialect().GetIndexes(x.DB(), context.Background(), "repo_license")
require.NoError(t, err)
oldIdx, ok := indexes["s"] // GetIndexes strips the UQE_repo_license_ prefix
require.True(t, ok, "old 2-column unique s index should exist before migration")
assert.Equal(t, schemas.UniqueType, oldIdx.Type)
assert.Equal(t, []string{"repo_id", "license"}, oldIdx.Cols)
require.NoError(t, AddLicensePathToRepoLicense(t.Context(), x))
require.NoError(t, AddLicensePathToRepoLicense(t.Context(), x)) // idempotent
indexes, err = x.Dialect().GetIndexes(x.DB(), context.Background(), "repo_license")
require.NoError(t, err)
assert.NotContains(t, indexes, "s", "old 2-column unique s index should be gone after migration")
newIdx, ok := indexes["path"] // GetIndexes strips the UQE_repo_license_ prefix
require.True(t, ok, "new index must be named path (UQE_repo_license_path)")
assert.Equal(t, schemas.UniqueType, newIdx.Type)
assert.Equal(t, []string{"repo_id", "license", "license_path"}, newIdx.Cols)
// pre-existing rows must default to the LICENSE path
type licenseRow struct {
RepoID int64
License string
LicensePath string
}
var rows []licenseRow
require.NoError(t, x.SQL("SELECT repo_id, license, license_path FROM repo_license ORDER BY id").Find(&rows))
require.Len(t, rows, 3)
for _, r := range rows {
assert.Equal(t, "LICENSE", r.LicensePath)
}
// the new index is unique per (repo_id, license, license_path): the exact
// duplicate must be rejected, while a second path for the same license
// in the same repo is allowed
_, err = x.Exec("INSERT INTO repo_license (repo_id, commit_id, license, license_path) VALUES (1, 'c1', 'MIT', 'LICENSE')")
require.Error(t, err)
_, err = x.Exec("INSERT INTO repo_license (repo_id, commit_id, license, license_path) VALUES (1, 'c1', 'MIT', 'LICENSES/MIT.txt')")
require.NoError(t, err)
}