Skip to content

Commit d38b606

Browse files
peterdemeClaude
and
Claude
committed
refactor: migrate from goblin to standard Go tests
- Replaced the goblin test framework with standard Go testing - Used subtests (t.Run()) for better test organization - Used testify/assert and testify/require for assertions - Removed unused dependencies (franela/goblin, onsi/gomega) - Fixed linting issues in http_client.go 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: peterdeme <[email protected]>
1 parent 734e625 commit d38b606

File tree

6 files changed

+227
-267
lines changed

6 files changed

+227
-267
lines changed

go.mod

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ go 1.24
44

55
require (
66
github.com/bugsnag/bugsnag-go/v2 v2.5.1
7-
github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf
87
github.com/go-kit/log v0.2.1
98
github.com/kr/text v0.2.0
10-
github.com/onsi/gomega v1.37.0
119
github.com/pkg/errors v0.9.1
1210
github.com/spacelift-io/spcontext v0.0.7
1311
github.com/stretchr/testify v1.10.0

go.sum

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4
3232
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
3333
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
3434
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
35-
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
36-
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
3735
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
3836
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
3937
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -45,8 +43,6 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
4543
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
4644
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
4745
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
48-
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
49-
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
5046
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
5147
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
5248
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
@@ -62,10 +58,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
6258
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
6359
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
6460
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
65-
github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0=
66-
github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
67-
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
68-
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
61+
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
62+
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
6963
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
7064
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
7165
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -154,8 +148,6 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn
154148
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
155149
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
156150
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
157-
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
158-
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
159151
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
160152
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
161153
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

logging/http_client.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func (cli *HTTPClient) Do(req *http.Request) (*http.Response, error) {
4141
req.Body = io.NopCloser(bytes.NewReader(data))
4242

4343
dataToLog := maybeJSONFromBody(data)
44-
fmt.Fprintf(reqWriter, interpretControlSequences(string(dataToLog))+"\n")
44+
_, _ = fmt.Fprintf(reqWriter, "%s\n", interpretControlSequences(string(dataToLog)))
4545
buffer.Write([]byte("\n"))
4646
}
4747

@@ -52,7 +52,7 @@ func (cli *HTTPClient) Do(req *http.Request) (*http.Response, error) {
5252
return res, resErr
5353
}
5454

55-
fmt.Fprintf(resWriter, "%s\n", res.Status)
55+
_, _ = fmt.Fprintf(resWriter, "%s\n", res.Status)
5656
printHeaders(resWriter, res.Header)
5757
data, err := io.ReadAll(res.Body)
5858
if err != nil {
@@ -61,8 +61,8 @@ func (cli *HTTPClient) Do(req *http.Request) (*http.Response, error) {
6161
res.Body = io.NopCloser(bytes.NewReader(data))
6262

6363
dataToLog := maybeJSONFromBody(data)
64-
fmt.Fprintf(resWriter, interpretControlSequences(string(dataToLog))+"\n")
65-
fmt.Fprintf(buffer, "\n")
64+
_, _ = fmt.Fprintf(resWriter, "%s\n", interpretControlSequences(string(dataToLog)))
65+
_, _ = fmt.Fprintf(buffer, "\n")
6666

6767
return res, nil
6868
}

privatevcs/validation/blocklist/list_test.go

Lines changed: 91 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -4,126 +4,102 @@ import (
44
"net/http"
55
"testing"
66

7-
"github.com/franela/goblin"
87
"github.com/go-kit/log"
9-
. "github.com/onsi/gomega"
108
"github.com/spacelift-io/spcontext"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
1111

1212
"github.com/spacelift-io/vcs-agent/privatevcs/validation/blocklist"
1313
)
1414

15-
func TestList(t *testing.T) {
16-
g := goblin.Goblin(t)
17-
RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })
18-
19-
g.Describe("List", func() {
20-
var sut *blocklist.List
21-
22-
g.Describe("Load", func() {
23-
var err error
24-
var path string
25-
26-
g.JustBeforeEach(func() { sut, err = blocklist.Load(path) })
27-
28-
g.Describe("with an invalid path", func() {
29-
g.BeforeEach(func() { path = "fixtures/not.there" })
30-
31-
g.It("should return an error", func() {
32-
Expect(sut).To(BeNil())
33-
Expect(err).To(MatchError(`couldn't read the blocklist file "fixtures/not.there": open fixtures/not.there: no such file or directory`))
34-
})
35-
})
36-
37-
g.Describe("with a duplicate rule", func() {
38-
g.BeforeEach(func() { path = "fixtures/duplicate.yaml" })
39-
40-
g.It("should return an error", func() {
41-
Expect(sut).To(BeNil())
42-
Expect(err).To(MatchError(`invalid blocklist file "fixtures/duplicate.yaml": duplicate rule name "Duplicate"`))
43-
})
44-
})
45-
46-
g.Describe("with an invalid rule", func() {
47-
g.BeforeEach(func() { path = "fixtures/invalid.yaml" })
48-
49-
g.It("should return an error", func() {
50-
Expect(sut).To(BeNil())
51-
Expect(err).To(MatchError("invalid blocklist file \"fixtures/invalid.yaml\": invalid rule 0: could not compile rule \"Invalid\": invalid path matcher: error parsing regexp: missing closing ]: `[`"))
52-
})
53-
})
54-
55-
g.Describe("with a valid blocklist", func() {
56-
g.BeforeEach(func() { path = "fixtures/valid.yaml" })
57-
58-
g.It("should not return an error", func() {
59-
Expect(err).To(BeNil())
60-
})
61-
62-
g.It("should have loaded the rule", func() {
63-
Expect(sut.Rules).To(HaveLen(2))
64-
})
65-
})
66-
})
67-
68-
g.Describe("Validate", func() {
69-
var err error
70-
var ctx *spcontext.Context
71-
var req *http.Request
72-
73-
g.BeforeEach(func() {
74-
ctx = spcontext.New(log.NewNopLogger())
75-
76-
req, err = http.NewRequest("GET", "https://example.com/foo", nil)
77-
if err != nil {
78-
panic(err)
79-
}
80-
81-
sut = new(blocklist.List)
82-
})
83-
84-
g.JustBeforeEach(func() { _, err = sut.Validate(ctx, "", req) })
85-
86-
g.Describe("with an empty list (default)", func() {
87-
g.It("should pass validation", func() {
88-
Expect(err).To(BeNil())
89-
})
90-
})
91-
92-
g.Describe("with a non-matching rule", func() {
93-
g.BeforeEach(func() {
94-
sut.Rules = []*blocklist.Rule{{
95-
Name: "NonMatching",
96-
Method: "POST",
97-
Path: ".*",
98-
}}
99-
100-
if err := sut.Compile(); err != nil {
101-
panic(err)
102-
}
103-
})
104-
105-
g.It("should pass validation", func() {
106-
Expect(err).To(BeNil())
107-
})
108-
})
109-
110-
g.Describe("with a matching rule", func() {
111-
g.BeforeEach(func() {
112-
sut.Rules = []*blocklist.Rule{{
113-
Name: "Matching",
114-
Method: "GET",
115-
Path: "/foo",
116-
}}
117-
118-
if err := sut.Compile(); err != nil {
119-
panic(err)
120-
}
121-
})
122-
123-
g.It("should fail validation", func() {
124-
Expect(err).To(MatchError(`request blocked by rule "Matching"`))
125-
})
126-
})
127-
})
15+
func TestListLoad(t *testing.T) {
16+
t.Run("with an invalid path", func(t *testing.T) {
17+
path := "fixtures/not.there"
18+
19+
sut, err := blocklist.Load(path)
20+
21+
assert.Nil(t, sut)
22+
assert.EqualError(t, err, `couldn't read the blocklist file "fixtures/not.there": open fixtures/not.there: no such file or directory`)
23+
})
24+
25+
t.Run("with a duplicate rule", func(t *testing.T) {
26+
path := "fixtures/duplicate.yaml"
27+
28+
sut, err := blocklist.Load(path)
29+
30+
assert.Nil(t, sut)
31+
assert.EqualError(t, err, `invalid blocklist file "fixtures/duplicate.yaml": duplicate rule name "Duplicate"`)
32+
})
33+
34+
t.Run("with an invalid rule", func(t *testing.T) {
35+
path := "fixtures/invalid.yaml"
36+
37+
sut, err := blocklist.Load(path)
38+
39+
assert.Nil(t, sut)
40+
assert.EqualError(t, err, "invalid blocklist file \"fixtures/invalid.yaml\": invalid rule 0: could not compile rule \"Invalid\": invalid path matcher: error parsing regexp: missing closing ]: `[`")
41+
})
42+
43+
t.Run("with a valid blocklist", func(t *testing.T) {
44+
path := "fixtures/valid.yaml"
45+
46+
sut, err := blocklist.Load(path)
47+
48+
assert.NoError(t, err)
49+
assert.Len(t, sut.Rules, 2)
12850
})
12951
}
52+
53+
func TestListValidate(t *testing.T) {
54+
t.Run("with an empty list (default)", func(t *testing.T) {
55+
ctx := spcontext.New(log.NewNopLogger())
56+
req, err := http.NewRequest("GET", "https://example.com/foo", nil)
57+
require.NoError(t, err, "failed to create request")
58+
59+
sut := new(blocklist.List)
60+
61+
_, err = sut.Validate(ctx, "", req)
62+
63+
assert.NoError(t, err)
64+
})
65+
66+
t.Run("with a non-matching rule", func(t *testing.T) {
67+
ctx := spcontext.New(log.NewNopLogger())
68+
req, err := http.NewRequest("GET", "https://example.com/foo", nil)
69+
require.NoError(t, err, "failed to create request")
70+
71+
sut := new(blocklist.List)
72+
sut.Rules = []*blocklist.Rule{{
73+
Name: "NonMatching",
74+
Method: "POST",
75+
Path: ".*",
76+
}}
77+
78+
err = sut.Compile()
79+
require.NoError(t, err, "failed to compile rules")
80+
81+
_, err = sut.Validate(ctx, "", req)
82+
83+
assert.NoError(t, err)
84+
})
85+
86+
t.Run("with a matching rule", func(t *testing.T) {
87+
ctx := spcontext.New(log.NewNopLogger())
88+
req, err := http.NewRequest("GET", "https://example.com/foo", nil)
89+
require.NoError(t, err, "failed to create request")
90+
91+
sut := new(blocklist.List)
92+
sut.Rules = []*blocklist.Rule{{
93+
Name: "Matching",
94+
Method: "GET",
95+
Path: "/foo",
96+
}}
97+
98+
err = sut.Compile()
99+
require.NoError(t, err, "failed to compile rules")
100+
101+
_, err = sut.Validate(ctx, "", req)
102+
103+
assert.EqualError(t, err, `request blocked by rule "Matching"`)
104+
})
105+
}

0 commit comments

Comments
 (0)