Files
firebase-ios-sdk/FirebaseStorage/Tests/ObjCIntegration/FIRStorageIntegrationTests.m
T

963 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 FirebaseStorage;
#import <FirebaseAuth/FirebaseAuth.h>
#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