Skip to content

Commit 1e2d00e

Browse files
authored
chore(test): check that the response can contain unknown field (#4805)
1 parent d423821 commit 1e2d00e

File tree

16 files changed

+160
-139
lines changed

16 files changed

+160
-139
lines changed

.github/workflows/check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ jobs:
378378
run: yarn cli cts generate ${{ matrix.client.language }} --language-version ${{ matrix.client.version }}
379379

380380
- name: Run unit CTS
381-
run: yarn cli cts run ${{ matrix.client.language }} --no-e2e
381+
run: yarn cli cts run ${{ matrix.client.language }} --no-e2e -v
382382

383383
- name: Run e2e CTS
384384
id: cts-e2e
Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
11
module github.com/algolia/algoliasearch-client-go/v4
22

33
go 1.21.11
4-
5-
require github.com/go-playground/validator/v10 v10.26.0
6-
7-
require (
8-
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
9-
github.com/go-playground/locales v0.14.1 // indirect
10-
github.com/go-playground/universal-translator v0.18.1 // indirect
11-
github.com/leodido/go-urn v1.4.0 // indirect
12-
golang.org/x/crypto v0.33.0 // indirect
13-
golang.org/x/net v0.34.0 // indirect
14-
golang.org/x/sys v0.30.0 // indirect
15-
golang.org/x/text v0.22.0 // indirect
16-
)
Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +0,0 @@
1-
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2-
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3-
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
4-
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
5-
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
6-
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
7-
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
8-
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
9-
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
10-
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
11-
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
12-
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
13-
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
14-
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
15-
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
16-
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
17-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
18-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
19-
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
20-
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
21-
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
22-
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
23-
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
24-
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
25-
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
26-
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
27-
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
28-
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

scripts/cts/testServer/algoliaMock.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,51 @@ function addRoutes(app: Express): void {
3737
processingTimeMS: 0,
3838
});
3939
});
40+
41+
// languages that just put the response in a map, there is no strict parsing or types to match.
42+
const isLaxLanguage = (lang: string) => {
43+
return lang === 'dart' || lang === 'javascript' || lang === 'python' || lang === 'php';
44+
};
45+
46+
app.get('/1/indexes/:indexName/settings', (req, res) => {
47+
const lang = req.params.indexName.match(/^cts_e2e_unknownField_(.*)$/)?.[1] as string;
48+
let unknown = {};
49+
if (!isLaxLanguage(lang)) {
50+
unknown = {
51+
unknownFieldNameThatWillNeverBeAddedToTheSpecIHope: 'hello',
52+
};
53+
}
54+
55+
res.json({
56+
minWordSizefor1Typo: 12,
57+
minWordSizefor2Typos: 13,
58+
hitsPerPage: 14,
59+
...unknown,
60+
});
61+
});
62+
63+
app.get('/1/indexes/:indexName/rules/:objectID', (req, res) => {
64+
const lang = req.params.indexName.match(/^cts_e2e_unknownFieldNested_(.*)$/)?.[1] as string;
65+
let unknown = {};
66+
if (!isLaxLanguage(lang)) {
67+
unknown = {
68+
unknownFieldNameThatWillNeverBeAddedToTheSpecIHope: 'hello',
69+
};
70+
}
71+
72+
res.json({
73+
objectID: req.params.objectID,
74+
consequence: {
75+
promote: [
76+
{
77+
objectID: '1',
78+
position: 10,
79+
...unknown,
80+
},
81+
],
82+
},
83+
});
84+
});
4085
}
4186

