|
|
@@ -17,407 +17,405 @@ import FirebaseCore
|
|
|
import FirebaseStorage
|
|
|
import XCTest
|
|
|
|
|
|
-#if swift(>=5.5) && canImport(_Concurrency)
|
|
|
- @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)
|
|
|
- class StorageAsyncAwait: StorageIntegrationCommon {
|
|
|
- func testGetMetadata() async throws {
|
|
|
- let ref = storage.reference().child("ios/public/1mb2")
|
|
|
- let result = try await ref.getMetadata()
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)
|
|
|
+class StorageAsyncAwait: StorageIntegrationCommon {
|
|
|
+ func testGetMetadata() async throws {
|
|
|
+ let ref = storage.reference().child("ios/public/1mb2")
|
|
|
+ let result = try await ref.getMetadata()
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testUpdateMetadata() async throws {
|
|
|
- let meta = StorageMetadata()
|
|
|
- meta.contentType = "lol/custom"
|
|
|
- meta.customMetadata = ["lol": "custom metadata is neat",
|
|
|
- "ちかてつ": "🚇",
|
|
|
- "shinkansen": "新幹線"]
|
|
|
-
|
|
|
- let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
- let metadata = try await ref.updateMetadata(meta)
|
|
|
- XCTAssertEqual(meta.contentType, metadata.contentType)
|
|
|
- XCTAssertEqual(meta.customMetadata!["lol"], metadata.customMetadata!["lol"])
|
|
|
- XCTAssertEqual(meta.customMetadata!["ちかてつ"], metadata.customMetadata!["ちかてつ"])
|
|
|
- XCTAssertEqual(meta.customMetadata!["shinkansen"],
|
|
|
- metadata.customMetadata!["shinkansen"])
|
|
|
- }
|
|
|
+ func testUpdateMetadata() async throws {
|
|
|
+ let meta = StorageMetadata()
|
|
|
+ meta.contentType = "lol/custom"
|
|
|
+ meta.customMetadata = ["lol": "custom metadata is neat",
|
|
|
+ "ちかてつ": "🚇",
|
|
|
+ "shinkansen": "新幹線"]
|
|
|
+
|
|
|
+ let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
+ let metadata = try await ref.updateMetadata(meta)
|
|
|
+ XCTAssertEqual(meta.contentType, metadata.contentType)
|
|
|
+ XCTAssertEqual(meta.customMetadata!["lol"], metadata.customMetadata!["lol"])
|
|
|
+ XCTAssertEqual(meta.customMetadata!["ちかてつ"], metadata.customMetadata!["ちかてつ"])
|
|
|
+ XCTAssertEqual(meta.customMetadata!["shinkansen"],
|
|
|
+ metadata.customMetadata!["shinkansen"])
|
|
|
+ }
|
|
|
|
|
|
- func testDelete() async throws {
|
|
|
- let objectLocation = "ios/public/fileToDelete"
|
|
|
- let ref = storage.reference(withPath: objectLocation)
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- let result = try await ref.putDataAsync(data)
|
|
|
- XCTAssertNotNil(result)
|
|
|
+ func testDelete() async throws {
|
|
|
+ let objectLocation = "ios/public/fileToDelete"
|
|
|
+ let ref = storage.reference(withPath: objectLocation)
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ let result = try await ref.putDataAsync(data)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ _ = try await ref.delete()
|
|
|
+ // Next delete should fail and verify the first delete succeeded.
|
|
|
+ var caughtError = false
|
|
|
+ do {
|
|
|
_ = try await ref.delete()
|
|
|
- // Next delete should fail and verify the first delete succeeded.
|
|
|
- var caughtError = false
|
|
|
- do {
|
|
|
- _ = try await ref.delete()
|
|
|
- } catch {
|
|
|
- caughtError = true
|
|
|
- let nsError = error as NSError
|
|
|
- XCTAssertEqual(nsError.code, StorageErrorCode.objectNotFound.rawValue)
|
|
|
- XCTAssertEqual(nsError.userInfo["ResponseErrorCode"] as? Int, 404)
|
|
|
- let underlyingError = try XCTUnwrap(nsError.userInfo[NSUnderlyingErrorKey] as? NSError)
|
|
|
- XCTAssertEqual(underlyingError.code, 404)
|
|
|
- XCTAssertEqual(underlyingError.domain, "com.google.HTTPStatus")
|
|
|
- }
|
|
|
- XCTAssertTrue(caughtError)
|
|
|
+ } catch {
|
|
|
+ caughtError = true
|
|
|
+ let nsError = error as NSError
|
|
|
+ XCTAssertEqual(nsError.code, StorageErrorCode.objectNotFound.rawValue)
|
|
|
+ XCTAssertEqual(nsError.userInfo["ResponseErrorCode"] as? Int, 404)
|
|
|
+ let underlyingError = try XCTUnwrap(nsError.userInfo[NSUnderlyingErrorKey] as? NSError)
|
|
|
+ XCTAssertEqual(underlyingError.code, 404)
|
|
|
+ XCTAssertEqual(underlyingError.domain, "com.google.HTTPStatus")
|
|
|
}
|
|
|
+ XCTAssertTrue(caughtError)
|
|
|
+ }
|
|
|
|
|
|
- func testDeleteAfterPut() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/fileToDelete")
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- let result = try await ref.putDataAsync(data)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- let result2: Void = try await ref.delete()
|
|
|
- XCTAssertNotNil(result2)
|
|
|
- }
|
|
|
+ func testDeleteAfterPut() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/fileToDelete")
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ let result = try await ref.putDataAsync(data)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ let result2: Void = try await ref.delete()
|
|
|
+ XCTAssertNotNil(result2)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutData() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/testBytesUpload")
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- let result = try await ref.putDataAsync(data)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testSimplePutData() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/testBytesUpload")
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ let result = try await ref.putDataAsync(data)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutSpecialCharacter() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/-._~!$'()*,=:@&+;")
|
|
|
- let data = try XCTUnwrap("Hello Swift World-._~!$'()*,=:@&+;".data(using: .utf8),
|
|
|
- "Data construction failed")
|
|
|
- let result = try await ref.putDataAsync(data)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testSimplePutSpecialCharacter() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/-._~!$'()*,=:@&+;")
|
|
|
+ let data = try XCTUnwrap("Hello Swift World-._~!$'()*,=:@&+;".data(using: .utf8),
|
|
|
+ "Data construction failed")
|
|
|
+ let result = try await ref.putDataAsync(data)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutDataInBackgroundQueue() async throws {
|
|
|
- actor Background {
|
|
|
- func uploadData(_ ref: StorageReference) async throws -> StorageMetadata {
|
|
|
- let data = try XCTUnwrap(
|
|
|
- "Hello Swift World".data(using: .utf8),
|
|
|
- "Data construction failed"
|
|
|
- )
|
|
|
- XCTAssertFalse(Thread.isMainThread)
|
|
|
- return try await ref.putDataAsync(data)
|
|
|
- }
|
|
|
+ func testSimplePutDataInBackgroundQueue() async throws {
|
|
|
+ actor Background {
|
|
|
+ func uploadData(_ ref: StorageReference) async throws -> StorageMetadata {
|
|
|
+ let data = try XCTUnwrap(
|
|
|
+ "Hello Swift World".data(using: .utf8),
|
|
|
+ "Data construction failed"
|
|
|
+ )
|
|
|
+ XCTAssertFalse(Thread.isMainThread)
|
|
|
+ return try await ref.putDataAsync(data)
|
|
|
}
|
|
|
- let ref = storage.reference(withPath: "ios/public/testBytesUpload")
|
|
|
- let result = try await Background().uploadData(ref)
|
|
|
- XCTAssertNotNil(result)
|
|
|
}
|
|
|
+ let ref = storage.reference(withPath: "ios/public/testBytesUpload")
|
|
|
+ let result = try await Background().uploadData(ref)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutEmptyData() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/testSimplePutEmptyData")
|
|
|
- let data = Data()
|
|
|
- let result = try await ref.putDataAsync(data)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testSimplePutEmptyData() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/testSimplePutEmptyData")
|
|
|
+ let data = Data()
|
|
|
+ let result = try await ref.putDataAsync(data)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutDataUnauthorized() async throws {
|
|
|
- let objectLocation = "ios/private/secretfile.txt"
|
|
|
- let ref = storage.reference(withPath: objectLocation)
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- do {
|
|
|
- _ = try await ref.putDataAsync(data)
|
|
|
- XCTFail("Unexpected success from unauthorized putData")
|
|
|
- } catch let StorageError.unauthorized(bucket, object) {
|
|
|
- XCTAssertEqual(bucket, "ios-opensource-samples.appspot.com")
|
|
|
- XCTAssertEqual(object, objectLocation)
|
|
|
- } catch {
|
|
|
- XCTFail("error failed to convert to StorageError.unauthorized")
|
|
|
- }
|
|
|
+ func testSimplePutDataUnauthorized() async throws {
|
|
|
+ let objectLocation = "ios/private/secretfile.txt"
|
|
|
+ let ref = storage.reference(withPath: objectLocation)
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ do {
|
|
|
+ _ = try await ref.putDataAsync(data)
|
|
|
+ XCTFail("Unexpected success from unauthorized putData")
|
|
|
+ } catch let StorageError.unauthorized(bucket, object) {
|
|
|
+ XCTAssertEqual(bucket, "ios-opensource-samples.appspot.com")
|
|
|
+ XCTAssertEqual(object, objectLocation)
|
|
|
+ } catch {
|
|
|
+ XCTFail("error failed to convert to StorageError.unauthorized")
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- func testAttemptToUploadDirectoryShouldFail() async throws {
|
|
|
- // This `.numbers` file is actually a directory.
|
|
|
- let fileName = "HomeImprovement.numbers"
|
|
|
- let bundle = Bundle(for: StorageIntegrationCommon.self)
|
|
|
- let fileURL = try XCTUnwrap(bundle.url(forResource: fileName, withExtension: ""),
|
|
|
- "Failed to get filePath")
|
|
|
- let ref = storage.reference(withPath: "ios/public/" + fileName)
|
|
|
- do {
|
|
|
- _ = try await ref.putFileAsync(from: fileURL)
|
|
|
- XCTFail("Unexpected success from putFile of a directory")
|
|
|
- } catch let StorageError.unknown(reason) {
|
|
|
- XCTAssertTrue(reason.starts(with: "File at URL:"))
|
|
|
- XCTAssertTrue(reason.hasSuffix(
|
|
|
- "is not reachable. Ensure file URL is not a directory, symbolic link, or invalid url."
|
|
|
- ))
|
|
|
- } catch {
|
|
|
- XCTFail("error failed to convert to StorageError.unknown")
|
|
|
- }
|
|
|
+ func testAttemptToUploadDirectoryShouldFail() async throws {
|
|
|
+ // This `.numbers` file is actually a directory.
|
|
|
+ let fileName = "HomeImprovement.numbers"
|
|
|
+ let bundle = Bundle(for: StorageIntegrationCommon.self)
|
|
|
+ let fileURL = try XCTUnwrap(bundle.url(forResource: fileName, withExtension: ""),
|
|
|
+ "Failed to get filePath")
|
|
|
+ let ref = storage.reference(withPath: "ios/public/" + fileName)
|
|
|
+ do {
|
|
|
+ _ = try await ref.putFileAsync(from: fileURL)
|
|
|
+ XCTFail("Unexpected success from putFile of a directory")
|
|
|
+ } catch let StorageError.unknown(reason) {
|
|
|
+ XCTAssertTrue(reason.starts(with: "File at URL:"))
|
|
|
+ XCTAssertTrue(reason.hasSuffix(
|
|
|
+ "is not reachable. Ensure file URL is not a directory, symbolic link, or invalid url."
|
|
|
+ ))
|
|
|
+ } catch {
|
|
|
+ XCTFail("error failed to convert to StorageError.unknown")
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- func testPutFileWithSpecialCharacters() async throws {
|
|
|
- let fileName = "hello&+@_ .txt"
|
|
|
- let ref = storage.reference(withPath: "ios/public/" + fileName)
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
- let fileURL = tmpDirURL.appendingPathComponent("hello.txt")
|
|
|
- try data.write(to: fileURL, options: .atomicWrite)
|
|
|
- let metadata = try await ref.putFileAsync(from: fileURL)
|
|
|
- XCTAssertEqual(fileName, metadata.name)
|
|
|
- let result = try await ref.getMetadata()
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testPutFileWithSpecialCharacters() async throws {
|
|
|
+ let fileName = "hello&+@_ .txt"
|
|
|
+ let ref = storage.reference(withPath: "ios/public/" + fileName)
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
+ let fileURL = tmpDirURL.appendingPathComponent(#function + "hello.txt")
|
|
|
+ try data.write(to: fileURL, options: .atomicWrite)
|
|
|
+ let metadata = try await ref.putFileAsync(from: fileURL)
|
|
|
+ XCTAssertEqual(fileName, metadata.name)
|
|
|
+ let result = try await ref.getMetadata()
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutDataNoMetadata() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/testSimplePutDataNoMetadata")
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- let result = try await ref.putDataAsync(data)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testSimplePutDataNoMetadata() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/testSimplePutDataNoMetadata")
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ let result = try await ref.putDataAsync(data)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutFileNoMetadata() async throws {
|
|
|
- let fileName = "hello&+@_ .txt"
|
|
|
- let ref = storage.reference(withPath: "ios/public/" + fileName)
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
- let fileURL = tmpDirURL.appendingPathComponent("hello.txt")
|
|
|
- try data.write(to: fileURL, options: .atomicWrite)
|
|
|
- let result = try await ref.putFileAsync(from: fileURL)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testSimplePutFileNoMetadata() async throws {
|
|
|
+ let fileName = "hello&+@_ .txt"
|
|
|
+ let ref = storage.reference(withPath: "ios/public/" + fileName)
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
+ let fileURL = tmpDirURL.appendingPathComponent("hello.txt")
|
|
|
+ try data.write(to: fileURL, options: .atomicWrite)
|
|
|
+ let result = try await ref.putFileAsync(from: fileURL)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimplePutFileWithAsyncProgress() async throws {
|
|
|
- var checkedProgress = false
|
|
|
- let ref = storage.reference(withPath: "ios/public/testSimplePutFile")
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
- let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
- let fileURL = tmpDirURL.appendingPathComponent("hello.txt")
|
|
|
- try data.write(to: fileURL, options: .atomicWrite)
|
|
|
- var uploadedBytes: Int64 = -1
|
|
|
- let successMetadata = try await ref.putFileAsync(from: fileURL) { progress in
|
|
|
- if let completed = progress?.completedUnitCount {
|
|
|
- checkedProgress = true
|
|
|
- XCTAssertGreaterThanOrEqual(completed, uploadedBytes)
|
|
|
- uploadedBytes = completed
|
|
|
- }
|
|
|
+ func testSimplePutFileWithAsyncProgress() async throws {
|
|
|
+ var checkedProgress = false
|
|
|
+ let ref = storage.reference(withPath: "ios/public/testSimplePutFile")
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
+ let fileURL = tmpDirURL.appendingPathComponent(#function + "hello.txt")
|
|
|
+ try data.write(to: fileURL, options: .atomicWrite)
|
|
|
+ var uploadedBytes: Int64 = -1
|
|
|
+ let successMetadata = try await ref.putFileAsync(from: fileURL) { progress in
|
|
|
+ if let completed = progress?.completedUnitCount {
|
|
|
+ checkedProgress = true
|
|
|
+ XCTAssertGreaterThanOrEqual(completed, uploadedBytes)
|
|
|
+ uploadedBytes = completed
|
|
|
}
|
|
|
- XCTAssertEqual(successMetadata.size, 17)
|
|
|
- XCTAssertTrue(checkedProgress)
|
|
|
}
|
|
|
+ XCTAssertEqual(successMetadata.size, 17)
|
|
|
+ XCTAssertTrue(checkedProgress)
|
|
|
+ }
|
|
|
|
|
|
- func testSimpleGetData() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
- let result = try await ref.data(maxSize: 1024 * 1024)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testSimpleGetData() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
+ let result = try await ref.data(maxSize: 1024 * 1024)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimpleGetDataWithTask() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
- let result = try await ref.data(maxSize: 1024 * 1024)
|
|
|
- XCTAssertNotNil(result)
|
|
|
- }
|
|
|
+ func testSimpleGetDataWithTask() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
+ let result = try await ref.data(maxSize: 1024 * 1024)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimpleGetDataInBackgroundQueue() async throws {
|
|
|
- actor Background {
|
|
|
- func data(from ref: StorageReference) async throws -> Data {
|
|
|
- XCTAssertFalse(Thread.isMainThread)
|
|
|
- return try await ref.data(maxSize: 1024 * 1024)
|
|
|
- }
|
|
|
+ func testSimpleGetDataInBackgroundQueue() async throws {
|
|
|
+ actor Background {
|
|
|
+ func data(from ref: StorageReference) async throws -> Data {
|
|
|
+ XCTAssertFalse(Thread.isMainThread)
|
|
|
+ return try await ref.data(maxSize: 1024 * 1024)
|
|
|
}
|
|
|
- let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
- let result = try await Background().data(from: ref)
|
|
|
- XCTAssertNotNil(result)
|
|
|
}
|
|
|
+ let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
+ let result = try await Background().data(from: ref)
|
|
|
+ XCTAssertNotNil(result)
|
|
|
+ }
|
|
|
|
|
|
- func testSimpleGetDataTooSmall() async {
|
|
|
- let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
- let max: Int64 = 1024
|
|
|
- do {
|
|
|
- _ = try await ref.data(maxSize: max)
|
|
|
- XCTFail("Unexpected success from getData too small")
|
|
|
- } catch let StorageError.downloadSizeExceeded(total, maxSize) {
|
|
|
- XCTAssertEqual(total, 1_048_576)
|
|
|
- XCTAssertEqual(maxSize, max)
|
|
|
- } catch {
|
|
|
- XCTFail("error failed to convert to StorageError.downloadSizeExceeded")
|
|
|
- }
|
|
|
+ func testSimpleGetDataTooSmall() async {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
+ let max: Int64 = 1024
|
|
|
+ do {
|
|
|
+ _ = try await ref.data(maxSize: max)
|
|
|
+ XCTFail("Unexpected success from getData too small")
|
|
|
+ } catch let StorageError.downloadSizeExceeded(total, maxSize) {
|
|
|
+ XCTAssertEqual(total, 1_048_576)
|
|
|
+ XCTAssertEqual(maxSize, max)
|
|
|
+ } catch {
|
|
|
+ XCTFail("error failed to convert to StorageError.downloadSizeExceeded")
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- func testSimpleGetDownloadURL() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
+ func testSimpleGetDownloadURL() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
|
|
|
- // Download URL format is
|
|
|
- // "https://firebasestorage.googleapis.com:443/v0/b/{bucket}/o/{path}?alt=media&token={token}"
|
|
|
- let downloadURLPattern =
|
|
|
- "^https:\\/\\/firebasestorage.googleapis.com:443\\/v0\\/b\\/[^\\/]*\\/o\\/" +
|
|
|
- "ios%2Fpublic%2F1mb2\\?alt=media&token=[a-z0-9-]*$"
|
|
|
+ // Download URL format is
|
|
|
+ // "https://firebasestorage.googleapis.com:443/v0/b/{bucket}/o/{path}?alt=media&token={token}"
|
|
|
+ let downloadURLPattern =
|
|
|
+ "^https:\\/\\/firebasestorage.googleapis.com:443\\/v0\\/b\\/[^\\/]*\\/o\\/" +
|
|
|
+ "ios%2Fpublic%2F1mb2\\?alt=media&token=[a-z0-9-]*$"
|
|
|
|
|
|
- let downloadURL = try await ref.downloadURL()
|
|
|
- let testRegex = try NSRegularExpression(pattern: downloadURLPattern)
|
|
|
- let urlString = downloadURL.absoluteString
|
|
|
- let range = NSRange(location: 0, length: urlString.count)
|
|
|
- XCTAssertNotNil(testRegex.firstMatch(in: urlString, options: [], range: range))
|
|
|
- }
|
|
|
+ let downloadURL = try await ref.downloadURL()
|
|
|
+ let testRegex = try NSRegularExpression(pattern: downloadURLPattern)
|
|
|
+ let urlString = downloadURL.absoluteString
|
|
|
+ let range = NSRange(location: 0, length: urlString.count)
|
|
|
+ XCTAssertNotNil(testRegex.firstMatch(in: urlString, options: [], range: range))
|
|
|
+ }
|
|
|
|
|
|
- func testAsyncWrite() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/helloworld")
|
|
|
- let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
- let fileURL = tmpDirURL.appendingPathComponent("hello.txt")
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
+ func testAsyncWrite() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/helloworld" + #function)
|
|
|
+ let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
+ let fileURL = tmpDirURL.appendingPathComponent(#function + "hello.txt")
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
|
|
|
- _ = try await ref.putDataAsync(data)
|
|
|
- let url = try await ref.writeAsync(toFile: fileURL)
|
|
|
- XCTAssertEqual(url.lastPathComponent, "hello.txt")
|
|
|
- }
|
|
|
+ _ = try await ref.putDataAsync(data)
|
|
|
+ let url = try await ref.writeAsync(toFile: fileURL)
|
|
|
+ XCTAssertEqual(url.lastPathComponent, #function + "hello.txt")
|
|
|
+ }
|
|
|
|
|
|
- func testSimpleGetFile() throws {
|
|
|
- let expectation = self.expectation(description: #function)
|
|
|
- let ref = storage.reference(withPath: "ios/public/helloworld")
|
|
|
- let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
- let fileURL = tmpDirURL.appendingPathComponent("hello.txt")
|
|
|
- let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
-
|
|
|
- Task {
|
|
|
- _ = try await ref.putDataAsync(data)
|
|
|
- let task = ref.write(toFile: fileURL)
|
|
|
-
|
|
|
- task.observe(StorageTaskStatus.success) { snapshot in
|
|
|
- do {
|
|
|
- let stringData = try String(contentsOf: fileURL, encoding: .utf8)
|
|
|
- XCTAssertEqual(stringData, "Hello Swift World")
|
|
|
- XCTAssertEqual(snapshot.description, "<State: Success>")
|
|
|
- } catch {
|
|
|
- XCTFail("Error processing success snapshot")
|
|
|
- }
|
|
|
- expectation.fulfill()
|
|
|
- }
|
|
|
+ func testSimpleGetFile() throws {
|
|
|
+ let expectation = self.expectation(description: #function)
|
|
|
+ let ref = storage.reference(withPath: "ios/public/helloworld" + #function)
|
|
|
+ let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
|
|
+ let fileURL = tmpDirURL.appendingPathComponent(#function + "hello.txt")
|
|
|
+ let data = try XCTUnwrap("Hello Swift World".data(using: .utf8), "Data construction failed")
|
|
|
|
|
|
- task.observe(StorageTaskStatus.progress) { snapshot in
|
|
|
- XCTAssertNil(snapshot.error, "Error should be nil")
|
|
|
- guard snapshot.progress != nil else {
|
|
|
- XCTFail("Missing progress")
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- task.observe(StorageTaskStatus.failure) { snapshot in
|
|
|
- XCTAssertNil(snapshot.error, "Error should be nil")
|
|
|
+ Task {
|
|
|
+ _ = try await ref.putDataAsync(data)
|
|
|
+ let task = ref.write(toFile: fileURL)
|
|
|
+
|
|
|
+ task.observe(StorageTaskStatus.success) { snapshot in
|
|
|
+ do {
|
|
|
+ let stringData = try String(contentsOf: fileURL, encoding: .utf8)
|
|
|
+ XCTAssertEqual(stringData, "Hello Swift World")
|
|
|
+ XCTAssertEqual(snapshot.description, "<State: Success>")
|
|
|
+ } catch {
|
|
|
+ XCTFail("Error processing success snapshot")
|
|
|
}
|
|
|
+ expectation.fulfill()
|
|
|
}
|
|
|
- waitForExpectations()
|
|
|
- }
|
|
|
|
|
|
- func testSimpleGetFileWithAsyncProgressCallbackAPI() async throws {
|
|
|
- var checkedProgress = false
|
|
|
- let ref = storage.reference().child("ios/public/1mb")
|
|
|
- let url = URL(fileURLWithPath: "\(NSTemporaryDirectory())/hello.txt")
|
|
|
- let fileURL = url
|
|
|
- var downloadedBytes: Int64 = 0
|
|
|
- var resumeAtBytes = 256 * 1024
|
|
|
- let successURL = try await ref.writeAsync(toFile: fileURL) { progress in
|
|
|
- if let completed = progress?.completedUnitCount {
|
|
|
- checkedProgress = true
|
|
|
- XCTAssertGreaterThanOrEqual(completed, downloadedBytes)
|
|
|
- downloadedBytes = completed
|
|
|
- if completed > resumeAtBytes {
|
|
|
- resumeAtBytes = Int.max
|
|
|
- }
|
|
|
+ task.observe(StorageTaskStatus.progress) { snapshot in
|
|
|
+ XCTAssertNil(snapshot.error, "Error should be nil")
|
|
|
+ guard snapshot.progress != nil else {
|
|
|
+ XCTFail("Missing progress")
|
|
|
+ return
|
|
|
}
|
|
|
}
|
|
|
- XCTAssertTrue(checkedProgress)
|
|
|
- XCTAssertEqual(successURL, url)
|
|
|
- XCTAssertEqual(resumeAtBytes, Int.max)
|
|
|
+ task.observe(StorageTaskStatus.failure) { snapshot in
|
|
|
+ XCTAssertNil(snapshot.error, "Error should be nil")
|
|
|
+ }
|
|
|
}
|
|
|
+ waitForExpectations()
|
|
|
+ }
|
|
|
|
|
|
- private func assertMetadata(actualMetadata: StorageMetadata,
|
|
|
- expectedContentType: String,
|
|
|
- expectedCustomMetadata: [String: String]) {
|
|
|
- XCTAssertEqual(actualMetadata.cacheControl, "cache-control")
|
|
|
- XCTAssertEqual(actualMetadata.contentDisposition, "content-disposition")
|
|
|
- XCTAssertEqual(actualMetadata.contentEncoding, "gzip")
|
|
|
- XCTAssertEqual(actualMetadata.contentLanguage, "de")
|
|
|
- XCTAssertEqual(actualMetadata.contentType, expectedContentType)
|
|
|
- XCTAssertEqual(actualMetadata.md5Hash?.count, 24)
|
|
|
- for (key, value) in expectedCustomMetadata {
|
|
|
- XCTAssertEqual(actualMetadata.customMetadata![key], value)
|
|
|
+ func testSimpleGetFileWithAsyncProgressCallbackAPI() async throws {
|
|
|
+ var checkedProgress = false
|
|
|
+ let ref = storage.reference().child("ios/public/1mb")
|
|
|
+ let url = URL(fileURLWithPath: "\(NSTemporaryDirectory())/hello.txt")
|
|
|
+ let fileURL = url
|
|
|
+ var downloadedBytes: Int64 = 0
|
|
|
+ var resumeAtBytes = 256 * 1024
|
|
|
+ let successURL = try await ref.writeAsync(toFile: fileURL) { progress in
|
|
|
+ if let completed = progress?.completedUnitCount {
|
|
|
+ checkedProgress = true
|
|
|
+ XCTAssertGreaterThanOrEqual(completed, downloadedBytes)
|
|
|
+ downloadedBytes = completed
|
|
|
+ if completed > resumeAtBytes {
|
|
|
+ resumeAtBytes = Int.max
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ XCTAssertTrue(checkedProgress)
|
|
|
+ XCTAssertEqual(successURL, url)
|
|
|
+ XCTAssertEqual(resumeAtBytes, Int.max)
|
|
|
+ }
|
|
|
|
|
|
- private func assertMetadataNil(actualMetadata: StorageMetadata) {
|
|
|
- XCTAssertNil(actualMetadata.cacheControl)
|
|
|
- XCTAssertNil(actualMetadata.contentDisposition)
|
|
|
- XCTAssertEqual(actualMetadata.contentEncoding, "identity")
|
|
|
- XCTAssertNil(actualMetadata.contentLanguage)
|
|
|
- XCTAssertNil(actualMetadata.contentType)
|
|
|
- XCTAssertEqual(actualMetadata.md5Hash?.count, 24)
|
|
|
- XCTAssertNil(actualMetadata.customMetadata)
|
|
|
+ private func assertMetadata(actualMetadata: StorageMetadata,
|
|
|
+ expectedContentType: String,
|
|
|
+ expectedCustomMetadata: [String: String]) {
|
|
|
+ XCTAssertEqual(actualMetadata.cacheControl, "cache-control")
|
|
|
+ XCTAssertEqual(actualMetadata.contentDisposition, "content-disposition")
|
|
|
+ XCTAssertEqual(actualMetadata.contentEncoding, "gzip")
|
|
|
+ XCTAssertEqual(actualMetadata.contentLanguage, "de")
|
|
|
+ XCTAssertEqual(actualMetadata.contentType, expectedContentType)
|
|
|
+ XCTAssertEqual(actualMetadata.md5Hash?.count, 24)
|
|
|
+ for (key, value) in expectedCustomMetadata {
|
|
|
+ XCTAssertEqual(actualMetadata.customMetadata![key], value)
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- func testUpdateMetadata2() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
-
|
|
|
- let metadata = StorageMetadata()
|
|
|
- metadata.cacheControl = "cache-control"
|
|
|
- metadata.contentDisposition = "content-disposition"
|
|
|
- metadata.contentEncoding = "gzip"
|
|
|
- metadata.contentLanguage = "de"
|
|
|
- metadata.contentType = "content-type-a"
|
|
|
- metadata.customMetadata = ["a": "b"]
|
|
|
-
|
|
|
- let updatedMetadata = try await ref.updateMetadata(metadata)
|
|
|
- assertMetadata(actualMetadata: updatedMetadata,
|
|
|
- expectedContentType: "content-type-a",
|
|
|
- expectedCustomMetadata: ["a": "b"])
|
|
|
-
|
|
|
- let metadata2 = updatedMetadata
|
|
|
- metadata2.contentType = "content-type-b"
|
|
|
- metadata2.customMetadata = ["a": "b", "c": "d"]
|
|
|
-
|
|
|
- let metadata3 = try await ref.updateMetadata(metadata2)
|
|
|
- assertMetadata(actualMetadata: metadata3,
|
|
|
- expectedContentType: "content-type-b",
|
|
|
- expectedCustomMetadata: ["a": "b", "c": "d"])
|
|
|
- metadata.cacheControl = nil
|
|
|
- metadata.contentDisposition = nil
|
|
|
- metadata.contentEncoding = nil
|
|
|
- metadata.contentLanguage = nil
|
|
|
- metadata.contentType = nil
|
|
|
- metadata.customMetadata = nil
|
|
|
- let metadata4 = try await ref.updateMetadata(metadata)
|
|
|
- XCTAssertNotNil(metadata4)
|
|
|
- }
|
|
|
+ private func assertMetadataNil(actualMetadata: StorageMetadata) {
|
|
|
+ XCTAssertNil(actualMetadata.cacheControl)
|
|
|
+ XCTAssertNil(actualMetadata.contentDisposition)
|
|
|
+ XCTAssertEqual(actualMetadata.contentEncoding, "identity")
|
|
|
+ XCTAssertNil(actualMetadata.contentLanguage)
|
|
|
+ XCTAssertNil(actualMetadata.contentType)
|
|
|
+ XCTAssertEqual(actualMetadata.md5Hash?.count, 24)
|
|
|
+ XCTAssertNil(actualMetadata.customMetadata)
|
|
|
+ }
|
|
|
|
|
|
- func testPagedListFiles() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/list")
|
|
|
- let listResult = try await ref.list(maxResults: 2)
|
|
|
- XCTAssertEqual(listResult.items, [ref.child("a"), ref.child("b")])
|
|
|
- XCTAssertEqual(listResult.prefixes, [])
|
|
|
- let pageToken = try XCTUnwrap(listResult.pageToken)
|
|
|
- let listResult2 = try await ref.list(maxResults: 2, pageToken: pageToken)
|
|
|
- XCTAssertEqual(listResult2.items, [])
|
|
|
- XCTAssertEqual(listResult2.prefixes, [ref.child("prefix")])
|
|
|
- XCTAssertNil(listResult2.pageToken, "pageToken should be nil")
|
|
|
- }
|
|
|
+ func testUpdateMetadata2() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/1mb2")
|
|
|
+
|
|
|
+ let metadata = StorageMetadata()
|
|
|
+ metadata.cacheControl = "cache-control"
|
|
|
+ metadata.contentDisposition = "content-disposition"
|
|
|
+ metadata.contentEncoding = "gzip"
|
|
|
+ metadata.contentLanguage = "de"
|
|
|
+ metadata.contentType = "content-type-a"
|
|
|
+ metadata.customMetadata = ["a": "b"]
|
|
|
+
|
|
|
+ let updatedMetadata = try await ref.updateMetadata(metadata)
|
|
|
+ assertMetadata(actualMetadata: updatedMetadata,
|
|
|
+ expectedContentType: "content-type-a",
|
|
|
+ expectedCustomMetadata: ["a": "b"])
|
|
|
+
|
|
|
+ let metadata2 = updatedMetadata
|
|
|
+ metadata2.contentType = "content-type-b"
|
|
|
+ metadata2.customMetadata = ["a": "b", "c": "d"]
|
|
|
+
|
|
|
+ let metadata3 = try await ref.updateMetadata(metadata2)
|
|
|
+ assertMetadata(actualMetadata: metadata3,
|
|
|
+ expectedContentType: "content-type-b",
|
|
|
+ expectedCustomMetadata: ["a": "b", "c": "d"])
|
|
|
+ metadata.cacheControl = nil
|
|
|
+ metadata.contentDisposition = nil
|
|
|
+ metadata.contentEncoding = nil
|
|
|
+ metadata.contentLanguage = nil
|
|
|
+ metadata.contentType = nil
|
|
|
+ metadata.customMetadata = nil
|
|
|
+ let metadata4 = try await ref.updateMetadata(metadata)
|
|
|
+ XCTAssertNotNil(metadata4)
|
|
|
+ }
|
|
|
|
|
|
- func testPagedListFilesError() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/list")
|
|
|
- do {
|
|
|
- let _: StorageListResult = try await ref.list(maxResults: 22222)
|
|
|
- XCTFail("Unexpected success from ref.list")
|
|
|
- } catch let StorageError.invalidArgument(message) {
|
|
|
- XCTAssertEqual(message, "Argument 'maxResults' must be between 1 and 1000 inclusive.")
|
|
|
- } catch {
|
|
|
- XCTFail("Unexpected error")
|
|
|
- }
|
|
|
- }
|
|
|
+ func testPagedListFiles() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/list")
|
|
|
+ let listResult = try await ref.list(maxResults: 2)
|
|
|
+ XCTAssertEqual(listResult.items, [ref.child("a"), ref.child("b")])
|
|
|
+ XCTAssertEqual(listResult.prefixes, [])
|
|
|
+ let pageToken = try XCTUnwrap(listResult.pageToken)
|
|
|
+ let listResult2 = try await ref.list(maxResults: 2, pageToken: pageToken)
|
|
|
+ XCTAssertEqual(listResult2.items, [])
|
|
|
+ XCTAssertEqual(listResult2.prefixes, [ref.child("prefix")])
|
|
|
+ XCTAssertNil(listResult2.pageToken, "pageToken should be nil")
|
|
|
+ }
|
|
|
|
|
|
- func testListAllFiles() async throws {
|
|
|
- let ref = storage.reference(withPath: "ios/public/list")
|
|
|
- let listResult = try await ref.listAll()
|
|
|
- XCTAssertEqual(listResult.items, [ref.child("a"), ref.child("b")])
|
|
|
- XCTAssertEqual(listResult.prefixes, [ref.child("prefix")])
|
|
|
- XCTAssertNil(listResult.pageToken, "pageToken should be nil")
|
|
|
+ func testPagedListFilesError() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/list")
|
|
|
+ do {
|
|
|
+ let _: StorageListResult = try await ref.list(maxResults: 22222)
|
|
|
+ XCTFail("Unexpected success from ref.list")
|
|
|
+ } catch let StorageError.invalidArgument(message) {
|
|
|
+ XCTAssertEqual(message, "Argument 'maxResults' must be between 1 and 1000 inclusive.")
|
|
|
+ } catch {
|
|
|
+ XCTFail("Unexpected error")
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- private func waitForExpectations() {
|
|
|
- let kTestTimeout = 60.0
|
|
|
- waitForExpectations(timeout: kTestTimeout,
|
|
|
- handler: { error in
|
|
|
- if let error = error {
|
|
|
- print(error)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
+ func testListAllFiles() async throws {
|
|
|
+ let ref = storage.reference(withPath: "ios/public/list")
|
|
|
+ let listResult = try await ref.listAll()
|
|
|
+ XCTAssertEqual(listResult.items, [ref.child("a"), ref.child("b")])
|
|
|
+ XCTAssertEqual(listResult.prefixes, [ref.child("prefix")])
|
|
|
+ XCTAssertNil(listResult.pageToken, "pageToken should be nil")
|
|
|
+ }
|
|
|
+
|
|
|
+ private func waitForExpectations() {
|
|
|
+ let kTestTimeout = 60.0
|
|
|
+ waitForExpectations(timeout: kTestTimeout,
|
|
|
+ handler: { error in
|
|
|
+ if let error = error {
|
|
|
+ print(error)
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
-#endif
|
|
|
+}
|