Added unit tests for NotificationHelper.

Test: atest CarServiceUnitTest:com.android.car.admin.NotificationHelperTest \
  CarServiceUnitTest:com.android.car.admin.NotificationHelperValidImportanceTest \
  CarServiceUnitTest:com.android.car.admin.NotificationHelperInvalidImportanceTest

Fixes: 190837918

Change-Id: I4b4861d41430338ded4af7c4a79aa5e4dfff6955
diff --git a/service/src/com/android/car/admin/NotificationHelper.java b/service/src/com/android/car/admin/NotificationHelper.java
index 44bba11..217bb46 100644
--- a/service/src/com/android/car/admin/NotificationHelper.java
+++ b/service/src/com/android/car/admin/NotificationHelper.java
@@ -16,6 +16,8 @@
 
 package com.android.car.admin;
 
+import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE;
+
 import android.annotation.NonNull;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -24,18 +26,26 @@
 import android.os.Bundle;
 
 import com.android.car.R;
+import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
+import com.android.internal.annotations.VisibleForTesting;
 
-// TODO(b/171603586): STOPSHIP move this class to CarSettings
+import java.util.Objects;
+
+// TODO: move this class to CarSettings or at least to some common package (not admin)
+
 /**
  * Helper for notification-related tasks
  */
 public final class NotificationHelper {
 
     static final int FACTORY_RESET_NOTIFICATION_ID = 42;
-    public static final int NEW_USER_DISCLAIMER_NOTIFICATION_ID = 108;
 
-    static final String IMPORTANCE_DEFAULT_ID = "importance_default";
-    static final String IMPORTANCE_HIGH_ID = "importance_high";
+    static final int NEW_USER_DISCLAIMER_NOTIFICATION_ID = 108;
+
+    @VisibleForTesting
+    static final String CHANNEL_ID_DEFAULT = "channel_id_default";
+    @VisibleForTesting
+    static final String CHANNEL_ID_HIGH = "channel_id_high";
 
     /**
      * Creates a notification (and its notification channel) for the given importance type, setting
@@ -48,14 +58,16 @@
     @NonNull
     public static Notification.Builder newNotificationBuilder(Context context,
             @NotificationManager.Importance int importance) {
-        String importanceId, importanceName;
+        Objects.requireNonNull(context, "context cannot be null");
+
+        String channelId, importanceName;
         switch (importance) {
             case NotificationManager.IMPORTANCE_DEFAULT:
-                importanceId = IMPORTANCE_DEFAULT_ID;
+                channelId = CHANNEL_ID_DEFAULT;
                 importanceName = context.getString(R.string.importance_default);
                 break;
             case NotificationManager.IMPORTANCE_HIGH:
-                importanceId = IMPORTANCE_HIGH_ID;
+                channelId = CHANNEL_ID_HIGH;
                 importanceName = context.getString(R.string.importance_high);
                 break;
             default:
@@ -63,15 +75,17 @@
         }
         NotificationManager notificationMgr = context.getSystemService(NotificationManager.class);
         notificationMgr.createNotificationChannel(
-                new NotificationChannel(importanceId, importanceName, importance));
+                new NotificationChannel(channelId, importanceName, importance));
 
         Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                 context.getString(com.android.internal.R.string.android_system_label));
 
-        return new Notification.Builder(context, importanceId).addExtras(extras);
+        return new Notification.Builder(context, channelId).addExtras(extras);
     }
 
+    @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE,
+            details = "private constructor")
     private NotificationHelper() {
         throw new UnsupportedOperationException("Contains only static methods");
     }
diff --git a/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperInvalidImportanceTest.java b/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperInvalidImportanceTest.java
new file mode 100644
index 0000000..de4af6d
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperInvalidImportanceTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.admin;
+
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MAX;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import static com.android.car.admin.NotificationHelper.newNotificationBuilder;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public final class NotificationHelperInvalidImportanceTest {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock
+    private Context mContext;
+
+    private final int mImportance;
+
+    public NotificationHelperInvalidImportanceTest(int importance) {
+        mImportance = importance;
+    }
+
+    @Test
+    public void testNewNotificationBuilder() {
+        assertThrows(IllegalArgumentException.class,
+                () -> newNotificationBuilder(mContext, mImportance));
+    }
+
+    @Parameterized.Parameters
+    public static Collection<Integer> provideParams() {
+        return Arrays.asList(
+                IMPORTANCE_LOW,
+                IMPORTANCE_MAX,
+                IMPORTANCE_MIN,
+                IMPORTANCE_NONE,
+                IMPORTANCE_UNSPECIFIED,
+                Integer.MIN_VALUE,
+                Integer.MAX_VALUE);
+    }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperTest.java b/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperTest.java
new file mode 100644
index 0000000..c4c481f
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.admin;
+
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
+import static com.android.car.admin.NotificationHelper.newNotificationBuilder;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.testng.Assert.expectThrows;
+
+import android.content.Context;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+
+@RunWith(MockitoJUnitRunner.class)
+public final class NotificationHelperTest {
+
+    @Mock
+    private Context mContext;
+
+    @Test
+    public void testNewNotificationBuilder_nullContext() {
+        NullPointerException exception = expectThrows(NullPointerException.class,
+                () -> newNotificationBuilder(/* context= */ null, IMPORTANCE_HIGH));
+
+        assertWithMessage("exception message").that(exception.getMessage()).contains("context");
+    }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperValidImportanceTest.java b/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperValidImportanceTest.java
new file mode 100644
index 0000000..daefcaf
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/admin/NotificationHelperValidImportanceTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.admin;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
+import static com.android.car.admin.NotificationHelper.CHANNEL_ID_DEFAULT;
+import static com.android.car.admin.NotificationHelper.CHANNEL_ID_HIGH;
+import static com.android.car.admin.NotificationHelper.newNotificationBuilder;
+import static com.android.internal.R.string.android_system_label;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.car.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+@RunWith(Parameterized.class)
+public final class NotificationHelperValidImportanceTest {
+
+    private static final String SYSTEM_LABEL = "System, I am your Label!";
+    private static final String IMPORTANCE_NAME = "The name is Bond, Importance Bond!";
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    private Context mRealContext = InstrumentationRegistry.getInstrumentation().getContext();
+
+    private Context mSpiedContext;
+
+    @Mock
+    private NotificationManager mNotificationMgr;
+
+    private final int mImportance;
+    private final String mChannelId;
+    private final int mResId;
+
+    public NotificationHelperValidImportanceTest(int importance, String channelId, int resId) {
+        mImportance = importance;
+        mChannelId = channelId;
+        mResId = resId;
+    }
+
+    @Before
+    public void setContext() {
+        mSpiedContext = spy(mRealContext);
+        when(mSpiedContext.getSystemService(NotificationManager.class))
+                .thenReturn(mNotificationMgr);
+        when(mSpiedContext.getString(android_system_label)).thenReturn(SYSTEM_LABEL);
+        when(mSpiedContext.getString(mResId)).thenReturn(IMPORTANCE_NAME);
+    }
+
+    @Test
+    public void testNewNotificationBuilder() {
+        Notification.Builder builder = newNotificationBuilder(mSpiedContext, mImportance);
+        assertWithMessage("builder").that(builder).isNotNull();
+
+        // Check custom label
+        Bundle extras = builder.getExtras();
+        assertWithMessage("extras").that(extras).isNotNull();
+        String label = extras.getString(Notification.EXTRA_SUBSTITUTE_APP_NAME);
+        assertWithMessage("label (extra %s)", Notification.EXTRA_SUBSTITUTE_APP_NAME).that(label)
+                .isEqualTo(SYSTEM_LABEL);
+
+        // Check notification arguments
+        ArgumentCaptor<NotificationChannel> captor = ArgumentCaptor
+                .forClass(NotificationChannel.class);
+        verify(mNotificationMgr).createNotificationChannel(captor.capture());
+        NotificationChannel channel = captor.getValue();
+        assertWithMessage("channel id").that(channel.getId()).isEqualTo(mChannelId);
+        assertWithMessage("importance").that(channel.getImportance()).isEqualTo(mImportance);
+        assertWithMessage("name").that(channel.getName()).isEqualTo(IMPORTANCE_NAME);
+    }
+
+    @Parameterized.Parameters
+    public static List<Object[]> provideParams() {
+        return Arrays.asList(new Object[][] {
+            { IMPORTANCE_DEFAULT, CHANNEL_ID_DEFAULT, R.string.importance_default },
+            { IMPORTANCE_HIGH, CHANNEL_ID_HIGH, R.string.importance_high }
+        });
+    }
+}