FDLURLComponentsTests.m 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. /*
  2. * Copyright 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import <XCTest/XCTest.h>
  17. #import "DynamicLinks/FDLURLComponents/FDLURLComponents+Private.h"
  18. #import "DynamicLinks/FDLURLComponents/FIRDynamicLinkComponentsKeyProvider.h"
  19. #import <OCMock/OCMock.h>
  20. static NSString *const kFDLURLDomain = @"https://xyz.page.link";
  21. static NSString *const kFDLURLCustomDomain = @"https://foo.com/path";
  22. @interface FDLURLComponentsTests : XCTestCase
  23. @end
  24. @implementation FDLURLComponentsTests
  25. #pragma mark - FIRDynamicLinkGoogleAnalyticsParameters
  26. - (void)testAnalyticsParamsFactoryReturnsInstanceOfCorrectClass {
  27. id returnValue = [FIRDynamicLinkGoogleAnalyticsParameters parameters];
  28. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkGoogleAnalyticsParameters class]]);
  29. }
  30. - (void)testAnalyticsParamsFactoryReturnsInstanceWithAllNilProperties {
  31. FIRDynamicLinkGoogleAnalyticsParameters *params =
  32. [FIRDynamicLinkGoogleAnalyticsParameters parameters];
  33. XCTAssertNil(params.source);
  34. XCTAssertNil(params.medium);
  35. XCTAssertNil(params.campaign);
  36. XCTAssertNil(params.term);
  37. XCTAssertNil(params.content);
  38. }
  39. - (void)testAnalyticsParamsPropertiesSetProperly {
  40. FIRDynamicLinkGoogleAnalyticsParameters *params =
  41. [FIRDynamicLinkGoogleAnalyticsParameters parameters];
  42. params.source = @"s";
  43. params.medium = @"m";
  44. params.campaign = @"ca";
  45. params.term = @"t";
  46. params.content = @"co";
  47. XCTAssertEqualObjects(params.source, @"s");
  48. XCTAssertEqualObjects(params.medium, @"m");
  49. XCTAssertEqualObjects(params.campaign, @"ca");
  50. XCTAssertEqualObjects(params.term, @"t");
  51. XCTAssertEqualObjects(params.content, @"co");
  52. params.source = nil;
  53. params.medium = nil;
  54. params.campaign = nil;
  55. params.term = nil;
  56. params.content = nil;
  57. XCTAssertNil(params.source);
  58. XCTAssertNil(params.medium);
  59. XCTAssertNil(params.campaign);
  60. XCTAssertNil(params.term);
  61. XCTAssertNil(params.content);
  62. }
  63. - (void)testAnalyticsParamsDictionaryRepresentationReturnsCorrectDictionaryFull {
  64. FIRDynamicLinkGoogleAnalyticsParameters *params =
  65. [FIRDynamicLinkGoogleAnalyticsParameters parameters];
  66. params.source = @"s";
  67. params.medium = @"m";
  68. params.campaign = @"ca";
  69. params.term = @"t";
  70. params.content = @"co";
  71. NSDictionary *expectedDictionary = @{
  72. @"utm_source" : @"s",
  73. @"utm_medium" : @"m",
  74. @"utm_campaign" : @"ca",
  75. @"utm_term" : @"t",
  76. @"utm_content" : @"co",
  77. };
  78. XCTAssertEqualObjects(expectedDictionary, params.dictionaryRepresentation);
  79. }
  80. - (void)testAnalyticsParamsDictionaryRepresentationReturnsCorrectDictionaryEmpty {
  81. FIRDynamicLinkGoogleAnalyticsParameters *params =
  82. [FIRDynamicLinkGoogleAnalyticsParameters parameters];
  83. XCTAssertEqualObjects(@{}, params.dictionaryRepresentation);
  84. }
  85. - (void)testAnalyticsParamsFactoryWithParamsReturnsInstanceOfCorrectClass {
  86. id returnValue =
  87. [FIRDynamicLinkGoogleAnalyticsParameters parametersWithSource:@"s" medium:@"m" campaign:@"c"];
  88. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkGoogleAnalyticsParameters class]]);
  89. }
  90. - (void)testAnalyticsParamsFactoryWithParamsReturnsInstanceWithCorrectInitalPropertyValues {
  91. FIRDynamicLinkGoogleAnalyticsParameters *params =
  92. [FIRDynamicLinkGoogleAnalyticsParameters parametersWithSource:@"s" medium:@"m" campaign:@"c"];
  93. XCTAssertEqualObjects(params.source, @"s");
  94. XCTAssertEqualObjects(params.medium, @"m");
  95. XCTAssertEqualObjects(params.campaign, @"c");
  96. XCTAssertNil(params.term);
  97. XCTAssertNil(params.content);
  98. }
  99. #pragma mark - FIRDynamicLinkIOSParameters
  100. - (void)testIOSParamsFactoryReturnsInstanceOfCorrectClass {
  101. id returnValue = [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.iphone.app"];
  102. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkIOSParameters class]]);
  103. }
  104. - (void)testIOSParamsFactoryReturnsInstanceWithAllOptionalNilProperties {
  105. FIRDynamicLinkIOSParameters *params =
  106. [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.iphone.app"];
  107. XCTAssertNil(params.fallbackURL);
  108. XCTAssertNil(params.customScheme);
  109. XCTAssertNil(params.minimumAppVersion);
  110. XCTAssertNil(params.iPadBundleID);
  111. XCTAssertNil(params.iPadFallbackURL);
  112. XCTAssertNil(params.appStoreID);
  113. }
  114. - (void)testIOSParamsPropertiesSetProperly {
  115. FIRDynamicLinkIOSParameters *params =
  116. [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.iphone.app"];
  117. params.fallbackURL = [NSURL URLWithString:@"https://google.com/iphone"];
  118. params.customScheme = @"mycustomsheme";
  119. params.minimumAppVersion = @"1.2.3";
  120. params.iPadBundleID = @"com.ipad.app";
  121. params.iPadFallbackURL = [NSURL URLWithString:@"https://google.com/ipad"];
  122. params.appStoreID = @"666";
  123. XCTAssertEqualObjects(params.bundleID, @"com.iphone.app");
  124. XCTAssertEqualObjects(params.fallbackURL, [NSURL URLWithString:@"https://google.com/iphone"]);
  125. XCTAssertEqualObjects(params.customScheme, @"mycustomsheme");
  126. XCTAssertEqualObjects(params.minimumAppVersion, @"1.2.3");
  127. XCTAssertEqualObjects(params.iPadBundleID, @"com.ipad.app");
  128. XCTAssertEqualObjects(params.iPadFallbackURL, [NSURL URLWithString:@"https://google.com/ipad"]);
  129. XCTAssertEqualObjects(params.appStoreID, @"666");
  130. params.fallbackURL = nil;
  131. params.customScheme = nil;
  132. params.minimumAppVersion = nil;
  133. params.iPadBundleID = nil;
  134. params.iPadFallbackURL = nil;
  135. params.appStoreID = nil;
  136. XCTAssertNil(params.fallbackURL);
  137. XCTAssertNil(params.customScheme);
  138. XCTAssertNil(params.minimumAppVersion);
  139. XCTAssertNil(params.iPadBundleID);
  140. XCTAssertNil(params.iPadFallbackURL);
  141. XCTAssertNil(params.appStoreID);
  142. }
  143. - (void)testIOSParamsDictionaryRepresentationReturnsCorrectDictionaryFull {
  144. FIRDynamicLinkIOSParameters *params =
  145. [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.iphone.app"];
  146. params.fallbackURL = [NSURL URLWithString:@"https://google.com/iphone"];
  147. params.customScheme = @"mycustomscheme";
  148. params.minimumAppVersion = @"1.2.3";
  149. params.iPadBundleID = @"com.ipad.app";
  150. params.iPadFallbackURL = [NSURL URLWithString:@"https://google.com/ipad"];
  151. params.appStoreID = @"666";
  152. NSDictionary *expectedDictionary = @{
  153. @"ibi" : @"com.iphone.app",
  154. @"ifl" : [NSURL URLWithString:@"https://google.com/iphone"].absoluteString,
  155. @"ius" : @"mycustomscheme",
  156. @"imv" : @"1.2.3",
  157. @"ipbi" : @"com.ipad.app",
  158. @"ipfl" : [NSURL URLWithString:@"https://google.com/ipad"].absoluteString,
  159. @"isi" : @"666"
  160. };
  161. XCTAssertEqualObjects(expectedDictionary, params.dictionaryRepresentation);
  162. }
  163. - (void)testIOSParamsDictionaryRepresentationReturnsCorrectDictionaryOnlyReqParams {
  164. FIRDynamicLinkIOSParameters *params =
  165. [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.iphone.app"];
  166. XCTAssertEqualObjects(@{@"ibi" : @"com.iphone.app"}, params.dictionaryRepresentation);
  167. }
  168. #pragma mark - FIRDynamicLinkItunesConnectAnalyticsParameters
  169. - (void)testIOSAppStoreParamsFactoryReturnsInstanceOfCorrectClass {
  170. id returnValue = [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
  171. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkItunesConnectAnalyticsParameters class]]);
  172. }
  173. - (void)testIOSAppStoreParamsFactoryReturnsInstanceWithAllNilProperties {
  174. FIRDynamicLinkItunesConnectAnalyticsParameters *params =
  175. [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
  176. XCTAssertNil(params.affiliateToken);
  177. XCTAssertNil(params.campaignToken);
  178. XCTAssertNil(params.providerToken);
  179. }
  180. - (void)testIOSAppStoreParamsPropertiesSetProperly {
  181. FIRDynamicLinkItunesConnectAnalyticsParameters *params =
  182. [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
  183. params.affiliateToken = @"affiliate";
  184. params.campaignToken = @"campaign";
  185. params.providerToken = @"provider";
  186. XCTAssertEqualObjects(params.affiliateToken, @"affiliate");
  187. XCTAssertEqualObjects(params.campaignToken, @"campaign");
  188. XCTAssertEqualObjects(params.providerToken, @"provider");
  189. params.affiliateToken = nil;
  190. params.campaignToken = nil;
  191. params.providerToken = nil;
  192. XCTAssertNil(params.affiliateToken);
  193. XCTAssertNil(params.campaignToken);
  194. XCTAssertNil(params.providerToken);
  195. }
  196. - (void)testIOSAppStoreDictionaryRepresentationReturnsCorrectDictionaryFull {
  197. FIRDynamicLinkItunesConnectAnalyticsParameters *params =
  198. [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
  199. params.affiliateToken = @"affiliate";
  200. params.campaignToken = @"campaign";
  201. params.providerToken = @"provider";
  202. NSDictionary *expectedDictionary = @{
  203. @"at" : @"affiliate",
  204. @"ct" : @"campaign",
  205. @"pt" : @"provider",
  206. };
  207. XCTAssertEqualObjects(expectedDictionary, params.dictionaryRepresentation);
  208. }
  209. - (void)testIOSAppStoreDictionaryRepresentationReturnsCorrectDictionaryEmpty {
  210. FIRDynamicLinkItunesConnectAnalyticsParameters *params =
  211. [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
  212. XCTAssertEqualObjects(@{}, params.dictionaryRepresentation);
  213. }
  214. #pragma mark - FIRDynamicLinkAndroidParameters
  215. - (void)testAndroidParamsFactoryReturnsInstanceOfCorrectClass {
  216. id returnValue =
  217. [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.google.android.gms"];
  218. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkAndroidParameters class]]);
  219. }
  220. - (void)testAndroidParamsFactoryReturnsInstanceWithAllOptionalNilProperties {
  221. FIRDynamicLinkAndroidParameters *params =
  222. [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.google.android.gms"];
  223. XCTAssertNil(params.fallbackURL);
  224. XCTAssertEqual(params.minimumVersion, 0);
  225. }
  226. - (void)testAndroidParamsPropertiesSetProperly {
  227. FIRDynamicLinkAndroidParameters *params =
  228. [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.google.android.gms"];
  229. params.fallbackURL = [NSURL URLWithString:@"https://google.com/android"];
  230. params.minimumVersion = 14;
  231. XCTAssertEqualObjects(params.packageName, @"com.google.android.gms");
  232. XCTAssertEqualObjects(params.fallbackURL, [NSURL URLWithString:@"https://google.com/android"]);
  233. XCTAssertEqual(params.minimumVersion, 14);
  234. params.fallbackURL = nil;
  235. params.minimumVersion = 0;
  236. XCTAssertNil(params.fallbackURL);
  237. XCTAssertEqual(params.minimumVersion, 0);
  238. }
  239. - (void)testAndroidParamsDictionaryRepresentationReturnsCorrectDictionaryFull {
  240. FIRDynamicLinkAndroidParameters *params =
  241. [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.google.android.gms"];
  242. params.fallbackURL = [NSURL URLWithString:@"https://google.com/android"];
  243. params.minimumVersion = 14;
  244. NSDictionary *expectedDictionary = @{
  245. @"apn" : @"com.google.android.gms",
  246. @"afl" : [NSURL URLWithString:@"https://google.com/android"].absoluteString,
  247. @"amv" : @"14",
  248. };
  249. XCTAssertEqualObjects(expectedDictionary, params.dictionaryRepresentation);
  250. }
  251. - (void)testAndroidParamsDictionaryRepresentationReturnsCorrectDictionaryEmpty {
  252. FIRDynamicLinkAndroidParameters *params =
  253. [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.google.android.gms"];
  254. XCTAssertEqualObjects(@{@"apn" : @"com.google.android.gms"}, params.dictionaryRepresentation);
  255. }
  256. #pragma mark - FIRDynamicLinkSocialMetaTagParameters
  257. - (void)testSocialParamsFactoryReturnsInstanceOfCorrectClass {
  258. id returnValue = [FIRDynamicLinkSocialMetaTagParameters parameters];
  259. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkSocialMetaTagParameters class]]);
  260. }
  261. - (void)testSocialParamsFactoryReturnsInstanceWithAllNilProperties {
  262. FIRDynamicLinkSocialMetaTagParameters *params =
  263. [FIRDynamicLinkSocialMetaTagParameters parameters];
  264. XCTAssertNil(params.title);
  265. XCTAssertNil(params.descriptionText);
  266. XCTAssertNil(params.imageURL);
  267. }
  268. - (void)testSocialParamsPropertiesSetProperly {
  269. FIRDynamicLinkSocialMetaTagParameters *params =
  270. [FIRDynamicLinkSocialMetaTagParameters parameters];
  271. params.title = @"title";
  272. params.descriptionText = @"description";
  273. params.imageURL = [NSURL URLWithString:@"https://google.com/someimage"];
  274. XCTAssertEqualObjects(params.title, @"title");
  275. XCTAssertEqualObjects(params.descriptionText, @"description");
  276. XCTAssertEqualObjects(params.imageURL, [NSURL URLWithString:@"https://google.com/someimage"]);
  277. params.title = nil;
  278. params.descriptionText = nil;
  279. params.imageURL = nil;
  280. XCTAssertNil(params.title);
  281. XCTAssertNil(params.descriptionText);
  282. XCTAssertNil(params.imageURL);
  283. }
  284. - (void)testSocialParamsDictionaryRepresentationReturnsCorrectDictionaryFull {
  285. FIRDynamicLinkSocialMetaTagParameters *params =
  286. [FIRDynamicLinkSocialMetaTagParameters parameters];
  287. params.title = @"title";
  288. params.descriptionText = @"description";
  289. params.imageURL = [NSURL URLWithString:@"https://google.com/someimage"];
  290. NSDictionary *expectedDictionary = @{
  291. @"st" : @"title",
  292. @"sd" : @"description",
  293. @"si" : [NSURL URLWithString:@"https://google.com/someimage"].absoluteString,
  294. };
  295. XCTAssertEqualObjects(expectedDictionary, params.dictionaryRepresentation);
  296. }
  297. - (void)testSocialParamsDictionaryRepresentationReturnsCorrectDictionaryEmpty {
  298. FIRDynamicLinkSocialMetaTagParameters *params =
  299. [FIRDynamicLinkSocialMetaTagParameters parameters];
  300. XCTAssertEqualObjects(@{}, params.dictionaryRepresentation);
  301. }
  302. #pragma mark - FIRDynamicLinkNavigationInfoParameters
  303. - (void)testNavigationOptionsReturnsCorrectClass {
  304. id returnValue = [FIRDynamicLinkNavigationInfoParameters parameters];
  305. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkNavigationInfoParameters class]]);
  306. }
  307. - (void)testNavigationOptionsFactoryReturnsInstanceWithAllNilProperties {
  308. FIRDynamicLinkNavigationInfoParameters *options =
  309. [FIRDynamicLinkNavigationInfoParameters parameters];
  310. XCTAssertEqual(options.forcedRedirectEnabled, NO);
  311. }
  312. - (void)testNavigationOptionsParamsPropertiesSetProperly {
  313. FIRDynamicLinkNavigationInfoParameters *options =
  314. [FIRDynamicLinkNavigationInfoParameters parameters];
  315. options.forcedRedirectEnabled = YES;
  316. XCTAssertEqual(options.forcedRedirectEnabled, YES);
  317. options.forcedRedirectEnabled = NO;
  318. XCTAssertEqual(options.forcedRedirectEnabled, NO);
  319. }
  320. #pragma mark - FIRDynamicLinkOtherPlatformParameters
  321. - (void)testOtherPlatformParametersReturnsCorrectClass {
  322. id returnValue = [FIRDynamicLinkOtherPlatformParameters parameters];
  323. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkOtherPlatformParameters class]]);
  324. }
  325. - (void)testOtherPlatformParametersFactoryReturnsInstanceWithAllNilProperties {
  326. FIRDynamicLinkOtherPlatformParameters *options =
  327. [FIRDynamicLinkOtherPlatformParameters parameters];
  328. XCTAssertNil(options.fallbackUrl);
  329. }
  330. - (void)testOtherPlatformParametersParamsPropertiesSetProperly {
  331. FIRDynamicLinkOtherPlatformParameters *options =
  332. [FIRDynamicLinkOtherPlatformParameters parameters];
  333. options.fallbackUrl = [NSURL URLWithString:@"https://google.com"];
  334. XCTAssertEqualObjects(options.fallbackUrl, [NSURL URLWithString:@"https://google.com"]);
  335. options.fallbackUrl = nil;
  336. XCTAssertNil(options.fallbackUrl);
  337. }
  338. #pragma mark - FIRDynamicLinkComponentsOptions
  339. - (void)testLinkOptionsFactoryReturnsInstanceOfCorrectClass {
  340. id returnValue = [FIRDynamicLinkComponentsOptions options];
  341. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkComponentsOptions class]]);
  342. }
  343. - (void)testLinkOptionsParamsFactoryReturnsInstanceWithAllNilProperties {
  344. FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
  345. XCTAssertEqual(options.pathLength, FIRShortDynamicLinkPathLengthDefault);
  346. }
  347. - (void)testLinkOptionsParamsPropertiesSetProperly {
  348. FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
  349. options.pathLength = FIRShortDynamicLinkPathLengthUnguessable;
  350. XCTAssertEqual(options.pathLength, FIRShortDynamicLinkPathLengthUnguessable);
  351. options.pathLength = FIRShortDynamicLinkPathLengthShort;
  352. XCTAssertEqual(options.pathLength, FIRShortDynamicLinkPathLengthShort);
  353. }
  354. #pragma mark - FIRDynamicLinkComponents
  355. - (void)testFDLComponentsFactoryReturnsInstanceOfCorrectClass {
  356. NSURL *link = [NSURL URLWithString:@"https://google.com"];
  357. id returnValue = [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
  358. XCTAssertTrue([returnValue isKindOfClass:[FIRDynamicLinkComponents class]]);
  359. }
  360. - (void)testFDLComponentsFactoryReturnsInstanceWithAllNilProperties {
  361. NSURL *link = [NSURL URLWithString:@"https://google.com"];
  362. FIRDynamicLinkComponents *components =
  363. [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
  364. XCTAssertNil(components.analyticsParameters);
  365. XCTAssertNil(components.socialMetaTagParameters);
  366. XCTAssertNil(components.iOSParameters);
  367. XCTAssertNil(components.iTunesConnectParameters);
  368. XCTAssertNil(components.analyticsParameters);
  369. XCTAssertNil(components.options);
  370. }
  371. - (void)testFDLComponentsCreatesSimplestLinkCorrectly {
  372. NSString *linkString = @"https://google.com";
  373. NSString *endcodedLinkString = @"https%3A%2F%2Fgoogle%2Ecom";
  374. NSURL *link = [NSURL URLWithString:linkString];
  375. NSString *expectedURLString =
  376. [NSString stringWithFormat:@"%@/?link=%@", kFDLURLDomain, endcodedLinkString];
  377. NSURL *expectedURL = [NSURL URLWithString:expectedURLString];
  378. FIRDynamicLinkComponents *components =
  379. [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
  380. NSURL *actualURL = components.url;
  381. XCTAssertEqualObjects(actualURL, expectedURL);
  382. }
  383. - (void)testFDLComponentsCustomDomainWithPath {
  384. NSString *linkString = @"https://google.com";
  385. NSString *endcodedLinkString = @"https%3A%2F%2Fgoogle%2Ecom";
  386. NSURL *link = [NSURL URLWithString:linkString];
  387. NSString *expectedURLString =
  388. [NSString stringWithFormat:@"%@/?link=%@", kFDLURLCustomDomain, endcodedLinkString];
  389. NSURL *expectedURL = [NSURL URLWithString:expectedURLString];
  390. FIRDynamicLinkComponents *components =
  391. [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLCustomDomain];
  392. NSURL *actualURL = components.url;
  393. XCTAssertEqualObjects(actualURL, expectedURL);
  394. }
  395. - (void)testFDLComponentsFailsOnMalformedDomain {
  396. NSString *linkString = @"https://google.com";
  397. NSURL *link = [NSURL URLWithString:linkString];
  398. FIRDynamicLinkComponents *components =
  399. [FIRDynamicLinkComponents componentsWithLink:link
  400. domainURIPrefix:@"this is invalid domain URI Prefix"];
  401. XCTAssertNil(components.url);
  402. }
  403. - (void)testFDLComponentsCreatesFullLinkCorrectly {
  404. FIRDynamicLinkGoogleAnalyticsParameters *analyticsParams =
  405. [FIRDynamicLinkGoogleAnalyticsParameters parameters];
  406. analyticsParams.source = @"s";
  407. analyticsParams.medium = @"m";
  408. analyticsParams.campaign = @"ca";
  409. analyticsParams.term = @"t";
  410. analyticsParams.content = @"co";
  411. FIRDynamicLinkIOSParameters *iosParams =
  412. [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.iphone.app"];
  413. iosParams.fallbackURL = [NSURL URLWithString:@"https://google.com/iphone"];
  414. iosParams.customScheme = @"mycustomsheme";
  415. iosParams.minimumAppVersion = @"1.2.3";
  416. iosParams.iPadBundleID = @"com.ipad.app";
  417. iosParams.iPadFallbackURL = [NSURL URLWithString:@"https://google.com/ipad"];
  418. iosParams.appStoreID = @"666";
  419. FIRDynamicLinkItunesConnectAnalyticsParameters *itcParams =
  420. [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
  421. itcParams.affiliateToken = @"affiliate";
  422. itcParams.campaignToken = @"campaign";
  423. itcParams.providerToken = @"provider";
  424. FIRDynamicLinkAndroidParameters *androidParams =
  425. [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.google.android.gms"];
  426. androidParams.fallbackURL = [NSURL URLWithString:@"https://google.com/android"];
  427. androidParams.minimumVersion = 14;
  428. FIRDynamicLinkSocialMetaTagParameters *socialParams =
  429. [FIRDynamicLinkSocialMetaTagParameters parameters];
  430. socialParams.title = @"title";
  431. socialParams.descriptionText = @"description";
  432. socialParams.imageURL = [NSURL URLWithString:@"https://google.com/someimage"];
  433. FIRDynamicLinkOtherPlatformParameters *otherPlatformParams =
  434. [FIRDynamicLinkOtherPlatformParameters parameters];
  435. otherPlatformParams.fallbackUrl =
  436. [NSURL URLWithString:@"https://google.com/fallbackForOtherPlatform"];
  437. FIRDynamicLinkNavigationInfoParameters *navInfo =
  438. [FIRDynamicLinkNavigationInfoParameters parameters];
  439. navInfo.forcedRedirectEnabled = YES;
  440. FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
  441. options.pathLength = FIRShortDynamicLinkPathLengthUnguessable;
  442. NSURL *link = [NSURL URLWithString:@"https://google.com"];
  443. FIRDynamicLinkComponents *fdlComponents =
  444. [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
  445. fdlComponents.analyticsParameters = analyticsParams;
  446. fdlComponents.iOSParameters = iosParams;
  447. fdlComponents.iTunesConnectParameters = itcParams;
  448. fdlComponents.androidParameters = androidParams;
  449. fdlComponents.socialMetaTagParameters = socialParams;
  450. fdlComponents.navigationInfoParameters = navInfo;
  451. fdlComponents.otherPlatformParameters = otherPlatformParams;
  452. fdlComponents.options = options;
  453. // This is a long FDL URL that has been verified to be a correct representation of the expected
  454. // URL. Since the parameters are not guaranteed to be in any specific order, we must compare
  455. // arrays of properties of the URLs rather than the URLs themselves.
  456. NSString *possibleExpectedURLString =
  457. @"https://xyz.page.link/?afl=https%3A%2F%2Fgoogle%2Ecom%2F"
  458. "android&amv=14&apn=com.google.android.gms&ibi=com%2Eiphone%2Eapp&utm_term=t&link=https%3A%"
  459. "2F"
  460. "%2Fgoogle%2Ecom&ipbi=com%2Eipad%2Eapp&ius=mycustomsheme&ifl=https%3A%2F%2Fgoogle%2Ecom%2"
  461. "Fiphone&isi=666&utm_content=co&utm_source=s&utm_medium=m&imv=1%2E2%2E3&ct=campaign&ipfl="
  462. "http"
  463. "s%3A%2F%2Fgoogle%2Ecom%2Fipad&si=https%3A%2F%2Fgoogle%2Ecom%2Fsomeimage&at=affiliate&pt="
  464. "prov"
  465. "ider&st=title&utm_campaign=ca&sd=description&efr=1&ofl=https%3A%2F%2Fgoogle%2Ecom%"
  466. "2Ffallback"
  467. "ForOtherPlatform";
  468. NSURL *possibleExpectedURL = [NSURL URLWithString:possibleExpectedURLString];
  469. NSURLComponents *expectedURLComponents =
  470. [NSURLComponents componentsWithString:possibleExpectedURLString];
  471. // sort both expected/actual arrays to prevent order influencing the test results
  472. NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
  473. NSArray<NSURLQueryItem *> *expectedURLQueryItems =
  474. [expectedURLComponents.queryItems sortedArrayUsingDescriptors:@[ sort ]];
  475. NSURL *actualURL = fdlComponents.url;
  476. NSURLComponents *actualURLComponents =
  477. [NSURLComponents componentsWithString:actualURL.absoluteString];
  478. NSArray<NSURLQueryItem *> *actualQueryItems =
  479. [actualURLComponents.queryItems sortedArrayUsingDescriptors:@[ sort ]];
  480. XCTAssertEqualObjects(actualQueryItems, expectedURLQueryItems);
  481. XCTAssertEqualObjects(actualURL.host, possibleExpectedURL.host);
  482. }
  483. - (void)testFDLComponentsCorrectlySetsPathLengthInRequest {
  484. NSURL *url = [NSURL URLWithString:@"https://google.com/abc"];
  485. NSURLRequest *request;
  486. NSDictionary *JSON;
  487. FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
  488. // Default path-length
  489. request = [FIRDynamicLinkComponents shorteningRequestForLongURL:url options:options];
  490. JSON = [NSJSONSerialization JSONObjectWithData:request.HTTPBody options:0 error:nil];
  491. XCTAssertNil(JSON[@"suffix"]);
  492. // Unguessable
  493. options.pathLength = FIRShortDynamicLinkPathLengthUnguessable;
  494. request = [FIRDynamicLinkComponents shorteningRequestForLongURL:url options:options];
  495. JSON = [NSJSONSerialization JSONObjectWithData:request.HTTPBody options:0 error:nil];
  496. XCTAssertTrue([JSON[@"suffix"][@"option"] isEqualToString:@"UNGUESSABLE"]);
  497. // Short
  498. options.pathLength = FIRShortDynamicLinkPathLengthShort;
  499. request = [FIRDynamicLinkComponents shorteningRequestForLongURL:url options:options];
  500. JSON = [NSJSONSerialization JSONObjectWithData:request.HTTPBody options:0 error:nil];
  501. XCTAssertTrue([JSON[@"suffix"][@"option"] isEqualToString:@"SHORT"]);
  502. }
  503. - (void)testShortenURL {
  504. NSString *shortURLString = @"https://xyz.page.link/abcd";
  505. // Mock key provider
  506. id keyProviderClassMock = OCMClassMock([FIRDynamicLinkComponentsKeyProvider class]);
  507. [[[keyProviderClassMock expect] andReturn:@"fake-api-key"] APIKey];
  508. id componentsClassMock = OCMClassMock([FIRDynamicLinkComponents class]);
  509. [[componentsClassMock expect]
  510. sendHTTPRequest:OCMOCK_ANY
  511. completion:[OCMArg checkWithBlock:^BOOL(id obj) {
  512. void (^completion)(NSData *_Nullable, NSError *_Nullable) = obj;
  513. NSDictionary *JSON = @{@"shortLink" : shortURLString};
  514. NSData *JSONData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:0];
  515. completion(JSONData, nil);
  516. return YES;
  517. }]];
  518. XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
  519. NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
  520. FIRDynamicLinkComponents *components =
  521. [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
  522. [components
  523. shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
  524. NSError *_Nullable error) {
  525. XCTAssertEqualObjects(shortURL.absoluteString, shortURLString);
  526. [expectation fulfill];
  527. }];
  528. [self waitForExpectationsWithTimeout:0.1 handler:nil];
  529. [keyProviderClassMock verify];
  530. [keyProviderClassMock stopMocking];
  531. [componentsClassMock verify];
  532. [componentsClassMock stopMocking];
  533. }
  534. - (void)testDeprecatedMethodComponentsWithLinkForDomain {
  535. NSString *shortURLString = @"https://xyz.page.link/abcd";
  536. // Mock key provider
  537. id keyProviderClassMock = OCMClassMock([FIRDynamicLinkComponentsKeyProvider class]);
  538. [[[keyProviderClassMock expect] andReturn:@"fake-api-key"] APIKey];
  539. id componentsClassMock = OCMClassMock([FIRDynamicLinkComponents class]);
  540. [[componentsClassMock expect]
  541. sendHTTPRequest:OCMOCK_ANY
  542. completion:[OCMArg checkWithBlock:^BOOL(id obj) {
  543. void (^completion)(NSData *_Nullable, NSError *_Nullable) = obj;
  544. NSDictionary *JSON = @{@"shortLink" : shortURLString};
  545. NSData *JSONData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:0];
  546. completion(JSONData, nil);
  547. return YES;
  548. }]];
  549. XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
  550. NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
  551. FIRDynamicLinkComponents *components =
  552. [FIRDynamicLinkComponents componentsWithLink:link domain:@"xyz.page.link"];
  553. [components
  554. shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
  555. NSError *_Nullable error) {
  556. XCTAssertEqualObjects(shortURL.absoluteString, shortURLString);
  557. [expectation fulfill];
  558. }];
  559. [self waitForExpectationsWithTimeout:0.1 handler:nil];
  560. [keyProviderClassMock verify];
  561. [keyProviderClassMock stopMocking];
  562. [componentsClassMock verify];
  563. [componentsClassMock stopMocking];
  564. }
  565. - (void)testDeprecatedMethodComponentsWithLinkForDomainWithInvalidDomainScheme {
  566. NSString *shortURLString = @"https://xyz.page.link/abcd";
  567. // Mock key provider
  568. id keyProviderClassMock = OCMClassMock([FIRDynamicLinkComponentsKeyProvider class]);
  569. [[[keyProviderClassMock expect] andReturn:@"fake-api-key"] APIKey];
  570. id componentsClassMock = OCMClassMock([FIRDynamicLinkComponents class]);
  571. [[componentsClassMock expect]
  572. sendHTTPRequest:OCMOCK_ANY
  573. completion:[OCMArg checkWithBlock:^BOOL(id obj) {
  574. void (^completion)(NSData *_Nullable, NSError *_Nullable) = obj;
  575. NSDictionary *JSON = @{@"shortLink" : shortURLString};
  576. NSData *JSONData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:0];
  577. completion(JSONData, nil);
  578. return YES;
  579. }]];
  580. XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
  581. NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
  582. FIRDynamicLinkComponents *components =
  583. [FIRDynamicLinkComponents componentsWithLink:link domain:@"http://xyz.page.link"];
  584. XCTAssertNotNil(components);
  585. [components
  586. shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
  587. NSError *_Nullable error) {
  588. XCTAssertEqualObjects(shortURL.absoluteString, shortURLString);
  589. [expectation fulfill];
  590. }];
  591. [self waitForExpectationsWithTimeout:0.1 handler:nil];
  592. [keyProviderClassMock verify];
  593. [keyProviderClassMock stopMocking];
  594. [componentsClassMock verify];
  595. [componentsClassMock stopMocking];
  596. }
  597. - (void)testShortenURLReturnsErrorWhenAPIKeyMissing {
  598. NSString *shortURLString = @"https://xyz.page.link/abcd";
  599. // Mock key provider
  600. id keyProviderClassMock = OCMClassMock([FIRDynamicLinkComponentsKeyProvider class]);
  601. [[[keyProviderClassMock expect] andReturn:nil] APIKey];
  602. id componentsClassMock = OCMClassMock([FIRDynamicLinkComponents class]);
  603. [[componentsClassMock stub]
  604. sendHTTPRequest:OCMOCK_ANY
  605. completion:[OCMArg checkWithBlock:^BOOL(id obj) {
  606. void (^completion)(NSData *_Nullable, NSError *_Nullable) = obj;
  607. NSDictionary *JSON = @{@"shortLink" : shortURLString};
  608. NSData *JSONData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:0];
  609. completion(JSONData, nil);
  610. return YES;
  611. }]];
  612. XCTestExpectation *expectation =
  613. [self expectationWithDescription:@"completion called with error"];
  614. NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
  615. FIRDynamicLinkComponents *components =
  616. [FIRDynamicLinkComponents componentsWithLink:link domainURIPrefix:kFDLURLDomain];
  617. [components
  618. shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
  619. NSError *_Nullable error) {
  620. XCTAssertNil(shortURL);
  621. if (error) {
  622. [expectation fulfill];
  623. }
  624. }];
  625. [self waitForExpectationsWithTimeout:0.1 handler:nil];
  626. [keyProviderClassMock verify];
  627. [keyProviderClassMock stopMocking];
  628. [componentsClassMock verify];
  629. [componentsClassMock stopMocking];
  630. }
  631. - (void)testShortenURLReturnsErrorWhenDomainIsMalformed {
  632. NSString *shortURLString = @"https://xyz.page.link/abcd";
  633. // Mock key provider
  634. id keyProviderClassMock = OCMClassMock([FIRDynamicLinkComponentsKeyProvider class]);
  635. [[keyProviderClassMock reject] APIKey];
  636. id componentsClassMock = OCMClassMock([FIRDynamicLinkComponents class]);
  637. [[componentsClassMock reject]
  638. sendHTTPRequest:OCMOCK_ANY
  639. completion:[OCMArg checkWithBlock:^BOOL(id obj) {
  640. void (^completion)(NSData *_Nullable, NSError *_Nullable) = obj;
  641. NSDictionary *JSON = @{@"shortLink" : shortURLString};
  642. NSData *JSONData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:0];
  643. completion(JSONData, nil);
  644. return YES;
  645. }]];
  646. NSURL *link = [NSURL URLWithString:@"https://google.com/abc"];
  647. FIRDynamicLinkComponents *components =
  648. [FIRDynamicLinkComponents componentsWithLink:link
  649. domainURIPrefix:@"this is invalid domain URI Prefix"];
  650. XCTAssertNil(components);
  651. [keyProviderClassMock verify];
  652. [keyProviderClassMock stopMocking];
  653. [componentsClassMock verify];
  654. [componentsClassMock stopMocking];
  655. }
  656. @end