Skip to content

Commit a36f78b

Browse files
authored
MIME Checking (#366)
* MIME Checking • Adds the ability for the SDK to use attachments with no file extension • Also adds the ability to specify the file type using the URL query parameter "file_type" • If a media attachment URL does not contain a file extension, the SDK will now download the file and check the MIME type of the request to make sure it is a valid file type. * Change Extension Priorities • Changes the file extension extraction priorities to be: 1. extract extension from URL itself 2. extract extension from MIME type. 3. extract extension from URL query parameter called 'filename' if provided • Adds tests to ensure the media URL's are being parsed correctly, and tests the priority of file extension parsing * Streamline Tests • Streamlines some code that shouldn't be duplicated * Cleanup • Removes URL parsing code that is no longer needed because we've changed the way URL's get parsed
1 parent a169edc commit a36f78b

File tree

9 files changed

+220
-23
lines changed

9 files changed

+220
-23
lines changed

iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@
132132
CA08FC801FE99B25004C445F /* Requests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA08FC7D1FE99B25004C445F /* Requests.m */; };
133133
CA08FC811FE99B25004C445F /* Requests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA08FC7D1FE99B25004C445F /* Requests.m */; };
134134
CA08FC871FE99BB4004C445F /* OneSignalClientOverrider.m in Sources */ = {isa = PBXBuildFile; fileRef = CA08FC831FE99BB4004C445F /* OneSignalClientOverrider.m */; };
135+
CA36A42C208FDEFB003EFA9A /* NSURL+OneSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = CA36A42A208FDEFB003EFA9A /* NSURL+OneSignal.h */; };
136+
CA36A42D208FDEFB003EFA9A /* NSURL+OneSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = CA36A42B208FDEFB003EFA9A /* NSURL+OneSignal.m */; };
137+
CA36A42E208FDEFB003EFA9A /* NSURL+OneSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = CA36A42B208FDEFB003EFA9A /* NSURL+OneSignal.m */; };
138+
CA36A42F208FDEFB003EFA9A /* NSURL+OneSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = CA36A42B208FDEFB003EFA9A /* NSURL+OneSignal.m */; };
135139
CA63AF8420211F7400E340FB /* EmailTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA63AF8320211F7400E340FB /* EmailTests.m */; };
136140
CA63AF8720211FF800E340FB /* UnitTestCommonMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = CA63AF8620211FF800E340FB /* UnitTestCommonMethods.m */; };
137141
CA63AFC22022670A00E340FB /* ReattemptRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CA63AFC02022670A00E340FB /* ReattemptRequest.h */; };
@@ -280,6 +284,8 @@
280284
CA08FC7D1FE99B25004C445F /* Requests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Requests.m; sourceTree = "<group>"; };
281285
CA08FC821FE99BB4004C445F /* OneSignalClientOverrider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneSignalClientOverrider.h; sourceTree = "<group>"; };
282286
CA08FC831FE99BB4004C445F /* OneSignalClientOverrider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneSignalClientOverrider.m; sourceTree = "<group>"; };
287+
CA36A42A208FDEFB003EFA9A /* NSURL+OneSignal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSURL+OneSignal.h"; sourceTree = "<group>"; };
288+
CA36A42B208FDEFB003EFA9A /* NSURL+OneSignal.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSURL+OneSignal.m"; sourceTree = "<group>"; };
283289
CA63AF8320211F7400E340FB /* EmailTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EmailTests.m; sourceTree = "<group>"; };
284290
CA63AF8520211FF800E340FB /* UnitTestCommonMethods.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UnitTestCommonMethods.h; sourceTree = "<group>"; };
285291
CA63AF8620211FF800E340FB /* UnitTestCommonMethods.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTestCommonMethods.m; sourceTree = "<group>"; };
@@ -505,6 +511,8 @@
505511
912412091E73342200E41FD7 /* UIApplicationDelegate+OneSignal.m */,
506512
9124120A1E73342200E41FD7 /* UNUserNotificationCenter+OneSignal.h */,
507513
9124120B1E73342200E41FD7 /* UNUserNotificationCenter+OneSignal.m */,
514+
CA36A42A208FDEFB003EFA9A /* NSURL+OneSignal.h */,
515+
CA36A42B208FDEFB003EFA9A /* NSURL+OneSignal.m */,
508516
);
509517
name = Categories;
510518
sourceTree = "<group>";
@@ -567,6 +575,7 @@
567575
912412291E73342200E41FD7 /* OneSignalReachability.h in Headers */,
568576
912412251E73342200E41FD7 /* OneSignalMobileProvision.h in Headers */,
569577
91F58D7A1E7C7D3F0017D24D /* OneSignalNotificationSettings.h in Headers */,
578+
CA36A42C208FDEFB003EFA9A /* NSURL+OneSignal.h in Headers */,
570579
CAEA1C66202BB3C600FBFE9E /* OSEmailSubscription.h in Headers */,
571580
91F58D811E7C80C30017D24D /* OneSignalNotificationSettingsIOS8.h in Headers */,
572581
CA08FC7E1FE99B25004C445F /* Requests.h in Headers */,
@@ -738,6 +747,7 @@
738747
91F58D7D1E7C7F330017D24D /* OneSignalNotificationSettingsIOS10.m in Sources */,
739748
9129C6B81E89E59B009CB6A0 /* OSPermission.m in Sources */,
740749
912412121E73342200E41FD7 /* OneSignalAlertViewDelegate.m in Sources */,
750+
CA36A42D208FDEFB003EFA9A /* NSURL+OneSignal.m in Sources */,
741751
912412421E73342200E41FD7 /* UNUserNotificationCenter+OneSignal.m in Sources */,
742752
CA97E14F2051C0A5003B8CB8 /* OneSignalWebOpenDialog.m in Sources */,
743753
9124123A1E73342200E41FD7 /* OneSignalWebView.m in Sources */,
@@ -777,6 +787,7 @@
777787
0338566D1FBBDB190002F7C1 /* OneSignalTrackFirebaseAnalytics.m in Sources */,
778788
91F58D841E7C88220017D24D /* OneSignalNotificationSettingsIOS10.m in Sources */,
779789
9129C6B91E89E59B009CB6A0 /* OSPermission.m in Sources */,
790+
CA36A42E208FDEFB003EFA9A /* NSURL+OneSignal.m in Sources */,
780791
912412131E73342200E41FD7 /* OneSignalAlertViewDelegate.m in Sources */,
781792
CA97E1502051C0A5003B8CB8 /* OneSignalWebOpenDialog.m in Sources */,
782793
0338566B1FBBD2270002F7C1 /* OSNotificationPayload.m in Sources */,
@@ -834,6 +845,7 @@
834845
4529DED51FA823B900CEAB1D /* TestHelperFunctions.m in Sources */,
835846
911E2CBD1E398AB3003112A4 /* UnitTests.m in Sources */,
836847
CA63AF8420211F7400E340FB /* EmailTests.m in Sources */,
848+
CA36A42F208FDEFB003EFA9A /* NSURL+OneSignal.m in Sources */,
837849
91B6EA431E85D38F00B5CF01 /* OSObservable.m in Sources */,
838850
4529DEDE1FA828E500CEAB1D /* NSDateOverrider.m in Sources */,
839851
CA08FC871FE99BB4004C445F /* OneSignalClientOverrider.m in Sources */,

