FDLURLComponentsTests.m 28 KB

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