4287
export function algoliaMockServer(): Promise<Server> {

templates/go/client.mustache

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import (
1818
"slices"
1919
"time"
2020

21-
"github.com/go-playground/validator/v10"
22-
2321
"github.com/algolia/algoliasearch-client-go/v4/algolia/call"
2422
"github.com/algolia/algoliasearch-client-go/v4/algolia/compression"
2523
"github.com/algolia/algoliasearch-client-go/v4/algolia/transport"
@@ -284,24 +282,6 @@ func reportError(format string, a ...any) error {
284282
return fmt.Errorf(format, a...)
285283
}
286284

287-
// A wrapper for strict JSON decoding
288-
func newStrictDecoder(data []byte) *json.Decoder { //nolint:unused
289-
dec := json.NewDecoder(bytes.NewBuffer(data))
290-
dec.DisallowUnknownFields()
291-
return dec
292-
}
293-
294-
// A wrapper for validating a struct, returns nil if value is not a struct
295-
func validateStruct(v any) error { //nolint:unused
296-
err := validator.New().Struct(v)
297-
validationErrors, ok := err.(validator.ValidationErrors)
298-
if ok && len(validationErrors) > 0 {
299-
return validationErrors
300-
}
301-
302-
return nil
303-
}
304-
305285
// Set request body from an any
306286
func setBody(body any, c compression.Compression) (*bytes.Buffer, error) {
307287
if body == nil {

templates/go/model_oneof.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error {
2828
{{#vendorExtensions.x-has-discriminator}}
2929
// use discriminator value to speed up the lookup if possible, if not we will try every possibility
3030
var jsonDict map[string]any
31-
_ = newStrictDecoder(data).Decode(&jsonDict)
31+
_ = json.Unmarshal(data, &jsonDict)
3232
{{/vendorExtensions.x-has-discriminator}}
3333
{{#composedSchemas.oneOf}}
3434
{{#vendorExtensions.x-discriminator-fields.size}}
3535
if {{#vendorExtensions.x-discriminator-fields}}utils.HasKey(jsonDict, "{{.}}"){{^-last}} && {{/-last}}{{/vendorExtensions.x-discriminator-fields}} {
3636
{{/vendorExtensions.x-discriminator-fields.size}}
3737
// try to unmarshal data into {{#lambda.type-to-name}}{{{dataType}}}{{/lambda.type-to-name}}
38-
err = newStrictDecoder(data).Decode(&dst.{{#lambda.type-to-name}}{{{dataType}}}{{/lambda.type-to-name}})
39-
if err == nil && validateStruct(dst.{{#lambda.type-to-name}}{{{dataType}}}{{/lambda.type-to-name}}) == nil {
38+
err = json.Unmarshal(data, &dst.{{#lambda.type-to-name}}{{{dataType}}}{{/lambda.type-to-name}})
39+
if err == nil {
4040
return nil // found the correct type
4141
} else {
4242
dst.{{#lambda.type-to-name}}{{{dataType}}}{{/lambda.type-to-name}} = nil

templates/go/snippets/go.mod.mustache

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,3 @@ go 1.21.11
55
replace github.com/algolia/algoliasearch-client-go/v4 => ../../../clients/algoliasearch-client-go
66

77
require github.com/algolia/algoliasearch-client-go/v4 v4.0.0
8-
9-
require (
10-
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
11-
github.com/go-playground/locales v0.14.1 // indirect
12-
github.com/go-playground/universal-translator v0.18.1 // indirect
13-
github.com/go-playground/validator/v10 v10.22.1 // indirect
14-
github.com/leodido/go-urn v1.4.0 // indirect
15-
golang.org/x/crypto v0.22.0 // indirect
16-
golang.org/x/net v0.24.0 // indirect
17-
golang.org/x/sys v0.19.0 // indirect
18-
golang.org/x/text v0.14.0 // indirect
19-
)

templates/kotlin/tests/client/tests.mustache

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fun `{{#lambda.replaceBacktick}}{{{testName}}}{{/lambda.replaceBacktick}}`() = r
3737
assertEquals({{#match}}{{> tests/param_value}}{{/match}}, it.url.host);
3838
{{/testHost}}
3939
}{{/testResponse}}{{#testResponse}}
40-
{{#isHelper}}response = {
40+
response = {
4141
{{^match.isPrimitive}}
4242
assertNotNull(it)
4343
JSONAssert.assertEquals("""{{{match.value}}}""", Json.encodeToString(Json.encodeToJsonElement(it)), JSONCompareMode.STRICT)
@@ -50,11 +50,7 @@ fun `{{#lambda.replaceBacktick}}{{{testName}}}{{/lambda.replaceBacktick}}`() = r
5050
assertEquals({{#match}}{{> tests/param_value}}{{/match}}, it)
5151
{{/match.isNull}}
5252
{{/match.isPrimitive}}
53-
}{{/isHelper}}
54-
{{^isHelper}}response = {
55-
val response = Json.encodeToString(it)
56-
assertEquals({{#match}}{{> tests/param_value}}{{/match}}, response)
57-
}{{/isHelper}}
53+
}
5854
{{/testResponse}}
5955
)
6056
{{/isMethod}}
Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
{{#hasResponse}}let response{{#isGeneric}}: Response<{{#lambda.prefix}}{{{returnType}}}{{/lambda.prefix}}<{{#lambda.prefix}}Hit{{/lambda.prefix}}>>{{/isGeneric}} = {{> tests/method}}{{/hasResponse}}
2-
{{^hasResponse}}let _{{#isGeneric}}: Response<{{#lambda.prefix}}{{{returnType}}}{{/lambda.prefix}}<{{#lambda.prefix}}Hit{{/lambda.prefix}}>>{{/isGeneric}} = {{> tests/method}}{{/hasResponse}}
1+
{{#hasResponse}}let response{{#isGeneric}}: {{#useEchoRequester}}Response<{{/useEchoRequester}}{{#lambda.prefix}}{{{returnType}}}{{/lambda.prefix}}<{{#lambda.prefix}}Hit{{/lambda.prefix}}>{{#useEchoRequester}}>{{/useEchoRequester}}{{/isGeneric}} = {{> tests/method}}{{/hasResponse}}
2+
{{^hasResponse}}let _ = {{> tests/method}}{{/hasResponse}}
33
{{^isHelper}}
44
{{^isBenchmark}}
5-
let responseBodyData = try XCTUnwrap(response.bodyData)
65
{{#useEchoRequester}}
7-
let echoResponse = try CodableHelper.jsonDecoder.decode(EchoResponse.self, from: responseBodyData)
8-
{{/useEchoRequester}}
9-
{{^useEchoRequester}}
10-
let responseBodyJSON = try XCTUnwrap(responseBodyData.jsonString)
6+
let echoResponse = try CodableHelper.jsonDecoder.decode(EchoResponse.self, from: XCTUnwrap(response.bodyData))
117
{{/useEchoRequester}}
128
{{/isBenchmark}}
139
{{/isHelper}}

templates/swift/tests/client/tests.mustache

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@
4141
{{#testResponse}}
4242
{{#isHelper}}
4343
{{^match.isPrimitive}}
44-
let comparableData = try XCTUnwrap("{{#lambda.escapeQuotes}}{{{match.value}}}{{/lambda.escapeQuotes}}".data(using: .utf8))
45-
try XCTLenientAssertEqual(received: CodableHelper.jsonEncoder.encode(response), expected: comparableData)
44+
try XCTLenientAssertEqual(received: response, expected: "{{#lambda.escapeQuotes}}{{{match.value}}}{{/lambda.escapeQuotes}}")
4645
{{/match.isPrimitive}}
4746
{{#match.isPrimitive}}
4847
{{#match.isNull}}
@@ -54,9 +53,7 @@
5453
{{/match.isPrimitive}}
5554
{{/isHelper}}
5655
{{^isHelper}}
57-
let comparableData = "{{#lambda.escapeQuotes}}{{{match.value}}}{{/lambda.escapeQuotes}}".data(using: .utf8)
58-
let comparableJSON = try XCTUnwrap(comparableData?.jsonString)
59-
XCTAssertEqual(comparableJSON, responseBodyJSON);
56+
XTCJSONEquals(received: response, expected: "{{#lambda.escapeQuotes}}{{{match.value}}}{{/lambda.escapeQuotes}}")
6057
{{/isHelper}}
6158
{{/testResponse}}
6259
{{#shouldScope}}

0 commit comments

Comments
 (0)