Add unit tests

Change-Id: I51360feaf8d0898c5da87225963954683d26a9f9
diff --git a/BUILD b/BUILD
index 7dc8ff5..06c5cb2 100644
--- a/BUILD
+++ b/BUILD
@@ -1,4 +1,10 @@
-load("//tools/bzl:plugin.bzl", "gerrit_plugin")
+load("//tools/bzl:junit.bzl", "junit_tests")
+load(
+    "//tools/bzl:plugin.bzl",
+    "PLUGIN_DEPS",
+    "PLUGIN_TEST_DEPS",
+    "gerrit_plugin",
+)
 
 gerrit_plugin(
     name = "avatars-external",
@@ -11,3 +17,22 @@
         "Gerrit-AvatarProvider: com.googlesource.gerrit.plugins.avatars.external.ExternalUrlAvatarProvider",
     ],
 )
+
+junit_tests(
+    name = "avatars-external_tests",
+    srcs = glob(["src/test/java/**/*.java"]),
+    tags = ["avatars-external"],
+    deps = [
+        ":avatars-external__plugin_test_deps",
+    ],
+)
+
+java_library(
+    name = "avatars-external__plugin_test_deps",
+    testonly = 1,
+    visibility = ["//visibility:public"],
+    exports = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
+        ":avatars-external__plugin",
+        "@mockito//jar",
+    ],
+)
diff --git a/src/test/java/com/googlesource/gerrit/plugins/avatars/external/ExternalUrlAvatarProviderTest.java b/src/test/java/com/googlesource/gerrit/plugins/avatars/external/ExternalUrlAvatarProviderTest.java
new file mode 100644
index 0000000..fa4cee7
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/avatars/external/ExternalUrlAvatarProviderTest.java
@@ -0,0 +1,132 @@
+// Copyright (C) 2022 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.googlesource.gerrit.plugins.avatars.external;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.extensions.restapi.Url;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.config.PluginConfig;
+import com.google.gerrit.server.config.PluginConfigFactory;
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ExternalUrlAvatarProviderTest {
+  private final String PLUGIN_NAME = "avatars-external";
+  private final String CANONICAL_WEB_URL = "https://gerrit.example.com";
+  private final String AVATAR_HOST = "avatars.example.com";
+
+  private ExternalUrlAvatarProvider avatarProvider;
+
+  @Mock private PluginConfigFactory cfgFactory;
+  @Mock private PluginConfig cfg;
+  @Mock private IdentifiedUser user;
+  @Mock private Account account;
+
+  @Before
+  public void setup() {
+    when(cfgFactory.getFromGerritConfig(PLUGIN_NAME)).thenReturn(cfg);
+
+    when(cfg.getString("url")).thenReturn(buildAvatarServiceUrl("${user}.jpg", false));
+    when(cfg.getString("changeUrl")).thenReturn(buildAvatarServiceUrl("change", false));
+    when(cfg.getString("sizeParameter")).thenReturn("s=${size}x${size}");
+
+    when(user.getAccountId()).thenReturn(Account.id(1));
+    when(user.getAccount()).thenReturn(account);
+    when(user.getUserName()).thenReturn(Optional.of("JDoe"));
+
+    when(account.preferredEmail()).thenReturn("john.doe@example.com");
+
+    avatarProvider = new ExternalUrlAvatarProvider(cfgFactory, PLUGIN_NAME, CANONICAL_WEB_URL);
+  }
+
+  @Test(expected = Test.None.class)
+  public void doNotFailIfNoUrlConfigured() {
+    when(cfg.getString("url")).thenReturn(null);
+    ExternalUrlAvatarProvider avatarProvider =
+        new ExternalUrlAvatarProvider(cfgFactory, PLUGIN_NAME, CANONICAL_WEB_URL);
+    String url = avatarProvider.getUrl(user, 30);
+    assertThat(url).isNull();
+  }
+
+  @Test(expected = Test.None.class)
+  public void doNotFailIfUrlHasNoPlaceholders() {
+    when(cfg.getString("url")).thenReturn(AVATAR_HOST);
+    avatarProvider = new ExternalUrlAvatarProvider(cfgFactory, PLUGIN_NAME, CANONICAL_WEB_URL);
+    String url = avatarProvider.getUrl(user, 30);
+    assertThat(url).isNull();
+  }
+
+  @Test
+  public void sslIsEnforcedIfGerritUsesSsl() {
+    String url = avatarProvider.getUrl(user, 30);
+    assertThat(url).startsWith("https://");
+  }
+
+  @Test
+  public void allAcceptedTemplatesAreReplaced() {
+    when(cfg.getString("url"))
+        .thenReturn(buildAvatarServiceUrl("${user}-${id}-${email}.jpg", true));
+    avatarProvider = new ExternalUrlAvatarProvider(cfgFactory, PLUGIN_NAME, CANONICAL_WEB_URL);
+    String url = avatarProvider.getUrl(user, 30);
+    assertThat(url)
+        .startsWith(buildAvatarServiceUrl(Url.encode("JDoe-1-john.doe@example.com.jpg"), true));
+  }
+
+  @Test
+  public void userNameInUrlIsConvertedToLowerCaseIfConfigured() {
+    String url = avatarProvider.getUrl(user, 30);
+    assertThat(url.toLowerCase()).isNotEqualTo(url);
+
+    when(cfg.getBoolean("lowerCase", false)).thenReturn(true);
+    avatarProvider = new ExternalUrlAvatarProvider(cfgFactory, PLUGIN_NAME, CANONICAL_WEB_URL);
+    url = avatarProvider.getUrl(user, 30);
+    assertThat(url.toLowerCase()).isEqualTo(url);
+  }
+
+  @Test
+  public void sizeParametersAreAddedToUrl() {
+    String url = avatarProvider.getUrl(user, 30);
+    assertThat(url).endsWith("?s=30x30");
+
+    when(cfg.getString("url")).thenReturn(buildAvatarServiceUrl("${user}?q=test", true));
+    avatarProvider = new ExternalUrlAvatarProvider(cfgFactory, PLUGIN_NAME, CANONICAL_WEB_URL);
+    url = avatarProvider.getUrl(user, 30);
+    assertThat(url).endsWith("?q=test&s=30x30");
+  }
+
+  @Test
+  public void changeAvatarUrlIsTemplated() {
+    String url = avatarProvider.getChangeAvatarUrl(user);
+    assertThat(url).isEqualTo(buildAvatarServiceUrl("change", false));
+
+    when(cfg.getString("changeUrl")).thenReturn(buildAvatarServiceUrl("change/${user}", true));
+    avatarProvider = new ExternalUrlAvatarProvider(cfgFactory, PLUGIN_NAME, CANONICAL_WEB_URL);
+    url = avatarProvider.getChangeAvatarUrl(user);
+    assertThat(url).isEqualTo(buildAvatarServiceUrl("change/JDoe", true));
+  }
+
+  private String buildAvatarServiceUrl(String path, boolean ssl) {
+    String protocol = ssl ? "https" : "http";
+    return String.format("%s://%s/%s", protocol, AVATAR_HOST, path);
+  }
+}