diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java index d9d5dd0f6a..50bc259bbb 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java @@ -24,6 +24,7 @@ public enum AnalyticsEvents { PAGE_REORDER, GENERATE_CRUD_PAGE("generate_CRUD_PAGE"), CREATE_SUPERUSER, + ACTION_RUN_BEHAVIOUR_CHANGED("action_RUN_BEHAVIOUR_CHANGED"), SUBSCRIBE_MARKETING_EMAILS, UNSUBSCRIBE_MARKETING_EMAILS, INSTALLATION_SETUP_COMPLETE("Installation Setup Complete"), diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java index 266781145e..a1b04e9f8e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java @@ -209,4 +209,6 @@ public class FieldNameCE { public static final String NONE = "none"; public static final String ORGANIZATION_ADMINISTRATOR_ROLE = "Organization Administrator Role"; public static final String INSTANCE_VARIABLES = "instanceVariables"; + + public static final String ACTION_CONFIGURATION_RUN_BEHAVIOUR = "runBehaviour"; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/RunBehaviourAnalyticsMetadata.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/RunBehaviourAnalyticsMetadata.java new file mode 100644 index 0000000000..f9735beabb --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/RunBehaviourAnalyticsMetadata.java @@ -0,0 +1,18 @@ +package com.appsmith.server.domains; + +import com.appsmith.external.models.ActionDTO; +import com.appsmith.external.models.CreatorContextType; +import com.appsmith.external.models.RunBehaviourEnum; +import com.appsmith.server.enums.RunBehaviourUpdateSource; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class RunBehaviourAnalyticsMetadata { + private ActionDTO actionDTO; + private RunBehaviourEnum oldRunBehaviour; + private CreatorContextType creatorContextType; + private RunBehaviourUpdateSource wasChangedBy; + private boolean isActionPartOfModuleInstance; +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/enums/RunBehaviourUpdateSource.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/enums/RunBehaviourUpdateSource.java new file mode 100644 index 0000000000..bde8c20015 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/enums/RunBehaviourUpdateSource.java @@ -0,0 +1,6 @@ +package com.appsmith.server.enums; + +public enum RunBehaviourUpdateSource { + SYSTEM, + USER +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/RunBehaviourAnalyticsUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/RunBehaviourAnalyticsUtils.java new file mode 100644 index 0000000000..61df4d6533 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/RunBehaviourAnalyticsUtils.java @@ -0,0 +1,106 @@ +package com.appsmith.server.helpers; + +import com.appsmith.external.constants.AnalyticsEvents; +import com.appsmith.external.models.ActionDTO; +import com.appsmith.external.models.CreatorContextType; +import com.appsmith.external.models.RunBehaviourEnum; +import com.appsmith.server.applications.base.ApplicationService; +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.domains.Application; +import com.appsmith.server.domains.ApplicationMode; +import com.appsmith.server.domains.RunBehaviourAnalyticsMetadata; +import com.appsmith.server.enums.RunBehaviourUpdateSource; +import com.appsmith.server.services.AnalyticsService; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import java.util.HashMap; +import java.util.Map; + +import static java.lang.Boolean.TRUE; + +@Component +@RequiredArgsConstructor +public class RunBehaviourAnalyticsUtils { + + private final AnalyticsService analyticsService; + private final ApplicationService applicationService; + + public Mono sendRunBehaviourChangedAnalytics(RunBehaviourAnalyticsMetadata params) { + ActionDTO actionDTO = params.getActionDTO(); + RunBehaviourEnum oldRunBehaviour = params.getOldRunBehaviour(); + CreatorContextType creatorType = params.getCreatorContextType(); + RunBehaviourUpdateSource wasChangedBy = params.getWasChangedBy(); + boolean isActionPartOfModuleInstance = params.isActionPartOfModuleInstance(); + + return Mono.justOrEmpty(actionDTO.getApplicationId()) + .flatMap(applicationService::findById) + .defaultIfEmpty(new Application()) + .flatMap(application -> { + Map data = new HashMap<>(); + data.put("actionId", ObjectUtils.defaultIfNull(actionDTO.getId(), "")); + data.put("name", ObjectUtils.defaultIfNull(actionDTO.getName(), "")); + data.put("pageId", ObjectUtils.defaultIfNull(actionDTO.getPageId(), "")); + data.put("applicationId", ObjectUtils.defaultIfNull(actionDTO.getApplicationId(), "")); + data.put("pluginId", ObjectUtils.defaultIfNull(actionDTO.getPluginId(), "")); + data.put("pluginName", ObjectUtils.defaultIfNull(actionDTO.getPluginName(), "")); + data.put("createdAt", ObjectUtils.defaultIfNull(actionDTO.getCreatedAt(), "")); + data.put("oldRunBehaviour", ObjectUtils.defaultIfNull(oldRunBehaviour, "")); + data.put("newRunBehaviour", ObjectUtils.defaultIfNull(actionDTO.getRunBehaviour(), "")); + data.put("pluginType", ObjectUtils.defaultIfNull(actionDTO.getPluginType(), "")); + data.put("actionConfiguration", ObjectUtils.defaultIfNull(actionDTO.getActionConfiguration(), "")); + + // Handle potential null createdAt for formatting + String actionCreated = actionDTO.getCreatedAt() != null + ? DateUtils.ISO_FORMATTER.format(actionDTO.getCreatedAt()) + : ""; + data.put("actionCreated", actionCreated); + + final String appMode = TRUE.equals(application.getViewMode()) + ? ApplicationMode.PUBLISHED.toString() + : ApplicationMode.EDIT.toString(); + + data.put("workspaceId", ObjectUtils.defaultIfNull(application.getWorkspaceId(), "")); + data.put(FieldName.APP_MODE, appMode); + data.put("appName", ObjectUtils.defaultIfNull(application.getName(), "")); + data.put("isExampleApp", ObjectUtils.defaultIfNull(application.isAppIsExample(), false)); + + // Handle datasource info with null checks + Map datasourceInfo = new HashMap<>(); + if (actionDTO.getDatasource() != null) { + datasourceInfo.put( + "name", + ObjectUtils.defaultIfNull( + actionDTO.getDatasource().getName(), "")); + datasourceInfo.put( + "dsIsMock", + ObjectUtils.defaultIfNull( + actionDTO.getDatasource().getIsMock(), false)); + datasourceInfo.put( + "dsIsTemplate", + ObjectUtils.defaultIfNull( + actionDTO.getDatasource().getIsTemplate(), false)); + datasourceInfo.put( + "dsId", + ObjectUtils.defaultIfNull( + actionDTO.getDatasource().getId(), "")); + } else { + datasourceInfo.put("name", ""); + datasourceInfo.put("dsIsMock", false); + datasourceInfo.put("dsIsTemplate", false); + datasourceInfo.put("dsId", ""); + } + data.put("datasource", datasourceInfo); + + data.put("wasChangedBy", ObjectUtils.defaultIfNull(wasChangedBy, "")); + data.put("creatorContextType", ObjectUtils.defaultIfNull(creatorType, CreatorContextType.PAGE)); + data.put("isActionPartOfModuleInstance", isActionPartOfModuleInstance); + + return analyticsService + .sendObjectEvent(AnalyticsEvents.ACTION_RUN_BEHAVIOUR_CHANGED, actionDTO, data) + .then(); // Return Mono for fire-and-forget + }); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java index 2cecaaa051..870d37c748 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java @@ -11,14 +11,19 @@ import com.appsmith.external.models.EntityReferenceType; import com.appsmith.external.models.Executable; import com.appsmith.external.models.Property; import com.appsmith.external.models.RunBehaviourEnum; +import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.domains.ExecutableDependencyEdge; import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewPage; +import com.appsmith.server.domains.RunBehaviourAnalyticsMetadata; +import com.appsmith.server.enums.RunBehaviourUpdateSource; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.CollectionUtils; import com.appsmith.server.helpers.ObservationHelperImpl; +import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils; import com.appsmith.server.onload.executables.ExecutableOnLoadService; +import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.AstService; import com.appsmith.server.services.FeatureFlagService; import com.fasterxml.jackson.core.type.TypeReference; @@ -94,6 +99,9 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { private final ObservationRegistry observationRegistry; private final ObservationHelperImpl observationHelper; private final FeatureFlagService featureFlagService; + private final AnalyticsService analyticsService; + private final ApplicationService applicationService; + private final RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils; /** * This function computes the sequenced on page load executables. @@ -307,6 +315,7 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { List messagesRef, CreatorContextType creatorType) { List toUpdateExecutables = new ArrayList<>(); + Map oldRunBehaviourMap = new HashMap<>(); // Fetch all the actions which exist in this page. Flux creatorContextExecutablesFlux = @@ -373,7 +382,6 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { turnedOnExecutableNames.removeAll(existingOnLoadExecutableNames); for (Executable executable : creatorContextExecutables) { - String executableName = executable.getUserExecutableName(); // If a user has ever set execute on load, this field can not be changed // automatically. @@ -382,6 +390,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { // this // condition is false. if (FALSE.equals(executable.getUserSetOnLoad())) { + // Store old run behaviour before updating + oldRunBehaviourMap.put(executableName, executable.getRunBehaviour()); // If this executable is no longer an onload executable, turn the execute on // load to @@ -457,8 +467,36 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { // Finally update the actions which require an update return Flux.fromIterable(toUpdateExecutables) - .flatMap(executable -> this.updateUnpublishedExecutable( - executable.getId(), executable, creatorType)) + .flatMap(executable -> { + RunBehaviourEnum oldRunBehaviour = oldRunBehaviourMap.getOrDefault( + executable.getUserExecutableName(), null); + return this.updateUnpublishedExecutable( + executable.getId(), executable, creatorType) + .flatMap(updatedExecutable -> { + if (!(updatedExecutable instanceof ActionDTO actionDTO)) { + return Mono.empty(); + } + return runBehaviourAnalyticsUtils + .sendRunBehaviourChangedAnalytics( + RunBehaviourAnalyticsMetadata.builder() + .actionDTO(actionDTO) + .oldRunBehaviour(oldRunBehaviour) + .creatorContextType(creatorType) + .wasChangedBy( + RunBehaviourUpdateSource.SYSTEM) + .isActionPartOfModuleInstance( + !isRegularAction(actionDTO)) + .build()) + .onErrorResume(e -> { + log.warn( + "Analytics publish failed for action {}: {}", + actionDTO.getId(), + e.getMessage()); + return Mono.empty(); + }); + }) + .then(); + }) .then(Mono.just(TRUE)); }); }); @@ -470,6 +508,11 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { return getExecutableOnLoadService(creatorType).findAndUpdateLayout(creatorId, layoutId, layout); } + // Regular action here means action created as part of application editor + protected boolean isRegularAction(ActionDTO actionDTO) { + return true; + } + private Mono updateUnpublishedExecutable( String id, Executable executable, CreatorContextType contextType) { if (executable instanceof ActionDTO actionDTO) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilImpl.java index a6bd2f1806..a11e155200 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilImpl.java @@ -1,8 +1,11 @@ package com.appsmith.server.onload.internal; +import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.domains.NewPage; import com.appsmith.server.helpers.ObservationHelperImpl; +import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils; import com.appsmith.server.onload.executables.ExecutableOnLoadService; +import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.AstService; import com.appsmith.server.services.FeatureFlagService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -20,13 +23,19 @@ public class OnLoadExecutablesUtilImpl extends OnLoadExecutablesUtilCEImpl imple ExecutableOnLoadService pageExecutableOnLoadService, ObservationRegistry observationRegistry, ObservationHelperImpl observationHelper, - FeatureFlagService featureFlagService) { + FeatureFlagService featureFlagService, + AnalyticsService analyticsService, + ApplicationService applicationService, + RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils) { super( astService, objectMapper, pageExecutableOnLoadService, observationRegistry, observationHelper, - featureFlagService); + featureFlagService, + analyticsService, + applicationService, + runBehaviourAnalyticsUtils); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java index cf61583245..963f6205df 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java @@ -1,6 +1,8 @@ package com.appsmith.server.services; +import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.datasources.base.DatasourceService; +import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -26,7 +28,9 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement DatasourceService datasourceService, PagePermission pagePermission, ActionPermission actionPermission, - ObservationRegistry observationRegistry) { + ObservationRegistry observationRegistry, + ApplicationService applicationService, + RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils) { super( analyticsService, @@ -38,6 +42,8 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement datasourceService, pagePermission, actionPermission, - observationRegistry); + observationRegistry, + applicationService, + runBehaviourAnalyticsUtils); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java index 84b4790a87..17cf55143a 100755 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java @@ -8,16 +8,20 @@ import com.appsmith.external.models.Datasource; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.RunBehaviourEnum; import com.appsmith.server.acl.AclPermission; +import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.datasources.base.DatasourceService; import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; +import com.appsmith.server.domains.RunBehaviourAnalyticsMetadata; import com.appsmith.server.dtos.ActionMoveDTO; import com.appsmith.server.dtos.CreateActionMetaDTO; import com.appsmith.server.dtos.PageDTO; +import com.appsmith.server.enums.RunBehaviourUpdateSource; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; +import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -64,6 +68,8 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { private final PagePermission pagePermission; private final ActionPermission actionPermission; private final ObservationRegistry observationRegistry; + private final ApplicationService applicationService; + private final RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils; /** * Called by Action controller to create Action @@ -321,16 +327,31 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { .flatMap(newAction -> { ActionDTO action = newAction.getUnpublishedAction(); + RunBehaviourEnum oldRunBehaviour = action.getRunBehaviour(); + action.setUserSetOnLoad(true); action.setRunBehaviour(behaviour); newAction.setUnpublishedAction(action); - return newActionService.save(newAction).flatMap(savedAction -> updateLayoutService - .updateLayoutByContextTypeAndContextId(action.getContextType(), action.getContextId()) - .name(UPDATE_PAGE_LAYOUT_BY_PAGE_ID) - .tap(Micrometer.observation(observationRegistry)) - .thenReturn(newActionService.generateActionByViewMode(savedAction, false))); + return newActionService + .save(newAction) + .flatMap(savedAction -> updateLayoutService + .updateLayoutByContextTypeAndContextId( + action.getContextType(), action.getContextId()) + .name(UPDATE_PAGE_LAYOUT_BY_PAGE_ID) + .tap(Micrometer.observation(observationRegistry)) + .thenReturn(newActionService.generateActionByViewMode(savedAction, false))) + .flatMap(updatedAction -> runBehaviourAnalyticsUtils + .sendRunBehaviourChangedAnalytics(RunBehaviourAnalyticsMetadata.builder() + .actionDTO(updatedAction) + .oldRunBehaviour(oldRunBehaviour) + .creatorContextType(action.getContextType()) + .wasChangedBy(RunBehaviourUpdateSource.USER) + .isActionPartOfModuleInstance(!isRegularAction(updatedAction)) + .build()) + .onErrorResume(e -> Mono.empty()) + .thenReturn(updatedAction)); }); } @@ -447,6 +468,11 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { }); } + // Regular action here means action created as part of application editor + protected boolean isRegularAction(ActionDTO actionDTO) { + return false; + } + protected Mono validateAndGenerateActionDomainBasedOnContext( ActionDTO action, CreateActionMetaDTO actionMetaDTO) { Boolean isJsAction = actionMetaDTO.getIsJsAction(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java index 5629e217a3..c19c9e15e8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java @@ -1244,6 +1244,7 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE } data.put(FieldName.ACTION_CONFIGURATION, rawActionConfiguration); data.put(FieldName.EVENT_DATA, eventData); + data.put(FieldName.ACTION_CONFIGURATION_RUN_BEHAVIOUR, actionDTO.getRunBehaviour()); return analyticsService .sendObjectEvent(AnalyticsEvents.EXECUTE_ACTION, actionDTO, data) .thenReturn(request); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImplTest.java index c110a62eb6..c2da944715 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImplTest.java @@ -6,8 +6,11 @@ import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.Executable; import com.appsmith.external.models.RunBehaviourEnum; +import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.helpers.ObservationHelperImpl; +import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils; import com.appsmith.server.onload.executables.ExecutableOnLoadService; +import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.AstService; import com.appsmith.server.services.FeatureFlagService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -30,6 +33,7 @@ import static java.lang.Boolean.TRUE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -58,23 +62,27 @@ public class OnLoadExecutablesUtilCEImplTest { private OnLoadExecutablesUtilCEImpl onLoadExecutablesUtilCE; + @Mock + private AnalyticsService analyticsService; + + @Mock + private ApplicationService applicationService; + + @Mock + private RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils; + @BeforeEach public void setUp() { - onLoadExecutablesUtilCE = new OnLoadExecutablesUtilCEImpl( - astService, - objectMapper, - executableOnLoadService, - observationRegistry, - observationHelper, - featureFlagService); - onLoadExecutablesUtilCE = spy(new OnLoadExecutablesUtilCEImpl( astService, objectMapper, executableOnLoadService, observationRegistry, observationHelper, - featureFlagService)); + featureFlagService, + analyticsService, + applicationService, + runBehaviourAnalyticsUtils)); ObservationRegistry.ObservationConfig mockObservationConfig = Mockito.mock(ObservationRegistry.ObservationConfig.class); @@ -107,6 +115,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class))) .thenAnswer(invocation -> Mono.just(invocation.getArgument(1))); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute Mono result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType); @@ -147,6 +158,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class))) .thenAnswer(invocation -> Mono.just(invocation.getArgument(1))); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute Mono result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType); @@ -190,6 +204,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class))) .thenAnswer(invocation -> Mono.just(invocation.getArgument(1))); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute Mono result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType); @@ -260,6 +277,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any())) .thenReturn(Mono.just(updatedAction)); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute and verify StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE)) @@ -296,6 +316,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any())) .thenReturn(Mono.just(updatedAction)); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute and verify StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE)) @@ -332,6 +355,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any())) .thenReturn(Mono.just(updatedAction)); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute and verify StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE)) @@ -384,6 +410,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(eq("2"), any())) .thenReturn(Mono.just(updatedAction2)); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute and verify StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE)) @@ -439,6 +468,9 @@ public class OnLoadExecutablesUtilCEImplTest { when(executableOnLoadService.updateUnpublishedExecutable(eq("2"), any())) .thenReturn(Mono.just(updatedAction2)); + // mock runBehaviourAnalyticsUtils to return mono of void + doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any()); + // Execute and verify StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour( onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))