iOS_SDK/OneSignalSDK/Source/NSString+OneSignal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- (NSString*)one_getVersionForRange:(NSRange)range;
1515
- (NSString*)one_substringAfter:(NSString *)needle;
1616
- (NSString*)one_getSemanticVersion;
17+
- (NSString *)fileExtensionForMimeType;
18+
- (NSString *)supportedFileExtension;
1719

1820
@end
1921
#endif

iOS_SDK/OneSignalSDK/Source/NSString+OneSignal.m

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
//
77

88
#import "NSString+OneSignal.h"
9+
#import "OneSignalCommonDefines.h"
10+
11+
#define MIME_MAP @{@"audio/aiff" : @"aiff", @"audio/x-wav" : @"wav", @"audio/mpeg" : @"mp3", @"video/mp4" : @"mp4", @"image/jpeg" : @"jpeg", @"image/jpg" : @"jpg", @"image/png" : @"png", @"image/gif" : @"gif", @"video/mpeg" : @"mpeg", @"video/mpg" : @"mpg", @"video/avi" : @"avi", @"sound/m4a" : @"m4a", @"video/m4v" : @"m4v"}
912

1013
@implementation NSString (OneSignal)
1114

@@ -43,5 +46,17 @@ - (NSString*)one_getSemanticVersion {
4346
return (NSString*)tmpstr;
4447
}
4548

