microsoft/typespec

Public

mirrored from https://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
bd60b0a68bb23817a01ab4aef22170c18abd81ed

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/openapi3/test/parameters.test.ts

237lines · modecode

1import { expectDiagnostics } from "@cadl-lang/compiler/testing";
2import { deepStrictEqual, ok, strictEqual } from "assert";
3import { diagnoseOpenApiFor, openApiFor } from "./test-host.js";
4
5describe("openapi3: parameters", () => {
6 it("create a query param", async () => {
7 const res = await openApiFor(
8 `
9 op test(@query arg1: string): void;
10 `
11 );
12 strictEqual(res.paths["/"].get.parameters[0].in, "query");
13 strictEqual(res.paths["/"].get.parameters[0].name, "arg1");
14 deepStrictEqual(res.paths["/"].get.parameters[0].schema, { type: "string" });
15 });
16
17 it("create a query param with a different name", async () => {
18 const res = await openApiFor(
19 `
20 op test(@query("$select") select: string): void;
21 `
22 );
23 strictEqual(res.paths["/"].get.parameters[0].in, "query");
24 strictEqual(res.paths["/"].get.parameters[0].name, "$select");
25 });
26
27 it("create a query param of array type", async () => {
28 const res = await openApiFor(
29 `
30 op test(
31 @query({name: "$select"}) selects: string[],
32 @query({name: "$order", format: "csv"}) orders: string[],
33 ): void;
34 `
35 );
36 strictEqual(res.paths["/"].get.parameters[0].in, "query");
37 strictEqual(res.paths["/"].get.parameters[0].name, "$select");
38 strictEqual(res.paths["/"].get.parameters[0].style, "form");
39 strictEqual(res.paths["/"].get.parameters[0].explode, true);
40 strictEqual(res.paths["/"].get.parameters[1].in, "query");
41 strictEqual(res.paths["/"].get.parameters[1].name, "$order");
42 strictEqual(res.paths["/"].get.parameters[1].style, "simple");
43 });
44
45 it("create a query param that is a model property", async () => {
46 const res = await openApiFor(
47 `
48 op test(@query id: UserContext.id): void;
49
50 model UserContext {
51 id: string;
52 }
53 `
54 );
55 deepStrictEqual(res.paths["/"].get.parameters[0], {
56 in: "query",
57 name: "id",
58 required: true,
59 schema: {
60 type: "string",
61 },
62 });
63 });
64
65 it("create an header param", async () => {
66 const res = await openApiFor(
67 `
68 op test(@header arg1: string): void;
69 `
70 );
71 strictEqual(res.paths["/"].get.parameters[0].in, "header");
72 strictEqual(res.paths["/"].get.parameters[0].name, "arg1");
73 deepStrictEqual(res.paths["/"].get.parameters[0].schema, { type: "string" });
74 });
75
76 it("create an header param with a different name", async () => {
77 const res = await openApiFor(
78 `
79 op test(@header("foo-bar") foo: string): void;
80 `
81 );
82 strictEqual(res.paths["/"].get.parameters[0].in, "header");
83 strictEqual(res.paths["/"].get.parameters[0].name, "foo-bar");
84 });
85
86 it("create an header param of array type", async () => {
87 const res = await openApiFor(
88 `
89 op test(@header("foo-bar") foo: string[]): void;
90 `
91 );
92 strictEqual(res.paths["/"].get.parameters[0].in, "header");
93 strictEqual(res.paths["/"].get.parameters[0].name, "foo-bar");
94 strictEqual(res.paths["/"].get.parameters[0].style, "simple");
95 });
96
97 // Regression test for https://github.com/microsoft/cadl/issues/414
98 it("@doc set the description on the parameter not its schema", async () => {
99 const res = await openApiFor(
100 `
101 op test(@query @doc("my-doc") arg1: string): void;
102 `
103 );
104 strictEqual(res.paths["/"].get.parameters[0].description, "my-doc");
105 strictEqual(res.paths["/"].get.parameters[0].schema.description, undefined);
106 });
107
108 it("errors on duplicate parameter keys", async () => {
109 const diagnostics = await diagnoseOpenApiFor(
110 `
111 model P {
112 @query id: string;
113 }
114
115 @friendlyName("P")
116 model Q {
117 @header id: string;
118 }
119
120 @route("/test1")
121 op test1(...P): void;
122
123 @route("/test2")
124 op test2(...Q): void;
125 `,
126 { "omit-unreachable-types": true }
127 );
128
129 expectDiagnostics(diagnostics, [
130 {
131 code: "@cadl-lang/openapi/duplicate-type-name",
132 message: /parameter/,
133 },
134 ]);
135 });
136
137 it("encodes parameter keys in references", async () => {
138 const oapi = await openApiFor(`
139 model Pet extends Pet$Id {
140 name: string;
141 }
142 model Pet$Id {
143 @path
144 petId: string;
145 }
146
147 @route("/Pets")
148 @get()
149 op get(... Pet$Id): Pet;
150 `);
151
152 ok(oapi.paths["/Pets/{petId}"].get);
153 strictEqual(
154 oapi.paths["/Pets/{petId}"].get.parameters[0]["$ref"],
155 "#/components/parameters/Pet%24Id"
156 );
157 strictEqual(oapi.components.parameters["Pet$Id"].name, "petId");
158 });
159
160 it("inline spread of parameters from anonymous model", async () => {
161 const oapi = await openApiFor(
162 `
163 op template<TParameters, TReturn>(...TParameters): TReturn;
164 op instantiation is template<{@path id: string}, void>;
165 `
166 );
167
168 ok(oapi.paths["/{id}"].get);
169
170 deepStrictEqual(oapi.paths["/{id}"].get.parameters, [
171 {
172 name: "id",
173 in: "path",
174 required: true,
175 schema: {
176 type: "string",
177 },
178 },
179 ]);
180 });
181
182 it("omit parameters with type never", async () => {
183 const res = await openApiFor(
184 `
185 op test(@query select: never, @query top: int32): void;
186 `
187 );
188 strictEqual(res.paths["/"].get.parameters.length, 1);
189 strictEqual(res.paths["/"].get.parameters[0].in, "query");
190 strictEqual(res.paths["/"].get.parameters[0].name, "top");
191 });
192
193 describe("content type parameter", () => {
194 it("header named with 'Content-Type' gets resolved as content type for operation.", async () => {
195 const res = await openApiFor(
196 `
197 op test(
198 @header("Content-Type") explicitContentType: "application/octet-stream",
199 @body foo: string
200 ): void;
201 `
202 );
203 ok(res.paths["/"].post.requestBody.content["application/octet-stream"]);
204 deepStrictEqual(res.paths["/"].post.requestBody.content["application/octet-stream"].schema, {
205 type: "string",
206 });
207 });
208
209 it("header named contentType gets resolved as content type for operation.", async () => {
210 const res = await openApiFor(
211 `
212 op test(
213 @header contentType: "application/octet-stream",
214 @body foo: string
215 ): void;
216 `
217 );
218 ok(res.paths["/"].post.requestBody.content["application/octet-stream"]);
219 deepStrictEqual(res.paths["/"].post.requestBody.content["application/octet-stream"].schema, {
220 type: "string",
221 });
222 });
223
224 it("query named contentType doesn't get resolved as the content type parmaeter.", async () => {
225 const res = await openApiFor(
226 `
227 op test(
228 @query contentType: "application/octet-stream",
229 @body foo: string
230 ): void;
231 `
232 );
233 strictEqual(res.paths["/"].post.requestBody.content["application/octet-stream"], undefined);
234 ok(res.paths["/"].post.requestBody.content["application/json"]);
235 });
236 });
237});
238