1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser.tests.utils;
18
19import android.content.ContentProvider;
20import android.content.Context;
21import android.content.SharedPreferences;
22import android.content.res.Resources;
23import android.database.ContentObserver;
24import android.net.Uri;
25import android.test.AndroidTestCase;
26import android.test.IsolatedContext;
27import android.test.RenamingDelegatingContext;
28import android.test.mock.MockContext;
29
30import java.io.File;
31
32/**
33 * Replacement for ProviderTestCase2 that keeps calls to ContentResolver.notifyChanged
34 * internal to observers registered with ProviderTestCase3.registerContentObserver
35 */
36public abstract class ProviderTestCase3<T extends ContentProvider> extends AndroidTestCase {
37
38    public static final String FILENAME_PREFIX = "test.";
39
40    Class<T> mProviderClass;
41    String[] mProviderAuthority;
42
43    private IsolatedContext mProviderContext;
44    private MockContentResolver2 mResolver;
45
46    private class MockContext2 extends MockContext {
47
48        @Override
49        public Resources getResources() {
50            return getContext().getResources();
51        }
52
53        @Override
54        public File getDir(String name, int mode) {
55            // name the directory so the directory will be separated from
56            // one created through the regular Context
57            return getContext().getDir("mockcontext2_" + name, mode);
58        }
59
60        @Override
61        public String getPackageName() {
62            return getContext().getPackageName();
63        }
64
65        @Override
66        public SharedPreferences getSharedPreferences(String name, int mode) {
67            return getContext().getSharedPreferences("mockcontext2_" + name, mode);
68        }
69
70        @Override
71        public Context getApplicationContext() {
72            return this;
73        }
74
75        @Override
76        public Object getSystemService(String name) {
77            return null;
78        }
79    }
80    /**
81     * Constructor.
82     *
83     * @param providerClass The class name of the provider under test
84     * @param providerAuthorities The provider's authority string
85     */
86    public ProviderTestCase3(Class<T> providerClass, String... providerAuthorities) {
87        mProviderClass = providerClass;
88        mProviderAuthority = providerAuthorities;
89    }
90
91    private T mProvider;
92
93    /**
94     * Returns the content provider created by this class in the {@link #setUp()} method.
95     * @return T An instance of the provider class given as a parameter to the test case class.
96     */
97    public T getProvider() {
98        return mProvider;
99    }
100
101    /**
102     * Sets up the environment for the test fixture.
103     * <p>
104     * Creates a new
105     * {@link com.android.browser.tests.utils.MockContentResolver2}, a new IsolatedContext
106     * that isolates the provider's file operations, and a new instance of
107     * the provider under test within the isolated environment.
108     * </p>
109     *
110     * @throws Exception
111     */
112    @Override
113    protected void setUp() throws Exception {
114        super.setUp();
115
116        mResolver = new MockContentResolver2();
117        RenamingDelegatingContext targetContextWrapper = new
118                RenamingDelegatingContext(
119                new MockContext2(), // The context that most methods are
120                                    //delegated to
121                getContext(), // The context that file methods are delegated to
122                FILENAME_PREFIX);
123        // The default IsolatedContext has a mock AccountManager that doesn't
124        // work for us, so override getSystemService to always return null
125        mProviderContext = new IsolatedContext(mResolver, targetContextWrapper) {
126
127            @Override
128            public Object getSystemService(String name) {
129                return null;
130            }
131        };
132
133        mProvider = mProviderClass.newInstance();
134        mProvider.attachInfo(mProviderContext, null);
135        assertNotNull(mProvider);
136        for (String auth : mProviderAuthority) {
137            mResolver.addProvider(auth, getProvider());
138        }
139    }
140
141    /**
142     * Tears down the environment for the test fixture.
143     * <p>
144     * Calls {@link android.content.ContentProvider#shutdown()} on the
145     * {@link android.content.ContentProvider} represented by mProvider.
146     */
147    @Override
148    protected void tearDown() throws Exception {
149        mProvider.shutdown();
150        super.tearDown();
151    }
152
153    /**
154     * Gets the {@link MockContentResolver2} created by this class during initialization. You
155     * must use the methods of this resolver to access the provider under test.
156     *
157     * @return A {@link MockContentResolver2} instance.
158     */
159    public MockContentResolver2 getMockContentResolver() {
160        return mResolver;
161    }
162
163    /**
164     * Gets the {@link IsolatedContext} created by this class during initialization.
165     * @return The {@link IsolatedContext} instance
166     */
167    public IsolatedContext getMockContext() {
168        return mProviderContext;
169    }
170
171    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
172            ContentObserver observer) {
173        mResolver.safeRegisterContentObserver(uri, notifyForDescendents, observer);
174    }
175
176    public void unregisterContentObserver(ContentObserver observer) {
177        mResolver.safeUnregisterContentObserver(observer);
178    }
179
180}
181