![JAR search and dependency download from the Maven repository](/logo.png)
act.e2e.Scenario Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of act-e2e Show documentation
Show all versions of act-e2e Show documentation
Support end to end test of ActFramework application
package act.e2e;
/*-
* #%L
* ACT E2E Plugin
* %%
* Copyright (C) 2018 ActFramework
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import static org.osgl.http.H.Header.Names.ACCEPT;
import static org.osgl.http.H.Header.Names.X_REQUESTED_WITH;
import act.Act;
import act.app.App;
import act.e2e.macro.Macro;
import act.e2e.req_modifier.RequestModifier;
import act.e2e.util.CookieStore;
import act.e2e.util.RequestTemplateManager;
import act.e2e.util.ScenarioManager;
import act.e2e.verifier.Verifier;
import act.util.LogSupport;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.osgl.$;
import org.osgl.exception.UnexpectedException;
import org.osgl.http.H;
import org.osgl.util.Codec;
import org.osgl.util.E;
import org.osgl.util.IO;
import org.osgl.util.S;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
public class Scenario extends LogSupport implements ScenarioPart {
private static final RequestBody EMPTY_BODY = RequestBody.create(null, "");
private class RequestBuilder {
private Request.Builder builder;
RequestBuilder(RequestSpec requestSpec) {
builder = new Request.Builder();
if ($.bool(requestSpec.json)) {
builder.addHeader(ACCEPT, H.Format.JSON.contentType());
}
if ($.bool(requestSpec.ajax)) {
builder.addHeader(X_REQUESTED_WITH, "XMLHttpRequest");
}
for (RequestModifier modifier : requestSpec.modifiers) {
modifier.modifyRequest(builder);
}
for (Map.Entry entry : requestSpec.headers.entrySet()) {
String headerName = entry.getKey();
String headerVal = S.string(entry.getValue());
if (headerVal.startsWith("last:") || headerVal.startsWith("last|")) {
String payload = headerVal.substring(5);
if (S.blank(payload)) {
payload = headerName;
}
headerVal = S.string(lastHeaders.get().get(payload));
}
builder.addHeader(headerName, headerVal);
}
String url = S.concat("http://localhost:", port, S.ensure(processStringSubstitution(requestSpec.url)).startWith("/"));
boolean hasParams = !requestSpec.params.isEmpty();
if (hasParams) {
processParamSubstitution(requestSpec.params);
}
switch (requestSpec.method) {
case GET:
case HEAD:
if (hasParams) {
S.Buffer buf = S.buffer(url);
if (!url.contains("?")) {
buf.a("?__nil__=nil");
}
for (Map.Entry entry : requestSpec.params.entrySet()) {
String paramName = Codec.encodeUrl(entry.getKey());
String paramVal = Codec.encodeUrl(S.string(entry.getValue()));
buf.a("&").a(paramName).a("=").a(paramVal);
}
url = buf.toString();
}
case DELETE:
builder.method(requestSpec.method.name(), null);
break;
case POST:
case PUT:
case PATCH:
RequestBody body = EMPTY_BODY;
String jsonBody = verifyJsonBody(requestSpec.jsonBody);
if (S.notBlank(requestSpec.jsonBody)) {
body = RequestBody.create(MediaType.parse("application/json"), jsonBody);
} else if (hasParams) {
MultipartBody.Builder formBuilder = new MultipartBody.Builder();
for (Map.Entry entry : requestSpec.params.entrySet()) {
formBuilder.addFormDataPart(entry.getKey(), S.string(entry.getValue()));
}
body = formBuilder.build();
}
builder.method((requestSpec.method.name()), body);
break;
default:
throw E.unexpected("HTTP method not supported: " + requestSpec.method);
}
builder.url(url);
}
private void processParamSubstitution(Map params) {
for (Map.Entry entry : params.entrySet()) {
Object val = entry.getValue();
if (val instanceof String) {
String sVal = (String) val;
if (sVal.startsWith("last:") || sVal.startsWith("last|")) {
String ref = sVal.substring(5);
entry.setValue(getLastVal(ref));
}
}
}
}
private Object getLastVal(String ref) {
Object val;
if (S.blank(ref)) {
val = lastData.get();
} else {
Object lastObj = lastData.get();
if (lastObj instanceof JSONArray) {
if (S.isInt(ref)) {
val = ((JSONArray) lastObj).get(Integer.parseInt(ref));
} else {
throw E.unexpected("Invalid last reference, expect number, found: " + ref);
}
} else {
JSONObject json = (JSONObject) lastObj;
val = json.get(ref);
}
}
return val;
}
private String processStringSubstitution(String s) {
int n = s.indexOf("${");
if (n < 0) {
return s;
}
int a = 0;
int z = n;
S.Buffer buf = S.buffer();
while (true) {
buf.append(s.substring(a, z));
n = s.indexOf("}", z);
a = n;
E.illegalArgumentIf(n < -1, "Invalid string: " + s);
String part = s.substring(z + 2, a);
E.illegalArgumentIf(!part.startsWith("last:"), "Unknown substitution: " + s);
String payload = part.substring(5);
buf.append(getLastVal(payload));
n = s.indexOf("${", a);
if (n < 0) {
buf.append(s.substring(a + 1));
return buf.toString();
}
z = n;
}
}
Request build() {
return builder.build();
}
private String verifyJsonBody(String jsonBody) {
final String origin = jsonBody;
if (S.blank(jsonBody)) {
return "";
}
if (jsonBody.startsWith("resource:")) {
jsonBody = S.ensure(jsonBody.substring(9).trim()).startWith("/");
URL url = Act.getResource(jsonBody);
E.unexpectedIf(null == url, "Cannot find JSON body: " + origin);
jsonBody = IO.read(url).toString();
}
try {
JSON.parse(jsonBody);
} catch (Exception e) {
E.unexpected(e, "Invalid JSON body: " + origin);
}
return jsonBody;
}
}
private int port = 5460;
private OkHttpClient http;
private CookieStore cookieStore;
private App app;
public String name;
public String description;
public List fixtures = new ArrayList<>();
public List depends = new ArrayList<>();
public List interactions = new ArrayList<>();
public boolean finished;
public Map errorMessages;
$.Var
© 2015 - 2025 Weber Informatics LLC | Privacy Policy