Skip to content

Commit ce9989c

Browse files
authored
Merge pull request #474 from python-openapi/feature/add-tag-tests
Add tags tests
2 parents 7c0ddf8 + 9f98c96 commit ce9989c

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

tests/integration/validation/test_validators.py

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,122 @@ def test_operation_tags_without_root_declaration_are_valid(self):
257257

258258
assert not errors
259259

260+
def test_tag_hierarchy_is_valid(self):
261+
spec = {
262+
"openapi": "3.2.0",
263+
"info": {
264+
"title": "Tag API",
265+
"version": "1.0.0",
266+
},
267+
"tags": [
268+
{
269+
"name": "external",
270+
"kind": "audience",
271+
},
272+
{
273+
"name": "partner",
274+
"parent": "external",
275+
"kind": "audience",
276+
},
277+
{
278+
"name": "partner-updates",
279+
"parent": "partner",
280+
"kind": "nav",
281+
},
282+
],
283+
"paths": {
284+
"/pets": {
285+
"get": {
286+
"responses": {
287+
"200": {
288+
"description": "ok",
289+
},
290+
},
291+
},
292+
},
293+
},
294+
}
295+
296+
errors = list(OpenAPIV32SpecValidator(spec).iter_errors())
297+
298+
assert not errors
299+
300+
def test_tag_hierarchy_fails_for_unknown_parent(self):
301+
spec = {
302+
"openapi": "3.2.0",
303+
"info": {
304+
"title": "Tag API",
305+
"version": "1.0.0",
306+
},
307+
"tags": [
308+
{
309+
"name": "partner",
310+
"parent": "external",
311+
},
312+
],
313+
"paths": {
314+
"/pets": {
315+
"get": {
316+
"responses": {
317+
"200": {
318+
"description": "ok",
319+
},
320+
},
321+
},
322+
},
323+
},
324+
}
325+
326+
errors = list(OpenAPIV32SpecValidator(spec).iter_errors())
327+
328+
assert len(errors) == 1
329+
assert (
330+
errors[0].message
331+
== "Tag 'partner' references unknown parent tag 'external'"
332+
)
333+
334+
def test_tag_hierarchy_fails_for_circular_reference(self):
335+
spec = {
336+
"openapi": "3.2.0",
337+
"info": {
338+
"title": "Tag API",
339+
"version": "1.0.0",
340+
},
341+
"tags": [
342+
{
343+
"name": "a",
344+
"parent": "b",
345+
},
346+
{
347+
"name": "b",
348+
"parent": "c",
349+
},
350+
{
351+
"name": "c",
352+
"parent": "a",
353+
},
354+
],
355+
"paths": {
356+
"/pets": {
357+
"get": {
358+
"responses": {
359+
"200": {
360+
"description": "ok",
361+
},
362+
},
363+
},
364+
},
365+
},
366+
}
367+
368+
errors = list(OpenAPIV32SpecValidator(spec).iter_errors())
369+
370+
assert errors
371+
assert any(
372+
err.message == "Circular tag hierarchy detected: a -> b -> c -> a"
373+
for err in errors
374+
)
375+
260376

261377
def test_oas31_query_operation_is_not_semantically_traversed():
262378
spec = {
@@ -312,6 +428,106 @@ def test_oas31_additional_operations_are_not_semantically_traversed():
312428
assert all("Path parameter 'item_id'" not in err.message for err in errors)
313429

314430

431+
@pytest.mark.parametrize(
432+
"spec,validator_cls",
433+
[
434+
(
435+
{
436+
"swagger": "2.0",
437+
"info": {
438+
"title": "Tag API",
439+
"version": "1.0.0",
440+
},
441+
"tags": [
442+
{
443+
"name": "pets",
444+
},
445+
{
446+
"name": "pets",
447+
"description": "duplicate by name",
448+
},
449+
],
450+
"paths": {
451+
"/pets": {
452+
"get": {
453+
"responses": {
454+
"200": {
455+
"description": "ok",
456+
},
457+
},
458+
},
459+
},
460+
},
461+
},
462+
OpenAPIV2SpecValidator,
463+
),
464+
(
465+
{
466+
"openapi": "3.0.3",
467+
"info": {
468+
"title": "Tag API",
469+
"version": "1.0.0",
470+
},
471+
"tags": [
472+
{
473+
"name": "pets",
474+
},
475+
{
476+
"name": "pets",
477+
},
478+
],
479+
"paths": {
480+
"/pets": {
481+
"get": {
482+
"responses": {
483+
"200": {
484+
"description": "ok",
485+
},
486+
},
487+
},
488+
},
489+
},
490+
},
491+
OpenAPIV30SpecValidator,
492+
),
493+
(
494+
{
495+
"openapi": "3.1.0",
496+
"info": {
497+
"title": "Tag API",
498+
"version": "1.0.0",
499+
},
500+
"tags": [
501+
{
502+
"name": "pets",
503+
},
504+
{
505+
"name": "pets",
506+
},
507+
],
508+
"paths": {
509+
"/pets": {
510+
"get": {
511+
"responses": {
512+
"200": {
513+
"description": "ok",
514+
},
515+
},
516+
},
517+
},
518+
},
519+
},
520+
OpenAPIV31SpecValidator,
521+
),
522+
],
523+
)
524+
def test_oas2_oas3_duplicate_top_level_tags_are_invalid(spec, validator_cls):
525+
errors = list(validator_cls(spec).iter_errors())
526+
527+
assert errors
528+
assert any(err.message == "Duplicate tag name 'pets'" for err in errors)
529+
530+
315531
@pytest.mark.network
316532
class TestRemoteOpenAPIv30Validator:
317533
REMOTE_SOURCE_URL = (

0 commit comments

Comments
 (0)