Skip to content

Commit 7f4542d

Browse files
author
AmandaRiu
committed
Merge branch 'develop' into amanda/leak_canary
2 parents f2c51b2 + d72c382 commit 7f4542d

16 files changed

+266
-78
lines changed

vendored/WordPressLoginFlow/build.gradle

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ android {
2121
buildToolsVersion "28.0.3"
2222

2323
defaultConfig {
24-
minSdkVersion 16
25-
targetSdkVersion 26
24+
minSdkVersion 17
25+
targetSdkVersion 28
2626
versionCode 2
2727
versionName "1.1"
2828

@@ -68,6 +68,12 @@ dependencies {
6868
annotationProcessor 'com.google.dagger:dagger-android-processor:2.22.1'
6969

7070
lintChecks 'org.wordpress:lint:1.0.1'
71+
72+
testImplementation 'junit:junit:4.12'
73+
testImplementation 'org.mockito:mockito-core:2.27.0'
74+
testImplementation 'androidx.arch.core:core-testing:2.0.1'
75+
testImplementation 'org.robolectric:robolectric:3.6.1'
76+
testImplementation 'org.assertj:assertj-core:3.11.1'
7177
}
7278

7379
// Add properties named "wp.xxx" to our BuildConfig

vendored/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ interface SelfSignedSSLCallback {
4848
// Login Site Address input callbacks
4949
void alreadyLoggedInWpcom(ArrayList<Integer> oldSitesIds);
5050
void gotWpcomSiteInfo(String siteAddress, String siteName, String siteIconUrl);
51-
void gotConnectedSiteInfo(String siteAddress, boolean hasJetpack);
51+
void gotConnectedSiteInfo(@NonNull String siteAddress, @Nullable String redirectUrl, boolean hasJetpack);
5252
void gotXmlRpcEndpoint(String inputSiteAddress, String endpointAddress);
5353
void handleSslCertificateError(MemorizingTrustManager memorizingTrustManager, SelfSignedSSLCallback callback);
5454
void helpSiteAddress(String url);

vendored/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginSiteAddressFragment.java

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
import android.content.Intent;
66
import android.os.Bundle;
77
import android.text.Editable;
8-
import android.text.TextUtils;
98
import android.text.TextWatcher;
10-
import android.util.Patterns;
119
import android.view.View;
1210
import android.view.View.OnClickListener;
1311
import android.view.ViewGroup;
@@ -18,6 +16,7 @@
1816
import androidx.annotation.LayoutRes;
1917
import androidx.annotation.NonNull;
2018
import androidx.annotation.Nullable;
19+
import androidx.lifecycle.Observer;
2120

2221
import org.greenrobot.eventbus.Subscribe;
2322
import org.greenrobot.eventbus.ThreadMode;
@@ -57,6 +56,8 @@ public class LoginSiteAddressFragment extends LoginBaseFormFragment<LoginListene
5756

5857
private String mRequestedSiteAddress;
5958

59+
private LoginSiteAddressValidator mLoginSiteAddressValidator;
60+
6061
@Inject AccountStore mAccountStore;
6162
@Inject Dispatcher mDispatcher;
6263
@Inject HTTPAuthManager mHTTPAuthManager;
@@ -139,6 +140,23 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
139140
} else {
140141
mAnalyticsListener.trackUrlFormViewed();
141142
}
143+
144+
mLoginSiteAddressValidator = new LoginSiteAddressValidator();
145+
146+
mLoginSiteAddressValidator.getIsValid().observe(this, new Observer<Boolean>() {
147+
@Override public void onChanged(Boolean enabled) {
148+
getPrimaryButton().setEnabled(enabled);
149+
}
150+
});
151+
mLoginSiteAddressValidator.getErrorMessageResId().observe(this, new Observer<Integer>() {
152+
@Override public void onChanged(Integer resId) {
153+
if (resId != null) {
154+
showError(resId);
155+
} else {
156+
mSiteAddressInput.setError(null);
157+
}
158+
}
159+
});
142160
}
143161

144162
@Override
@@ -148,24 +166,17 @@ public void onSaveInstanceState(Bundle outState) {
148166
outState.putString(KEY_REQUESTED_SITE_ADDRESS, mRequestedSiteAddress);
149167
}
150168

169+
@Override public void onDestroyView() {
170+
super.onDestroyView();
171+
mLoginSiteAddressValidator.dispose();
172+
}
173+
151174
protected void discover() {
152175
if (!NetworkUtils.checkConnection(getActivity())) {
153176
return;
154177
}
155178

156-
String cleanedSiteAddress = getCleanedSiteAddress();
157-
158-
if (TextUtils.isEmpty(cleanedSiteAddress)) {
159-
showError(R.string.login_empty_site_url);
160-
return;
161-
}
162-
163-
if (!Patterns.WEB_URL.matcher(cleanedSiteAddress).matches()) {
164-
showError(R.string.login_invalid_site_url);
165-
return;
166-
}
167-
168-
mRequestedSiteAddress = cleanedSiteAddress;
179+
mRequestedSiteAddress = mLoginSiteAddressValidator.getCleanedSiteAddress();
169180

170181
String cleanedXmlrpcSuffix = UrlUtils.removeXmlrpcSuffix(mRequestedSiteAddress);
171182

@@ -182,17 +193,16 @@ protected void discover() {
182193
startProgress();
183194
}
184195

185-
private String getCleanedSiteAddress() {
186-
return EditTextUtils.getText(mSiteAddressInput.getEditText()).trim().replaceAll("[\r\n]", "");
187-
}
188-
189196
@Override
190197
public void onEditorCommit() {
191-
discover();
198+
if (getPrimaryButton().isEnabled()) {
199+
discover();
200+
}
192201
}
193202

194203
@Override
195204
public void afterTextChanged(Editable s) {
205+
mLoginSiteAddressValidator.setAddress(EditTextUtils.getText(mSiteAddressInput.getEditText()));
196206
}
197207

198208
@Override
@@ -359,7 +369,7 @@ public void onDiscoverySucceeded(OnDiscoveryResponse event) {
359369
return;
360370
} else {
361371
AppLog.e(T.API, "onDiscoveryResponse has error: " + event.error.name()
362-
+ " - " + event.error.toString());
372+
+ " - " + event.error.toString());
363373
handleDiscoveryError(event.error, event.failedEndpoint);
364374
return;
365375
}
@@ -402,13 +412,24 @@ public void onFetchedConnectSiteInfo(OnConnectSiteInfoChecked event) {
402412
// TODO: If we plan to keep this logic we should convert these labels to constants
403413
HashMap<String, String> properties = new HashMap<>();
404414
properties.put("url", event.info.url);
405-
properties.put("urlAfterRedirects", event.info.urlAfterRedirects);
415+
properties.put("url_after_redirects", event.info.urlAfterRedirects);
406416
properties.put("exists", Boolean.toString(event.info.exists));
407-
properties.put("hasJetpack", Boolean.toString(event.info.hasJetpack));
408-
properties.put("isJetpackActive", Boolean.toString(event.info.isJetpackActive));
409-
properties.put("isJetpackConnected", Boolean.toString(event.info.isJetpackConnected));
410-
properties.put("isWordPress", Boolean.toString(event.info.isWordPress));
411-
properties.put("isWPCom", Boolean.toString(event.info.isWPCom));
417+
properties.put("has_jetpack", Boolean.toString(event.info.hasJetpack));
418+
properties.put("is_jetpack_active", Boolean.toString(event.info.isJetpackActive));
419+
properties.put("is_jetpack_connected", Boolean.toString(event.info.isJetpackConnected));
420+
properties.put("is_wordpress", Boolean.toString(event.info.isWordPress));
421+
properties.put("is_wp_com", Boolean.toString(event.info.isWPCom));
422+
423+
// Determining if jetpack is actually installed takes additional logic. This final
424+
// calculated event property will make querying this event more straight-forward:
425+
boolean hasJetpack = false;
426+
if (event.info.isWPCom && event.info.hasJetpack) {
427+
// This is likely an atomic site.
428+
hasJetpack = true;
429+
} else if (event.info.hasJetpack && event.info.isJetpackActive && event.info.isJetpackConnected) {
430+
hasJetpack = true;
431+
}
432+
properties.put("login_calculated_has_jetpack", Boolean.toString(hasJetpack));
412433
mAnalyticsListener.trackConnectedSiteInfoSucceeded(properties);
413434

414435
if (!event.info.exists) {
@@ -418,14 +439,10 @@ public void onFetchedConnectSiteInfo(OnConnectSiteInfoChecked event) {
418439
// Not a WordPress site
419440
showError(R.string.enter_wordpress_site);
420441
} else {
421-
boolean hasJetpack = false;
422-
if (event.info.isWPCom && event.info.hasJetpack) {
423-
// This is likely an atomic site.
424-
hasJetpack = true;
425-
} else if (event.info.hasJetpack && event.info.isJetpackActive && event.info.isJetpackConnected) {
426-
hasJetpack = true;
427-
}
428-
mLoginListener.gotConnectedSiteInfo(event.info.url, hasJetpack);
442+
mLoginListener.gotConnectedSiteInfo(
443+
event.info.url,
444+
event.info.urlAfterRedirects,
445+
hasJetpack);
429446
}
430447
}
431448
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.wordpress.android.login;
2+
3+
import android.util.Patterns;
4+
5+
import androidx.annotation.NonNull;
6+
import androidx.lifecycle.LiveData;
7+
import androidx.lifecycle.MutableLiveData;
8+
9+
import org.wordpress.android.util.helpers.Debouncer;
10+
11+
import java.util.concurrent.TimeUnit;
12+
13+
/**
14+
* Encapsulates the site address validation, cleaning, and error reporting of {@link LoginSiteAddressFragment}.
15+
*/
16+
class LoginSiteAddressValidator {
17+
private static final int SECONDS_DELAY_BEFORE_SHOWING_ERROR_MESSAGE = 2;
18+
19+
private MutableLiveData<Boolean> mIsValid = new MutableLiveData<>();
20+
private MutableLiveData<Integer> mErrorMessageResId = new MutableLiveData<>();
21+
22+
private String mCleanedSiteAddress = "";
23+
private final Debouncer mDebouncer;
24+
25+
@NonNull LiveData<Boolean> getIsValid() {
26+
return mIsValid;
27+
}
28+
29+
@NonNull LiveData<Integer> getErrorMessageResId() {
30+
return mErrorMessageResId;
31+
}
32+
33+
@NonNull String getCleanedSiteAddress() {
34+
return mCleanedSiteAddress;
35+
}
36+
37+
LoginSiteAddressValidator() {
38+
this(new Debouncer());
39+
}
40+
41+
LoginSiteAddressValidator(@NonNull Debouncer debouncer) {
42+
mIsValid.setValue(false);
43+
mDebouncer = debouncer;
44+
}
45+
46+
void dispose() {
47+
mDebouncer.shutdown();
48+
}
49+
50+
void setAddress(@NonNull String siteAddress) {
51+
mCleanedSiteAddress = cleanSiteAddress(siteAddress);
52+
final boolean isValid = siteAddressIsValid(mCleanedSiteAddress);
53+
54+
mIsValid.setValue(isValid);
55+
mErrorMessageResId.setValue(null);
56+
57+
// Call debounce regardless if there was an error so that the previous Runnable will be cancelled.
58+
mDebouncer.debounce(Void.class, new Runnable() {
59+
@Override public void run() {
60+
if (!isValid && !mCleanedSiteAddress.isEmpty()) {
61+
mErrorMessageResId.postValue(R.string.login_invalid_site_url);
62+
}
63+
}
64+
}, SECONDS_DELAY_BEFORE_SHOWING_ERROR_MESSAGE, TimeUnit.SECONDS);
65+
}
66+
67+
private static String cleanSiteAddress(@NonNull String siteAddress) {
68+
return siteAddress.trim().replaceAll("[\r\n]", "");
69+
}
70+
71+
private static boolean siteAddressIsValid(@NonNull String cleanedSiteAddress) {
72+
return Patterns.WEB_URL.matcher(cleanedSiteAddress).matches();
73+
}
74+
}

vendored/WordPressLoginFlow/src/main/res/layout-land/login_magic_link_request_screen.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@
5050
android:layout_width="match_parent"
5151
android:layout_height="wrap_content"
5252
android:background="@color/login_background_color"
53-
android:paddingLeft="@dimen/margin_small_medium"
5453
android:paddingStart="@dimen/margin_small_medium"
55-
android:paddingRight="@dimen/margin_medium_large"
5654
android:paddingEnd="@dimen/margin_medium_large"
5755
android:paddingTop="@dimen/margin_medium_large"
5856
android:paddingBottom="@dimen/margin_medium_large"
@@ -65,15 +63,12 @@
6563
android:id="@+id/login_enter_password"
6664
android:layout_width="wrap_content"
6765
android:layout_height="wrap_content"
68-
android:layout_alignParentLeft="true"
6966
android:layout_alignParentStart="true"
70-
android:layout_toLeftOf="@+id/login_request_magic_link"
7167
android:layout_toStartOf="@+id/login_request_magic_link"
7268
android:paddingLeft="@dimen/margin_medium_large"
7369
android:paddingStart="@dimen/margin_medium_large"
7470
android:paddingRight="@dimen/margin_medium_large"
7571
android:paddingEnd="@dimen/margin_medium_large"
76-
android:layout_marginRight="@dimen/margin_extra_large"
7772
android:layout_marginEnd="@dimen/margin_extra_large"
7873
android:gravity="start|center_vertical"
7974
android:text="@string/enter_your_password_instead"/>
@@ -83,7 +78,6 @@
8378
android:id="@+id/login_request_magic_link"
8479
android:layout_width="wrap_content"
8580
android:layout_height="wrap_content"
86-
android:layout_alignParentRight="true"
8781
android:layout_alignParentEnd="true"
8882
android:text="@string/send_link" />
8983
</RelativeLayout>

vendored/WordPressLoginFlow/src/main/res/layout-land/login_magic_link_sent_screen.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@
3939
android:layout_width="match_parent"
4040
android:layout_height="wrap_content"
4141
android:background="@color/login_background_color"
42-
android:paddingLeft="@dimen/margin_small_medium"
4342
android:paddingStart="@dimen/margin_small_medium"
44-
android:paddingRight="@dimen/margin_medium_large"
4543
android:paddingEnd="@dimen/margin_medium_large"
4644
android:paddingTop="@dimen/margin_medium_large"
4745
android:paddingBottom="@dimen/margin_medium_large"
@@ -54,15 +52,12 @@
5452
android:id="@+id/login_enter_password"
5553
android:layout_width="wrap_content"
5654
android:layout_height="wrap_content"
57-
android:layout_alignParentLeft="true"
5855
android:layout_alignParentStart="true"
59-
android:layout_toLeftOf="@+id/login_open_email_client"
6056
android:layout_toStartOf="@+id/login_open_email_client"
6157
android:paddingLeft="@dimen/margin_medium_large"
6258
android:paddingStart="@dimen/margin_medium_large"
6359
android:paddingRight="@dimen/margin_medium_large"
6460
android:paddingEnd="@dimen/margin_medium_large"
65-
android:layout_marginRight="@dimen/margin_extra_large"
6661
android:layout_marginEnd="@dimen/margin_extra_large"
6762
android:gravity="start|center_vertical"
6863
android:text="@string/enter_your_password_instead"/>
@@ -72,7 +67,6 @@
7267
android:id="@+id/login_open_email_client"
7368
android:layout_width="wrap_content"
7469
android:layout_height="wrap_content"
75-
android:layout_alignParentRight="true"
7670
android:layout_alignParentEnd="true"
7771
android:text="@string/open_mail" />
7872
</RelativeLayout>

vendored/WordPressLoginFlow/src/main/res/layout-land/signup_bottom_sheet_dialog.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
android:id="@+id/signup_email"
3535
android:layout_height="match_parent"
3636
android:layout_marginEnd="@dimen/margin_medium"
37-
android:layout_marginRight="@dimen/margin_medium"
3837
android:layout_weight="1"
3938
android:layout_width="wrap_content"
4039
android:text="@string/signup_with_email_button"
@@ -45,7 +44,6 @@
4544
android:id="@+id/signup_google"
4645
android:layout_height="match_parent"
4746
android:layout_marginStart="@dimen/margin_medium"
48-
android:layout_marginLeft="@dimen/margin_medium"
4947
android:layout_weight="1"
5048
android:layout_width="wrap_content"
5149
android:text="@string/signup_with_google_button"

vendored/WordPressLoginFlow/src/main/res/layout-land/signup_magic_link.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,13 @@
5353
android:layout_width="match_parent"
5454
android:paddingBottom="@dimen/margin_medium_large"
5555
android:paddingEnd="@dimen/margin_medium_large"
56-
android:paddingLeft="@dimen/margin_small_medium"
57-
android:paddingRight="@dimen/margin_medium_large"
5856
android:paddingStart="@dimen/margin_small_medium"
5957
android:paddingTop="@dimen/margin_medium_large"
6058
tools:ignore="InconsistentLayout">
6159

6260
<androidx.appcompat.widget.AppCompatButton
6361
android:id="@+id/signup_magic_link_button"
6462
android:layout_alignParentEnd="true"
65-
android:layout_alignParentRight="true"
6663
android:layout_height="wrap_content"
6764
android:layout_width="wrap_content"
6865
android:text="@string/open_mail"

vendored/WordPressLoginFlow/src/main/res/layout/login_email_password_screen.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
android:layout_width="match_parent"
4242
android:layout_height="wrap_content"
4343
android:orientation="vertical"
44-
android:layout_marginLeft="@dimen/margin_extra_large"
4544
android:layout_marginStart="@dimen/margin_extra_large"
4645
android:focusable="true">
4746

0 commit comments

Comments
 (0)