All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
act.test.Interaction Maven / Gradle / Ivy
package act.test;
/*-
* #%L
* ACT Framework
* %%
* 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 act.Act;
import act.metric.Metric;
import act.test.inbox.Inbox;
import act.test.macro.Macro;
import act.test.util.ErrorMessage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.osgl.exception.UnexpectedException;
import org.osgl.http.H;
import org.osgl.util.E;
import org.osgl.util.IO;
import org.osgl.util.N;
import org.osgl.util.S;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static act.metric.MetricInfo.ACT_TEST_INTERACTION;
import static act.test.TestStatus.PENDING;
import static act.test.util.ErrorMessage.error;
public class Interaction implements ScenarioPart {
public List preActions = new ArrayList<>();
public String description = "test interaction";
public RequestSpec request;
public ResponseSpec response;
public List postActions = new ArrayList<>();
public Map cache = new LinkedHashMap<>();
// see https://github.com/actframework/actframework/issues/1119
public Map assign = new LinkedHashMap<>();
public Map store = new LinkedHashMap<>();
public Map save = new LinkedHashMap<>();
public String errorMessage;
public transient Throwable cause;
public TestStatus status = PENDING;
private transient Metric metric = Act.metricPlugin().metric(ACT_TEST_INTERACTION);
@Override
public void validate(TestSession session) throws UnexpectedException {
E.unexpectedIf(null == request, "request spec not specified in interaction[%s]", this);
//E.unexpectedIf(null == response, "response spec not specified");
act.metric.Timer timer = metric.startTimer("validate");
try {
request.resolveParent(session.requestTemplateManager);
request.validate(this);
if (null != response) {
response.validate(this);
}
reset();
} finally {
timer.stop();
}
}
@Override
public String toString() {
return description;
}
public String getStackTrace() {
return causeStackTrace();
}
public boolean run() {
act.metric.Timer timer = metric.startTimer("run");
if (!assign.isEmpty()) {
cache.putAll(assign);
}
if (!store.isEmpty()) {
cache.putAll(store);
}
if (!save.isEmpty()) {
cache.putAll(save);
}
try {
boolean pass = run(preActions) && verify() && run(postActions);
status = TestStatus.of(pass);
return pass;
} finally {
timer.stop();
}
}
public String causeStackTrace() {
return null == cause ? null: E.stackTrace(cause);
}
public void reset() {
errorMessage = null;
cause = null;
status = PENDING;
}
private boolean verify() {
Response resp = null;
try {
if (S.notBlank(request.email)) {
doVerifyEmail(request.email);
} else {
resp = TestSession.current().sendRequest(request);
doVerify(resp);
}
return true;
} catch (Exception e) {
errorMessage = e.getMessage();
if (null == errorMessage) {
errorMessage = e.getClass().getName();
}
cause = causeOf(e);
return false;
} finally {
IO.close(resp);
}
}
private void doVerify(Response resp) throws Exception {
act.metric.Timer timer = metric.startTimer("verify");
try {
verifyStatus(resp);
verifyHeaders(resp);
verifyBody(resp);
} finally {
timer.stop();
}
}
private void doVerifyEmail(String email) throws Exception {
email = TestSession.current().processStringSubstitution(email);
Inbox inbox = Act.getInstance(Inbox.class);
Inbox.Reader reader = inbox.getReader();
String content = reader.readLatest(email);
TestSession.current().verifyBody(content, response);
}
private boolean run(List macros) {
for (Macro macro : macros) {
boolean okay = run(macro);
if (!okay) {
return false;
}
}
return true;
}
private boolean run(Macro macro) {
try {
macro.run(TestSession.current());
return true;
} catch (Exception e) {
errorMessage = e.getMessage();
if (null == errorMessage) {
errorMessage = e.getClass().getName();
}
cause = causeOf(e);
return false;
}
}
private void verifyStatus(Response resp) {
H.Status expected = expectedStatus();
if (null == expected) {
if (!resp.isSuccessful()) {
int status = resp.code();
try {
String body = resp.body().string();
String msg = body;
if (body.startsWith("{") && body.endsWith("}")) {
try {
JSONObject json = JSON.parseObject(body);
if (json.containsKey("message")) {
msg = json.getString("message");
}
} catch (Exception e) {
// ignore
}
}
if (msg.contains("")) {
Document doc = Jsoup.parse(msg, S.concat("http://localhost:", TestSession.current().port(), "/"));
Elements elements = doc.select(".error-message");
if (elements.hasText()) {
msg = elements.text();
} else {
elements = doc.select("h1");
if (elements.hasText()) {
msg = doc.text();
} else {
msg = doc.title();
}
}
}
error("Status verification failure. Expected: successful, Found: %s, Error message: %s", status, msg);
} catch (IOException e) {
error("Status verification failure. Expected: successful, Found: %s", status);
}
}
} else {
if (expected.code() != resp.code()) {
error("Status verification failure. Expected: %s, Found: %s", expected.code(), resp.code());
}
}
}
private void verifyHeaders(Response resp) {
if (null == response) {
return;
}
for (Map.Entry entry : response.headers.entrySet()) {
String headerName = entry.getKey();
String headerVal = resp.header(headerName);
try {
TestSession.current().verifyValue(headerName, headerVal, entry.getValue());
} catch (Exception e) {
error(e, S.concat("Failed verifying header[", headerName, "]: ", e.getMessage()));
}
}
TestSession.current().lastHeaders.set(resp.headers());
}
private void verifyBody(Response rs) throws Exception {
if (null != response && S.notBlank(response.checksum)) {
TestSession.current().verifyDownloadChecksum(rs, response.checksum);
if (S.notBlank(response.downloadFilename)) {
TestSession.current().verifyDownloadFilename(rs, response.downloadFilename);
}
} else if (null != response && S.notBlank(response.downloadFilename)) {
TestSession.current().verifyDownloadFilename(rs, response.downloadFilename);
} else {
String bodyString = S.string(rs.body().string()).trim();
TestSession.current().verifyBody(bodyString, response);
}
}
private H.Status expectedStatus() {
return null == response ? null : response.status;
}
private static Throwable causeOf(Exception e) {
Throwable cause = e.getCause();
Throwable t = null == cause ? e : cause;
if (t instanceof ErrorMessage) {
t = null;
}
return t;
}
}