Files
kandev/apps/backend/internal/task/models/remote_contribution_test.go

197 lines
7.0 KiB
Go

package models
import (
"encoding/json"
"strings"
"testing"
)
func TestRemoteContributionRoundTripsAndPreservesUnrelatedMetadata(t *testing.T) {
binding := RemoteContribution{
Version: 1,
Provider: RemoteContributionProviderGitHub,
Kind: RemoteContributionKindPullRequest,
CanonicalURL: "https://github.com/acme/widget/pull/123",
Number: 123,
State: RemoteContributionStateOpen,
BaseBranch: "main",
HeadBranch: "fix/widget",
HeadSHA: "0123456789abcdef0123456789abcdef01234567",
SourceRepository: RemoteContributionRepository{
Host: "github.com",
Path: "contributor/widget",
ProviderID: "42",
RemoteURL: "https://github.com/contributor/widget.git",
},
CollaborationAllowed: true,
}
metadata := map[string]interface{}{"unrelated": "value"}
if err := PutRemoteContribution(metadata, &binding); err != nil {
t.Fatalf("PutRemoteContribution: %v", err)
}
got, ok, err := LoadRemoteContribution(metadata)
if err != nil {
t.Fatalf("LoadRemoteContribution: %v", err)
}
if !ok {
t.Fatal("LoadRemoteContribution reported no binding")
}
if got != binding {
t.Fatalf("round trip mismatch: %#v != %#v", got, binding)
}
if metadata["unrelated"] != "value" {
t.Fatalf("unrelated metadata changed: %#v", metadata)
}
}
func TestValidatePRBaseContributionIdentity(t *testing.T) {
binding := RemoteContribution{
Version: RemoteContributionVersion, Provider: RemoteContributionProviderGitHub,
Kind: RemoteContributionKindPullRequest, CanonicalURL: "https://github.com/upstream/widgets/pull/42",
Number: 42, State: RemoteContributionStateOpen, BaseBranch: "release", HeadBranch: "feature",
HeadSHA: "0123456789abcdef0123456789abcdef01234567", CollaborationAllowed: true,
SourceRepository: RemoteContributionRepository{
Host: "github.com", Path: "fork-owner/widgets",
RemoteURL: "https://github.com/fork-owner/widgets.git",
},
}
base := PRBase{Target: ComparisonTarget{
Version: ComparisonTargetVersion, Provider: ComparisonTargetProviderGitHub,
Kind: ComparisonTargetKindPullRequest, Number: 42, HeadBranch: "feature", TargetBranch: "release",
HeadRepository: ComparisonTargetRepository{
Host: "github.com", Path: "fork-owner/widgets", RemoteURL: binding.SourceRepository.RemoteURL,
},
TargetRepository: ComparisonTargetRepository{
Host: "github.com", Path: "upstream/widgets", RemoteURL: "https://github.com/upstream/widgets.git",
},
}}
if err := ValidatePRBaseContributionIdentity(&base, &binding); err != nil {
t.Fatalf("valid contribution whose attachment is the base repository: %v", err)
}
base.Target.HeadRepository = ComparisonTargetRepository{
Host: "github.com", Path: "other-fork/widgets", RemoteURL: "https://github.com/other-fork/widgets.git",
}
if err := ValidatePRBaseContributionIdentity(&base, &binding); err == nil {
t.Fatal("accepted a same-number PR from a different head repository")
}
}
func TestRemoteContributionRejectsUnsafeOrCredentialBearingValues(t *testing.T) {
base := RemoteContribution{
Version: 1,
Provider: RemoteContributionProviderGitLab,
Kind: RemoteContributionKindMergeRequest,
CanonicalURL: "https://gitlab.example.test/group/widget/-/merge_requests/7",
Number: 7,
State: RemoteContributionStateOpen,
BaseBranch: "main",
HeadBranch: "feature/fix",
HeadSHA: "0123456789abcdef0123456789abcdef01234567",
SourceRepository: RemoteContributionRepository{
Host: "gitlab.example.test",
Path: "group/widget",
RemoteURL: "https://gitlab.example.test/group/widget.git",
},
CollaborationAllowed: true,
}
cases := []struct {
name string
mutate func(*RemoteContribution)
want string
}{
{name: "unsafe head ref", mutate: func(v *RemoteContribution) { v.HeadBranch = "feature/../escape" }, want: "head_branch"},
{name: "unsafe base ref", mutate: func(v *RemoteContribution) { v.BaseBranch = "-main" }, want: "base_branch"},
{name: "credential in source URL", mutate: func(v *RemoteContribution) {
v.SourceRepository.RemoteURL = "https://user:secret@gitlab.example.test/group/widget.git"
}, want: "credentials"},
{name: "unknown version", mutate: func(v *RemoteContribution) { v.Version = 99 }, want: "version"},
{name: "canonical host mismatch", mutate: func(v *RemoteContribution) {
v.CanonicalURL = "https://other.example.test/group/widget/-/merge_requests/7"
}, want: "host"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
candidate := base
tc.mutate(&candidate)
if err := candidate.Validate(); err == nil || !strings.Contains(err.Error(), tc.want) {
t.Fatalf("Validate() error = %v, want substring %q", err, tc.want)
}
})
}
}
func TestRemoteContributionAcceptsGitLabPortAndIPv6Authorities(t *testing.T) {
cases := []struct {
name string
host string
url string
}{
{
name: "custom port",
host: "gitlab.example.test:8443",
url: "https://gitlab.example.test:8443/group/widget",
},
{
name: "bracketed IPv6 with port",
host: "[::1]:8443",
url: "https://[::1]:8443/group/widget",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
binding := RemoteContribution{
Version: RemoteContributionVersion,
Provider: RemoteContributionProviderGitLab,
Kind: RemoteContributionKindMergeRequest,
CanonicalURL: tc.url + "/-/merge_requests/7",
Number: 7,
State: RemoteContributionStateOpen,
BaseBranch: "main",
HeadBranch: "feature/fix",
HeadSHA: "0123456789abcdef0123456789abcdef01234567",
SourceRepository: RemoteContributionRepository{
Host: tc.host,
Path: "group/widget",
RemoteURL: tc.url + ".git",
},
CollaborationAllowed: true,
}
if err := binding.Validate(); err != nil {
t.Fatalf("Validate() error = %v", err)
}
})
}
}
func TestRemoteContributionRejectsInvalidGitLabPortAuthority(t *testing.T) {
binding := RemoteContribution{
Version: RemoteContributionVersion,
Provider: RemoteContributionProviderGitLab,
Kind: RemoteContributionKindMergeRequest,
CanonicalURL: "https://gitlab.example.test:99999/group/widget/-/merge_requests/7",
Number: 7,
State: RemoteContributionStateOpen,
BaseBranch: "main",
HeadBranch: "feature/fix",
HeadSHA: "0123456789abcdef0123456789abcdef01234567",
SourceRepository: RemoteContributionRepository{
Host: "gitlab.example.test:99999",
Path: "group/widget",
RemoteURL: "https://gitlab.example.test:99999/group/widget.git",
},
CollaborationAllowed: true,
}
if err := binding.Validate(); err == nil {
t.Fatal("Validate() accepted an out-of-range port")
}
}
func TestLoadRemoteContributionRejectsMalformedJSON(t *testing.T) {
metadata := map[string]interface{}{RemoteContributionMetadataKey: json.RawMessage(`{"version":1}`)}
if _, ok, err := LoadRemoteContribution(metadata); err == nil || ok {
t.Fatalf("LoadRemoteContribution() = (%v, %v, %v), want error and no binding", ok, err, ok)
}
}