49+
- (NSString *)supportedFileExtension {
50+
NSArray <NSString *> *components = [self componentsSeparatedByString:@"."];
51+
52+
if (components.count >= 2 && [ONESIGNAL_SUPPORTED_ATTACHMENT_TYPES containsObject:components.lastObject])
53+
return components.lastObject;
54+
55+
return nil;
56+
}
57+
58+
- (NSString *)fileExtensionForMimeType {
59+
return MIME_MAP[self];
60+
}
4661

4762
@end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Modified MIT License
3+
*
4+
* Copyright 2017 OneSignal
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* 1. The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* 2. All copies of substantial portions of the Software may only be used in connection
17+
* with services provided by OneSignal.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#import <Foundation/Foundation.h>
29+
30+
@interface NSURL (OneSignal)
31+
32+
- (NSString *)valueForQueryParameter:(NSString *)parameter;
33+
34+
@end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Modified MIT License
3+
*
4+
* Copyright 2017 OneSignal
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* 1. The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* 2. All copies of substantial portions of the Software may only be used in connection
17+
* with services provided by OneSignal.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#import "NSURL+OneSignal.h"
29+
30+
@implementation NSURL (OneSignal)
31+
- (NSString *)valueForQueryParameter:(NSString *)parameter {
32+
NSURLComponents *components = [NSURLComponents componentsWithURL:self resolvingAgainstBaseURL:false];
33+
34+
for(NSURLQueryItem *item in components.queryItems)
35+
if([item.name isEqualToString:parameter])
36+
return item.value;
37+
38+
return nil;
39+
}
40+
@end

iOS_SDK/OneSignalSDK/Source/OneSignalCommonDefines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,6 @@
6262
#define ONESIGNAL_FB_LAST_GAF_CAMPAIGN_RECEIVED @"OS_LAST_RECIEVED_GAF_CAMPAIGN"
6363
#define ONESIGNAL_FB_LAST_NOTIFICATION_ID_RECEIVED @"OS_LAST_RECIEVED_NOTIFICATION_ID"
6464

65+
#define ONESIGNAL_SUPPORTED_ATTACHMENT_TYPES @[@"aiff", @"wav", @"mp3", @"mp4", @"jpg", @"jpeg", @"png", @"gif", @"mpeg", @"mpg", @"avi", @"m4a", @"m4v"]
66+
6567
#endif /* OneSignalCommonDefines_h */

iOS_SDK/OneSignalSDK/Source/OneSignalHelper.m

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
#import "OneSignalWebOpenDialog.h"
4242
#import "OneSignalInternal.h"
4343

44+
#import "NSString+OneSignal.h"
45+
#import "NSURL+OneSignal.h"
46+
47+
#import "OneSignalCommonDefines.h"
48+
4449
#define NOTIFICATION_TYPE_ALL 7
4550
#pragma clang diagnostic push
4651
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
@@ -103,12 +108,12 @@ - (id)initWithFilePath:(NSString*)path {
103108
@end
104109

105110
@interface NSURLSession (DirectDownload)
106-
+ (BOOL)downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSError *)error;
111+
+ (NSString *)downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSError *)error;
107112
@end
108113

109114
@implementation NSURLSession (DirectDownload)
110115

111-
+ (BOOL)downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSError *)error {
116+
+ (NSString *)downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSError *)error {
112117
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
113118

114119
DirectDownloadDelegate *delegate = [[DirectDownloadDelegate alloc] initWithFilePath:localPath];
@@ -130,10 +135,10 @@ + (BOOL)downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSErr
130135
if (error != nil) {
131136
error = downloadError;
132137
}
133-
return false;
138+
return nil;
134139
}
135140

136-
return true;
141+
return delegate.response.MIMEType;
137142
}
138143

139144
@end
@@ -716,39 +721,70 @@ + (void)addNotificationRequest:(OSNotificationPayload*)payload
716721

