1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.adservices.utils; 18 19 import com.google.auto.value.AutoValue; 20 import com.google.common.collect.ImmutableMap; 21 22 import java.util.Map; 23 24 /** 25 * The Scenario class represents a configuration for a mock HTTP server used in scenario-based 26 * testing. It encapsulates a mapping of requests to corresponding mock responses, along with 27 * options for verification. 28 * 29 * <p>You should ideally not construct this class directly, instead use {@link ScenarioLoader} and 30 * {@link ScenarioDispatcherFactory} to load scenarios from JSON. 31 */ 32 public class Scenario { 33 34 private final ImmutableMap<Request, MockResponse> mScenarioMap; 35 36 /** 37 * Constructs a new Scenario instance. 38 * 39 * @param scenarioMap An immutable map containing Request-Mock pairs, defining the scenario's 40 * behavior. 41 */ Scenario(ImmutableMap<Request, MockResponse> scenarioMap)42 Scenario(ImmutableMap<Request, MockResponse> scenarioMap) { 43 this.mScenarioMap = scenarioMap; 44 } 45 46 /** 47 * Returns the immutable map defining the request-response associations for this scenario. 48 * 49 * @return An ImmutableMap containing the scenario's configuration. 50 */ getScenarioMap()51 public ImmutableMap<Request, MockResponse> getScenarioMap() { 52 return mScenarioMap; 53 } 54 55 /** Represents a mock HTTP request within a scenario. */ 56 @AutoValue 57 public abstract static class Request { 58 /** 59 * Returns the relative path of the HTTP request (e.g., "/api/data") 60 * 61 * @return the relative path as a String 62 */ getRelativePath()63 abstract String getRelativePath(); 64 65 /** 66 * Returns an immutable map of HTTP headers associated with the request. 67 * 68 * @return an ImmutableMap of headers 69 */ getHeaders()70 abstract ImmutableMap<String, String> getHeaders(); 71 72 /** 73 * Returns a new Builder instance for constructing Request objects. 74 * 75 * @return a Request.Builder instance 76 */ newBuilder()77 static Builder newBuilder() { 78 return new AutoValue_Scenario_Request.Builder(); 79 } 80 81 /** Builder class for creating Request instances. */ 82 @AutoValue.Builder 83 public abstract static class Builder { 84 /** 85 * Sets the relative path of the request. 86 * 87 * @param path the relative path to set 88 * @return the Builder instance for chaining 89 */ setRelativePath(String path)90 abstract Builder setRelativePath(String path); 91 92 /** 93 * Sets the HTTP headers for the request. 94 * 95 * @param headers an ImmutableMap containing headers 96 * @return the Builder instance for chaining 97 */ setHeaders(Map<String, String> headers)98 abstract Builder setHeaders(Map<String, String> headers); 99 100 /** 101 * Builds a new Request instance based on the configured values. 102 * 103 * @return a Request instance 104 */ build()105 abstract Request build(); 106 } 107 } 108 109 /** Represents a mock HTTP response within a scenario. */ 110 @AutoValue 111 public abstract static class MockResponse { 112 /** 113 * Returns the default response to be used for matching requests. 114 * 115 * @return a Response object representing the default response 116 */ getDefaultResponse()117 abstract Response getDefaultResponse(); 118 119 /** 120 * Indicates whether a call to this mock should be verified during testing. 121 * 122 * @return true if the call should be verified, false otherwise 123 */ getShouldVerifyCalled()124 abstract boolean getShouldVerifyCalled(); 125 126 /** 127 * Indicates whether a call to this mock should *not* be verified during testing. 128 * 129 * @return true if absence of a call should be verified, false otherwise 130 */ getShouldVerifyNotCalled()131 abstract boolean getShouldVerifyNotCalled(); 132 133 /** 134 * Returns a new Builder instance for constructing Mock objects. 135 * 136 * @return a Mock.Builder instance 137 */ newBuilder()138 static Builder newBuilder() { 139 return new AutoValue_Scenario_MockResponse.Builder(); 140 } 141 142 /** Builder class for creating {@link MockResponse} instances. */ 143 @AutoValue.Builder 144 public abstract static class Builder { 145 146 /** 147 * Sets the default response that the mock should return when a matching request is 148 * received. 149 * 150 * @param response The {@link Response} object representing the default response. 151 * @return This builder instance for method chaining. 152 */ setDefaultResponse(Response response)153 abstract Builder setDefaultResponse(Response response); 154 155 /** 156 * t Sets a flag indicating whether calls to this mock should be verified during 157 * testing. This typically means ensuring the mock was invoked during the test scenario. 158 * 159 * @param verifyCalled true if calls to this mock should be verified, false otherwise. 160 * @return This builder instance for method chaining. 161 */ setShouldVerifyCalled(boolean verifyCalled)162 abstract Builder setShouldVerifyCalled(boolean verifyCalled); 163 164 /** 165 * Sets a flag indicating whether the *absence* of calls to this mock should be verified 166 * during testing. This is useful when you want to ensure certain interactions with the 167 * mock HTTP server did *not* occur. 168 * 169 * @param verifyNotCalled true if the lack of calls to the mock should be verified, 170 * false otherwise. 171 * @return This builder instance for method chaining. 172 */ setShouldVerifyNotCalled(boolean verifyNotCalled)173 abstract Builder setShouldVerifyNotCalled(boolean verifyNotCalled); 174 175 /** 176 * Builds a new {@link MockResponse} instance using the values configured in this 177 * builder. 178 * 179 * @return A newly constructed Mock object. 180 */ build()181 abstract MockResponse build(); 182 } 183 } 184 185 /** 186 * Represents a mock HTTP response within a scenario. This class encapsulates the response body, 187 * headers, and an optional delay to simulate network latency. 188 */ 189 @AutoValue 190 public abstract static class Response { 191 192 /** 193 * Returns the body content of the HTTP response. 194 * 195 * @return The response body as a String. 196 */ getBody()197 abstract String getBody(); 198 199 /** 200 * Returns an immutable map of HTTP headers associated with the response. 201 * 202 * @return An immutable map of headers. 203 */ getHeaders()204 abstract ImmutableMap<String, String> getHeaders(); 205 206 /** 207 * Returns the delay in seconds to be applied to the response, simulating network latency. 208 * 209 * @return The delay in seconds. 210 */ getDelaySeconds()211 abstract int getDelaySeconds(); 212 213 /** 214 * Returns a new Builder instance for constructing Mock objects. 215 * 216 * @return a Response.Builder instance 217 */ newBuilder()218 static Response.Builder newBuilder() { 219 return new AutoValue_Scenario_Response.Builder(); 220 } 221 222 /** 223 * Builder class for creating {@link Response} instances. Use this class to fluently 224 * configure the response body, headers, and delay for your mock HTTP server scenarios. 225 */ 226 @AutoValue.Builder 227 public abstract static class Builder { 228 229 /** 230 * Sets the response body content. 231 * 232 * @param body The response body as a String. 233 * @return This builder instance for method chaining. 234 */ setBody(String body)235 abstract Builder setBody(String body); 236 237 /** 238 * Sets the HTTP headers for the response. 239 * 240 * @param headers An immutable map containing headers. 241 * @return This builder instance for method chaining. 242 */ setHeaders(Map<String, String> headers)243 abstract Builder setHeaders(Map<String, String> headers); 244 245 /** 246 * Sets an artificial delay (in seconds) for the response to simulate network 247 * conditions. 248 * 249 * @param delay The delay in seconds. 250 * @return This builder instance for method chaining. 251 */ setDelaySeconds(int delay)252 abstract Builder setDelaySeconds(int delay); 253 254 /** 255 * Builds a new {@link Response} instance using the configured values. 256 * 257 * @return A newly constructed Response object. 258 */ build()259 abstract Response build(); 260 } 261 } 262 } 263