com.microsoft.office.integration.test.AbstractTest.java Source code

Java tutorial

Introduction

Here is the source code for com.microsoft.office.integration.test.AbstractTest.java

Source

/**
 * Copyright  Microsoft Open Technologies, Inc.
 *
 * All Rights Reserved
 *
 * 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
 *
 * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
 * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
 * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
 *
 * See the Apache License, Version 2.0 for the specific language
 * governing permissions and limitations under the License.
 */
package com.microsoft.office.integration.test;

import static com.microsoft.office.integration.test.TestRunner.getAuthorityUrl;
import static com.microsoft.office.integration.test.TestRunner.getClientId;
import static com.microsoft.office.integration.test.TestRunner.getPassword;
import static com.microsoft.office.integration.test.TestRunner.getResourceId;
import static com.microsoft.office.integration.test.TestRunner.getRootUrl;
import static com.microsoft.office.integration.test.TestRunner.getUsername;
import static com.microsoft.office.integration.test.TestRunner.getRedirectUrl;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.IOUtils;

import android.app.Activity;
import android.app.Instrumentation.ActivityMonitor;
import android.content.Context;
import android.content.IntentFilter;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;

import com.microsoft.exchange.services.odata.model.Me;
import com.microsoft.office.core.Configuration;
import com.microsoft.office.core.auth.IOfficeCredentials;
import com.microsoft.office.core.auth.OfficeCredentialsImpl;
import com.microsoft.office.core.auth.method.AbstractBasicAuthenticator;
import com.microsoft.office.integration.AbstractOfficeAuthenticator;
import com.microsoft.office.integration.TestActivity;
import com.msopentech.odatajclient.engine.client.ODataClient;
import com.msopentech.odatajclient.engine.client.ODataClientFactory;
import com.msopentech.odatajclient.engine.client.ODataV3Client;
import com.msopentech.odatajclient.engine.client.ODataV4Client;
import com.msopentech.odatajclient.engine.data.ODataEntity;
import com.msopentech.odatajclient.engine.format.ODataFormat;
import com.msopentech.odatajclient.engine.format.ODataPubFormat;
import com.msopentech.odatajclient.proxy.api.AsyncCall;
import com.msopentech.odatajclient.proxy.api.EntityContainerFactory;

public class AbstractTest extends ActivityInstrumentationTestCase2<TestActivity> {
    private static final String ENTER_PASSWORD_COMMAND = "javascript: document.getElementById('cred_password_inputtext').value = '%s';";
    private static final String SEND_AUTHENTICATION_REQUEST_COMMAND = "Post.SubmitCreds();";

    private static final long WAIT_ADAL_ACTIVITY_TIMEOUT = 30 * 1000;
    private static final long WAIT_OPEN_DIALOG_TIMEOUT = 20 * 1000;
    private static final long WAIT_CLOSE_DIALOG_TIMEOUT = 3 * 60 * 1000;
    private static final long SMALL_DELAY = 250;

    protected static ODataV3Client v3Client;

    protected static ODataV4Client v4Client;

    private static Semaphore sAvailable = new Semaphore(0);

    /** Flag indicating if current test execution is the first for this session or not. */
    private static boolean wasStarted = false;

    /** Message for fatal error. null means there are no fatal errors. */
    private static String fatalErrorMessage = null;

    Activity mainActivity = null;
    Activity adalActivity = null;
    ActivityMonitor activityMonitor = null;

    String windowManagerString = null;
    Class<?> windowManager = null;

