Add Share module

Summary:
revision of https://github.com/facebook/react-native/pull/5476

It has only one method `shareTextContent` and next will be`shareBinaryContent`.

In Android, Promise can't receive a result, because `startActivityForResult` is not working with `Intent.ACTION_SEND`. Maybe we can use `createChooser(Intent target, CharSequence title, IntentSender sender)` which requires API level 22.
Closes https://github.com/facebook/react-native/pull/5904

Differential Revision: D3612889

fbshipit-source-id: 0e7aaf34b076a99089cc76bd649e6da067d9a760
This commit is contained in:
SangYeob Bono Yu
2016-07-25 03:34:06 -07:00
committed by Facebook Github Bot 6
parent c21d3a1029
commit 3b35732800
16 changed files with 700 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ robolectric3_test(
CSSLAYOUT_TARGET,
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp3'),
@@ -24,6 +25,7 @@ robolectric3_test(
react_native_target('java/com/facebook/react/modules/debug:debug'),
react_native_target('java/com/facebook/react/modules/dialog:dialog'),
react_native_target('java/com/facebook/react/modules/network:network'),
react_native_target('java/com/facebook/react/modules/share:share'),
react_native_target('java/com/facebook/react/modules/storage:storage'),
react_native_target('java/com/facebook/react/modules/systeminfo:systeminfo'),
react_native_target('java/com/facebook/react/touch:touch'),

View File

@@ -0,0 +1,179 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.modules.share;
import android.app.Activity;
import android.content.Intent;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactTestHelper;
import com.facebook.react.bridge.JavaOnlyMap;
import javax.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.internal.ShadowExtractor;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@PrepareForTest({Arguments.class})
@RunWith(RobolectricTestRunner.class)
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
public class ShareModuleTest {
private Activity mActivity;
private ShareModule mShareModule;
@Rule
public PowerMockRule rule = new PowerMockRule();
@Before
public void prepareModules() throws Exception {
PowerMockito.mockStatic(Arguments.class);
Mockito.when(Arguments.createMap()).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return new JavaOnlyMap();
}
});
mShareModule = new ShareModule(ReactTestHelper.createCatalystContextForTest());
}
@After
public void cleanUp() {
mActivity = null;
mShareModule = null;
}
@Test
public void testShareDialog() {
final String title = "Title";
final String message = "Message";
final String dialogTitle = "Dialog Title";
JavaOnlyMap content = new JavaOnlyMap();
content.putString("title", title);
content.putString("message", message);
final SimplePromise promise = new SimplePromise();
mShareModule.share(content, dialogTitle, promise);
final Intent chooserIntent =
((ShadowApplication)ShadowExtractor.extract(RuntimeEnvironment.application)).getNextStartedActivity();
assertNotNull("Dialog was not displayed", chooserIntent);
assertEquals(Intent.ACTION_CHOOSER, chooserIntent.getAction());
assertEquals(dialogTitle, chooserIntent.getExtras().get(Intent.EXTRA_TITLE));
final Intent contentIntent = (Intent)chooserIntent.getExtras().get(Intent.EXTRA_INTENT);
assertNotNull("Intent was not built correctly", contentIntent);
assertEquals(Intent.ACTION_SEND, contentIntent.getAction());
assertEquals(title, contentIntent.getExtras().get(Intent.EXTRA_SUBJECT));
assertEquals(message, contentIntent.getExtras().get(Intent.EXTRA_TEXT));
assertEquals(1, promise.getResolved());
}
@Test
public void testInvalidContent() {
final String dialogTitle = "Dialog Title";
final SimplePromise promise = new SimplePromise();
mShareModule.share(null, dialogTitle, promise);
assertEquals(1, promise.getRejected());
assertEquals(ShareModule.ERROR_INVALID_CONTENT, promise.getErrorCode());
}
final static class SimplePromise implements Promise {
private static final String DEFAULT_ERROR = "EUNSPECIFIED";
private int mResolved;
private int mRejected;
private Object mValue;
private String mErrorCode;
private String mErrorMessage;
public int getResolved() {
return mResolved;
}
public int getRejected() {
return mRejected;
}
public Object getValue() {
return mValue;
}
public String getErrorCode() {
return mErrorCode;
}
public String getErrorMessage() {
return mErrorMessage;
}
@Override
public void resolve(Object value) {
mResolved++;
mValue = value;
}
@Override
public void reject(String code, String message) {
reject(code, message, /*Throwable*/null);
}
@Override
@Deprecated
public void reject(String message) {
reject(DEFAULT_ERROR, message, /*Throwable*/null);
}
@Override
public void reject(String code, Throwable e) {
reject(code, e.getMessage(), e);
}
@Override
public void reject(Throwable e) {
reject(DEFAULT_ERROR, e.getMessage(), e);
}
@Override
public void reject(String code, String message, @Nullable Throwable e) {
mRejected++;
mErrorCode = code;
mErrorMessage = message;
}
}
}