diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index c5f3c81894a..8b909fd76c4 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -494,7 +494,7 @@ private Timeout createTimeout(Long timeout) { } private static ObjectNode accountConfigFor(Account account, HookId hookId) { - final AccountHooksConfiguration accountHooksConfiguration = account.getHooks(); + final AccountHooksConfiguration accountHooksConfiguration = account != null ? account.getHooks() : null; final Map modulesConfiguration = accountHooksConfiguration != null ? accountHooksConfiguration.getModules() : Collections.emptyMap(); diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index ea9ad000891..80fb8d58135 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -2828,6 +2828,48 @@ null, singletonMap("module-alpha", mapper.createObjectNode()), null)) })); } + @Test + public void shouldExecuteAuctionResponseHooksAndTolerateNullAccount(VertxTestContext context) { + // given + final AuctionResponseHookImpl hookImpl = spy( + AuctionResponseHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + given(hookCatalog.hookById(eqHook("module-alpha", "hook-a"), eq(StageWithHookType.AUCTION_RESPONSE))) + .willReturn(hookImpl); + + final HookStageExecutor executor = createExecutor( + executionPlan(singletonMap( + Endpoint.openrtb2_auction, + EndpointExecutionPlan.of(singletonMap( + Stage.auction_response, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); + + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + + // when + final Future> future = executor.executeAuctionResponseStage( + BidResponse.builder().build(), + AuctionContext.builder() + .bidRequest(BidRequest.builder().build()) + .account(null) + .hookExecutionContext(hookExecutionContext) + .debugContext(DebugContext.empty()) + .build()); + + // then + future.onComplete(context.succeeding(result -> { + final ArgumentCaptor invocationContextCaptor = + ArgumentCaptor.forClass(AuctionInvocationContext.class); + verify(hookImpl).call(any(), invocationContextCaptor.capture()); + + assertThat(invocationContextCaptor.getValue()).satisfies(invocationContext -> { + assertThat(invocationContext.endpoint()).isNotNull(); + assertThat(invocationContext.timeout()).isNotNull(); + assertThat(invocationContext.accountConfig()).isNull(); + }); + + context.completeNow(); + })); + } + @Test public void shouldExecuteAuctionResponseHooksAndIgnoreRejection(VertxTestContext context) { // given