175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting/*
275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * Copyright (C) 2012 The Android Open Source Project
375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting *
475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * Licensed under the Apache License, Version 2.0 (the "License"); you may not
575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * use this file except in compliance with the License. You may obtain a copy of
675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * the License at
775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting *
875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * http://www.apache.org/licenses/LICENSE-2.0
975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting *
1075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * Unless required by applicable law or agreed to in writing, software
1175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * License for the specific language governing permissions and limitations under
1475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * the License.
1575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting */
1675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
1775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingpackage com.android.calendar;
1875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
1975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.content.ContentResolver;
2075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.content.ContentValues;
2175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.content.Context;
2275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.content.SharedPreferences;
2375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.content.res.Resources;
2475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.database.Cursor;
2575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.net.Uri;
2675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.os.Bundle;
2775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.test.mock.MockContentProvider;
2875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.test.mock.MockContentResolver;
2975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.test.mock.MockContext;
3075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport android.test.mock.MockCursor;
3175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
3275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport java.util.ArrayList;
3375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingimport java.util.List;
3475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
3575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting/**
3675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * A helper class for creating and wiring fake implementations of db classes, like
3775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting * Context, ContentResolver, ContentProvider, etc.  Typical setup will look something like:
3875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting *      DbUtils dbUtils = new DbUtils(mockResources);
3975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting *      dbUtils.getContentResolver().addProvider("settings", dbUtils.getContentProvider());
4075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting *      dbUtils.getContentResolver().addProvider(CalendarCache.URI.getAuthority(),
4175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting *            dbUtils.getContentProvider());
4275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting */
4375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Tingclass DbTestUtils {
4475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    private final MockContentResolver contentResolver;
4575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    private final FakeContext context;
4675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    private final FakeSharedPreferences sharedPreferences;
4775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    private final FakeContentProvider contentProvider;
4875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
4975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    class FakeContext extends MockContext {
5075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        private ContentResolver contentResolver;
5175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        private Resources resources;
5275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        private SharedPreferences sharedPreferences;
5375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
5475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        FakeContext(ContentResolver contentResolver, Resources resources) {
5575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            this.contentResolver = contentResolver;
5675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            this.resources = resources;
5775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
5875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
5975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
6075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public ContentResolver getContentResolver() {
6175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return contentResolver;
6275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
6375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
6475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
6575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public Resources getResources() {
6675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return resources;
6775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
6875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
6975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public void setSharedPreferences(SharedPreferences sharedPreferences) {
7075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            this.sharedPreferences = sharedPreferences;
7175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
7275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
7375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
7475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public SharedPreferences getSharedPreferences(String name, int mode) {
7575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            if (sharedPreferences != null) {
7675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting                return sharedPreferences;
7775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            } else {
7875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting                return super.getSharedPreferences(name, mode);
7975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            }
8075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
8175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
8275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
8375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    // TODO: finish fake implementation.
8475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    static class FakeCursor extends MockCursor {
8575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        private List<String> queryResult;
8675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        int mCurrentPosition = -1;
8775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
8875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        FakeCursor(List<String> queryResult) {
8975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            this.queryResult = queryResult;
9075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
9175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
9275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
9375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public int getCount() {
9475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return queryResult.size();
9575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
9675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
9775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
9875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public boolean moveToFirst() {
9975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            mCurrentPosition = 0;
10075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return true;
10175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
10275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
10375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
10475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public boolean moveToNext() {
10575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            if (queryResult.size() > 0 && mCurrentPosition < queryResult.size()) {
10675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting                mCurrentPosition++;
10775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting                return true;
10875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            } else {
10975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting                return false;
11075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            }
11175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
11275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
11375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
11475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public boolean isBeforeFirst() {
11575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return mCurrentPosition < 0;
11675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
11775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
11875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
11975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public String getString(int columnIndex) {
12075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return queryResult.get(columnIndex);
12175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
12275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
12375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
12475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public void close() {
12575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
12675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
12775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
12875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    // TODO: finish implementation, perhaps using an in-memory table
12975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    static class FakeContentProvider extends MockContentProvider {
13075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        private ArrayList<String> queryResult = null;
13175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
13275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public FakeContentProvider(Context context) {
13375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            super(context);
13475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
13575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
13675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
13775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public Bundle call(String method, String request, Bundle args) {
13875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return null;
13975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
14075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
14175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
14275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
14375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            // TODO: not currently implemented
14475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return 1;
14575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
14675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
14775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        /**
14875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting         * Set the mocked results to return from a query call.
14975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting         */
15075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public void setQueryResult(ArrayList<String> result) {
15175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            this.queryResult = result;
15275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
15375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
15475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
15575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public final Cursor query(Uri uri, String[] projection, String selection,
15675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting                String[] selectionArgs, String orderBy) {
15775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            ArrayList<String> result = (queryResult == null) ?
15875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting                    new ArrayList<String>() : queryResult;
15975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return new FakeCursor(result);
16075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
16175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
16275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
16375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public String getType(Uri uri) {
16475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return null;
16575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
16675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
16775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        @Override
16875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        public boolean onCreate() {
16975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting            return false;
17075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        }
17175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
17275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
17375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    public DbTestUtils(Resources resources) {
17475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        this.contentResolver = new MockContentResolver();
17575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        this.context = new FakeContext(contentResolver, resources);
17675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        this.sharedPreferences = new FakeSharedPreferences();
17775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        this.contentProvider = new FakeContentProvider(context);
17875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        context.setSharedPreferences(sharedPreferences);
17975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
18075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
18175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    public MockContentResolver getContentResolver() {
18275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        return contentResolver;
18375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
18475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
18575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    public FakeContext getContext() {
18675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        return context;
18775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
18875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
18975f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    public FakeContentProvider getContentProvider() {
19075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        return contentProvider;
19175f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
19275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting
19375f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    public FakeSharedPreferences getMockSharedPreferences() {
19475f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting        return sharedPreferences;
19575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting    }
19675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting}
197