Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Swift Integration Test #230

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 14 additions & 0 deletions .github/workflows/integration-swift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Integrations (Swift)
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run tests
run: docker-compose run integration_swift

- name: Cleanup
if: always()
run: docker-compose down
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,14 @@ services:
- HTTPBIN=true
- INTEGRATION_CLIENT=go
- NODE_ENV=integration
integration_swift:
depends_on:
- reverse_proxy
build:
context: .
dockerfile: integrations/swift.Dockerfile
command: 'npx vitest run src/integration.test.ts'
environment:
- HTTPBIN=true
- INTEGRATION_CLIENT=swift
- NODE_ENV=integration
19 changes: 19 additions & 0 deletions integrations/swift.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM swift:latest

COPY integrations/https-cert/rootCA.pem /usr/local/share/ca-certificates/integration-test.crt
RUN rm -rf /var/lib/apt/lists/* && \
update-ca-certificates

RUN apt-get update && \
apt-get install -y nodejs npm curl && \
npm install -g n && \
n stable

WORKDIR /src

# add pacakge.json first so we don't have to `npm install` unless it changes
# package.json has changed
ADD package.json /src/
RUN npm install

ADD . /src
1 change: 1 addition & 0 deletions src/helpers/__snapshots__/utils.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ exports[`availableTargets > returns all available targets 1`] = `
"title": "Shell",
},
{
"cli": "swift",
"clients": [
{
"description": "Foundation's URLSession request",
Expand Down
29 changes: 29 additions & 0 deletions src/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
php: ['curl', 'guzzle'],
python: ['requests'],
shell: ['curl'],
swift: ['urlsession'],
},
local: {
// When running tests locally, or within a CI environment, we shold limit the targets that
Expand Down Expand Up @@ -68,6 +69,34 @@
},
go: (fixturePath: string) => {
return shell.execSync(`go run ${fixturePath}`);

},
swift: (fixturePath: string) => {
const filePath = `/tmp/${path.basename(fixturePath)}`;

Check warning

Code scanning / CodeQL

Unsafe shell command constructed from library input Medium

This string concatenation which depends on
library input
is later used in a
shell command
.
writeFileSync(
filePath,
`
import FoundationNetworking

extension URLSession {
func data(for request: URLRequest, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse) {
return try await withCheckedThrowingContinuation { continuation in
self.dataTask(with: request) { data, response, error in
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: (data!, response!))
}
}
.resume()
}
}
}

${readFileSync(fixturePath, 'utf8')}
`,
);
return shell.execSync(`swift ${filePath}`);

Check warning

Code scanning / CodeQL

Shell command built from environment values Medium

This shell command depends on an uncontrolled
file name
.

Check warning

Code scanning / CodeQL

Unsafe shell command constructed from library input Medium

This string concatenation which depends on
library input
is later used in a
shell command
.
},
};

Expand Down
1 change: 1 addition & 0 deletions src/targets/swift/target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const swift: Target = {
key: 'swift',
title: 'Swift',
default: 'urlsession',
cli: 'swift',
},
clientsById: {
urlsession,
Expand Down
6 changes: 3 additions & 3 deletions src/targets/swift/urlsession/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const urlsession: Client<UrlsessionOptions> = {

case 'application/json':
if (postData.jsonObj) {
push(`${literalDeclaration('parameters', postData.jsonObj, opts)} as [String : Any]`);
push(`${literalDeclaration('parameters', postData.jsonObj, opts)} as [String : Any?]`);
blank();
push('let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])');
blank();
Expand All @@ -87,7 +87,7 @@ export const urlsession: Client<UrlsessionOptions> = {
push('body += "--\\(boundary)\\r\\n"', 1);
push('body += "Content-Disposition:form-data; name=\\"\\(paramName)\\""', 1);
push('if let filename = param["fileName"] {', 1);
push('let contentType = param["content-type"]!', 2);
push('let contentType = param["contentType"]!', 2);
push('let fileContent = try String(contentsOfFile: filename, encoding: .utf8)', 2);
push('body += "; filename=\\"\\(filename)\\"\\r\\n"', 2);
push('body += "Content-Type: \\(contentType)\\r\\n\\r\\n"', 2);
Expand Down Expand Up @@ -150,7 +150,7 @@ export const urlsession: Client<UrlsessionOptions> = {

blank();

push('let (data, response) = try await URLSession.shared.data(for: request)');
push('let (data, _) = try await URLSession.shared.data(for: request)');
push('print(String(decoding: data, as: UTF8.self))');

return join();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "application/x-www-form-urlencoded"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
4 changes: 2 additions & 2 deletions src/targets/swift/urlsession/fixtures/application-json.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let parameters = [
"nested": ["a": "b"],
"arr_mix": [1, "a", ["arr_mix_nested": []]],
"boolean": false
] as [String : Any]
] as [String : Any?]

let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])

Expand All @@ -18,5 +18,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "application/json"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/cookies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ request.httpMethod = "GET"
request.timeoutInterval = 10
request.allHTTPHeaderFields = ["cookie": "foo=bar; bar=baz"]

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/custom-method.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ var request = URLRequest(url: url)
request.httpMethod = "PROPFIND"
request.timeoutInterval = 10

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/full.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ request.allHTTPHeaderFields = [
]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/headers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ request.allHTTPHeaderFields = [
"quoted-value": "\"quoted\" 'string'"
]

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/http-insecure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ var request = URLRequest(url: url)
request.httpMethod = "GET"
request.timeoutInterval = 10

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/indent-option.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ var request = URLRequest(url: url)
request.httpMethod = "GET"
request.timeoutInterval = 10

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
4 changes: 2 additions & 2 deletions src/targets/swift/urlsession/fixtures/json-null-value.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

let parameters = ["foo": nil] as [String : Any]
let parameters = ["foo": nil] as [String : Any?]

let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])

Expand All @@ -11,5 +11,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "application/json"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
4 changes: 2 additions & 2 deletions src/targets/swift/urlsession/fixtures/jsonObj-multiline.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

let parameters = ["foo": "bar"] as [String : Any]
let parameters = ["foo": "bar"] as [String : Any?]

let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])

Expand All @@ -11,5 +11,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "application/json"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

let parameters = ["foo": nil] as [String : Any]
let parameters = ["foo": nil] as [String : Any?]

let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])

Expand All @@ -11,5 +11,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "application/json"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
4 changes: 2 additions & 2 deletions src/targets/swift/urlsession/fixtures/multipart-data.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ for param in parameters {
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(paramName)\""
if let filename = param["fileName"] {
let contentType = param["content-type"]!
let contentType = param["contentType"]!
let fileContent = try String(contentsOfFile: filename, encoding: .utf8)
body += "; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(contentType)\r\n\r\n"
Expand All @@ -40,5 +40,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "multipart/form-data; boundary=---011000010111000001101001"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
4 changes: 2 additions & 2 deletions src/targets/swift/urlsession/fixtures/multipart-file.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ for param in parameters {
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(paramName)\""
if let filename = param["fileName"] {
let contentType = param["content-type"]!
let contentType = param["contentType"]!
let fileContent = try String(contentsOfFile: filename, encoding: .utf8)
body += "; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(contentType)\r\n\r\n"
Expand All @@ -35,5 +35,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "multipart/form-data; boundary=---011000010111000001101001"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ request.httpMethod = "POST"
request.timeoutInterval = 10
request.allHTTPHeaderFields = ["Content-Type": "multipart/form-data"]

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ for param in parameters {
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(paramName)\""
if let filename = param["fileName"] {
let contentType = param["content-type"]!
let contentType = param["contentType"]!
let fileContent = try String(contentsOfFile: filename, encoding: .utf8)
body += "; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(contentType)\r\n\r\n"
Expand All @@ -34,5 +34,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["Content-Type": "multipart/form-data; boundary=---011000010111000001101001"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/nested.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ var request = URLRequest(url: components.url!)
request.httpMethod = "GET"
request.timeoutInterval = 10

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ request.httpMethod = "POST"
request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "application/json"]

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/pretty-option.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["cookie": "foo=bar; bar=baz", "accept": "application/json", "content-type": "application/x-www-form-urlencoded"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/query-encoded.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ var request = URLRequest(url: components.url!)
request.httpMethod = "GET"
request.timeoutInterval = 10

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/query.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ var request = URLRequest(url: components.url!)
request.httpMethod = "GET"
request.timeoutInterval = 10

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/short.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ var request = URLRequest(url: url)
request.httpMethod = "GET"
request.timeoutInterval = 10

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/text-plain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ request.timeoutInterval = 10
request.allHTTPHeaderFields = ["content-type": "text/plain"]
request.httpBody = postData

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))
2 changes: 1 addition & 1 deletion src/targets/swift/urlsession/fixtures/timeout-option.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ var request = URLRequest(url: url)
request.httpMethod = "GET"
request.timeoutInterval = 5

let (data, response) = try await URLSession.shared.data(for: request)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))