Skip to content

Commit c200c49

Browse files
Merge pull request #51 from PDOK/jd/validation-tests
Added more tests
2 parents 9a53a23 + a112495 commit c200c49

14 files changed

+490
-105
lines changed

internal/webhook/v3/atom_webhook_test.go

Lines changed: 104 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ package v3
2626

2727
import (
2828
"errors"
29-
"fmt"
3029
"os"
31-
"strings"
3230

3331
. "github.com/onsi/ginkgo/v2" //nolint:revive // ginkgo bdd
3432
. "github.com/onsi/gomega" //nolint:revive // ginkgo bdd
@@ -63,124 +61,125 @@ var _ = Describe("Atom Webhook", func() {
6361

6462
Context("When creating or updating Atom under Validating Webhook", func() {
6563
It("Should create atom without errors or warnings", func() {
66-
By("simulating a valid creation scenario")
67-
input, err := os.ReadFile("test_data/input/1-create-no-error-no-warning.yaml")
68-
Expect(err).NotTo(HaveOccurred())
69-
atom := &pdoknlv3.Atom{}
70-
err = yaml.Unmarshal(input, atom)
71-
Expect(err).NotTo(HaveOccurred())
72-
warnings, errors := validator.ValidateCreate(ctx, atom)
73-
Expect(errors).To(BeNil())
74-
Expect(len(warnings)).To(Equal(0))
64+
testCreate(validator, "valid/minimal.yaml", nil)
7565
})
7666

7767
It("Should deny creation if no labels are available", func() {
78-
By("simulating an invalid creation scenario")
79-
input, err := os.ReadFile("test_data/input/2-create-error-no-lables.yaml")
80-
Expect(err).NotTo(HaveOccurred())
81-
atom := &pdoknlv3.Atom{}
82-
err = yaml.Unmarshal(input, atom)
83-
Expect(err).NotTo(HaveOccurred())
84-
warnings, errorsCreate := validator.ValidateCreate(ctx, atom)
85-
86-
expectedError := errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: metadata.labels: Required value: can't be empty")
87-
Expect(len(warnings)).To(Equal(0))
88-
Expect(expectedError.Error()).To(Equal(errorsCreate.Error()))
68+
testCreate(validator, "invalid/no-labels.yaml", errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: metadata.labels: Required value: can't be empty"))
69+
})
70+
71+
It("Should create atom with ingressRouteUrls that contains the service baseUrl", func() {
72+
testCreate(validator, "valid/ingress-route-urls.yaml", nil)
73+
})
74+
75+
It("Should deny creation if ingressRouteUrls is set but does not contain the service baseUrl", func() {
76+
testCreate(
77+
validator,
78+
"invalid/ingress-route-urls-missing-baseurl.yaml",
79+
errors.New("Atom.pdok.nl \"ingress-route-urls\" is invalid: spec.ingressRouteUrls: Invalid value: \"[{http://test.com/path}]\": must contain baseURL: http://localhost:32788/rvo/wetlands/atom"),
80+
)
8981
})
9082

9183
It("Should create and update atom without errors or warnings", func() {
92-
By("simulating a valid creation scenario")
93-
input, err := os.ReadFile("test_data/input/1-create-no-error-no-warning.yaml")
94-
Expect(err).NotTo(HaveOccurred())
95-
atomOld := &pdoknlv3.Atom{}
96-
err = yaml.Unmarshal(input, atomOld)
97-
Expect(err).NotTo(HaveOccurred())
98-
warnings, errors := validator.ValidateCreate(ctx, atomOld)
99-
Expect(errors).To(BeNil())
100-
Expect(len(warnings)).To(Equal(0))
101-
102-
By("simulating a valid update scenario")
103-
input, err = os.ReadFile("test_data/input/3-update-no-error-no-warning.yaml")
104-
Expect(err).NotTo(HaveOccurred())
105-
atomNew := &pdoknlv3.Atom{}
106-
err = yaml.Unmarshal(input, atomNew)
107-
Expect(err).NotTo(HaveOccurred())
108-
warnings, errors = validator.ValidateUpdate(ctx, atomOld, atomNew)
109-
Expect(errors).To(BeNil())
110-
Expect(len(warnings)).To(Equal(0))
84+
testUpdate(validator, "valid/minimal.yaml", "valid/minimal-service-title-changed.yaml", nil)
11185
})
11286

11387
It("Should deny update atom with error label names cannot be added or deleted", func() {
114-
By("simulating a valid creation scenario")
115-
input, err := os.ReadFile("test_data/input/1-create-no-error-no-warning.yaml")
116-
Expect(err).NotTo(HaveOccurred())
117-
atomOld := &pdoknlv3.Atom{}
118-
err = yaml.Unmarshal(input, atomOld)
119-
Expect(err).NotTo(HaveOccurred())
120-
warningsCreate, errorsCreate := validator.ValidateCreate(ctx, atomOld)
121-
Expect(errorsCreate).To(BeNil())
122-
Expect(len(warningsCreate)).To(Equal(0))
123-
124-
By("simulating an invalid update scenario. error label names cannot be added or deleted")
125-
input, err = os.ReadFile("test_data/input/4-update-error-add-or-delete-labels.yaml")
126-
Expect(err).NotTo(HaveOccurred())
127-
atomNew := &pdoknlv3.Atom{}
128-
err = yaml.Unmarshal(input, atomNew)
129-
Expect(err).NotTo(HaveOccurred())
130-
warningsUpdate, errorsUpdate := validator.ValidateUpdate(ctx, atomOld, atomNew)
131-
132-
expectedError := errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: [metadata.labels.pdok.nl/dataset-id: Required value: labels cannot be removed, metadata.labels.pdok.nl/dataset-idsssssssss: Forbidden: new labels cannot be added]")
133-
Expect(len(warningsUpdate)).To(Equal(0))
134-
Expect(expectedError.Error()).To(Equal(errorsUpdate.Error()))
88+
testUpdate(
89+
validator,
90+
"valid/minimal.yaml",
91+
"invalid/minimal-immutable-labels-key-change.yaml",
92+
errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: [metadata.labels.pdok.nl/dataset-id: Required value: labels cannot be removed, metadata.labels.pdok.nl/dataset-idsssssssss: Forbidden: new labels cannot be added]"),
93+
)
13594
})
13695

13796
It("Should deny update atom with error label names are immutable", func() {
138-
By("simulating a valid creation scenario")
139-
input, err := os.ReadFile("test_data/input/1-create-no-error-no-warning.yaml")
140-
Expect(err).NotTo(HaveOccurred())
141-
atomOld := &pdoknlv3.Atom{}
142-
err = yaml.Unmarshal(input, atomOld)
143-
Expect(err).NotTo(HaveOccurred())
144-
warningsCreate, errorsCreate := validator.ValidateCreate(ctx, atomOld)
145-
Expect(errorsCreate).To(BeNil())
146-
Expect(len(warningsCreate)).To(Equal(0))
147-
148-
By("simulating an invalid update scenario. Lablels are immutable")
149-
input, err = os.ReadFile("test_data/input/5-update-error-labels-immutable.yaml")
150-
Expect(err).NotTo(HaveOccurred())
151-
atomNew := &pdoknlv3.Atom{}
152-
err = yaml.Unmarshal(input, atomNew)
153-
Expect(err).NotTo(HaveOccurred())
154-
warningsUpdate, errorsUpdate := validator.ValidateUpdate(ctx, atomOld, atomNew)
155-
156-
fmt.Printf("actual-error test 5 atom-webhook is: \n%v\n", errorsUpdate.Error())
157-
expectedError := errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: metadata.labels.pdok.nl/dataset-id: Invalid value: \"wetlands-changed\": immutable: should be wetlands")
158-
Expect(strings.ReplaceAll(expectedError.Error(), ":", "")).To(Equal(strings.ReplaceAll(errorsUpdate.Error(), ":", "")))
159-
Expect(len(warningsUpdate)).To(Equal(0))
97+
testUpdate(
98+
validator,
99+
"valid/minimal.yaml",
100+
"invalid/minimal-immutable-labels-value-change.yaml",
101+
errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: metadata.labels.pdok.nl/dataset-id: Invalid value: \"wetlands-changed\": immutable: should be: wetlands"),
102+
)
160103
})
161104

162105
It("Should deny update atom with error URL are immutable", func() {
163-
By("simulating a valid creation scenario")
164-
input, err := os.ReadFile("test_data/input/1-create-no-error-no-warning.yaml")
165-
Expect(err).NotTo(HaveOccurred())
166-
atomOld := &pdoknlv3.Atom{}
167-
err = yaml.Unmarshal(input, atomOld)
168-
Expect(err).NotTo(HaveOccurred())
169-
warnings, errorsCreate := validator.ValidateCreate(ctx, atomOld)
170-
Expect(errorsCreate).To(BeNil())
171-
Expect(len(warnings)).To(Equal(0))
172-
173-
By("simulating an invalid update scenario. URL is immutable")
174-
input, err = os.ReadFile("test_data/input/6-update-error-url-immutable.yaml")
175-
Expect(err).NotTo(HaveOccurred())
176-
atomNew := &pdoknlv3.Atom{}
177-
err = yaml.Unmarshal(input, atomNew)
178-
Expect(err).NotTo(HaveOccurred())
179-
warnings, errorsUpdate := validator.ValidateUpdate(ctx, atomOld, atomNew)
180-
181-
expectedError := errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: spec.service.baseUrl: Forbidden: is immutable")
182-
Expect(len(warnings)).To(Equal(0))
183-
Expect(expectedError.Error()).To(Equal(errorsUpdate.Error()))
106+
testUpdate(
107+
validator,
108+
"valid/minimal.yaml",
109+
"invalid/minimal-immutable-url.yaml", errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: spec.service.baseUrl: Forbidden: is immutable"),
110+
)
111+
})
112+
113+
It("Should deny update atom as ingressRouteURLs cannot be removed", func() {
114+
testUpdate(
115+
validator,
116+
"valid/ingress-route-urls.yaml",
117+
"invalid/ingress-route-urls-removed-url.yaml",
118+
errors.New("Atom.pdok.nl \"ingress-route-urls\" is invalid: spec.ingressRouteUrls: Invalid value: \"[{http://localhost:32788/rvo/wetlands/atom}]\": urls cannot be removed, missing: {http://localhost:32788/other/path}"),
119+
)
120+
})
121+
122+
It("Should deny update atom when the service baseUrl is changed and the old value is not added to the ingressRouteUrls", func() {
123+
testUpdate(
124+
validator,
125+
"valid/minimal.yaml",
126+
"invalid/minimal-service-url-changed-ingress-route-urls-missing-old.yaml",
127+
errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: spec.ingressRouteUrls: Invalid value: \"[{http://localhost:32788/new/path}]\": must contain baseURL: http://localhost:32788/rvo/wetlands/atom"),
128+
)
129+
})
130+
131+
It("Should deny update atom when the service baseUrl is changed and the new value is not added to the ingressRouteUrls", func() {
132+
testUpdate(
133+
validator,
134+
"valid/minimal.yaml",
135+
"invalid/minimal-service-url-changed-ingress-route-urls-missing-new.yaml",
136+
errors.New("Atom.pdok.nl \"asis-readonly-prod\" is invalid: spec.ingressRouteUrls: Invalid value: \"[{http://localhost:32788/rvo/wetlands/atom}]\": must contain baseURL: http://localhost:32788/new/path"),
137+
)
138+
})
139+
140+
It("Should create and update atom with changed service url if ingressRouteUrls is filled correctly", func() {
141+
testUpdate(validator, "valid/minimal.yaml", "valid/minimal-service-url-changed.yaml", nil)
184142
})
185143
})
186144
})
145+
146+
func testUpdate(validator AtomCustomValidator, createFile, updateFile string, expectedError error) {
147+
atomOld := testCreate(validator, createFile, nil)
148+
149+
By("Simulating an (in)valid update scenario")
150+
input, err := os.ReadFile("test_data/updates/" + updateFile)
151+
Expect(err).NotTo(HaveOccurred())
152+
atomNew := &pdoknlv3.Atom{}
153+
err = yaml.Unmarshal(input, atomNew)
154+
Expect(err).NotTo(HaveOccurred())
155+
Expect(atomOld.GetName()).To(Equal(atomNew.GetName()))
156+
warnings, errorsUpdate := validator.ValidateUpdate(ctx, atomOld, atomNew)
157+
158+
Expect(len(warnings)).To(Equal(0))
159+
160+
if expectedError == nil {
161+
Expect(errorsUpdate).To(Not(HaveOccurred()))
162+
} else {
163+
Expect(errorsUpdate).To(HaveOccurred())
164+
Expect(expectedError.Error()).To(Equal(errorsUpdate.Error()))
165+
}
166+
}
167+
168+
func testCreate(validator AtomCustomValidator, createFile string, expectedError error) *pdoknlv3.Atom {
169+
By("simulating a (in)valid creation scenario")
170+
input, err := os.ReadFile("test_data/creates/" + createFile)
171+
Expect(err).NotTo(HaveOccurred())
172+
atom := &pdoknlv3.Atom{}
173+
err = yaml.Unmarshal(input, atom)
174+
Expect(err).NotTo(HaveOccurred())
175+
warnings, err := validator.ValidateCreate(ctx, atom)
176+
Expect(len(warnings)).To(Equal(0))
177+
178+
if expectedError == nil {
179+
Expect(err).To(Not(HaveOccurred()))
180+
} else {
181+
Expect(expectedError.Error()).To(Equal(err.Error()))
182+
}
183+
184+
return atom
185+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Directory setup
2+
3+
This directory contains test data to the the Atom validation webhook.
4+
5+
Files inside the `updates` subdirectory correspond to files in the `creates/valid` subdirectory.
6+
7+
For example:
8+
9+
- updates/invalid/**ingress-route-urls**-removed-url.yaml represents an update of the creates/valid/**ingress-route-urls**.yaml.
10+
- updates/valid/**minimal**-service-url-changed.yaml represents an update of the creates/valid/**minimal**.yaml.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
apiVersion: pdok.nl/v3
2+
kind: Atom
3+
metadata:
4+
annotations:
5+
kangaroo.pdok.nl/lifecycle-phase: prod
6+
kangaroo.pdok.nl/service-bundle-ids: 65daed5f-e9e4-5791-a7c9-7e9effcca520
7+
kangaroo.pdok.nl/readonly: "true"
8+
labels:
9+
pdok.nl/dataset-id: wetlands
10+
pdok.nl/owner-id: rvo
11+
pdok.nl/service-type: atom
12+
name: ingress-route-urls
13+
namespace: services
14+
spec:
15+
ingressRouteUrls:
16+
- url: http://test.com/path
17+
service:
18+
baseUrl: http://localhost:32788/rvo/wetlands/atom
19+
datasetFeeds:
20+
- author:
21+
22+
name: Ministerie van EL&I - GIS Competence Center
23+
datasetMetadataLinks:
24+
metadataIdentifier: 07d73b60-dfd6-4c54-9c82-9fac70c6c48e
25+
templates:
26+
- csw
27+
- html
28+
entries:
29+
- content:
30+
Wetlands zijn de natte natuurgebieden in Nederland (44 gebieden).
31+
Het Wetland verdrag is op 2 februari 1971 te Ramsar in Iran ondertekend.
32+
Nederland was een van de zestien landen die het Verdrag toen ondertekende.
33+
downloadlinks:
34+
- data: public/rvo/wetlands/65daed5f-e9e4-5791-a7c9-7e9effcca520/3/wetlands.gpkg
35+
polygon:
36+
bbox:
37+
maxx: "7.5553527"
38+
maxy: "55.66948"
39+
minx: "2.354173"
40+
miny: "50.71447"
41+
srs:
42+
name: Amersfoort / RD New
43+
uri: https://www.opengis.net/def/crs/EPSG/0/28992
44+
technicalName: wetlands
45+
title: wetlands
46+
updated: "2025-02-28T09:04:17Z"
47+
spatialDatasetIdentifierCode: 07d73b60-dfd6-4c54-9c82-9fac70c6c48e
48+
spatialDatasetIdentifierNamespace: http://www.pdok.nl
49+
subtitle: wetlands
50+
technicalName: wetlands
51+
title: wetlands
52+
lang: nl
53+
ownerInfoRef: pdok
54+
rights: https://creativecommons.org/publicdomain/zero/1.0/deed.nl
55+
serviceMetadataLinks:
56+
metadataIdentifier: 2751ba40-5100-4186-81be-b7fdee95b49c
57+
templates:
58+
- csw
59+
- opensearch
60+
- html
61+
subtitle: Download Service van wetlands
62+
title: Wetlands

internal/webhook/v3/test_data/input/2-create-error-no-lables.yaml renamed to internal/webhook/v3/test_data/creates/invalid/no-labels.yaml

File renamed without changes.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
apiVersion: pdok.nl/v3
2+
kind: Atom
3+
metadata:
4+
annotations:
5+
kangaroo.pdok.nl/lifecycle-phase: prod
6+
kangaroo.pdok.nl/service-bundle-ids: 65daed5f-e9e4-5791-a7c9-7e9effcca520
7+
kangaroo.pdok.nl/readonly: "true"
8+
labels:
9+
pdok.nl/dataset-id: wetlands
10+
pdok.nl/owner-id: rvo
11+
pdok.nl/service-type: atom
12+
name: ingress-route-urls
13+
namespace: services
14+
spec:
15+
ingressRouteUrls:
16+
- url: http://localhost:32788/rvo/wetlands/atom
17+
- url: http://localhost:32788/other/path
18+
service:
19+
baseUrl: http://localhost:32788/rvo/wetlands/atom
20+
datasetFeeds:
21+
- author:
22+
23+
name: Ministerie van EL&I - GIS Competence Center
24+
datasetMetadataLinks:
25+
metadataIdentifier: 07d73b60-dfd6-4c54-9c82-9fac70c6c48e
26+
templates:
27+
- csw
28+
- html
29+
entries:
30+
- content:
31+
Wetlands zijn de natte natuurgebieden in Nederland (44 gebieden).
32+
Het Wetland verdrag is op 2 februari 1971 te Ramsar in Iran ondertekend.
33+
Nederland was een van de zestien landen die het Verdrag toen ondertekende.
34+
downloadlinks:
35+
- data: public/rvo/wetlands/65daed5f-e9e4-5791-a7c9-7e9effcca520/3/wetlands.gpkg
36+
polygon:
37+
bbox:
38+
maxx: "7.5553527"
39+
maxy: "55.66948"
40+
minx: "2.354173"
41+
miny: "50.71447"
42+
srs:
43+
name: Amersfoort / RD New
44+
uri: https://www.opengis.net/def/crs/EPSG/0/28992
45+
technicalName: wetlands
46+
title: wetlands
47+
updated: "2025-02-28T09:04:17Z"
48+
spatialDatasetIdentifierCode: 07d73b60-dfd6-4c54-9c82-9fac70c6c48e
49+
spatialDatasetIdentifierNamespace: http://www.pdok.nl
50+
subtitle: wetlands
51+
technicalName: wetlands
52+
title: wetlands
53+
lang: nl
54+
ownerInfoRef: pdok
55+
rights: https://creativecommons.org/publicdomain/zero/1.0/deed.nl
56+
serviceMetadataLinks:
57+
metadataIdentifier: 2751ba40-5100-4186-81be-b7fdee95b49c
58+
templates:
59+
- csw
60+
- opensearch
61+
- html
62+
subtitle: Download Service van wetlands
63+
title: Wetlands

internal/webhook/v3/test_data/input/1-create-no-error-no-warning.yaml renamed to internal/webhook/v3/test_data/creates/valid/minimal.yaml

File renamed without changes.

0 commit comments

Comments
 (0)