    public AbstractTest() {
        super(TestActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        if (fatalErrorMessage != null) {
            fail(fatalErrorMessage);
        }

        if (wasStarted) {
            return;
        }

        super.setUp();

        prepare();

        // Sets authenticator
        Configuration.setServerBaseUrl(getRootUrl());
        switch (TestRunner.getAuthType()) {
        case BASIC:
            Configuration.setAuthenticator(new AbstractBasicAuthenticator() {
                protected String getUsername() {
                    return TestRunner.getUsername();
                }

                protected String getPassword() {
                    return TestRunner.getPassword();
                }
            });
            break;
        case AAD:
            AbstractOfficeAuthenticator officeAuthenticator = new AbstractOfficeAuthenticator() {
                @Override
                protected IOfficeCredentials getCredentials() {
                    OfficeCredentialsImpl creds = new OfficeCredentialsImpl(getAuthorityUrl(), getClientId(),
                            getResourceId(), getRedirectUrl());
                    creds.setUserHint(getUsername());
                    return creds;
                }

                @Override
                protected Activity getActivity() {
                    return mainActivity;
                }

                @Override
                public void onDone(String result) {
                    super.onDone(result);
                    sAvailable.release();
                }

                @Override
                public void onError(Throwable error) {
                    super.onError(error);
                    // FIXME assert fail on it.
                }
            };
            TestActivity.setOfficeAuthenticator(officeAuthenticator);
            Configuration.setAuthenticator(officeAuthenticator);
            if (TestRunner.getAuthType() == AuthType.AAD) {
                final Future<Void> emails = new AsyncCall<Void>(ODataClientFactory.getV4().getConfiguration()) {
                    @Override
                    public Void call() {
                        Me.getDrafts();
                        return null;
                    }
                };
                Thread th = new Thread(new Runnable() {

                    public void run() {
                        try {
                            emails.get(120, TimeUnit.SECONDS);
                        } catch (Exception e) {
                            fail(e.toString());
                        }
                    }

                });
                th.start();
                try {
                    if (!waitForAdalActivity(WAIT_ADAL_ACTIVITY_TIMEOUT)) {
                        fatalErrorMessage = "Adal activity not opened";
                        fail(fatalErrorMessage);
                    }
                    // In case when adal authorized on this devices spinner isn't displayed.
                    if (waitForDialogToOpen(WAIT_OPEN_DIALOG_TIMEOUT)) {
                        if (!waitForDialogToClose(WAIT_CLOSE_DIALOG_TIMEOUT)) {
                            fatalErrorMessage = "Adal activity not opened";
                            fail(fatalErrorMessage);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                final WebView webView = getWebView(adalActivity.getWindow().getDecorView().getRootView());
                assertNotNull(webView);
                mainActivity.runOnUiThread(new Runnable() {
                    public void run() {
                        webView.loadUrl(String.format(ENTER_PASSWORD_COMMAND, getPassword())
                                + SEND_AUTHENTICATION_REQUEST_COMMAND);
                    }
                });

                sAvailable.acquire();
            }
            break;
        default:
            fatalErrorMessage = "Unknown auth.";
            fail(fatalErrorMessage);
            break;
        }
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
        EntityContainerFactory.getContext().detachAll();
    }

    private void prepare() {
        wasStarted = true;

        // Sets field name for reflection to work with various android version.
        if (android.os.Build.VERSION.SDK_INT >= 17) {
            windowManagerString = "sDefaultWindowManager";
        } else if (android.os.Build.VERSION.SDK_INT >= 13) {
            windowManagerString = "sWindowManager";
        } else {
            windowManagerString = "mWindowManager";
        }

        // Prepare reflection specific window manager for various android version.
        String windowManagerClassName;
        if (android.os.Build.VERSION.SDK_INT >= 17) {
            windowManagerClassName = "android.view.WindowManagerGlobal";
        } else {
            windowManagerClassName = "android.view.WindowManagerImpl";
        }
        try {
            windowManager = Class.forName(windowManagerClassName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Set up odata clients.
        v3Client = ODataClientFactory.getV3();
        v4Client = ODataClientFactory.getV4();

        // Initialize activity monitor.
        activityMonitor = new ActivityMonitor((IntentFilter) null, null, false);
        getInstrumentation().addMonitor(activityMonitor);

        // Start and check main test activity.
        mainActivity = getActivity();
        assertNotNull(mainActivity);
    }

    private boolean waitForAdalActivity(long timeout) {
        final long endTime = SystemClock.uptimeMillis() + timeout;

        while (SystemClock.uptimeMillis() < endTime) {
            Activity activity = activityMonitor.getLastActivity();
            // Wait for authentication activity (not the test activity).
            if ((activity != null) && !(activity instanceof TestActivity)) {
                adalActivity = activity;
                return true;
            }
            try {
                Thread.sleep(SMALL_DELAY);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        adalActivity = null;
        return false;
    }

    public boolean waitForDialogToClose(long timeout) {
        final long endTime = SystemClock.uptimeMillis() + timeout;

        while (SystemClock.uptimeMillis() < endTime) {
            if (!isDialogOpen()) {
                return true;
            }
            try {
                Thread.sleep(SMALL_DELAY);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public boolean waitForDialogToOpen(long timeout) {
        final long endTime = SystemClock.uptimeMillis() + timeout;

        if (isDialogOpen()) {
            return true;
        }

        while (SystemClock.uptimeMillis() < endTime) {

            if (isDialogOpen()) {
                return true;
            }
            try {
                Thread.sleep(SMALL_DELAY);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private WebView getWebView(View rootView) {
        if (rootView instanceof WebView) {
            return (WebView) rootView;
        } else if (rootView instanceof ViewGroup) {
            ViewGroup rootViewGroup = (ViewGroup) rootView;
            for (int i = 0; i < rootViewGroup.getChildCount(); i++) {
                View view = getWebView(rootViewGroup.getChildAt(i));
                if (view != null) {
                    return (WebView) view;
                }
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    private View[] getWindowDecorViews() {
        try {
            Field viewsField = windowManager.getDeclaredField("mViews");
            Field instanceField = windowManager.getDeclaredField(windowManagerString);
            viewsField.setAccessible(true);
            instanceField.setAccessible(true);
            Object instance = instanceField.get(null);
            if (android.os.Build.VERSION.SDK_INT >= 19) {
                return ((ArrayList<View>) viewsField.get(instance)).toArray(new View[0]);
            } else {
                return (View[]) viewsField.get(instance);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private boolean isDialog(Activity activity, View decorView) {
        if (decorView == null || !decorView.isShown()) {
            return false;
        }
        Context viewContext = null;
        if (decorView != null) {
            viewContext = decorView.getContext();
        }

        if (viewContext instanceof ContextThemeWrapper) {
            ContextThemeWrapper ctw = (ContextThemeWrapper) viewContext;
            viewContext = ctw.getBaseContext();
        }
        Context activityContext = activity;
        Context activityBaseContext = activity.getBaseContext();
        return (activityContext.equals(viewContext) || activityBaseContext.equals(viewContext))
                && (decorView != activity.getWindow().getDecorView());
    }

    private boolean isDialogOpen() {
        View[] views = getWindowDecorViews();
        for (View v : views) {
            if (isDialog(adalActivity, v)) {
                return true;
            }
        }
        return false;
    }

    protected ODataClient getClient() {
        return v4Client;
    }

    protected ODataEntity getEntityFromResource(String resourceFileName) {
        try {
            InputStream input = getInstrumentation().getContext().getAssets().open(resourceFileName);
            return getClient().getBinder().getODataEntity(getClient().getDeserializer().toEntry(input,
                    getClient().getResourceFactory().entryClassForFormat(ODataPubFormat.JSON)));
        } catch (Exception e) {
            return null;
        }
    }

    protected byte[] getImageInByteFromResource(String path) {
        InputStream input = null;
        try {
            input = getInstrumentation().getContext().getAssets().open(path);
            return IOUtils.toByteArray(input);
        } catch (Exception e) {
            return null;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (Exception ignore) {
                }
            }
        }
    }

    protected static void assertArrayEquals(byte[] expected, byte[] actual) {
        assertTrue(Arrays.equals(expected, actual));
    }

    protected String getSuffix(final ODataPubFormat format) {
        return format == ODataPubFormat.ATOM ? "xml" : "json";
    }

    protected String getSuffix(final ODataFormat format) {
        return format == ODataFormat.XML ? "xml" : "json";
    }
}