Skip to content

Allow setting the domainURIPrefix for custom domain names/paths when creating dynamic links #2071

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 14, 2018
Merged
9 changes: 5 additions & 4 deletions Example/DynamicLinks/FDLBuilderTestAppObjC/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ - (void)_initDefaultValues {
},
// The default value of domain appcode belongs to project: app-invites-qa
@{
@"id" : @"domain",
@"label" : @"App domain (required)",
@"defaultValue" : @"testfdl.page.link",
@"id" : @"domainURIPrefix",
@"label" : @"App domainURIPrefix (required)",
@"defaultValue" : @"https://testfdl.page.link",
},
// analytics params
@{
Expand Down Expand Up @@ -289,7 +289,8 @@ - (void)_initDefaultValues {
- (void)_buildFDLLink {
NSURL *link = [NSURL URLWithString:_paramValues[@"linkString"]];
FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:_paramValues[@"domain"]];
[FIRDynamicLinkComponents componentsWithLink:link
domainURIPrefix:_paramValues[@"https://domain"]];

FIRDynamicLinkGoogleAnalyticsParameters *analyticsParams =
[FIRDynamicLinkGoogleAnalyticsParameters
Expand Down
51 changes: 30 additions & 21 deletions Example/DynamicLinks/Tests/FDLURLComponentsTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

#import <OCMock/OCMock.h>

static NSString *const kFDLURLDomain = @"xyz.page.link";
static NSString *const kFDLURLDomain = @"https://xyz.page.link";
static NSString *const kFDLURLCustomDomain = @"https://foo.com/path";

@interface FDLURLComponentsTests : XCTestCase
@end
Expand Down Expand Up @@ -461,14 +462,14 @@ - (void)testLinkOptionsParamsPropertiesSetProperly {

- (void)testFDLComponentsFactoryReturnsInstanceOfCorrectClass {
NSURL *link = [NSURL URLWithString:@"https://google.com"];
id returnValue = [FIRDynamicLinkComponents componentsWithLink:link domain:kFDLURLDomain];
id returnValue = [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkComponents class]]);
}

- (void)testFDLComponentsFactoryReturnsInstanceWithAllNilProperties {
NSURL *link = [NSURL URLWithString:@"https://google.com"];
FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:kFDLURLDomain];
[FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];

XCTAssertNil(components.analyticsParameters);
XCTAssertNil(components.socialMetaTagParameters);
Expand All @@ -484,11 +485,27 @@ - (void)testFDLComponentsCreatesSimplestLinkCorrectly {
NSURL *link = [NSURL URLWithString:linkString];

NSString *expectedURLString =
[NSString stringWithFormat:@"https://%@/?link=%@", kFDLURLDomain, endcodedLinkString];
[NSString stringWithFormat:@"%@/?link=%@", kFDLURLDomain, endcodedLinkString];
NSURL *expectedURL = [NSURL URLWithString:expectedURLString];

FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:kFDLURLDomain];
[FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
NSURL *actualURL = components.url;

XCTAssertEqualObjects(actualURL, expectedURL);
}

- (void)testFDLComponentsCustomDomainWithPath {
NSString *linkString = @"https://google.com";
NSString *endcodedLinkString = @"https%3A%2F%2Fgoogle%2Ecom";
NSURL *link = [NSURL URLWithString:linkString];

NSString *expectedURLString =
[NSString stringWithFormat:@"%@/?link=%@", kFDLURLCustomDomain, endcodedLinkString];
NSURL *expectedURL = [NSURL URLWithString:expectedURLString];

FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLCustomDomain];
NSURL *actualURL = components.url;

XCTAssertEqualObjects(actualURL, expectedURL);
Expand All @@ -499,7 +516,8 @@ - (void)testFDLComponentsFailsOnMalformedDomain {
NSURL *link = [NSURL URLWithString:linkString];

FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:@"this is invalid domain"];
[FIRDynamicLinkComponents componentsWithLink:link
domainURIPrefix:@"this is invalid domain URI Prefix"];

XCTAssertNil(components.url);
}
Expand Down Expand Up @@ -553,7 +571,7 @@ - (void)testFDLComponentsCreatesFullLinkCorrectly {

NSURL *link = [NSURL URLWithString:@"https://google.com"];
FIRDynamicLinkComponents *fdlComponents =
[FIRDynamicLinkComponents componentsWithLink:link domain:kFDLURLDomain];
[FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
fdlComponents.analyticsParameters = analyticsParams;
fdlComponents.iOSParameters = iosParams;
fdlComponents.iTunesConnectParameters = itcParams;
Expand Down Expand Up @@ -642,7 +660,7 @@ - (void)testShortenURL {
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:kFDLURLDomain];
[FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
[components
shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
NSError *_Nullable error) {
Expand Down Expand Up @@ -679,7 +697,7 @@ - (void)testShortenURLReturnsErrorWhenAPIKeyMissing {
[self expectationWithDescription:@"completion called with error"];
NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:kFDLURLDomain];
[FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
[components
shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
NSError *_Nullable error) {
Expand Down Expand Up @@ -714,20 +732,11 @@ - (void)testShortenURLReturnsErrorWhenDomainIsMalformed {
return YES;
}]];

XCTestExpectation *expectation =
[self expectationWithDescription:@"completion called with error"];
NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
FIRDynamicLinkComponents *components =
[FIRDynamicLinkComponents componentsWithLink:link domain:@"this is invalid domain"];
[components
shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
NSError *_Nullable error) {
XCTAssertNil(shortURL);
if (error) {
[expectation fulfill];
}
}];
[self waitForExpectationsWithTimeout:0.1 handler:nil];
[FIRDynamicLinkComponents componentsWithLink:link
domainURIPrefix:@"this is invalid domain URI Prefix"];
XCTAssertNil(components);

[keyProviderClassMock verify];
[keyProviderClassMock stopMocking];
Expand Down
2 changes: 1 addition & 1 deletion Example/DynamicLinks/Tests/FIRDynamicLinkNetworkingTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#import <XCTest/XCTest.h>

#import "OCMock.h"
#import <OCMock/OCMock.h>

#import <GoogleUtilities/GULSwizzler.h>
#import "DynamicLinks/FIRDynamicLinkNetworking+Private.h"
Expand Down
42 changes: 39 additions & 3 deletions Firebase/DynamicLinks/FDLURLComponents/FDLURLComponents.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#import "DynamicLinks/FDLURLComponents/FIRDynamicLinkComponentsKeyProvider.h"
#import "DynamicLinks/Public/FDLURLComponents.h"

#import "DynamicLinks/Logging/FDLLogging.h"
#import "DynamicLinks/Utilities/FDLUtilities.h"

/// The exact behavior of dict[key] = value is unclear when value is nil. This function safely adds
Expand Down Expand Up @@ -448,15 +449,50 @@ - (instancetype)init {

@implementation FIRDynamicLinkComponents

#pragma mark Deprecated Initializers.
+ (instancetype)componentsWithLink:(NSURL *)link domain:(NSString *)domain {
return [[self alloc] initWithLink:link domain:domain];
NSString *domainURIPrefix = [NSString stringWithFormat:@"https://%@", domain];
return [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:domainURIPrefix];
}

- (instancetype)initWithLink:(NSURL *)link domain:(NSString *)domain {
NSString *domainURIPrefix = [NSString stringWithFormat:@"https://%@", domain];
return [self initWithLink:link domainURIPrefix:domainURIPrefix];
}

#pragma mark Initializers.
+ (instancetype)componentsWithLink:(NSURL *)link domainURIPrefix:(NSString *)domainURIPrefix {
NSURL *domainURIPrefixURL = [NSURL URLWithString:domainURIPrefix];
if (!domainURIPrefixURL) {
FDLLog(FDLLogLevelError, FDLLogIdentifierSetupInvalidDomainURIPrefix,
@"Invalid domainURIPrefix. Please input a valid URL.");
return nil;
}
if (![[domainURIPrefixURL.scheme lowercaseString] hasPrefix:@"https"]) {
FDLLog(FDLLogLevelError, FDLLogIdentifierSetupInvalidDomainURIPrefixScheme,
@"Invalid domainURIPrefix scheme. Scheme needs to be https");
return nil;
}
return [[self alloc] initWithLink:link domainURIPrefix:domainURIPrefix];
}

- (instancetype)initWithLink:(NSURL *)link domainURIPrefix:(NSString *)domainURIPrefix {
self = [super init];
if (self) {
_link = link;
_domain = [domain copy];
/// Must be a URL that conforms to RFC 2396.
NSURL *domainURIPrefixURL = [NSURL URLWithString:domainURIPrefix];
if (!domainURIPrefixURL) {
FDLLog(FDLLogLevelError, FDLLogIdentifierSetupInvalidDomainURIPrefix,
@"Invalid domainURIPrefix. Please input a valid URL.");
return nil;
}
if (![[domainURIPrefixURL.scheme lowercaseString] hasPrefix:@"https"]) {
FDLLog(FDLLogLevelError, FDLLogIdentifierSetupInvalidDomainURIPrefixScheme,
@"Invalid domainURIPrefix scheme. Scheme needs to be https");
return nil;
}
_domain = [domainURIPrefix copy];
}
return self;
}
Expand Down Expand Up @@ -593,7 +629,7 @@ - (NSURL *)url {
addEntriesFromDictionaryRepresentingConformerToDictionary(_otherPlatformParameters);

NSString *queryString = FIRDLURLQueryStringFromDictionary(queryDictionary);
NSString *urlString = [NSString stringWithFormat:@"https://%@/%@", _domain, queryString];
NSString *urlString = [NSString stringWithFormat:@"%@/%@", _domain, queryString];
return [NSURL URLWithString:urlString];
}

Expand Down
2 changes: 2 additions & 0 deletions Firebase/DynamicLinks/Logging/FDLLogging.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ typedef NS_ENUM(NSInteger, FDLLogIdentifier) {
FDLLogIdentifierSetupNilAPIKey = 0,
FDLLogIdentifierSetupNilClientID = 1,
FDLLogIdentifierSetupNonDefaultApp = 2,
FDLLogIdentifierSetupInvalidDomainURIPrefixScheme = 3,
FDLLogIdentifierSetupInvalidDomainURIPrefix = 4,
};

/** The appropriate formatter for using NSInteger in FIRLogger. */
Expand Down
38 changes: 36 additions & 2 deletions Firebase/DynamicLinks/Public/FDLURLComponents.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,9 @@ FIR_SWIFT_NAME(DynamicLinkComponents)
*/
+ (instancetype)componentsWithLink:(NSURL *)link
domain:(NSString *)domain
NS_SWIFT_UNAVAILABLE("Use init(link:domain:)");
NS_SWIFT_UNAVAILABLE("Use init(link:domain:)")DEPRECATED_MSG_ATTRIBUTE(
"This method is deprecated. Please use the new method with support for "
"domainUriPrefix- componentsWithLink:domainURIPrefix.");

/**
* @method initWithLink:domain:
Expand All @@ -527,7 +529,39 @@ FIR_SWIFT_NAME(DynamicLinkComponents)
* @param domain Domain of your App. This value must be equal to your assigned domain from Firebase
* Console.
*/
- (instancetype)initWithLink:(NSURL *)link domain:(NSString *)domain;
- (instancetype)initWithLink:(NSURL *)link
domain:(NSString *)domain
DEPRECATED_MSG_ATTRIBUTE(
"This method is deprecated. Please use the new method with support for "
"domainUriPrefix- initWithLink:domainURIPrefix.");

/**
* @method componentsWithLink:domain:
* @abstract Generates a Dynamic Link URL components object with the minimum necessary parameters
* set to generate a fully-functional Dynamic Link.
* @param link Deep link to be stored in created Dynamic link. This link also called "payload" of
* the Dynamic link.
* @param domainURIPrefix Domain URI Prefix of your App. This value must be either a. your assigned
* domain from the Firebase console or b. your custom domain or c. your custom domain with a valid
* path that is registered for Dynamic Links. The domain URI prefix must start with a valid scheme
* (https://)
*/
+ (instancetype)componentsWithLink:(NSURL *)link
domainURIPrefix:(NSString *)domainURIPrefix
NS_SWIFT_UNAVAILABLE("Use init(link:domainURIPrefix:)");

/**
* @method initWithLink:domain:
* @abstract Generates a Dynamic Link URL components object with the minimum necessary parameters
* set to generate a fully-functional Dynamic Link.
* @param link Deep link to be stored in created Dynamic link. This link also called "payload" of
* the Dynamic link.
* @param domainURIPrefix Domain URI Prefix of your App. This value must be either a. your assigned
* domain from the Firebase console or b. your custom domain or c. your custom domain with a valid
* path that is registered for Dynamic Links. The domain URI prefix must start with a valid scheme
* (https://).
*/
- (instancetype)initWithLink:(NSURL *)link domainURIPrefix:(NSString *)domainURIPrefix;

/**
* @method shortenURL:options:completion:
Expand Down