| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- // Copyright 2022 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- import Foundation
- import FirebaseCore
- @testable import FirebaseStorage
- import FirebaseAppCheckInterop
- import FirebaseAuthInterop
- import SharedTestUtilities
- import XCTest
- class StorageReferenceTests: XCTestCase {
- override class func setUp() {
- let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000",
- gcmSenderID: "00000000000000000-00000000000-000000000")
- options.projectID = "myProjectID-Ref"
- FirebaseApp.configure(name: "test-StorageReference", options: options)
- }
- var storage: Storage?
- override func setUp() {
- guard let app = try? getApp(bucket: "bucket") else {
- fatalError("")
- }
- storage = Storage.storage(app: app)
- }
- func testRoot() throws {
- let ref = storage!.reference(forURL: "gs://bucket/path/to/object")
- XCTAssertEqual(ref.root().description, "gs://bucket/")
- }
- func testRootWithURLAPI() throws {
- let url = try XCTUnwrap(URL(string: "gs://bucket/path/to/object"))
- let ref = try storage!.reference(for: url)
- XCTAssertEqual(ref.root().description, "gs://bucket/")
- }
- func testRootWithNoPath() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- XCTAssertEqual(ref.root().description, "gs://bucket/")
- }
- func testMismatchedBucket() throws {
- do {
- let url = try XCTUnwrap(URL(string: "gs://bcket/"))
- _ = try storage!.reference(for: url)
- } catch let StorageError.bucketMismatch(string) {
- XCTAssertEqual(string, "Provided bucket: `bcket` does not match the Storage " +
- "bucket of the current instance: `bucket`")
- return
- }
- XCTFail()
- }
- func testMismatchedBucket2() throws {
- let url = try XCTUnwrap(URL(string: "gs://bcket/"))
- XCTAssertThrowsError(try storage!.reference(for: url), "This was supposed to fail.") { error in
- XCTAssertEqual(
- "\(error)",
- "bucketMismatch(\"Provided bucket: `bcket` does not match the Storage " +
- "bucket of the current instance: `bucket`\")"
- )
- }
- }
- func testBadBucketScheme() throws {
- do {
- let url = try XCTUnwrap(URL(string: "htttp://bucket/"))
- _ = try storage!.reference(for: url)
- } catch let StorageError.pathError(string) {
- XCTAssertEqual(
- string,
- "Internal error: URL scheme must be one of gs://, http://, or https://"
- )
- return
- }
- XCTFail()
- }
- func testBadBucketScheme2() throws {
- let url = try XCTUnwrap(URL(string: "htttp://bucket/"))
- XCTAssertThrowsError(try storage!.reference(for: url), "This was supposed to fail.") { error in
- XCTAssertEqual("\(error)", "pathError(\"Internal error: URL scheme must be one of gs://, " +
- "http://, or https://\")")
- }
- }
- func testSingleChild() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- let childRef = ref.child("path")
- XCTAssertEqual(childRef.description, "gs://bucket/path")
- }
- func testMultipleChildrenSingleString() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- let childRef = ref.child("path/to/object")
- XCTAssertEqual(childRef.description, "gs://bucket/path/to/object")
- }
- func testMultipleChildrenMultipleStrings() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- let childRef = ref.child("path").child("to").child("object")
- XCTAssertEqual(childRef.description, "gs://bucket/path/to/object")
- }
- func testSameChildDifferentRef() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- let firstRef = ref.child("1")
- let secondRef = ref.child("1")
- XCTAssertEqual(ref.description, "gs://bucket/")
- XCTAssertTrue(firstRef == secondRef)
- XCTAssertFalse(firstRef === secondRef)
- }
- func testDifferentChildDifferentRef() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- let firstRef = ref.child("1")
- let secondRef = ref.child("2")
- XCTAssertEqual(ref.description, "gs://bucket/")
- XCTAssertFalse(firstRef == secondRef)
- XCTAssertFalse(firstRef === secondRef)
- }
- func testChildWithTrailingSlash() throws {
- let ref = storage!.reference(forURL: "gs://bucket/path/to/object/")
- XCTAssertEqual(ref.description, "gs://bucket/path/to/object")
- }
- func testChildWithLeadingSlash() throws {
- let ref = storage!.reference(forURL: "gs://bucket//path/to/object/")
- XCTAssertEqual(ref.description, "gs://bucket/path/to/object")
- }
- func testChildCompressSlashes() throws {
- let ref = storage!.reference(forURL: "gs://bucket//path/////to////object////")
- XCTAssertEqual(ref.description, "gs://bucket/path/to/object")
- }
- func testParent() throws {
- let ref = storage!.reference(forURL: "gs://bucket//path/to/object/")
- let parentRef = try XCTUnwrap(ref.parent())
- XCTAssertEqual(parentRef.description, "gs://bucket/path/to")
- }
- func testParentToRoot() throws {
- let ref = storage!.reference(forURL: "gs://bucket/path")
- let parentRef = try XCTUnwrap(ref.parent())
- XCTAssertEqual(parentRef.description, "gs://bucket/")
- }
- func testParentToRootTrailingSlash() throws {
- let ref = storage!.reference(forURL: "gs://bucket/path/")
- let parentRef = try XCTUnwrap(ref.parent())
- XCTAssertEqual(parentRef.description, "gs://bucket/")
- }
- func testParentAtRoot() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- XCTAssertNil(ref.parent())
- }
- func testBucket() throws {
- let ref = storage!.reference(forURL: "gs://bucket//path/to/object/")
- XCTAssertEqual(ref.bucket, "bucket")
- }
- func testName() throws {
- let ref = storage!.reference(forURL: "gs://bucket/path/to/object/")
- XCTAssertEqual(ref.name, "object")
- }
- func testNameNoObject() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- XCTAssertEqual(ref.name, "")
- }
- func testFullPath() throws {
- let ref = storage!.reference(forURL: "gs://bucket/path/to/object/")
- XCTAssertEqual(ref.fullPath, "path/to/object")
- }
- func testFullPathNoObject() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- XCTAssertEqual(ref.fullPath, "")
- }
- func testCopy() throws {
- let ref = storage!.reference(forURL: "gs://bucket/")
- let copiedRef = ref.copy() as? StorageReference
- XCTAssertTrue(ref == copiedRef)
- XCTAssertFalse(ref === copiedRef)
- }
- func testReferenceWithNonExistentFileFailsWithCompletionResult() throws {
- let tempFilePath = NSTemporaryDirectory().appending("temp.data")
- let ref = storage!.reference(withPath: tempFilePath)
- let dummyFileURL = try XCTUnwrap(URL(string: "some_non_existing-folder/file.data"))
- let expectation = self.expectation(description: #function)
- ref.putFile(from: dummyFileURL) { result in
- expectation.fulfill()
- switch result {
- case .success:
- XCTFail("Unexpected success.", file: #file, line: #line)
- case let .failure(error):
- switch error {
- case let StorageError.unknown(message):
- let expectedDescription = "File at URL: \(dummyFileURL.absoluteString) " +
- "is not reachable. Ensure file URL is not a directory, symbolic link, or invalid url."
- XCTAssertEqual(expectedDescription, message)
- default:
- XCTFail("Failed to match expected Internal Error")
- }
- }
- }
- waitForExpectations(timeout: 0.5)
- }
- func testReferenceWithNonExistentFileFailsWithCompletionCallback() throws {
- let tempFilePath = NSTemporaryDirectory().appending("temp.data")
- let ref = storage!.reference(withPath: tempFilePath)
- let dummyFileURL = try XCTUnwrap(URL(string: "some_non_existing-folder/file.data"))
- let expectation = self.expectation(description: #function)
- ref.putFile(from: dummyFileURL) { metadata, error in
- expectation.fulfill()
- XCTAssertNil(metadata)
- let nsError = (error as? NSError)!
- XCTAssertEqual(nsError.code, StorageErrorCode.unknown.rawValue)
- let expectedDescription = "File at URL: \(dummyFileURL.absoluteString) " +
- "is not reachable. Ensure file URL is not a directory, symbolic link, or invalid url."
- XCTAssertEqual(expectedDescription, nsError.localizedDescription)
- XCTAssertEqual(nsError.domain, StorageErrorDomain)
- }
- waitForExpectations(timeout: 0.5)
- }
- func testReferenceWithNilFileFailsWithCompletionCallback() throws {
- let tempFilePath = NSTemporaryDirectory().appending("temp.data")
- let ref = storage!.reference(withPath: tempFilePath)
- let dummyFileURL = try XCTUnwrap(URL(string: "bad-url"))
- let expectation = self.expectation(description: #function)
- ref.putFile(from: dummyFileURL) { metadata, error in
- expectation.fulfill()
- XCTAssertNil(metadata)
- let nsError = (error as? NSError)!
- XCTAssertEqual(nsError.code, StorageErrorCode.unknown.rawValue)
- let expectedDescription = "File at URL: \(dummyFileURL.absoluteString) " +
- "is not reachable. Ensure file URL is not a directory, symbolic link, or invalid url."
- XCTAssertEqual(expectedDescription, nsError.localizedDescription)
- XCTAssertEqual(nsError.domain, StorageErrorDomain)
- }
- waitForExpectations(timeout: 1.0)
- }
- // MARK: Private Helpers
- // Cache the app associated with each Storage bucket
- private static var appDictionary: [String: FirebaseApp] = [:]
- private func getApp(bucket: String) throws -> FirebaseApp {
- let savedApp = StorageReferenceTests.appDictionary[bucket]
- guard savedApp == nil else {
- return try XCTUnwrap(savedApp)
- }
- let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000",
- gcmSenderID: "00000000000000000-00000000000-000000000")
- options.projectID = "myProjectID"
- options.storageBucket = bucket
- let name = "StorageTests\(bucket)"
- let app = FirebaseApp(instanceWithName: name, options: options)
- StorageReferenceTests.appDictionary[bucket] = app
- return app
- }
- }
|