[ios] fix link creation API, reject invalid arguments on creation and fix tests

This commit is contained in:
Omer Levy 2017-10-07 18:00:36 -04:00
parent de6904e6f4
commit 20d414652b
2 changed files with 124 additions and 42 deletions

View File

@ -131,6 +131,7 @@ RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPr
} }
RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
@try {
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata]; FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata];
if (components == nil) { if (components == nil) {
@ -140,11 +141,17 @@ RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTProm
NSLog(@"created long dynamic link: %@", longLink.absoluteString); NSLog(@"created long dynamic link: %@", longLink.absoluteString);
resolve(longLink.absoluteString); resolve(longLink.absoluteString);
} }
}
@catch(NSException * e) {
NSLog(@"create dynamic link failure %@", e);
reject(@"links/failure",[e reason], nil);
}
} }
RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
@try {
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata]; FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata];
[self setSuffixParameters:metadata components:components];
[components shortenWithCompletion:^(NSURL *_Nullable shortURL, [components shortenWithCompletion:^(NSURL *_Nullable shortURL,
NSArray *_Nullable warnings, NSArray *_Nullable warnings,
NSError *_Nullable error) { NSError *_Nullable error) {
@ -156,76 +163,149 @@ RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RC
NSLog(@"created short dynamic link: %@", shortLink.absoluteString); NSLog(@"created short dynamic link: %@", shortLink.absoluteString);
resolve(shortLink.absoluteString); resolve(shortLink.absoluteString);
}]; }];
}
@catch(NSException * e) {
NSLog(@"create short dynamic link failure %@", e);
reject(@"links/failure",[e reason], nil);
}
} }
- (FIRDynamicLinkComponents *)getDynamicLinkComponentsFromMetadata:(NSDictionary *)metadata { - (FIRDynamicLinkComponents *)getDynamicLinkComponentsFromMetadata:(NSDictionary *)metadata {
NSURL *link = [NSURL URLWithString:metadata[@"link"]]; NSMutableDictionary* dynamicLinkInfoMetadata = metadata[@"dynamicLinkInfo"];
@try {
NSURL *link = [NSURL URLWithString:dynamicLinkInfoMetadata[@"link"]];
[dynamicLinkInfoMetadata removeObjectForKey:@"link"];
FIRDynamicLinkComponents *components = FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:metadata[@"dynamicLinkDomain"]]; [FIRDynamicLinkComponents componentsWithLink:link domain:dynamicLinkInfoMetadata[@"dynamicLinkDomain"]];
[self setAndroidParameters:metadata components:components]; [dynamicLinkInfoMetadata removeObjectForKey:@"dynamicLinkDomain"];
[self setIosParameters:metadata components:components];
[self setSocialMetaTagParameters:metadata components:components]; [self setAndroidParameters:dynamicLinkInfoMetadata components:components];
[self setSuffixParameters:metadata components:components]; [dynamicLinkInfoMetadata removeObjectForKey:@"androidInfo"];
[self setIosParameters:dynamicLinkInfoMetadata components:components];
[dynamicLinkInfoMetadata removeObjectForKey:@"iosInfo"];
[self setSocialMetaTagParameters:dynamicLinkInfoMetadata components:components];
[dynamicLinkInfoMetadata removeObjectForKey:@"socialMetaTagInfo"];
if ([dynamicLinkInfoMetadata count] > 0) {
@throw [NSException
exceptionWithName:@"Invalid arguments"
reason:@"Invalid arguments"
userInfo:nil];
}
return components; return components;
}
@catch(NSException * e) {
NSLog(@"error while building componets from meta data %@", e);
@throw;
}
} }
- (void)setAndroidParameters:(NSDictionary *)metadata - (void)setAndroidParameters:(NSMutableDictionary *)metadata
components:(FIRDynamicLinkComponents *)components { components:(FIRDynamicLinkComponents *)components {
NSDictionary *androidParametersDict = metadata[@"androidInfo"]; NSMutableDictionary *androidParametersDict = metadata[@"androidInfo"];
if (androidParametersDict && androidParametersDict[@"androidPackageName"]) { if (androidParametersDict) {
if (!androidParametersDict[@"androidPackageName"]) {
@throw [NSException
exceptionWithName:@"Invalid arguments"
reason:@"no androidPackageName was specified"
userInfo:nil];
}
FIRDynamicLinkAndroidParameters *androidParams = [FIRDynamicLinkAndroidParameters FIRDynamicLinkAndroidParameters *androidParams = [FIRDynamicLinkAndroidParameters
parametersWithPackageName: androidParametersDict[@"androidPackageName"]]; parametersWithPackageName: androidParametersDict[@"androidPackageName"]];
[androidParametersDict removeObjectForKey:@"androidPackageName"];
if (androidParametersDict[@"androidFallbackLink"]) { if (androidParametersDict[@"androidFallbackLink"]) {
androidParams.fallbackURL = [NSURL URLWithString:androidParametersDict[@"androidFallbackLink"]]; androidParams.fallbackURL = [NSURL URLWithString:androidParametersDict[@"androidFallbackLink"]];
[androidParametersDict removeObjectForKey:@"androidFallbackLink"];
} }
if (androidParametersDict[@"androidMinPackageVersionCode"]) { if (androidParametersDict[@"androidMinPackageVersionCode"]) {
androidParams.minimumVersion = [androidParametersDict[@"androidMinPackageVersionCode"] integerValue]; androidParams.minimumVersion = [androidParametersDict[@"androidMinPackageVersionCode"] integerValue];
[androidParametersDict removeObjectForKey:@"androidMinPackageVersionCode"];
}
if ([androidParametersDict count] > 0) {
@throw [NSException
exceptionWithName:@"Invalid arguments"
reason:@"Invalid arguments"
userInfo:nil];
} }
components.androidParameters = androidParams; components.androidParameters = androidParams;
} }
} }
- (void)setIosParameters:(NSDictionary *)metadata - (void)setIosParameters:(NSMutableDictionary *)metadata
components:(FIRDynamicLinkComponents *)components { components:(FIRDynamicLinkComponents *)components {
NSDictionary *iosParametersDict = metadata[@"iosInfo"]; NSMutableDictionary *iosParametersDict = metadata[@"iosInfo"];
if (iosParametersDict && iosParametersDict[@"iosBundleId"]) { if (iosParametersDict) {
if (!iosParametersDict[@"iosBundleId"]) {
@throw [NSException
exceptionWithName:@"Invalid arguments"
reason:@"no iosBundleId was specified"
userInfo:nil];
}
FIRDynamicLinkIOSParameters *iOSParams = [FIRDynamicLinkIOSParameters FIRDynamicLinkIOSParameters *iOSParams = [FIRDynamicLinkIOSParameters
parametersWithBundleID:iosParametersDict[@"iosBundleId"]]; parametersWithBundleID:iosParametersDict[@"iosBundleId"]];
[iosParametersDict removeObjectForKey:@"iosBundleId"];
if (iosParametersDict[@"iosAppStoreId"]) { if (iosParametersDict[@"iosAppStoreId"]) {
iOSParams.appStoreID = iosParametersDict[@"iosAppStoreId"]; iOSParams.appStoreID = iosParametersDict[@"iosAppStoreId"];
[iosParametersDict removeObjectForKey:@"iosAppStoreId"];
} }
if (iosParametersDict[@"iosCustomScheme"]) { if (iosParametersDict[@"iosCustomScheme"]) {
iOSParams.customScheme = iosParametersDict[@"iosCustomScheme"]; iOSParams.customScheme = iosParametersDict[@"iosCustomScheme"];
[iosParametersDict removeObjectForKey:@"iosCustomScheme"];
} }
if (iosParametersDict[@"iosFallbackLink"]) { if (iosParametersDict[@"iosFallbackLink"]) {
iOSParams.fallbackURL = [NSURL URLWithString:iosParametersDict[@"iosFallbackLink"]]; iOSParams.fallbackURL = [NSURL URLWithString:iosParametersDict[@"iosFallbackLink"]];
[iosParametersDict removeObjectForKey:@"iosFallbackLink"];
} }
if (iosParametersDict[@"iosIpadBundleId"]) { if (iosParametersDict[@"iosIpadBundleId"]) {
iOSParams.iPadBundleID = iosParametersDict[@"iosIpadBundleId"]; iOSParams.iPadBundleID = iosParametersDict[@"iosIpadBundleId"];
[iosParametersDict removeObjectForKey:@"iosIpadBundleId"];
} }
if (iosParametersDict[@"iosIpadFallbackLink"]) { if (iosParametersDict[@"iosIpadFallbackLink"]) {
iOSParams.iPadFallbackURL = [NSURL URLWithString:iosParametersDict[@"iosIpadFallbackLink"]]; iOSParams.iPadFallbackURL = [NSURL URLWithString:iosParametersDict[@"iosIpadFallbackLink"]];
[iosParametersDict removeObjectForKey:@"iosIpadFallbackLink"];
} }
if (iosParametersDict[@"iosMinPackageVersionCode"]) { if (iosParametersDict[@"iosMinPackageVersionCode"]) {
iOSParams.minimumAppVersion = iosParametersDict[@"iosMinPackageVersionCode"]; iOSParams.minimumAppVersion = iosParametersDict[@"iosMinPackageVersionCode"];
[iosParametersDict removeObjectForKey:@"iosMinPackageVersionCode"];
}
if ([iosParametersDict count] > 0) {
@throw [NSException
exceptionWithName:@"Invalid arguments"
reason:@"Invalid arguments"
userInfo:nil];
} }
components.iOSParameters = iOSParams; components.iOSParameters = iOSParams;
} }
} }
- (void)setSocialMetaTagParameters:(NSDictionary *)metadata - (void)setSocialMetaTagParameters:(NSMutableDictionary *)metadata
components:(FIRDynamicLinkComponents *)components { components:(FIRDynamicLinkComponents *)components {
NSDictionary *socialParamsDict = metadata[@"socialMetaTagInfo"]; NSMutableDictionary *socialParamsDict = metadata[@"socialMetaTagInfo"];
if (socialParamsDict) { if (socialParamsDict) {
FIRDynamicLinkSocialMetaTagParameters *socialParams = [FIRDynamicLinkSocialMetaTagParameters parameters]; FIRDynamicLinkSocialMetaTagParameters *socialParams = [FIRDynamicLinkSocialMetaTagParameters parameters];
if (socialParamsDict[@"socialTitle"]) { if (socialParamsDict[@"socialTitle"]) {
socialParams.title = socialParamsDict[@"socialTitle"]; socialParams.title = socialParamsDict[@"socialTitle"];
[socialParamsDict removeObjectForKey:@"socialTitle"];
} }
if (socialParamsDict[@"socialDescription"]) { if (socialParamsDict[@"socialDescription"]) {
socialParams.descriptionText = socialParamsDict[@"socialDescription"]; socialParams.descriptionText = socialParamsDict[@"socialDescription"];
[socialParamsDict removeObjectForKey:@"socialDescription"];
} }
if (socialParamsDict[@"socialImageLink"]) { if (socialParamsDict[@"socialImageLink"]) {
socialParams.imageURL = [NSURL URLWithString:socialParamsDict[@"socialImageLink"]]; socialParams.imageURL = [NSURL URLWithString:socialParamsDict[@"socialImageLink"]];
[socialParamsDict removeObjectForKey:@"socialImageLink"];
}
if ([socialParamsDict count] > 0) {
@throw [NSException
exceptionWithName:@"Invalid arguments"
reason:@"Invalid arguments"
userInfo:nil];
} }
components.socialMetaTagParameters = socialParams; components.socialMetaTagParameters = socialParams;
} }
@ -252,3 +332,4 @@ RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RC
@implementation RNFirebaseLinks @implementation RNFirebaseLinks
@end @end
#endif #endif

View File

@ -69,6 +69,7 @@ function linksTests({ describe, it, firebase, tryCatch }) {
const val = expectedParameters[key]; const val = expectedParameters[key];
const encodedVal = encodeURIComponent(val); const encodedVal = encodeURIComponent(val);
const encodedValWithPeriod = encodedVal.replace(/\./g, '%2E'); const encodedValWithPeriod = encodedVal.replace(/\./g, '%2E');
console.log(`val: ${val}, eval: ${encodedVal}, evalP: ${encodedValWithPeriod}, url: ${result}`);
(result.includes(`${key}=${val}`) || (result.includes(`${key}=${val}`) ||
result.includes(`${key}=${encodedVal}`) || result.includes(`${key}=${encodedVal}`) ||
result.includes(`${key}=${encodedValWithPeriod}`)).should.be.true(); result.includes(`${key}=${encodedValWithPeriod}`)).should.be.true();
@ -85,10 +86,10 @@ function linksTests({ describe, it, firebase, tryCatch }) {
}; };
const result = await links.createDynamicLink(data); const result = await links.createDynamicLink(data);
console.log(result); const expectedUrl = `https://${dynamicLinkDomain}/?link=${encodeURIComponent(link)}`;
const expectedUrl = `https://${dynamicLinkDomain}?link=${encodeURIComponent(link)}`; const expectedUrlWithEncodedPeriod = `https://${dynamicLinkDomain}/?link=${
encodeURIComponent(link).replace(/\./g, '%2E')}`;
result.should.eql(expectedUrl); [expectedUrl, expectedUrlWithEncodedPeriod].should.matchAny(result);
Promise.resolve(); Promise.resolve();
}); });