001/* 002 * Copyright 2022-2025 Revetware LLC. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.soklet.core; 018 019import com.soklet.SokletConfiguration; 020 021import javax.annotation.Nonnull; 022import java.util.function.Consumer; 023 024/** 025 * Simulates server behavior of accepting a request and returning a response, useful for writing integration tests. 026 * <p> 027 * <a href="https://www.soklet.com/docs/server-sent-events">Server-Sent Event</a> simulation is also supported. 028 * <p> 029 * Instances of {@link Simulator} are made available via {@link com.soklet.Soklet#runSimulator(SokletConfiguration, Consumer)}. 030 * <p> 031 * Usage example: 032 * <pre>{@code @Test 033 * public void basicIntegrationTest() { 034 * // Build your configuration however you like 035 * SokletConfiguration config = obtainMySokletConfig(); 036 * 037 * // Instead of running on a real HTTP server that listens on a port, 038 * // a simulator is provided against which you can issue requests 039 * // and receive responses. 040 * Soklet.runSimulator(config, (simulator -> { 041 * // Construct a request. 042 * // You may alternatively specify query parameters directly in the URI 043 * // as a query string, e.g. "/hello?name=Mark" 044 * Request request = Request.with(HttpMethod.GET, "/hello") 045 * .queryParameters(Map.of("name", Set.of("Mark"))) 046 * .build(); 047 * 048 * // Perform the request and get a handle to the result 049 * RequestResult result = simulator.performRequest(request); 050 * 051 * // Verify status code 052 * Integer expectedCode = 200; 053 * Integer actualCode = result.getMarshaledResponse().getStatusCode(); 054 * Assert.assertEquals("Bad status code", expectedCode, actualCode); 055 * })); 056 * }}</pre> 057 * <p> 058 * Full documentation is available at <a href="https://www.soklet.com/docs/automated-testing">https://www.soklet.com/docs/automated-testing</a>. 059 * 060 * @author <a href="https://www.revetkn.com">Mark Allen</a> 061 */ 062public interface Simulator { 063 /** 064 * Given a request, process it and return response data (both logical {@link Response}, if present, and the {@link MarshaledResponse} bytes to be sent over the wire) as well as the matching <em>Resource Method</em>, if available. 065 * 066 * @param request the request to process 067 * @return the result (logical response, marshaled response, etc.) that corresponds to the request 068 */ 069 @Nonnull 070 RequestResult performRequest(@Nonnull Request request); 071 072 /** 073 * Registers a {@link ServerSentEvent} "consumer" for the given {@link ResourcePath} - similar to how a real client would listen for Server-Sent Events. 074 * <p> 075 * See documentation at <a href="https://www.soklet.com/docs/server-sent-events#testing">https://www.soklet.com/docs/server-sent-events#testing</a>. 076 * 077 * @param resourcePath the Resource Path on which to listen for Server-Sent Events 078 * @param serverSentEventConsumer function to be invoked when a Server-Sent Event has been broadcast on the Resource Path 079 */ 080 void registerServerSentEventConsumer(@Nonnull ResourcePath resourcePath, 081 @Nonnull Consumer<ServerSentEvent> serverSentEventConsumer); 082 083 /** 084 * Acquires a Server-Sent Event broadcaster for the given {@link ResourcePath}. 085 * <p> 086 * See documentation at <a href="https://www.soklet.com/docs/server-sent-events#testing">https://www.soklet.com/docs/server-sent-events#testing</a>. 087 * 088 * @param resourcePath the Resource Path on which to broadcast Server-Sent Events 089 * @return a Server-Sent Event broadcaster 090 */ 091 @Nonnull 092 ServerSentEventBroadcaster acquireServerSentEventBroadcaster(@Nonnull ResourcePath resourcePath); 093}