1 /* 2 * Copyright 2017 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 androidx.work.impl.utils; 18 19 import static androidx.work.impl.utils.IdGenerator.INITIAL_ID; 20 21 import static org.hamcrest.CoreMatchers.is; 22 import static org.hamcrest.MatcherAssert.assertThat; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.eq; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.when; 27 28 import static java.lang.Integer.MAX_VALUE; 29 30 import android.content.Context; 31 import android.content.SharedPreferences; 32 import android.support.test.filters.SdkSuppress; 33 import android.support.test.filters.SmallTest; 34 import android.support.test.runner.AndroidJUnit4; 35 36 import androidx.work.impl.WorkManagerImpl; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.mockito.invocation.InvocationOnMock; 42 import org.mockito.stubbing.Answer; 43 44 @SmallTest 45 @RunWith(AndroidJUnit4.class) 46 @SdkSuppress(minSdkVersion = WorkManagerImpl.MIN_JOB_SCHEDULER_API_LEVEL) 47 public class IdGeneratorTest { 48 private Integer mMockSharedPrefsNextId; 49 private IdGenerator mIdGenerator; 50 51 @Before 52 public void setUp() { 53 Context mMockContext = mock(Context.class); 54 SharedPreferences.Editor mockEditor = createMockSharedPreferencesEditor(); 55 SharedPreferences mockSharedPrefs = createMockSharedPreferences(mockEditor); 56 when(mMockContext.getSharedPreferences( 57 eq(IdGenerator.PREFERENCE_FILE_KEY), anyInt())) 58 .thenReturn(mockSharedPrefs); 59 mIdGenerator = new IdGenerator(mMockContext); 60 } 61 62 @Test 63 public void testNextId_returnsInitialIdWhenNoStoredNextId() { 64 int nextId = mIdGenerator.nextJobSchedulerIdWithRange(INITIAL_ID, MAX_VALUE); 65 assertThat(nextId, is(INITIAL_ID)); 66 } 67 68 @Test 69 public void testNextId_returnsStoredNextId() { 70 int expectedId = 100; 71 storeNextIdInSharedPrefs(expectedId); 72 int nextId = mIdGenerator.nextJobSchedulerIdWithRange(INITIAL_ID, MAX_VALUE); 73 assertThat(nextId, is(expectedId)); 74 } 75 76 @Test 77 public void testNextId_returnsInitialIdAfterReturningMaxInteger() { 78 int expectedId = MAX_VALUE; 79 storeNextIdInSharedPrefs(expectedId); 80 int nextId = mIdGenerator.nextJobSchedulerIdWithRange(INITIAL_ID, MAX_VALUE); 81 assertThat(nextId, is(MAX_VALUE)); 82 nextId = mIdGenerator.nextJobSchedulerIdWithRange(INITIAL_ID, MAX_VALUE); 83 assertThat(nextId, is(INITIAL_ID)); 84 } 85 86 @Test 87 public void testNextId_belowMinRange() { 88 storeNextIdInSharedPrefs(2); 89 assertThat(mIdGenerator.nextJobSchedulerIdWithRange(10, 100), is(10)); 90 } 91 92 @Test 93 public void testNextId_aboveMaxRange() { 94 storeNextIdInSharedPrefs(100); 95 assertThat(mIdGenerator.nextJobSchedulerIdWithRange(10, 100), is(100)); 96 } 97 98 @Test 99 public void testNextId_aboveMaxRange2() { 100 storeNextIdInSharedPrefs(110); 101 assertThat(mIdGenerator.nextJobSchedulerIdWithRange(10, 100), is(10)); 102 } 103 104 @Test 105 public void testNextId_withinRange() { 106 storeNextIdInSharedPrefs(20); 107 assertThat(mIdGenerator.nextJobSchedulerIdWithRange(10, 100), is(20)); 108 } 109 110 /** 111 * Mocks setting a stored value in {@link SharedPreferences} for the next ID. 112 * 113 * @param nextId The next ID to store in {@link SharedPreferences}. 114 */ 115 private void storeNextIdInSharedPrefs(int nextId) { 116 mMockSharedPrefsNextId = nextId; 117 } 118 119 private SharedPreferences createMockSharedPreferences(SharedPreferences.Editor mockEditor) { 120 final SharedPreferences mockSharedPreferences = mock(SharedPreferences.class); 121 when(mockSharedPreferences.edit()).thenReturn(mockEditor); 122 when(mockSharedPreferences.getInt(eq(IdGenerator.NEXT_JOB_SCHEDULER_ID_KEY), anyInt())) 123 .thenAnswer(new Answer<Integer>() { 124 @Override 125 public Integer answer(InvocationOnMock invocation) throws Throwable { 126 int defValue = invocation.getArgument(1); 127 return (mMockSharedPrefsNextId == null) ? defValue : mMockSharedPrefsNextId; 128 } 129 }); 130 return mockSharedPreferences; 131 } 132 133 private SharedPreferences.Editor createMockSharedPreferencesEditor() { 134 final SharedPreferences.Editor mockEditor = mock(SharedPreferences.Editor.class); 135 when(mockEditor.putInt(eq(IdGenerator.NEXT_JOB_SCHEDULER_ID_KEY), anyInt())).thenAnswer( 136 new Answer<SharedPreferences.Editor>() { 137 @Override 138 public SharedPreferences.Editor answer(InvocationOnMock invocation) 139 throws Throwable { 140 mMockSharedPrefsNextId = invocation.getArgument(1); 141 return mockEditor; 142 } 143 }); 144 return mockEditor; 145 } 146 } 147