package com.orgzly.android.espresso; import android.support.test.rule.ActivityTestRule; import com.orgzly.R; import com.orgzly.android.OrgzlyTest; import com.orgzly.android.sync.BookSyncStatus; import com.orgzly.android.ui.MainActivity; import org.junit.Rule; import org.junit.Test; import java.io.IOException; import static android.support.test.espresso.Espresso.onData; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.Espresso.pressBack; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; import static android.support.test.espresso.action.ViewActions.longClick; import static android.support.test.espresso.action.ViewActions.replaceText; import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.contrib.DrawerActions.close; import static android.support.test.espresso.contrib.DrawerActions.open; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static com.orgzly.android.espresso.EspressoUtils.closeSoftKeyboardWithDelay; import static com.orgzly.android.espresso.EspressoUtils.onActionItemClick; import static com.orgzly.android.espresso.EspressoUtils.onListItem; import static com.orgzly.android.espresso.EspressoUtils.onSpinnerString; import static com.orgzly.android.espresso.EspressoUtils.settingsSetTodoKeywords; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.not; @SuppressWarnings("unchecked") public class SyncingTest extends OrgzlyTest { @Rule public ActivityTestRule activityRule = new ActivityTestRule<>(MainActivity.class, true, false); /** * Utility method for starting sync using drawer button. */ private void sync() { onView(withId(R.id.drawer_layout)).perform(open()); onView(withId(R.id.sync_button_container)).perform(click()); // onView(withId(R.id.sync_button_text)).check(matches(withText(startsWith("Last sync:")))); onView(withId(R.id.drawer_layout)).perform(close()); } @Test public void testForceLoadingBookWithLink() { shelfTestUtils.setupBook("booky", "First book used for testing\n* Note A"); shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/booky.org", "New content", "abc", 1234567890000L); activityRule.launchActivity(null); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText(R.string.no_link)).check(matches(isDisplayed())); // Current value onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("mock://repo-a").perform(click()); onView(withText(R.string.set)).perform(click()); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_load)).perform(click()); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches((withText(containsString(context.getString(R.string.force_loaded_from_uri, "mock://repo-a/booky.org")))))); onView(allOf(withText("booky"), isDisplayed())).perform(click()); onView(withText("New content")).check(matches(isDisplayed())); } @Test public void testSyncAfterNoteCreatedPreference() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/booky.org", "", "abc", 1234567890000L); activityRule.launchActivity(null); sync(); // Set preference onActionItemClick(R.id.activity_action_settings, R.string.settings); onListItem(EspressoUtils.SETTINGS_SYNC_AFTER).perform(click()); // Open book onView(withId(R.id.drawer_layout)).perform(open()); onView(allOf(withText(R.string.notebooks), isDisplayed())).perform(click()); onView(withId(R.id.fragment_books_container)).check(matches(isDisplayed())); onView(allOf(withText("booky"), isDisplayed())).check(matches(isDisplayed())); onListItem(0).perform(click()); // Add note onView(withId(R.id.fab)).perform(click()); onView(withId(R.id.fragment_note_title)) .perform(replaceText("new note created by test"), closeSoftKeyboardWithDelay()); onView(withId(R.id.done)).perform(click()); // Check it is synced onView(withId(R.id.drawer_layout)).perform(open()); onView(allOf(withText(R.string.notebooks), isDisplayed())).perform(click()); onView(withId(R.id.fragment_books_container)).check(matches(isDisplayed())); onView(allOf(withText("booky"), isDisplayed())).check(matches(isDisplayed())); onView(allOf(withId(R.id.item_book_modified_after_sync_icon))).check(matches(not(isDisplayed()))); } @Test public void testForceLoadingBookWithNoLinkNoRepos() { shelfTestUtils.setupBook("booky", "First book used for testing\n* Note A"); shelfTestUtils.setupBook("book-two", "Second book used for testing\n* Note 1\n* Note 2"); activityRule.launchActivity(null); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_load)).perform(click()); onView(withText(endsWith(context.getString(R.string.message_book_has_no_link)))).check(matches(isDisplayed())); } @Test public void testForceLoadingBookWithNoLinkSingleRepo() { shelfTestUtils.setupBook("booky", "First book used for testing\n* Note A"); shelfTestUtils.setupBook("book-two", "Second book used for testing\n* Note 1\n* Note 2"); shelfTestUtils.setupRepo("mock://repo-a"); activityRule.launchActivity(null); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_load)).perform(click()); onView(withText(endsWith(context.getString(R.string.message_book_has_no_link)))) .check(matches(isDisplayed())); } /* Books view was returning multiple entries for the same book, due to duplicates in encodings * table. The last statement in this method will fail if there are multiple books matching. */ @Test public void testForceLoadingMultipleTimes() { shelfTestUtils.setupBook("book-one", "First book used for testing\n* Note A"); shelfTestUtils.setupBook("book-two", "Second book used for testing\n* Note 1\n* Note 2"); shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/book-one.org", "New content", "abc", 1234567890000L); activityRule.launchActivity(null); onView(allOf(withText("book-one"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText(R.string.no_link)).check(matches(isDisplayed())); // Current value onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("mock://repo-a").perform(click()); onView(withText(R.string.set)).perform(click()); onView(allOf(withText("book-one"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_load)).perform(click()); onView(withText(containsString(context.getString(R.string.force_loaded_from_uri, "mock://repo-a/book-one.org")))).check(matches(isDisplayed())); onView(allOf(withText("book-one"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_load)).perform(click()); onView(withText(containsString(context.getString(R.string.force_loaded_from_uri, "mock://repo-a/book-one.org")))).check(matches(isDisplayed())); } @Test public void testForceSavingBookWithNoLinkAndMultipleRepos() { shelfTestUtils.setupBook("book-one", "First book used for testing\n* Note A"); shelfTestUtils.setupBook("book-two", "Second book used for testing\n* Note 1\n* Note 2"); shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRepo("mock://repo-b"); activityRule.launchActivity(null); onView(allOf(withText("book-one"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_save)).perform(click()); onView(withText(endsWith(context.getString(R.string.force_saving_failed, context.getString(R.string.multiple_repos))))).check(matches(isDisplayed())); } @Test public void testForceSavingBookWithNoLinkNoRepos() { shelfTestUtils.setupBook("book-one", "First book used for testing\n* Note A"); shelfTestUtils.setupBook("book-two", "Second book used for testing\n* Note 1\n* Note 2"); activityRule.launchActivity(null); onView(allOf(withText("book-one"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_save)).perform(click()); onView(withText(endsWith(context.getString(R.string.force_saving_failed, context.getString(R.string.no_repos))))).check(matches(isDisplayed())); } @Test public void testForceSavingBookWithNoLinkSingleRepo() { shelfTestUtils.setupBook("book-one", "First book used for testing\n* Note A"); shelfTestUtils.setupBook("book-two", "Second book used for testing\n* Note 1\n* Note 2"); shelfTestUtils.setupRepo("mock://repo-a"); activityRule.launchActivity(null); onView(allOf(withText("book-one"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_save)).perform(click()); onView(withText(containsString(context.getString(R.string.force_saved_to_uri, "mock://repo-a/book-one.org")))).check(matches(isDisplayed())); } @Test public void testForceSavingBookWithLink() { shelfTestUtils.setupBook("booky", "First book used for testing\n* Note A", "mock://repo-a"); shelfTestUtils.setupRepo("mock://repo-a"); activityRule.launchActivity(null); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_force_save)).perform(click()); onView(withText(containsString(context.getString(R.string.force_saved_to_uri, "mock://repo-a/booky.org")))).check(matches(isDisplayed())); } @Test public void testSyncButton() throws IOException { shelfTestUtils.setupBook("book-one", "First book used for testing\n* Note A"); shelfTestUtils.setupBook("book-two", "Second book used for testing\n* Note 1\n* Note 2"); shelfTestUtils.setupRepo("mock://repo-a"); activityRule.launchActivity(null); sync(); } @Test public void testSavingAndLoadingBookBySyncing() throws IOException { shelfTestUtils.setupBook("booky", "Sample book used for tests\n" + "* Note #1.\n" + "* Note #2.\n" + "** TODO Note #3.\n" + "** Note #4.\n" + "*** DONE Note #5.\n" + "**** Note #6.\n" + "** Note #7.\n" + "* Note #8.\n" + "**** Note #9.\n" + "** ANTIVIVISECTIONISTS Note #10.\n" + "** Note #11. DIE PERSER (Ü: Andreas Röhler) Schauspiel 1 D 3 H Stand:\n" + ""); shelfTestUtils.setupRepo("mock://repo-a"); activityRule.launchActivity(null); sync(); onView(withId(R.id.drawer_layout)).perform(open()); onView(allOf(withText(R.string.notebooks), isDisplayed())).perform(click()); onView(withId(R.id.fragment_books_container)).check(matches(isDisplayed())); onView(allOf(withText("booky"), isDisplayed())).check(matches(isDisplayed())); onListItem(0).perform(longClick()); onData(hasToString(containsString(context.getString(R.string.delete)))).perform(click()); onView(withText(R.string.ok)).perform(click()); onView(withId(R.id.item_book_card_view)).check(doesNotExist()); sync(); onView(withId(R.id.drawer_layout)).perform(open()); onView(withText(R.string.notebooks)).perform(click()); onView(withId(R.id.fragment_books_container)).check(matches(isDisplayed())); onView(allOf(withText("booky"), isDisplayed())).check(matches(isDisplayed())); onListItem(0).perform(click()); onListItem(11).perform(click()); onView(withText("Note #11. DIE PERSER (Ü: Andreas Röhler) Schauspiel 1 D 3 H Stand:")).perform(click()); onView(withId(R.id.fragment_note_container)).check(matches(isDisplayed())); } @Test public void testBackToModifiedBookAfterSyncing() throws IOException { shelfTestUtils.setupBook("booky", "Sample book used for tests\n" + "* Note #1.\n" + "* Note #2.\n" + "** TODO Note #3.\n" + "** Note #4.\n" + "*** DONE Note #5.\n" + "**** Note #6.\n" + "** Note #7.\n" + "* Note #8.\n" + "**** Note #9.\n" + "** ANTIVIVISECTIONISTS Note #10.\n" + "** Note #11. DIE PERSER (Ü: Andreas Röhler) Schauspiel 1 D 3 H Stand:\n" + ""); shelfTestUtils.setupRepo("mock://repo-a"); activityRule.launchActivity(null); sync(); onView(allOf(withText("booky"), isDisplayed())).perform(click()); onView(withId(R.id.drawer_layout)).perform(open()); onView(allOf(withText(R.string.notebooks), isDisplayed())).perform(click()); /* Make sure book has been uploaded to repo and is linked now. */ onListItem(0).onChildView(withId(R.id.item_book_link_url)).check(matches(allOf(withText("mock://repo-a/booky.org"), isDisplayed()))); onListItem(0).onChildView(withId(R.id.item_book_synced_url)).check(matches(allOf(withText("mock://repo-a/booky.org"), isDisplayed()))); /* Modify remote book directly. */ shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/booky.org", "NEW CONTENT", "abc", 1234567890000L); sync(); /* Go back to book. */ pressBack(); onView(withText("NEW CONTENT")).check(matches(isDisplayed())); } @Test public void testBookParsingAfterKeywordsSettingChange() throws IOException { shelfTestUtils.setupBook("booky", "Sample book used for tests\n" + "* Note #1.\n" + "* Note #2.\n" + "** TODO Note #3.\n" + "** Note #4.\n" + "*** DONE Note #5.\n" + "**** Note #6.\n" + "** Note #7.\n" + "* Note #8.\n" + "**** Note #9.\n" + "** ANTIVIVISECTIONISTS Note #10.\n" + "** Note #11. DIE PERSER (Ü: Andreas Röhler) Schauspiel 1 D 3 H Stand:\n" + ""); shelfTestUtils.setupRepo("mock://repo-a"); activityRule.launchActivity(null); sync(); onView(allOf(withText("booky"), isDisplayed())).perform(click()); /* Open note "ANTIVIVISECTIONISTS Note #10." and check title. */ onListItem(10).perform(click()); onView(withId(R.id.fragment_note_title)).check(matches(allOf(withText("ANTIVIVISECTIONISTS Note #10."), isDisplayed()))); settingsSetTodoKeywords("ANTIVIVISECTIONISTS"); onView(withId(R.id.drawer_layout)).perform(open()); onView(allOf(withText(R.string.notebooks), isDisplayed())).perform(click()); onView(withId(R.id.fragment_books_container)).check(matches(isDisplayed())); /* Delete book */ onListItem(0).perform(longClick()); onData(hasToString(containsString(context.getString(R.string.delete)))).perform(click()); onView(withText(R.string.ok)).perform(click()); sync(); onView(allOf(withText("booky"), isDisplayed())).perform(click()); /* Open note "ANTIVIVISECTIONISTS Note #10." and check title. */ onListItem(10).perform(click()); onView(withId(R.id.fragment_note_title)).check(matches(allOf(withText("Note #10."), isDisplayed()))); } @Test public void testChangeBookLink() throws IOException { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/book-1.org", "Remote content for book in repo a", "abc", 1234567890); shelfTestUtils.setupRepo("mock://repo-b"); shelfTestUtils.setupRook("mock://repo-b", "mock://repo-b/book-1.org", "Remote content for book in repo b", "def", 1234567891); activityRule.launchActivity(null); sync(); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.DUMMY_WITHOUT_LINK_AND_MULTIPLE_ROOKS.msg())), isDisplayed()))); /* Set link to repo-b. */ onView(allOf(withText("book-1"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText(R.string.no_link)).check(matches(isDisplayed())); // Current value onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("mock://repo-b").perform(click()); onView(withText(R.string.set)).perform(click()); onView(withText("mock://repo-b/book-1.org")).check(matches(isDisplayed())); sync(); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.DUMMY_WITH_LINK.msg())), isDisplayed()))); onListItem(0).perform(click()); onView(withText("Remote content for book in repo b")).check(matches(isDisplayed())); pressBack(); /* Set link to repo-a. */ onView(allOf(withText("book-1"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText("mock://repo-b")).check(matches(isDisplayed())); // Current value onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("mock://repo-a").perform(click()); onView(withText(R.string.set)).perform(click()); onView(withText("mock://repo-a/book-1.org")).check(matches(isDisplayed())); sync(); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.CONFLICT_LAST_SYNCED_ROOK_AND_LATEST_ROOK_ARE_DIFFERENT.msg())), isDisplayed()))); /* Still the same content due to conflict. */ onListItem(0).perform(click()); onView(withText("Remote content for book in repo b")).check(matches(isDisplayed())); } @Test public void test1() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRepo("mock://repo-b"); shelfTestUtils.setupRook("mock://repo-b", "mock://repo-b/book-2.org", "Remote content for book 2", "abc", 1234567890000L); shelfTestUtils.setupRook("mock://repo-b", "mock://repo-b/book-3.org", "Remote content for book 3", "def", 1234567891000L); shelfTestUtils.setupBook("book-1", "Local content for book 1"); shelfTestUtils.setupBook("book-2", "Local content for book 2", "mock://repo-b"); activityRule.launchActivity(null); sync(); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.ONLY_BOOK_WITHOUT_LINK_AND_MULTIPLE_REPOS.msg())), isDisplayed()))); onListItem(1).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.CONFLICT_BOOK_WITH_LINK_AND_ROOK_BUT_NEVER_SYNCED_BEFORE.msg())), isDisplayed()))); onListItem(2).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.DUMMY_WITHOUT_LINK_AND_ONE_ROOK.msg())), isDisplayed()))); onListItem(0).perform(click()); onView(withText("Local content for book 1")).check(matches(isDisplayed())); pressBack(); onListItem(1).perform(click()); onView(withText("Local content for book 2")).check(matches(isDisplayed())); pressBack(); /* Whole notebook view is too big to fit on small devices' screen, so we get * "at least 90 percent of the view's area is displayed to the user" * when trying to click on it. Clicking on specific view inside (book name) instead. */ onListItem(2).onChildView(withId(R.id.item_book_title)).perform(click()); onView(withText("Remote content for book 3")).check(matches(isDisplayed())); pressBack(); sync(); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.ONLY_BOOK_WITHOUT_LINK_AND_MULTIPLE_REPOS.msg())), isDisplayed()))); onListItem(1).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.CONFLICT_BOOK_WITH_LINK_AND_ROOK_BUT_NEVER_SYNCED_BEFORE.msg())), isDisplayed()))); onListItem(2).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(containsString(BookSyncStatus.NO_CHANGE.msg())), isDisplayed()))); onListItem(0).perform(click()); onView(withText("Local content for book 1")).check(matches(isDisplayed())); pressBack(); onListItem(1).perform(click()); onView(withText("Local content for book 2")).check(matches(isDisplayed())); pressBack(); onListItem(2).perform(click()); onView(withText("Remote content for book 3")).check(matches(isDisplayed())); pressBack(); } @Test public void testEncodingAfterSyncSaving() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/book-one.org", "Täht", "1abcde", 1400067156000L); activityRule.launchActivity(null); sync(); onListItem(0).onChildView(withId(R.id.item_book_encoding_used)).check(matches((withText("UTF-8 used")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_detected)).check(matches((withText("UTF-8 detected")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_selected)).check(matches(not(isDisplayed()))); sync(); onListItem(0).onChildView(withId(R.id.item_book_encoding_used)).check(matches((withText("UTF-8 used")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_detected)).check(matches((withText("UTF-8 detected")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_selected)).check(matches(not(isDisplayed()))); } @Test public void testSettingLinkToRenamedRepo() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/booky.org", "Täht", "1abcde", 1400067156000L); activityRule.launchActivity(null); sync(); onListItem(0).onChildView(withId(R.id.item_book_link_url)).check(matches(allOf(withText("mock://repo-a/booky.org"), isDisplayed()))); onListItem(0).onChildView(withId(R.id.item_book_synced_url)).check(matches(allOf(withText("mock://repo-a/booky.org"), isDisplayed()))); onListItem(0).onChildView(withId(R.id.item_book_encoding_used)).check(matches((withText("UTF-8 used")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_detected)).check(matches((withText("UTF-8 detected")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_selected)).check(matches(not(isDisplayed()))); /* Rename repository. */ onActionItemClick(R.id.activity_action_settings, R.string.settings); onListItem(EspressoUtils.SETTINGS_REPOS).perform(click()); onListItem(0).perform(click()); onView(withId(R.id.fragment_repo_dropbox_directory)).perform(replaceText("repo-b")); onActionItemClick(R.id.done, R.string.close); pressBack(); pressBack(); onView(withId(R.id.drawer_layout)).perform(open()); onView(withText(R.string.notebooks)).perform(click()); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText(R.string.no_link)).check(matches(isDisplayed())); // Current value onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("dropbox:/repo-b").perform(click()); onView(withText(R.string.set)).perform(click()); onListItem(0).onChildView(withId(R.id.item_book_link_url)).check(matches(allOf(withText("dropbox:/repo-b/booky.org"), isDisplayed()))); onListItem(0).onChildView(withId(R.id.item_book_synced_url)).check(matches(allOf(withText("mock://repo-a/booky.org"), isDisplayed()))); onListItem(0).onChildView(withId(R.id.item_book_encoding_used)).check(matches((withText("UTF-8 used")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_detected)).check(matches((withText("UTF-8 detected")))); onListItem(0).onChildView(withId(R.id.item_book_encoding_selected)).check(matches(not(isDisplayed()))); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText("dropbox:/repo-b")).check(matches(isDisplayed())); // Current value } @Test public void testRenamingReposRemovesLinksWhatUsedThem() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRepo("mock://repo-b"); shelfTestUtils.setupBook("booky", ""); activityRule.launchActivity(null); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText(R.string.no_link)).check(matches(isDisplayed())); // Current value onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("mock://repo-a").perform(click()); onView(withText(R.string.set)).perform(click()); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText("mock://repo-a")).check(matches(isDisplayed())); // Current value onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("mock://repo-a").perform(click()); onView(withText(R.string.cancel)).perform(click()); /* Rename all repositories. */ onActionItemClick(R.id.activity_action_settings, R.string.settings); onListItem(EspressoUtils.SETTINGS_REPOS).perform(click()); onListItem(0).perform(click()); onView(withId(R.id.fragment_repo_dropbox_directory)).perform(replaceText("repo-1")); onActionItemClick(R.id.done, R.string.close); onListItem(0).perform(click()); onView(withId(R.id.fragment_repo_dropbox_directory)).perform(replaceText("repo-2")); onActionItemClick(R.id.done, R.string.close); pressBack(); pressBack(); onView(withId(R.id.drawer_layout)).perform(open()); onView(withText(R.string.notebooks)).perform(click()); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withText(R.string.no_link)).check(matches(isDisplayed())); // Current value } @Test public void testRemovingLinkFromBook() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupBook("booky", "", "mock://repo-a"); activityRule.launchActivity(null); onListItem(0).onChildView(withId(R.id.item_book_link_url)).check(matches(allOf(withText("mock://repo-a/booky.org"), isDisplayed()))); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString(activityRule.getActivity().getString(R.string.no_link)).perform(click()); onView(withText(R.string.set)).perform(click()); onListItem(0).onChildView(withId(R.id.item_book_link_container)).check(matches(not(isDisplayed()))); } @Test public void testSettingLinkForLoadedOrgTxtBook() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/booky.org.txt", "", "1abcdef", 1400067155); activityRule.launchActivity(null); sync(); onListItem(0).onChildView(withId(R.id.item_book_last_action)).check(matches(withText(containsString("Loaded from mock://repo-a/booky.org.txt")))); onListItem(0).onChildView(withId(R.id.item_book_link_url)).check(matches(allOf(withText("mock://repo-a/booky.org.txt"), isDisplayed()))); onView(allOf(withText("booky"), isDisplayed())).perform(longClick()); onView(withText(R.string.books_context_menu_item_set_link)).perform(click()); onView(withId(R.id.dialog_spinner)).perform(click()); // Open spinner onSpinnerString("mock://repo-a").perform(click()); onView(withText(R.string.set)).perform(click()); onListItem(0).onChildView(withId(R.id.item_book_link_url)).check(matches(allOf(withText("mock://repo-a/booky.org.txt"), isDisplayed()))); } @Test public void testSpaceSeparatedBookName() throws IOException { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupRook("mock://repo-a", "mock://repo-a/Book%20Name.org", "", "1abcdef", 1400067155); activityRule.launchActivity(null); sync(); onListItem(0).onChildView(withId(R.id.item_book_link_url)) .check(matches(allOf(withText("mock://repo-a/Book Name.org"), isDisplayed()))); onListItem(0).onChildView(withId(R.id.item_book_synced_url)) .check(matches(allOf(withText("mock://repo-a/Book Name.org"), isDisplayed()))); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches(allOf(withText(endsWith("Loaded from mock://repo-a/Book Name.org")), isDisplayed()))); } @Test public void testRenameModifiedBook() { shelfTestUtils.setupRepo("mock://repo-a"); shelfTestUtils.setupBook("booky", "* Note"); activityRule.launchActivity(null); sync(); onListItem(0).perform(click()); // Open notebook onListItem(0).perform(click()); // Open note onView(withId(R.id.fragment_note_title)).perform(replaceText("New title")); onView(withId(R.id.done)).perform(click()); pressBack(); // Back to the list of notebooks onListItem(0).perform(longClick()); onView(withText(R.string.books_context_menu_item_rename)).perform(click()); onView(withId(R.id.name)).perform(replaceText("book-two"), closeSoftKeyboard()); onView(withText(R.string.rename)).perform(click()); String errMsg = context.getString( R.string.failed_renaming_book_with_reason, "Notebook is not synced"); onListItem(0).onChildView(withId(R.id.item_book_last_action)) .check(matches(withText(endsWith(errMsg)))); } }