Skip to content

Commit 6abe6ff

Browse files
fix(cpp-qt): Fix enum query parameter serialization for both inline and referenced enums (#22559)
* fix(cpp-qt): Fix enum query parameter serialization for both inline and referenced enums For enum query parameters, the template was incorrectly using asJsonObject() which returns {"value": "enumValue"} and then iterating over keys, using "value" as the parameter name instead of the actual parameter name. This fix adds special handling for both inline enums (isEnum) and referenced enums (isEnumRef) to use asJson() directly, which returns the correct enum string value for URL serialization. Fixes enum query parameters like ?scope=property instead of ?value=property. Completes the fix started in PR #21211 which added the asJsonObject() method to make enum code compile, but the template logic was still incorrect for URL query parameter serialization. Note: The petstore samples don't contain enum query parameter tests to demonstrate this fix (they use string arrays). Future contributors may want to add enum query parameter examples to better showcase this functionality. * add tests for enum inline, ref for query parameters * update cmake version to 3.5 --------- Co-authored-by: Sohaib Athar <[email protected]>
1 parent a529769 commit 6abe6ff

File tree

20 files changed

+1417
-24
lines changed

20 files changed

+1417
-24
lines changed

modules/openapi-generator/src/main/resources/cpp-qt-client/api-body.mustache

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,21 @@ void {{classname}}::{{nickname}}({{#allParams}}{{#required}}const {{{dataType}}}
344344
else
345345
fullPath.append("?");
346346
{{^isPrimitiveType}}
347+
{{#isEnum}}
348+
// For enum parameters, use direct string serialization instead of object iteration
349+
QString enumValue = {{paramName}}{{^required}}.value(){{/required}}.asJson();
350+
if (!enumValue.isEmpty()) {
351+
fullPath.append(QUrl::toPercentEncoding("{{baseName}}")).append("=").append(QUrl::toPercentEncoding(enumValue));
352+
}
353+
{{/isEnum}}
354+
{{#isEnumRef}}
355+
// For enum reference parameters, use direct string serialization instead of object iteration
356+
QString enumValue = {{paramName}}{{^required}}.value(){{/required}}.asJson();
357+
if (!enumValue.isEmpty()) {
358+
fullPath.append(QUrl::toPercentEncoding("{{baseName}}")).append("=").append(QUrl::toPercentEncoding(enumValue));
359+
}
360+
{{/isEnumRef}}
361+
{{^isEnum}}{{^isEnumRef}}
347362
QString paramString = (queryStyle == "form" && {{isExplode}}) ? "" : (queryStyle == "form" && !({{isExplode}})) ? "{{baseName}}"+querySuffix : "";
348363
QJsonObject parameter = {{paramName}}{{^required}}.value(){{/required}}.asJsonObject();
349364
qint32 count = 0;
@@ -390,6 +405,7 @@ void {{classname}}::{{nickname}}({{#allParams}}{{#required}}const {{{dataType}}}
390405
count++;
391406
}
392407
fullPath.append(paramString);
408+
{{/isEnumRef}}{{/isEnum}}
393409
{{/isPrimitiveType}}{{#isPrimitiveType}}
394410
fullPath.append(QUrl::toPercentEncoding("{{baseName}}")).append(querySuffix).append(QUrl::toPercentEncoding(::{{cppNamespace}}::toStringValue({{paramName}}{{^required}}.stringValue(){{/required}})));
395411
{{/isPrimitiveType}}

modules/openapi-generator/src/test/resources/3_0/cpp-qt/petstore.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,35 @@ paths:
572572
description: Invalid username supplied
573573
"404":
574574
description: User not found
575+
"/fake/enum_inline_or_ref":
576+
get:
577+
tags:
578+
- fake
579+
summary: fake endpoint to test enum (inline or ref)
580+
description: ""
581+
operationId: get_enum_inline_or_ref
582+
parameters:
583+
- name: enum_inline
584+
in: query
585+
description: Enum status inline
586+
schema:
587+
type: string
588+
enum:
589+
- placed
590+
- approved
591+
- delivered
592+
- name: enum_ref
593+
in: query
594+
description: Enum status
595+
schema:
596+
$ref: "#/components/schemas/EnumStatus"
597+
responses:
598+
"200":
599+
description: successful operation
600+
"400":
601+
description: Invalid username supplied
602+
"404":
603+
description: User not found
575604
servers:
576605
- url: http://petstore.swagger.io/v2
577606
- url: http://localhost:8080/v2
@@ -610,6 +639,13 @@ components:
610639
name: api_key
611640
in: header
612641
schemas:
642+
EnumStatus:
643+
type: string
644+
description: Order Status
645+
enum:
646+
- placed
647+
- approved
648+
- delivered
613649
Order:
614650
title: Pet Order
615651
description: An order for a pets from the pet store

samples/client/petstore/cpp-qt-addDownloadProgress/.openapi-generator/FILES

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ client/PFXApiResponse.h
66
client/PFXCategory.cpp
77
client/PFXCategory.h
88
client/PFXEnum.h
9+
client/PFXEnumStatus.cpp
10+
client/PFXEnumStatus.h
11+
client/PFXFakeApi.cpp
12+
client/PFXFakeApi.h
913
client/PFXHelpers.cpp
1014
client/PFXHelpers.h
1115
client/PFXHttpFileElement.cpp

samples/client/petstore/cpp-qt-addDownloadProgress/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.2)
1+
cmake_minimum_required(VERSION 3.5)
22

33
project(cpp-qt-petstore)
44
set(CMAKE_VERBOSE_MAKEFILE ON)

samples/client/petstore/cpp-qt-addDownloadProgress/README.md

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@ example.h:
2727
```c++
2828

2929
#include <iostream>
30-
#include "../client/PFXPetApi.h"
30+
#include "../client/PFXFakeApi.h"
3131

3232
using namespace test_namespace;
3333

3434
class Example : public QObject {
3535
Q_OBJECT
36-
PFXPet create();
36+
QString create();
37+
PFXEnumStatus create();
3738
public Q_SLOTS:
3839
void exampleFunction1();
3940
};
@@ -43,32 +44,43 @@ public Q_SLOTS:
4344
example.cpp:
4445
```c++
4546
46-
#include "../client/PFXPetApi.h"
47+
#include "../client/PFXFakeApi.h"
4748
#include "example.h"
4849
#include <QTimer>
4950
#include <QEventLoop>
5051
51-
PFXPet Example::create(){
52-
PFXPet obj;
52+
QString Example::create(){
53+
QString obj;
54+
PFXEnumStatus Example::create(){
55+
PFXEnumStatus obj;
5356
return obj;
5457
}
5558
5659
void Example::exampleFunction1(){
57-
PFXPetApi apiInstance;
60+
PFXFakeApi apiInstance;
5861
59-
//OAuth Authentication supported right now
62+
QEventLoop loop;
63+
connect(&apiInstance, &PFXFakeApi::getEnumInlineOrRefSignal, [&]() {
64+
loop.quit();
65+
});
66+
connect(&apiInstance, &PFXFakeApi::getEnumInlineOrRefSignalE, [&](QNetworkReply::NetworkError, QString error_str) {
67+
qDebug() << "Error happened while issuing request : " << error_str;
68+
loop.quit();
69+
});
70+
71+
QString enum_inline = create(); // QString | Enum status inline
6072
6173
QEventLoop loop;
62-
connect(&apiInstance, &PFXPetApi::addPetSignal, [&]() {
74+
connect(&apiInstance, &PFXFakeApi::getEnumInlineOrRefSignal, [&]() {
6375
loop.quit();
6476
});
65-
connect(&apiInstance, &PFXPetApi::addPetSignalE, [&](QNetworkReply::NetworkError, QString error_str) {
77+
connect(&apiInstance, &PFXFakeApi::getEnumInlineOrRefSignalE, [&](QNetworkReply::NetworkError, QString error_str) {
6678
qDebug() << "Error happened while issuing request : " << error_str;
6779
loop.quit();
6880
});
6981
70-
PFXPet pfx_pet = create(); // PFXPet | Pet object that needs to be added to the store
71-
apiInstance.addPet(pfx_pet);
82+
PFXEnumStatus enum_ref = create(); // PFXEnumStatus | Enum status
83+
apiInstance.getEnumInlineOrRef(enum_inlineenum_ref);
7284
QTimer::singleShot(5000, &loop, &QEventLoop::quit);
7385
loop.exec();
7486
}

samples/client/petstore/cpp-qt-addDownloadProgress/client/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ include(CMakePackageConfigHelpers)
1313
add_library(${PROJECT_NAME}
1414
PFXApiResponse.h
1515
PFXCategory.h
16+
PFXEnumStatus.h
1617
PFXOrder.h
1718
PFXPet.h
1819
PFXTag.h
1920
PFXTestAnyType.h
2021
PFXUser.h
22+
PFXFakeApi.h
2123
PFXPetApi.h
2224
PFXPrimitivesApi.h
2325
PFXStoreApi.h
@@ -32,11 +34,13 @@ add_library(${PROJECT_NAME}
3234
PFXOauth.h
3335
PFXApiResponse.cpp
3436
PFXCategory.cpp
37+
PFXEnumStatus.cpp
3538
PFXOrder.cpp
3639
PFXPet.cpp
3740
PFXTag.cpp
3841
PFXTestAnyType.cpp
3942
PFXUser.cpp
43+
PFXFakeApi.cpp
4044
PFXPetApi.cpp
4145
PFXPrimitivesApi.cpp
4246
PFXStoreApi.cpp
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* OpenAPI Petstore
3+
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
4+
*
5+
* The version of the OpenAPI document: 1.0.0
6+
*
7+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
8+
* https://openapi-generator.tech
9+
* Do not edit the class manually.
10+
*/
11+
12+
#include "PFXEnumStatus.h"
13+
14+
#include <QDebug>
15+
#include <QJsonArray>
16+
#include <QJsonDocument>
17+
#include <QObject>
18+
19+
#include "PFXHelpers.h"
20+
21+
namespace test_namespace {
22+
23+
PFXEnumStatus::PFXEnumStatus(QString json) {
24+
this->initializeModel();
25+
this->fromJson(json);
26+
}
27+
28+
PFXEnumStatus::PFXEnumStatus() {
29+
this->initializeModel();
30+
}
31+
32+
PFXEnumStatus::~PFXEnumStatus() {}
33+
34+
void PFXEnumStatus::initializeModel() {
35+
36+
m_value_isSet = false;
37+
m_value_isValid = false;
38+
m_value = ePFXEnumStatus::INVALID_VALUE_OPENAPI_GENERATED;
39+
}
40+
41+
void PFXEnumStatus::fromJson(QString jsonString) {
42+
43+
if ( jsonString.compare("placed", Qt::CaseInsensitive) == 0) {
44+
m_value = ePFXEnumStatus::PLACED;
45+
m_value_isSet = m_value_isValid = true;
46+
}
47+
else if ( jsonString.compare("approved", Qt::CaseInsensitive) == 0) {
48+
m_value = ePFXEnumStatus::APPROVED;
49+
m_value_isSet = m_value_isValid = true;
50+
}
51+
else if ( jsonString.compare("delivered", Qt::CaseInsensitive) == 0) {
52+
m_value = ePFXEnumStatus::DELIVERED;
53+
m_value_isSet = m_value_isValid = true;
54+
}
55+
}
56+
57+
void PFXEnumStatus::fromJsonValue(QJsonValue json) {
58+
fromJson(json.toString());
59+
}
60+
61+
QString PFXEnumStatus::asJson() const {
62+
63+
QString val;
64+
switch (m_value){
65+
case ePFXEnumStatus::PLACED:
66+
val = "placed";
67+
break;
68+
case ePFXEnumStatus::APPROVED:
69+
val = "approved";
70+
break;
71+
case ePFXEnumStatus::DELIVERED:
72+
val = "delivered";
73+
break;
74+
default:
75+
break;
76+
}
77+
return val;
78+
}
79+
80+
QJsonValue PFXEnumStatus::asJsonValue() const {
81+
82+
return QJsonValue(asJson());
83+
}
84+
85+
86+
PFXEnumStatus::ePFXEnumStatus PFXEnumStatus::getValue() const {
87+
return m_value;
88+
}
89+
90+
void PFXEnumStatus::setValue(const PFXEnumStatus::ePFXEnumStatus& value){
91+
m_value = value;
92+
m_value_isSet = true;
93+
}
94+
bool PFXEnumStatus::isSet() const {
95+
96+
return m_value_isSet;
97+
}
98+
99+
bool PFXEnumStatus::isValid() const {
100+
// only required properties are required for the object to be considered valid
101+
return m_value_isValid;
102+
}
103+
104+
} // namespace test_namespace
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* OpenAPI Petstore
3+
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
4+
*
5+
* The version of the OpenAPI document: 1.0.0
6+
*
7+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
8+
* https://openapi-generator.tech
9+
* Do not edit the class manually.
10+
*/
11+
12+
/*
13+
* PFXEnumStatus.h
14+
*
15+
* Order Status
16+
*/
17+
18+
#ifndef PFXEnumStatus_H
19+
#define PFXEnumStatus_H
20+
21+
#include <QJsonObject>
22+
23+
24+
#include "PFXEnum.h"
25+
#include "PFXObject.h"
26+
27+
namespace test_namespace {
28+
29+
class PFXEnumStatus : public PFXEnum {
30+
public:
31+
PFXEnumStatus();
32+
PFXEnumStatus(QString json);
33+
~PFXEnumStatus() override;
34+
35+
QString asJson() const override;
36+
QJsonValue asJsonValue() const override;
37+
void fromJsonValue(QJsonValue json) override;
38+
void fromJson(QString jsonString) override;
39+
40+
enum class ePFXEnumStatus {
41+
INVALID_VALUE_OPENAPI_GENERATED = 0,
42+
PLACED,
43+
APPROVED,
44+
DELIVERED
45+
};
46+
PFXEnumStatus::ePFXEnumStatus getValue() const;
47+
void setValue(const PFXEnumStatus::ePFXEnumStatus& value);
48+
virtual bool isSet() const override;
49+
virtual bool isValid() const override;
50+
51+
private:
52+
void initializeModel();
53+
54+
ePFXEnumStatus m_value;
55+
bool m_value_isSet;
56+
bool m_value_isValid;
57+
};
58+
59+
} // namespace test_namespace
60+
61+
Q_DECLARE_METATYPE(test_namespace::PFXEnumStatus)
62+
63+
#endif // PFXEnumStatus_H

0 commit comments

Comments
 (0)