mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-10 22:45:59 +05:45
288 lines
11 KiB
Swift
288 lines
11 KiB
Swift
// 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
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
class StorageTests: XCTestCase {
|
|
override class func setUp() {
|
|
let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000",
|
|
gcmSenderID: "00000000000000000-00000000000-000000000")
|
|
options.projectID = "myProjectID"
|
|
FirebaseApp.configure(name: "test-StorageTests", options: options)
|
|
}
|
|
|
|
func testBucketNotEnforced() throws {
|
|
let app = try getApp(bucket: "")
|
|
let storage = Storage.storage(app: app)
|
|
_ = storage.reference(forURL: "gs://benwu-test1.storage.firebase.com/child")
|
|
_ = storage.reference(forURL: "gs://benwu-test2.storage.firebase.com/child")
|
|
}
|
|
|
|
func testBucketEnforced() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app, url: "gs://benwu-test1.storage.firebase.com")
|
|
let url = try XCTUnwrap(URL(string: "gs://benwu-test2.storage.firebase.com/child"))
|
|
XCTAssertThrowsError(try storage.reference(for: url), "This was supposed to fail.") { error in
|
|
XCTAssertEqual(
|
|
"\(error)",
|
|
"bucketMismatch(message: \"Provided bucket: `benwu-test2.storage.firebase.com` does not match the " +
|
|
"Storage bucket of the current instance: `benwu-test1.storage.firebase.com`\")"
|
|
)
|
|
}
|
|
}
|
|
|
|
func testInitWithCustomURL() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app, url: "gs://foo-bar.appspot.com")
|
|
XCTAssertEqual("gs://foo-bar.appspot.com/", storage.reference().description)
|
|
let storage2 = Storage.storage(app: app, url: "gs://foo-bar.appspot.com/")
|
|
XCTAssertEqual("gs://foo-bar.appspot.com/", storage2.reference().description)
|
|
}
|
|
|
|
func SKIPtestInitWithWrongScheme() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
XCTAssertThrowsObjCException {
|
|
_ = Storage.storage(app: app, url: "http://foo-bar.appspot.com")
|
|
}
|
|
}
|
|
|
|
func SKIPtestInitWithNoScheme() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
XCTAssertThrowsObjCException {
|
|
_ = Storage.storage(app: app, url: "foo-bar.appspot.com")
|
|
}
|
|
}
|
|
|
|
func testInitWithoutURL() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
XCTAssertNoThrowObjCException {
|
|
_ = Storage.storage(app: app)
|
|
}
|
|
}
|
|
|
|
func SKIPtestInitWithPath() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
XCTAssertThrowsObjCException {
|
|
_ = Storage.storage(app: app, url: "gs://foo-bar.appspot.com/child")
|
|
}
|
|
}
|
|
|
|
func testInitWithDefaultAndCustomURL() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let defaultInstance = Storage.storage(app: app)
|
|
let customInstance = Storage.storage(app: app, url: "gs://foo-bar.appspot.com")
|
|
XCTAssertEqual("gs://foo-bar.appspot.com/", customInstance.reference().description)
|
|
XCTAssertEqual("gs://bucket/", defaultInstance.reference().description)
|
|
}
|
|
|
|
func testStorageDefaultApp() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app)
|
|
XCTAssertEqual(storage.app.name, app.name)
|
|
}
|
|
|
|
func SKIPtestStorageNoBucketInConfig() throws {
|
|
let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000",
|
|
gcmSenderID: "00000000000000000-00000000000-000000000")
|
|
options.projectID = "myProjectID"
|
|
let name = "StorageTestsNil"
|
|
let app = FirebaseApp(instanceWithName: name, options: options)
|
|
XCTAssertThrowsObjCException {
|
|
_ = Storage.storage(app: app)
|
|
}
|
|
}
|
|
|
|
func testStorageEmptyBucketInConfig() throws {
|
|
let app = try getApp(bucket: "")
|
|
let storage = Storage.storage(app: app)
|
|
let ref = storage.reference(forURL: "gs://bucket/path/to/object")
|
|
XCTAssertEqual(ref.bucket, "bucket")
|
|
}
|
|
|
|
func testStorageWrongBucketInConfig() throws {
|
|
let app = try getApp(bucket: "notMyBucket")
|
|
let storage = Storage.storage(app: app)
|
|
let url = try XCTUnwrap(URL(string: "gs://bucket/path/to/object"))
|
|
XCTAssertThrowsError(try storage.reference(for: url), "This was supposed to fail.") { error in
|
|
XCTAssertEqual(
|
|
"\(error)",
|
|
"bucketMismatch(message: \"Provided bucket: `bucket` does not match the " +
|
|
"Storage bucket of the current instance: `notMyBucket`\")"
|
|
)
|
|
}
|
|
}
|
|
|
|
func testUseEmulator() throws {
|
|
let app = try getApp(bucket: "bucket-for-testUseEmulator")
|
|
let storage = Storage.storage(app: app)
|
|
storage.useEmulator(withHost: "localhost", port: 8080)
|
|
XCTAssertNoThrow(storage.reference())
|
|
}
|
|
|
|
func SKIPtestUseEmulatorValidatesHost() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app, url: "gs://foo-bar.appspot.com")
|
|
XCTAssertThrowsObjCException {
|
|
storage.useEmulator(withHost: "", port: 8080)
|
|
}
|
|
}
|
|
|
|
func SKIPtestUseEmulatorValidatesPort() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app, url: "gs://foo-bar.appspot.com")
|
|
XCTAssertThrowsObjCException {
|
|
storage.useEmulator(withHost: "localhost", port: -1)
|
|
}
|
|
}
|
|
|
|
func SKIPtestUseEmulatorCannotBeCalledAfterObtainingReference() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app, url: "gs://benwu-test1.storage.firebase.com")
|
|
_ = storage.reference()
|
|
XCTAssertThrowsObjCException {
|
|
storage.useEmulator(withHost: "localhost", port: 8080)
|
|
}
|
|
}
|
|
|
|
func testRefDefaultApp() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage(app: app, bucket: "bucket")
|
|
let convenienceRef = storage.reference(forURL: "gs://bucket/path/to/object")
|
|
let path = StoragePath(with: "bucket", object: "path/to/object")
|
|
let builtRef = StorageReference(storage: storage, path: path)
|
|
XCTAssertEqual(convenienceRef.description, builtRef.description)
|
|
XCTAssertEqual(convenienceRef.storage.app, builtRef.storage.app)
|
|
}
|
|
|
|
func testRefCustomApp() throws {
|
|
let secondApp = try getApp(bucket: "bucket2")
|
|
let storage2 = Storage.storage(app: secondApp)
|
|
let convenienceRef = storage2.reference(forURL: "gs://bucket2/path/to/object")
|
|
let path = StoragePath(with: "bucket2", object: "path/to/object")
|
|
let builtRef = StorageReference(storage: storage2, path: path)
|
|
XCTAssertEqual(convenienceRef.description, builtRef.description)
|
|
XCTAssertEqual(convenienceRef.storage.app, builtRef.storage.app)
|
|
}
|
|
|
|
func testRootRefDefaultApp() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app)
|
|
let convenienceRef = storage.reference()
|
|
let path = StoragePath(with: "bucket")
|
|
let builtRef = StorageReference(storage: storage, path: path)
|
|
XCTAssertEqual(convenienceRef.description, builtRef.description)
|
|
XCTAssertEqual(convenienceRef.storage.app, builtRef.storage.app)
|
|
}
|
|
|
|
func testRefWithPathDefaultApp() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app)
|
|
let convenienceRef = storage.reference(forURL: "gs://bucket/path/to/object")
|
|
let path = StoragePath(with: "bucket", object: "path/to/object")
|
|
let builtRef = StorageReference(storage: storage, path: path)
|
|
XCTAssertEqual(convenienceRef.description, builtRef.description)
|
|
XCTAssertEqual(convenienceRef.storage.app, builtRef.storage.app)
|
|
}
|
|
|
|
func testEqual() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app)
|
|
let copy = try XCTUnwrap(storage.copy() as? Storage)
|
|
XCTAssertEqual(storage.app.name, copy.app.name)
|
|
XCTAssertEqual(storage.hash, copy.hash)
|
|
}
|
|
|
|
func testNotEqual() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app)
|
|
let secondApp = try getApp(bucket: "bucket2")
|
|
let storage2 = Storage.storage(app: secondApp)
|
|
XCTAssertNotEqual(storage, storage2)
|
|
XCTAssertNotEqual(storage.hash, storage2.hash)
|
|
}
|
|
|
|
func testHash() throws {
|
|
let app = try getApp(bucket: "bucket")
|
|
let storage = Storage.storage(app: app)
|
|
let copy = try XCTUnwrap(storage.copy() as? Storage)
|
|
XCTAssertEqual(storage.app.name, copy.app.name)
|
|
}
|
|
|
|
func testTranslateRetryTime() {
|
|
// The 1st retry attempt runs after 1 second.
|
|
// The 2nd retry attempt is delayed by 2 seconds (3s total)
|
|
// The 3rd retry attempt is delayed by 4 seconds (7s total)
|
|
// The 4th retry attempt is delayed by 8 seconds (15s total)
|
|
// The 5th retry attempt is delayed by 16 seconds (31s total)
|
|
// The 6th retry attempt is delayed by 32 seconds (63s total)
|
|
// Thus, we should exit just between the 5th and 6th retry attempt and cut off before 32s.
|
|
XCTAssertEqual(1.0, Storage.computeRetryInterval(fromRetryTime: 1.0))
|
|
XCTAssertEqual(2.0, Storage.computeRetryInterval(fromRetryTime: 2.0))
|
|
XCTAssertEqual(4.0, Storage.computeRetryInterval(fromRetryTime: 4.0))
|
|
XCTAssertEqual(8.0, Storage.computeRetryInterval(fromRetryTime: 10.0))
|
|
XCTAssertEqual(16.0, Storage.computeRetryInterval(fromRetryTime: 20.0))
|
|
XCTAssertEqual(16.0, Storage.computeRetryInterval(fromRetryTime: 30.0))
|
|
XCTAssertEqual(32.0, Storage.computeRetryInterval(fromRetryTime: 40.0))
|
|
XCTAssertEqual(32.0, Storage.computeRetryInterval(fromRetryTime: 50.0))
|
|
XCTAssertEqual(32.0, Storage.computeRetryInterval(fromRetryTime: 60.0))
|
|
}
|
|
|
|
func testRetryTimeChange() throws {
|
|
let app = try getApp(bucket: "")
|
|
let storage = Storage.storage(app: app)
|
|
XCTAssertEqual(storage.maxOperationRetryInterval, 64)
|
|
storage.maxOperationRetryTime = 11
|
|
XCTAssertEqual(storage.maxOperationRetryTime, 11)
|
|
XCTAssertEqual(storage.maxOperationRetryInterval, 8)
|
|
}
|
|
|
|
// 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 = StorageTests.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)
|
|
StorageTests.appDictionary[bucket] = app
|
|
return app
|
|
}
|
|
|
|
private func XCTAssertThrowsObjCException(_ closure: @escaping () -> Void) {
|
|
XCTAssertThrowsError(try ExceptionCatcher.catchException(closure))
|
|
}
|
|
|
|
private func XCTAssertNoThrowObjCException(_ closure: @escaping () -> Void) {
|
|
XCTAssertNoThrow(try ExceptionCatcher.catchException(closure))
|
|
}
|
|
}
|