Add Google Analytics to registrar console

To support the open source community, which may want to use different analytics services, we implement a soy template for analytics services that:

1) Does not require users to implement Google Analytics
2) Allows users to add their own analytics code to `Analytics.soy`
3) Gives users the flexibility to pass as much or as little static configuration to their custom analytics code as needed.
4) Ensures that users can merge upstream Nomulus code in the future without having to delete their custom analytics implementations
5) Does not allow code to be injected from configuration, which Soy as a framework actively discourages.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=248340081
This commit is contained in:
jianglai 2019-05-15 08:44:56 -07:00
parent 7f69ebc5d9
commit b12a462f5e
15 changed files with 135 additions and 3 deletions

View file

@ -61,6 +61,7 @@ registry.registrar.ConsoleTestUtil.renderConsoleMain = function(
supportPhoneNumber: args.supportPhoneNumber || '+1 (888) 555 0123',
technicalDocsUrl: args.technicalDocsUrl || 'http://example.com/techdocs',
environment: args.environment || 'UNITTEST',
analyticsConfig: args.analyticsConfig || {googleAnalyticsId: null},
});
};
@ -80,6 +81,9 @@ registry.registrar.ConsoleTestUtil.visit = function(
opt_args.clientId = opt_args.clientId || 'dummyRegistrarId';
opt_args.xsrfToken = opt_args.xsrfToken || 'dummyXsrfToken';
opt_args.isAdmin = !!opt_args.isAdmin;
opt_args.analyticsConfig =
opt_args.analyticsConfig || {googleAnalyticsIds: null};
// set the default isOwner to be the opposite of isAdmin.
// That way, if we don't explicitly state them both we get what we'd expect:
// {} -> OWNER (the "regular" case of a visitor to the console)

View file

@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.config.RegistryEnvironment;
import google.registry.model.registry.Registry;
@ -97,6 +98,7 @@ public final class ConsoleOteSetupActionTest {
action.productName = "Nomulus";
action.clientId = Optional.empty();
action.email = Optional.empty();
action.analyticsConfig = ImmutableMap.of("googleAnalyticsId", "sampleId");
action.optionalPassword = Optional.empty();
action.passwordGenerator = new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
@ -115,6 +117,7 @@ public final class ConsoleOteSetupActionTest {
public void testGet_authorized() {
action.run();
assertThat(response.getPayload()).contains("<h1>Setup OT&E</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
@Test
@ -129,6 +132,7 @@ public final class ConsoleOteSetupActionTest {
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
action.run();
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
@Test
@ -160,6 +164,7 @@ public final class ConsoleOteSetupActionTest {
+ " Registrar myclientid-4 with access to TLD myclientid-ga\n"
+ " Registrar myclientid-5 with access to TLD myclientid-eap\n"
+ "Gave user contact@registry.example web access to these Registrars\n");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
@Test
@ -189,5 +194,6 @@ public final class ConsoleOteSetupActionTest {
action.method = Method.POST;
action.run();
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
}

View file

@ -26,6 +26,7 @@ import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.config.RegistryEnvironment;
import google.registry.model.registrar.Registrar;
@ -119,6 +120,8 @@ public final class ConsoleRegistrarCreatorActionTest {
action.passwordGenerator = new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
action.passcodeGenerator = new DeterministicStringGenerator("314159265");
action.analyticsConfig = ImmutableMap.of("googleAnalyticsId", "sampleId");
}
@Test
@ -134,6 +137,7 @@ public final class ConsoleRegistrarCreatorActionTest {
public void testGet_authorized() {
action.run();
assertThat(response.getPayload()).contains("<h1>Create Registrar</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
@Test
@ -141,6 +145,7 @@ public final class ConsoleRegistrarCreatorActionTest {
action.registryEnvironment = RegistryEnvironment.PRODUCTION;
action.run();
assertThat(response.getPayload()).contains("<h1>Create Registrar</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
@Test
@ -149,6 +154,7 @@ public final class ConsoleRegistrarCreatorActionTest {
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
action.run();
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
@Test
@ -243,6 +249,7 @@ public final class ConsoleRegistrarCreatorActionTest {
assertThat(response.getPayload())
.contains("<h1>Successfully created Registrar myclientid</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
Registrar registrar = loadByClientId("myclientid").orElse(null);
assertThat(registrar).isNotNull();
@ -414,5 +421,6 @@ public final class ConsoleRegistrarCreatorActionTest {
action.method = Method.POST;
action.run();
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
}

View file

@ -25,6 +25,7 @@ import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.net.MediaType;
import google.registry.config.RegistryEnvironment;
@ -79,6 +80,7 @@ public class ConsoleUiActionTest {
action.paramClientId = Optional.empty();
action.authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
action.environment = RegistryEnvironment.UNITTEST;
action.analyticsConfig = ImmutableMap.of("googleAnalyticsId", "sampleId");
action.registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(
@ -122,6 +124,13 @@ public class ConsoleUiActionTest {
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
}
@Test
public void testWebPage_containsGoogleAnalyticsId() {
action.run();
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
}
@Test
public void testUserHasAccessAsTheRegistrar_showsRegistrarConsole() {
action.run();
@ -135,6 +144,7 @@ public class ConsoleUiActionTest {
action.enabled = false;
action.run();
assertThat(response.getPayload()).contains("<h1>Console is disabled</h1>");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
}
@Test
@ -144,6 +154,7 @@ public class ConsoleUiActionTest {
action.run();
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
assertThat(response.getPayload()).contains("not associated with Nomulus.");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
assertMetric("<null>", "false", "[]", "FORBIDDEN");
}
@ -172,6 +183,7 @@ public class ConsoleUiActionTest {
action.run();
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
assertThat(response.getPayload()).contains("not associated with the registrar fakeRegistrar.");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
assertMetric("fakeRegistrar", "true", "[]", "FORBIDDEN");
}
@ -181,6 +193,7 @@ public class ConsoleUiActionTest {
action.run();
assertThat(response.getPayload()).contains("Registrar Console");
assertThat(response.getPayload()).contains("reg-content-and-footer");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
assertMetric("NewRegistrar", "true", "[OWNER, ADMIN]", "SUCCESS");
}
@ -190,6 +203,7 @@ public class ConsoleUiActionTest {
assertThat(response.getPayload()).contains("<option value=\"TheRegistrar\" selected>");
assertThat(response.getPayload()).contains("<option value=\"NewRegistrar\">");
assertThat(response.getPayload()).contains("<option value=\"AdminRegistrar\">");
assertThat(response.getPayload()).contains("gtag('config', 'sampleId')");
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
}
}