1 /*
2  * Copyright (C) 2019 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 package com.android.customization.model.clock;
17 
18 import static junit.framework.TestCase.fail;
19 
20 import static org.junit.Assert.assertEquals;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.when;
23 
24 import android.content.ContentResolver;
25 import android.provider.Settings.Secure;
26 
27 import androidx.annotation.Nullable;
28 
29 import com.android.customization.model.CustomizationManager.Callback;
30 import com.android.customization.module.ThemesUserEventLogger;
31 
32 import org.json.JSONException;
33 import org.json.JSONObject;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.mockito.Mock;
38 import org.mockito.MockitoAnnotations;
39 import org.robolectric.RobolectricTestRunner;
40 import org.robolectric.RuntimeEnvironment;
41 
42 @RunWith(RobolectricTestRunner.class)
43 public class ClockManagerTest {
44 
45     private static final String CLOCK_ID = "id";
46     private static final String CLOCK_FIELD = "clock";
47     private static final String CLOCK_FACE_SETTING = "fake_clock_face_setting";
48 
49     @Mock ClockProvider mProvider;
50     @Mock ThemesUserEventLogger mLogger;
51     private ContentResolver mContentResolver;
52     private ClockManager mManager;
53     @Mock private Clockface mMockClockface;
54     @Mock private Callback mMockCallback;
55 
56     @Before
setUp()57     public void setUp() {
58         MockitoAnnotations.initMocks(this);
59         mContentResolver = RuntimeEnvironment.application.getContentResolver();
60         mManager = new ClockManager(mContentResolver, mProvider, mLogger);
61     }
62 
63     @Test
testApply()64     public void testApply() throws JSONException {
65         Clockface clock = new Clockface.Builder().setId(CLOCK_ID).build();
66 
67         mManager.apply(clock, new Callback() {
68             @Override
69             public void onSuccess() {
70                 //Nothing to do here, the test passed
71             }
72 
73             @Override
74             public void onError(@Nullable Throwable throwable) {
75                 fail("onError was called when grid had been applied successfully");
76             }
77         });
78 
79         // THEN the clock id is written to secure settings.
80         JSONObject json =
81                 new JSONObject(Secure.getString(mContentResolver, ClockManager.CLOCK_FACE_SETTING));
82         assertEquals(CLOCK_ID, json.getString(CLOCK_FIELD));
83         // AND the event is logged
84         verify(mLogger).logClockApplied(clock);
85     }
86 
87     @Test
testApply_whenJSONExceptionOccurs_callsOnError()88     public void testApply_whenJSONExceptionOccurs_callsOnError() {
89         when(mMockClockface.getId()).thenThrow(JSONException.class);
90 
91         mManager.apply(mMockClockface, mMockCallback);
92 
93         verify(mMockCallback).onError(null);
94     }
95 
96     @Test
testGetCurrentClock_returnsClockId()97     public void testGetCurrentClock_returnsClockId() throws JSONException {
98         // Secure settings contains a clock id
99         JSONObject json = new JSONObject().put(CLOCK_FIELD, CLOCK_ID);
100         Secure.putString(mContentResolver, ClockManager.CLOCK_FACE_SETTING, json.toString());
101 
102         // The current clock is that id
103         assertEquals(CLOCK_ID, mManager.getCurrentClock());
104     }
105 
106     @Test
testGetCurrentClock_whenJSONExceptionOccurs_returnsClockFaceSetting()107     public void testGetCurrentClock_whenJSONExceptionOccurs_returnsClockFaceSetting() {
108         // Secure settings contains a clock face setting with invalid format to cause JSONException.
109         Secure.putString(mContentResolver, ClockManager.CLOCK_FACE_SETTING, CLOCK_FACE_SETTING);
110 
111         // The current clock is the clock face setting which is saved in secure settings.
112         assertEquals(CLOCK_FACE_SETTING, mManager.getCurrentClock());
113     }
114 
115     @Test
testGetCurrentClock_withNullIdInSecureSettings_returnsNullId()116     public void testGetCurrentClock_withNullIdInSecureSettings_returnsNullId() {
117         // Secure settings contains a null clock id
118         Secure.putString(mContentResolver, ClockManager.CLOCK_FACE_SETTING, /* value= */ null);
119 
120         // The current clock is null
121         assertEquals(null, mManager.getCurrentClock());
122     }
123 
124     @Test
testGetCurrentClock_withEmptyIdInSecureSettings_returnsEmptyId()125     public void testGetCurrentClock_withEmptyIdInSecureSettings_returnsEmptyId() {
126         // Secure settings contains an empty clock id
127         Secure.putString(mContentResolver, ClockManager.CLOCK_FACE_SETTING, /* value= */ "");
128 
129         // The current clock is empty
130         assertEquals("", mManager.getCurrentClock());
131     }
132 }
133