add test for the wall app
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
parent
c4776d81dd
commit
9e287e4e6a
15 changed files with 3022 additions and 1 deletions
355
internal/core/repo_test.go
Normal file
355
internal/core/repo_test.go
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
package core_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
aptclone "github.com/syonad/clonepack/internal/clone/apt"
|
||||
"github.com/syonad/clonepack/internal/core"
|
||||
"github.com/syonad/clonepack/internal/store"
|
||||
)
|
||||
|
||||
// mockRepoStore is an in-memory implementation of store.RepoStore for tests.
|
||||
type mockRepoStore struct {
|
||||
repos map[int64]*store.Repo
|
||||
nextID int64
|
||||
}
|
||||
|
||||
func newMockRepoStore() *mockRepoStore {
|
||||
return &mockRepoStore{repos: make(map[int64]*store.Repo), nextID: 1}
|
||||
}
|
||||
|
||||
func (m *mockRepoStore) CreateRepo(_ context.Context, r *store.Repo) (int64, error) {
|
||||
for _, existing := range m.repos {
|
||||
if existing.Name == r.Name {
|
||||
return 0, errors.New("UNIQUE constraint failed: repos.name")
|
||||
}
|
||||
}
|
||||
id := m.nextID
|
||||
m.nextID++
|
||||
clone := *r
|
||||
clone.ID = id
|
||||
m.repos[id] = &clone
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (m *mockRepoStore) GetRepo(_ context.Context, id int64) (*store.Repo, error) {
|
||||
r, ok := m.repos[id]
|
||||
if !ok {
|
||||
return nil, store.ErrNotFound
|
||||
}
|
||||
clone := *r
|
||||
return &clone, nil
|
||||
}
|
||||
|
||||
func (m *mockRepoStore) GetRepoByName(_ context.Context, name string) (*store.Repo, error) {
|
||||
for _, r := range m.repos {
|
||||
if r.Name == name {
|
||||
clone := *r
|
||||
return &clone, nil
|
||||
}
|
||||
}
|
||||
return nil, store.ErrNotFound
|
||||
}
|
||||
|
||||
func (m *mockRepoStore) ListRepos(_ context.Context) ([]store.Repo, error) {
|
||||
out := make([]store.Repo, 0, len(m.repos))
|
||||
for _, r := range m.repos {
|
||||
out = append(out, *r)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (m *mockRepoStore) DeleteRepo(_ context.Context, id int64) error {
|
||||
if _, ok := m.repos[id]; !ok {
|
||||
return store.ErrNotFound
|
||||
}
|
||||
delete(m.repos, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockRepoStore) UpdateRepoSyncMode(_ context.Context, id int64, mode string) error {
|
||||
r, ok := m.repos[id]
|
||||
if !ok {
|
||||
return store.ErrNotFound
|
||||
}
|
||||
r.SyncMode = mode
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockRepoStore) UpdateRepo(_ context.Context, id int64, sourceURL, syncMode, config string) error {
|
||||
r, ok := m.repos[id]
|
||||
if !ok {
|
||||
return store.ErrNotFound
|
||||
}
|
||||
r.SourceURL = sourceURL
|
||||
r.SyncMode = syncMode
|
||||
r.Config = config
|
||||
return nil
|
||||
}
|
||||
|
||||
func newTestRepoService(t *testing.T) *core.RepoService {
|
||||
t.Helper()
|
||||
return core.NewRepoService(newMockRepoStore(), t.TempDir())
|
||||
}
|
||||
|
||||
// --- Create tests ---
|
||||
|
||||
func TestCreate_validRPM(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
repo, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Name: "rocky9",
|
||||
Type: "rpm",
|
||||
SourceURL: "https://download.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if repo.ID <= 0 {
|
||||
t.Errorf("expected positive ID, got %d", repo.ID)
|
||||
}
|
||||
if repo.SyncMode != "auto" {
|
||||
t.Errorf("default SyncMode: got %q, want auto", repo.SyncMode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate_validAPT(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
repo, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Name: "debian-bookworm",
|
||||
Type: "apt",
|
||||
SourceURL: "https://deb.debian.org/debian",
|
||||
AptSuite: "bookworm",
|
||||
AptComponents: []string{"main", "contrib"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
// Config should be valid JSON with suite set.
|
||||
var cfg aptclone.Config
|
||||
if err := json.Unmarshal([]byte(repo.Config), &cfg); err != nil {
|
||||
t.Fatalf("Config is not valid JSON: %v", err)
|
||||
}
|
||||
if cfg.Suite != "bookworm" {
|
||||
t.Errorf("cfg.Suite: got %q, want bookworm", cfg.Suite)
|
||||
}
|
||||
if len(cfg.Components) != 2 {
|
||||
t.Errorf("cfg.Components: got %v, want [main contrib]", cfg.Components)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate_aptDefaultsComponents(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
repo, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Name: "debian-minimal",
|
||||
Type: "apt",
|
||||
SourceURL: "https://deb.debian.org/debian",
|
||||
AptSuite: "bookworm",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
var cfg aptclone.Config
|
||||
json.Unmarshal([]byte(repo.Config), &cfg)
|
||||
if len(cfg.Components) == 0 {
|
||||
t.Error("expected default components, got empty")
|
||||
}
|
||||
if len(cfg.Architectures) == 0 {
|
||||
t.Error("expected default architectures, got empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate_missingName(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
_, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Type: "rpm",
|
||||
SourceURL: "https://example.com",
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("expected error for missing name, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate_invalidType(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
_, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Name: "bad-type",
|
||||
Type: "maven",
|
||||
SourceURL: "https://example.com",
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("expected error for invalid type, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate_missingSourceURL(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
_, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Name: "no-url",
|
||||
Type: "rpm",
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("expected error for missing source_url, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate_aptMissingSuite(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
_, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Name: "apt-no-suite",
|
||||
Type: "apt",
|
||||
SourceURL: "https://deb.debian.org/debian",
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("expected error for missing apt_suite, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate_invalidSyncMode(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
_, err := svc.Create(context.Background(), core.CreateRepoInput{
|
||||
Name: "bad-mode",
|
||||
Type: "rpm",
|
||||
SourceURL: "https://example.com",
|
||||
SyncMode: "cron",
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("expected error for invalid sync_mode, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Update tests ---
|
||||
|
||||
func TestUpdate_changeSourceURL(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
repo, _ := svc.Create(ctx, core.CreateRepoInput{
|
||||
Name: "rpm-repo",
|
||||
Type: "rpm",
|
||||
SourceURL: "https://old.example.com",
|
||||
})
|
||||
|
||||
newURL := "https://new.example.com"
|
||||
updated, err := svc.Update(ctx, repo.ID, core.UpdateRepoInput{SourceURL: &newURL})
|
||||
if err != nil {
|
||||
t.Fatalf("Update: %v", err)
|
||||
}
|
||||
if updated.SourceURL != newURL {
|
||||
t.Errorf("SourceURL: got %q, want %q", updated.SourceURL, newURL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate_changeSyncMode(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
repo, _ := svc.Create(ctx, core.CreateRepoInput{
|
||||
Name: "rpm-repo-2",
|
||||
Type: "rpm",
|
||||
SourceURL: "https://example.com",
|
||||
})
|
||||
|
||||
mode := "manual"
|
||||
updated, err := svc.Update(ctx, repo.ID, core.UpdateRepoInput{SyncMode: &mode})
|
||||
if err != nil {
|
||||
t.Fatalf("Update: %v", err)
|
||||
}
|
||||
if updated.SyncMode != "manual" {
|
||||
t.Errorf("SyncMode: got %q, want manual", updated.SyncMode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate_aptComponents(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
repo, _ := svc.Create(ctx, core.CreateRepoInput{
|
||||
Name: "apt-repo",
|
||||
Type: "apt",
|
||||
SourceURL: "https://deb.debian.org/debian",
|
||||
AptSuite: "bookworm",
|
||||
})
|
||||
|
||||
suite := "bookworm-backports"
|
||||
updated, err := svc.Update(ctx, repo.ID, core.UpdateRepoInput{
|
||||
AptSuite: &suite,
|
||||
AptComponents: []string{"main", "contrib", "non-free"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Update: %v", err)
|
||||
}
|
||||
|
||||
var cfg aptclone.Config
|
||||
if err := json.Unmarshal([]byte(updated.Config), &cfg); err != nil {
|
||||
t.Fatalf("Config JSON: %v", err)
|
||||
}
|
||||
if cfg.Suite != "bookworm-backports" {
|
||||
t.Errorf("Suite: got %q, want bookworm-backports", cfg.Suite)
|
||||
}
|
||||
if len(cfg.Components) != 3 {
|
||||
t.Errorf("Components: got %v", cfg.Components)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate_invalidSyncMode(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
repo, _ := svc.Create(ctx, core.CreateRepoInput{
|
||||
Name: "rpm-repo-3",
|
||||
Type: "rpm",
|
||||
SourceURL: "https://example.com",
|
||||
})
|
||||
|
||||
bad := "weekly"
|
||||
_, err := svc.Update(ctx, repo.ID, core.UpdateRepoInput{SyncMode: &bad})
|
||||
if err == nil {
|
||||
t.Error("expected error for invalid sync_mode, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate_aptFieldsOnRPMRepo(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
repo, _ := svc.Create(ctx, core.CreateRepoInput{
|
||||
Name: "rpm-repo-4",
|
||||
Type: "rpm",
|
||||
SourceURL: "https://example.com",
|
||||
})
|
||||
|
||||
suite := "bookworm"
|
||||
_, err := svc.Update(ctx, repo.ID, core.UpdateRepoInput{AptSuite: &suite})
|
||||
if err == nil {
|
||||
t.Error("expected error applying apt fields to rpm repo, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate_emptySourceURL(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
repo, _ := svc.Create(ctx, core.CreateRepoInput{
|
||||
Name: "rpm-repo-5",
|
||||
Type: "rpm",
|
||||
SourceURL: "https://example.com",
|
||||
})
|
||||
|
||||
empty := ""
|
||||
_, err := svc.Update(ctx, repo.ID, core.UpdateRepoInput{SourceURL: &empty})
|
||||
if err == nil {
|
||||
t.Error("expected error for empty source_url, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate_notFound(t *testing.T) {
|
||||
svc := newTestRepoService(t)
|
||||
url := "https://example.com"
|
||||
_, err := svc.Update(context.Background(), 9999, core.UpdateRepoInput{SourceURL: &url})
|
||||
if !errors.Is(err, store.ErrNotFound) {
|
||||
t.Errorf("expected ErrNotFound, got %v", err)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue