[android] validation of dynamicLinkInfo parameters, force using androidPackageName and tests fixes

This commit is contained in:
Omer Levy 2017-10-06 14:56:03 +03:00
parent 9e26d042d3
commit de6904e6f4
2 changed files with 152 additions and 39 deletions

View File

@ -196,12 +196,23 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
if (dynamicLinkInfo != null) {
try {
parametersBuilder.setLink(Uri.parse((String) dynamicLinkInfo.get("link")));
dynamicLinkInfo.remove("link");
parametersBuilder.setDynamicLinkDomain((String) dynamicLinkInfo.get("dynamicLinkDomain"));
dynamicLinkInfo.remove("dynamicLinkDomain");
setAndroidParameters(dynamicLinkInfo, parametersBuilder);
setIosParameters(dynamicLinkInfo, parametersBuilder);
setSocialMetaTagParameters(dynamicLinkInfo, parametersBuilder);
dynamicLinkInfo.remove("androidInfo");
setIosParameters(dynamicLinkInfo, parametersBuilder);
dynamicLinkInfo.remove("iosInfo");
setSocialMetaTagParameters(dynamicLinkInfo, parametersBuilder);
dynamicLinkInfo.remove("socialMetaTagInfo");
if (dynamicLinkInfo.size() > 0) {
throw new IllegalArgumentException("Invalid arguments: " + dynamicLinkInfo.keySet().toString());
}
} catch (Exception e) {
Log.e(TAG, "error while building parameters " + e.getMessage());
throw e;
@ -227,10 +238,12 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
private void setAndroidParameters(final Map<String, Object> dynamicLinkInfo, final DynamicLink.Builder parametersBuilder) {
Map<String, Object> androidParameters = (Map<String, Object>) dynamicLinkInfo.get("androidInfo");
if (androidParameters != null) {
if (!androidParameters.containsKey("androidPackageName")) {
throw new IllegalArgumentException("no androidPackageName was specified.");
}
DynamicLink.AndroidParameters.Builder androidParametersBuilder =
androidParameters.containsKey("androidPackageName") ?
new DynamicLink.AndroidParameters.Builder((String) androidParameters.get("androidPackageName")) :
new DynamicLink.AndroidParameters.Builder();
new DynamicLink.AndroidParameters.Builder((String) androidParameters.get("androidPackageName"));
androidParameters.remove("androidPackageName");
if (androidParameters.containsKey("androidFallbackLink")) {
@ -255,8 +268,10 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
if (!iosParameters.containsKey("iosBundleId")) {
throw new IllegalArgumentException("no iosBundleId was specified.");
}
DynamicLink.IosParameters.Builder iosParametersBuilder = new DynamicLink.IosParameters.Builder((String) iosParameters.get("iosBundleId"));
DynamicLink.IosParameters.Builder iosParametersBuilder =
new DynamicLink.IosParameters.Builder((String) iosParameters.get("iosBundleId"));
iosParameters.remove("iosBundleId");
if (iosParameters.containsKey("iosAppStoreId")) {
iosParametersBuilder.setAppStoreId((String) iosParameters.get("iosAppStoreId"));
iosParameters.remove("iosAppStoreId");

View File

@ -4,7 +4,6 @@ function linksTests({ describe, it, firebase, tryCatch }) {
describe('test links', () => {
const links = firebase.native.links();
const link = 'https://yoursite.example.com';
const linkString = 'https%3A%2F%2Fyoursite.example.com';
const dynamicLinkDomain = 'x59dg.app.goo.gl';
const androidPackageName = 'com.reactnativefirebasedemo';
@ -50,46 +49,70 @@ function linksTests({ describe, it, firebase, tryCatch }) {
const result = await links.createDynamicLink(data);
const expectedUrl = `https://${dynamicLinkDomain}?sd=${
socialDescription}&si=${
socialImageLink}&st=${
socialTitle}&afl=${
androidFallbackLink}&amv=${
androidMinPackageVersionCode}&apn=${
androidPackageName}&ibi=${
iosBundleId}&ifl=${
iosFallbackLink}&isi=${
iosAppStoreId}&ius=${
iosCustomScheme}&ipbi=${
iosIpadBundleId}&ipfl=${
iosIpadFallbackLink}&link=${linkString}`;
const expectedParameters = { sd: socialDescription,
si: socialImageLink,
st: socialTitle,
afl: androidFallbackLink,
amv: androidMinPackageVersionCode,
apn: androidPackageName,
ibi: iosBundleId,
ifl: iosFallbackLink,
isi: iosAppStoreId,
ius: iosCustomScheme,
ipbi: iosIpadBundleId,
ipfl: iosIpadFallbackLink,
link,
};
result.should.startWith(`https://${dynamicLinkDomain}`);
Object.keys(expectedParameters).forEach((key) => {
const val = expectedParameters[key];
const encodedVal = encodeURIComponent(val);
const encodedValWithPeriod = encodedVal.replace(/\./g, '%2E');
(result.includes(`${key}=${val}`) ||
result.includes(`${key}=${encodedVal}`) ||
result.includes(`${key}=${encodedValWithPeriod}`)).should.be.true();
});
Promise.resolve();
});
it('create long dynamic link with minimal parameters', async () => {
const data = {
dynamicLinkInfo: {
link,
dynamicLinkDomain,
},
};
const result = await links.createDynamicLink(data);
console.log(result);
const expectedUrl = `https://${dynamicLinkDomain}?link=${encodeURIComponent(link)}`;
result.should.eql(expectedUrl);
Promise.resolve();
});
it('create long dynamic link with few parameters', async () => {
const data = {
dynamicLinkInfo: {
link,
dynamicLinkDomain,
androidInfo: {
androidPackageName,
},
iosInfo: {
iosBundleId,
},
},
};
it('fail to create long dynamic link with empty data object', () => {
return new Promise((resolve, reject) => {
const success = tryCatch(() => {
// Assertion
reject(new Error('createDynamicLink did not fail.'));
}, reject);
const result = await links.createDynamicLink(data);
const failure = tryCatch((error) => {
// Assertion
error.code.includes('links/failure').should.be.true();
resolve();
}, reject);
const expectedUrl = `https://${dynamicLinkDomain}?apn=${
androidPackageName}&ibi=${
iosBundleId}&link=${linkString}`;
const data = { };
result.should.eql(expectedUrl);
Promise.resolve();
// Test
links.createDynamicLink(data)
.then(success)
.catch(failure);
});
});
it('fail to create long dynamic link without iosBundleId', () => {
@ -138,6 +161,81 @@ function linksTests({ describe, it, firebase, tryCatch }) {
});
});
it('fail to create long dynamic link without androidPackageName', () => {
return new Promise((resolve, reject) => {
const success = tryCatch(() => {
// Assertion
reject(new Error('createDynamicLink did not fail.'));
}, reject);
const failure = tryCatch((error) => {
// Assertion
error.code.includes('links/failure').should.be.true();
resolve();
}, reject);
// Setup
const data = {
dynamicLinkInfo: {
link,
dynamicLinkDomain,
androidInfo: {
androidFallbackLink,
androidMinPackageVersionCode,
},
iosInfo: {
iosBundleId,
iosFallbackLink,
iosCustomScheme,
iosIpadFallbackLink,
iosIpadBundleId,
iosAppStoreId,
},
socialMetaTagInfo: {
socialTitle,
socialDescription,
socialImageLink,
},
},
};
// Test
links.createDynamicLink(data)
.then(success)
.catch(failure);
});
});
it('fail to create long dynamic link with unsupported dynamicLinkInfo parameters', () => {
return new Promise((resolve, reject) => {
const success = tryCatch(() => {
// Assertion
reject(new Error('createDynamicLink did not fail.'));
}, reject);
const failure = tryCatch((error) => {
// Assertion
error.code.includes('links/failure').should.be.true();
resolve();
}, reject);
const data = {
dynamicLinkInfo: {
link,
dynamicLinkDomain,
someInvalidParameter: 'invalid',
},
};
// Test
links.createDynamicLink(data)
.then(success)
.catch(failure);
});
});
it('fail to create long dynamic link with unsupported ios parameters', () => {
return new Promise((resolve, reject) => {
const success = tryCatch(() => {