-
Notifications
You must be signed in to change notification settings - Fork 198
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Storage): Adding integration tests for getURL, remove and list (#…
- Loading branch information
Showing
4 changed files
with
449 additions
and
0 deletions.
There are no files selected for viewing
85 changes: 85 additions & 0 deletions
85
...HostApp/AWSS3StoragePluginIntegrationTests/AWSS3StoragePluginGetURLIntegrationTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
@testable import Amplify | ||
|
||
import AWSS3StoragePlugin | ||
import ClientRuntime | ||
import AWSClientRuntime | ||
import CryptoKit | ||
import XCTest | ||
import AWSS3 | ||
|
||
class AWSS3StoragePluginGetURLIntegrationTests: AWSS3StoragePluginTestBase { | ||
|
||
/// Given: An object in storage | ||
/// When: Call the getURL API | ||
/// Then: The operation completes successfully with the URL retrieved | ||
func testGetRemoteURL() async throws { | ||
let key = "public/" + UUID().uuidString | ||
try await uploadData(key: key, dataString: key) | ||
_ = try await Amplify.Storage.uploadData( | ||
path: .fromString(key), | ||
data: Data(key.utf8), | ||
options: .init()) | ||
|
||
let remoteURL = try await Amplify.Storage.getURL(path: .fromString(key)) | ||
|
||
// The presigned URL generation does not result in an SDK or HTTP call. | ||
XCTAssertEqual(requestRecorder.sdkRequests.map { $0.method} , []) | ||
|
||
let (data, response) = try await URLSession.shared.data(from: remoteURL) | ||
let httpResponse = try XCTUnwrap(response as? HTTPURLResponse) | ||
XCTAssertEqual(httpResponse.statusCode, 200) | ||
|
||
let dataString = try XCTUnwrap(String(data: data, encoding: .utf8)) | ||
XCTAssertEqual(dataString, key) | ||
|
||
_ = try await Amplify.Storage.remove(path: .fromString(key)) | ||
} | ||
|
||
/// - Given: A key for a non-existent S3 object | ||
/// - When: A pre-signed URL is requested for that key with `validateObjectExistence = true` | ||
/// - Then: A StorageError.keyNotFound error is thrown | ||
func testGetURLForUnknownKeyWithValidation() async throws { | ||
let unknownKey = "public/" + UUID().uuidString | ||
do { | ||
let url = try await Amplify.Storage.getURL( | ||
path: .fromString(unknownKey), | ||
options: .init( | ||
pluginOptions: AWSStorageGetURLOptions(validateObjectExistence: true) | ||
) | ||
) | ||
XCTFail("Expecting failure but got url: \(url)") | ||
} catch StorageError.keyNotFound(let key, _, _, _) { | ||
XCTAssertTrue(key.contains(unknownKey)) | ||
} | ||
|
||
// A S3 HeadObject call is expected | ||
XCTAssert(requestRecorder.sdkRequests.map(\.method).allSatisfy { $0 == .head }) | ||
|
||
XCTAssertEqual(requestRecorder.urlRequests.map { $0.httpMethod }, []) | ||
} | ||
|
||
/// - Given: A key for a non-existent S3 object | ||
/// - When: A pre-signed URL is requested for that key with `validateObjectExistence = false` | ||
/// - Then: A pre-signed URL is returned | ||
func testGetURLForUnknownKeyWithoutValidation() async throws { | ||
let unknownKey = UUID().uuidString | ||
let url = try await Amplify.Storage.getURL( | ||
path: .fromString(unknownKey), | ||
options: .init( | ||
pluginOptions: AWSStorageGetURLOptions(validateObjectExistence: false) | ||
) | ||
) | ||
XCTAssertNotNil(url) | ||
|
||
// No SDK or URLRequest calls expected | ||
XCTAssertEqual(requestRecorder.sdkRequests.map { $0.method} , []) | ||
XCTAssertEqual(requestRecorder.urlRequests.map { $0.httpMethod }, []) | ||
} | ||
} |
186 changes: 186 additions & 0 deletions
186
...pp/AWSS3StoragePluginIntegrationTests/AWSS3StoragePluginListObjectsIntegrationTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
@testable import Amplify | ||
|
||
import AWSS3StoragePlugin | ||
import ClientRuntime | ||
import AWSClientRuntime | ||
import CryptoKit | ||
import XCTest | ||
import AWSS3 | ||
|
||
class AWSS3StoragePluginListObjectsIntegrationTests: AWSS3StoragePluginTestBase { | ||
|
||
/// Given: Multiple data object which is uploaded to a public path | ||
/// When: `Amplify.Storage.list` is run | ||
/// Then: The API should execute successfully and list objects for path | ||
func testListObjectsUploadedPublicData() async throws { | ||
let key = UUID().uuidString | ||
let data = Data(key.utf8) | ||
let uniqueStringPath = "public/\(key)" | ||
|
||
_ = try await Amplify.Storage.uploadData(path: .fromString(uniqueStringPath + "/test1"), data: data, options: nil).value | ||
|
||
let firstListResult = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
|
||
// Validate the item was uploaded. | ||
XCTAssertEqual(firstListResult.items.filter({ $0.path == uniqueStringPath}).count, 1) | ||
|
||
_ = try await Amplify.Storage.uploadData(path: .fromString(uniqueStringPath + "/test2"), data: data, options: nil).value | ||
|
||
let secondListResult = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
|
||
// Validate the item was uploaded. | ||
XCTAssertEqual(secondListResult.items.filter({ $0.path == uniqueStringPath}).count, 2) | ||
|
||
// Clean up | ||
_ = try await Amplify.Storage.remove(path: .fromString(uniqueStringPath + "/test1")) | ||
_ = try await Amplify.Storage.remove(path: .fromString(uniqueStringPath + "/test2")) | ||
} | ||
|
||
/// Given: Multiple data object which is uploaded to a protected path | ||
/// When: `Amplify.Storage.list` is run | ||
/// Then: The API should execute successfully and list objects for path | ||
func testListObjectsUploadedProtectedData() async throws { | ||
let key = UUID().uuidString | ||
let data = Data(key.utf8) | ||
var uniqueStringPath = "" | ||
|
||
// Sign in | ||
_ = try await Amplify.Auth.signIn(username: Self.user1, password: Self.password) | ||
|
||
_ = try await Amplify.Storage.uploadData( | ||
path: .fromIdentityID({ identityId in | ||
uniqueStringPath = "protected/\(identityId)/\(key)" | ||
return uniqueStringPath + "test1" | ||
}), | ||
data: data, | ||
options: nil).value | ||
|
||
let firstListResult = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
|
||
// Validate the item was uploaded. | ||
XCTAssertEqual(firstListResult.items.filter({ $0.path == uniqueStringPath}).count, 1) | ||
|
||
_ = try await Amplify.Storage.uploadData( | ||
path: .fromIdentityID({ identityId in | ||
uniqueStringPath = "protected/\(identityId)/\(key)" | ||
return uniqueStringPath + "test2" | ||
}), | ||
data: data, | ||
options: nil).value | ||
|
||
let secondListResult = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
|
||
// Validate the item was uploaded. | ||
XCTAssertEqual(secondListResult.items.filter({ $0.path == uniqueStringPath}).count, 2) | ||
|
||
// clean up | ||
_ = try await Amplify.Storage.remove(path: .fromString(uniqueStringPath + "test1")) | ||
_ = try await Amplify.Storage.remove(path: .fromString(uniqueStringPath + "test2")) | ||
|
||
} | ||
|
||
/// Given: Multiple data object which is uploaded to a private path | ||
/// When: `Amplify.Storage.list` is run | ||
/// Then: The API should execute successfully and list objects for path | ||
func testListObjectsUploadedPrivateData() async throws { | ||
let key = UUID().uuidString | ||
let data = Data(key.utf8) | ||
var uniqueStringPath = "" | ||
|
||
// Sign in | ||
_ = try await Amplify.Auth.signIn(username: Self.user1, password: Self.password) | ||
|
||
_ = try await Amplify.Storage.uploadData( | ||
path: .fromIdentityID({ identityId in | ||
uniqueStringPath = "private/\(identityId)/\(key)" | ||
return uniqueStringPath + "test1" | ||
}), | ||
data: data, | ||
options: nil).value | ||
|
||
let firstListResult = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
|
||
// Validate the item was uploaded. | ||
XCTAssertEqual(firstListResult.items.filter({ $0.path == uniqueStringPath}).count, 1) | ||
|
||
_ = try await Amplify.Storage.uploadData( | ||
path: .fromIdentityID({ identityId in | ||
uniqueStringPath = "private/\(identityId)/\(key)" | ||
return uniqueStringPath + "test2" | ||
}), | ||
data: data, | ||
options: nil).value | ||
|
||
let secondListResult = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
|
||
// Validate the item was uploaded. | ||
XCTAssertEqual(secondListResult.items.filter({ $0.path == uniqueStringPath}).count, 2) | ||
|
||
// clean up | ||
_ = try await Amplify.Storage.remove(path: .fromString(uniqueStringPath + "test1")) | ||
_ = try await Amplify.Storage.remove(path: .fromString(uniqueStringPath + "test2")) | ||
|
||
} | ||
|
||
/// Given: Give a unique key that does not exist | ||
/// When: `Amplify.Storage.list` is run | ||
/// Then: The API should execute and throw an error | ||
func testRemoveKeyDoesNotExist() async throws { | ||
let key = UUID().uuidString | ||
let uniqueStringPath = "public/\(key)" | ||
|
||
do { | ||
_ = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
} | ||
catch { | ||
guard let storageError = error as? StorageError else { | ||
XCTFail("Error should be of type StorageError but got \(error)") | ||
return | ||
} | ||
guard case .keyNotFound(_, _, _, let underlyingError) = storageError else { | ||
XCTFail("Error should be of type keyNotFound but got \(error)") | ||
return | ||
} | ||
|
||
guard underlyingError is AWSS3.NotFound else { | ||
XCTFail("Underlying error should be of type AWSS3.NotFound but got \(error)") | ||
return | ||
} | ||
} | ||
} | ||
|
||
/// Given: Give a unique key where is user is NOT logged in | ||
/// When: `Amplify.Storage.list` is run | ||
/// Then: The API should execute and throw an error | ||
func testRemoveKeyWhenNotSignedInForPrivateKey() async throws { | ||
let key = UUID().uuidString | ||
let uniqueStringPath = "private/\(key)" | ||
|
||
do { | ||
_ = try await Amplify.Storage.list(path: .fromString(uniqueStringPath)) | ||
} | ||
catch { | ||
guard let storageError = error as? StorageError else { | ||
XCTFail("Error should be of type StorageError but got \(error)") | ||
return | ||
} | ||
guard case .accessDenied(_, _, let underlyingError) = storageError else { | ||
XCTFail("Error should be of type keyNotFound but got \(error)") | ||
return | ||
} | ||
|
||
guard underlyingError is UnknownAWSHTTPServiceError else { | ||
XCTFail("Underlying error should be of type UnknownAWSHTTPServiceError but got \(error)") | ||
return | ||
} | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.