mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-17 12:19:12 +08:00
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:
committed by
Facebook Github Bot 6
parent
c21d3a1029
commit
3b35732800
@@ -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'),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user