BP2TestCaseHelper.java revision 57e39f9e46091750c8a07895531446a7f0efdb21
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 com.android.browser.provider.BrowserProvider2;
20
21import android.content.ContentValues;
22import android.database.ContentObserver;
23import android.net.Uri;
24import android.provider.Browser;
25import android.provider.BrowserContract;
26import android.provider.BrowserContract.Bookmarks;
27import android.provider.BrowserContract.History;
28import android.util.Log;
29
30/**
31 *  This is a replacement for ProviderTestCase2 that can handle notifyChange testing.
32 *  It also has helper methods specifically for testing BrowserProvider2
33 */
34public abstract class BP2TestCaseHelper extends ProviderTestCase3<BrowserProvider2> {
35
36    // Tag for potential performance impacts
37    private static final String PERFTAG = "BP2-PerfCheck";
38
39    private TriggeredObserver mLegacyObserver;
40    private TriggeredObserver mRootObserver;
41    private TriggeredObserver mBookmarksObserver;
42    private TriggeredObserver mHistoryObserver;
43    private TriggeredObserver mWidgetObserver;
44
45    @Override
46    protected void setUp() throws Exception {
47        super.setUp();
48        mLegacyObserver = new TriggeredObserver(Browser.BOOKMARKS_URI);
49        mRootObserver = new TriggeredObserver(BrowserContract.AUTHORITY_URI);
50        mBookmarksObserver = new TriggeredObserver(Bookmarks.CONTENT_URI);
51        mHistoryObserver = new TriggeredObserver(History.CONTENT_URI);
52        mWidgetObserver = new TriggeredObserver();
53        // We don't need to worry about setting this back to null since this
54        // is a private instance local to the MockContentResolver
55        getProvider().setWidgetObserver(mWidgetObserver);
56    }
57
58    public BP2TestCaseHelper() {
59        super(BrowserProvider2.class,
60                BrowserContract.AUTHORITY, BrowserProvider2.LEGACY_AUTHORITY);
61    }
62
63    public void perfIdeallyUntriggered(TriggeredObserver... obs) {
64        for (TriggeredObserver ob : obs) {
65            if (ob.checkTriggered()) {
66                // Not ideal, unnecessary notification
67                Log.i(PERFTAG, ob.mUri + " onChange called but content unaltered!");
68            }
69        }
70    }
71
72    public void assertObserversTriggered(boolean triggered,
73            TriggeredObserver... observers) {
74        for (TriggeredObserver obs : observers) {
75            assertEquals(obs.mUri + ", descendents:" + obs.mNotifyForDescendents,
76                    triggered, obs.checkTriggered());
77        }
78    }
79
80    public class TriggeredObserver extends ContentObserver {
81        private boolean mTriggered;
82        Uri mUri;
83        boolean mNotifyForDescendents;
84
85        /**
86         * Creates an unmanaged TriggeredObserver
87         */
88        public TriggeredObserver() {
89            super(null);
90        }
91
92        /**
93         * Same as TriggeredObserver(uri, true);
94         */
95        public TriggeredObserver(Uri uri) {
96            this(uri, true);
97        }
98
99        /**
100         * Creates a managed TriggeredObserver that self-registers with the
101         * mock ContentResolver
102         */
103        public TriggeredObserver(Uri uri, boolean notifyForDescendents) {
104            super(null);
105            mUri = uri;
106            mNotifyForDescendents = notifyForDescendents;
107            registerContentObserver(uri, notifyForDescendents, this);
108        }
109
110        @Override
111        public void onChange(boolean selfChange) {
112            super.onChange(selfChange);
113            mTriggered = true;
114        }
115
116        public boolean checkTriggered() {
117            boolean ret = mTriggered;
118            mTriggered = false;
119            return ret;
120        }
121    }
122
123    Uri mockInsert(Uri uri, ContentValues values) {
124        assertObserversTriggered(false, mLegacyObserver, mRootObserver);
125        Uri ret = getMockContentResolver().insert(uri, values);
126        assertObserversTriggered(true, mLegacyObserver, mRootObserver);
127        return ret;
128    }
129
130    int mockUpdate(Uri uri, ContentValues values, String where,
131            String[] selectionArgs) {
132        assertObserversTriggered(false, mLegacyObserver, mRootObserver);
133        int ret = getMockContentResolver().update(uri, values, where, selectionArgs);
134        if (ret > 0) {
135            assertObserversTriggered(true, mLegacyObserver, mRootObserver);
136        } else {
137            perfIdeallyUntriggered(mLegacyObserver);
138            perfIdeallyUntriggered(mRootObserver);
139        }
140        return ret;
141    }
142
143    public Uri insertBookmark(String url, String title) {
144        ContentValues values = new ContentValues();
145        values.put(BrowserContract.Bookmarks.TITLE, title);
146        values.put(BrowserContract.Bookmarks.URL, url);
147        values.put(BrowserContract.Bookmarks.IS_FOLDER, 0);
148        return insertBookmark(values);
149    }
150
151    public Uri insertBookmark(ContentValues values) {
152        assertObserversTriggered(false, mBookmarksObserver, mWidgetObserver);
153        Uri ret = mockInsert(Bookmarks.CONTENT_URI, values);
154        assertObserversTriggered(true, mBookmarksObserver, mWidgetObserver);
155        perfIdeallyUntriggered(mHistoryObserver);
156        return ret;
157    }
158
159    public boolean updateBookmark(Uri uri, String url, String title) {
160        ContentValues values = new ContentValues();
161        values.put(BrowserContract.Bookmarks.TITLE, title);
162        values.put(BrowserContract.Bookmarks.URL, url);
163        return updateBookmark(uri, values);
164    }
165
166    public boolean updateBookmark(Uri uri, ContentValues values) {
167        assertObserversTriggered(false, mBookmarksObserver, mWidgetObserver);
168        int modifyCount = mockUpdate(uri, values, null, null);
169        assertTrue("UpdatedBookmark modified too much! " + uri, modifyCount <= 1);
170        boolean updated = modifyCount == 1;
171        if (updated) {
172            assertObserversTriggered(updated, mBookmarksObserver, mWidgetObserver);
173        } else {
174            perfIdeallyUntriggered(mBookmarksObserver, mWidgetObserver);
175        }
176        perfIdeallyUntriggered(mHistoryObserver);
177        return updated;
178    }
179
180    public Uri insertHistory(String url, String title) {
181        ContentValues values = new ContentValues();
182        values.put(BrowserContract.History.TITLE, title);
183        values.put(BrowserContract.History.URL, url);
184        assertObserversTriggered(false, mHistoryObserver);
185        Uri ret = mockInsert(History.CONTENT_URI, values);
186        assertObserversTriggered(true, mHistoryObserver);
187        perfIdeallyUntriggered(mBookmarksObserver, mWidgetObserver);
188        return ret;
189    }
190
191    public boolean updateHistory(Uri uri, String url, String title) {
192        ContentValues values = new ContentValues();
193        values.put(BrowserContract.History.TITLE, title);
194        values.put(BrowserContract.History.URL, url);
195        return updateHistory(uri, values);
196    }
197
198    public boolean updateHistory(Uri uri, ContentValues values) {
199        assertObserversTriggered(false, mHistoryObserver);
200        int modifyCount = mockUpdate(uri, values, null, null);
201        assertTrue("UpdatedHistory modified too much! " + uri, modifyCount <= 1);
202        boolean updated = modifyCount == 1;
203        if (updated) {
204            assertObserversTriggered(updated, mHistoryObserver);
205        } else {
206            perfIdeallyUntriggered(mHistoryObserver);
207        }
208        perfIdeallyUntriggered(mBookmarksObserver, mWidgetObserver);
209        return updated;
210    }
211}
212