Skip to content

Commit 20ff383

Browse files
authored
Merge pull request #45 from Artifizer/main
test: Add docs and tests for rejecting plain/wildcard GTS schema IDs
2 parents 00472ee + f5caf22 commit 20ff383

3 files changed

Lines changed: 126 additions & 0 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,8 @@ This section provides **recommended** conventions for embedding GTS identifiers
11371137

11381138
It is recommended to put the GTS **type identifier** into the JSON Schema `$id` field, using a URI-like form by prepending the `gts://` prefix:
11391139

1140+
> **Reserved prefix note**: Do **not** place the canonical `gts.` string directly in `$id`. Always wrap the identifier with the `gts://` scheme (for example: `"$id": "gts://gts.x.core.events.type.v1~"`). The raw `gts.` prefix is reserved for canonical identifiers inside the scheme, and mixing it directly into `$id` leads to ambiguity and upload failures.
1141+
11401142
```json
11411143
{
11421144
"$id": "gts://gts.x.core.events.type.v1~",
@@ -1147,10 +1149,14 @@ It is recommended to put the GTS **type identifier** into the JSON Schema `$id`
11471149

11481150
Implementation note: GTS itself defines the canonical identifier string starting with `gts.`. When `$id` is expressed as `gts://...`, implementations should trim the `gts://` prefix and treat the remainder as the canonical GTS identifier for validation, comparison, and registry keys. The `gts://` prefix exists only to make `$id` URI-compatible.
11491151

1152+
When `$id` starts with `gts://`, the remainder **must** be a valid, wildcard-free GTS identifier (see OP#1 rules). Asterisks and other wildcard tokens are not permitted in schema identifiers.
1153+
11501154
**JSON Schema (`$ref`)**
11511155

11521156
It is recommended to make GTS schema references in JSON Schema `$ref` URI-compatible the same way as `$id`, by prepending the `gts://` prefix when `$ref` points at a GTS schema identifier:
11531157

1158+
> **Note:** Just like `$id`, do not embed raw `gts.` prefixes in `$ref`. Use the URI form (`gts://...`) and ensure the referenced identifier is a valid GTS ID with no wildcard characters.
1159+
11541160
```json
11551161
{
11561162
"allOf": [
@@ -1163,6 +1169,8 @@ Note: local JSON Schema references (e.g. `"$ref": "#/definitions/Foo"`, `"$ref":
11631169

11641170
Implementation note: When `$ref` is expressed as `gts://...`, implementations should trim the `gts://` prefix and treat the remainder as the canonical GTS identifier for resolution, validation, comparison, and registry keys. The `gts://` prefix exists only to make `$ref` URI-compatible.
11651171

1172+
The post-`gts://` content must therefore parse as a valid GTS identifier with no wildcards; otherwise the schema upload should be rejected.
1173+
11661174
**JSON instances (well-known vs anonymous)**
11671175

11681176
- **Well-known instances (named)**: recommended to use a GTS identifier in the `id` field (alternatives: `gtsId`, `gts_id`). Prefer a chained identifier so the **left segment(s)** define the schema/type automatically, and the **rightmost** segment is the instance name.

tests/test_op6_schema_validation.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,62 @@ def test_start(self):
189189
]
190190

191191

