@voxgig/sdkgen 0.44.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/cmp/ReadmeEntity.js +9 -153
- package/dist/cmp/ReadmeEntity.js.map +1 -1
- package/dist/cmp/ReadmeIntro.js +9 -14
- package/dist/cmp/ReadmeIntro.js.map +1 -1
- package/dist/cmp/ReadmeModel.js +6 -4
- package/dist/cmp/ReadmeModel.js.map +1 -1
- package/dist/cmp/ReadmeOptions.js +9 -61
- package/dist/cmp/ReadmeOptions.js.map +1 -1
- package/dist/cmp/ReadmeRef.js +10 -1328
- package/dist/cmp/ReadmeRef.js.map +1 -1
- package/dist/sdkgen.d.ts +2 -2
- package/dist/sdkgen.js +2 -1
- package/dist/sdkgen.js.map +1 -1
- package/dist/utility.d.ts +2 -1
- package/dist/utility.js +9 -0
- package/dist/utility.js.map +1 -1
- package/package.json +3 -3
- package/project/.sdk/src/cmp/go/Config_go.ts +9 -4
- package/project/.sdk/src/cmp/go/Entity_go.ts +2 -2
- package/project/.sdk/src/cmp/go/Main_go.ts +8 -4
- package/project/.sdk/src/cmp/go/Package_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +138 -0
- package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +8 -5
- package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeIntro_go.ts +18 -0
- package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +8 -5
- package/project/.sdk/src/cmp/go/ReadmeOptions_go.ts +58 -0
- package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +13 -9
- package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +354 -0
- package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +8 -6
- package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +2 -2
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +222 -41
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +142 -60
- package/project/.sdk/src/cmp/go/Test_go.ts +2 -2
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +21 -4
- package/project/.sdk/src/cmp/js/Config_js.ts +18 -0
- package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +138 -0
- package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +11 -6
- package/project/.sdk/src/cmp/js/ReadmeIntro_js.ts +18 -0
- package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +6 -3
- package/project/.sdk/src/cmp/js/ReadmeOptions_js.ts +58 -0
- package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +6 -4
- package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +384 -0
- package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +6 -4
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +23 -12
- package/project/.sdk/src/cmp/js/TestEntity_js.ts +107 -74
- package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +1 -5
- package/project/.sdk/src/cmp/lua/Config_lua.ts +9 -4
- package/project/.sdk/src/cmp/lua/Package_lua.ts +9 -2
- package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +138 -0
- package/project/.sdk/src/cmp/lua/ReadmeHowto_lua.ts +6 -3
- package/project/.sdk/src/cmp/lua/ReadmeIntro_lua.ts +18 -0
- package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +6 -3
- package/project/.sdk/src/cmp/lua/ReadmeOptions_lua.ts +58 -0
- package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +6 -4
- package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +360 -0
- package/project/.sdk/src/cmp/lua/ReadmeTopQuick_lua.ts +6 -4
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +172 -29
- package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +120 -52
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +20 -4
- package/project/.sdk/src/cmp/php/Config_php.ts +10 -8
- package/project/.sdk/src/cmp/php/Package_php.ts +7 -1
- package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +138 -0
- package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +6 -3
- package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +18 -0
- package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +6 -3
- package/project/.sdk/src/cmp/php/ReadmeOptions_php.ts +58 -0
- package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +6 -4
- package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +358 -0
- package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +6 -4
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +171 -28
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +126 -55
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +17 -3
- package/project/.sdk/src/cmp/py/Config_py.ts +9 -4
- package/project/.sdk/src/cmp/py/Package_py.ts +8 -1
- package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +138 -0
- package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +6 -3
- package/project/.sdk/src/cmp/py/ReadmeIntro_py.ts +18 -0
- package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +6 -3
- package/project/.sdk/src/cmp/py/ReadmeOptions_py.ts +58 -0
- package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +9 -6
- package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +356 -0
- package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +9 -6
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +164 -27
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +125 -51
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -4
- package/project/.sdk/src/cmp/rb/Config_rb.ts +9 -4
- package/project/.sdk/src/cmp/rb/Package_rb.ts +9 -2
- package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +138 -0
- package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +6 -3
- package/project/.sdk/src/cmp/rb/ReadmeIntro_rb.ts +18 -0
- package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +6 -3
- package/project/.sdk/src/cmp/rb/ReadmeOptions_rb.ts +58 -0
- package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +6 -4
- package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +361 -0
- package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +6 -4
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +172 -29
- package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +120 -52
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +19 -3
- package/project/.sdk/src/cmp/ts/Config_ts.ts +18 -0
- package/project/.sdk/src/cmp/ts/Package_ts.ts +1 -1
- package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +138 -0
- package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +11 -6
- package/project/.sdk/src/cmp/ts/ReadmeIntro_ts.ts +18 -0
- package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +9 -5
- package/project/.sdk/src/cmp/ts/ReadmeOptions_ts.ts +58 -0
- package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +6 -4
- package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +384 -0
- package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +6 -4
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +213 -42
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +168 -75
- package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +1 -5
- package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +8 -1
- package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +8 -2
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +21 -1
- package/project/.sdk/tm/go/feature/test_feature.go +51 -3
- package/project/.sdk/tm/go/test/runner_test.go +106 -6
- package/project/.sdk/tm/go/test/sdk-test-control.json +19 -0
- package/project/.sdk/tm/go/utility/fetcher.go +10 -0
- package/project/.sdk/tm/go/utility/make_url.go +12 -0
- package/project/.sdk/tm/go/utility/prepare_auth.go +15 -1
- package/project/.sdk/tm/js/src/utility/PrepareAuthUtility.js +7 -1
- package/project/.sdk/tm/lua/feature/test_feature.lua +41 -3
- package/project/.sdk/tm/lua/test/runner.lua +74 -0
- package/project/.sdk/tm/lua/test/sdk-test-control.json +19 -0
- package/project/.sdk/tm/lua/utility/fetcher.lua +13 -0
- package/project/.sdk/tm/lua/utility/make_url.lua +16 -0
- package/project/.sdk/tm/lua/utility/prepare_auth.lua +9 -1
- package/project/.sdk/tm/php/feature/TestFeature.php +185 -43
- package/project/.sdk/tm/php/test/Runner.php +62 -0
- package/project/.sdk/tm/php/test/sdk-test-control.json +19 -0
- package/project/.sdk/tm/php/utility/Fetcher.php +132 -9
- package/project/.sdk/tm/php/utility/MakeUrl.php +16 -0
- package/project/.sdk/tm/php/utility/PrepareAuth.php +11 -1
- package/project/.sdk/tm/py/feature/test_feature.py +35 -3
- package/project/.sdk/tm/py/test/runner.py +60 -0
- package/project/.sdk/tm/py/test/sdk-test-control.json +19 -0
- package/project/.sdk/tm/py/utility/fetcher.py +13 -0
- package/project/.sdk/tm/py/utility/make_url.py +13 -0
- package/project/.sdk/tm/py/utility/prepare_auth.py +10 -1
- package/project/.sdk/tm/rb/feature/test_feature.rb +36 -3
- package/project/.sdk/tm/rb/test/runner.rb +46 -0
- package/project/.sdk/tm/rb/test/sdk-test-control.json +19 -0
- package/project/.sdk/tm/rb/utility/fetcher.rb +49 -28
- package/project/.sdk/tm/rb/utility/make_url.rb +16 -0
- package/project/.sdk/tm/rb/utility/prepare_auth.rb +8 -1
- package/project/.sdk/tm/ts/src/utility/MakeUrlUtility.ts +7 -8
- package/project/.sdk/tm/ts/src/utility/PrepareAuthUtility.ts +7 -1
- package/project/.sdk/tm/ts/test/sdk-test-control.json +19 -0
- package/project/.sdk/tm/ts/test/utility.ts +120 -2
- package/src/cmp/ReadmeEntity.ts +11 -178
- package/src/cmp/ReadmeIntro.ts +11 -25
- package/src/cmp/ReadmeModel.ts +7 -5
- package/src/cmp/ReadmeOptions.ts +12 -74
- package/src/cmp/ReadmeRef.ts +11 -1372
- package/src/sdkgen.ts +2 -1
- package/src/utility.ts +12 -0
- /package/project/.sdk/tm/go/utility/{make_target.go → make_point.go} +0 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import {
|
|
3
|
+
Model,
|
|
4
|
+
ModelEntity,
|
|
5
|
+
nom,
|
|
3
6
|
depluralize,
|
|
4
7
|
} from '@voxgig/apidef'
|
|
5
8
|
|
|
@@ -8,6 +11,7 @@ import {
|
|
|
8
11
|
File,
|
|
9
12
|
cmp,
|
|
10
13
|
snakify,
|
|
14
|
+
isAuthActive,
|
|
11
15
|
} from '@voxgig/sdkgen'
|
|
12
16
|
|
|
13
17
|
|
|
@@ -55,13 +59,21 @@ function normalizePathParams(
|
|
|
55
59
|
|
|
56
60
|
const TestDirect = cmp(function TestDirect(props: any) {
|
|
57
61
|
const ctx$ = props.ctx$
|
|
58
|
-
const model = ctx$.model
|
|
62
|
+
const model: Model = ctx$.model
|
|
59
63
|
|
|
60
64
|
const target = props.target
|
|
61
|
-
const entity = props.entity
|
|
65
|
+
const entity: ModelEntity = props.entity
|
|
62
66
|
const gomodule = props.gomodule
|
|
63
67
|
|
|
64
|
-
const PROJECTNAME = model
|
|
68
|
+
const PROJECTNAME = nom(model, 'Name').toUpperCase().replace(/[^A-Z_]/g, '_')
|
|
69
|
+
|
|
70
|
+
const authActive = isAuthActive(model)
|
|
71
|
+
const apikeyEnvEntry = authActive
|
|
72
|
+
? `\n\t\t"${PROJECTNAME}_APIKEY": "NONE",`
|
|
73
|
+
: ''
|
|
74
|
+
const apikeyLiveField = authActive
|
|
75
|
+
? `\n\t\t\t"apikey": env["${PROJECTNAME}_APIKEY"],`
|
|
76
|
+
: ''
|
|
65
77
|
|
|
66
78
|
const opnames = Object.keys(entity.op)
|
|
67
79
|
const hasLoad = opnames.includes('load')
|
|
@@ -77,15 +89,64 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
77
89
|
// Get load point info
|
|
78
90
|
const loadPoint = loadOp?.points?.[0]
|
|
79
91
|
const loadPath = loadPoint ? normalizePathParams(loadPoint.parts || [], loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
80
|
-
const
|
|
92
|
+
const allLoadParams = loadPoint?.args?.params || []
|
|
93
|
+
// Some upstream OpenAPI specs declare a parameter as `in: path` even when
|
|
94
|
+
// that path has no `{name}` placeholder for it. Only path params that
|
|
95
|
+
// actually appear in the URL template should drive direct-test path-param
|
|
96
|
+
// setup and URL-substitution asserts; otherwise the SDK silently drops
|
|
97
|
+
// them and the URL-includes assert fails.
|
|
98
|
+
const _pathPlaceholders = new Set<string>()
|
|
99
|
+
for (const part of (loadPoint?.parts || [])) {
|
|
100
|
+
if (typeof part === 'string' && part.startsWith('{') && part.endsWith('}')) {
|
|
101
|
+
_pathPlaceholders.add(part.slice(1, -1))
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const _renameMap = (loadPoint?.rename?.param || {}) as Record<string, string>
|
|
105
|
+
const _renamedPlaceholders = new Set<string>()
|
|
106
|
+
for (const ph of _pathPlaceholders) {
|
|
107
|
+
_renamedPlaceholders.add(ph)
|
|
108
|
+
for (const [orig, renamed] of Object.entries(_renameMap)) {
|
|
109
|
+
if (renamed === ph) _renamedPlaceholders.add(orig)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const loadParams = allLoadParams.filter((p: any) =>
|
|
113
|
+
_renamedPlaceholders.has(p.name) || _renamedPlaceholders.has(p.orig))
|
|
81
114
|
|
|
82
115
|
// Get list point info
|
|
83
116
|
const listPoint = listOp?.points?.[0]
|
|
84
117
|
const listPath = listPoint ? normalizePathParams(listPoint.parts || [], listPoint?.args?.params || [], listPoint?.rename?.param) : ''
|
|
85
118
|
const listParams = listPoint?.args?.params || []
|
|
86
119
|
|
|
120
|
+
// Required query params with spec-provided examples — needed in live mode
|
|
121
|
+
// to satisfy API contracts (e.g. /v2018/history requires city/start/end).
|
|
122
|
+
const loadQuery = loadPoint?.args?.query || []
|
|
123
|
+
const loadLiveQueryEntries = loadQuery
|
|
124
|
+
.filter((q: any) => q.reqd && undefined !== q.example && null !== q.example)
|
|
125
|
+
const loadLiveQueryLines = loadLiveQueryEntries
|
|
126
|
+
.map((q: any) => `\t\t\tquery["${q.name}"] = ${JSON.stringify(q.example)}`)
|
|
127
|
+
.join('\n')
|
|
128
|
+
|
|
129
|
+
const listQuery = listPoint?.args?.query || []
|
|
130
|
+
const listLiveQueryEntries = listQuery
|
|
131
|
+
.filter((q: any) => q.reqd && undefined !== q.example && null !== q.example)
|
|
132
|
+
const listLiveQueryLines = listLiveQueryEntries
|
|
133
|
+
.map((q: any) => `\t\t\tquery["${q.name}"] = ${JSON.stringify(q.example)}`)
|
|
134
|
+
.join('\n')
|
|
135
|
+
|
|
136
|
+
// Path params with spec-provided examples — when ALL load params have
|
|
137
|
+
// spec examples, prefer them over list-bootstrap. Spec example values are
|
|
138
|
+
// by definition real identifiers the API accepts (e.g. casa: "blue",
|
|
139
|
+
// fecha: "2024/01/01"), avoiding the brittle list-bootstrap path-param
|
|
140
|
+
// semantic mismatch.
|
|
141
|
+
const loadAllHaveExamples =
|
|
142
|
+
loadParams.length > 0 &&
|
|
143
|
+
loadParams.every((p: any) => undefined !== p.example && null !== p.example)
|
|
144
|
+
const loadExampleLines = loadAllHaveExamples
|
|
145
|
+
? loadParams.map((p: any) => `\t\t\tparams["${p.name}"] = ${JSON.stringify(p.example)}`).join('\n')
|
|
146
|
+
: ''
|
|
147
|
+
|
|
87
148
|
// Build the ENTID env var name for this entity
|
|
88
|
-
const entidEnvVar = `${PROJECTNAME}_TEST_${entity
|
|
149
|
+
const entidEnvVar = `${PROJECTNAME}_TEST_${nom(entity, 'NAME').replace(/[^A-Z_]/g, '_')}_ENTID`
|
|
89
150
|
|
|
90
151
|
File({ name: entity.name + '_direct_test.' + target.ext }, () => {
|
|
91
152
|
|
|
@@ -119,12 +180,44 @@ func Test${entity.Name}Direct(t *testing.T) {
|
|
|
119
180
|
return { name: p.name, key }
|
|
120
181
|
})
|
|
121
182
|
|
|
183
|
+
// Track idmap keys this test consumes in live mode. If any are
|
|
184
|
+
// missing (no ENTID override), skip — the request would 4xx on
|
|
185
|
+
// undefined path params.
|
|
186
|
+
const listLiveIdKeys = listParams.length > 0
|
|
187
|
+
? listLiveParams.map((lp: any) => lp.key)
|
|
188
|
+
: []
|
|
189
|
+
const listLiveIdKeysGoLiteral = listLiveIdKeys.length > 0
|
|
190
|
+
? `[]string{${listLiveIdKeys.map((k: string) => `"${k}"`).join(', ')}}`
|
|
191
|
+
: ''
|
|
192
|
+
const listSkipBlock = listLiveIdKeys.length > 0
|
|
193
|
+
? ` if setup.live {
|
|
194
|
+
for _, _liveKey := range ${listLiveIdKeysGoLiteral} {
|
|
195
|
+
if v := setup.idmap[_liveKey]; v == nil {
|
|
196
|
+
t.Skipf("live test needs %s via *_ENTID env var (synthetic IDs only)", _liveKey)
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
`
|
|
202
|
+
: ''
|
|
203
|
+
|
|
122
204
|
Content(` t.Run("direct-list-${entity.name}", func(t *testing.T) {
|
|
123
205
|
setup := ${entity.name}DirectSetup([]any{
|
|
124
206
|
map[string]any{"id": "direct01"},
|
|
125
207
|
map[string]any{"id": "direct02"},
|
|
126
208
|
})
|
|
127
|
-
|
|
209
|
+
_mode := "unit"
|
|
210
|
+
if setup.live {
|
|
211
|
+
_mode = "live"
|
|
212
|
+
}
|
|
213
|
+
if _shouldSkip, _reason := isControlSkipped("direct", "direct-list-${entity.name}", _mode); _shouldSkip {
|
|
214
|
+
if _reason == "" {
|
|
215
|
+
_reason = "skipped via sdk-test-control.json"
|
|
216
|
+
}
|
|
217
|
+
t.Skip(_reason)
|
|
218
|
+
return
|
|
219
|
+
}
|
|
220
|
+
${listSkipBlock} client := setup.client
|
|
128
221
|
|
|
129
222
|
`)
|
|
130
223
|
|
|
@@ -160,15 +253,30 @@ func Test${entity.Name}Direct(t *testing.T) {
|
|
|
160
253
|
`)
|
|
161
254
|
}
|
|
162
255
|
|
|
163
|
-
Content(` if
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
256
|
+
Content(` if setup.live {
|
|
257
|
+
// Live mode is lenient: synthetic IDs frequently 4xx and the
|
|
258
|
+
// list-response shape varies wildly across public APIs. Skip
|
|
259
|
+
// rather than fail when the call doesn't return a usable list.
|
|
260
|
+
if err != nil {
|
|
261
|
+
t.Skipf("list call failed (likely synthetic IDs against live API): %v", err)
|
|
262
|
+
}
|
|
263
|
+
if result["ok"] != true {
|
|
264
|
+
t.Skipf("list call not ok (likely synthetic IDs against live API): %v", result)
|
|
265
|
+
}
|
|
266
|
+
status := core.ToInt(result["status"])
|
|
267
|
+
if status < 200 || status >= 300 {
|
|
268
|
+
t.Skipf("expected 2xx status, got %v", result["status"])
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
if err != nil {
|
|
272
|
+
t.Fatalf("direct failed: %v", err)
|
|
273
|
+
}
|
|
274
|
+
if result["ok"] != true {
|
|
275
|
+
t.Fatalf("expected ok to be true, got %v", result["ok"])
|
|
276
|
+
}
|
|
277
|
+
if core.ToInt(result["status"]) != 200 {
|
|
278
|
+
t.Fatalf("expected status 200, got %v", result["status"])
|
|
279
|
+
}
|
|
172
280
|
}
|
|
173
281
|
|
|
174
282
|
if !setup.live {
|
|
@@ -220,22 +328,75 @@ func Test${entity.Name}Direct(t *testing.T) {
|
|
|
220
328
|
// Identify ancestor params (not 'id') for live mode
|
|
221
329
|
const ancestorParams = loadParams.filter((p: any) => p.name !== 'id')
|
|
222
330
|
|
|
331
|
+
// Determine which idmap keys this load test will consume in live mode.
|
|
332
|
+
// - allHaveExamples: spec provides example values for every load
|
|
333
|
+
// path-param, so live mode uses them — no idmap needed.
|
|
334
|
+
// - hasList: we list-bootstrap, so we need the keys for the list call's
|
|
335
|
+
// path params (ancestors of the list path).
|
|
336
|
+
// - synthetic-only: we'd use idmap for load path-params; without an
|
|
337
|
+
// override they're undefined and the live request 4xx's.
|
|
338
|
+
let loadLiveIdKeys: string[] = []
|
|
339
|
+
if (loadParams.length > 0 && !loadAllHaveExamples) {
|
|
340
|
+
if (hasList) {
|
|
341
|
+
loadLiveIdKeys = listParams.map((p: any) => {
|
|
342
|
+
return p.name === 'id'
|
|
343
|
+
? entity.name + '01'
|
|
344
|
+
: p.name.replace(/_id$/, '') + '01'
|
|
345
|
+
})
|
|
346
|
+
} else {
|
|
347
|
+
loadLiveIdKeys = loadParams.map((p: any) => p.name + '01')
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const loadSkipBlock = loadLiveIdKeys.length > 0
|
|
351
|
+
? ` if setup.live {
|
|
352
|
+
for _, _liveKey := range []string{${loadLiveIdKeys.map(k => `"${k}"`).join(', ')}} {
|
|
353
|
+
if v := setup.idmap[_liveKey]; v == nil {
|
|
354
|
+
t.Skipf("live test needs %s via *_ENTID env var (synthetic IDs only)", _liveKey)
|
|
355
|
+
return
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
`
|
|
360
|
+
: ''
|
|
361
|
+
|
|
223
362
|
Content(` t.Run("direct-load-${entity.name}", func(t *testing.T) {
|
|
224
363
|
setup := ${entity.name}DirectSetup(map[string]any{"id": "direct01"})
|
|
225
|
-
|
|
364
|
+
_mode := "unit"
|
|
365
|
+
if setup.live {
|
|
366
|
+
_mode = "live"
|
|
367
|
+
}
|
|
368
|
+
if _shouldSkip, _reason := isControlSkipped("direct", "direct-load-${entity.name}", _mode); _shouldSkip {
|
|
369
|
+
if _reason == "" {
|
|
370
|
+
_reason = "skipped via sdk-test-control.json"
|
|
371
|
+
}
|
|
372
|
+
t.Skip(_reason)
|
|
373
|
+
return
|
|
374
|
+
}
|
|
375
|
+
${loadSkipBlock} client := setup.client
|
|
226
376
|
|
|
227
377
|
`)
|
|
228
378
|
|
|
229
|
-
|
|
379
|
+
// Always emit a query map so the test can pass it to Direct(); only
|
|
380
|
+
// set values in live mode.
|
|
381
|
+
const needsQuery = loadParams.length > 0 || loadLiveQueryLines !== ''
|
|
382
|
+
if (needsQuery) {
|
|
230
383
|
Content(` params := map[string]any{}
|
|
384
|
+
query := map[string]any{}
|
|
231
385
|
`)
|
|
232
386
|
|
|
233
387
|
Content(` if setup.live {
|
|
234
388
|
`)
|
|
235
389
|
|
|
236
|
-
//
|
|
237
|
-
if (
|
|
238
|
-
|
|
390
|
+
// Required-query setup (e.g. /v2018/history needs city/start/end).
|
|
391
|
+
if (loadLiveQueryLines) {
|
|
392
|
+
Content(loadLiveQueryLines + '\n')
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (loadAllHaveExamples) {
|
|
396
|
+
// Use spec-provided path-param examples — no list bootstrap needed.
|
|
397
|
+
Content(loadExampleLines + '\n')
|
|
398
|
+
} else if (hasList && loadParams.length > 0) {
|
|
399
|
+
// List-bootstrap: first call list, take id from response.
|
|
239
400
|
Content(` listParams := map[string]any{}
|
|
240
401
|
`)
|
|
241
402
|
for (const p of listParams) {
|
|
@@ -252,10 +413,10 @@ func Test${entity.Name}Direct(t *testing.T) {
|
|
|
252
413
|
"params": listParams,
|
|
253
414
|
})
|
|
254
415
|
if listErr != nil {
|
|
255
|
-
t.
|
|
416
|
+
t.Skipf("list call failed (likely synthetic IDs against live API): %v", listErr)
|
|
256
417
|
}
|
|
257
418
|
if listResult["ok"] != true {
|
|
258
|
-
t.
|
|
419
|
+
t.Skipf("list call not ok (likely synthetic IDs against live API): %v", listResult)
|
|
259
420
|
}
|
|
260
421
|
|
|
261
422
|
// Get first entity ID from list
|
|
@@ -274,11 +435,13 @@ func Test${entity.Name}Direct(t *testing.T) {
|
|
|
274
435
|
}
|
|
275
436
|
}
|
|
276
437
|
|
|
277
|
-
|
|
438
|
+
if (loadParams.length > 0) {
|
|
439
|
+
Content(` } else {
|
|
278
440
|
`)
|
|
279
|
-
|
|
280
|
-
|
|
441
|
+
for (let i = 0; i < loadParams.length; i++) {
|
|
442
|
+
Content(` params["${loadParams[i].name}"] = "direct0${i + 1}"
|
|
281
443
|
`)
|
|
444
|
+
}
|
|
282
445
|
}
|
|
283
446
|
Content(` }
|
|
284
447
|
`)
|
|
@@ -291,24 +454,44 @@ func Test${entity.Name}Direct(t *testing.T) {
|
|
|
291
454
|
`)
|
|
292
455
|
if (loadParams.length > 0) {
|
|
293
456
|
Content(` "params": params,
|
|
457
|
+
"query": query,
|
|
458
|
+
`)
|
|
459
|
+
} else if (loadLiveQueryLines) {
|
|
460
|
+
Content(` "params": params,
|
|
461
|
+
"query": query,
|
|
294
462
|
`)
|
|
295
463
|
} else {
|
|
296
464
|
Content(` "params": map[string]any{},
|
|
297
465
|
`)
|
|
298
466
|
}
|
|
299
467
|
Content(` })
|
|
300
|
-
if
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
468
|
+
if setup.live {
|
|
469
|
+
// Live mode is lenient: synthetic IDs frequently 4xx. Skip
|
|
470
|
+
// rather than fail when the load endpoint isn't reachable with
|
|
471
|
+
// the IDs we can construct from setup.idmap.
|
|
472
|
+
if err != nil {
|
|
473
|
+
t.Skipf("load call failed (likely synthetic IDs against live API): %v", err)
|
|
474
|
+
}
|
|
475
|
+
if result["ok"] != true {
|
|
476
|
+
t.Skipf("load call not ok (likely synthetic IDs against live API): %v", result)
|
|
477
|
+
}
|
|
478
|
+
status := core.ToInt(result["status"])
|
|
479
|
+
if status < 200 || status >= 300 {
|
|
480
|
+
t.Skipf("expected 2xx status, got %v", result["status"])
|
|
481
|
+
}
|
|
482
|
+
} else {
|
|
483
|
+
if err != nil {
|
|
484
|
+
t.Fatalf("direct failed: %v", err)
|
|
485
|
+
}
|
|
486
|
+
if result["ok"] != true {
|
|
487
|
+
t.Fatalf("expected ok to be true, got %v", result["ok"])
|
|
488
|
+
}
|
|
489
|
+
if core.ToInt(result["status"]) != 200 {
|
|
490
|
+
t.Fatalf("expected status 200, got %v", result["status"])
|
|
491
|
+
}
|
|
492
|
+
if result["data"] == nil {
|
|
493
|
+
t.Fatal("expected data to be non-nil")
|
|
494
|
+
}
|
|
312
495
|
}
|
|
313
496
|
|
|
314
497
|
if !setup.live {
|
|
@@ -360,15 +543,13 @@ func ${entity.name}DirectSetup(mockres any) *${entity.name}DirectSetupResult {
|
|
|
360
543
|
|
|
361
544
|
env := envOverride(map[string]any{
|
|
362
545
|
"${entidEnvVar}": map[string]any{},
|
|
363
|
-
"${PROJECTNAME}_TEST_LIVE": "FALSE"
|
|
364
|
-
"${PROJECTNAME}_APIKEY": "NONE",
|
|
546
|
+
"${PROJECTNAME}_TEST_LIVE": "FALSE",${apikeyEnvEntry}
|
|
365
547
|
})
|
|
366
548
|
|
|
367
549
|
live := env["${PROJECTNAME}_TEST_LIVE"] == "TRUE"
|
|
368
550
|
|
|
369
551
|
if live {
|
|
370
|
-
mergedOpts := map[string]any{
|
|
371
|
-
"apikey": env["${PROJECTNAME}_APIKEY"],
|
|
552
|
+
mergedOpts := map[string]any{${apikeyLiveField}
|
|
372
553
|
}
|
|
373
554
|
client := sdk.New${model.const.Name}SDK(mergedOpts)
|
|
374
555
|
|