1 /* 2 * Copyright (C) 2015 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 17 package com.android.messaging.datamodel.action; 18 19 import android.os.Bundle; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 23 import androidx.test.filters.MediumTest; 24 import androidx.test.filters.SmallTest; 25 26 import com.android.messaging.BugleTestCase; 27 import com.android.messaging.FakeFactory; 28 import com.android.messaging.datamodel.DataModelImpl; 29 import com.android.messaging.datamodel.action.ActionTestHelpers.StubChatActionMonitor; 30 31 import java.util.ArrayList; 32 33 @MediumTest 34 public class ActionTest extends BugleTestCase { 35 private static final String parameter = "parameter"; 36 private static final Object executeActionResult = "executeActionResult"; 37 private static final Object processResponseResult = "processResponseResult"; 38 private static final Object processFailureResult = "processFailureResult"; 39 40 private static final String mActionKey = "TheActionKey"; 41 private static final Object mData = "PrivateData"; 42 private StubChatActionMonitor mMonitor; 43 private TestChatAction mAction; 44 45 private ArrayList<StubChatActionMonitor.StateTransition> mTransitions; 46 47 @Override setUp()48 public void setUp() throws Exception { 49 super.setUp(); 50 FakeFactory.register(getTestContext()) 51 .withDataModel(new DataModelImpl(getContext())); 52 53 mMonitor = new StubChatActionMonitor(ActionMonitor.STATE_CREATED, mActionKey, 54 mData); 55 mAction = new TestChatAction(mActionKey, parameter); 56 mTransitions = mMonitor.getTransitions(); 57 } 58 verifyState(final int count, final int from, final int to)59 private void verifyState(final int count, final int from, final int to) { 60 assertEquals(to, mMonitor.getState()); 61 assertEquals(mTransitions.size(), count); 62 verifyTransition(count-1, from , to); 63 } 64 verifyTransition(final int index, final int from, final int to)65 private void verifyTransition(final int index, final int from, final int to) { 66 assertTrue(mTransitions.size() > index); 67 assertEquals(mAction, mTransitions.get(index).action); 68 assertEquals(from, mTransitions.get(index).from); 69 assertEquals(to, mTransitions.get(index).to); 70 } 71 72 @SmallTest testActionStartTransitionsCorrectly()73 public void testActionStartTransitionsCorrectly() { 74 mMonitor.setState(ActionMonitor.STATE_CREATED); 75 76 ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor); 77 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 78 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 79 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 80 81 mAction.markStart(); 82 assertEquals("After start state: STATE_QUEUED", ActionMonitor.STATE_QUEUED, 83 mMonitor.getState()); 84 verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED); 85 86 ActionMonitor.unregisterActionMonitor(mAction.actionKey, mMonitor); 87 88 assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 89 assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 90 } 91 92 @SmallTest testActionStartAssertsFromIncorrectState()93 public void testActionStartAssertsFromIncorrectState() { 94 mMonitor.setState(ActionMonitor.STATE_UNDEFINED); 95 96 ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor); 97 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 98 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 99 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 100 101 try { 102 mAction.markStart(); 103 fail("Expect assertion when starting from STATE_UNDEFINED"); 104 } catch (final IllegalStateException ex){ 105 } 106 ActionMonitor.unregisterActionMonitor(mAction.actionKey, mMonitor); 107 108 assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 109 assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 110 } 111 testActionTransitionsEndToEndWithRequests()112 public void testActionTransitionsEndToEndWithRequests() { 113 assertEquals("Start state: STATE_CREATED", ActionMonitor.STATE_CREATED, 114 mMonitor.getState()); 115 116 ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor); 117 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 118 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 119 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 120 121 mAction.markStart(); 122 123 verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED); 124 125 mAction.markBeginExecute(); 126 127 verifyState(2, ActionMonitor.STATE_QUEUED, ActionMonitor.STATE_EXECUTING); 128 129 final Object result = mAction.executeAction(); 130 mAction.requestBackgroundWork(); 131 132 assertEquals("Check executeAction result", result, executeActionResult); 133 134 mAction.markEndExecute(result); 135 136 verifyState(3, ActionMonitor.STATE_EXECUTING, 137 ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED); 138 139 mAction.markBackgroundWorkStarting(); 140 141 verifyState(4, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED, 142 ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION); 143 144 mAction.markBackgroundWorkQueued(); 145 146 verifyState(5, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION, 147 ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED); 148 149 mAction.markBackgroundWorkStarting(); 150 151 verifyState(6, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED, 152 ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION); 153 154 final Bundle response = null; 155 156 mAction.markBackgroundCompletionQueued(); 157 158 verifyState(7, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION, 159 ActionMonitor.STATE_BACKGROUND_COMPLETION_QUEUED); 160 161 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 162 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 163 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 164 165 mAction.processBackgroundWorkResponse(response); 166 167 verifyTransition(7, ActionMonitor.STATE_BACKGROUND_COMPLETION_QUEUED, 168 ActionMonitor.STATE_PROCESSING_BACKGROUND_RESPONSE); 169 170 verifyState(9, ActionMonitor.STATE_PROCESSING_BACKGROUND_RESPONSE, 171 ActionMonitor.STATE_COMPLETE); 172 173 assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 174 assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 175 } 176 testActionTransitionsEndToEndFailsRequests()177 public void testActionTransitionsEndToEndFailsRequests() { 178 assertEquals("Start state: STATE_CREATED", ActionMonitor.STATE_CREATED, 179 mMonitor.getState()); 180 181 ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor); 182 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 183 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 184 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 185 186 mAction.markStart(); 187 188 verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED); 189 190 mAction.markBeginExecute(); 191 192 verifyState(2, ActionMonitor.STATE_QUEUED, ActionMonitor.STATE_EXECUTING); 193 194 final Object result = mAction.executeAction(); 195 mAction.requestBackgroundWork(); 196 197 assertEquals("Check executeAction result", result, executeActionResult); 198 199 mAction.markEndExecute(result); 200 201 verifyState(3, ActionMonitor.STATE_EXECUTING, 202 ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED); 203 204 mAction.markBackgroundWorkStarting(); 205 206 verifyState(4, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED, 207 ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION); 208 209 mAction.markBackgroundWorkQueued(); 210 211 verifyState(5, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION, 212 ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED); 213 214 mAction.markBackgroundWorkStarting(); 215 216 verifyState(6, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED, 217 ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION); 218 219 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 220 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 221 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 222 223 mAction.processBackgroundWorkFailure(); 224 225 verifyState(7, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION, 226 ActionMonitor.STATE_COMPLETE); 227 228 assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 229 assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 230 } 231 testActionTransitionsEndToEndNoRequests()232 public void testActionTransitionsEndToEndNoRequests() { 233 assertEquals("Start state: STATE_CREATED", ActionMonitor.STATE_CREATED, 234 mMonitor.getState()); 235 236 ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor); 237 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 238 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 239 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 240 241 mAction.markStart(); 242 243 verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED); 244 245 mAction.markBeginExecute(); 246 247 verifyState(2, ActionMonitor.STATE_QUEUED, ActionMonitor.STATE_EXECUTING); 248 249 final Object result = mAction.executeAction(); 250 251 assertEquals("Check executeAction result", result, executeActionResult); 252 253 assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 254 assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 255 assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor); 256 257 mAction.markEndExecute(result); 258 259 verifyState(3, ActionMonitor.STATE_EXECUTING, 260 ActionMonitor.STATE_COMPLETE); 261 262 assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey)); 263 assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor)); 264 } 265 266 public static class TestChatAction extends Action implements Parcelable { TestChatAction(final String key, final String parameter)267 protected TestChatAction(final String key, final String parameter) { 268 super(key); 269 this.parameter = parameter; 270 } 271 272 public final String parameter; 273 274 /** 275 * Process the action locally - runs on service thread 276 */ 277 @Override executeAction()278 protected Object executeAction() { 279 assertEquals("Check parameter", parameter, ActionTest.parameter); 280 return executeActionResult; 281 } 282 283 /** 284 * Process the response from the server - runs on service thread 285 */ 286 @Override processBackgroundResponse(final Bundle response)287 protected Object processBackgroundResponse(final Bundle response) { 288 assertEquals("Check parameter", parameter, ActionTest.parameter); 289 return processResponseResult; 290 } 291 292 /** 293 * Called in case of failures when sending requests - runs on service thread 294 */ 295 @Override processBackgroundFailure()296 protected Object processBackgroundFailure() { 297 assertEquals("Check parameter", parameter, ActionTest.parameter); 298 return processFailureResult; 299 } 300 TestChatAction(final Parcel in)301 private TestChatAction(final Parcel in) { 302 super(in); 303 parameter = in.readString(); 304 } 305 306 public static final Parcelable.Creator<TestChatAction> CREATOR 307 = new Parcelable.Creator<TestChatAction>() { 308 @Override 309 public TestChatAction createFromParcel(final Parcel in) { 310 return new TestChatAction(in); 311 } 312 313 @Override 314 public TestChatAction[] newArray(final int size) { 315 return new TestChatAction[size]; 316 } 317 }; 318 319 @Override writeToParcel(final Parcel parcel, final int flags)320 public void writeToParcel(final Parcel parcel, final int flags) { 321 writeActionToParcel(parcel, flags); 322 parcel.writeString(parameter); 323 } 324 } 325 } 326