diff --git a/app/build.gradle b/app/build.gradle index a4f3e951..958a7a18 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,6 +40,13 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + + testOptions { + unitTests { + returnDefaultValues = true + includeAndroidResources = true + } + } } def firebaseReleaseProjectId = "mthmmy-release-3aef0" @@ -103,6 +110,14 @@ dependencies { implementation 'net.gotev:uploadservice:3.5.2' implementation 'net.gotev:uploadservice-okhttp:3.4.2' //TODO: Warning: v.3.5 depends on okhttp 3.13! implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.5' //Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler + + // Required for local unit tests (JUnit 4 framework) + testImplementation 'junit:junit:4.12' + + // Required for instrumented tests + androidTestImplementation 'com.android.support:support-annotations:28.0.0' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + } apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java index b6925fba..b8d74f45 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java @@ -31,6 +31,9 @@ public class CreatePMActivity extends BaseActivity implements ExternalAsyncTask. private EmojiKeyboard emojiKeyboard; private String username, sendPmUrl; + public static final String BUNDLE_SEND_PM_URL = "send-pm-url"; + public static final String BUNDLE_PM_CONTENT = "pm-content"; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -38,7 +41,7 @@ public class CreatePMActivity extends BaseActivity implements ExternalAsyncTask. Intent callingIntent = getIntent(); username = callingIntent.getStringExtra(ProfileActivity.BUNDLE_PROFILE_USERNAME); - sendPmUrl = callingIntent.getStringExtra(ProfileActivity.BUNDLE_SEND_PM_URL); + sendPmUrl = callingIntent.getStringExtra(BUNDLE_SEND_PM_URL); //Initialize toolbar toolbar = findViewById(R.id.toolbar); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java index f58252f4..9d8b5f91 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java @@ -38,6 +38,7 @@ import java.util.Objects; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.board.BoardActivity; +import gr.thmmy.mthmmy.activities.create_pm.CreatePMActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.model.PM; @@ -228,6 +229,10 @@ public class InboxAdapter extends RecyclerView.Adapter quoteButton.setOnClickListener(v -> { Toast.makeText(context, "TODO", Toast.LENGTH_SHORT).show(); // TODO: Create quote PM task + Intent sendPMIntent = new Intent(context, CreatePMActivity.class); + sendPMIntent.putExtra(CreatePMActivity.BUNDLE_SEND_PM_URL, currentPM.getQuoteUrl()); + context.startActivity(sendPMIntent); + popUp.dismiss(); }); final TextView replyButton = popupContent.findViewById(R.id.pm_reply_button); @@ -235,8 +240,10 @@ public class InboxAdapter extends RecyclerView.Adapter replyButton.setCompoundDrawablesRelativeWithIntrinsicBounds(replyDrawable, null, null, null); replyButton.setOnClickListener(v -> { - Toast.makeText(context, "TODO", Toast.LENGTH_SHORT).show(); - // TODO: Create reply PM task + Intent sendPMIntent = new Intent(context, CreatePMActivity.class); + sendPMIntent.putExtra(CreatePMActivity.BUNDLE_SEND_PM_URL, currentPM.getReplyUrl()); + context.startActivity(sendPMIntent); + popUp.dismiss(); }); TextView deletePostButton = popupContent.findViewById(R.id.delete_post); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java index 95c4fd9c..3b86bf87 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java @@ -84,7 +84,6 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment * If username is not available put an empty string or leave it null. */ public static final String BUNDLE_PROFILE_USERNAME = "USERNAME"; - public static final String BUNDLE_SEND_PM_URL = "send-pm-url"; private TextView usernameView; private ImageView avatarView; @@ -153,11 +152,11 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment if (sessionManager.isLoggedIn()) { Intent sendPMIntent = new Intent(ProfileActivity.this, CreatePMActivity.class); sendPMIntent.putExtra(BUNDLE_PROFILE_USERNAME, username); - sendPMIntent.putExtra(BUNDLE_SEND_PM_URL, sendPmUrl); + sendPMIntent.putExtra(CreatePMActivity.BUNDLE_SEND_PM_URL, sendPmUrl); startActivity(sendPMIntent); } else { new AlertDialog.Builder(ProfileActivity.this) - .setMessage("You need to be logged in to sent a personal message!") + .setMessage("You need to be logged in to send a personal message!") .setPositiveButton("Login", (dialogInterface, i) -> { Intent intent = new Intent(ProfileActivity.this, LoginActivity.class); startActivity(intent); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java index ff136bd7..04a22a66 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java @@ -55,7 +55,7 @@ import gr.thmmy.mthmmy.model.TopicItem; import gr.thmmy.mthmmy.utils.CustomLinearLayoutManager; import gr.thmmy.mthmmy.utils.HTMLUtils; import gr.thmmy.mthmmy.utils.NetworkResultCodes; -import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; +import gr.thmmy.mthmmy.utils.parsing.StringUtils; import gr.thmmy.mthmmy.viewmodel.TopicViewModel; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import timber.log.Timber; @@ -539,7 +539,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo if ((((Post) topicItems.get(topicItems.size() - 1)).getPostNumber() + 1) % 15 == 0) { Timber.i("Reply was posted in new page. Switching to last page."); - viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647); + viewModel.loadUrl(StringUtils.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647); } else { viewModel.reloadPage(); } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index 100630de..1d8f1ed2 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java @@ -75,6 +75,7 @@ import gr.thmmy.mthmmy.model.TopicItem; import gr.thmmy.mthmmy.utils.CircleTransform; import gr.thmmy.mthmmy.utils.MessageAnimations; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; +import gr.thmmy.mthmmy.utils.parsing.StringUtils; import gr.thmmy.mthmmy.utils.parsing.ThmmyParser; import gr.thmmy.mthmmy.viewmodel.TopicViewModel; import timber.log.Timber; @@ -965,7 +966,7 @@ class TopicAdapter extends RecyclerView.Adapter { if (target.is(ThmmyPage.PageCategory.TOPIC)) { //This url points to a topic //Checks if the page to be loaded is the one already shown - if (uriString.contains(ParseHelpers.getBaseURL(viewModel.getTopicUrl()))) { + if (uriString.contains(StringUtils.getBaseURL(viewModel.getTopicUrl()))) { if (uriString.contains("topicseen#new") || uriString.contains("#new")) { if (viewModel.getCurrentPageIndex() == viewModel.getPageCount()) { //same page @@ -987,9 +988,9 @@ class TopicAdapter extends RecyclerView.Adapter { return true; } } - } else if ((Objects.equals(uriString, ParseHelpers.getBaseURL(viewModel.getTopicUrl())) && + } else if ((Objects.equals(uriString, StringUtils.getBaseURL(viewModel.getTopicUrl())) && viewModel.getCurrentPageIndex() == 1) || - Integer.parseInt(uriString.substring(ParseHelpers.getBaseURL(viewModel.getTopicUrl()).length() + 1)) / 15 + 1 == + Integer.parseInt(uriString.substring(StringUtils.getBaseURL(viewModel.getTopicUrl()).length() + 1)) / 15 + 1 == viewModel.getCurrentPageIndex()) { //same page return true; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java index e9792ac0..e16c41e2 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java @@ -284,23 +284,6 @@ public class ParseHelpers { return parsedPage; } - /** - * Method that extracts the base URL from a topic's page URL. For example a topic with url similar to - * "https://www.thmmy.gr/smf/index.php?topic=1.15;topicseen" or - * "https://www.thmmy.gr/smf/index.php?topic=1.msg1#msg1" - * has the base url "https://www.thmmy.gr/smf/index.php?topic=1" - * - * @param topicURL a topic's page URL - * @return the base URL of the given topic - */ - public static String getBaseURL(String topicURL) { - String forumUrl = "https://www.thmmy.gr/smf/index.php?"; - Matcher baseUrlMatcher = Pattern.compile("topic=[0-9]+").matcher(topicURL); - if (baseUrlMatcher.find()) - return forumUrl + topicURL.substring(baseUrlMatcher.start(), baseUrlMatcher.end()); - else return ""; - } - /** * Method that replaces CloudFlare-obfuscated emails with deobfuscated ones * Replace Jsoup.parse with this wherever needed diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/StringUtils.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/StringUtils.java new file mode 100644 index 00000000..de13d2d7 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/StringUtils.java @@ -0,0 +1,30 @@ +package gr.thmmy.mthmmy.utils.parsing; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StringUtils { + /** + * Method that extracts the base URL from a topic's page URL. For example a topic with url similar to + * "https://www.thmmy.gr/smf/index.php?topic=1.15;topicseen" or + * "https://www.thmmy.gr/smf/index.php?topic=1.msg1#msg1" + * has the base url "https://www.thmmy.gr/smf/index.php?topic=1" + * + * @param topicURL a topic's page URL + * @return the base URL of the given topic + */ + public static String getBaseURL(String topicURL) { + String forumUrl = "https://www.thmmy.gr/smf/index.php?"; + Matcher baseUrlMatcher = Pattern.compile("topic=[0-9]+").matcher(topicURL); + if (baseUrlMatcher.find()) + return forumUrl + topicURL.substring(baseUrlMatcher.start(), baseUrlMatcher.end()); + else return ""; + } + + public static int extractUserCodeFromUrl(String url) { + Matcher userCodeMatcher = Pattern.compile("u=[0-9]+").matcher(url); + if (userCodeMatcher.find()) + return Integer.parseInt(url.substring(userCodeMatcher.start()+2, userCodeMatcher.end())); + else return -1; + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java index dee6d866..4d0a83a7 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java +++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java @@ -31,7 +31,7 @@ import gr.thmmy.mthmmy.model.TopicItem; import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.utils.ExternalAsyncTask; import gr.thmmy.mthmmy.utils.NetworkTask; -import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; +import gr.thmmy.mthmmy.utils.parsing.StringUtils; import timber.log.Timber; public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTaskCompleted, @@ -112,7 +112,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa public void resetPage() { if (topicUrl == null) throw new NullPointerException("No topic task has been requested yet!"); Timber.i("Resetting page"); - loadUrl(ParseHelpers.getBaseURL(topicUrl) + "." + currentPageIndex * 15); + loadUrl(StringUtils.getBaseURL(topicUrl) + "." + currentPageIndex * 15); } public void resetPageThen(Runnable runnable) { @@ -123,7 +123,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa TopicViewModel.this.onTopicTaskCompleted(result); runnable.run(); }); - currentTopicTask.execute(ParseHelpers.getBaseURL(topicUrl) + "." + currentPageIndex * 15); + currentTopicTask.execute(StringUtils.getBaseURL(topicUrl) + "." + currentPageIndex * 15); } public void loadPageIndicated() { @@ -132,7 +132,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa int pageRequested = pageIndicatorIndex.getValue() - 1; if (pageRequested != currentPageIndex - 1) { Timber.i("Changing to page " + pageRequested + 1); - loadUrl(ParseHelpers.getBaseURL(topicUrl) + "." + pageRequested * 15); + loadUrl(StringUtils.getBaseURL(topicUrl) + "." + pageRequested * 15); pageIndicatorIndex.setValue(pageRequested + 1); } else { stopLoading(); diff --git a/app/src/test/java/gr/thmmy/mthmmy/utils/parsing/StringUtilsTest.java b/app/src/test/java/gr/thmmy/mthmmy/utils/parsing/StringUtilsTest.java new file mode 100644 index 00000000..fd41a65d --- /dev/null +++ b/app/src/test/java/gr/thmmy/mthmmy/utils/parsing/StringUtilsTest.java @@ -0,0 +1,19 @@ +package gr.thmmy.mthmmy.utils.parsing; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class StringUtilsTest { + + @Before + public void setUp() throws Exception { + } + + @Test + public void extractUserCodeFromUrl() { + String url = "https://www.thmmy.gr/smf/index.php?action=profile;u=14670"; + assertEquals(StringUtils.extractUserCodeFromUrl(url), 14670); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 70b74ad6..67c53209 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.google.gms:google-services:4.3.2' classpath 'io.fabric.tools:gradle:1.29.0' classpath 'org.ajoberstar.grgit:grgit-core:3.1.1' // Also change in app/gradle/grgit.gradle