go.jolheiser.com/git-age@v0.0.4-0.20231114033257-72352f984f8c/cmd/cmd_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"path/filepath"
     7  	"runtime"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/matryer/is"
    12  )
    13  
    14  const (
    15  	ageIntro            = "age-encryption.org/v1"
    16  	ageSecretContent    = "Super duper secret age text!"
    17  	sshSecretContent    = "Super duper secret ssh text!"
    18  	newAgeSecretContent = "Super duper secret age text!!"
    19  )
    20  
    21  func TestGitAge(t *testing.T) {
    22  	assert := is.New(t)
    23  
    24  	gitDir, err := gitBaseDir()
    25  	assert.NoErr(err) // Should get git base dir
    26  	tmp := t.TempDir()
    27  	clone := exec.Command("git", "clone", gitDir, tmp)
    28  	clone.Dir = tmp
    29  	assert.NoErr(clone.Run()) // Should clone project to temp dir
    30  
    31  	ageSecretPath := filepath.Join(tmp, "secrets", "age.txt")
    32  	assertEncrypted(assert, ageSecretPath) // Age secret should be encrypted before init
    33  	sshSecretPath := filepath.Join(tmp, "secrets", "ssh.txt")
    34  	assertEncrypted(assert, sshSecretPath) // SSH secret should be encrypted before init
    35  
    36  	err = os.Chdir(tmp)
    37  	assert.NoErr(err) // Should change to temp dir
    38  	build := exec.Command("go", "build")
    39  	build.Dir = tmp
    40  	err = build.Run()
    41  	assert.NoErr(err) // Should build git-age
    42  	binPath := filepath.Join(tmp, "git-age")
    43  	if runtime.GOOS == "windows" {
    44  		binPath += ".exe"
    45  	}
    46  	bin := func(args ...string) error {
    47  		c := exec.Command(binPath, args...)
    48  		c.Dir = tmp
    49  		return c.Run()
    50  	}
    51  	assertGitCatFileEncrypted(assert) // cat-file should always be encrypted (initial clone)
    52  
    53  	// Init should do nothing at first
    54  	err = bin("init")
    55  	assert.NoErr(err)                      // Should successfully run init
    56  	assertEncrypted(assert, ageSecretPath) // Age secret should be encrypted on init without identities
    57  	assertEncrypted(assert, sshSecretPath) // SSH secret should be encrypted on init without identities
    58  
    59  	// Add identities
    60  	err = bin("ident", "key.txt")
    61  	assert.NoErr(err) // Should add age identity
    62  	err = bin("ident", "ssh")
    63  	assert.NoErr(err) // Should add ssh identity
    64  
    65  	// Init should work now
    66  	err = bin("init")
    67  	assert.NoErr(err) // Should successfully run init
    68  	ageContent, err := os.ReadFile(ageSecretPath)
    69  	assert.NoErr(err)                                   // Should read age secret file
    70  	assert.True(string(ageContent) == ageSecretContent) // Age secret content should match constant
    71  	sshContent, err := os.ReadFile(sshSecretPath)
    72  	assert.NoErr(err)                                   // Should read ssh secret file
    73  	assert.True(string(sshContent) == sshSecretContent) // SSH secret content should match constant
    74  	assertGitCatFileEncrypted(assert)                   // cat-file should always be encrypted (after git-age init)
    75  
    76  	err = os.WriteFile(ageSecretPath, []byte(newAgeSecretContent), os.ModePerm)
    77  	assert.NoErr(err) // Should be able to write the file
    78  
    79  	git := func(args ...string) error {
    80  		args = append([]string{"-c", "user.name=foo", "-c", "user.email=baz@bar.bux", "-c", "commit.gpgsign=false"}, args...)
    81  		c := exec.Command("git", args...)
    82  		c.Dir = tmp
    83  		return c.Run()
    84  	}
    85  
    86  	err = git("add", ageSecretPath)
    87  	assert.NoErr(err) // Git add should succeed
    88  	err = git("commit", "-m", "feat!: YOLO")
    89  	assert.NoErr(err) // Commit should succeed
    90  
    91  	assertGitCatFileEncrypted(assert) // cat-file should always be encrypted (after commit)
    92  }
    93  
    94  func assertGitCatFileEncrypted(t *is.I) {
    95  	t.Helper()
    96  
    97  	out, err := exec.Command("git", "cat-file", "blob", "HEAD:secrets/age.txt").Output()
    98  	t.NoErr(err)
    99  	t.True(strings.HasPrefix(string(out), ageIntro))
   100  }
   101  
   102  func assertEncrypted(t *is.I, fp string) {
   103  	t.Helper()
   104  
   105  	content, err := os.ReadFile(fp)
   106  	t.NoErr(err)
   107  
   108  	t.True(strings.HasPrefix(string(content), ageIntro))
   109  }