Skip to content

Commit

Permalink
Merge pull request #1739 from lnash94/test_example_improvements
Browse files Browse the repository at this point in the history
[master]Add tests for example mapping
  • Loading branch information
lnash94 authored Jul 24, 2024
2 parents 65e47db + ebe31a0 commit d710e5b
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ public enum DiagnosticMessages {
OAS_CONVERTOR_127("OAS_CONVERTOR_127", "Generated OpenAPI definition does not contain the request" +
" parameter information from the interceptor pipeline. Cause: %s", DiagnosticSeverity.WARNING),
OAS_CONVERTOR_128("OAS_CONVERTOR_128", "Given example path `%s` is not exist, therefore " +
"generated yaml doesn't contain example for `%s` ", DiagnosticSeverity.WARNING),
"generated yaml does not contain example for `%s` ", DiagnosticSeverity.WARNING),
OAS_CONVERTOR_129("OAS_CONVERTOR_129", "Given example path `%s` should be JSON file for" +
" example `%s`", DiagnosticSeverity.WARNING),
OAS_CONVERTOR_130("OAS_CONVERTOR_130", "Following issue occurred parsing given example:" +
" %s", DiagnosticSeverity.WARNING),
OAS_CONVERTOR_130("OAS_CONVERTOR_130", "Generated OpenAPI definition does not contain the example" +
" details since the JSON value provided for the example has parser errors", DiagnosticSeverity.WARNING),
OAS_CONVERTOR_131("OAS_CONVERTOR_131", "`%s` example can not have a blank path",
DiagnosticSeverity.WARNING);
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,7 @@ private static void handleExamples(ResourceMetaInfoAnnotation.Builder resMetaInf
setResponseExamples(resMetaInfoBuilder, objectMap, ballerinFilePath, expressValue.location());
} catch (JsonProcessingException e) {
DiagnosticMessages messages = DiagnosticMessages.OAS_CONVERTOR_130;
ExceptionDiagnostic diagnostic = new ExceptionDiagnostic(messages, mapNode.location(),
e.getOriginalMessage());
ExceptionDiagnostic diagnostic = new ExceptionDiagnostic(messages, mapNode.location());
diagnostics.add(diagnostic);
}
} else if (fName.equals(REQUEST_BODY_ATTRIBUTE)) {
Expand All @@ -192,8 +191,7 @@ private static void handleExamples(ResourceMetaInfoAnnotation.Builder resMetaInf
setRequestExamples(resMetaInfoBuilder, objectMap, ballerinFilePath, expressValue.location());
} catch (JsonProcessingException e) {
DiagnosticMessages messages = DiagnosticMessages.OAS_CONVERTOR_130;
ExceptionDiagnostic diagnostic = new ExceptionDiagnostic(messages, mapNode.location(),
e.getOriginalMessage());
ExceptionDiagnostic diagnostic = new ExceptionDiagnostic(messages, mapNode.location());
diagnostics.add(diagnostic);
}
}
Expand Down Expand Up @@ -291,8 +289,7 @@ private static Map<String, Map<String, Object>> extractExamples(Object exampleVa
modifiedExample.put(exampleName, valueMap);
} catch (IOException e) {
DiagnosticMessages messages = DiagnosticMessages.OAS_CONVERTOR_130;
ExceptionDiagnostic diagnostic = new ExceptionDiagnostic(messages, location,
e.toString());
ExceptionDiagnostic diagnostic = new ExceptionDiagnostic(messages, location);
diagnostics.add(diagnostic);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,15 @@ public void generateOAS3DefinitionsAllService(Path servicePath, Path outPath, St
List<String> fileNames = new ArrayList<>();
for (OASResult definition : openAPIDefinitions) {
try {
List<OpenAPIMapperDiagnostic> definitionDiagnostics = definition.getDiagnostics();
boolean hasErrors = definitionDiagnostics.stream()
.anyMatch(d -> DiagnosticSeverity.ERROR.equals(d.getDiagnosticSeverity()));
this.diagnostics.addAll(definition.getDiagnostics());
if (hasErrors) {
outStream.println("openapi contract generation skipped due to the following code generation " +
"error(s):");
return;
}
if (definition.getOpenAPI().isPresent()) {
Optional<String> content;
if (needJson) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ public class OpenAPIDiagnostic extends Diagnostic {
private final DiagnosticInfo diagnosticInfo;
private final Location location;
private final List<DiagnosticProperty<?>> properties;
private final String message;
private String message = null;

public OpenAPIDiagnostic(DiagnosticInfo diagnosticInfo, Location location, List<DiagnosticProperty<?>> properties,
Object[] args) {
this.diagnosticInfo = diagnosticInfo;
this.location = location;
this.properties = properties;
this.message = MessageFormat.format(diagnosticInfo.messageFormat(), args);
try {
this.message = MessageFormat.format(diagnosticInfo.messageFormat(), args);
} catch (IllegalArgumentException e) {
this.message = diagnosticInfo.messageFormat();
}
}

public Location location() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,34 @@ public void testForGivenBalServiceHasCompilationIssue() throws IOException, Inte
assertOnErrorStream(process, out);
}

@Test(description = "Test for given bal service file example value has json parser issues")
public void testForExamplesHasCompilerErrorse() throws IOException, InterruptedException {
String balFilePath = "examples/negative_test/service.bal";
List<String> buildArgs = new LinkedList<>();
buildArgs.add(0, "openapi");
buildArgs.add("-i");
buildArgs.add(balFilePath);
buildArgs.add("-o");
buildArgs.add(tmpDir.toString());

Process process = getProcess(buildArgs, TEST_RESOURCE);

String out = "openapi contract generation is skipped because of the following error(s) occurred " +
"during the code generation:\n" +
"WARNING [main.bal:(12:25,25:14)] Given example path `examples01.json` " +
"is not exist, therefore generated yaml does not contain example for `responseExample01` \n" +
"WARNING [main.bal:(12:25,25:14)] Generated OpenAPI definition does not contain the example " +
"details since the JSON value provided for the example has parser errors " +
"WARNING [main.bal:(11:19,36:10)] Following issue occurred parsing given example: " +
"Unexpected character (r (code 114)): was expecting double-quote to start field name";
//Thread for wait out put generate
Thread.sleep(5000);
// compare generated file has not included constraint annotation for scenario record field.
Assert.assertTrue(Files.exists(TEST_RESOURCE.resolve("convert_openapi.yaml")));
process.waitFor();
assertOnErrorStream(process, out);
}

@AfterClass
public void cleanUp() throws IOException {
TestUtil.cleanDistribution();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ public void nonOpenAPIAnnotationWithWithoutBasePath() throws IOException, Interr
"project_non_openapi_annotation_without_base_path/result.yaml");
}

@Test(description = "Service is with non openapi annotation and without a base path")
public void exampleMapping() throws IOException, InterruptedException {
executeCommand("examples/response_example/service.bal",
"convert_openapi.yaml",
"examples/response_example/result.yaml");
}

//TODO enable after resolving dependency issue
@Test(description = "Service is with openapi annotation include all oas infor section details", enabled = false)
public void openAPInForSectionTest() throws IOException, InterruptedException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
org = "openapi_example"
name = "negative"
version = "0.1.0"

[build-options]
observabilityIncluded = true

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
fromCurrency: "EUR",
"toCurrency": "LKR",
"fromAmount": 200,
"toAmount": 60000,
"timestamp": "2024-07-14"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import ballerina/http;
import ballerina/openapi;

listener http:Listener httpListener = check new (9000);

final http:Client xeClientSimple = check new ("https://xecdapi.xe.com/v1");

service /convert on httpListener {

@openapi:ResourceInfo {
examples: {
"response": {
"201": {
"examples": {
"application/json": {
"responseExample01": {
"filePath": "examples01.json"
},
"responseExample02": {
"filePath": "example.json"
}
}
}
}
},
"requestBody": {
"application/json": {
requestExample01: {
"value": {
"fromCurrancy": "LKR",
"toCurrancy": "USD"
}
}
}
}
}
}
resource function post rate(record {} payload) returns record {}? {
return {};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
org = "openapi_example"
name = "negative"
version = "0.1.0"

[build-options]
observabilityIncluded = true

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"fromCurrency": "EUR",
"toCurrency": "LKR",
"fromAmount": 200,
"toAmount": 60000,
"timestamp": "2024-07-14"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
openapi: 3.0.1
info:
title: Convert
version: 0.1.0
servers:
- url: "{server}:{port}/convert"
variables:
server:
default: http://localhost
port:
default: "9000"
paths:
/rate:
post:
operationId: postRate
requestBody:
content:
application/json:
schema:
type: object
properties: {}
examples:
requestExample01:
value:
fromCurrancy: LKR
toCurrancy: USD
required: true
responses:
"201":
description: Created
content:
application/json:
schema:
type: object
properties: {}
examples:
responseExample01:
value:
toAmount: 60000
fromCurrency: EUR
toCurrency: LKR
fromAmount: 200
timestamp: 2024-07-14
"202":
description: Accepted
"400":
description: BadRequest
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorPayload'
components:
schemas:
ErrorPayload:
required:
- message
- method
- path
- reason
- status
- timestamp
type: object
properties:
timestamp:
type: string
status:
type: integer
format: int64
reason:
type: string
message:
type: string
path:
type: string
method:
type: string
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import ballerina/http;
import ballerina/openapi;

listener http:Listener httpListener = check new (9000);

final http:Client xeClientSimple = check new ("https://xecdapi.xe.com/v1");

service /convert on httpListener {

@openapi:ResourceInfo {
examples: {
"response": {
"201": {
"examples": {
"application/json": {
"responseExample01": {
"filePath": "example.json"
}
}
}
}
},
"requestBody": {
"application/json": {
"requestExample01": {
"value": {
"fromCurrancy": "LKR",
"toCurrancy": "USD"
}
}
}
}
}
}
resource function post rate(record {} payload) returns record {}? {
return {};
}
}

0 comments on commit d710e5b

Please sign in to comment.