v0.35.2 80d5067

storage_test.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2package config_test
3
4import (
5	"crypto/sha256"
6	"encoding/base64"
7	"os"
8	"path/filepath"
9	"strings"
10	"testing"
11
12	"bnema.dev/ermite/internal/config"
13	"github.com/stretchr/testify/assert"
14	"github.com/stretchr/testify/require"
15)
16
17func s3Env() map[string]string {
18	return map[string]string{
19		config.EnvS3Bucket: "bucket", config.EnvS3Region: "us-east-1",
20		config.EnvS3AccessKeyID: "private-id", config.EnvS3SecretAccessKey: "private-secret",
21	}
22}
23func TestStorageConfig(t *testing.T) {
24	c, err := config.Load(lookup(valid(nil)))
25	require.NoError(t, err)
26	assert.Empty(t, c.S3Bucket)
27	env := s3Env()
28	env[config.EnvS3Endpoint] = "http://localhost:9000/"
29	env[config.EnvS3Prefix] = "/forge/blobs/"
30	env[config.EnvS3ForcePathStyle] = "1"
31	env[config.EnvReleaseAssetMax] = "512MiB"
32	env[config.EnvReleaseQuota] = "10GiB"
33	env[config.EnvReleaseAssetsMax] = "7"
34	c, err = config.Load(lookup(valid(env)))
35	require.NoError(t, err)
36	assert.Equal(t, "forge/blobs/", c.S3Prefix)
37	assert.Equal(t, "http://localhost:9000", c.S3Endpoint)
38	assert.True(t, c.S3ForcePathStyle)
39	assert.EqualValues(t, 512<<20, c.ReleaseAssetMax)
40	assert.EqualValues(t, 10<<30, c.ReleaseQuota)
41	assert.Equal(t, 7, c.ReleaseAssetsMax)
42	for _, key := range []string{config.EnvS3Region, config.EnvS3AccessKeyID, config.EnvS3SecretAccessKey} {
43		t.Run(key, func(t *testing.T) {
44			env := s3Env()
45			env[key] = ""
46			_, err := config.Load(lookup(valid(env)))
47			require.Error(t, err)
48			assert.Contains(t, err.Error(), key)
49			assert.NotContains(t, err.Error(), "private-")
50		})
51	}
52	for key, value := range map[string]string{config.EnvS3Endpoint: "https://private-id:private-secret@example.org", config.EnvS3ForcePathStyle: "yes", config.EnvS3Prefix: "x/../y", config.EnvReleaseAssetMax: "0", config.EnvReleaseQuota: "-1", config.EnvReleaseAssetsMax: "0"} {
53		t.Run(key+" invalid", func(t *testing.T) {
54			env := s3Env()
55			env[key] = value
56			_, err := config.Load(lookup(valid(env)))
57			require.Error(t, err)
58			assert.Contains(t, err.Error(), key)
59			assert.NotContains(t, err.Error(), "private-")
60		})
61	}
62	for _, value := range []string{"0", "1", "false", "true"} {
63		env := s3Env()
64		env[config.EnvS3ForcePathStyle] = value
65		_, err := config.Load(lookup(valid(env)))
66		require.NoError(t, err)
67	}
68}
69func TestSecretFiles(t *testing.T) {
70	for _, key := range []string{config.EnvAdminToken, config.EnvSecretsKey, config.EnvS3AccessKeyID, config.EnvS3SecretAccessKey} {
71		t.Run(key, func(t *testing.T) {
72			secret := strings.Repeat("s", 32)
73			if key == config.EnvSecretsKey {
74				secret = base64.StdEncoding.EncodeToString([]byte(secret))
75			}
76			path := filepath.Join(t.TempDir(), "secret")
77			require.NoError(t, os.WriteFile(path, []byte(secret+"\r\n"), 0600))
78			env := valid(s3Env())
79			env[key] = ""
80			env[key+"_FILE"] = path
81			c, err := config.Load(lookup(env))
82			require.NoError(t, err)
83			switch key {
84			case config.EnvAdminToken:
85				assert.Equal(t, sha256.Sum256([]byte(secret)), c.AdminTokenHash)
86			case config.EnvSecretsKey:
87				assert.Len(t, c.SecretsKey, 32)
88			case config.EnvS3AccessKeyID:
89				assert.Equal(t, secret, c.S3AccessKeyID)
90			case config.EnvS3SecretAccessKey:
91				assert.Equal(t, secret, c.S3SecretAccessKey)
92			}
93			env[key] = secret
94			_, err = config.Load(lookup(env))
95			require.Error(t, err)
96			assert.Contains(t, err.Error(), "both")
97			assert.NotContains(t, err.Error(), secret)
98			env[key] = ""
99			env[key+"_FILE"] = path + "missing"
100			_, err = config.Load(lookup(env))
101			require.Error(t, err)
102			assert.Contains(t, err.Error(), key+"_FILE")
103			assert.NotContains(t, err.Error(), path)
104			require.NoError(t, os.WriteFile(path, []byte("\n"), 0600))
105			env[key+"_FILE"] = path
106			_, err = config.Load(lookup(env))
107			require.Error(t, err)
108			assert.Contains(t, err.Error(), "empty")
109		})
110	}
111}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 45

↑↓ moveenter openesc close