mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-10 22:45:59 +05:45
962 lines
36 KiB
Objective-C
962 lines
36 KiB
Objective-C
// Copyright 2017 Google
|
|
//
|
|
// 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 <XCTest/XCTest.h>
|
|
|
|
@import FirebaseAuth;
|
|
@import FirebaseStorage;
|
|
|
|
#import "FirebaseCore/Extension/FirebaseCoreInternal.h"
|
|
|
|
#import "FirebaseStorage/Tests/ObjCIntegration/Credentials.h"
|
|
|
|
NSTimeInterval kFIRStorageIntegrationTestTimeout = 60;
|
|
|
|
/**
|
|
* Firebase Storage Integration tests
|
|
*
|
|
* To run these tests, you need to define the following access rights:
|
|
*
|
|
rules_version = '2';
|
|
service firebase.storage {
|
|
match /b/{bucket}/o {
|
|
match /{directChild=*} {
|
|
allow read: if request.auth != null;
|
|
}
|
|
match /ios {
|
|
match /public/{allPaths=**} {
|
|
allow write: if request.auth != null;
|
|
allow read: if true;
|
|
}
|
|
match /private/{allPaths=**} {
|
|
allow read, write: if false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*
|
|
* You also need to enable email/password sign in and add a test user in your
|
|
* Firebase Authentication settings. Your account credentials need to match
|
|
* the credentials defined in `kTestUser` and `kTestPassword`.
|
|
*
|
|
* You can define these access rights in the Firebase Console of your project.
|
|
*/
|
|
|
|
NSString *const kTestUser = KUSER_NAME;
|
|
NSString *const kTestPassword = KPASSWORD;
|
|
|
|
@interface FIRStorageIntegrationTests : XCTestCase
|
|
|
|
@property(strong, nonatomic) FIRApp *app;
|
|
@property(strong, nonatomic) FIRAuth *auth;
|
|
@property(strong, nonatomic) FIRStorage *storage;
|
|
|
|
@end
|
|
|
|
@implementation FIRStorageIntegrationTests
|
|
|
|
+ (void)setUp {
|
|
[FIRApp configure];
|
|
}
|
|
|
|
- (void)setUp {
|
|
[super setUp];
|
|
|
|
self.app = [FIRApp defaultApp];
|
|
self.auth = [FIRAuth authWithApp:self.app];
|
|
self.storage = [FIRStorage storageForApp:self.app];
|
|
|
|
static dispatch_once_t once;
|
|
dispatch_once(&once, ^{
|
|
XCTestExpectation *signInExpectation = [self expectationWithDescription:@"signIn"];
|
|
[self.auth signInWithEmail:kTestUser
|
|
password:kTestPassword
|
|
completion:^(FIRAuthDataResult *result, NSError *error) {
|
|
XCTAssertNil(error);
|
|
[signInExpectation fulfill];
|
|
}];
|
|
[self waitForExpectations];
|
|
|
|
XCTestExpectation *setUpExpectation = [self expectationWithDescription:@"setUp"];
|
|
|
|
NSArray<NSString *> *largeFiles = @[ @"ios/public/1mb" ];
|
|
NSArray<NSString *> *emptyFiles = @[
|
|
@"ios/public/empty", @"ios/public/list/a", @"ios/public/list/b", @"ios/public/list/prefix/c"
|
|
];
|
|
setUpExpectation.expectedFulfillmentCount = largeFiles.count + emptyFiles.count;
|
|
|
|
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"1mb" ofType:@"dat"];
|
|
if (filePath == nil) {
|
|
// Use bundleForClass to allow 1mb.dat to be in the test target's bundle.
|
|
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
|
|
filePath = [bundle pathForResource:@"1mb" ofType:@"dat"];
|
|
}
|
|
NSData *data = [NSData dataWithContentsOfFile:filePath];
|
|
XCTAssertNotNil(data, "Could not load bundled file");
|
|
|
|
for (NSString *largeFile in largeFiles) {
|
|
FIRStorageReference *file = [[FIRStorage storage].reference child:largeFile];
|
|
[file putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNil(error);
|
|
[setUpExpectation fulfill];
|
|
}];
|
|
}
|
|
|
|
for (NSString *emptyFile in emptyFiles) {
|
|
FIRStorageReference *file = [[FIRStorage storage].reference child:emptyFile];
|
|
[file putData:[NSData data]
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNil(error);
|
|
[setUpExpectation fulfill];
|
|
}];
|
|
}
|
|
|
|
[self waitForExpectations];
|
|
});
|
|
}
|
|
|
|
- (void)tearDown {
|
|
self.app = nil;
|
|
self.storage = nil;
|
|
|
|
[super tearDown];
|
|
}
|
|
|
|
- (void)testSameInstanceNoBucket {
|
|
FIRStorage *storage1 = [FIRStorage storageForApp:self.app];
|
|
FIRStorage *storage2 = [FIRStorage storageForApp:self.app];
|
|
XCTAssertEqual(storage1, storage2);
|
|
}
|
|
|
|
- (void)testSameInstanceCustomBucket {
|
|
FIRStorage *storage1 = [FIRStorage storageForApp:self.app URL:@"gs://foo-bar.appspot.com"];
|
|
FIRStorage *storage2 = [FIRStorage storageForApp:self.app URL:@"gs://foo-bar.appspot.com"];
|
|
XCTAssertEqual(storage1, storage2);
|
|
}
|
|
|
|
- (void)testDifferentInstance {
|
|
FIRStorage *storage1 = [FIRStorage storageForApp:self.app];
|
|
FIRStorage *storage2 = [FIRStorage storageForApp:self.app URL:@"gs://foo-bar.appspot.com"];
|
|
XCTAssertNotEqual(storage1, storage2);
|
|
}
|
|
|
|
- (void)testName {
|
|
NSString *aGSURI = [NSString
|
|
stringWithFormat:@"gs://%@.appspot.com/path/to", [[FIRApp defaultApp] options].projectID];
|
|
FIRStorageReference *ref = [self.storage referenceForURL:aGSURI];
|
|
XCTAssertEqualObjects(ref.description, aGSURI);
|
|
}
|
|
|
|
- (void)testGetMetadata {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testGetMetadata"];
|
|
FIRStorageReference *ref = [self.storage.reference child:@"ios/public/1mb"];
|
|
|
|
[ref metadataWithCompletion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testCopyMetadata {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testGetMetadata"];
|
|
FIRStorageReference *ref = [self.storage.reference child:@"ios/public/1mb"];
|
|
|
|
[ref metadataWithCompletion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
FIRStorageMetadata *metadata2 = metadata.copy;
|
|
XCTAssertNotEqual(metadata, metadata2);
|
|
XCTAssertEqualObjects(metadata, metadata2);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testDelete {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testDelete"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/fileToDelete"];
|
|
|
|
NSData *data = [@"Delete me!!!!!!!" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
[ref putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[ref deleteWithCompletion:^(NSError *error) {
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testDeleteWithNilCompletion {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testDeleteWithNilCompletion"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/fileToDelete"];
|
|
|
|
NSData *data = [@"Delete me!!!!!!!" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
[ref putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[ref deleteWithCompletion:nil];
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutDataSpecialCharacter {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPutDataSpecialCharacter"];
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/-._~!$'()*,=:@&+;"];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
[ref putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutDataInBackgroundQueue {
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"testPutDataInBackgroundQueue"];
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/testBytesUpload"];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
[ref putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
});
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutDataWithEmptyData {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPutDataWithEmptyData"];
|
|
|
|
FIRStorageReference *ref =
|
|
[self.storage referenceWithPath:@"ios/public/testUnauthenticatedSimplePutEmptyData"];
|
|
|
|
NSData *data = [[NSData alloc] init];
|
|
|
|
[ref putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutData {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPutData"];
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/private/secretfile.txt"];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
[ref putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNil(metadata, "Metadata should be nil");
|
|
XCTAssertNotNil(error, "Error should not be nil");
|
|
XCTAssertEqual(error.code, FIRStorageErrorCodeUnauthorized);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutFile {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPutFile"];
|
|
|
|
FIRStorageReference *ref =
|
|
[self.storage referenceWithPath:@"ios/public/testUnauthenticatedSimplePutFile"];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL =
|
|
[[tmpDirURL URLByAppendingPathComponent:@"hello"] URLByAppendingPathExtension:@"txt"];
|
|
[data writeToURL:fileURL atomically:YES];
|
|
|
|
FIRStorageUploadTask *task = [ref putFile:fileURL
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
}];
|
|
|
|
__block long uploadedBytes = -1;
|
|
|
|
[task observeStatus:FIRStorageTaskStatusSuccess
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertEqualObjects([snapshot description], @"<State: Success>");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusProgress
|
|
handler:^(FIRStorageTaskSnapshot *_Nonnull snapshot) {
|
|
XCTAssertTrue([[snapshot description] containsString:@"State: Progress"] ||
|
|
[[snapshot description] containsString:@"State: Resume"]);
|
|
NSProgress *progress = snapshot.progress;
|
|
XCTAssertGreaterThanOrEqual(progress.completedUnitCount, uploadedBytes);
|
|
uploadedBytes = (long)progress.completedUnitCount;
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutFileWithMetadata {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPutFileWithMetaData"];
|
|
|
|
FIRStorageReference *ref =
|
|
[self.storage referenceWithPath:@"ios/public/testUnauthenticatedSimplePutFile"];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL =
|
|
[[tmpDirURL URLByAppendingPathComponent:@"hello"] URLByAppendingPathExtension:@"txt"];
|
|
[data writeToURL:fileURL atomically:YES];
|
|
|
|
FIRStorageMetadata *putMetadata = [[FIRStorageMetadata alloc] init];
|
|
putMetadata.contentType = @"text/plain";
|
|
|
|
FIRStorageUploadTask *task = [ref putFile:fileURL
|
|
metadata:putMetadata
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
}];
|
|
|
|
__block long uploadedBytes = -1;
|
|
|
|
[task observeStatus:FIRStorageTaskStatusSuccess
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertEqualObjects([snapshot description], @"<State: Success>");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusProgress
|
|
handler:^(FIRStorageTaskSnapshot *_Nonnull snapshot) {
|
|
XCTAssertTrue([[snapshot description] containsString:@"State: Progress"] ||
|
|
[[snapshot description] containsString:@"State: Resume"]);
|
|
NSProgress *progress = snapshot.progress;
|
|
XCTAssertGreaterThanOrEqual(progress.completedUnitCount, uploadedBytes);
|
|
uploadedBytes = (long)progress.completedUnitCount;
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutFileWithSpecialCharacters {
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"testPutFileWithSpecialCharacters"];
|
|
|
|
NSString *fileName = @"hello&+@_ .txt";
|
|
FIRStorageReference *ref =
|
|
[self.storage referenceWithPath:[@"ios/public/" stringByAppendingString:fileName]];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL = [tmpDirURL URLByAppendingPathComponent:fileName];
|
|
[data writeToURL:fileURL atomically:YES];
|
|
|
|
[ref putFile:fileURL
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
XCTAssertEqualObjects(fileName, metadata.name);
|
|
FIRStorageReference *download =
|
|
[self.storage referenceWithPath:[@"ios/public/" stringByAppendingString:fileName]];
|
|
[download metadataWithCompletion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
XCTAssertEqualObjects(fileName, metadata.name);
|
|
[expectation fulfill];
|
|
}];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutDataNoMetadata {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPutDataNoMetadata"];
|
|
|
|
FIRStorageReference *ref =
|
|
[self.storage referenceWithPath:@"ios/public/testUnauthenticatedSimplePutDataNoMetadata"];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
[ref putData:data
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testPutFileNoMetadata {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPutFileNoMetadata"];
|
|
|
|
FIRStorageReference *ref =
|
|
[self.storage referenceWithPath:@"ios/public/testUnauthenticatedSimplePutFileNoMetadata"];
|
|
|
|
NSData *data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL =
|
|
[[tmpDirURL URLByAppendingPathComponent:@"hello"] URLByAppendingPathExtension:@"txt"];
|
|
[data writeToURL:fileURL atomically:YES];
|
|
|
|
[ref putFile:fileURL
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
XCTAssertNotNil(metadata, "Metadata should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testGetData {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testGetData"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
[ref dataWithMaxSize:1 * 1024 * 1024
|
|
completion:^(NSData *data, NSError *error) {
|
|
XCTAssertNotNil(data, "Data should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testGetDataInBackgroundQueue {
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"testGetDataInBackgroundQueue"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
[ref dataWithMaxSize:1 * 1024 * 1024
|
|
completion:^(NSData *data, NSError *error) {
|
|
XCTAssertNotNil(data, "Data should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
[expectation fulfill];
|
|
}];
|
|
});
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testGetDataWithCustomCallbackQueue {
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"testUnauthenticatedGetDataInCustomCallbackQueue"];
|
|
|
|
NSString *callbackQueueLabelString = @"customCallbackQueue";
|
|
const char *callbackQueueLabel = [callbackQueueLabelString UTF8String];
|
|
const void *callbackQueueKey = callbackQueueLabel;
|
|
dispatch_queue_t callbackQueue = dispatch_queue_create(callbackQueueLabel, NULL);
|
|
|
|
dispatch_queue_set_specific(callbackQueue, callbackQueueKey, (void *)callbackQueueKey, NULL);
|
|
_storage.callbackQueue = callbackQueue;
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
[ref dataWithMaxSize:1 * 1024 * 1024
|
|
completion:^(NSData *data, NSError *error) {
|
|
XCTAssertNotNil(data, "Data should not be nil");
|
|
XCTAssertNil(error, "Error should be nil");
|
|
|
|
char *currentQueueLabel = dispatch_get_specific(callbackQueueKey);
|
|
NSString *currentQueueLabelString = [NSString stringWithUTF8String:currentQueueLabel];
|
|
XCTAssertEqualObjects(currentQueueLabelString, callbackQueueLabelString);
|
|
|
|
[expectation fulfill];
|
|
|
|
// Reset the callbackQueue to default (main queue).
|
|
self.storage.callbackQueue = dispatch_get_main_queue();
|
|
dispatch_queue_set_specific(callbackQueue, callbackQueueKey, NULL, NULL);
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testGetDataTooSmall {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testGetDataTooSmall"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
/// Only allow 1kB size, which is smaller than our file
|
|
[ref dataWithMaxSize:1 * 1024
|
|
completion:^(NSData *data, NSError *error) {
|
|
XCTAssertNil(data);
|
|
XCTAssertEqual(error.code, FIRStorageErrorCodeDownloadSizeExceeded);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testGetDownloadURL {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testGetDownloadURL"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
// Download URL format is
|
|
// "https://firebasestorage.googleapis.com:443/v0/b/{bucket}/o/{path}?alt=media&token={token}"
|
|
NSString *downloadURLPattern =
|
|
@"^https:\\/\\/firebasestorage.googleapis.com:443\\/v0\\/b\\/[^\\/]*\\/o\\/"
|
|
@"ios%2Fpublic%2F1mb\\?alt=media&token=[a-z0-9-]*$";
|
|
|
|
[ref downloadURLWithCompletion:^(NSURL *downloadURL, NSError *error) {
|
|
XCTAssertNil(error);
|
|
NSRegularExpression *testRegex =
|
|
[NSRegularExpression regularExpressionWithPattern:downloadURLPattern options:0 error:nil];
|
|
NSString *urlString = [downloadURL absoluteString];
|
|
XCTAssertEqual([testRegex numberOfMatchesInString:urlString
|
|
options:0
|
|
range:NSMakeRange(0, [urlString length])],
|
|
1);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testGetFile {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testGetFile"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/helloworld"];
|
|
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL =
|
|
[[tmpDirURL URLByAppendingPathComponent:@"hello"] URLByAppendingPathExtension:@"txt"];
|
|
NSData *fileData = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
[ref putData:fileData
|
|
metadata:nil
|
|
completion:^(FIRStorageMetadata *metadata, NSError *error) {
|
|
FIRStorageDownloadTask *task = [ref writeToFile:fileURL];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusSuccess
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
[ref dataWithMaxSize:fileData.length
|
|
completion:^(NSData *_Nullable data, NSError *_Nullable error) {
|
|
XCTAssertEqualObjects(data, fileData);
|
|
[expectation fulfill];
|
|
}];
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusProgress
|
|
handler:^(FIRStorageTaskSnapshot *_Nonnull snapshot) {
|
|
NSProgress *progress = snapshot.progress;
|
|
NSLog(@"%lld of %lld", progress.completedUnitCount, progress.totalUnitCount);
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusFailure
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertNil(snapshot.error);
|
|
}];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testCancelDownload {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testCancelDownload"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL =
|
|
[[tmpDirURL URLByAppendingPathComponent:@"hello"] URLByAppendingPathExtension:@"dat"];
|
|
|
|
FIRStorageDownloadTask *task = [ref writeToFile:fileURL];
|
|
// Don't fulfill twice if a second observe failure happens before the cancel completes.
|
|
BOOL __block fulfilled = NO;
|
|
|
|
[task observeStatus:FIRStorageTaskStatusFailure
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertTrue([[snapshot description] containsString:@"State: Failed"]);
|
|
if (!fulfilled) {
|
|
fulfilled = YES;
|
|
XCTAssertEqual(snapshot.error.code, FIRStorageErrorCodeCancelled);
|
|
[expectation fulfill];
|
|
}
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusProgress
|
|
handler:^(FIRStorageTaskSnapshot *_Nonnull snapshot) {
|
|
[task cancel];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)assertMetadata:(FIRStorageMetadata *)actualMetadata
|
|
contentType:(NSString *)expectedContentType
|
|
customMetadata:(NSDictionary *)expectedCustomMetadata {
|
|
XCTAssertEqualObjects(actualMetadata.cacheControl, @"cache-control");
|
|
XCTAssertEqualObjects(actualMetadata.contentDisposition, @"content-disposition");
|
|
XCTAssertEqualObjects(actualMetadata.contentEncoding, @"gzip");
|
|
XCTAssertEqualObjects(actualMetadata.contentLanguage, @"de");
|
|
XCTAssertEqualObjects(actualMetadata.contentType, expectedContentType);
|
|
XCTAssertEqualObjects(actualMetadata.name, @"1mb");
|
|
XCTAssertTrue([actualMetadata.md5Hash length] == 24);
|
|
for (NSString *key in expectedCustomMetadata) {
|
|
XCTAssertEqualObjects([actualMetadata.customMetadata objectForKey:key],
|
|
[expectedCustomMetadata objectForKey:key]);
|
|
}
|
|
}
|
|
|
|
- (void)assertMetadataNil:(FIRStorageMetadata *)actualMetadata {
|
|
XCTAssertNil(actualMetadata.cacheControl);
|
|
XCTAssertNil(actualMetadata.contentDisposition);
|
|
XCTAssertEqualObjects(actualMetadata.contentEncoding, @"identity");
|
|
XCTAssertNil(actualMetadata.contentLanguage);
|
|
XCTAssertNil(actualMetadata.contentType);
|
|
XCTAssertTrue([actualMetadata.md5Hash length] == 24);
|
|
XCTAssertNil(actualMetadata.customMetadata);
|
|
}
|
|
|
|
- (void)testUpdateMetadata {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testUpdateMetadata"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
// Update all available metadata
|
|
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init];
|
|
metadata.cacheControl = @"cache-control";
|
|
metadata.contentDisposition = @"content-disposition";
|
|
metadata.contentEncoding = @"gzip";
|
|
metadata.contentLanguage = @"de";
|
|
metadata.contentType = @"content-type-a";
|
|
metadata.customMetadata = @{@"a" : @"b", @"y" : @"z"};
|
|
|
|
[ref updateMetadata:metadata
|
|
completion:^(FIRStorageMetadata *updatedMetadata, NSError *error) {
|
|
XCTAssertNil(error);
|
|
[self assertMetadata:updatedMetadata
|
|
contentType:@"content-type-a"
|
|
customMetadata:@{@"a" : @"b", @"y" : @"z"}];
|
|
|
|
// Update a subset of the metadata using the existing object.
|
|
FIRStorageMetadata *metadata = updatedMetadata;
|
|
metadata.contentType = @"content-type-b";
|
|
metadata.customMetadata = @{@"c" : @"d", @"y" : @""};
|
|
|
|
[ref updateMetadata:metadata
|
|
completion:^(FIRStorageMetadata *updatedMetadata, NSError *error) {
|
|
XCTAssertNil(error);
|
|
[self assertMetadata:updatedMetadata
|
|
contentType:@"content-type-b"
|
|
|
|
// "a" is now deleted and the empty string for "y" remains.
|
|
customMetadata:@{@"c" : @"d", @"y" : @""}];
|
|
|
|
// Clear all metadata with nils.
|
|
FIRStorageMetadata *metadata = updatedMetadata;
|
|
metadata.cacheControl = nil;
|
|
metadata.contentDisposition = nil;
|
|
metadata.contentEncoding = nil;
|
|
metadata.contentLanguage = nil;
|
|
metadata.contentType = nil;
|
|
metadata.customMetadata = nil;
|
|
|
|
[ref updateMetadata:metadata
|
|
completion:^(FIRStorageMetadata *updatedMetadata, NSError *error) {
|
|
XCTAssertNil(error);
|
|
[self assertMetadataNil:updatedMetadata];
|
|
XCTAssertNil(updatedMetadata.customMetadata);
|
|
[expectation fulfill];
|
|
}];
|
|
}];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testMetadataDictInitAndClear {
|
|
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] initWithDictionary:@{
|
|
@"cacheControl" : @"cache-control",
|
|
@"contentDisposition" : @"content-disposition",
|
|
@"contentEncoding" : @"gzip",
|
|
@"contentLanguage" : @"de",
|
|
@"contentType" : @"content-type-a",
|
|
@"md5Hash" : @"123456789012345678901234", // length 24
|
|
@"name" : @"1mb",
|
|
@"metadata" : @{@"a" : @"b", @"y" : @"z"}
|
|
}];
|
|
|
|
[self assertMetadata:metadata
|
|
contentType:@"content-type-a"
|
|
customMetadata:@{@"a" : @"b", @"y" : @"z"}];
|
|
|
|
metadata.cacheControl = nil;
|
|
metadata.contentDisposition = nil;
|
|
metadata.contentEncoding = @"identity";
|
|
metadata.contentLanguage = nil;
|
|
metadata.contentType = nil;
|
|
metadata.customMetadata = nil;
|
|
[self assertMetadataNil:metadata];
|
|
|
|
metadata.contentEncoding = nil;
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"testMetadataDictInitAndClear"];
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
[ref updateMetadata:metadata
|
|
completion:^(FIRStorageMetadata *updatedMetadata, NSError *error) {
|
|
XCTAssertNil(error);
|
|
[self assertMetadataNil:updatedMetadata];
|
|
XCTAssertNil(updatedMetadata.customMetadata);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testResumeGetFile {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testResumeGetFile"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL =
|
|
[[tmpDirURL URLByAppendingPathComponent:@"hello"] URLByAppendingPathExtension:@"txt"];
|
|
|
|
__block long resumeAtBytes = 256 * 1024;
|
|
__block long downloadedBytes = 0;
|
|
__block double computationResult = 0;
|
|
|
|
FIRStorageDownloadTask *task = [ref writeToFile:fileURL];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusSuccess
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertEqualObjects([snapshot description], @"<State: Success>");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusProgress
|
|
handler:^(FIRStorageTaskSnapshot *_Nonnull snapshot) {
|
|
XCTAssertTrue([[snapshot description] containsString:@"State: Progress"] ||
|
|
[[snapshot description] containsString:@"State: Resume"]);
|
|
NSProgress *progress = snapshot.progress;
|
|
XCTAssertGreaterThanOrEqual(progress.completedUnitCount, downloadedBytes);
|
|
downloadedBytes = (long)progress.completedUnitCount;
|
|
if (progress.completedUnitCount > resumeAtBytes) {
|
|
// Making sure the main run loop is busy.
|
|
for (int i = 0; i < 500; ++i) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
computationResult = sqrt(INT_MAX - i);
|
|
});
|
|
}
|
|
NSLog(@"Pausing");
|
|
[task pause];
|
|
resumeAtBytes = INT_MAX;
|
|
}
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusPause
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertEqualObjects([snapshot description], @"<State: Paused>");
|
|
NSLog(@"Resuming");
|
|
[task resume];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
XCTAssertEqual(INT_MAX, resumeAtBytes);
|
|
XCTAssertEqualWithAccuracy(sqrt(INT_MAX - 499), computationResult, 0.1);
|
|
}
|
|
|
|
- (void)testResumeGetFileInBackgroundQueue {
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"testResumeGetFileInBackgroundQueue"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"];
|
|
|
|
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
|
|
NSURL *fileURL =
|
|
[[tmpDirURL URLByAppendingPathComponent:@"hello"] URLByAppendingPathExtension:@"txt"];
|
|
|
|
__block long resumeAtBytes = 256 * 1024;
|
|
__block long downloadedBytes = 0;
|
|
|
|
FIRStorageDownloadTask *task = [ref writeToFile:fileURL];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusSuccess
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertEqualObjects([snapshot description], @"<State: Success>");
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusProgress
|
|
handler:^(FIRStorageTaskSnapshot *_Nonnull snapshot) {
|
|
XCTAssertTrue([[snapshot description] containsString:@"State: Progress"] ||
|
|
[[snapshot description] containsString:@"State: Resume"]);
|
|
NSProgress *progress = snapshot.progress;
|
|
XCTAssertGreaterThanOrEqual(progress.completedUnitCount, downloadedBytes);
|
|
downloadedBytes = (long)progress.completedUnitCount;
|
|
if (progress.completedUnitCount > resumeAtBytes) {
|
|
NSLog(@"Pausing");
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
[task pause];
|
|
});
|
|
resumeAtBytes = INT_MAX;
|
|
}
|
|
}];
|
|
|
|
[task observeStatus:FIRStorageTaskStatusPause
|
|
handler:^(FIRStorageTaskSnapshot *snapshot) {
|
|
XCTAssertEqualObjects([snapshot description], @"<State: Paused>");
|
|
NSLog(@"Resuming");
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
[task resume];
|
|
});
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
XCTAssertEqual(INT_MAX, resumeAtBytes);
|
|
}
|
|
|
|
- (void)testPagedListFiles {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testPagedListFiles"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/list"];
|
|
|
|
[ref listWithMaxResults:2
|
|
completion:^(FIRStorageListResult *_Nullable listResult, NSError *_Nullable error) {
|
|
XCTAssertNotNil(listResult);
|
|
XCTAssertNil(error);
|
|
|
|
XCTAssertEqualObjects(listResult.items, (@[ [ref child:@"a"], [ref child:@"b"] ]));
|
|
XCTAssertEqualObjects(listResult.prefixes, @[]);
|
|
XCTAssertNotNil(listResult.pageToken);
|
|
|
|
[ref listWithMaxResults:2
|
|
pageToken:listResult.pageToken
|
|
completion:^(FIRStorageListResult *_Nullable listResult,
|
|
NSError *_Nullable error) {
|
|
XCTAssertNotNil(listResult);
|
|
XCTAssertNil(error);
|
|
|
|
XCTAssertEqualObjects(listResult.items, @[]);
|
|
XCTAssertEqualObjects(listResult.prefixes,
|
|
@[ [ref child:@"prefix"] ]);
|
|
XCTAssertNil(listResult.pageToken);
|
|
|
|
[expectation fulfill];
|
|
}];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testListAllFiles {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testListAllFiles"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/list"];
|
|
|
|
[ref listAllWithCompletion:^(FIRStorageListResult *_Nullable listResult,
|
|
NSError *_Nullable error) {
|
|
XCTAssertNotNil(listResult);
|
|
XCTAssertNil(error);
|
|
|
|
XCTAssertEqualObjects(listResult.items, (@[ [ref child:@"a"], [ref child:@"b"] ]));
|
|
XCTAssertEqualObjects(listResult.prefixes, @[ [ref child:@"prefix"] ]);
|
|
XCTAssertNil(listResult.pageToken);
|
|
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testListFilesAtRoot {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testListFilesAtRoot"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@""];
|
|
|
|
[ref listAllWithCompletion:^(FIRStorageListResult *_Nullable listResult,
|
|
NSError *_Nullable error) {
|
|
XCTAssertNotNil(listResult);
|
|
XCTAssertNil(error);
|
|
XCTAssertNil(listResult.pageToken);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)testCopyListResult {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"testCopyListResult"];
|
|
|
|
FIRStorageReference *ref = [self.storage referenceWithPath:@""];
|
|
|
|
[ref listAllWithCompletion:^(FIRStorageListResult *_Nullable listResult,
|
|
NSError *_Nullable error) {
|
|
XCTAssertNotNil(listResult);
|
|
XCTAssertNil(error);
|
|
XCTAssertNil(listResult.pageToken);
|
|
FIRStorageListResult *listResult2 = listResult.copy;
|
|
XCTAssertEqual(listResult.pageToken, listResult2.pageToken);
|
|
XCTAssertNotEqual(listResult, listResult2);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations];
|
|
}
|
|
|
|
- (void)waitForExpectations {
|
|
[self waitForExpectationsWithTimeout:kFIRStorageIntegrationTestTimeout
|
|
handler:^(NSError *_Nullable error) {
|
|
if (error) {
|
|
NSLog(@"%@", error);
|
|
}
|
|
}];
|
|
}
|
|
|
|
@end
|