Skip to content

Commit e47280a

Browse files
committed
WIP
1 parent 8cd7dfb commit e47280a

File tree

6 files changed

+304
-6
lines changed

6 files changed

+304
-6
lines changed

scripts/audit-implementation.mjs

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ async function main() {
3434
const counts = {
3535
total: 0,
3636
ok: 0,
37+
notice: 0,
3738
warn: 0,
3839
error: 0,
3940
};
@@ -42,6 +43,9 @@ async function main() {
4243
if (result.status === 'ok') {
4344
counts.ok++;
4445
}
46+
if (result.status === 'notice') {
47+
counts.notice++;
48+
}
4549
if (result.status === 'warn') {
4650
counts.warn++;
4751
}

src/__tests__/__snapshots__/audits.ts.snap

+92
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,38 @@ exports[`should not change globally unique audit ids 1`] = `
4242
"id": "9C48",
4343
"name": "MAY NOT allow executing mutations on GET requests",
4444
},
45+
{
46+
"id": "9ABE",
47+
"name": "MAY respond with 4xx status code if content-type is not supplied on POST requests",
48+
},
4549
{
4650
"id": "03D4",
4751
"name": "MUST accept application/json POST requests",
4852
},
53+
{
54+
"id": "A5BF",
55+
"name": "MAY use 400 status code when request body is missing on POST",
56+
},
57+
{
58+
"id": "423L",
59+
"name": "MAY use 400 status code on missing {query} parameter",
60+
},
61+
{
62+
"id": "LKJ0",
63+
"name": "MAY use 400 status code on object {query} parameter",
64+
},
65+
{
66+
"id": "LKJ1",
67+
"name": "MAY use 400 status code on number {query} parameter",
68+
},
69+
{
70+
"id": "LKJ2",
71+
"name": "MAY use 400 status code on boolean {query} parameter",
72+
},
73+
{
74+
"id": "LKJ3",
75+
"name": "MAY use 400 status code on array {query} parameter",
76+
},
4977
{
5078
"id": "34A2",
5179
"name": "SHOULD allow string {query} parameter when accepting application/graphql-response+json",
@@ -54,6 +82,22 @@ exports[`should not change globally unique audit ids 1`] = `
5482
"id": "13EE",
5583
"name": "MUST allow string {query} parameter when accepting application/json",
5684
},
85+
{
86+
"id": "6C00",
87+
"name": "MAY use 400 status code on object {operationName} parameter",
88+
},
89+
{
90+
"id": "6C01",
91+
"name": "MAY use 400 status code on number {operationName} parameter",
92+
},
93+
{
94+
"id": "6C02",
95+
"name": "MAY use 400 status code on boolean {operationName} parameter",
96+
},
97+
{
98+
"id": "6C03",
99+
"name": "MAY use 400 status code on array {operationName} parameter",
100+
},
57101
{
58102
"id": "8161",
59103
"name": "SHOULD allow string {operationName} parameter when accepting application/graphql-response+json",
@@ -86,6 +130,22 @@ exports[`should not change globally unique audit ids 1`] = `
86130
"id": "0222",
87131
"name": "MUST allow null {extensions} parameter when accepting application/json",
88132
},
133+
{
134+
"id": "4760",
135+
"name": "MAY use 400 status code on string {variables} parameter",
136+
},
137+
{
138+
"id": "4761",
139+
"name": "MAY use 400 status code on number {variables} parameter",
140+
},
141+
{
142+
"id": "4762",
143+
"name": "MAY use 400 status code on boolean {variables} parameter",
144+
},
145+
{
146+
"id": "4763",
147+
"name": "MAY use 400 status code on array {variables} parameter",
148+
},
89149
{
90150
"id": "2EA1",
91151
"name": "SHOULD allow map {variables} parameter when accepting application/graphql-response+json",
@@ -102,6 +162,22 @@ exports[`should not change globally unique audit ids 1`] = `
102162
"id": "6A70",
103163
"name": "MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json",
104164
},
165+
{
166+
"id": "58B0",
167+
"name": "MAY use 400 status code on string {extensions} parameter",
168+
},
169+
{
170+
"id": "58B1",
171+
"name": "MAY use 400 status code on number {extensions} parameter",
172+
},
173+
{
174+
"id": "58B2",
175+
"name": "MAY use 400 status code on boolean {extensions} parameter",
176+
},
177+
{
178+
"id": "58B3",
179+
"name": "MAY use 400 status code on array {extensions} parameter",
180+
},
105181
{
106182
"id": "428F",
107183
"name": "SHOULD allow map {extensions} parameter when accepting application/graphql-response+json",
@@ -110,6 +186,22 @@ exports[`should not change globally unique audit ids 1`] = `
110186
"id": "1B7A",
111187
"name": "MUST allow map {extensions} parameter when accepting application/json",
112188
},
189+
{
190+
"id": "B6DC",
191+
"name": "MAY use 4xx or 5xx status codes on JSON parsing failure",
192+
},
193+
{
194+
"id": "BCF8",
195+
"name": "MAY use 400 status code on JSON parsing failure",
196+
},
197+
{
198+
"id": "8764",
199+
"name": "MAY use 4xx or 5xx status codes if parameters are invalid",
200+
},
201+
{
202+
"id": "3E3A",
203+
"name": "MAY use 400 status code if parameters are invalid",
204+
},
113205
{
114206
"id": "572B",
115207
"name": "SHOULD use 200 status code on document parsing failure when accepting application/json",

src/audits/common.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
*
1010
* @category Audits
1111
*/
12-
export type AuditRequirement = 'MUST' | 'SHOULD' | 'MAY';
12+
export type AuditRequirement =
13+
| 'MUST' // error
14+
| 'SHOULD' // warning
15+
| 'MAY'; // notice (suggestion)
1316

1417
/**
1518
* Audit name starting with the audit requirement level.
@@ -67,7 +70,7 @@ export interface AuditFail {
6770
*/
6871
id: string;
6972
name: AuditName;
70-
status: 'warn' | 'error';
73+
status: 'notice' | 'warn' | 'error';
7174
reason: string;
7275
response: Response;
7376
}

src/audits/render.ts

+16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export async function renderAuditResultsToHTML(results: AuditResult[]) {
1010
const grouped = {
1111
total: 0,
1212
ok: [] as AuditOk[],
13+
notice: [] as AuditFail[],
1314
warn: [] as AuditFail[],
1415
error: [] as AuditFail[],
1516
};
@@ -34,6 +35,9 @@ export async function renderAuditResultsToHTML(results: AuditResult[]) {
3435
if (grouped.ok.length) {
3536
report += `<li><span style="font-family: monospace">✅</span> <b>${grouped.ok.length}</b> pass</li>\n`;
3637
}
38+
if (grouped.notice.length) {
39+
report += `<li><span style="font-family: monospace">💡</span> <b>${grouped.notice.length}</b> notices (suggestions)</li>\n`;
40+
}
3741
if (grouped.warn.length) {
3842
// TODO: warning sign is rendered as "⚠️" in markdown instead of the emoji
3943
report += `<li><span style="font-family: monospace">⚠️</span> <b>${grouped.warn.length}</b> warnings (optional)</li>\n`;
@@ -54,6 +58,18 @@ export async function renderAuditResultsToHTML(results: AuditResult[]) {
5458
report += '\n';
5559
}
5660

61+
if (grouped.notice.length) {
62+
report += `<h2>Notices</h2>\n`;
63+
report +=
64+
'The server <i>MAY</i> support these, but are truly optional. These are suggestions following recommended conventions.\n';
65+
report += '<ol>\n';
66+
for (const [, result] of grouped.notice.entries()) {
67+
report += await printAuditFail(result);
68+
}
69+
report += '</ol>\n';
70+
report += '\n';
71+
}
72+
5773
if (grouped.warn.length) {
5874
report += `<h2>Warnings</h2>\n`;
5975
report += 'The server <i>SHOULD</i> support these, but is not required.\n';

0 commit comments

Comments
 (0)