Skip to content

Commit 1921a5e

Browse files
committed
Use local mock server instead external ones
Signed-off-by: Matheus Cruz <matheuscruz.dev@gmail.com>
1 parent 5b06e0e commit 1921a5e

File tree

11 files changed

+226
-40
lines changed

11 files changed

+226
-40
lines changed

impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AbstractHttpExecutorBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ protected static RequestSupplier buildRequestSupplier(
4444
return new WithoutBodyRequestSupplier(Invocation.Builder::delete, application, redirect);
4545
case HttpMethod.HEAD:
4646
return new WithoutBodyRequestSupplier(Invocation.Builder::head, application, redirect);
47+
case HttpMethod.PATCH:
48+
return new WithBodyRequestSupplier(
49+
(request, entity) -> request.method("PATCH", entity), application, body, redirect);
4750
case HttpMethod.OPTIONS:
4851
return new WithoutBodyRequestSupplier(Invocation.Builder::options, application, redirect);
4952
case HttpMethod.GET:

impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AbstractRequestSupplier.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ public WorkflowModel apply(
4040
Builder request, WorkflowContext workflow, TaskContext task, WorkflowModel model) {
4141
HttpModelConverter converter = HttpConverterResolver.converter(workflow, task);
4242

43-
if (!redirect) {
44-
// disable automatic redirects handling from Jersey client
45-
request.property("jersey.config.client.followRedirects", false);
46-
}
47-
4843
Response response = invokeRequest(request, converter, workflow, task, model);
4944
validateStatus(task, response);
5045
return workflow

impl/test/src/test/java/io/serverlessworkflow/impl/test/HTTPWorkflowDefinitionTest.java

Lines changed: 201 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
import io.serverlessworkflow.impl.WorkflowApplication;
2424
import io.serverlessworkflow.impl.WorkflowModel;
2525
import java.io.IOException;
26+
import java.nio.charset.StandardCharsets;
2627
import java.util.Map;
2728
import java.util.concurrent.CompletionException;
2829
import mockwebserver3.MockResponse;
2930
import mockwebserver3.MockWebServer;
31+
import mockwebserver3.RecordedRequest;
3032
import okhttp3.Headers;
31-
import org.assertj.core.api.Condition;
33+
import org.assertj.core.api.SoftAssertions;
3234
import org.junit.jupiter.api.AfterAll;
3335
import org.junit.jupiter.api.AfterEach;
3436
import org.junit.jupiter.api.BeforeAll;
@@ -68,73 +70,204 @@ private static boolean httpCondition(WorkflowModel obj) {
6870

6971
@Test
7072
void callHttpGet_should_return_pet_data() throws Exception {
73+
mockServer.enqueue(
74+
new MockResponse(
75+
200,
76+
Headers.of("Content-Type", "application/json"),
77+
"""
78+
{
79+
"petId": 10,
80+
"photoUrls": [
81+
"https://example.com/photos/rex1.jpg",
82+
"https://example.com/photos/rex2.jpg"
83+
]
84+
}
85+
"""));
7186
WorkflowModel result =
7287
appl.workflowDefinition(readWorkflowFromClasspath("workflows-samples/call-http-get.yaml"))
7388
.instance(Map.of("petId", 10))
7489
.start()
7590
.join();
76-
assertThat(result)
77-
.has(new Condition<>(HTTPWorkflowDefinitionTest::httpCondition, "callHttpCondition"));
91+
SoftAssertions.assertSoftly(
92+
softly -> {
93+
softly
94+
.assertThat(result.asMap().orElseThrow())
95+
.containsKey("petId")
96+
.containsKey("photoUrls");
97+
try {
98+
RecordedRequest recordedRequest = mockServer.takeRequest();
99+
softly.assertThat(recordedRequest.getUrl()).asString().contains("/pets/10");
100+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("GET");
101+
} catch (InterruptedException e) {
102+
softly.fail(e);
103+
}
104+
});
78105
}
79106

80107
@Test
81108
void callHttpGet_with_not_found_petId_should_keep_input_petId() throws Exception {
109+
mockServer.enqueue(
110+
new MockResponse(
111+
404,
112+
Headers.of("Content-Type", "application/json"),
113+
"""
114+
{"message": "Pet not found"}
115+
"""));
82116
WorkflowModel result =
83117
appl.workflowDefinition(readWorkflowFromClasspath("workflows-samples/call-http-get.yaml"))
84118
.instance(Map.of("petId", "-1"))
85119
.start()
86120
.join();
87-
assertThat(result.asMap().orElseThrow()).containsKey("petId");
121+
122+
RecordedRequest recordedRequest = mockServer.takeRequest();
123+
SoftAssertions.assertSoftly(
124+
softly -> {
125+
softly.assertThat(result.asMap().orElseThrow()).containsKey("petId");
126+
softly.assertThat(recordedRequest.getUrl()).asString().contains("/pets/-1");
127+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("GET");
128+
});
88129
}
89130

90131
@Test
91132
void callHttpEndpointInterpolation_should_work() throws Exception {
133+
mockServer.enqueue(
134+
new MockResponse(
135+
200,
136+
Headers.of("Content-Type", "application/json"),
137+
"""
138+
{
139+
"petId": 1994,
140+
"photoUrls": [
141+
"https://example.com/photos/dog1.jpg",
142+
"https://example.com/photos/dog2.jpg"
143+
]
144+
}
145+
"""));
92146
WorkflowModel result =
93147
appl.workflowDefinition(
94148
readWorkflowFromClasspath(
95149
"workflows-samples/call-http-endpoint-interpolation.yaml"))
96-
.instance(Map.of("petId", 10))
150+
.instance(Map.of("petId", 1994))
97151
.start()
98152
.join();
99-
assertThat(result)
100-
.has(new Condition<>(HTTPWorkflowDefinitionTest::httpCondition, "callHttpCondition"));
153+
154+
RecordedRequest recordedRequest = mockServer.takeRequest();
155+
SoftAssertions.assertSoftly(
156+
softly -> {
157+
softly
158+
.assertThat(result.asMap().orElseThrow())
159+
.containsKey("petId")
160+
.containsKey("photoUrls");
161+
softly.assertThat(recordedRequest.getUrl()).asString().contains("/pets/1994");
162+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("GET");
163+
});
101164
}
102165

103166
@Test
104167
void callHttpQueryParameters_should_find_star_trek_movie() throws Exception {
168+
mockServer.enqueue(
169+
new MockResponse(
170+
200,
171+
Headers.of("Content-Type", "application/json"),
172+
"""
173+
{
174+
"movie": {
175+
"uid": "MOMA0000092393",
176+
"title": "Star Trek",
177+
"director": "J.J. Abrams"
178+
}
179+
}
180+
"""));
181+
105182
WorkflowModel result =
106183
appl.workflowDefinition(
107184
readWorkflowFromClasspath("workflows-samples/call-http-query-parameters.yaml"))
108185
.instance(Map.of("uid", "MOMA0000092393"))
109186
.start()
110187
.join();
111-
assertThat(((Map<String, Object>) result.asMap().orElseThrow().get("movie")).get("title"))
112-
.isEqualTo("Star Trek");
188+
189+
RecordedRequest recordedRequest = mockServer.takeRequest();
190+
SoftAssertions.assertSoftly(
191+
softly -> {
192+
Map<String, Object> response = result.asMap().orElseThrow();
193+
softly.assertThat(response).containsKey("movie");
194+
var movie = (Map<String, Object>) response.get("movie");
195+
softly.assertThat(movie).containsEntry("title", "Star Trek");
196+
softly.assertThat(recordedRequest.getUrl()).asString().contains("uid=MOMA0000092393");
197+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("GET");
198+
});
113199
}
114200

115201
@Test
116202
void callHttpFindByStatus_should_return_non_empty_collection() throws Exception {
203+
mockServer.enqueue(
204+
new MockResponse(
205+
200,
206+
Headers.of("Content-Type", "application/json"),
207+
"""
208+
[
209+
{
210+
"id": 1,
211+
"name": "Rex",
212+
"status": "sold"
213+
},
214+
{
215+
"id": 2,
216+
"name": "Fido",
217+
"status": "sold"
218+
}
219+
]
220+
"""));
117221

118222
WorkflowModel result =
119223
appl.workflowDefinition(
120224
readWorkflowFromClasspath("workflows-samples/call-http-find-by-status.yaml"))
121225
.instance(Map.of())
122226
.start()
123227
.join();
124-
assertThat(result.asCollection()).isNotEmpty();
228+
229+
RecordedRequest recordedRequest = mockServer.takeRequest();
230+
SoftAssertions.assertSoftly(
231+
softly -> {
232+
softly.assertThat(result.asCollection()).isNotEmpty();
233+
softly.assertThat(recordedRequest.getUrl()).asString().contains("status=sold");
234+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("GET");
235+
});
125236
}
126237

127238
@Test
128239
void callHttpQueryParameters_external_schema_should_find_star_trek() throws Exception {
240+
mockServer.enqueue(
241+
new MockResponse(
242+
200,
243+
Headers.of("Content-Type", "application/json"),
244+
"""
245+
{
246+
"movie": {
247+
"uid": "MOMA0000092393",
248+
"title": "Star Trek",
249+
"director": "J.J. Abrams"
250+
}
251+
}
252+
"""));
253+
129254
WorkflowModel result =
130255
appl.workflowDefinition(
131-
readWorkflowFromClasspath(
132-
"workflows-samples/call-http-query-parameters-external-schema.yaml"))
256+
readWorkflowFromClasspath("workflows-samples/call-http-query-parameters.yaml"))
133257
.instance(Map.of("uid", "MOMA0000092393"))
134258
.start()
135259
.join();
136-
assertThat(((Map<String, Object>) result.asMap().orElseThrow().get("movie")).get("title"))
137-
.isEqualTo("Star Trek");
260+
261+
RecordedRequest recordedRequest = mockServer.takeRequest();
262+
SoftAssertions.assertSoftly(
263+
softly -> {
264+
Map<String, Object> response = result.asMap().orElseThrow();
265+
softly.assertThat(response).containsKey("movie");
266+
var movie = (Map<String, Object>) response.get("movie");
267+
softly.assertThat(movie).containsEntry("title", "Star Trek");
268+
softly.assertThat(recordedRequest.getUrl()).asString().contains("uid=MOMA0000092393");
269+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("GET");
270+
});
138271
}
139272

140273
@Test
@@ -144,38 +277,78 @@ void callHttpPost_should_return_created_firstName() throws Exception {
144277
200,
145278
Headers.of("Content-Type", "application/json"),
146279
"""
147-
{
148-
"firstName": "Javierito"
149-
}
150-
"""));
280+
{
281+
"firstName": "Javierito"
282+
}
283+
"""));
151284
WorkflowModel result =
152285
appl.workflowDefinition(readWorkflowFromClasspath("workflows-samples/call-http-post.yaml"))
153286
.instance(Map.of("name", "Javierito", "surname", "Unknown"))
154287
.start()
155288
.join();
156-
assertThat(result.asText().orElseThrow()).isEqualTo("Javierito");
289+
290+
RecordedRequest recordedRequest = mockServer.takeRequest();
291+
SoftAssertions.assertSoftly(
292+
softly -> {
293+
softly.assertThat(result.asText().orElseThrow()).isEqualTo("Javierito");
294+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("POST");
295+
softly.assertThat(recordedRequest.getBody()).isNotNull();
296+
softly
297+
.assertThat(recordedRequest.getBody().string(StandardCharsets.UTF_8))
298+
.contains("\"firstName\":\"Javierito\"")
299+
.contains("\"lastName\":\"Unknown\"");
300+
});
157301
}
158302

159303
@Test
160-
void testCallHttpDelete() {
161-
assertDoesNotThrow(
162-
() -> {
163-
appl.workflowDefinition(
164-
readWorkflowFromClasspath("workflows-samples/call-http-delete.yaml"))
165-
.instance(Map.of())
166-
.start()
167-
.join();
304+
void testCallHttpDelete() throws IOException, InterruptedException {
305+
mockServer.enqueue(new MockResponse(204, Headers.of(), ""));
306+
307+
WorkflowModel model =
308+
appl.workflowDefinition(
309+
readWorkflowFromClasspath("workflows-samples/call-http-delete.yaml"))
310+
.instance(Map.of())
311+
.start()
312+
.join();
313+
314+
RecordedRequest recordedRequest = mockServer.takeRequest();
315+
SoftAssertions.assertSoftly(
316+
softly -> {
317+
softly.assertThat(model).isNotNull();
318+
softly.assertThat(recordedRequest.getMethod()).isEqualTo("DELETE");
319+
softly.assertThat(recordedRequest.getUrl()).asString().contains("/api/v1/authors/1");
168320
});
169321
}
170322

171323
@Test
172324
void callHttpPut_should_contain_firstName_with_john() throws Exception {
325+
mockServer.enqueue(
326+
new MockResponse(
327+
200,
328+
Headers.of("Content-Type", "application/json"),
329+
"""
330+
{
331+
"id": 1,
332+
"firstName": "John"
333+
}
334+
"""));
335+
173336
WorkflowModel result =
174337
appl.workflowDefinition(readWorkflowFromClasspath("workflows-samples/call-http-put.yaml"))
175338
.instance(Map.of("firstName", "John"))
176339
.start()
177340
.join();
178-
assertThat(result.asText().orElseThrow()).contains("John");
341+
342+
RecordedRequest recordedRequest = mockServer.takeRequest();
343+
SoftAssertions.assertSoftly(
344+
softly -> {
345+
softly.assertThat(result.asText().orElseThrow()).contains("John");
346+
softly.assertThat(recordedRequest.getMethod()).contains("PUT");
347+
softly
348+
.assertThat(recordedRequest.getBody().string(StandardCharsets.UTF_8))
349+
.contains("\"firstName\":\"John\"");
350+
softly.assertThat(recordedRequest.getUrl()).asString().contains("api/v1/authors/1");
351+
});
179352
}
180353

181354
@Test

impl/test/src/test/resources/workflows-samples/call-http-delete.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ do:
99
with:
1010
method: delete
1111
endpoint:
12-
uri: https://fakerestapi.azurewebsites.net/api/v1/Authors/1
12+
uri: https://localhost:9876/api/v1/authors/1

impl/test/src/test/resources/workflows-samples/call-http-endpoint-interpolation.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ do:
1212
headers:
1313
content-type: application/json
1414
method: get
15-
endpoint: ${ "https://petstore.swagger.io/v2/pet/\(.petId)" }
15+
endpoint: ${ "http://localhost:9876/pets/\(.petId)" }
1616
catch:
1717
errors:
1818
with:

impl/test/src/test/resources/workflows-samples/call-http-find-by-status.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ do:
1313
content-type: application/json
1414
method: get
1515
endpoint:
16-
uri: https://petstore.swagger.io/v2/pet/findByStatus?status=sold
16+
uri: http://localhost:9876/v2/pet/findByStatus?status=sold
1717
catch:
1818
errors:
1919
with:

impl/test/src/test/resources/workflows-samples/call-http-get.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ do:
1313
content-type: application/json
1414
method: get
1515
endpoint:
16-
uri: https://petstore.swagger.io/v2/pet/{petId}
16+
uri: http://localhost:9876/pets/{petId}
1717
catch:
1818
errors:
1919
with:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: test
4+
name: call-http-patch
5+
version: 1.0.0
6+
do:
7+
- deleteAuthor:
8+
call: http
9+
with:
10+
method: patch
11+
endpoint:
12+
uri: http://localhost:9876/users/1
13+
headers:
14+
Content-Type: application/json
15+
body: "${{ newStatus: .status }}"

0 commit comments

Comments
 (0)