env_test.go RawHistoryFolder

1package domain
2
3import (
4	"testing"
5
6	"github.com/stretchr/testify/assert"
7	"github.com/stretchr/testify/require"
8)
9
10func TestValidateEnvKey(t *testing.T) {
11	tests := []struct {
12		name        string
13		key         string
14		wantErr     bool
15		wantErrType error
16	}{
17		{name: "simple", key: "FOO", wantErr: false},
18		{name: "with underscore", key: "FOO_BAR", wantErr: false},
19		{name: "starts with underscore", key: "_PRIVATE", wantErr: false},
20		{name: "lowercase", key: "foo", wantErr: false},
21		{name: "mixed", key: "myApp_v2", wantErr: false},
22		{name: "empty", key: "", wantErr: true, wantErrType: ErrInvalidEnvKey},
23		{name: "starts with number", key: "1BAD", wantErr: true, wantErrType: ErrInvalidEnvKey},
24		{name: "contains dot", key: "FOO.BAR", wantErr: true, wantErrType: ErrInvalidEnvKey},
25		{name: "contains slash", key: "FOO/BAR", wantErr: true, wantErrType: ErrPathTraversal},
26		{name: "contains backslash", key: `FOO\BAR`, wantErr: true, wantErrType: ErrPathTraversal},
27		{name: "path traversal", key: "..", wantErr: true, wantErrType: ErrPathTraversal},
28		{name: "contains hyphen", key: "FOO-BAR", wantErr: true, wantErrType: ErrInvalidEnvKey},
29		{name: "contains space", key: "FOO BAR", wantErr: true, wantErrType: ErrInvalidEnvKey},
30	}
31
32	for _, tt := range tests {
33		t.Run(tt.name, func(t *testing.T) {
34			err := ValidateEnvKey(tt.key)
35			if tt.wantErr {
36				require.Error(t, err)
37				if tt.wantErrType != nil {
38					assert.ErrorIs(t, err, tt.wantErrType)
39				}
40			} else {
41				assert.NoError(t, err)
42			}
43		})
44	}
45}
46
47func TestContainsSecretReference(t *testing.T) {
48	tests := []struct {
49		name     string
50		value    string
51		expected bool
52	}{
53		{name: "simple pass reference", value: "${pass:myapp/db}", expected: true},
54		{name: "simple sops reference", value: "${sops:secrets.yaml#/key}", expected: true},
55		{name: "pass reference in text", value: "prefix-${pass:path}-suffix", expected: true},
56		{name: "sops reference in text", value: "${sops:file.yaml}", expected: true},
57		{name: "no reference - plain text", value: "hello world", expected: false},
58		{name: "no reference - dollar sign only", value: "$FOO", expected: false},
59		{name: "no reference - empty braces", value: "${}", expected: false},
60		{name: "no reference - missing colon", value: "${pass}", expected: false},
61		{name: "no reference - extra braces", value: "${{pass:path}}", expected: false},
62		{name: "normal env var", value: "${FOO}", expected: false},
63		{name: "value with equals and reference", value: "key=${pass:secret}", expected: true},
64		{name: "quoted reference", value: `"${pass:secret}"`, expected: true},
65		{name: "multiple references", value: "${pass:a}${sops:b}", expected: true},
66		{name: "case sensitive - uppercase", value: "${PASS:secret}", expected: false},
67		{name: "case sensitive - mixed", value: "${Pass:secret}", expected: false},
68	}
69
70	for _, tt := range tests {
71		t.Run(tt.name, func(t *testing.T) {
72			result := ContainsSecretReference(tt.value)
73			assert.Equal(t, tt.expected, result)
74		})
75	}
76}

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 7

Tags 106

↑↓ moveenter openesc close