Skip to content

Commit cfce5c8

Browse files
committed
fix: conflict source properties must be in error objects
1 parent f530615 commit cfce5c8

3 files changed

Lines changed: 103 additions & 20 deletions

File tree

__tests__/patch-409-response.test.ts

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe("Rule patch-409-response", () => {
99
spectral = createWithRules(["patch-409-response"]);
1010
});
1111

12-
it("patch includes explicit 409 response", async () => {
12+
it("invalid: 409 response errors object does not define source", async () => {
1313
const document = {
1414
...openApiBase,
1515
paths: {
@@ -35,6 +35,24 @@ describe("Rule patch-409-response", () => {
3535
},
3636
"409": {
3737
description: "conflict",
38+
content: {
39+
"application/vnd.api+json": {
40+
schema: {
41+
type: "object",
42+
properties: {
43+
errors: {
44+
type: "array",
45+
items: {
46+
type: "object",
47+
properties: {
48+
title: { type: "string" },
49+
},
50+
},
51+
},
52+
},
53+
},
54+
},
55+
},
3856
},
3957
},
4058
},
@@ -45,14 +63,27 @@ describe("Rule patch-409-response", () => {
4563
await expectRuleErrors(spectral, "patch-409-response", document, [
4664
{
4765
message:
48-
"PATCH 409 responses should include source to explain the conflict.",
49-
path: ["paths", "/articles/{id}", "patch", "responses", "409"],
66+
"PATCH 409 error objects should include source to explain the conflict.",
67+
path: [
68+
"paths",
69+
"/articles/{id}",
70+
"patch",
71+
"responses",
72+
"409",
73+
"content",
74+
"application/vnd.api+json",
75+
"schema",
76+
"properties",
77+
"errors",
78+
"items",
79+
"properties",
80+
],
5081
severity: DiagnosticSeverity.Information,
5182
},
5283
]);
5384
});
5485

55-
it("valid patch-409-response case", async () => {
86+
it("valid: 409 response errors object includes source", async () => {
5687
const document = {
5788
...openApiBase,
5889
paths: {
@@ -76,6 +107,38 @@ describe("Rule patch-409-response", () => {
76107
"200": {
77108
description: "ok",
78109
},
110+
"409": {
111+
description: "conflict",
112+
content: {
113+
"application/vnd.api+json": {
114+
schema: {
115+
type: "object",
116+
properties: {
117+
errors: {
118+
type: "array",
119+
items: {
120+
type: "object",
121+
properties: {
122+
source: {
123+
type: "object",
124+
properties: {
125+
pointer: {
126+
type: "string",
127+
format: "json-pointer",
128+
},
129+
parameter: {
130+
type: "string",
131+
},
132+
},
133+
},
134+
},
135+
},
136+
},
137+
},
138+
},
139+
},
140+
},
141+
},
79142
},
80143
},
81144
},

__tests__/post-409-response.test.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe("Rule post-409-response", () => {
99
spectral = createWithRules(["post-409-response"]);
1010
});
1111

12-
it("invalid: 409 response does not define a source", async () => {
12+
it("invalid: 409 response errors object does not define source", async () => {
1313
const document = {
1414
...openApiBase,
1515
paths: {
@@ -23,7 +23,15 @@ describe("Rule post-409-response", () => {
2323
schema: {
2424
type: "object",
2525
properties: {
26-
nonsense: {},
26+
errors: {
27+
type: "array",
28+
items: {
29+
type: "object",
30+
properties: {
31+
title: { type: "string" },
32+
},
33+
},
34+
},
2735
},
2836
},
2937
},
@@ -38,7 +46,7 @@ describe("Rule post-409-response", () => {
3846
await expectRuleErrors(spectral, "post-409-response", document, [
3947
{
4048
message:
41-
"POST 409 responses should include source to explain the conflict.",
49+
"POST 409 error objects should include source to explain the conflict.",
4250
path: [
4351
"paths",
4452
"/articles",
@@ -49,13 +57,16 @@ describe("Rule post-409-response", () => {
4957
"application/vnd.api+json",
5058
"schema",
5159
"properties",
60+
"errors",
61+
"items",
62+
"properties",
5263
],
5364
severity: DiagnosticSeverity.Information,
5465
},
5566
]);
5667
});
5768

58-
it("valid: JSON response shows source of conflict", async () => {
69+
it("valid: 409 response errors object includes source", async () => {
5970
const document = {
6071
...openApiBase,
6172
paths: {
@@ -69,12 +80,20 @@ describe("Rule post-409-response", () => {
6980
schema: {
7081
type: "object",
7182
properties: {
72-
source: {
73-
type: "object",
74-
properties: {
75-
pointer: {
76-
type: "string",
77-
format: "json-pointer",
83+
errors: {
84+
type: "array",
85+
items: {
86+
type: "object",
87+
properties: {
88+
source: {
89+
type: "object",
90+
properties: {
91+
pointer: {
92+
type: "string",
93+
format: "json-pointer",
94+
},
95+
},
96+
},
7897
},
7998
},
8099
},

src/ruleset.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,10 +2362,10 @@ Related specification information can be found [here](https://jsonapi.org/format
23622362
documentationUrl:
23632363
"https://jsonapi.org/format/1.1/#crud-creating-responses",
23642364
message:
2365-
"POST 409 responses should include source to explain the conflict.",
2365+
"POST 409 error objects should include source to explain the conflict.",
23662366
severity: DiagnosticSeverity.Information,
23672367
given:
2368-
"$.paths[*][post].responses[409].content['application/vnd.api+json'].schema.properties",
2368+
"$.paths[*][post].responses[409].content['application/vnd.api+json'].schema.properties.errors.items.properties",
23692369
then: {
23702370
field: "source",
23712371
function: truthy,
@@ -2681,12 +2681,13 @@ Related specification information can be found [here](https://jsonapi.org/format
26812681
documentationUrl:
26822682
"https://jsonapi.org/format/1.1/#crud-updating-responses",
26832683
message:
2684-
"PATCH 409 responses should include source to explain the conflict.",
2684+
"PATCH 409 error objects should include source to explain the conflict.",
26852685
severity: DiagnosticSeverity.Information,
2686-
given: "$.paths[*][patch].responses",
2686+
given:
2687+
"$.paths[*][patch].responses[409].content['application/vnd.api+json'].schema.properties.errors.items.properties",
26872688
then: {
2688-
field: "409",
2689-
function: falsy,
2689+
field: "source",
2690+
function: truthy,
26902691
},
26912692
},
26922693
"delete-2xx-response-codes": {

0 commit comments

Comments
 (0)