192+
class TestCaseTestOp6SchemaValidation_InvalidSchemaIdPrefix(HttpRunner):
193+
"""OP#6 - Reject JSON Schema identifier values that start with 'gts.'"""
194+
195+
config = Config(
196+
"OP#6 - Schema Validation: reject plain gts prefix in id"
197+
).base_url(get_gts_base_url())
198+
199+
def test_start(self):
200+
super().test_start()
201+
202+
teststeps = [
203+
Step(
204+
RunRequest("register schema with plain gts prefix should fail")
205+
.post("/entities")
206+
.with_params(**{"validate": "true"})
207+
.with_json({
208+
"$$id": "gts.x.test6.invalid_id.plain_prefix.v1~",
209+
"$$schema": "http://json-schema.org/draft-07/schema#",
210+
"type": "object",
211+
"properties": {"id": {"type": "string"}},
212+
"required": ["id"]
213+
})
214+
.validate()
215+
.assert_equal("status_code", 422)
216+
),
217+
]
218+
219+
220+
class TestCaseTestOp6SchemaValidation_InvalidSchemaIdWildcard(HttpRunner):
221+
"""OP#6 - Reject JSON Schema identifier with wildcard after gts://"""
222+
223+
config = Config(
224+
"OP#6 - Schema Validation: reject wildcard gts:// id"
225+
).base_url(get_gts_base_url())
226+
227+
def test_start(self):
228+
super().test_start()
229+
230+
teststeps = [
231+
Step(
232+
RunRequest("register schema with wildcard gts:// id should fail")
233+
.post("/entities")
234+
.with_params(**{"validate": "true"})
235+
.with_json({
236+
"$$id": "gts://gts.x.test6.events.*.v1~",
237+
"$$schema": "http://json-schema.org/draft-07/schema#",
238+
"type": "object",
239+
"properties": {"id": {"type": "string"}},
240+
"required": ["id"]
241+
})
242+
.validate()
243+
.assert_equal("status_code", 422)
244+
),
245+
]
246+
247+
192248
class TestCaseTestOp6ValidateInstance_NotFound(HttpRunner):
193249
"""OP#6 - Schema Validation: Validate non-existent instance"""
194250
config = Config("OP#6 - Validate Instance (not found)").base_url(get_gts_base_url())

tests/test_op7_relationship_resolution.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,68 @@ def test_start(self):
133133
]
134134

135135

136+
class TestCaseTestOp7SchemaGraph_RefPlainGtsPrefix(HttpRunner):
137+
"""OP#7 - Reject $ref that starts with 'gts.' instead of 'gts://'"""
138+
139+
config = Config("OP#7 - Schema Graph ($$ref plain gts prefix)").base_url(
140+
get_gts_base_url()
141+
)
142+
143+
def test_start(self):
144+
super().test_start()
145+
146+
teststeps = [
147+
Step(
148+
RunRequest("register schema with plain gts. $ref should fail")
149+
.post("/entities")
150+
.with_params(**{"validate": "true"})
151+
.with_json({
152+
"$$id": "gts://gts.x.test7.invalid_ref.plain_prefix.v1~",
153+
"$$schema": "http://json-schema.org/draft-07/schema#",
154+
"type": "object",
155+
"allOf": [
156+
{
157+
"$$ref": "gts.x.test7.invalid_ref.plain_prefix.v1~"
158+
}
159+
]
160+
})
161+
.validate()
162+
.assert_equal("status_code", 422)
163+
),
164+
]
165+
166+
167+
class TestCaseTestOp7SchemaGraph_RefWildcardGts(HttpRunner):
168+
"""OP#7 - Reject $ref using wildcards after gts://"""
169+
170+
config = Config("OP#7 - Schema Graph ($$ref wildcard gts://)").base_url(
171+
get_gts_base_url()
172+
)
173+
174+
def test_start(self):
175+
super().test_start()
176+
177+
teststeps = [
178+
Step(
179+
RunRequest("register schema with wildcard gts:// $ref should fail")
180+
.post("/entities")
181+
.with_params(**{"validate": "true"})
182+
.with_json({
183+
"$$id": "gts://gts.x.test7.invalid_ref.wildcard.v1~",
184+
"$$schema": "http://json-schema.org/draft-07/schema#",
185+
"type": "object",
186+
"allOf": [
187+
{
188+
"$$ref": "gts://gts.x.test7.events.*.v1~"
189+
}
190+
]
191+
})
192+
.validate()
193+
.assert_equal("status_code", 422)
194+
),
195+
]
196+
197+
136198
class TestCaseTestOp7SchemaGraph_LocalRefAllowed(HttpRunner):
137199
"""OP#7 - Relationship Resolution: Allow local JSON Schema $ref"""
138200
config = Config("OP#7 - Schema Graph (local $$ref allowed)").base_url(

0 commit comments

Comments
 (0)