Skip to content

Commit e5dee54

Browse files
[R][client] Make enum parameters with required: false optional to request arguments (#19654)
* ODM-11697: Adding null check in R-api * bin/generate-samples.sh executed --------- Co-authored-by: Kunitsyn Oleg <114428801+genestack-okunitsyn@users.noreply.github.com>
1 parent 77eb192 commit e5dee54

File tree

7 files changed

+77
-9
lines changed

7 files changed

+77
-9
lines changed

modules/openapi-generator/src/main/resources/r/api.mustache

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@
324324
{{#items}}
325325
{{#isEnum}}
326326
# validate enum values
327-
if (!(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
327+
if (!is.null(query_item) && !(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
328328
{{#useDefaultExceptionHandling}}
329329
stop("Invalid value for {{{paramName}}} when calling {{classname}}${{operationId}}. Must be {{_enum}}.")
330330
{{/useDefaultExceptionHandling}}
@@ -346,7 +346,7 @@
346346
{{#isEnum}}
347347
# validate enum values
348348
for (query_item in `{{{paramName}}}`) {
349-
if (!(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
349+
if (!is.null(query_item) && !(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
350350
{{#useDefaultExceptionHandling}}
351351
stop("Invalid value for {{{paramName}}} when calling {{classname}}${{operationId}}. Must be {{_enum}}.")
352352
{{/useDefaultExceptionHandling}}
@@ -370,7 +370,7 @@
370370
{{#items}}
371371
{{#isEnum}}
372372
# validate enum values
373-
if (!(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
373+
if (!is.null(query_item) && !(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
374374
{{#useDefaultExceptionHandling}}
375375
stop("Invalid value for {{{paramName}}} when calling {{classname}}${{operationId}}. Must be {{_enum}}.")
376376
{{/useDefaultExceptionHandling}}
@@ -392,7 +392,7 @@
392392
{{#isEnum}}
393393
# validate enum values
394394
for (query_item in `{{{paramName}}}`) {
395-
if (!(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
395+
if (!is.null(query_item) && !(query_item %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
396396
{{#useDefaultExceptionHandling}}
397397
stop("Invalid value for {{{paramName}}} when calling {{classname}}${{operationId}}. Must be {{_enum}}.")
398398
{{/useDefaultExceptionHandling}}
@@ -412,7 +412,7 @@
412412
{{/isArray}}
413413
{{^isArray}}
414414
{{#isEnum}}
415-
if (!(`{{paramName}}` %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
415+
if (!is.null(`{{paramName}}`) && !(`{{paramName}}` %in% c({{#_enum}}"{{{.}}}"{{^-last}}, {{/-last}}{{/_enum}}))) {
416416
{{#useDefaultExceptionHandling}}
417417
stop("Invalid value for {{{paramName}}} when calling {{classname}}${{operationId}}. Must be {{_enum}}.")
418418
{{/useDefaultExceptionHandling}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/r/RClientCodegenTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@
1717

1818
package org.openapitools.codegen.r;
1919

20+
import io.swagger.v3.oas.models.OpenAPI;
21+
import org.openapitools.codegen.ClientOptInput;
2022
import org.openapitools.codegen.CodegenConstants;
23+
import org.openapitools.codegen.DefaultGenerator;
24+
import org.openapitools.codegen.TestUtils;
2125
import org.openapitools.codegen.languages.RClientCodegen;
2226
import org.testng.Assert;
2327
import org.testng.annotations.Test;
2428

29+
import java.io.File;
30+
import java.io.IOException;
31+
import java.nio.file.Files;
32+
import java.nio.file.Paths;
33+
import java.util.regex.Pattern;
34+
2535
public class RClientCodegenTest {
2636

2737
@Test
@@ -53,4 +63,35 @@ public void testAdditionalPropertiesPutForConfigValues() throws Exception {
5363
Assert.assertEquals(codegen.isHideGenerationTimestamp(), false);
5464
}
5565

66+
@Test
67+
public void testNullCheckOnEnumValues() throws IOException {
68+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
69+
output.deleteOnExit();
70+
final DefaultGenerator defaultGenerator = new DefaultGenerator();
71+
72+
RClientCodegen rClientCodegen = new RClientCodegen();
73+
rClientCodegen.setOutputDir(output.getAbsolutePath());
74+
75+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/bugs/issue_18016.yaml");
76+
final ClientOptInput clientOptInput = new ClientOptInput();
77+
clientOptInput.openAPI(openAPI);
78+
clientOptInput.config(rClientCodegen);
79+
defaultGenerator.opts(clientOptInput);
80+
81+
var petsApi = defaultGenerator.generate().stream()
82+
.filter(file -> "pets_api.R".equals(file.getName())).findFirst();
83+
if (petsApi.isEmpty()) {
84+
Assert.fail("`pets_api.R` have not been generated");
85+
}
86+
var isIfCondition = Pattern.compile("^\\s*(?!<#)\\s*if.*\\s%in%\\s.*").asPredicate();
87+
var containsNullCheck = Pattern.compile("![(\\s]*is\\.null").asPredicate();
88+
var hit = false;
89+
for (var line: Files.readAllLines(Paths.get(petsApi.get().getAbsolutePath()))) {
90+
if (isIfCondition.test(line)) {
91+
hit = true;
92+
Assert.assertTrue(containsNullCheck.test(line), "Null check is missing in line: " + line);
93+
}
94+
}
95+
Assert.assertTrue(hit, "No if statement for enum found");
96+
}
5697
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
openapi: "3.0.0"
2+
info:
3+
version: 1.0.0
4+
description: Specification to generate null check for enums in R client
5+
title: RClientNullCheck
6+
paths:
7+
/exists:
8+
get:
9+
tags:
10+
- pets
11+
parameters:
12+
- name: type
13+
in: query
14+
description: Type of pet
15+
required: false
16+
schema:
17+
enum:
18+
- cat
19+
- dog
20+
type: string
21+
responses:
22+
'200':
23+
description: OK
24+
content:
25+
application/json:
26+
schema:
27+
type: boolean

samples/client/echo_api/r/R/query_api.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ QueryApi <- R6::R6Class(
223223

224224

225225

226-
if (!(`enum_nonref_string_query` %in% c("success", "failure", "unclassified"))) {
226+
if (!is.null(`enum_nonref_string_query`) && !(`enum_nonref_string_query` %in% c("success", "failure", "unclassified"))) {
227227
stop("Invalid value for enum_nonref_string_query when calling QueryApi$TestEnumRefString. Must be [success, failure, unclassified].")
228228
}
229229
query_params[["enum_nonref_string_query"]] <- `enum_nonref_string_query`

samples/client/petstore/R-httr2-wrapper/R/pet_api.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ PetApi <- R6::R6Class(
664664
# explore
665665
for (query_item in `status`) {
666666
# validate enum values
667-
if (!(query_item %in% c("available", "pending", "sold"))) {
667+
if (!is.null(query_item) && !(query_item %in% c("available", "pending", "sold"))) {
668668
rlang::abort(message = "Invalid value for `status` when calling PetApi$find_pets_by_status. Must be [available, pending, sold].",
669669
.subclass = "ApiException",
670670
ApiException = ApiException$new(status = 0,

samples/client/petstore/R-httr2/R/pet_api.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ PetApi <- R6::R6Class(
664664
# explore
665665
for (query_item in `status`) {
666666
# validate enum values
667-
if (!(query_item %in% c("available", "pending", "sold"))) {
667+
if (!is.null(query_item) && !(query_item %in% c("available", "pending", "sold"))) {
668668
rlang::abort(message = "Invalid value for `status` when calling PetApi$find_pets_by_status. Must be [available, pending, sold].",
669669
.subclass = "ApiException",
670670
ApiException = ApiException$new(status = 0,

samples/client/petstore/R/R/pet_api.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ PetApi <- R6::R6Class(
664664
# explore
665665
for (query_item in `status`) {
666666
# validate enum values
667-
if (!(query_item %in% c("available", "pending", "sold"))) {
667+
if (!is.null(query_item) && !(query_item %in% c("available", "pending", "sold"))) {
668668
rlang::abort(message = "Invalid value for `status` when calling PetApi$FindPetsByStatus. Must be [available, pending, sold].",
669669
.subclass = "ApiException",
670670
ApiException = ApiException$new(status = 0,

0 commit comments

Comments
 (0)