diff --git a/build.gradle b/build.gradle index 2f0557db..aa87fb05 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ dependencies { testImplementation( "org.junit.jupiter:junit-jupiter:5.9.1", "org.junit.platform:junit-platform-launcher:1.9.1", - "org.assertj:assertj-core:3.22.0", + "org.assertj:assertj-core:3.24.2", "org.mockito:mockito-inline:4.5.1" ) testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' diff --git a/gradle.properties b/gradle.properties index fa7e4eb1..54306334 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ideaVersion = IC-2020.3 # https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html sinceIdeaBuild=203 projectVersion=1.0.1-SNAPSHOT -intellijPluginVersion=1.13.3 +intellijPluginVersion=1.16.1 jetBrainsToken=invalid jetBrainsChannel=stable nexusUser=invalid diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/IMessageBroker.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/IMessageBroker.java index 77031532..f16ebd44 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/IMessageBroker.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/IMessageBroker.java @@ -10,9 +10,9 @@ ******************************************************************************/ package com.redhat.devtools.intellij.telemetry.core; -import com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent; +import com.redhat.devtools.intellij.telemetry.core.service.Event; public interface IMessageBroker { - void send(TelemetryEvent event); + void send(Event event); void dispose(); } diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/ITelemetryService.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/IService.java similarity index 74% rename from src/main/java/com/redhat/devtools/intellij/telemetry/core/ITelemetryService.java rename to src/main/java/com/redhat/devtools/intellij/telemetry/core/IService.java index c5d8961f..fe8cb531 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/ITelemetryService.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/IService.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 Red Hat, Inc. + * Copyright (c) 2023 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, @@ -10,8 +10,8 @@ ******************************************************************************/ package com.redhat.devtools.intellij.telemetry.core; -import com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent; +import com.redhat.devtools.intellij.telemetry.core.service.Event; -public interface ITelemetryService { - void send(TelemetryEvent event); +public interface IService { + void send(Event event); } diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryEvent.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/Event.java similarity index 84% rename from src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryEvent.java rename to src/main/java/com/redhat/devtools/intellij/telemetry/core/service/Event.java index 76dad9f0..7b8ca510 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryEvent.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/Event.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 Red Hat, Inc. + * Copyright (c) 2023 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, @@ -13,7 +13,7 @@ import java.util.HashMap; import java.util.Map; -public class TelemetryEvent { +public class Event { public enum Type { USER, ACTION, STARTUP, SHUTDOWN @@ -23,11 +23,11 @@ public enum Type { private final String name; private final Map properties; - public TelemetryEvent(Type type, String name) { + public Event(Type type, String name) { this(type, name, new HashMap<>()); } - public TelemetryEvent(Type type, String name, Map properties) { + public Event(Type type, String name, Map properties) { this.type = type; this.name = name; this.properties = properties; diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackEvent.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackEvent.java new file mode 100644 index 00000000..00d15b87 --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackEvent.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.telemetry.core.service; + +import java.util.HashMap; +import java.util.Map; + +public class FeedbackEvent extends Event { + + public FeedbackEvent(String name) { + this(name, new HashMap<>()); + } + + public FeedbackEvent(String name, Map properties) { + super(Type.ACTION, name, properties); + } +} diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilder.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilder.java new file mode 100644 index 00000000..5fdc251d --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilder.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.telemetry.core.service; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.redhat.devtools.intellij.telemetry.core.IService; +import com.redhat.devtools.intellij.telemetry.core.util.Lazy; + +import java.util.function.Supplier; + +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.ACTION; + +public class FeedbackMessageBuilder { + + private static final Logger LOGGER = Logger.getInstance(FeedbackMessageBuilder.class); + + private final IService serviceFacade; + + public FeedbackMessageBuilder(ClassLoader classLoader) { + this(new FeedbackServiceFacade(classLoader)); + } + + FeedbackMessageBuilder(IService serviceFacade) { + this.serviceFacade = serviceFacade; + } + + static class FeedbackServiceFacade extends Lazy implements IService { + + protected FeedbackServiceFacade(final ClassLoader classLoader) { + this(() -> ApplicationManager.getApplication().getService(FeedbackServiceFactory.class).create(classLoader)); + } + + protected FeedbackServiceFacade(final Supplier supplier) { + super(supplier); + } + + @Override + public void send(Event event) { + get().send(event); + } + } + + public FeedbackMessage feedback(String name) { + return new FeedbackMessage(name, serviceFacade); + } + + public static class FeedbackMessage extends Message{ + + private FeedbackMessage(String name, IService service) { + super(ACTION, name, service); + } + } +} diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackService.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackService.java new file mode 100644 index 00000000..43d0db3b --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.telemetry.core.service; + +import com.intellij.openapi.diagnostic.Logger; +import com.redhat.devtools.intellij.telemetry.core.IMessageBroker; +import com.redhat.devtools.intellij.telemetry.core.IService; + +public class FeedbackService implements IService { + + private static final Logger LOGGER = Logger.getInstance(FeedbackService.class); + + protected final IMessageBroker broker; + + public FeedbackService(final IMessageBroker broker) { + this.broker = broker; + } + + @Override + public void send(Event event) { + broker.send(event); + } + + public void dispose() { + broker.dispose(); + } +} diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackServiceFactory.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackServiceFactory.java new file mode 100644 index 00000000..5a02f0e0 --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackServiceFactory.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.telemetry.core.service; + +import com.intellij.openapi.project.DumbAware; +import com.redhat.devtools.intellij.telemetry.core.IMessageBroker; +import com.redhat.devtools.intellij.telemetry.core.IService; +import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration; +import com.redhat.devtools.intellij.telemetry.core.service.segment.SegmentBroker; +import com.redhat.devtools.intellij.telemetry.core.service.segment.SegmentConfiguration; + +public class FeedbackServiceFactory implements DumbAware { + + public IService create(ClassLoader classLoader) { + TelemetryConfiguration configuration = TelemetryConfiguration.getInstance(); + IMessageBroker broker = createSegmentBroker(configuration.isDebug(), classLoader); + return new FeedbackService(broker); + } + + private IMessageBroker createSegmentBroker(boolean isDebug, ClassLoader classLoader) { + SegmentConfiguration brokerConfiguration = new SegmentConfiguration(classLoader); + return new SegmentBroker( + isDebug, + UserId.INSTANCE.get(), + null, + brokerConfiguration); + } + +} diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/Message.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/Message.java new file mode 100644 index 00000000..af0f7e7c --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/Message.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.telemetry.core.service; + +import com.intellij.openapi.diagnostic.Logger; +import com.redhat.devtools.intellij.telemetry.core.IService; + +import java.util.HashMap; +import java.util.Map; + +abstract class Message { + + private static final Logger LOGGER = Logger.getInstance(Message.class); + + private final Event.Type type; + private final Map properties = new HashMap<>(); + private final String name; + private final IService service; + + protected Message(Event.Type type, String name, IService service) { + this.name = name; + this.type = type; + this.service = service; + } + + String getName() { + return name; + } + + Event.Type getType() { + return type; + } + + public T property(String key, String value) { + if (key == null + || value == null) { + LOGGER.warn("Ignored property with key: " + key + " value: " + value); + } else { + properties.put(key, value); + } + return (T) this; + } + + String getProperty(String key) { + return properties.get(key); + } + + Map properties() { + return properties; + } + + protected boolean hasProperty(String key) { + return properties.containsKey(key); + } + + public Event send() { + Event event = new Event(type, name, new HashMap<>(properties)); + service.send(event); + return event; + } + } \ No newline at end of file diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilder.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilder.java index 71896cf8..a819d51e 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilder.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilder.java @@ -10,36 +10,36 @@ ******************************************************************************/ package com.redhat.devtools.intellij.telemetry.core.service; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.ACTION; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.SHUTDOWN; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.STARTUP; -import static com.redhat.devtools.intellij.telemetry.core.util.AnonymizeUtils.anonymize; -import static com.redhat.devtools.intellij.telemetry.core.util.TimeUtils.toLocalTime; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.HashMap; -import java.util.Map; - import com.intellij.ide.AppLifecycleListener; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.messages.MessageBusConnection; -import com.redhat.devtools.intellij.telemetry.core.ITelemetryService; -import com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type; +import com.redhat.devtools.intellij.telemetry.core.IService; +import com.redhat.devtools.intellij.telemetry.core.service.Event.Type; +import com.redhat.devtools.intellij.telemetry.core.util.Lazy; import com.redhat.devtools.intellij.telemetry.core.util.TimeUtils; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.function.Supplier; + +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.ACTION; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.SHUTDOWN; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.STARTUP; +import static com.redhat.devtools.intellij.telemetry.core.util.AnonymizeUtils.anonymize; +import static com.redhat.devtools.intellij.telemetry.core.util.TimeUtils.toLocalTime; + public class TelemetryMessageBuilder { private static final Logger LOGGER = Logger.getInstance(TelemetryMessageBuilder.class); - private final ServiceFacade service; + private final TelemetryServiceFacade service; public TelemetryMessageBuilder(ClassLoader classLoader) { - this(new ServiceFacade(classLoader)); + this(new TelemetryServiceFacade(classLoader)); } - TelemetryMessageBuilder(ServiceFacade serviceFacade) { + TelemetryMessageBuilder(TelemetryServiceFacade serviceFacade) { this.service = serviceFacade; } @@ -47,26 +47,26 @@ public ActionMessage action(String name) { return new ActionMessage(name, service); } - static class StartupMessage extends Message { + static class StartupMessage extends TelemetryMessage { - private StartupMessage(ServiceFacade service) { + private StartupMessage(IService service) { super(STARTUP, "startup", service); } } - static class ShutdownMessage extends Message { + static class ShutdownMessage extends TelemetryMessage { private static final String PROP_SESSION_DURATION = "session_duration"; - private ShutdownMessage(ServiceFacade service) { + private ShutdownMessage(IService service) { this(toLocalTime(ApplicationManager.getApplication().getStartTime()), service); } - private ShutdownMessage(LocalDateTime startup, ServiceFacade service) { + private ShutdownMessage(LocalDateTime startup, IService service) { this(startup, LocalDateTime.now(), service); } - ShutdownMessage(LocalDateTime startup, LocalDateTime shutdown, ServiceFacade service) { + ShutdownMessage(LocalDateTime startup, LocalDateTime shutdown, IService service) { super(SHUTDOWN, "shutdown", service); sessionDuration(startup, shutdown); } @@ -84,7 +84,7 @@ String getSessionDuration() { } } - public static class ActionMessage extends Message { + public static class ActionMessage extends TelemetryMessage { static final String PROP_DURATION = "duration"; static final String PROP_ERROR = "error"; @@ -94,7 +94,7 @@ public static class ActionMessage extends Message { private LocalDateTime started; - private ActionMessage(String name, ServiceFacade service) { + private ActionMessage(String name, IService service) { super(ACTION, name, service); started(); } @@ -166,7 +166,7 @@ String getError() { } @Override - public TelemetryEvent send() { + public Event send() { ensureFinished(); ensureResultOrError(); return super.send(); @@ -186,76 +186,26 @@ private void ensureResultOrError() { } } - private abstract static class Message> { - - private final Type type; - private final Map properties = new HashMap<>(); - private final String name; - private final ServiceFacade service; - - private Message(Type type, String name, ServiceFacade service) { - this.name = name; - this.type = type; - this.service = service; - } - - String getName() { - return name; - } - - Type getType() { - return type; - } - - public T property(String key, String value) { - if (key == null - || value == null) { - LOGGER.warn("Ignored property with key: " + key + " value: " + value); - } else { - properties.put(key, value); - } - return (T) this; - } - - String getProperty(String key) { - return properties.get(key); - } - - Map properties() { - return properties; - } - - protected boolean hasProperty(String key) { - return properties.containsKey(key); - } - - public TelemetryEvent send() { - TelemetryEvent event = new TelemetryEvent(type, name, new HashMap<>(properties)); - service.send(event); - return event; + private static class TelemetryMessage> extends Message { + protected TelemetryMessage(Type type, String name, IService service) { + super(type, name, service); } } - static class ServiceFacade { - private final ClassLoader classLoader; - private ITelemetryService service = null; + static class TelemetryServiceFacade extends Lazy implements IService { - protected ServiceFacade(final ClassLoader classLoader) { - this.classLoader = classLoader; + protected TelemetryServiceFacade(final ClassLoader classLoader) { + this(() -> ApplicationManager.getApplication().getService(TelemetryServiceFactory.class).create(classLoader)); } - public void send(final TelemetryEvent event) { - if (service == null) { - this.service = createService(classLoader); - sendStartup(); - onShutdown(); - } - service.send(event); + protected TelemetryServiceFacade(final Supplier supplier) { + super(supplier); } - protected ITelemetryService createService(ClassLoader classLoader) { - TelemetryServiceFactory factory = ApplicationManager.getApplication().getService(TelemetryServiceFactory.class); - return factory.create(classLoader); + @Override + protected void onCreated(IService service) { + sendStartup(); + onShutdown(); } private void sendStartup() { @@ -273,12 +223,16 @@ public void appWillBeClosed(boolean isRestart) { } protected void sendShutdown() { - new ShutdownMessage(ServiceFacade.this).send(); + new ShutdownMessage(TelemetryServiceFacade.this).send(); } protected MessageBusConnection createMessageBusConnection() { return ApplicationManager.getApplication().getMessageBus().connect(); } + @Override + public void send(Event event) { + get().send(event); + } } } diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryService.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryService.java index 428d5ef0..b11d4d4e 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryService.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryService.java @@ -18,15 +18,15 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.messages.MessageBusConnection; import com.redhat.devtools.intellij.telemetry.core.IMessageBroker; -import com.redhat.devtools.intellij.telemetry.core.ITelemetryService; +import com.redhat.devtools.intellij.telemetry.core.IService; import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration; import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration.ConfigurationChangedListener; import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration.Mode; -import com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type; +import com.redhat.devtools.intellij.telemetry.core.service.Event.Type; import com.redhat.devtools.intellij.telemetry.core.util.CircularBuffer; import com.redhat.devtools.intellij.telemetry.ui.TelemetryNotifications; -public class TelemetryService implements ITelemetryService { +public class TelemetryService implements IService { private static final Logger LOGGER = Logger.getInstance(TelemetryService.class); @@ -36,16 +36,17 @@ public class TelemetryService implements ITelemetryService { private final TelemetryConfiguration configuration; protected final IMessageBroker broker; private final AtomicBoolean userQueried = new AtomicBoolean(false); - private final CircularBuffer onHold = new CircularBuffer<>(BUFFER_SIZE); + private final CircularBuffer onHold = new CircularBuffer<>(BUFFER_SIZE); public TelemetryService(final TelemetryConfiguration configuration, final IMessageBroker broker) { this(configuration, broker, ApplicationManager.getApplication().getMessageBus().connect(), new TelemetryNotifications()); } - TelemetryService(final TelemetryConfiguration configuration, - final IMessageBroker broker, - final MessageBusConnection connection, - final TelemetryNotifications notifications) { + TelemetryService( + final TelemetryConfiguration configuration, + final IMessageBroker broker, + final MessageBusConnection connection, + final TelemetryNotifications notifications) { this.configuration = configuration; this.broker = broker; this.notifications = notifications; @@ -62,14 +63,14 @@ private void onConfigurationChanged(MessageBusConnection connection) { } @Override - public void send(TelemetryEvent event) { + public void send(Event event) { sendUserInfo(); doSend(event); queryUserConsent(); } private void sendUserInfo() { - doSend(new TelemetryEvent( + doSend(new Event( Type.USER, "Anonymous ID: " + UserId.INSTANCE.get())); } @@ -81,7 +82,7 @@ private void queryUserConsent() { } } - private void doSend(TelemetryEvent event) { + private void doSend(Event event) { if (isEnabled()) { flushOnHold(); broker.send(event); diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/ISegmentConfiguration.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/ISegmentConfiguration.java index 5ca0178d..130cdba6 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/ISegmentConfiguration.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/ISegmentConfiguration.java @@ -13,4 +13,13 @@ public interface ISegmentConfiguration { String getNormalWriteKey(); String getDebugWriteKey(); + + default String getWriteKey(boolean isDebug) { + if (isDebug) { + return getDebugWriteKey(); + } else { + return getNormalWriteKey(); + } + } + } diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBroker.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBroker.java index 2a23bc3c..bceff031 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBroker.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBroker.java @@ -14,7 +14,7 @@ import com.redhat.devtools.intellij.telemetry.core.IMessageBroker; import com.redhat.devtools.intellij.telemetry.core.service.Application; import com.redhat.devtools.intellij.telemetry.core.service.Environment; -import com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent; +import com.redhat.devtools.intellij.telemetry.core.service.Event; import com.redhat.devtools.intellij.telemetry.core.util.Lazy; import com.redhat.devtools.intellij.telemetry.core.util.MapBuilder; import com.segment.analytics.Analytics; @@ -23,6 +23,7 @@ import com.segment.analytics.messages.PageMessage; import com.segment.analytics.messages.TrackMessage; +import java.util.Collections; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Function; @@ -53,25 +54,25 @@ public class SegmentBroker implements IMessageBroker { enum SegmentType { IDENTIFY { - public MessageBuilder toMessage(TelemetryEvent event, Map context, SegmentBroker broker) { + public MessageBuilder toMessage(Event event, Map context, SegmentBroker broker) { return broker.toMessage(IdentifyMessage.builder(), event, context); } }, TRACK { - public MessageBuilder toMessage(TelemetryEvent event, Map context, SegmentBroker broker) { + public MessageBuilder toMessage(Event event, Map context, SegmentBroker broker) { return broker.toMessage(TrackMessage.builder(event.getName()), event, context); } }, PAGE { - public MessageBuilder toMessage(TelemetryEvent event, Map context, SegmentBroker broker) { + public MessageBuilder toMessage(Event event, Map context, SegmentBroker broker) { return broker.toMessage(PageMessage.builder(event.getName()), event, context); } }; - public abstract MessageBuilder toMessage(TelemetryEvent event, Map context, SegmentBroker broker); + public abstract MessageBuilder toMessage(Event event, Map context, SegmentBroker broker); - public static SegmentType valueOf(TelemetryEvent.Type eventType) { + public static SegmentType valueOf(Event.Type eventType) { switch (eventType) { case USER: return IDENTIFY; @@ -87,21 +88,28 @@ public static SegmentType valueOf(TelemetryEvent.Type eventType) { private final String userId; private final IdentifyTraitsPersistence identifyTraitsPersistence; private final Environment environment; - private Lazy analytics; + private final Lazy analytics; public SegmentBroker(boolean isDebug, String userId, Environment environment, ISegmentConfiguration configuration) { this(isDebug, userId, IdentifyTraitsPersistence.INSTANCE, environment, configuration, new AnalyticsFactory()); } - public SegmentBroker(boolean isDebug, String userId, IdentifyTraitsPersistence identifyTraitsPersistence, Environment environment, ISegmentConfiguration configuration, Function analyticsFactory) { + public SegmentBroker( + boolean isDebug, + String userId, + IdentifyTraitsPersistence identifyTraitsPersistence, + Environment environment, + ISegmentConfiguration configuration, + Function analyticsFactory + ) { this.userId = userId; this.identifyTraitsPersistence = identifyTraitsPersistence; this.environment = environment; - this.analytics = new Lazy<>(() -> analyticsFactory.apply(getWriteKey(isDebug, configuration))); + this.analytics = new Lazy<>(() -> analyticsFactory.apply(configuration.getWriteKey(isDebug))); } @Override - public void send(TelemetryEvent event) { + public void send(Event event) { try { if (analytics.get() == null) { LOGGER.warn("Could not send " + event.getType() + " event '" + event.getName() + "': no analytics instance present."); @@ -121,21 +129,31 @@ public void send(TelemetryEvent event) { } } - private MessageBuilder toMessage(IdentifyMessage.Builder builder, TelemetryEvent event, Map context) { - IdentifyTraits identifyTraits = new IdentifyTraits( - environment.getLocale(), - environment.getTimezone(), - environment.getPlatform().getName(), - environment.getPlatform().getVersion(), - environment.getPlatform().getDistribution()); - if (!haveChanged(identifyTraits, identifyTraitsPersistence)) { - LOGGER.debug("Skipping identify message: already sent." + identifyTraits); + private MessageBuilder toMessage(IdentifyMessage.Builder builder, Event event, Map context) { + if (!addTraits(builder, event)) { return null; } return builder .userId(userId) - .traits(addIdentifyTraits(identifyTraits, event.getProperties())) - .context(context); + .context(context == null ? Collections.emptyMap() : context); + + } + + private boolean addTraits(IdentifyMessage.Builder builder, Event event) { + if (environment != null) { + IdentifyTraits identifyTraits = new IdentifyTraits( + environment.getLocale(), + environment.getTimezone(), + environment.getPlatform().getName(), + environment.getPlatform().getVersion(), + environment.getPlatform().getDistribution()); + if (!haveChanged(identifyTraits, identifyTraitsPersistence)) { + LOGGER.debug("Skipping identify message: already sent." + identifyTraits); + return false; + } + builder.traits(addIdentifyTraits(identifyTraits, event.getProperties())); + } + return true; } /** @@ -164,7 +182,7 @@ private synchronized boolean haveChanged(IdentifyTraits identifyTraits, Identify return properties; } - private MessageBuilder toMessage(TrackMessage.Builder builder, TelemetryEvent event, Map context) { + private MessageBuilder toMessage(TrackMessage.Builder builder, Event event, Map context) { return builder .userId(userId) .properties(addTrackProperties(event.getProperties())) @@ -172,17 +190,19 @@ private MessageBuilder toMessage(TrackMessage.Builder builder, TelemetryEvent ev } private Map addTrackProperties(final Map properties) { - Application application = environment.getIde(); - putIfNotNull(PROP_APP_NAME, application.getName(), properties); - putIfNotNull(PROP_APP_VERSION, application.getVersion(), properties); - application.getProperties().forEach( - appProperty -> putIfNotNull(appProperty.getKey(), String.valueOf(appProperty.getValue()), properties)); - putIfNotNull(PROP_EXTENSION_NAME, environment.getPlugin().getName(), properties); - putIfNotNull(PROP_EXTENSION_VERSION, environment.getPlugin().getVersion(), properties); + if (environment != null) { + Application application = environment.getIde(); + putIfNotNull(PROP_APP_NAME, application.getName(), properties); + putIfNotNull(PROP_APP_VERSION, application.getVersion(), properties); + application.getProperties().forEach( + appProperty -> putIfNotNull(appProperty.getKey(), String.valueOf(appProperty.getValue()), properties)); + putIfNotNull(PROP_EXTENSION_NAME, environment.getPlugin().getName(), properties); + putIfNotNull(PROP_EXTENSION_VERSION, environment.getPlugin().getVersion(), properties); + } return properties; } - private MessageBuilder toMessage(PageMessage.Builder builder, TelemetryEvent event, Map context) { + private MessageBuilder toMessage(PageMessage.Builder builder, Event event, Map context) { return builder .userId(userId) .properties(event.getProperties()) @@ -199,6 +219,9 @@ private void putIfNotNull(String key, String value, Map properti } private Map createContext(Environment environment) { + if (environment == null) { + return Collections.emptyMap(); + } return new MapBuilder() .mapPair(PROP_APP) .pair(PROP_NAME, environment.getIde().getName()) @@ -218,20 +241,12 @@ private Map createContext(Environment environment) { .build(); } + @Override public void dispose() { analytics.get().flush(); analytics.get().shutdown(); } - - private String getWriteKey(boolean isDebug, ISegmentConfiguration configuration) { - if (isDebug) { - return configuration.getDebugWriteKey(); - } else { - return configuration.getNormalWriteKey(); - } - } - private static class AnalyticsFactory implements Function { private static final int FLUSH_INTERVAL = 10000; diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/FileUtils.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/FileUtils.java index 15aad373..f577f590 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/FileUtils.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/FileUtils.java @@ -17,6 +17,9 @@ public class FileUtils { + private FileUtils() { + } + /** * Creates the file for the given path and the folder that contains it. * Does nothing if it any of those already exist. diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/Lazy.java b/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/Lazy.java index 01d07b6a..ccfa04ef 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/Lazy.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/core/util/Lazy.java @@ -25,7 +25,12 @@ public Lazy(Supplier factory) { public T get() { if (value == null) { this.value = factory.get(); + onCreated(value); } return value; } + + protected void onCreated(T value) { + // override to customized + } } diff --git a/src/main/java/com/redhat/devtools/intellij/telemetry/ui/utils/NotificationGroupFactory.java b/src/main/java/com/redhat/devtools/intellij/telemetry/ui/utils/NotificationGroupFactory.java index f6fcfb1e..473240a5 100644 --- a/src/main/java/com/redhat/devtools/intellij/telemetry/ui/utils/NotificationGroupFactory.java +++ b/src/main/java/com/redhat/devtools/intellij/telemetry/ui/utils/NotificationGroupFactory.java @@ -37,6 +37,8 @@ */ public class NotificationGroupFactory { + private NotificationGroupFactory() {} + public static NotificationGroup create(String displayId, NotificationDisplayType type, boolean logByDefault) { try { // < IC-2021.3 diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index c15d0bd1..2d86daf5 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -42,5 +42,7 @@ displayName="Red Hat Telemetry"/> + diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/ClasspathConfigurationTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/ClasspathConfigurationTest.java index 5d45966e..312ae1c0 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/ClasspathConfigurationTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/ClasspathConfigurationTest.java @@ -24,13 +24,13 @@ class ClasspathConfigurationTest { private ClasspathConfiguration config; @BeforeEach - public void beforeEach() throws IOException { + void beforeEach() throws IOException { Path path = Paths.get("segment.properties"); this.config = new ClasspathConfiguration(path); } @Test - public void get_loads_property_file() throws IOException { + void get_loads_property_file() throws IOException { // given // when String value = config.get("writeKey"); diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/FileConfigurationTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/FileConfigurationTest.java index 910315a4..6f1abf36 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/FileConfigurationTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/FileConfigurationTest.java @@ -30,14 +30,14 @@ class FileConfigurationTest { private static final Pair property1 = new Pair<>("luke", "jedy"); @BeforeEach - public void beforeEach() throws IOException { + void beforeEach() throws IOException { this.path = Paths.get(System.getProperty("java.io.tmpdir"), getClass().getSimpleName() + ".properties"); createPropertyFile(path, property1); this.config = new FileConfiguration(path); } @Test - public void get_loads_property_file() throws IOException { + void get_loads_property_file() throws IOException { // given // when String value = config.get(property1.first); @@ -46,7 +46,7 @@ public void get_loads_property_file() throws IOException { } @Test - public void get_returns_null_if_no_file_exists() throws IOException { + void get_returns_null_if_no_file_exists() throws IOException { // given Files.delete(path); // when diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SaveableFileConfigurationTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SaveableFileConfigurationTest.java index bea670cb..abd410cb 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SaveableFileConfigurationTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SaveableFileConfigurationTest.java @@ -31,14 +31,14 @@ class SaveableFileConfigurationTest { private static final Pair property2 = new Pair<>("anakin", "sith"); @BeforeEach - public void beforeEach() throws IOException { + void beforeEach() throws IOException { this.path = Paths.get(System.getProperty("java.io.tmpdir"), getClass().getSimpleName() + ".properties"); createPropertyFile(path, property1); this.config = new SaveableFileConfiguration(path); } @Test - public void save_creates_property_file_if_it_doesnt_exist() throws IOException { + void save_creates_property_file_if_it_doesnt_exist() throws IOException { // given Files.delete(path); assertThat(Files.exists(path)).isFalse(); @@ -49,7 +49,7 @@ public void save_creates_property_file_if_it_doesnt_exist() throws IOException { } @Test - public void save_saves_additional_properties() throws IOException { + void save_saves_additional_properties() throws IOException { // given assertThat(config.get(property2.first)).isNull(); config.put(property2.first, property2.second); diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SegmentConfigurationTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SegmentConfigurationTest.java index 6211d06a..d5ed6bc8 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SegmentConfigurationTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/configuration/SegmentConfigurationTest.java @@ -23,7 +23,7 @@ class SegmentConfigurationTest { private SegmentConfiguration config; @BeforeEach - public void beforeEach() { + void beforeEach() { this.config = new SegmentConfiguration(getClass().getClassLoader()); } diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/Fakes.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/Fakes.java index b8df33ba..7dbd21db 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/Fakes.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/Fakes.java @@ -2,7 +2,9 @@ import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration; import com.redhat.devtools.intellij.telemetry.core.service.segment.ISegmentConfiguration; +import org.mockito.stubbing.Answer; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -45,6 +47,15 @@ public static ISegmentConfiguration segmentConfiguration(String normalWriteKey, .thenReturn(normalWriteKey); when(configuration.getDebugWriteKey()) .thenReturn(debugWriteKey); + when(configuration.getWriteKey(anyBoolean())) + .thenAnswer((Answer) invocation -> { + Boolean isDebug = invocation.getArgument(0); + if (isDebug) { + return debugWriteKey; + } else { + return normalWriteKey; + } + }); return configuration; } } diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilderIntegrationTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilderIntegrationTest.java new file mode 100644 index 00000000..a789b385 --- /dev/null +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilderIntegrationTest.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2021 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.telemetry.core.service; + +import com.jakewharton.retrofit.Ok3Client; +import com.redhat.devtools.intellij.telemetry.core.IService; +import com.redhat.devtools.intellij.telemetry.core.service.segment.ISegmentConfiguration; +import com.redhat.devtools.intellij.telemetry.core.service.segment.IdentifyTraitsPersistence; +import com.redhat.devtools.intellij.telemetry.core.service.segment.SegmentBroker; +import com.redhat.devtools.intellij.telemetry.util.BlockingFlush; +import com.redhat.devtools.intellij.telemetry.util.StdOutLogging; +import com.segment.analytics.Analytics; +import okhttp3.OkHttpClient; +import org.junit.Ignore; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import retrofit.client.Client; + +import java.util.concurrent.TimeUnit; + +import static com.redhat.devtools.intellij.telemetry.core.service.Fakes.segmentConfiguration; +import static com.redhat.devtools.intellij.telemetry.core.service.FeedbackMessageBuilder.*; +import static org.mockito.Mockito.mock; + +@Ignore("For manual testing purposes only") +class FeedbackMessageBuilderIntegrationTest { + + public static final String SEGMENT_WRITE_KEY = "ySk3bh8S8hDIGVKX9FQ1BMGOdFxbsufn"; + + private BlockingFlush blockingFlush; + private Analytics analytics; + private FeedbackMessage message; + + @BeforeEach + void before() { + this.blockingFlush = BlockingFlush.create(); + this.analytics = createAnalytics(blockingFlush, createClient()); + ISegmentConfiguration configuration = segmentConfiguration(SEGMENT_WRITE_KEY, ""); + SegmentBroker broker = new SegmentBroker( + false, + UserId.INSTANCE.get(), + IdentifyTraitsPersistence.INSTANCE, + null, + configuration, + key -> analytics); + IService service = new FeedbackService(broker); + this.message = new FeedbackMessageBuilder(service) + .feedback("Testing Feedback"); + } + + @AfterEach + void after() { + shutdownAnalytics(); + } + + @Test + void should_send_track_event() { + // given + message.property("jedi", "yoda") + .property("use", "the force"); + // when + message.send(); + // then + } + + private Analytics createAnalytics(BlockingFlush blockingFlush, Client client) { + return Analytics.builder(SEGMENT_WRITE_KEY) + .plugin(new StdOutLogging()) + .plugin(blockingFlush.plugin()) + .client(client) + .build(); + } + + private Client createClient() { + return new Ok3Client( + new OkHttpClient.Builder() + .connectTimeout(5, TimeUnit.SECONDS) + .readTimeout(5, TimeUnit.SECONDS) + .writeTimeout(5, TimeUnit.SECONDS) + .build()); + } + + private void shutdownAnalytics() { + analytics.flush(); + blockingFlush.block(); + analytics.shutdown(); + } + +} diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilderTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilderTest.java new file mode 100644 index 00000000..2b7106c9 --- /dev/null +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/FeedbackMessageBuilderTest.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.telemetry.core.service; + +import com.redhat.devtools.intellij.telemetry.core.IService; +import com.redhat.devtools.intellij.telemetry.core.service.FeedbackMessageBuilder.FeedbackMessage; +import com.redhat.devtools.intellij.telemetry.core.service.FeedbackMessageBuilder.FeedbackServiceFacade; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.ACTION; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +class FeedbackMessageBuilderTest { + + private final IService serviceFacadeMock = mock(IService.class); + private final FeedbackMessageBuilder builder = new FeedbackMessageBuilder(serviceFacadeMock); + private final IService service = mock(IService.class); + private final TestableFeedbackServiceFacade serviceFacade = spy(new TestableFeedbackServiceFacade(service)); + private final Event event = mock(Event.class); + + @Test + void action_should_create_message_with_action_type() { + // given + // when + FeedbackMessage message = builder.feedback("azrael"); + // then + assertThat(message.getType()).isEqualTo(ACTION); + } + + @Test + void action_should_create_message_with_given_name() { + // given + String name = "papa smurf"; + // when + FeedbackMessage message = builder.feedback(name); + // then + assertThat(message.getName()).isEqualTo(name); + } + + @Test + void property_should_add_property_with_given_key_and_name() { + // given + String key = "likes"; + String value = "papa smurf"; + // when + FeedbackMessage message = builder.feedback("smurfette").property(key, value); + // then + assertThat(message.getProperty(key)).isEqualTo(value); + } + + @Test + void property_should_ignore_property_with_null_key() { + // given + FeedbackMessage message = builder.feedback("smurfette"); + int beforeAdding = message.properties().size(); + // when + message.property(null, "papa smurf"); + // then + assertThat(message.properties()).hasSize(beforeAdding); + } + + @Test + void property_should_ignore_property_with_null_value() { + // given + FeedbackMessage message = builder.feedback("smurfette"); + int beforeAdding = message.properties().size(); + // when + message.property("likes", null); + // then + assertThat(message.properties()).hasSize(beforeAdding); + } + + @Test + void send_should_send_message_via_service_facade() { + // given + FeedbackMessage message = builder.feedback("gargamel"); + // when + message.send(); + // then + verify(serviceFacadeMock).send(any(Event.class)); + } + + @Test + void send_should_send_event_with_given_type_name_and_properties() { + // given + String name = "gargamel"; + String key1 = "the lovliest"; + String value1 = "smurfette"; + String key2 = "the smallest"; + String value2 = "baby smurf"; + FeedbackMessage message = builder.feedback(name) + .property(key1, value1) + .property(key2, value2); + ArgumentCaptor eventArgument = ArgumentCaptor.forClass(Event.class); + // when + message.send(); + // then + verify(serviceFacadeMock).send(eventArgument.capture()); + Event event = eventArgument.getValue(); + assertThat(event.getType()).isEqualTo(ACTION); + assertThat(event.getName()).isEqualTo(name); + assertThat(event.getProperties()) + .containsEntry(key1, value1) + .containsEntry(key2,value2); + } + + @Test + void send_should_send_to_same_facade_instance() { + // given + FeedbackMessage message1 = builder.feedback("gargamel"); + FeedbackMessage message2 = builder.feedback("azrael"); + FeedbackMessage message3 = builder.feedback("papa smurf"); + // when + message1.send(); + message2.send(); + message3.send(); + // then + verify(serviceFacadeMock, times(3)).send(any(Event.class)); + } + + @Test + void serviceFacade_send_should_create_service_once_only() { + // given + // when + serviceFacade.send(event); + serviceFacade.send(event); + serviceFacade.send(event); + // then + verify(serviceFacade, times(1)).onCreated(any()); + } + + private static class TestableFeedbackServiceFacade extends FeedbackServiceFacade { + + protected TestableFeedbackServiceFacade(IService service) { + super(() -> service); + } + + /* public for testing purposes */ + @Override + public void onCreated(IService value) { + super.onCreated(value); + } + } + +} diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilderTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilderTest.java index 3ff8b4f4..241582de 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilderTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryMessageBuilderTest.java @@ -12,7 +12,7 @@ import com.intellij.ide.AppLifecycleListener; import com.intellij.util.messages.MessageBusConnection; -import com.redhat.devtools.intellij.telemetry.core.ITelemetryService; +import com.redhat.devtools.intellij.telemetry.core.IService; import com.redhat.devtools.intellij.telemetry.core.util.AnonymizeUtils; import com.redhat.devtools.intellij.telemetry.core.util.TimeUtils; import org.junit.jupiter.api.Test; @@ -24,33 +24,32 @@ import java.time.LocalTime; import java.time.temporal.ChronoUnit; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.ACTION; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.STARTUP; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.ACTION; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.STARTUP; +import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.ActionMessage; import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.ActionMessage.PROP_DURATION; import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.ActionMessage.PROP_RESULT; import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.ShutdownMessage; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.ActionMessage; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.ServiceFacade; +import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.TelemetryServiceFacade; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -public class TelemetryMessageBuilderTest { - - private ServiceFacade serviceFacadeMock = mock(ServiceFacade.class); - private TelemetryMessageBuilder builder = new TelemetryMessageBuilder(serviceFacadeMock); +class TelemetryMessageBuilderTest { - private ITelemetryService service = mock(ITelemetryService.class); - private MessageBusConnection bus = mock(MessageBusConnection.class); - private TestableServiceFacade serviceFacade = spy(new TestableServiceFacade(service, bus)); - private TelemetryEvent event = new TelemetryEvent(ACTION, "smurfette collects mushrooms"); + private final TelemetryServiceFacade serviceFacadeMock = mock(TelemetryServiceFacade.class); + private final TelemetryMessageBuilder builder = new TelemetryMessageBuilder(serviceFacadeMock); + private final IService service = mock(IService.class); + private final MessageBusConnection bus = mock(MessageBusConnection.class); + private final TestableTelemetryServiceFacade serviceFacade = spy(new TestableTelemetryServiceFacade(service, bus)); + private final Event event = mock(Event.class); @Test - public void action_should_create_message_with_action_type() { + void action_should_create_message_with_action_type() { // given // when ActionMessage message = builder.action("azrael"); @@ -59,7 +58,7 @@ public void action_should_create_message_with_action_type() { } @Test - public void action_should_create_message_with_given_name() { + void action_should_create_message_with_given_name() { // given String name = "papa smurf"; // when @@ -69,7 +68,7 @@ public void action_should_create_message_with_given_name() { } @Test - public void property_should_add_property_with_given_key_and_name() { + void property_should_add_property_with_given_key_and_name() { // given String key = "likes"; String value = "papa smurf"; @@ -80,39 +79,39 @@ public void property_should_add_property_with_given_key_and_name() { } @Test - public void property_should_ignore_property_with_null_key() { + void property_should_ignore_property_with_null_key() { // given ActionMessage message = builder.action("smurfette"); int beforeAdding = message.properties().size(); // when message.property(null, "papa smurf"); // then - assertThat(message.properties().size()).isEqualTo(beforeAdding); + assertThat(message.properties()).hasSize(beforeAdding); } @Test - public void property_should_ignore_property_with_null_value() { + void property_should_ignore_property_with_null_value() { // given ActionMessage message = builder.action("smurfette"); int beforeAdding = message.properties().size(); // when message.property("likes", null); // then - assertThat(message.properties().size()).isEqualTo(beforeAdding); + assertThat(message.properties()).hasSize(beforeAdding); } @Test - public void send_should_send_message_via_service_facade() { + void send_should_send_message_via_service_facade() { // given ActionMessage message = builder.action("gargamel"); // when message.send(); // then - verify(serviceFacadeMock).send(any(TelemetryEvent.class)); + verify(serviceFacadeMock).send(any(Event.class)); } @Test - public void send_should_send_event_with_given_type_name_and_properties() { + void send_should_send_event_with_given_type_name_and_properties() { // given String name = "gargamel"; String key1 = "the lovliest"; @@ -122,80 +121,80 @@ public void send_should_send_event_with_given_type_name_and_properties() { ActionMessage message = builder.action(name) .property(key1, value1) .property(key2, value2); - ArgumentCaptor eventArgument = ArgumentCaptor.forClass(TelemetryEvent.class); + ArgumentCaptor eventArgument = ArgumentCaptor.forClass(Event.class); // when message.send(); // then verify(serviceFacadeMock).send(eventArgument.capture()); - TelemetryEvent event = eventArgument.getValue(); + Event event = eventArgument.getValue(); assertThat(event.getType()).isEqualTo(ACTION); assertThat(event.getName()).isEqualTo(name); - assertThat(event.getProperties()).containsEntry(key1, value1); - assertThat(event.getProperties()).containsEntry(key2,value2); + assertThat(event.getProperties()) + .containsEntry(key1, value1) + .containsEntry(key2,value2); } @Test - public void send_should_set_duration() throws InterruptedException { + void send_should_set_duration() { // given ActionMessage message = builder.action("jolly jumper"); // when - TelemetryEvent event = message.send(); + Event event = message.send(); // then dont override existing duration assertThat(TimeUtils.toDuration(event.getProperties().get(PROP_DURATION))) .isNotNull(); } @Test - public void send_should_NOT_set_duration_if_already_exists() throws InterruptedException { + void send_should_NOT_set_duration_if_already_exists() { // given ActionMessage message = builder.action("jolly jumper"); Duration existing = Duration.ofDays(7); message.duration(existing); // when - TelemetryEvent event = message.send(); + Event event = message.send(); // then dont override existing duration assertThat(TimeUtils.toDuration(event.getProperties().get(PROP_DURATION))) .isEqualTo(existing); } @Test - public void send_should_set_result() throws InterruptedException { + void send_should_set_result() { // given ActionMessage message = builder.action("jolly jumper"); // when - TelemetryEvent event = message.send(); + Event event = message.send(); // then assertThat(event.getProperties().get(PROP_RESULT)) .isNotNull(); } @Test - public void send_should_NOT_set_result_if_error_exists() throws InterruptedException { + void send_should_NOT_set_result_if_error_exists() { // given ActionMessage message = builder.action("jolly jumper"); message.error("lost luky luke"); // when - TelemetryEvent event = message.send(); + Event event = message.send(); // then assertThat(event.getProperties().get(PROP_RESULT)) .isNull(); } @Test - public void send_should_NOT_set_result_if_result_exists() throws InterruptedException { + void send_should_NOT_set_result_if_result_exists() { // given ActionMessage message = builder.action("jolly jumper"); String result = "spits like a cowboy"; message.result(result); // when - TelemetryEvent event = message.send(); + Event event = message.send(); // then dont override existing result - assertThat(event.getProperties().get(PROP_RESULT)) - .isEqualTo(result); + assertThat(event.getProperties()).containsEntry(PROP_RESULT, result); } @Test - public void send_should_send_to_same_facade_instance() { + void send_should_send_to_same_facade_instance() { // given ActionMessage message1 = builder.action("gargamel"); ActionMessage message2 = builder.action("azrael"); @@ -205,11 +204,11 @@ public void send_should_send_to_same_facade_instance() { message2.send(); message3.send(); // then - verify(serviceFacadeMock, times(3)).send(any(TelemetryEvent.class)); + verify(serviceFacadeMock, times(3)).send(any(Event.class)); } @Test - public void finished_should_set_duration() throws InterruptedException { + void finished_should_set_duration() throws InterruptedException { // given ActionMessage message = builder.action("inspector gadget"); final long delay = 1 * 1000; @@ -222,7 +221,7 @@ public void finished_should_set_duration() throws InterruptedException { } @Test - public void finished_should_set_duration_btw_given_start_and_finished_when_stop_is_new_day() { + void finished_should_set_duration_btw_given_start_and_finished_when_stop_is_new_day() { // given ActionMessage message = builder.action("inspector gadget hits the button"); LocalDateTime started = LocalDateTime.of(LocalDate.now(), LocalTime.of(23, 0)); @@ -237,7 +236,7 @@ public void finished_should_set_duration_btw_given_start_and_finished_when_stop_ } @Test - public void finished_should_set_duration_btw_given_start_and_finished_when_finished_is_in_new_year() { + void finished_should_set_duration_btw_given_start_and_finished_when_finished_is_in_new_year() { // given ActionMessage message = builder.action("the daltons break out"); LocalDateTime started = LocalDateTime.of(LocalDate.now(), LocalTime.of(23, 0)); @@ -252,7 +251,7 @@ public void finished_should_set_duration_btw_given_start_and_finished_when_finis } @Test - public void result_should_set_result_property() { + void result_should_set_result_property() { // given ActionMessage message = builder.action("flinstones"); String result = "crushed stones"; @@ -264,7 +263,7 @@ public void result_should_set_result_property() { } @Test - public void result_should_clear_error() { + void result_should_clear_error() { // given ActionMessage message = builder.action("flinstones") .error("went bowling"); @@ -276,7 +275,7 @@ public void result_should_clear_error() { } @Test - public void error_should_set_error_property() { + void error_should_set_error_property() { // given ActionMessage message = builder.action("the simpsons"); String error = "nuclear plant emergency"; @@ -288,7 +287,7 @@ public void error_should_set_error_property() { } @Test - public void error_should_NOT_NPE_for_given_null_exception() { + void error_should_NOT_NPE_for_given_null_exception() { // given ActionMessage message = builder.action("the simpsons"); // when @@ -299,7 +298,7 @@ public void error_should_NOT_NPE_for_given_null_exception() { } @Test - public void error_should_clear_result() { + void error_should_clear_result() { // given ActionMessage message = builder.action("the simpsons") .result("went skateboarding"); @@ -311,7 +310,7 @@ public void error_should_clear_result() { } @Test - public void error_should_anonymize_email() { + void error_should_anonymize_email() { // given ActionMessage message = builder.action("the simpsons"); String email = "bart@simpsons.com"; @@ -323,7 +322,7 @@ public void error_should_anonymize_email() { } @Test - public void error_should_anonymize_username() { + void error_should_anonymize_username() { // given ActionMessage message = builder.action("the simpsons"); // when @@ -335,7 +334,7 @@ public void error_should_anonymize_username() { } @Test - public void error_should_anonymize_homedir() { + void error_should_anonymize_homedir() { // given ActionMessage message = builder.action("the smurfs"); // when @@ -347,7 +346,7 @@ public void error_should_anonymize_homedir() { } @Test - public void error_should_anonymize_tmpdir() { + void error_should_anonymize_tmpdir() { // given ActionMessage message = builder.action("the smurfs"); // when @@ -359,7 +358,7 @@ public void error_should_anonymize_tmpdir() { } @Test - public void error_should_anonymize_IP_address() { + void error_should_anonymize_IP_address() { // given ActionMessage message = builder.action("the smurfs"); // when @@ -371,20 +370,20 @@ public void error_should_anonymize_IP_address() { } @Test - public void serviceFacade_send_should_lazy_create_service() { + void serviceFacade_send_should_lazy_create_service() { // given // when serviceFacade.send(event); serviceFacade.send(event); serviceFacade.send(event); // then - verify(serviceFacade, times(1)).createService(any()); + verify(serviceFacade, times(1)).onCreated(any()); } @Test - public void serviceFacade_send_should_send_given_event_and_startup_message() { + void serviceFacade_send_should_send_given_event_and_startup_message() { // given - ArgumentCaptor events = ArgumentCaptor.forClass(TelemetryEvent.class); + ArgumentCaptor events = ArgumentCaptor.forClass(Event.class); // when serviceFacade.send(event); // then @@ -395,7 +394,7 @@ public void serviceFacade_send_should_send_given_event_and_startup_message() { } @Test - public void serviceFacade_send_should_subscribe_to_AppLifeCycle() { + void serviceFacade_send_should_subscribe_to_AppLifeCycle() { // given // when serviceFacade.send(event); @@ -404,7 +403,7 @@ public void serviceFacade_send_should_subscribe_to_AppLifeCycle() { } @Test - public void serviceFacade_send_should_register_IDE_shutdown_listener() { + void serviceFacade_send_should_register_IDE_shutdown_listener() { // given ArgumentCaptor listenerArgument = ArgumentCaptor.forClass(AppLifecycleListener.class); serviceFacade.send(event); @@ -417,7 +416,7 @@ public void serviceFacade_send_should_register_IDE_shutdown_listener() { } @Test - public void shutdownMessage_should_report_session_duration() { + void shutdownMessage_should_report_session_duration() { // given LocalDateTime startup = LocalDateTime.of(LocalDate.now(), LocalTime.of(23, 1)); LocalDateTime shutdown = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.of(4, 2)); @@ -428,29 +427,21 @@ public void shutdownMessage_should_report_session_duration() { assertThat(message.getSessionDuration()).isEqualTo(TimeUtils.toString(duration)); } - private class TestableServiceFacade extends ServiceFacade { - private final ITelemetryService service; + private static class TestableTelemetryServiceFacade extends TelemetryServiceFacade { private final MessageBusConnection bus; - protected TestableServiceFacade(ITelemetryService service, MessageBusConnection bus) { - super(mock(ClassLoader.class)); - this.service = service; + protected TestableTelemetryServiceFacade(IService service, MessageBusConnection bus) { + super(() -> service); this.bus = bus; } - @Override - protected ITelemetryService createService(ClassLoader classLoader) { - return service; - } - @Override protected MessageBusConnection createMessageBusConnection() { return bus; } @Override - public void sendShutdown() { - } + public void sendShutdown() {} } } diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceIntegrationTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceIntegrationTest.java index 83725933..33bdf799 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceIntegrationTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceIntegrationTest.java @@ -12,7 +12,7 @@ import com.intellij.util.messages.MessageBusConnection; import com.jakewharton.retrofit.Ok3Client; -import com.redhat.devtools.intellij.telemetry.core.ITelemetryService; +import com.redhat.devtools.intellij.telemetry.core.IService; import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration; import com.redhat.devtools.intellij.telemetry.core.service.segment.ISegmentConfiguration; import com.redhat.devtools.intellij.telemetry.core.service.segment.IdentifyTraitsPersistence; @@ -32,7 +32,7 @@ import static com.redhat.devtools.intellij.telemetry.core.service.Fakes.environment; import static com.redhat.devtools.intellij.telemetry.core.service.Fakes.segmentConfiguration; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.ACTION; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.ACTION; import static org.mockito.Mockito.mock; @Ignore("For manual testing purposes only") @@ -52,8 +52,8 @@ class TelemetryServiceIntegrationTest { private BlockingFlush blockingFlush; private Analytics analytics; - private ITelemetryService service; - private TelemetryEvent event; + private IService service; + private Event event; @BeforeEach void before() { @@ -83,7 +83,7 @@ void before() { broker, mock(MessageBusConnection.class), mock(TelemetryNotifications.class)); - this.event = new TelemetryEvent(ACTION, "Testing Telemetry"); + this.event = new Event(ACTION, "Testing Telemetry"); } @AfterEach diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceTest.java index 6df0fd9a..93d38132 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/TelemetryServiceTest.java @@ -11,7 +11,7 @@ package com.redhat.devtools.intellij.telemetry.core.service; import com.intellij.util.messages.MessageBusConnection; -import com.redhat.devtools.intellij.telemetry.core.ITelemetryService; +import com.redhat.devtools.intellij.telemetry.core.IService; import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration; import com.redhat.devtools.intellij.telemetry.core.service.segment.SegmentBroker; import com.redhat.devtools.intellij.telemetry.ui.TelemetryNotifications; @@ -22,8 +22,8 @@ import java.util.List; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.USER; import static com.redhat.devtools.intellij.telemetry.core.service.Fakes.telemetryConfiguration; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.USER; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.atLeastOnce; @@ -34,23 +34,20 @@ class TelemetryServiceTest { - private static final String TIMEZONE = "GMT+2:00"; - private static final String LOCALE = "en/US"; - private static final String COUNTRY = "Switzerland"; private SegmentBroker broker; private MessageBusConnection bus; - private ITelemetryService service; - private TelemetryEvent event; + private IService service; + private Event event; private TelemetryNotifications notifications; @BeforeEach - public void before() { + void before() { this.broker = createSegmentBroker(); this.bus = createMessageBusConnection(); this.notifications = createTelemetryNotifications(); TelemetryConfiguration configuration = telemetryConfiguration(true, true); this.service = new TelemetryService(configuration, broker, bus, notifications); - this.event = new TelemetryEvent(null, "Testing Telemetry", null); + this.event = new Event(null, "Testing Telemetry", null); } @Test @@ -59,7 +56,7 @@ void send_should_send_if_is_enabled() { // when service.send(event); // then - verify(broker, atLeastOnce()).send(any(TelemetryEvent.class)); + verify(broker, atLeastOnce()).send(any(Event.class)); } @Test @@ -70,7 +67,7 @@ void send_should_NOT_send_if_is_NOT_configured() { // when service.send(event); // then - verify(broker, never()).send(any(TelemetryEvent.class)); + verify(broker, never()).send(any(Event.class)); } @Test @@ -82,24 +79,24 @@ void send_should_send_all_events_once_it_gets_enabled() { service.send(event); service.send(event); // then - verify(broker, never()).send(any(TelemetryEvent.class)); + verify(broker, never()).send(any(Event.class)); // when config gets enabled doReturn(true) .when(configuration).isEnabled(); service.send(event); // then - verify(broker, VerificationModeFactory.atLeast(3)).send(any(TelemetryEvent.class)); + verify(broker, VerificationModeFactory.atLeast(3)).send(any(Event.class)); } @Test void send_should_send_userinfo() { // given - ArgumentCaptor eventArgument = ArgumentCaptor.forClass(TelemetryEvent.class); + ArgumentCaptor eventArgument = ArgumentCaptor.forClass(Event.class); // when service.send(event); // then verify(broker, atLeastOnce()).send(eventArgument.capture()); - List allArguments = eventArgument.getAllValues(); + List allArguments = eventArgument.getAllValues(); assertThat(allArguments.size()).isGreaterThanOrEqualTo(2); assertThat(allArguments.get(0).getType()).isEqualTo(USER); } diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBrokerTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBrokerTest.java index e66ba231..c78793b8 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBrokerTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/service/segment/SegmentBrokerTest.java @@ -12,7 +12,7 @@ import com.redhat.devtools.intellij.telemetry.core.IMessageBroker; import com.redhat.devtools.intellij.telemetry.core.service.Environment; -import com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent; +import com.redhat.devtools.intellij.telemetry.core.service.Event; import com.segment.analytics.Analytics; import com.segment.analytics.messages.IdentifyMessage; import com.segment.analytics.messages.Message; @@ -27,10 +27,10 @@ import static com.redhat.devtools.intellij.telemetry.core.service.Fakes.environment; import static com.redhat.devtools.intellij.telemetry.core.service.Fakes.segmentConfiguration; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.ACTION; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.SHUTDOWN; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.STARTUP; -import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryEvent.Type.USER; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.ACTION; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.SHUTDOWN; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.STARTUP; +import static com.redhat.devtools.intellij.telemetry.core.service.Event.Type.USER; import static com.redhat.devtools.intellij.telemetry.core.service.segment.SegmentBroker.PROP_APP; import static com.redhat.devtools.intellij.telemetry.core.service.segment.SegmentBroker.PROP_APP_NAME; import static com.redhat.devtools.intellij.telemetry.core.service.segment.SegmentBroker.PROP_APP_VERSION; @@ -73,14 +73,14 @@ class SegmentBrokerTest { private IdentifyTraitsPersistence identifyTraitsPersistence; private Environment environment; private SegmentBroker broker; - private TelemetryEvent actionEvent; - private TelemetryEvent userEvent; - private TelemetryEvent startupEvent; - private TelemetryEvent shutdownEvent; + private Event actionEvent; + private Event userEvent; + private Event startupEvent; + private Event shutdownEvent; private ISegmentConfiguration configuration; @BeforeEach - public void before() { + void before() { this.analytics = createAnalytics(); this.identifyTraitsPersistence = mock(IdentifyTraitsPersistence.class); this.environment = environment( @@ -96,10 +96,10 @@ public void before() { COUNTRY); this.configuration = segmentConfiguration(NORMAL_WRITE_KEY, DEBUG_WRITE_KEY); this.broker = new SegmentBroker(false, USER_ID, identifyTraitsPersistence, environment, configuration, key -> analytics); - this.actionEvent = new TelemetryEvent(ACTION, "Action event"); - this.userEvent = new TelemetryEvent(USER, "User event"); - this.startupEvent = new TelemetryEvent(STARTUP, "Startup event"); - this.shutdownEvent = new TelemetryEvent(SHUTDOWN, "Startup event"); + this.actionEvent = new Event(ACTION, "Action event"); + this.userEvent = new Event(USER, "User event"); + this.startupEvent = new Event(STARTUP, "Startup event"); + this.shutdownEvent = new Event(SHUTDOWN, "Startup event"); } @Test @@ -112,7 +112,13 @@ public Analytics apply(String key) { return analytics; } }); - SegmentBroker broker = new SegmentBroker(false, USER_ID, identifyTraitsPersistence, environment, configuration, analyticsFactory); + SegmentBroker broker = new SegmentBroker( + false, + USER_ID, + identifyTraitsPersistence, + environment, + configuration, + analyticsFactory); // when broker.send(actionEvent); // then @@ -298,7 +304,7 @@ void send_should_NOT_add_NULL_properties_to_identify_message() { } @Test - void send_should_enqueue_track_message_with_properties() { + void send_should_enqueue_track_message_with_traits() { // given ArgumentCaptor builder = ArgumentCaptor.forClass(TrackMessage.Builder.class); // when @@ -312,6 +318,23 @@ void send_should_enqueue_track_message_with_properties() { assertThat(traits.get(PROP_EXTENSION_VERSION)).isEqualTo(EXTENSION_VERSION); } + @Test + void send_should_enqueue_track_message_with_additional_properties() { + // given + ArgumentCaptor builder = ArgumentCaptor.forClass(TrackMessage.Builder.class); + Map properties = actionEvent.getProperties(); + properties.put("jedi", "yoda"); + properties.put("sith", "darth sidious"); + // when + broker.send(actionEvent); + // then + verify(analytics).enqueue(builder.capture()); + Map traits = builder.getValue().build().properties(); + assertThat(traits.get("jedi")).isEqualTo("yoda"); + assertThat(traits.get("sith")).isEqualTo("darth sidious"); + } + + @Test void send_should_NOT_add_NULL_properties_to_track_message() { // given diff --git a/src/test/java/com/redhat/devtools/intellij/telemetry/core/util/AnonymizeUtilsTest.java b/src/test/java/com/redhat/devtools/intellij/telemetry/core/util/AnonymizeUtilsTest.java index c96b5e76..444ee055 100644 --- a/src/test/java/com/redhat/devtools/intellij/telemetry/core/util/AnonymizeUtilsTest.java +++ b/src/test/java/com/redhat/devtools/intellij/telemetry/core/util/AnonymizeUtilsTest.java @@ -16,7 +16,7 @@ public class AnonymizeUtilsTest { @Test - public void anonymizeEmail_should_replace_email() { + void anonymizeEmail_should_replace_email() { // given String email = "adietish@redhat.com"; String msgWithEmail = "This is the email address " + email + " within a message."; @@ -28,7 +28,7 @@ public void anonymizeEmail_should_replace_email() { } @Test - public void anonymizeEmail_should_NOT_replace_bogus_email() { + void anonymizeEmail_should_NOT_replace_bogus_email() { // given String bogusEmail = "adietish@redhat"; String msgWithBogusEmail = "This is the email address " + bogusEmail + " within a message."; @@ -40,7 +40,7 @@ public void anonymizeEmail_should_NOT_replace_bogus_email() { } @Test - public void anonymizeUserName_should_replace_username() { + void anonymizeUserName_should_replace_username() { // given String username = AnonymizeUtils.USER_NAME; String msgWithUsername = "This is the username " + username + " within a message."; @@ -52,7 +52,7 @@ public void anonymizeUserName_should_replace_username() { } @Test - public void anonymizeHomeDir_should_replace_homedir() { + void anonymizeHomeDir_should_replace_homedir() { // given String homeDir = AnonymizeUtils.HOME_DIR; String msgWithHomeDir = "This is the path to the " + homeDir + " within a message."; @@ -64,7 +64,7 @@ public void anonymizeHomeDir_should_replace_homedir() { } @Test - public void anonymizeHomeDir_should_NOT_replace_other_directory() { + void anonymizeHomeDir_should_NOT_replace_other_directory() { // given String otherDir = "C:\\\\Documents and Settings\\\\All Users"; String msgWithOtherDir = "This is the path to the " + otherDir + " within a message."; @@ -76,7 +76,7 @@ public void anonymizeHomeDir_should_NOT_replace_other_directory() { } @Test - public void anonymizeTmpDir_should_replace_tmpDir() { + void anonymizeTmpDir_should_replace_tmpDir() { // given String tmpDir = AnonymizeUtils.TMP_DIR; String msgWithTmpDir = "This is the path to the " + tmpDir + " within a message."; @@ -88,7 +88,7 @@ public void anonymizeTmpDir_should_replace_tmpDir() { } @Test - public void replaceIP_should_replace_IP() { + void replaceIP_should_replace_IP() { // given String ip = "192.168.0.1"; String msgWithIp = "This is the ip " + ip + " within a message."; @@ -100,7 +100,7 @@ public void replaceIP_should_replace_IP() { } @Test - public void replaceIP_should_NOT_replace_bogus_IP() { + void replaceIP_should_NOT_replace_bogus_IP() { // given String bogusIP = "10.0.12"; String msgWithIp = "This is the ip " + bogusIP + " within a message."; @@ -112,7 +112,7 @@ public void replaceIP_should_NOT_replace_bogus_IP() { } @Test - public void anonymizeResource_should_anonymize_resource_and_namespace() { + void anonymizeResource_should_anonymize_resource_and_namespace() { // given String resource = "smurf village"; String namespace = "blue county";