Skip to content
go-libfossil Artifact [eef7d69749]
Login

Artifact [eef7d69749]

Artifact eef7d69749d4425fb2c3b88099f1bc1d1efb1a050386b916634f605e30e16f7c:


package cli

import (
	"os"
	"path/filepath"
	"strings"
	"testing"

	libfossil "github.com/danmestas/go-libfossil"
)

// A late missing payload or overwrite refusal must not leave an earlier file
// exported. Existing destination bytes survive even when --force was requested.
func TestRepoCoPreflightPreservesDestination(t *testing.T) {
	for _, missing := range []bool{false, true} {
		t.Run(map[bool]string{false: "existing", true: "missing"}[missing], func(t *testing.T) {
			dir := t.TempDir()
			path := filepath.Join(dir, "repo.fossil")
			r, err := libfossil.Create(path, libfossil.CreateOpts{User: "u"})
			if err != nil {
				t.Fatal(err)
			}
			_, _, err = r.Commit(libfossil.CommitOpts{User: "u", Files: []libfossil.FileToCommit{
				{Name: "a.txt", Content: []byte("new a")},
				{Name: "z.txt", Content: []byte("new z")},
			}})
			if err != nil {
				t.Fatal(err)
			}
			if missing {
				_, err = r.Inner().DB().Exec(`UPDATE blob SET size=-1, content=NULL
					WHERE rid IN (SELECT fid FROM mlink WHERE fnid IN
					(SELECT fnid FROM filename WHERE name='z.txt'))`)
				if err != nil {
					t.Fatal(err)
				}
			}
			if err := r.Close(); err != nil {
				t.Fatal(err)
			}
			out := filepath.Join(dir, "out")
			if err := os.Mkdir(out, 0o755); err != nil {
				t.Fatal(err)
			}
			keep := "z.txt"
			if missing {
				keep = "a.txt"
			}
			if err := os.WriteFile(filepath.Join(out, keep), []byte("original"), 0o600); err != nil {
				t.Fatal(err)
			}
			err = (&RepoCoCmd{Dir: out, Force: missing}).Run(&Globals{Repo: path})
			if err == nil {
				t.Fatal("export unexpectedly succeeded")
			}
			if missing && !strings.Contains(err.Error(), "required file payload") {
				t.Fatalf("missing payload diagnostic: %v", err)
			}
			got, readErr := os.ReadFile(filepath.Join(out, keep))
			if readErr != nil || string(got) != "original" {
				t.Fatalf("destination changed: %q, %v", got, readErr)
			}
			entries, err := os.ReadDir(out)
			if err != nil || len(entries) != 1 {
				t.Fatalf("partial export left destination entries: %d, %v", len(entries), err)
			}
		})
	}
}