1 /*
2  * Copyright (C) 2024 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 android.adservices.ondevicepersonalization;
18 
19 import static org.junit.Assert.assertThrows;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.anyBoolean;
22 import static org.mockito.ArgumentMatchers.isNull;
23 import static org.mockito.Mockito.doAnswer;
24 import static org.mockito.Mockito.doThrow;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.times;
27 import static org.mockito.Mockito.verify;
28 
29 import android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationConfigService;
30 import android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationConfigServiceCallback;
31 import android.os.OutcomeReceiver;
32 import android.os.RemoteException;
33 
34 import com.android.federatedcompute.internal.util.AbstractServiceBinder;
35 
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.junit.runners.Parameterized;
40 import org.mockito.Mock;
41 import org.mockito.Mockito;
42 
43 import java.util.Arrays;
44 import java.util.Collection;
45 import java.util.concurrent.Executor;
46 
47 @RunWith(Parameterized.class)
48 public class OnDevicePersonalizationConfigManagerTest {
49 
50     @Mock private IOnDevicePersonalizationConfigService mMockConfigService;
51 
52     private OnDevicePersonalizationConfigManager mConfigManager;
53 
54     @Parameterized.Parameter(0)
55     public String scenario;
56 
57     @Before
setUp()58     public void setUp() {
59         mMockConfigService = Mockito.mock(IOnDevicePersonalizationConfigService.class);
60         TestServiceBinder mTestBinder = new TestServiceBinder(mMockConfigService);
61         mConfigManager = new OnDevicePersonalizationConfigManager(mTestBinder);
62     }
63 
64     @Parameterized.Parameters
data()65     public static Collection<Object[]> data() {
66         return Arrays.asList(
67                 new Object[][] {
68                     {"testSuccess"}, {"testNPE"}, {"testGenericException"},
69                 });
70     }
71 
72     @Test
testSetPersonalizationStatus()73     public void testSetPersonalizationStatus() throws RemoteException {
74         OutcomeReceiver<Void, Exception> spyCallback = spy(new MyTestCallback());
75 
76         switch (scenario) {
77             case "testSuccess":
78                 doAnswer(
79                                 invocation -> {
80                                     IOnDevicePersonalizationConfigServiceCallback serviceCallback =
81                                             invocation.getArgument(1);
82                                     serviceCallback.onSuccess();
83                                     return null;
84                                 })
85                         .when(mMockConfigService)
86                         .setPersonalizationStatus(anyBoolean(), any());
87                 mConfigManager.setPersonalizationEnabled(true, Runnable::run, spyCallback);
88                 verify(spyCallback, times(1)).onResult(isNull());
89                 break;
90             case "testNPE":
91                 doThrow(new NullPointerException())
92                         .when(mMockConfigService)
93                         .setPersonalizationStatus(anyBoolean(), any());
94                 assertThrows(
95                         NullPointerException.class,
96                         () ->
97                                 mConfigManager.setPersonalizationEnabled(
98                                         true, Runnable::run, spyCallback));
99                 break;
100             case "testGenericException":
101                 doThrow(new RuntimeException())
102                         .when(mMockConfigService)
103                         .setPersonalizationStatus(anyBoolean(), any());
104                 mConfigManager.setPersonalizationEnabled(true, Runnable::run, spyCallback);
105                 verify(spyCallback, times(1)).onError(any(RuntimeException.class));
106                 break;
107         }
108     }
109 
110     static class TestServiceBinder
111             extends AbstractServiceBinder<IOnDevicePersonalizationConfigService> {
112         private final IOnDevicePersonalizationConfigService mService;
113 
TestServiceBinder(IOnDevicePersonalizationConfigService service)114         TestServiceBinder(IOnDevicePersonalizationConfigService service) {
115             mService = service;
116         }
117 
118         @Override
getService(Executor executor)119         public IOnDevicePersonalizationConfigService getService(Executor executor) {
120             return mService;
121         }
122 
123         @Override
unbindFromService()124         public void unbindFromService() {}
125     }
126 
127     public static class MyTestCallback implements OutcomeReceiver<Void, Exception> {
128 
129         @Override
onResult(Void result)130         public void onResult(Void result) {}
131 
132         @Override
onError(Exception error)133         public void onError(Exception error) {}
134     }
135 }
136