Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31e104f8 authored by Steve McKay's avatar Steve McKay
Browse files

Add DownloadsActivity functional test.

Bug: 25809806
Change-Id: I43ceaf3a99715a57e3d349bee60f2edf7f6666bd
parent 0fd6eb4d
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -260,8 +260,7 @@ public abstract class BaseActivity extends Activity {
        } else if (id == R.id.menu_settings) {
            final RootInfo root = getCurrentRoot();
            final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
            intent.setDataAndType(DocumentsContract.buildRootUri(root.authority, root.rootId),
                    DocumentsContract.Root.MIME_TYPE_ITEM);
            intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
            startActivity(intent);
            return true;
        }
+11 −5
Original line number Diff line number Diff line
@@ -23,8 +23,10 @@ import static com.android.documentsui.model.DocumentInfo.getCursorString;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.text.TextUtils;

@@ -195,6 +197,10 @@ public class RootInfo implements Durable, Parcelable {
        }
    }

    public Uri getUri() {
        return DocumentsContract.buildRootUri(authority, rootId);
    }

    public boolean isRecents() {
        return authority == null && rootId == null;
    }
@@ -238,11 +244,6 @@ public class RootInfo implements Durable, Parcelable {
                || derivedType == TYPE_RECENTS || derivedType == TYPE_DOWNLOADS;
    }

    @Override
    public String toString() {
        return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
    }

    public Drawable loadIcon(Context context) {
        if (derivedIcon != 0) {
            return context.getDrawable(derivedIcon);
@@ -283,6 +284,11 @@ public class RootInfo implements Durable, Parcelable {
        return Objects.hash(authority, rootId);
    }

    @Override
    public String toString() {
        return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
    }

    public String getDirectoryString() {
        return !TextUtils.isEmpty(summary) ? summary : title;
    }
+154 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.documentsui;

import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
import static com.android.documentsui.StubProvider.ROOT_0_ID;

import android.app.Instrumentation;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Configurator;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import android.view.MotionEvent;

import com.android.documentsui.model.RootInfo;

@LargeTest
public class DownloadsActivityUiTest extends InstrumentationTestCase {

    private static final int TIMEOUT = 5000;
    private static final String TAG = "DownloadsActivityUiTest";
    private static final String TARGET_PKG = "com.android.documentsui";
    private static final String LAUNCHER_PKG = "com.android.launcher";

    private UiBot mBot;
    private UiDevice mDevice;
    private Context mContext;
    private ContentResolver mResolver;
    private DocumentsProviderHelper mDocsHelper;
    private ContentProviderClient mClient;
    private RootInfo mRoot;

    public void setUp() throws Exception {
        // Initialize UiDevice instance.
        Instrumentation instrumentation = getInstrumentation();

        mDevice = UiDevice.getInstance(instrumentation);

        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);

        // Start from the home screen.
        mDevice.pressHome();
        mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), TIMEOUT);

        // NOTE: Must be the "target" context, else security checks in content provider will fail.
        mContext = instrumentation.getTargetContext();
        mResolver = mContext.getContentResolver();

        mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
        mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);

        mRoot = mDocsHelper.getRoot(ROOT_0_ID);

        // Open the Downloads activity on our stub provider root.
        Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_ROOT);
        intent.setDataAndType(mRoot.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        mContext.startActivity(intent);

        // Wait for the app to appear.
        mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), TIMEOUT);
        mDevice.waitForIdle();

        mBot = new UiBot(mDevice, TIMEOUT);

        resetStorage();  // Just in case a test failed and tearDown didn't happen.
    }

    @Override
    protected void tearDown() throws Exception {
        // Need to kill off the task we started.
        super.tearDown();
        Log.d(TAG, "Resetting storage from setUp");
        resetStorage();
        mClient.release();
    }

    private void resetStorage() throws RemoteException {
        mClient.call("clear", null, null);
        // TODO: Would be nice to have an event to wait on here.
        mDevice.waitForIdle();
    }

    private void initTestFiles() throws RemoteException {
        mDocsHelper.createDocument(mRoot, "text/plain", "file0.log");
        mDocsHelper.createDocument(mRoot, "image/png", "file1.png");
        mDocsHelper.createDocument(mRoot, "text/csv", "file2.csv");
    }

    public void testWindowTitle() throws Exception {
        initTestFiles();

        mBot.assertWindowTitle(ROOT_0_ID);
    }

    public void testFilesListed() throws Exception {
        initTestFiles();

        mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
    }

    public void testFilesList_LiveUpdate() throws Exception {
        initTestFiles();

        mDocsHelper.createDocument(mRoot, "yummers/sandwich", "Ham & Cheese.sandwich");
        mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
    }

    public void testDeleteDocument() throws Exception {
        initTestFiles();

        mBot.clickDocument("file1.png");
        mDevice.waitForIdle();
        mBot.menuDelete().click();

        mBot.waitForDeleteSnackbar();
        assertFalse(mBot.hasDocuments("file1.png"));

        mBot.waitForDeleteSnackbarGone();
        assertFalse(mBot.hasDocuments("file1.png"));
    }

    public void testSupportsShare() throws Exception {
        initTestFiles();

        mBot.clickDocument("file1.png");
        mDevice.waitForIdle();
        assertNotNull(mBot.menuShare());
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -225,6 +225,12 @@ public class StubProvider extends DocumentsProvider {
                null, false);
    }

    @Override
    public Cursor queryChildDocumentsForManage(String parentDocumentId, String[] projection,
            String sortOrder) throws FileNotFoundException {
        return queryChildDocuments(parentDocumentId, projection, sortOrder);
    }

    @Override
    public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder)
            throws FileNotFoundException {
+4 −0
Original line number Diff line number Diff line
@@ -179,6 +179,10 @@ class UiBot {
        return find(By.res("com.android.documentsui:id/menu_delete"));
    }

    UiObject2 menuShare() {
        return find(By.res("com.android.documentsui:id/menu_share"));
    }

    private UiObject2 find(BySelector selector) {
        mDevice.wait(Until.findObject(selector), mTimeout);
        return mDevice.findObject(selector);