diff --git a/Makefile b/Makefile index e427a9e0..6dce33df 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ test: test-core test-ktor test-springboot-demo .PHONY: itest itest: - gradle inngest-spring-boot-demo:integrationTest + gradle test $(TEST_ARGS) -p inngest-spring-boot-demo integrationTest .PHONY: test-core test-core: diff --git a/inngest-core/src/main/kotlin/com/inngest/Function.kt b/inngest-core/src/main/kotlin/com/inngest/Function.kt index bc4500f7..335369d9 100644 --- a/inngest-core/src/main/kotlin/com/inngest/Function.kt +++ b/inngest-core/src/main/kotlin/com/inngest/Function.kt @@ -10,11 +10,13 @@ data class FunctionOptions( val triggers: Array, ) -data class FunctionTrigger( - @Json(serializeNull = false) val event: String? = null, - @Json(serializeNull = false) val `if`: String? = null, - @Json(serializeNull = false) val cron: String? = null, -) +data class FunctionTrigger + @JvmOverloads + constructor( + @Json(serializeNull = false) val event: String? = null, + @Json(serializeNull = false) val `if`: String? = null, + @Json(serializeNull = false) val cron: String? = null, + ) // TODO - Add an abstraction layer between the Function call response and the comm handler response enum class OpCode { diff --git a/inngest-core/src/main/kotlin/com/inngest/State.kt b/inngest-core/src/main/kotlin/com/inngest/State.kt index 8d5b17b5..e0366a14 100644 --- a/inngest-core/src/main/kotlin/com/inngest/State.kt +++ b/inngest-core/src/main/kotlin/com/inngest/State.kt @@ -18,17 +18,22 @@ class State(val payloadJson: String) { return sb.toString() } - inline fun getState(hashedId: String): T? = getState(hashedId, T::class.java) + inline fun getState( + hashedId: String, + fieldName: String = "data", + ): T? = getState(hashedId, T::class.java, fieldName) fun getState( hashedId: String, type: Class, + fieldName: String = "data", ): T? { val mapper = ObjectMapper() val node: JsonNode = mapper.readTree(payloadJson) val stepResult = node.path("steps").get(hashedId) ?: throw StateNotFound() - if (stepResult.has("data")) { - val dataNode = stepResult.get("data") + + if (stepResult.has(fieldName)) { + val dataNode = stepResult.get(fieldName) return mapper.treeToValue(dataNode, type) } else if (stepResult.has("error")) { // TODO - Parse the error and throw it diff --git a/inngest-core/src/main/kotlin/com/inngest/Step.kt b/inngest-core/src/main/kotlin/com/inngest/Step.kt index 7725d4a5..b3c596dd 100644 --- a/inngest-core/src/main/kotlin/com/inngest/Step.kt +++ b/inngest-core/src/main/kotlin/com/inngest/Step.kt @@ -95,7 +95,7 @@ class Step(val state: State, val client: Inngest) { } /** - * Sends multiple event to Inngest + * Sends multiple events to Inngest * * @param id Unique step id for memoization. * @param event An event payload object. @@ -117,18 +117,16 @@ class Step(val state: State, val client: Inngest) { fun sendEvent( id: String, events: Array, - ) { + ): SendEventsResponse { val hashedId = state.getHashFromId(id) try { - // If this doesn't throw an error, it's null and that's what is expected - // TODO - Get the event_ids that were sent and return it from this method - // event_ids are not in the data field but it's actually a separate one. - val stepState = state.getState(hashedId) + val stepState = state.getState>(hashedId, "event_ids") + if (stepState != null) { - throw Exception("step state expected sendEvent, got something else") + return SendEventsResponse(stepState) } - return + throw Exception("step state expected sendEvent, got something else") } catch (e: StateNotFound) { val response = client.send(events) throw StepInterruptSendEventException(id, hashedId, response!!.ids) diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java index e4740c7e..3543d338 100644 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java @@ -16,7 +16,7 @@ public class DemoConfiguration extends InngestConfiguration { @Override public HashMap functions() { String followUpEvent = "user.signup.completed"; - FunctionTrigger fnTrigger = new FunctionTrigger("user-signup", null, null); + FunctionTrigger fnTrigger = new FunctionTrigger("user-signup"); FunctionTrigger[] triggers = {fnTrigger}; FunctionOptions fnConfig = new FunctionOptions("fn-id-slug", "My function!", triggers); @@ -55,7 +55,7 @@ public HashMap functions() { }}; }; - FunctionTrigger followupFnTrigger = new FunctionTrigger(followUpEvent, null, null); + FunctionTrigger followupFnTrigger = new FunctionTrigger(followUpEvent); FunctionOptions followupFnConfig = new FunctionOptions( "fn-follow-up", "Follow up function!", diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java index d385ff5c..c9586bef 100644 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java @@ -1,5 +1,6 @@ package com.inngest.springbootdemo; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.Request; @@ -40,23 +41,39 @@ private void waitForStartup() throws Exception { } } - RunIdsResponse runIds(String runId) throws Exception { + // TODO: Figure out how to make this generic. + // The issue is that deserialization will fail on the `output` generic + // type and return either `LinkedHashMap` or `ArrayList`. + EventRunsResponse runsByEvent(String eventId) throws Exception { Request request = new Request.Builder() - .url(String.format("%s/v1/events/%s/runs", baseUrl, runId)) + .url(String.format("%s/v1/events/%s/runs", baseUrl, eventId)) .build(); + return makeRequest(request, new TypeReference>() { + }); + } + + RunResponse runById(String eventId) throws Exception { + Request request = new Request.Builder() + .url(String.format("%s/v1/runs/%S", baseUrl, eventId)) + .build(); + return makeRequest(request, new TypeReference>() { + }); + } + private T makeRequest(Request request, TypeReference typeReference) throws Exception { try (Response response = httpClient.newCall(request).execute()) { if (response.code() == 200) { assert response.body() != null; String strResponse = response.body().string(); ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(strResponse, RunIdsResponse.class); + return mapper.readValue(strResponse, typeReference); } } return null; } + @PreDestroy public void stop() throws Exception { Runtime rt = Runtime.getRuntime(); diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/EventRunsResponse.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/EventRunsResponse.java new file mode 100644 index 00000000..0b2c3a86 --- /dev/null +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/EventRunsResponse.java @@ -0,0 +1,41 @@ +package com.inngest.springbootdemo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +class EventRunsResponse { + RunEntry[] data; + + RunEntry first() { + return data[0]; + } +} + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +class RunResponse { + RunEntry data; +} + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +class RunEntry { + String run_id; + String event_id; + + String run_started_at; + String ended_at; + + String function_id; + String function_version; + + T output; + String status; +} + diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/RunIdsResponse.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/RunIdsResponse.java deleted file mode 100644 index 8bce6bb9..00000000 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/RunIdsResponse.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.inngest.springbootdemo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@JsonIgnoreProperties(ignoreUnknown = true) -class RunIdsResponse { - RunIdsResponseDataEntry[] data; - - RunIdsResponseDataEntry first() { - return data[0]; - } -} - -@Getter -@Setter -@JsonIgnoreProperties(ignoreUnknown = true) -class RunIdsResponseDataEntry { - String output; - String status; -} diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/SendEventResponse.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/SendEventResponse.java index d8ce62d9..77fb3f6b 100644 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/SendEventResponse.java +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/SendEventResponse.java @@ -10,4 +10,8 @@ class SendEventResponse { String status; String[] ids; + + String first() { + return ids[0]; + } } diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java index 96556d45..44883884 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java @@ -12,6 +12,10 @@ public class DemoTestConfiguration extends InngestConfiguration { protected HashMap functions() { HashMap functions = new HashMap<>(); functions.put("no-step-fn", InngestFunctionTestHelpers.emptyStepFunction()); + functions.put("sleep-fn", InngestFunctionTestHelpers.sleepStepFunction()); + functions.put("two-steps-fn", InngestFunctionTestHelpers.twoStepsFunction()); + functions.put("wait-for-event-fn", InngestFunctionTestHelpers.waitForEventFunction()); + functions.put("send-fn", InngestFunctionTestHelpers.sendEventFunction()); return functions; } diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/InngestFunctionExecutionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/InngestFunctionExecutionIntegrationTest.java deleted file mode 100644 index b78a301a..00000000 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/InngestFunctionExecutionIntegrationTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.inngest.springbootdemo; - -import com.inngest.CommHandler; -import com.inngest.Inngest; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.IfProfileValue; - - -import static org.junit.jupiter.api.Assertions.assertEquals; - - -@IntegrationTest -@Import(DemoTestConfiguration.class) -@AutoConfigureMockMvc -@Execution(ExecutionMode.CONCURRENT) -class InngestFunctionExecutionIntegrationTest { - - - @BeforeAll - static void setup(@Autowired CommHandler handler) { - handler.register(); - } - - @Autowired - private DevServerComponent devServerComponent; - - static int sleepTime = 5000; - - @Autowired - private Inngest client; - - @Test - void testNoStepFunctionRunningSuccessfully() throws Exception { - SendEventResponse response = InngestFunctionTestHelpers.sendEvent(client, "test/no-step"); - - Thread.sleep(sleepTime); - - assert response.ids.length > 0; - - RunIdsResponse runId = devServerComponent.runIds(response.ids[0]); - assertEquals(runId.first().getStatus(), "Completed"); - assertEquals(runId.first().getOutput(), "hello world"); - } -} diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/InngestFunctionTestHelpers.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/InngestFunctionTestHelpers.java index 433695a4..ee06832a 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/InngestFunctionTestHelpers.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/InngestFunctionTestHelpers.java @@ -2,18 +2,23 @@ import com.inngest.*; +import java.time.Duration; import java.util.HashMap; +import java.util.Objects; import java.util.function.BiFunction; public class InngestFunctionTestHelpers { static SendEventResponse sendEvent(Inngest inngest, String eventName) { InngestEvent event = new InngestEvent(eventName, new HashMap()); - return inngest.send(event, SendEventResponse.class); + SendEventResponse response = inngest.send(event, SendEventResponse.class); + + assert Objects.requireNonNull(response).ids.length > 0; + return response; } static InngestFunction emptyStepFunction() { - FunctionTrigger fnTrigger = new FunctionTrigger("test/no-step", null, null); + FunctionTrigger fnTrigger = new FunctionTrigger("test/no-step"); FunctionTrigger[] triggers = {fnTrigger}; FunctionOptions fnConfig = new FunctionOptions("no-step-fn", "No Step Function", triggers); @@ -21,4 +26,68 @@ static InngestFunction emptyStepFunction() { return new InngestFunction(fnConfig, handler); } + + static InngestFunction sleepStepFunction() { + FunctionTrigger fnTrigger = new FunctionTrigger("test/sleep"); + FunctionTrigger[] triggers = {fnTrigger}; + FunctionOptions fnConfig = new FunctionOptions("sleep-fn", "Sleep Function", triggers); + + BiFunction handler = (ctx, step) -> { + int result = step.run("num", () -> 42, Integer.class); + step.sleep("wait-one-sec", Duration.ofSeconds(9)); + + return result; + }; + + return new InngestFunction(fnConfig, handler); + } + + static InngestFunction twoStepsFunction() { + FunctionTrigger fnTrigger = new FunctionTrigger("test/two.steps"); + FunctionTrigger[] triggers = {fnTrigger}; + FunctionOptions fnConfig = new FunctionOptions("two-steps-fn", "Two Steps Function", triggers); + + int count = 0; + + BiFunction handler = (ctx, step) -> { + int step1 = step.run("step1", () -> count + 1, Integer.class); + int tmp1 = step1 + 1; + + int step2 = step.run("step2", () -> tmp1 + 1, Integer.class); + int tmp2 = step2 + 1; + + return tmp2 + 1; + }; + + return new InngestFunction(fnConfig, handler); + } + + static InngestFunction waitForEventFunction() { + FunctionTrigger fnTrigger = new FunctionTrigger("test/wait-for-event"); + FunctionTrigger[] triggers = {fnTrigger}; + FunctionOptions fnConfig = new FunctionOptions("wait-for-event-fn", "Wait for Event Function", triggers); + + BiFunction handler = (ctx, step) -> { + Object event = step.waitForEvent("wait-test", "test/yolo.wait", "8s", null); + + return event == null ? "empty" : "fullfilled"; + }; + + return new InngestFunction(fnConfig, handler); + } + + static InngestFunction sendEventFunction() { + FunctionTrigger fnTrigger = new FunctionTrigger("test/send"); + FunctionTrigger[] triggers = {fnTrigger}; + FunctionOptions fnConfig = new FunctionOptions("send-fn", "Send Function", triggers); + + BiFunction handler = (ctx, step) -> + step.sendEvent("send-test", new InngestEvent( + "test/no-match", + new HashMap())); + + return new InngestFunction(fnConfig, handler); + } + + } diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/IntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/IntegrationTest.java index 47389956..fcf3231d 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/IntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/IntegrationTest.java @@ -1,7 +1,9 @@ package com.inngest.springbootdemo; import org.junit.jupiter.api.condition.EnabledIfSystemProperty; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -9,5 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) @EnabledIfSystemProperty(named = "test-group", matches = "integration-test") @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@Import(DemoTestConfiguration.class) +@AutoConfigureMockMvc public @interface IntegrationTest { } diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/MultiStepsFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/MultiStepsFunctionIntegrationTest.java new file mode 100644 index 00000000..626e3981 --- /dev/null +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/MultiStepsFunctionIntegrationTest.java @@ -0,0 +1,41 @@ +package com.inngest.springbootdemo; + +import com.inngest.CommHandler; +import com.inngest.Inngest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@IntegrationTest +@Execution(ExecutionMode.CONCURRENT) +class MultiStepsFunctionIntegrationTest { + @BeforeAll + static void setup(@Autowired CommHandler handler) { + handler.register(); + } + + @Autowired + private DevServerComponent devServer; + + static int sleepTime = 5000; + + @Autowired + private Inngest client; + + + @Test + void testTwoStepsFunctionValidResult() throws Exception { + String eventId = InngestFunctionTestHelpers.sendEvent(client, "test/two.steps").first(); + + Thread.sleep(sleepTime); + + RunEntry run = devServer.runsByEvent(eventId).first(); + + assertEquals(run.getStatus(), "Completed"); + assertEquals(run.getOutput(), 5); + } +} diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/NoStepFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/NoStepFunctionIntegrationTest.java new file mode 100644 index 00000000..ab98f8b1 --- /dev/null +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/NoStepFunctionIntegrationTest.java @@ -0,0 +1,39 @@ +package com.inngest.springbootdemo; + +import com.inngest.CommHandler; +import com.inngest.Inngest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.*; + +@IntegrationTest +@Execution(ExecutionMode.CONCURRENT) +class NoStepFunctionIntegrationTest { + @BeforeAll + static void setup(@Autowired CommHandler handler) { + handler.register(); + } + + @Autowired + private DevServerComponent devServer; + + static int sleepTime = 5000; + + @Autowired + private Inngest client; + + @Test + void testNoStepFunctionRunningSuccessfully() throws Exception { + String eventId = InngestFunctionTestHelpers.sendEvent(client, "test/no-step").first(); + + Thread.sleep(sleepTime); + + RunEntry run = devServer.runsByEvent(eventId).first(); + assertEquals(run.getStatus(), "Completed"); + assertEquals(run.getOutput(), "hello world"); + } +} diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SendEventFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SendEventFunctionIntegrationTest.java new file mode 100644 index 00000000..6ec8864c --- /dev/null +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SendEventFunctionIntegrationTest.java @@ -0,0 +1,47 @@ +package com.inngest.springbootdemo; + +import com.inngest.CommHandler; +import com.inngest.Inngest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import static org.junit.jupiter.api.Assertions.*; + +@IntegrationTest +@Execution(ExecutionMode.CONCURRENT) +class SendEventFunctionIntegrationTest { + @BeforeAll + static void setup(@Autowired CommHandler handler) { + handler.register(); + } + + @Autowired + private DevServerComponent devServer; + + static int sleepTime = 5000; + + @Autowired + private Inngest client; + + @Test + void testSendEventFunctionSendsEventSuccessfully() throws Exception { + String eventId = InngestFunctionTestHelpers.sendEvent(client, "test/send").first(); + + Thread.sleep(sleepTime); + + RunEntry run = devServer.runsByEvent(eventId).first(); + + // Generic nested structures are frustrating to deserialize properly. + LinkedHashMap> output = (LinkedHashMap>) run.getOutput(); + ArrayList ids = output.get("ids"); + + assertEquals(run.getStatus(), "Completed"); + assert !ids.isEmpty(); + } +} diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SleepFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SleepFunctionIntegrationTest.java new file mode 100644 index 00000000..6883bc08 --- /dev/null +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SleepFunctionIntegrationTest.java @@ -0,0 +1,47 @@ +package com.inngest.springbootdemo; + +import com.inngest.CommHandler; +import com.inngest.Inngest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.*; + +@IntegrationTest +@Execution(ExecutionMode.CONCURRENT) +class SleepFunctionIntegrationTest { + + @BeforeAll + static void setup(@Autowired CommHandler handler) { + handler.register(); + } + + @Autowired + private DevServerComponent devServer; + + @Autowired + private Inngest client; + + @Test + void testSleepFunctionRunningSuccessfully() throws Exception { + String eventId = InngestFunctionTestHelpers.sendEvent(client, "test/sleep").first(); + + Thread.sleep(5000); + + RunEntry run = devServer.runsByEvent(eventId).first(); + + assertEquals(run.getStatus(), "Running"); + assertNull(run.getEnded_at()); + + Thread.sleep(10000); + + RunEntry updatedRun = devServer.runById(run.getRun_id()).getData(); + + assertEquals(updatedRun.getEvent_id(), eventId); + assertEquals(updatedRun.getStatus(), "Completed"); + assertEquals(updatedRun.getOutput(), 42); + } +} diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WaitForEventFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WaitForEventFunctionIntegrationTest.java new file mode 100644 index 00000000..625c155b --- /dev/null +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WaitForEventFunctionIntegrationTest.java @@ -0,0 +1,76 @@ +package com.inngest.springbootdemo; + +import com.inngest.CommHandler; +import com.inngest.Inngest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.*; + +@IntegrationTest +@Execution(ExecutionMode.CONCURRENT) +class WaitForEventFunctionIntegrationTest { + + @BeforeAll + static void setup(@Autowired CommHandler handler) { + handler.register(); + } + + @Autowired + private DevServerComponent devServer; + + static int sleepTime = 5000; + + @Autowired + private Inngest client; + + @Test + void testWaitForEventFunctionWhenFullFilled() throws Exception { + String eventId = InngestFunctionTestHelpers.sendEvent(client, "test/wait-for-event").first(); + + Thread.sleep(sleepTime); + + RunEntry run = devServer.runsByEvent(eventId).first(); + + // It should still be waiting for the expected event. + assertEquals(run.getStatus(), "Running"); + assertNull(run.getEnded_at()); + + InngestFunctionTestHelpers.sendEvent(client, "test/yolo.wait").first(); + + Thread.sleep(sleepTime); + + RunEntry updatedRun = devServer.runById(run.getRun_id()).getData(); + + assertEquals(updatedRun.getEvent_id(), eventId); + assertEquals(updatedRun.getRun_id(), run.getRun_id()); + assertEquals(updatedRun.getStatus(), "Completed"); + assertEquals(updatedRun.getOutput(), "fullfilled"); + } + + @Test + void testWaitForEventFunctionWhenTimeOut() throws Exception { + String eventId = InngestFunctionTestHelpers.sendEvent(client, "test/wait-for-event").first(); + + Thread.sleep(sleepTime); + + RunEntry run = devServer.runsByEvent(eventId).first(); + + // It should still be waiting for the expected event. + assertEquals(run.getStatus(), "Running"); + assertNull(run.getEnded_at()); + + Thread.sleep(sleepTime); + + RunEntry updatedRun = devServer.runById(run.getRun_id()).getData(); + + assertEquals(updatedRun.getEvent_id(), eventId); + assertEquals(updatedRun.getRun_id(), run.getRun_id()); + assertEquals(updatedRun.getStatus(), "Completed"); + assertEquals(updatedRun.getOutput(), "empty"); + } + +}