Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/config/read_api_key_file_test.go
3434 views
1
package config_test
2
3
import (
4
"os"
5
"path/filepath"
6
"strings"
7
"testing"
8
9
"github.com/kardolus/chatgpt-cli/config"
10
. "github.com/onsi/gomega"
11
"github.com/sclevine/spec"
12
"github.com/sclevine/spec/report"
13
)
14
15
func TestUnitReadAPIKeyFile(t *testing.T) {
16
spec.Run(t, "ReadAPIKeyFile", testReadAPIKeyFile, spec.Report(report.Terminal{}))
17
}
18
19
func testReadAPIKeyFile(t *testing.T, when spec.G, it spec.S) {
20
it.Before(func() {
21
RegisterTestingT(t)
22
})
23
24
when("the file exists and is small", func() {
25
it("returns trimmed contents", func() {
26
dir := t.TempDir()
27
p := filepath.Join(dir, "key.txt")
28
Expect(os.WriteFile(p, []byte(" sk-test-123 \n"), 0o600)).To(Succeed())
29
30
key, err := config.ReadAPIKeyFile(p)
31
32
Expect(err).NotTo(HaveOccurred())
33
Expect(key).To(Equal("sk-test-123"))
34
})
35
36
it("accepts exactly maxAPIKeyFileBytes bytes", func() {
37
dir := t.TempDir()
38
p := filepath.Join(dir, "key.txt")
39
40
// Build an exactly-max-sized content with no leading/trailing whitespace,
41
// so TrimSpace doesn't change length.
42
content := strings.Repeat("a", int(config.MaxAPIKeyFileBytesForTest()))
43
Expect(os.WriteFile(p, []byte(content), 0o600)).To(Succeed())
44
45
key, err := config.ReadAPIKeyFile(p)
46
47
Expect(err).NotTo(HaveOccurred())
48
Expect(key).To(Equal(content))
49
})
50
})
51
52
when("the file is empty or whitespace", func() {
53
it("returns an 'empty' error for empty file", func() {
54
dir := t.TempDir()
55
p := filepath.Join(dir, "empty.txt")
56
Expect(os.WriteFile(p, []byte(""), 0o600)).To(Succeed())
57
58
_, err := config.ReadAPIKeyFile(p)
59
60
Expect(err).To(HaveOccurred())
61
Expect(err).To(MatchError("api key file is empty"))
62
})
63
64
it("returns an 'empty' error for whitespace-only file", func() {
65
dir := t.TempDir()
66
p := filepath.Join(dir, "ws.txt")
67
Expect(os.WriteFile(p, []byte(" \n\t "), 0o600)).To(Succeed())
68
69
_, err := config.ReadAPIKeyFile(p)
70
71
Expect(err).To(HaveOccurred())
72
Expect(err).To(MatchError("api key file is empty"))
73
})
74
})
75
76
when("the file is too large", func() {
77
it("fails when size is greater than max", func() {
78
dir := t.TempDir()
79
p := filepath.Join(dir, "big.txt")
80
81
maxBytes := int(config.MaxAPIKeyFileBytesForTest())
82
content := strings.Repeat("a", maxBytes+1)
83
Expect(os.WriteFile(p, []byte(content), 0o600)).To(Succeed())
84
85
_, err := config.ReadAPIKeyFile(p)
86
87
Expect(err).To(HaveOccurred())
88
Expect(err.Error()).To(ContainSubstring("api key file too large"))
89
})
90
})
91
92
when("the path cannot be opened", func() {
93
it("returns a wrapped open error", func() {
94
_, err := config.ReadAPIKeyFile(filepath.Join(t.TempDir(), "does-not-exist.txt"))
95
96
Expect(err).To(HaveOccurred())
97
Expect(err.Error()).To(ContainSubstring("failed to open api key file"))
98
// Avoid asserting exact OS error text.
99
})
100
})
101
102
when("the path is not a regular file", func() {
103
it("returns a 'regular file' error for a directory path", func() {
104
dir := t.TempDir()
105
106
_, err := config.ReadAPIKeyFile(dir)
107
108
Expect(err).To(HaveOccurred())
109
Expect(err).To(MatchError("api key file must be a regular file"))
110
})
111
})
112
113
when("path is cleaned", func() {
114
it("works with a path containing .. segments", func() {
115
dir := t.TempDir()
116
sub := filepath.Join(dir, "sub")
117
Expect(os.MkdirAll(sub, 0o700)).To(Succeed())
118
119
target := filepath.Join(dir, "key.txt")
120
Expect(os.WriteFile(target, []byte("sk-test-abc"), 0o600)).To(Succeed())
121
122
// sub/../key.txt -> key.txt
123
p := filepath.Join(sub, "..", "key.txt")
124
125
key, err := config.ReadAPIKeyFile(p)
126
127
Expect(err).NotTo(HaveOccurred())
128
Expect(key).To(Equal("sk-test-abc"))
129
})
130
})
131
}
132
133