1/*
2 * Copyright (C) 2008 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.mms.ui;
18
19import com.android.mms.R;
20import com.android.mms.ui.ComposeMessageActivity;
21import com.android.mms.ui.RecipientsEditor;
22import com.android.mms.data.ContactList;
23import com.android.mms.data.Conversation;
24import com.android.mms.data.WorkingMessage;
25import com.android.mms.ui.MessageListAdapter.ColumnsMap;
26
27import android.content.Context;
28import android.database.Cursor;
29import android.test.ActivityInstrumentationTestCase2;
30import android.test.suitebuilder.annotation.MediumTest;
31import android.test.suitebuilder.annotation.SmallTest;
32import android.test.suitebuilder.annotation.LargeTest;
33import android.util.Log;
34import android.view.View;
35import android.view.ViewStub;
36import android.widget.EditText;
37import android.widget.TextView;
38import android.widget.Button;
39import android.widget.ImageButton;
40
41/**
42 * Various instrumentation tests for ComposeMessageActivity.
43 */
44public class ComposeMessageActivityTests
45    extends ActivityInstrumentationTestCase2<ComposeMessageActivity> {
46
47    private static final String TAG = "ComposeMessageActivityTests";
48    private Context mContext;
49    private RecipientsEditor mRecipientsEditor;
50    private EditText mTextEditor;
51    private MessageListView mMsgListView;
52    private MessageListAdapter mMsgListAdapter;
53    private ColumnsMap mColumnsMap;
54    private ComposeMessageActivity mActivity;
55
56    public ComposeMessageActivityTests() {
57        super(ComposeMessageActivity.class);
58    }
59
60    @Override
61    protected void setUp() throws Exception {
62        super.setUp();
63        mContext = getInstrumentation().getTargetContext();
64
65        mActivity = getActivity();
66
67        ViewStub stub = (ViewStub)mActivity.findViewById(R.id.recipients_editor_stub);
68        if (stub != null) {
69            View stubView = stub.inflate();
70            mRecipientsEditor = (RecipientsEditor) stubView.findViewById(R.id.recipients_editor);
71        } else {
72            mRecipientsEditor = (RecipientsEditor)mActivity.findViewById(R.id.recipients_editor);
73            mRecipientsEditor.setVisibility(View.VISIBLE);
74        }
75        mTextEditor = (EditText)mActivity.findViewById(R.id.embedded_text_editor);
76        mMsgListView = (MessageListView)mActivity.findViewById(R.id.history);
77        mMsgListAdapter = (MessageListAdapter)mMsgListView.getAdapter();
78    }
79
80    class BoxChecker {
81        private int[] mExpectedBoxStates;
82        private boolean mDone;
83        private String mError;
84
85        public BoxChecker(int[] expectedBoxStates) {
86            mExpectedBoxStates = expectedBoxStates;
87            mDone = false;
88            mError = null;
89            mMsgListAdapter.setOnDataSetChangedListener(mDataSetChangedListener);
90        }
91
92        private final MessageListAdapter.OnDataSetChangedListener
93        mDataSetChangedListener = new MessageListAdapter.OnDataSetChangedListener() {
94            public void onDataSetChanged(MessageListAdapter adapter) {
95                int count = adapter.getCount();
96                if (count > 0) {
97                    MessageItem item = getMessageItem(count - 1);   // get most recent
98
99                    int boxId = item.getBoxId();
100
101                    // is boxId a valid box?
102                    boolean found = false;
103                    boolean isLast = false;
104                    for (int i = 0; i < mExpectedBoxStates.length; i++) {
105                        if (mExpectedBoxStates[i] == boxId) {
106                            found = true;
107                            isLast = i == mExpectedBoxStates.length - 1;
108                            break;
109                        }
110                    }
111                    if (!found) {
112                        setError("Unexpected box state");
113                        return;
114                    }
115                    if (isLast) {
116                        mDone = true;
117                    }
118               }
119            }
120
121            public void onContentChanged(MessageListAdapter adapter) {
122            }
123        };
124
125        private void setError(String error) {
126            mError = error;
127            mDone = true;
128        }
129
130        public String getError() {
131            return mError;
132        }
133
134        public boolean isDone() {
135            return mDone;
136        }
137
138        private MessageItem getMessageItem(int index) {
139            Cursor cursor = (Cursor)mMsgListAdapter.getItem(index);
140
141            mColumnsMap = new MessageListAdapter.ColumnsMap(cursor);
142            String type = cursor.getString(mColumnsMap.mColumnMsgType);
143            long msgId = cursor.getLong(mColumnsMap.mColumnMsgId);
144
145            MessageItem msgItem = mMsgListAdapter.getCachedMessageItem(type, msgId, cursor);
146
147            return msgItem;
148        }
149}
150
151    /**
152     * Tests that a simple SMS message is successfully sent.
153     */
154    @LargeTest
155    public void testSendMessage() throws Throwable {
156        runTestOnUiThread(new Runnable() {
157            public void run() {
158                checkFocused(mRecipientsEditor);
159                mRecipientsEditor.setText("2012130903");
160                mTextEditor.setText("This is a test message");
161                ImageButton send = (ImageButton)mActivity.findViewById(R.id.send_button_sms);
162                send.performClick();
163            }
164        });
165
166        // Now poll while watching the adapter to see if the message got sent
167        BoxChecker boxChecker = new BoxChecker(new int[] {4, 2});    // outbox, sent
168        long now = System.currentTimeMillis();
169        boolean success = true;
170        while (!boxChecker.isDone()) {
171            Thread.sleep(1000);
172            if (System.currentTimeMillis() - now > 10000) {
173                // Give up after ten seconds
174                success = false;
175                break;
176            }
177        }
178        assertTrue(success && boxChecker.getError() == null);
179    }
180
181    /**
182     * Helper method to verify which field has the focus
183     * @param focused The view that should be focused (all others should not have focus)
184     */
185    @SmallTest
186    private void checkFocused(View focused) {
187        assertEquals(focused == mRecipientsEditor, mRecipientsEditor.isFocused());
188        assertEquals(focused == mTextEditor, mTextEditor.isFocused());
189    }
190
191    // Here's how to execute just this one test:
192    //   runtest -m testCreateManyThreads mms -c com.android.mms.ui.ComposeMessageActivityTests
193    // This test intentionally uses the UI functions to create the threads rather than adding
194    // the threads directly to the mms provider's threads table.
195    @LargeTest
196    public void testCreateManyThreads() {
197        for (int i = 0; i < 10; i++) {
198            String phoneNum = String.format("424-123-%04d", i);
199            ContactList contactList = ContactList.getByNumbers(phoneNum, false, false);
200            Conversation conv = Conversation.get(mActivity, contactList, false);
201
202            WorkingMessage workingMsg = WorkingMessage.loadDraft(mActivity, conv);
203            workingMsg.setConversation(conv);
204            workingMsg.setText("This is test #" + i + " thread id: " + conv.getThreadId());
205
206//            Log.i(TAG, "[testCreateManyThreads] workingMsg: ");
207//            workingMsg.dump();
208
209            workingMsg.saveDraft(false);
210        }
211    }
212}
213