717722
}
718723

719-
// Synchroneously downloads a media
720-
// On success returns bundle resource name, otherwise returns nil
724+
/*
725+
Synchroneously downloads an attachment
726+
On success returns bundle resource name, otherwise returns nil
727+
The preference order for file type determination is as follows:
728+
1. File extension in the actual URL
729+
2. MIME type
730+
3. URL Query parameter called 'filename', such as test.jpg. The SDK will extract the file extension from it
731+
*/
721732
+ (NSString*)downloadMediaAndSaveInBundle:(NSString*)urlString {
722733

723-
let inputUrl = [NSURL URLWithString:urlString];
734+
let url = [NSURL URLWithString:urlString];
724735

725-
//removes any unnecessary query parameters that would break extension type checking
726-
let url = [[NSURL alloc] initWithScheme:inputUrl.scheme host:inputUrl.host path:inputUrl.path].absoluteString;
736+
NSString* extension = url.pathExtension;
727737

728-
NSArray<NSString*>* supportedExtensions = @[@"aiff", @"wav", @"mp3", @"mp4", @"jpg", @"jpeg", @"png", @"gif", @"mpeg", @"mpg", @"avi", @"m4a", @"m4v"];
729-
NSArray* components = [url componentsSeparatedByString:@"."];
730-
731-
// URL is not to a file
732-
if ([components count] < 2)
733-
return NULL;
734-
NSString* extension = [components lastObject];
738+
if ([extension isEqualToString:@""])
739+
extension = nil;
735740

736741
// Unrecognized extention
737-
if (![supportedExtensions containsObject:extension])
738-
return NULL;
742+
if (extension != nil && ![ONESIGNAL_SUPPORTED_ATTACHMENT_TYPES containsObject:extension])
743+
return nil;
739744

740-
NSURL* URL = [NSURL URLWithString:url];
745+
var name = [self randomStringWithLength:10];
741746

747+
if (extension)
748+
name = [name stringByAppendingString:[NSString stringWithFormat:@".%@", extension]];
742749

743-
NSString* name = [[self randomStringWithLength:10] stringByAppendingString:[NSString stringWithFormat:@".%@", extension]];
744750
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
745751
NSString* filePath = [paths[0] stringByAppendingPathComponent:name];
746752

747753
//guard against situations where for example, available storage is too low
748754

749755
@try {
750756
NSError* error = nil;
751-
[NSURLSession downloadItemAtURL:URL toFile:filePath error:error];
757+
let mimeType = [NSURLSession downloadItemAtURL:url toFile:filePath error:error];
758+
759+
if (error) {
760+
[OneSignal onesignal_Log:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"Encountered an error while attempting to download file with URL: %@", error]];
761+
return nil;
762+
}
763+
764+
if (!extension) {
765+
NSString *newExtension;
766+
767+
if (mimeType != nil && ![mimeType isEqualToString:@""]) {
768+
newExtension = mimeType.fileExtensionForMimeType;
769+
} else {
770+
newExtension = [[[NSURL URLWithString:urlString] valueForQueryParameter:@"filename"] supportedFileExtension];
771+
}
772+
773+
if (!newExtension || ![ONESIGNAL_SUPPORTED_ATTACHMENT_TYPES containsObject:newExtension])
774+
return nil;
775+
776+
name = [NSString stringWithFormat:@"%@.%@", name, newExtension];
777+
778+
let newPath = [paths[0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", name]];
779+
780+
[[NSFileManager defaultManager] moveItemAtPath:filePath toPath:newPath error:&error];
781+
}
782+
783+
if (error) {
784+
[OneSignal onesignal_Log:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"Encountered an error while attempting to download file with URL: %@", error]];
785+
return nil;
786+
}
787+
752788
NSArray* cachedFiles = [[NSUserDefaults standardUserDefaults] objectForKey:@"CACHED_MEDIA"];
753789
NSMutableArray* appendedCache;
754790
if (cachedFiles) {

iOS_SDK/OneSignalSDK/UnitTests/Shadows/NSURLSessionOverrider.m

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,19 @@ + (void)load {
3737
}
3838

3939
// Override downloading of media attachment
40-
+ (BOOL)overrideDownloadItemAtURL:(NSURL*)url toFile:(NSString*)localPath error:(NSError*)error {
40+
+ (NSString *)overrideDownloadItemAtURL:(NSURL*)url toFile:(NSString*)localPath error:(NSError*)error {
4141
NSString *content = @"File Contents";
4242
NSData *fileContents = [content dataUsingEncoding:NSUTF8StringEncoding];
4343
[[NSFileManager defaultManager] createFileAtPath:localPath
4444
contents:fileContents
4545
attributes:nil];
4646

47-
return true;
47+
if ([url.absoluteString isEqualToString:@"http://domain.com/file"])
48+
return @"image/png";
49+
else if ([url.absoluteString isEqualToString:@"http://domain.com/secondFile"])
50+
return nil;
51+
else
52+
return @"image/jpg";
4853
}
4954

5055
@end

iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,4 +1956,55 @@ - (void)testSwizzling {
19561956

19571957
}
19581958

1959+
- (UNNotificationAttachment *)deliverNotificationWithJSON:(id)json {
1960+
id notifResponse = [UnitTestCommonMethods createBasiciOSNotificationResponseWithPayload:json];
1961+
1962+
[[notifResponse notification].request.content setValue:@"some_category" forKey:@"categoryIdentifier"];
1963+
1964+
UNMutableNotificationContent* content = [OneSignal didReceiveNotificationExtensionRequest:[notifResponse notification].request withMutableNotificationContent:nil];
1965+
1966+
return content.attachments.firstObject;
1967+
}
1968+
1969+
- (id)exampleNotificationJSONWithMediaURL:(NSString *)urlString {
1970+
return @{@"aps": @{
1971+
@"mutable-content": @1,
1972+
@"alert": @"Message Body"
1973+
},
1974+
@"os_data": @{
1975+
@"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55ba",
1976+
@"buttons": @[@{@"i": @"id1", @"n": @"text1"}],
1977+
@"att": @{ @"id": urlString }
1978+
}};
1979+
}
1980+
1981+
- (void)testExtractFileExtensionFromMimeType {
1982+
//test to make sure the MIME type parsing works correctly
1983+
//NSURLSessionOverrider returns image/png for this URL
1984+
id pngFormat = [self exampleNotificationJSONWithMediaURL:@"http://domain.com/file"];
1985+
1986+
let downloadedPngFilename = [self deliverNotificationWithJSON:pngFormat].URL.lastPathComponent;
1987+
XCTAssertTrue([downloadedPngFilename.supportedFileExtension isEqualToString:@"png"]);
1988+
}
1989+
1990+
- (void)testExtractFileExtensionFromQueryParameter {
1991+
// we allow developers to add ?filename=test.jpg (for example) to attachment URL's in cases where there is no extension & no mime type
1992+
// tests to make sure the SDK correctly extracts the file extension from the `filename` URL query parameter
1993+
// NSURLSessionOverrider returns nil for this URL
1994+
id jpgFormat = [self exampleNotificationJSONWithMediaURL:@"http://domain.com/secondFile?filename=test.jpg"];
1995+
1996+
let downloadedJpgFilename = [self deliverNotificationWithJSON:jpgFormat].URL.lastPathComponent;
1997+
XCTAssertTrue([downloadedJpgFilename.supportedFileExtension isEqualToString:@"jpg"]);
1998+
}
1999+
2000+
- (void)testFileExtensionPrioritizesURLFileExtension {
2001+
//tests to make sure that the URL's file extension is prioritized above the MIME type and URL query param
2002+
//this attachment URL will have a file extension, a MIME type, and a filename query parameter. It should prioritize the URL file extension (gif)
2003+
//NSURLSessionOverrider returns image/png for this URL
2004+
id gifFormat = [self exampleNotificationJSONWithMediaURL:@"http://domain.com/file.gif?filename=test.png"];
2005+
2006+
let downloadedGifFilename = [self deliverNotificationWithJSON:gifFormat].URL.lastPathComponent;
2007+
XCTAssertTrue([downloadedGifFilename.supportedFileExtension isEqualToString:@"gif"]);
2008+
}
2009+
19592010
@end

0 commit comments

Comments
 (0)