Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/1161/fluent generated openapi actions rebase #9

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions connectors/citrus-openapi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static String createRandomValueExpression(String name, OasSchema schema,
}

public static <T> T createRawRandomValueExpression(String name, OasSchema schema, Map<String, OasSchema> definitions,
boolean quotes, OpenApiSpecification specification, TestContext context) {
boolean quotes, OpenApiSpecification specification, TestContext context) {
if (context.getVariables().containsKey(name)) {
return (T)context.getVariables().get(CitrusSettings.VARIABLE_PREFIX + name + CitrusSettings.VARIABLE_SUFFIX);
}
Expand Down Expand Up @@ -147,7 +147,7 @@ public static String createRandomValueExpression(OasSchema schema, Map<String, O
}

public static <T> T createRawRandomValueExpression(OasSchema schema, Map<String, OasSchema> definitions, boolean quotes,
OpenApiSpecification specification, TestContext context) {
OpenApiSpecification specification, TestContext context) {
if (OasModelHelper.isReferenceType(schema)) {
OasSchema resolved = definitions.get(OasModelHelper.getReferenceName(schema.$ref));
return createRawRandomValueExpression(resolved, definitions, quotes, specification, context);
Expand Down Expand Up @@ -236,6 +236,7 @@ public static String createValidationExpression(String name, OasSchema schema, M
}

/**
* TODO TAT-1291 this method does not respect optional/required properties
* Create validation expression using functions according to schema type and format.
*/
public static String createValidationExpression(OasSchema schema, Map<String, OasSchema> definitions, boolean quotes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
import org.citrusframework.util.ObjectHelper;
import org.springframework.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

/**
* Action executes http client operations such as sending requests and receiving responses.
*
Expand Down Expand Up @@ -61,11 +64,34 @@ public OpenApiClientActionBuilder(String httpClientUri, OpenApiSpecification spe
this.specification = specification;
}

/**
* Sends Http requests as client.
*/
public OpenApiClientRequestActionBuilder send(String operationId) {
OpenApiClientRequestActionBuilder builder = new OpenApiClientRequestActionBuilder(specification, operationId);
public static class OpenApiOperationBuilder {
private final String operationId;
private final Map<String, Object> parameters = new HashMap<>();

public OpenApiOperationBuilder(String operationId) {
this.operationId = operationId;
}

public static OpenApiOperationBuilder operation(String operationId) {
return new OpenApiOperationBuilder(operationId);
}

public OpenApiOperationBuilder withParameter(String name, Object value) {
parameters.put(name, value);
return this;
}

public OpenApiOperationBuilder withParameters(Map<String, Object> parameters) {
this.parameters.putAll(parameters);
return this;
}
}

public OpenApiClientRequestActionBuilder send(OpenApiOperationBuilder openApiOperationBuilder) {
var builder = OpenApiClientRequestActionBuilder.create(
specification,
openApiOperationBuilder.operationId
);
if (httpClient != null) {
builder.endpoint(httpClient);
} else {
Expand All @@ -74,11 +100,19 @@ public OpenApiClientRequestActionBuilder send(String operationId) {

builder.name("openapi:send-request");
builder.withReferenceResolver(referenceResolver);
openApiOperationBuilder.parameters.forEach(builder::withParameter);

this.delegate = builder;
return builder;
}

/**
* Sends Http requests as client.
*/
public OpenApiClientRequestActionBuilder send(String operationId) {
return send(OpenApiOperationBuilder.operation(operationId));
}

/**
* Receives Http response messages as client.
* Uses default Http status 200 OK.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,17 @@ public OpenApiClientRequestMessageBuilder(HttpMessage httpMessage, OpenApiSpecif
@Override
public Message build(TestContext context, String messageType) {
openApiSpec.getOperation(operationId, context).ifPresentOrElse(operationPathAdapter ->
buildMessageFromOperation(operationPathAdapter, context), () -> {
throw new CitrusRuntimeException("Unable to locate operation with id '%s' in OpenAPI specification %s".formatted(operationId, openApiSpec.getSpecUrl()));
});
buildMessageFromOperation(operationPathAdapter, context), () -> {
throw new CitrusRuntimeException("Unable to locate operation with id '%s' in OpenAPI specification %s".formatted(operationId, openApiSpec.getSpecUrl()));
});

return super.build(context, messageType);
}

private void buildMessageFromOperation(OperationPathAdapter operationPathAdapter, TestContext context) {
OasOperation operation = operationPathAdapter.operation();
String path = operationPathAdapter.apiPath();
HttpMethod method = HttpMethod.valueOf(operationPathAdapter.operation().getMethod().toUpperCase(Locale.US));
OasOperation operation = operationPathAdapter.operation();
String path = operationPathAdapter.apiPath();
HttpMethod method = HttpMethod.valueOf(operationPathAdapter.operation().getMethod().toUpperCase(Locale.US));

if (operation.parameters != null) {
setSpecifiedHeaders(context, operation);
Expand All @@ -111,7 +111,7 @@ private void buildMessageFromOperation(OperationPathAdapter operationPathAdapter
String randomizedPath = path;
if (operation.parameters != null) {
List<OasParameter> pathParams = operation.parameters.stream()
.filter(p -> "path".equals(p.in)).toList();
.filter(p -> "path".equals(p.in)).toList();

for (OasParameter parameter : pathParams) {
String parameterValue;
Expand All @@ -121,13 +121,13 @@ private void buildMessageFromOperation(OperationPathAdapter operationPathAdapter
parameterValue = OpenApiTestDataGenerator.createRandomValueExpression((OasSchema) parameter.schema);
}
randomizedPath = Pattern.compile("\\{" + parameter.getName() + "}")
.matcher(randomizedPath)
.replaceAll(parameterValue);
.matcher(randomizedPath)
.replaceAll(parameterValue);
}
}

OasModelHelper.getRequestContentType(operation)
.ifPresent(contentType -> httpMessage.setHeader(HttpHeaders.CONTENT_TYPE, contentType));
.ifPresent(contentType -> httpMessage.setHeader(HttpHeaders.CONTENT_TYPE, contentType));

httpMessage.path(randomizedPath);
httpMessage.method(method);
Expand All @@ -136,40 +136,40 @@ private void buildMessageFromOperation(OperationPathAdapter operationPathAdapter

private void setSpecifiedBody(TestContext context, OasOperation operation) {
Optional<OasSchema> body = OasModelHelper.getRequestBodySchema(
openApiSpec.getOpenApiDoc(context), operation);
openApiSpec.getOpenApiDoc(context), operation);
body.ifPresent(oasSchema -> httpMessage.setPayload(OpenApiTestDataGenerator.createOutboundPayload(oasSchema,
OasModelHelper.getSchemaDefinitions(openApiSpec.getOpenApiDoc(context)), openApiSpec)));
OasModelHelper.getSchemaDefinitions(openApiSpec.getOpenApiDoc(context)), openApiSpec)));
}

private void setSpecifiedQueryParameters(TestContext context, OasOperation operation) {
operation.parameters.stream()
.filter(param -> "query".equals(param.in))
.filter(param -> (param.required != null && param.required) || context.getVariables().containsKey(param.getName()))
.forEach(param -> {
if(!httpMessage.getQueryParams().containsKey(param.getName())) {
httpMessage.queryParam(param.getName(),
OpenApiTestDataGenerator.createRandomValueExpression(param.getName(), (OasSchema) param.schema,
context));
}
});
.filter(param -> "query".equals(param.in))
.filter(param -> (param.required != null && param.required) || context.getVariables().containsKey(param.getName()))
.forEach(param -> {
if(!httpMessage.getQueryParams().containsKey(param.getName())) {
httpMessage.queryParam(param.getName(),
OpenApiTestDataGenerator.createRandomValueExpression(param.getName(), (OasSchema) param.schema,
context));
}
});
}

private void setSpecifiedHeaders(TestContext context, OasOperation operation) {
List<String> configuredHeaders = getHeaderBuilders()
.stream()
.flatMap(b -> b.builderHeaders(context).keySet().stream())
.toList();
.stream()
.flatMap(b -> b.builderHeaders(context).keySet().stream())
.toList();
operation.parameters.stream()
.filter(param -> "header".equals(param.in))
.filter(param -> (param.required != null && param.required) || context.getVariables().containsKey(param.getName()))
.forEach(param -> {
if(httpMessage.getHeader(param.getName()) == null && !configuredHeaders.contains(param.getName())) {
httpMessage.setHeader(param.getName(),
OpenApiTestDataGenerator.createRandomValueExpression(param.getName(), (OasSchema) param.schema,
OasModelHelper.getSchemaDefinitions(openApiSpec.getOpenApiDoc(
context)), false, openApiSpec, context));
}
});
.filter(param -> "header".equals(param.in))
.filter(param -> (param.required != null && param.required) || context.getVariables().containsKey(param.getName()))
.forEach(param -> {
if(httpMessage.getHeader(param.getName()) == null && !configuredHeaders.contains(param.getName())) {
httpMessage.setHeader(param.getName(),
OpenApiTestDataGenerator.createRandomValueExpression(param.getName(), (OasSchema) param.schema,
OasModelHelper.getSchemaDefinitions(openApiSpec.getOpenApiDoc(
context)), false, openApiSpec, context));
}
});
}
}
}
Loading
Loading