Skip to content

Commit 08bc3c8

Browse files
committed
test: implement end2end tests
1 parent a3ff814 commit 08bc3c8

10 files changed

Lines changed: 547 additions & 14 deletions

File tree

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,7 @@ test/
3939
# Build results in project root
4040
ctRestClient*
4141

42-
coverage.*
42+
coverage.*
43+
44+
*.kdbx
45+
.vscode

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
.PHONY: test coverage coverage-html coverage-func generate lint build clean help
1+
.PHONY: test alltest coverage coverage-html coverage-func generate lint build clean help
22

33
test:
4+
go test -coverprofile=coverage.out $$(go list ./... | grep -v fakes | grep -v ./tests/end2end)
5+
6+
alltest:
47
go test -coverprofile=coverage.out $$(go list ./... | grep -v fakes)
58

69
coverage-report: test

cmd/ctrestclient/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ func getExecutableDir() string {
104104
}
105105

106106
func getPasswordFromUser() (string, error) {
107+
if password, exists := os.LookupEnv("KEY_PASS_PASSWORD"); exists {
108+
return password, nil
109+
}
110+
107111
fmt.Print("Enter Keepass database password: ")
108112

109113
// Use the appropriate file descriptor based on the platform

go.mod

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module ctRestClient
33
go 1.24.0
44

55
require (
6-
github.com/maxbrunsfeld/counterfeiter/v6 v6.9.0
6+
github.com/lithammer/dedent v1.1.0
77
github.com/onsi/ginkgo/v2 v2.20.2
88
github.com/onsi/gomega v1.34.2
99
golang.org/x/term v0.38.0
@@ -17,11 +17,9 @@ require (
1717
github.com/google/go-cmp v0.6.0 // indirect
1818
github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d // indirect
1919
github.com/kr/pretty v0.3.1 // indirect
20-
github.com/lithammer/dedent v1.1.0 // indirect
21-
golang.org/x/mod v0.31.0 // indirect
2220
golang.org/x/net v0.48.0 // indirect
23-
golang.org/x/sync v0.19.0 // indirect
2421
golang.org/x/sys v0.39.0 // indirect
2522
golang.org/x/tools v0.40.0 // indirect
2623
google.golang.org/protobuf v1.34.2 // indirect
24+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
2725
)

go.sum

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
99
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1010
github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d h1:Jaz2JzpQaQXyET0AjLBXShrthbpqMkhGiEfkcQAiAUs=
1111
github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
12+
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
1213
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
1314
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
15+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
16+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
1417
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
1518
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
1619
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
1720
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
18-
github.com/maxbrunsfeld/counterfeiter/v6 v6.9.0 h1:ERhc+PJKEyqWQnKu7/K0frSVGFihYYImqNdqP5r0cN0=
19-
github.com/maxbrunsfeld/counterfeiter/v6 v6.9.0/go.mod h1:tU2wQdIyJ7fib/YXxFR0dgLlFz3yl4p275UfUKmDFjk=
2021
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
2122
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
2223
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
@@ -26,16 +27,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
2627
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2728
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
2829
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
29-
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
30-
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
3130
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
3231
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
33-
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
34-
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
3532
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
3633
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
37-
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
38-
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
3934
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
4035
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
4136
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=

tests/end2end/README.MD

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Test setup
2+
This tests require a churchtools instance with following groups:
3+
4+
```yaml
5+
testGroup1:
6+
type: dynamic group
7+
members:
8+
- Anna;Mustermann;Musterstraße 1;11111;Musterstadt;weiblich;2008-09-12
9+
- Max;Beispiel;Beispielweg 2;22222;Musterdorf;männlich;2008-09-24
10+
- Lisa;Tester;Testallee 3;33333;Mustertal;weiblich;2008-09-29
11+
- Tom;Probe;Probestraße 4/1;44444;Musterhausen;männlich;2008-09-18
12+
```
13+
14+
```yaml
15+
testGroup2:
16+
type: dynamic group
17+
members:
18+
- Kerstin;Demonstration;Demoweg 5;55555;Musterberg;weiblich;1982-03-25
19+
- Markus;Vorschau;Vorschauplatz 6;66666;Musterfeld;männlich;1982-03-04
20+
```
21+
22+
```yaml
23+
testGroup3:
24+
type: dynamic group
25+
group updates: disabled
26+
members: none
27+
```
28+
29+
```yaml
30+
testGroup4:
31+
type: non dynamic
32+
```
33+

tests/end2end/blocklist_test.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package endtoend_test
2+
3+
import (
4+
"ctRestClient/internal/testutil"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
10+
. "github.com/onsi/ginkgo/v2"
11+
. "github.com/onsi/gomega"
12+
)
13+
14+
var blocklistsDir string
15+
16+
var _ = Describe("running ctRestClient with configured blocklist", func() {
17+
18+
BeforeEach(func() {
19+
configContent := testutil.YamlToString(fmt.Sprintf(`
20+
---
21+
instances:
22+
- hostname: %s
23+
token_name: %s
24+
groups:
25+
- name: testGroup1
26+
fields: [firstName, lastName, street, zip, city, sexId, birthday]
27+
`, ctInstanceUrl, ctInstanceUrl))
28+
29+
configPath = filepath.Join(tempDir, "geburtstage-config.yml")
30+
err = os.WriteFile(configPath, []byte(configContent), 0644)
31+
Expect(err).ToNot(HaveOccurred())
32+
33+
blocklistsDir = filepath.Join(dataDir, "blocklists")
34+
err := os.MkdirAll(blocklistsDir, 0755)
35+
Expect(err).NotTo(HaveOccurred())
36+
})
37+
38+
var _ = Describe("with an empty blocklist", func() {
39+
BeforeEach(func() {
40+
emptyBlocklist := testutil.YamlToString(``)
41+
err = os.WriteFile(filepath.Join(blocklistsDir, "testGroup1.yml"), []byte(emptyBlocklist), 0644)
42+
Expect(err).NotTo(HaveOccurred())
43+
})
44+
45+
It("should create the expected csv files", func() {
46+
runBinary()
47+
48+
csvString := csvFileToString("testGroup1.csv")
49+
50+
Expect(csvString).To(Equal(`firstName;lastName;street;zip;city;sexId;birthday
51+
Anna;Mustermann;Musterstraße 1;11111;Musterstadt;2;2008-09-12
52+
Max;Beispiel;Beispielweg 2;22222;Musterdorf;1;2008-09-24
53+
Lisa;Tester;Testallee 3;33333;Mustertal;2;2008-09-29
54+
Tom;Probe;Probestraße 4/1;44444;Musterhausen;1;2008-09-18
55+
`))
56+
})
57+
58+
It("should log the expected output", func() {
59+
expectedLog := fmt.Sprintf(`%s
60+
[INFO] +----------------------------------------------------------------------+
61+
[INFO] | Processing instance '%s' |
62+
[INFO] +----------------------------------------------------------------------+
63+
[INFO]
64+
[INFO] processing group 'testGroup1'
65+
[INFO] the group has 4 persons
66+
[INFO] using blocklist 'testGroup1.yml'
67+
[INFO] blocked 0 persons
68+
`, LOG_HEADER, ctInstanceUrl)
69+
70+
runBinary()
71+
72+
normalizedLines := getNormalizedLogLines(logFilePath())
73+
expectedLogLines := strings.Split(expectedLog, "\n")
74+
75+
for i, line := range normalizedLines {
76+
Expect(line).To(Equal(expectedLogLines[i]), fmt.Sprintf("Mismatch at line %d:\nExpected: %s\nActual: %s", i+1, expectedLogLines[i], line))
77+
}
78+
})
79+
})
80+
81+
var _ = Describe("with a not matching blocklist", func() {
82+
BeforeEach(func() {
83+
emptyBlocklist := testutil.YamlToString(`
84+
- street: "Non Matching Street"
85+
`)
86+
err = os.WriteFile(filepath.Join(blocklistsDir, "testGroup1.yml"), []byte(emptyBlocklist), 0644)
87+
Expect(err).NotTo(HaveOccurred())
88+
})
89+
90+
It("should create the expected csv files", func() {
91+
runBinary()
92+
93+
csvString := csvFileToString("testGroup1.csv")
94+
95+
Expect(csvString).To(Equal(`firstName;lastName;street;zip;city;sexId;birthday
96+
Anna;Mustermann;Musterstraße 1;11111;Musterstadt;2;2008-09-12
97+
Max;Beispiel;Beispielweg 2;22222;Musterdorf;1;2008-09-24
98+
Lisa;Tester;Testallee 3;33333;Mustertal;2;2008-09-29
99+
Tom;Probe;Probestraße 4/1;44444;Musterhausen;1;2008-09-18
100+
`))
101+
})
102+
103+
It("should log the expected output", func() {
104+
expectedLog := fmt.Sprintf(`%s
105+
[INFO] +----------------------------------------------------------------------+
106+
[INFO] | Processing instance '%s' |
107+
[INFO] +----------------------------------------------------------------------+
108+
[INFO]
109+
[INFO] processing group 'testGroup1'
110+
[INFO] the group has 4 persons
111+
[INFO] using blocklist 'testGroup1.yml'
112+
[INFO] blocked 0 persons
113+
`, LOG_HEADER, ctInstanceUrl)
114+
115+
runBinary()
116+
117+
normalizedLines := getNormalizedLogLines(logFilePath())
118+
expectedLogLines := strings.Split(expectedLog, "\n")
119+
120+
for i, line := range normalizedLines {
121+
Expect(line).To(Equal(expectedLogLines[i]), fmt.Sprintf("Mismatch at line %d:\nExpected: %s\nActual: %s", i+1, expectedLogLines[i], line))
122+
}
123+
})
124+
})
125+
126+
var _ = Describe("with matching blocklist", func() {
127+
BeforeEach(func() {
128+
emptyBlocklist := testutil.YamlToString(`
129+
- street: "Testallee 3"
130+
`)
131+
err = os.WriteFile(filepath.Join(blocklistsDir, "testGroup1.yml"), []byte(emptyBlocklist), 0644)
132+
Expect(err).NotTo(HaveOccurred())
133+
})
134+
135+
It("should create the expected csv files", func() {
136+
runBinary()
137+
138+
csvString := csvFileToString("testGroup1.csv")
139+
140+
Expect(csvString).To(Equal(`firstName;lastName;street;zip;city;sexId;birthday
141+
Anna;Mustermann;Musterstraße 1;11111;Musterstadt;2;2008-09-12
142+
Max;Beispiel;Beispielweg 2;22222;Musterdorf;1;2008-09-24
143+
Tom;Probe;Probestraße 4/1;44444;Musterhausen;1;2008-09-18
144+
`))
145+
})
146+
147+
It("should log the expected output", func() {
148+
expectedLog := fmt.Sprintf(`%s
149+
[INFO] +----------------------------------------------------------------------+
150+
[INFO] | Processing instance '%s' |
151+
[INFO] +----------------------------------------------------------------------+
152+
[INFO]
153+
[INFO] processing group 'testGroup1'
154+
[INFO] the group has 4 persons
155+
[INFO] using blocklist 'testGroup1.yml'
156+
[INFO] -> "Lisa" "Tester" will not be added to csv file
157+
[INFO] blocked 1 persons
158+
`, LOG_HEADER, ctInstanceUrl)
159+
160+
runBinary()
161+
162+
normalizedLines := getNormalizedLogLines(logFilePath())
163+
expectedLogLines := strings.Split(expectedLog, "\n")
164+
165+
for i, line := range normalizedLines {
166+
Expect(line).To(Equal(expectedLogLines[i]), fmt.Sprintf("Mismatch at line %d:\nExpected: %s\nActual: %s", i+1, expectedLogLines[i], line))
167+
}
168+
})
169+
})
170+
})
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package endtoend_test
2+
3+
import (
4+
"ctRestClient/internal/testutil"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
10+
. "github.com/onsi/ginkgo/v2"
11+
. "github.com/onsi/gomega"
12+
)
13+
14+
var _ = Describe("Group status check", func() {
15+
16+
var _ = Describe("with dynamic groups", func() {
17+
BeforeEach(func() {
18+
configContent := testutil.YamlToString(fmt.Sprintf(`
19+
---
20+
instances:
21+
- hostname: %s
22+
token_name: %s
23+
groups:
24+
- name: testGroup3
25+
fields: [firstName, lastName, street, zip, city, sexId, birthday]
26+
`, ctInstanceUrl, ctInstanceUrl))
27+
28+
configPath = filepath.Join(tempDir, "geburtstage-config.yml")
29+
err = os.WriteFile(configPath, []byte(configContent), 0644)
30+
Expect(err).ToNot(HaveOccurred())
31+
})
32+
33+
It("should not create the csv files", func() {
34+
runBinary()
35+
36+
notExistingCsvFile := filepath.Join(filepath.Dir(logFilePath()), ctInstanceUrl, "testGroup1.csv")
37+
Expect(notExistingCsvFile).NotTo(BeAnExistingFile())
38+
})
39+
40+
It("should log the expected output", func() {
41+
expectedLog := fmt.Sprintf(`%s
42+
[INFO] +----------------------------------------------------------------------+
43+
[INFO] | Processing instance '%s' |
44+
[INFO] +----------------------------------------------------------------------+
45+
[INFO]
46+
[INFO] processing group 'testGroup3'
47+
[WARN] skipping csv creation since the group is not active
48+
`, LOG_HEADER, ctInstanceUrl)
49+
50+
runBinary()
51+
52+
normalizedLines := getNormalizedLogLines(logFilePath())
53+
expectedLogLines := strings.Split(expectedLog, "\n")
54+
55+
for i, line := range normalizedLines {
56+
Expect(line).To(Equal(expectedLogLines[i]), fmt.Sprintf("Mismatch at line %d:\nExpected: %s\nActual: %s", i+1, expectedLogLines[i], line))
57+
}
58+
})
59+
})
60+
61+
var _ = Describe("with non dynamic groups", func() {
62+
BeforeEach(func() {
63+
configContent := testutil.YamlToString(fmt.Sprintf(`
64+
---
65+
instances:
66+
- hostname: %s
67+
token_name: %s
68+
groups:
69+
- name: testGroup4
70+
fields: [id, firstName, lastName, street, zip, city, sexId, birthday]
71+
`, ctInstanceUrl, ctInstanceUrl))
72+
73+
configPath = filepath.Join(tempDir, "geburtstage-config.yml")
74+
err = os.WriteFile(configPath, []byte(configContent), 0644)
75+
Expect(err).ToNot(HaveOccurred())
76+
})
77+
78+
It("should log the expected output", func() {
79+
expectedLog := fmt.Sprintf(`%s
80+
[INFO] +----------------------------------------------------------------------+
81+
[INFO] | Processing instance '%s' |
82+
[INFO] +----------------------------------------------------------------------+
83+
[INFO]
84+
[INFO] processing group 'testGroup4'
85+
[INFO] the group has 1 persons
86+
`, LOG_HEADER, ctInstanceUrl)
87+
88+
runBinary()
89+
90+
normalizedLines := getNormalizedLogLines(logFilePath())
91+
expectedLogLines := strings.Split(expectedLog, "\n")
92+
93+
for i, line := range normalizedLines {
94+
Expect(line).To(Equal(expectedLogLines[i]), fmt.Sprintf("Mismatch at line %d:\nExpected: %s\nActual: %s", i+1, expectedLogLines[i], line))
95+
}
96+
})
97+
})
98+
})

0 commit comments

Comments
 (0)