Skip to content
This repository has been archived by the owner on Jan 21, 2025. It is now read-only.

[Multipart] add test case with HttpPart #613

Merged
merged 22 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lemon-fireants-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@azure-tools/cadl-ranch-specs": patch
---

Add test case with `HttpPart` for multipart
75 changes: 75 additions & 0 deletions packages/cadl-ranch-specs/cadl-ranch-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -2481,6 +2481,30 @@ Content-Type: image/jpg
--abcde12345--
```

### Payload_MultiPart_FormData_checkFileNameAndContentTypeWithHttpPart

- Endpoint: `post /multipart/form-data/check-filename-and-content-type-with-httppart`

This case will check filename and content-type of file part, so expect request:

```
POST /upload HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=abcde12345

--abcde12345
Content-Disposition: form-data; name="id"
Content-Type: text/plain

123
--abcde12345
Content-Disposition: form-data; name="profileImage"; filename="hello.jpg"
Content-Type: image/jpg

{…file content…}
--abcde12345--
```

### Payload_MultiPart_FormData_complex

- Endpoint: `post /multipart/form-data/complex-parts`
Expand Down Expand Up @@ -2537,6 +2561,57 @@ Content-Type: application/octet-stream
--abcde12345--
```

### Payload_MultiPart_FormData_complexWithHttpPart
msyyc marked this conversation as resolved.
Show resolved Hide resolved

- Endpoint: `post /multipart/form-data/complex-parts-with-httppart`

For File part, filename will not be checked but it is necessary otherwise cadl-ranch can't parse it;
content-type will be checked with value "application/octet-stream". Expect request:

```
POST /upload HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=abcde12345

--abcde12345
Content-Disposition: form-data; name="id"
Content-Type: text/plain

123
--abcde12345
Content-Disposition: form-data; name="address"
Content-Type: application/json

{
"city": "X"
}
--abcde12345
Content-Disposition: form-data; name="profileImage"; filename="<any-name-is-ok>"
Content-Type: application/octet-stream

{…file content…}
--abcde12345--
Content-Disposition: form-data; name="previousAddresses"
Content-Type: application/json

[{
"city": "Y"
},{
"city": "Z"
}]
--abcde12345
Content-Disposition: form-data; name="pictures"; filename="<any-name-is-ok>"
Content-Type: application/octet-stream

{…file content…}
--abcde12345
Content-Disposition: form-data; name="pictures"; filename="<any-name-is-ok>"
Content-Type: application/octet-stream

{…file content…}
--abcde12345--
```

### Payload_MultiPart_FormData_jsonArrayParts

- Endpoint: `post /multipart/form-data/json-array-parts`
Expand Down
102 changes: 102 additions & 0 deletions packages/cadl-ranch-specs/http/payload/multipart/main.tsp
msyyc marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ model Address {
city: string;
}

model FileRequiredMetaData extends File {
filename: string;
contentType: string;
}
model CheckRequiredMetaDataRequest {
id: HttpPart<string>;
profileImage: HttpPart<FileRequiredMetaData>;
}

model ComplexHttpPartsModelRequest {
id: HttpPart<string>;
address: HttpPart<Address>;
profileImage: HttpPart<FileRequiredMetaData>;
previousAddresses: HttpPart<Address[]>;
pictures: HttpPart<FileRequiredMetaData>[];
msyyc marked this conversation as resolved.
Show resolved Hide resolved
}

model ComplexPartsRequest {
id: string;
address: Address;
Expand Down Expand Up @@ -332,4 +349,89 @@ Content-Type: application/octet-stream;
@header contentType: "multipart/form-data",
profileImage: MultiPartRequest.profileImage,
): NoContentResponse;

@scenario
@scenarioDoc("""
This case will check filename and content-type of file part, so expect request:
```
POST /upload HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=abcde12345

--abcde12345
Content-Disposition: form-data; name="id"
Content-Type: text/plain

123
--abcde12345
Content-Disposition: form-data; name="profileImage"; filename="hello.jpg"
Content-Type: image/jpg

{…file content…}
--abcde12345--
```
""")
@doc("Test content-type: multipart/form-data")
@post
@route("/check-filename-and-content-type-with-httppart")
op checkFileNameAndContentTypeWithHttpPart(
@header contentType: "multipart/form-data",
@body body: CheckRequiredMetaDataRequest,
): NoContentResponse;

@scenario
@scenarioDoc("""
For File part, filename will not be checked but it is necessary otherwise cadl-ranch can't parse it;
content-type will be checked with value "application/octet-stream". Expect request:
```
POST /upload HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=abcde12345

--abcde12345
Content-Disposition: form-data; name="id"
Content-Type: text/plain

123
--abcde12345
Content-Disposition: form-data; name="address"
Content-Type: application/json

{
"city": "X"
}
--abcde12345
Content-Disposition: form-data; name="profileImage"; filename="<any-name-is-ok>"
Content-Type: application/octet-stream

{…file content…}
--abcde12345--
Content-Disposition: form-data; name="previousAddresses"
Content-Type: application/json

[{
"city": "Y"
},{
"city": "Z"
}]
--abcde12345
Content-Disposition: form-data; name="pictures"; filename="<any-name-is-ok>"
Content-Type: application/octet-stream

{…file content…}
msyyc marked this conversation as resolved.
Show resolved Hide resolved
--abcde12345
Content-Disposition: form-data; name="pictures"; filename="<any-name-is-ok>"
Content-Type: application/octet-stream

{…file content…}
msyyc marked this conversation as resolved.
Show resolved Hide resolved
--abcde12345--
```
""")
@doc("Test content-type: multipart/form-data for mixed scenarios")
@post
@route("/complex-parts-with-httppart")
op complexWithHttpPart(
@header contentType: "multipart/form-data",
@body body: ComplexHttpPartsModelRequest,
): NoContentResponse;
}
8 changes: 8 additions & 0 deletions packages/cadl-ranch-specs/http/payload/multipart/mockapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,11 @@ Scenarios.Payload_MultiPart_FormData_checkFileNameAndContentType = passOnSuccess
Scenarios.Payload_MultiPart_FormData_anonymousModel = passOnSuccess(
createMockApis("anonymous-model", [checkProfileImage]),
);

Scenarios.Payload_MultiPart_FormData_checkFileNameAndContentTypeWithHttpPart = passOnSuccess(
msyyc marked this conversation as resolved.
Show resolved Hide resolved
createMockApis("/check-filename-and-content-type-with-httppart", [checkId, checkFileNameAndContentType]),
);

Scenarios.Payload_MultiPart_FormData_complexWithHttpPart = passOnSuccess(
createMockApis("/complex-parts-with-httppart", [checkId, checkAddress, checkPreviousAddresses, checkAllFiles]),
);
Loading