/*************************************************************************** * Copyright 2006-2016 by Christian Ihle * * contact@kouchat.net * * * * This file is part of KouChat. * * * * KouChat is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version. * * * * KouChat is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with KouChat. * * If not, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ package net.usikkert.kouchat.android; import java.io.File; import java.io.IOException; import java.util.Set; import net.usikkert.kouchat.android.chatwindow.AndroidUserInterface; import net.usikkert.kouchat.android.controller.MainChatController; import net.usikkert.kouchat.android.controller.ReceiveFileController; import net.usikkert.kouchat.android.notification.NotificationService; import net.usikkert.kouchat.android.util.AndroidFile; import net.usikkert.kouchat.android.util.FileUtils; import net.usikkert.kouchat.android.util.RobotiumTestUtils; import net.usikkert.kouchat.misc.User; import net.usikkert.kouchat.testclient.TestClient; import net.usikkert.kouchat.testclient.TestUtils; import com.google.common.io.ByteSource; import com.google.common.io.Files; import com.robotium.solo.Solo; import android.app.Instrumentation; import android.content.ContentResolver; import android.content.Intent; import android.os.Environment; import android.test.ActivityInstrumentationTestCase2; import android.widget.TextView; /** * Tests file reception. * * @author Christian Ihle */ public class ReceiveFileTest extends ActivityInstrumentationTestCase2<MainChatController> { private static TestClient albert; private static TestClient tina; private static TestClient xen; private static AndroidFile image; private static File requestedFile; private static File requestedFile1; private static File requestedFile2; private Solo solo; private NotificationService notificationService; private User me; public ReceiveFileTest() { super(MainChatController.class); } public void setUp() { final MainChatController mainChatController = getActivity(); final Instrumentation instrumentation = getInstrumentation(); // To avoid issues with "." and "," in asserts containing file sizes RobotiumTestUtils.switchUserInterfaceToEnglish(mainChatController); solo = new Solo(instrumentation, mainChatController); me = RobotiumTestUtils.getMe(mainChatController); final AndroidUserInterface ui = TestUtils.getFieldValue(mainChatController, AndroidUserInterface.class, "androidUserInterface"); notificationService = TestUtils.getFieldValue(ui, NotificationService.class, "notificationService"); if (albert == null) { albert = new TestClient("Albert", 0); tina = new TestClient("Tina", 0); xen = new TestClient("Xen", 0); albert.logon(); tina.logon(); xen.logon(); // Make sure we have an image to send from a test client to the real client FileUtils.copyKouChatImageFromAssetsToSdCard(instrumentation, mainChatController); image = FileUtils.getKouChatImageFromSdCardWithContentUri(mainChatController); requestedFile = getLocationToRequestedFile(""); requestedFile1 = getLocationToRequestedFile("_1"); requestedFile2 = getLocationToRequestedFile("_2"); } solo.sleep(500); checkThatNoFileTransferNotificationsAreActive(); } public void test01ShouldShowMissingFileDialogIfNoFileTransferRequestAvailable() { openReceiveFileDialog(); solo.sleep(500); checkDialogMessage("Unable to find the specified file transfer request"); checkThatTheDialogIsInFront(); solo.clickOnText("OK"); // Close dialog solo.sleep(500); checkThatTheMainChatIsInFront(); checkThatNoFileTransferNotificationsAreActive(); } public void test02RejectFileTransferRequest() { checkThatTheFilesHaveNotBeenTransferred(); tina.sendFile(me, image.getFile()); solo.sleep(500); checkMainChatMessage("*** Tina is trying to send the file kouchat-1600x1600.png"); checkActiveFileTransferNotifications(1); solo.sleep(500); openReceiveFileDialog(tina, 1); solo.sleep(500); checkThatTheDialogIsInFront(); checkDialogMessage("Tina is trying to send you the file ‘kouchat-1600x1600.png’ (67.16KB). " + "Do you want to accept the file transfer?"); solo.sleep(500); rejectFileTransfer(); solo.sleep(500); checkThatTheMainChatIsInFront(); checkMainChatMessage("*** You declined to receive kouchat-1600x1600.png from Tina"); checkThatNoFileTransferNotificationsAreActive(); checkThatTheFilesHaveNotBeenTransferred(); } public void test03AcceptFileTransferRequest() throws IOException { checkThatTheFilesHaveNotBeenTransferred(); albert.sendFile(me, image.getFile()); solo.sleep(500); checkMainChatMessage("*** Albert is trying to send the file kouchat-1600x1600.png"); checkActiveFileTransferNotifications(2); solo.sleep(500); openReceiveFileDialog(albert, 2); solo.sleep(500); checkThatTheDialogIsInFront(); checkDialogMessage("Albert is trying to send you the file ‘kouchat-1600x1600.png’ (67.16KB). " + "Do you want to accept the file transfer?"); solo.sleep(500); acceptFileTransfer(); solo.sleep(1000); checkThatTheMainChatIsInFront(); checkMainChatMessage("*** Receiving kouchat-1600x1600.png from Albert"); checkMainChatMessage("*** Successfully received kouchat-1600x1600.png from Albert, and saved as kouchat-1600x1600.png"); checkThatNoFileTransferNotificationsAreActive(); checkThatTheFileWasReceivedSuccessfully(requestedFile); solo.sleep(500); } public void test04CancelFileTransferRequestBeforeOpeningActivity() { checkThatTheFilesHaveNotBeenTransferred(); xen.sendFile(me, image.getFile()); solo.sleep(500); checkMainChatMessage("*** Xen is trying to send the file kouchat-1600x1600.png"); checkActiveFileTransferNotifications(3); solo.sleep(500); xen.cancelFileSending(me, image.getFile()); solo.sleep(1000); checkMainChatMessage("*** Xen aborted sending of kouchat-1600x1600.png"); checkThatNoFileTransferNotificationsAreActive(); checkThatTheFilesHaveNotBeenTransferred(); } public void test05CancelFileTransferRequestBeforeRejecting() { checkThatTheFilesHaveNotBeenTransferred(); xen.changeNickName("XenMaster"); solo.sleep(500); xen.sendFile(me, image.getFile()); solo.sleep(500); checkMainChatMessage("*** XenMaster is trying to send the file kouchat-1600x1600.png"); checkActiveFileTransferNotifications(4); solo.sleep(500); openReceiveFileDialog(xen, 4); solo.sleep(500); checkThatTheDialogIsInFront(); checkDialogMessage("XenMaster is trying to send you the file ‘kouchat-1600x1600.png’ (67.16KB). " + "Do you want to accept the file transfer?"); solo.sleep(500); xen.cancelFileSending(me, image.getFile()); solo.sleep(500); rejectFileTransfer(); solo.sleep(500); checkThatTheMainChatIsInFront(); checkMainChatMessage("*** XenMaster aborted sending of kouchat-1600x1600.png"); checkThatNoFileTransferNotificationsAreActive(); checkThatTheFilesHaveNotBeenTransferred(); } public void test06CancelFileTransferRequestBeforeAccepting() { checkThatTheFilesHaveNotBeenTransferred(); tina.changeNickName("SuperTina"); solo.sleep(500); tina.sendFile(me, image.getFile()); solo.sleep(500); checkMainChatMessage("*** SuperTina is trying to send the file kouchat-1600x1600.png"); checkActiveFileTransferNotifications(5); solo.sleep(500); openReceiveFileDialog(tina, 5); solo.sleep(500); checkThatTheDialogIsInFront(); checkDialogMessage("SuperTina is trying to send you the file ‘kouchat-1600x1600.png’ (67.16KB). " + "Do you want to accept the file transfer?"); solo.sleep(500); tina.cancelFileSending(me, image.getFile()); solo.sleep(500); acceptFileTransfer(); solo.sleep(500); checkThatTheMainChatIsInFront(); checkMainChatMessage("*** SuperTina aborted sending of kouchat-1600x1600.png"); checkThatNoFileTransferNotificationsAreActive(); checkThatTheFilesHaveNotBeenTransferred(); } public void test07CloseAndReopenDialog() { checkThatTheFilesHaveNotBeenTransferred(); albert.changeNickName("Alban"); solo.sleep(500); albert.sendFile(me, image.getFile()); solo.sleep(500); checkMainChatMessage("*** Alban is trying to send the file kouchat-1600x1600.png"); checkActiveFileTransferNotifications(6); solo.sleep(500); // First try openReceiveFileDialog(albert, 6); solo.sleep(500); checkThatTheDialogIsInFront(); checkDialogMessage("Alban is trying to send you the file ‘kouchat-1600x1600.png’ (67.16KB). " + "Do you want to accept the file transfer?"); solo.sleep(500); // Close dialog without accepting or rejecting solo.goBack(); solo.sleep(500); checkThatTheMainChatIsInFront(); checkActiveFileTransferNotifications(6); // The notification should still be there // Second try openReceiveFileDialog(albert, 6); solo.sleep(500); checkThatTheDialogIsInFront(); checkDialogMessage("Alban is trying to send you the file ‘kouchat-1600x1600.png’ (67.16KB). " + "Do you want to accept the file transfer?"); solo.sleep(500); rejectFileTransfer(); solo.sleep(500); checkThatTheMainChatIsInFront(); checkMainChatMessage("*** You declined to receive kouchat-1600x1600.png from Alban"); checkThatNoFileTransferNotificationsAreActive(); checkThatTheFilesHaveNotBeenTransferred(); } public void test08ConcurrentFileTransfers() throws IOException { checkThatTheFilesHaveNotBeenTransferred(); albert.changeNickName("Albino"); tina.changeNickName("TinaBurger"); xen.changeNickName("XenXei"); solo.sleep(500); albert.sendFile(me, image.getFile()); solo.sleep(500); checkActiveFileTransferNotifications(7); xen.sendFile(me, image.getFile()); solo.sleep(500); checkActiveFileTransferNotifications(7, 8); tina.sendFile(me, image.getFile()); solo.sleep(500); checkActiveFileTransferNotifications(7, 8, 9); checkMainChatMessage("*** Albino is trying to send the file kouchat-1600x1600.png"); checkMainChatMessage("*** TinaBurger is trying to send the file kouchat-1600x1600.png"); checkMainChatMessage("*** XenXei is trying to send the file kouchat-1600x1600.png"); openReceiveFileDialog(albert, 7); acceptFileTransfer(); solo.sleep(100); openReceiveFileDialog(xen, 8); acceptFileTransfer(); solo.sleep(100); openReceiveFileDialog(tina, 9); acceptFileTransfer(); solo.sleep(1000); checkThatTheMainChatIsInFront(); checkThatNoFileTransferNotificationsAreActive(); // Depending on screen size, some of the messages might have scrolled by, currently making them invisible. checkPastMainChatMessage("*** Receiving kouchat-1600x1600.png from Albino"); checkPastMainChatMessage("*** Successfully received kouchat-1600x1600.png from Albino, and saved as kouchat-1600x1600.png"); checkPastMainChatMessage("*** Receiving kouchat-1600x1600.png from XenXei"); checkPastMainChatMessage("*** Successfully received kouchat-1600x1600.png from XenXei, and saved as kouchat-1600x1600_1.png"); checkMainChatMessage("*** Receiving kouchat-1600x1600.png from TinaBurger"); checkMainChatMessage("*** Successfully received kouchat-1600x1600.png from TinaBurger, and saved as kouchat-1600x1600_2.png"); checkThatTheFileWasReceivedSuccessfully(requestedFile); checkThatTheFileWasReceivedSuccessfully(requestedFile1); checkThatTheFileWasReceivedSuccessfully(requestedFile2); solo.sleep(500); } public void test09UserLoggingOffShouldCancelFileTransferRequest() { checkThatTheFilesHaveNotBeenTransferred(); tina.changeNickName("TinaTurner"); solo.sleep(500); tina.sendFile(me, image.getFile()); solo.sleep(500); checkMainChatMessage("*** TinaTurner is trying to send the file kouchat-1600x1600.png"); checkActiveFileTransferNotifications(10); solo.sleep(500); tina.logoff(); solo.sleep(1000); checkMainChatMessage("*** TinaTurner logged off"); checkThatNoFileTransferNotificationsAreActive(); } public void test99Quit() { albert.logoff(); tina.logoff(); xen.logoff(); albert = null; tina = null; xen = null; image = null; requestedFile = null; requestedFile1 = null; requestedFile2 = null; RobotiumTestUtils.quit(solo); } public void tearDown() { final ContentResolver contentResolver = getActivity().getContentResolver(); FileUtils.deleteFileFromSdCard(contentResolver, requestedFile); FileUtils.deleteFileFromSdCard(contentResolver, requestedFile1); FileUtils.deleteFileFromSdCard(contentResolver, requestedFile2); solo.finishOpenedActivities(); solo = null; setActivity(null); System.gc(); } private void openReceiveFileDialog(final TestClient client, final int fileTransferId) { final Intent intent = new Intent(); intent.putExtra("userCode", client.getUserCode()); intent.putExtra("fileTransferId", fileTransferId); final String packageName = getInstrumentation().getTargetContext().getPackageName(); launchActivityWithIntent(packageName, ReceiveFileController.class, intent); } private void openReceiveFileDialog() { final String packageName = getInstrumentation().getTargetContext().getPackageName(); launchActivity(packageName, ReceiveFileController.class, null); } private File getLocationToRequestedFile(final String postfix) { return new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), image.getBaseName() + postfix + image.getExtension()); } private void checkMainChatMessage(final String textToFind) { assertTrue(RobotiumTestUtils.textIsVisible(solo, R.id.mainChatView, R.id.mainChatScroll, textToFind)); } private void checkPastMainChatMessage(final String text) { final TextView mainChatView = (TextView) getActivity().findViewById(R.id.mainChatView); assertTrue(mainChatView.getText().toString().contains(text)); } private void checkDialogMessage(final String textToFind) { assertTrue(RobotiumTestUtils.searchText(solo, textToFind)); } private void checkThatNoFileTransferNotificationsAreActive() { assertTrue(notificationService.getCurrentFileTransferIds().isEmpty()); } private void checkActiveFileTransferNotifications(final int... expectedFileTransferIds) { final Set<Integer> currentFileTransferIds = notificationService.getCurrentFileTransferIds(); assertEquals(expectedFileTransferIds.length, currentFileTransferIds.size()); for (final Integer expectedFileTransferId : expectedFileTransferIds) { assertTrue(currentFileTransferIds.contains(expectedFileTransferId)); } } private void rejectFileTransfer() { solo.clickOnText("Reject"); // Button in the popup dialog } private void acceptFileTransfer() { solo.clickOnText("Accept"); // Button in the popup dialog } private void checkThatTheDialogIsInFront() { assertFalse(getActivity().isVisible()); // The dialog should be in front of the main chat } private void checkThatTheMainChatIsInFront() { assertTrue(getActivity().isVisible()); // The dialog should be closed, and the main chat in front } private void checkThatTheFilesHaveNotBeenTransferred() { assertFalse(requestedFile.exists()); assertFalse(requestedFile1.exists()); assertFalse(requestedFile2.exists()); } private void checkThatTheFileWasReceivedSuccessfully(final File file) throws IOException { assertTrue("Should exist: " + file, file.exists()); final ByteSource originalFile = Files.asByteSource(image.getFile()); final ByteSource savedFile = Files.asByteSource(file); assertTrue(originalFile.contentEquals(savedFile)); } }