Skip to content

Commit 7a2e79c

Browse files
committed
test: add tests for InlineModelResolver requestBody with component schema refs
1 parent efc23fa commit 7a2e79c

File tree

7 files changed

+60
-150
lines changed

7 files changed

+60
-150
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ public class CodegenOperation {
3030
hasVersionHeaders = false, hasVersionQueryParams = false,
3131
isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false, defaultReturnType = false,
3232
isDeprecated, isCallbackRequest, uniqueItems,
33-
hasErrorResponseObject, // if 4xx, 5xx responses have at least one error object defined
34-
allowsAnonymous = false; // if the operation allows anonymous access (empty security requirement)
33+
hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined
3534
public CodegenProperty returnProperty;
3635
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
3736
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
@@ -404,7 +403,6 @@ public String toString() {
404403
final StringBuffer sb = new StringBuffer("CodegenOperation{");
405404
sb.append("responseHeaders=").append(responseHeaders);
406405
sb.append(", hasAuthMethods=").append(hasAuthMethods);
407-
sb.append(", allowsAnonymous=").append(allowsAnonymous);
408406
sb.append(", hasConsumes=").append(hasConsumes);
409407
sb.append(", hasProduces=").append(hasProduces);
410408
sb.append(", hasOptionalParams=").append(hasOptionalParams);
@@ -477,7 +475,6 @@ public boolean equals(Object o) {
477475
if (o == null || getClass() != o.getClass()) return false;
478476
CodegenOperation that = (CodegenOperation) o;
479477
return hasAuthMethods == that.hasAuthMethods &&
480-
allowsAnonymous == that.allowsAnonymous &&
481478
hasConsumes == that.hasConsumes &&
482479
hasProduces == that.hasProduces &&
483480
hasOptionalParams == that.hasOptionalParams &&
@@ -546,7 +543,7 @@ public boolean equals(Object o) {
546543
@Override
547544
public int hashCode() {
548545

549-
return Objects.hash(responseHeaders, hasAuthMethods, allowsAnonymous, hasConsumes, hasProduces, hasOptionalParams,
546+
return Objects.hash(responseHeaders, hasAuthMethods, hasConsumes, hasProduces, hasOptionalParams,
550547
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
551548
isArray, isMultipart, isVoid, isResponseBinary, isResponseFile, isResponseOptional, hasReference,
552549
isDeprecated, isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod,

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,19 +1579,6 @@ private void processOperation(String resourcePath, String httpMethod, Operation
15791579
continue;
15801580
}
15811581

1582-
// Check if anonymous access is allowed (empty SecurityRequirement means anonymous is allowed)
1583-
// This must be checked before processing auth methods to properly handle mixed security requirements
1584-
boolean allowsAnonymous = checkAllowsAnonymous(securities);
1585-
if (!allowsAnonymous && securities == null) {
1586-
// If no operation-level securities, check global securities
1587-
allowsAnonymous = checkAllowsAnonymous(globalSecurities);
1588-
}
1589-
// If no securities at all (neither operation nor global), anonymous is allowed by default
1590-
if (!allowsAnonymous && securities == null && (globalSecurities == null || globalSecurities.isEmpty())) {
1591-
allowsAnonymous = true;
1592-
}
1593-
codegenOperation.allowsAnonymous = allowsAnonymous;
1594-
15951582
Map<String, SecurityScheme> authMethods = getAuthMethods(securities, securitySchemes);
15961583

15971584
if (authMethods != null && !authMethods.isEmpty()) {
@@ -1801,25 +1788,6 @@ private ModelsMap processModels(CodegenConfig config, Map<String, Schema> defini
18011788
return objs;
18021789
}
18031790

1804-
/**
1805-
* Check if the security requirements allow anonymous access.
1806-
* An empty SecurityRequirement (empty map) indicates anonymous access is allowed.
1807-
*
1808-
* @param securities List of security requirements to check
1809-
* @return true if any security requirement is empty (allows anonymous), false otherwise
1810-
*/
1811-
private boolean checkAllowsAnonymous(List<SecurityRequirement> securities) {
1812-
if (securities == null || securities.isEmpty()) {
1813-
return false;
1814-
}
1815-
for (SecurityRequirement req : securities) {
1816-
if (req == null || req.isEmpty()) {
1817-
return true;
1818-
}
1819-
}
1820-
return false;
1821-
}
1822-
18231791
private Map<String, SecurityScheme> getAuthMethods(List<SecurityRequirement> securities, Map<String, SecurityScheme> securitySchemes) {
18241792
if (securities == null || (securitySchemes == null || securitySchemes.isEmpty())) {
18251793
return null;

modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,23 @@ private void flattenContent(Content content, String name) {
496496
if (schema == null) {
497497
continue;
498498
}
499-
String schemaName = resolveModelName(schema.getTitle(), name); // name example: testPost_request
499+
// Check if schema has a $ref pointing to a component schema
500+
// If so, prefer the referenced schema name over operation-based naming
501+
String schemaName;
502+
if (schema.get$ref() != null) {
503+
String refName = ModelUtils.getSimpleRef(schema.get$ref());
504+
if (refName != null && openAPI.getComponents() != null &&
505+
openAPI.getComponents().getSchemas() != null &&
506+
openAPI.getComponents().getSchemas().containsKey(refName)) {
507+
// Use the referenced schema name instead of operation-based name
508+
schemaName = resolveModelName(schema.getTitle(), refName);
509+
} else {
510+
// Fallback to original behavior if ref doesn't point to a component schema
511+
schemaName = resolveModelName(schema.getTitle(), name);
512+
}
513+
} else {
514+
schemaName = resolveModelName(schema.getTitle(), name); // name example: testPost_request
515+
}
500516
// Recursively gather/make inline models within this schema if any
501517
gatherInlineModels(schema, schemaName);
502518
if (isModelNeeded(schema)) {

modules/openapi-generator/src/main/resources/typescript-axios/apiInner.mustache

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
6767
const localVarHeaderParameter = {} as any;
6868
const localVarQueryParameter = {} as any;{{#vendorExtensions}}{{#hasFormParams}}
6969
const localVarFormParams = new {{^multipartFormData}}URLSearchParams(){{/multipartFormData}}{{#multipartFormData}}((configuration && configuration.formDataCtor) || FormData)(){{/multipartFormData}};{{/hasFormParams}}{{/vendorExtensions}}
70-
const allowsAnonymous = {{allowsAnonymous}};
7170
7271
{{#authMethods}}
7372
// authentication {{name}} required
@@ -77,23 +76,23 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
7776
await setAWS4SignatureInterceptor(globalAxios, configuration)
7877
{{/withAWSV4Signature}}
7978
{{#isKeyInHeader}}
80-
await setApiKeyToObject(localVarHeaderParameter, "{{keyParamName}}", configuration, allowsAnonymous)
79+
await setApiKeyToObject(localVarHeaderParameter, "{{keyParamName}}", configuration)
8180
{{/isKeyInHeader}}
8281
{{#isKeyInQuery}}
83-
await setApiKeyToObject(localVarQueryParameter, "{{keyParamName}}", configuration, allowsAnonymous)
82+
await setApiKeyToObject(localVarQueryParameter, "{{keyParamName}}", configuration)
8483
{{/isKeyInQuery}}
8584
{{/isApiKey}}
8685
{{#isBasicBasic}}
8786
// http basic authentication required
88-
setBasicAuthToObject(localVarRequestOptions, configuration, allowsAnonymous)
87+
setBasicAuthToObject(localVarRequestOptions, configuration)
8988
{{/isBasicBasic}}
9089
{{#isBasicBearer}}
9190
// http bearer authentication required
92-
await setBearerAuthToObject(localVarHeaderParameter, configuration, allowsAnonymous)
91+
await setBearerAuthToObject(localVarHeaderParameter, configuration)
9392
{{/isBasicBearer}}
9493
{{#isOAuth}}
9594
// oauth required
96-
await setOAuthToObject(localVarHeaderParameter, "{{name}}", [{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}], configuration, allowsAnonymous)
95+
await setOAuthToObject(localVarHeaderParameter, "{{name}}", [{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}], configuration)
9796
{{/isOAuth}}
9897
9998
{{/authMethods}}

modules/openapi-generator/src/main/resources/typescript-axios/common.mustache

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,70 +25,36 @@ export const assertParamExists = function (functionName: string, paramName: stri
2525
}
2626
}
2727

28-
export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration, allowsAnonymous?: boolean) {
28+
export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) {
2929
if (configuration && configuration.apiKey) {
30-
try {
31-
const localVarApiKeyValue = typeof configuration.apiKey === 'function'
32-
? await configuration.apiKey(keyParamName)
33-
: await configuration.apiKey;
34-
if (localVarApiKeyValue) {
35-
object[keyParamName] = localVarApiKeyValue;
36-
}
37-
} catch (error) {
38-
if (!allowsAnonymous) {
39-
throw error;
40-
}
41-
// If anonymous is allowed, silently ignore authentication failures
42-
}
30+
const localVarApiKeyValue = typeof configuration.apiKey === 'function'
31+
? await configuration.apiKey(keyParamName)
32+
: await configuration.apiKey;
33+
object[keyParamName] = localVarApiKeyValue;
4334
}
4435
}
4536

46-
export const setBasicAuthToObject = function (object: any, configuration?: Configuration, allowsAnonymous?: boolean) {
37+
export const setBasicAuthToObject = function (object: any, configuration?: Configuration) {
4738
if (configuration && (configuration.username || configuration.password)) {
48-
try {
49-
object["auth"] = { username: configuration.username, password: configuration.password };
50-
} catch (error) {
51-
if (!allowsAnonymous) {
52-
throw error;
53-
}
54-
// If anonymous is allowed, silently ignore authentication failures
55-
}
39+
object["auth"] = { username: configuration.username, password: configuration.password };
5640
}
5741
}
5842

59-
export const setBearerAuthToObject = async function (object: any, configuration?: Configuration, allowsAnonymous?: boolean) {
43+
export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) {
6044
if (configuration && configuration.accessToken) {
61-
try {
62-
const accessToken = typeof configuration.accessToken === 'function'
63-
? await configuration.accessToken()
64-
: await configuration.accessToken;
65-
if (accessToken) {
66-
object["Authorization"] = "Bearer " + accessToken;
67-
}
68-
} catch (error) {
69-
if (!allowsAnonymous) {
70-
throw error;
71-
}
72-
// If anonymous is allowed, silently ignore authentication failures
73-
}
45+
const accessToken = typeof configuration.accessToken === 'function'
46+
? await configuration.accessToken()
47+
: await configuration.accessToken;
48+
object["Authorization"] = "Bearer " + accessToken;
7449
}
7550
}
7651

77-
export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration, allowsAnonymous?: boolean) {
52+
export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) {
7853
if (configuration && configuration.accessToken) {
79-
try {
80-
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
81-
? await configuration.accessToken(name, scopes)
82-
: await configuration.accessToken;
83-
if (localVarAccessTokenValue) {
84-
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
85-
}
86-
} catch (error) {
87-
if (!allowsAnonymous) {
88-
throw error;
89-
}
90-
// If anonymous is allowed, silently ignore authentication failures
91-
}
54+
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
55+
? await configuration.accessToken(name, scopes)
56+
: await configuration.accessToken;
57+
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
9258
}
9359
}
9460

samples/client/echo_api/typescript-axios/build/api.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,10 @@ export const AuthApiAxiosParamCreator = function (configuration?: Configuration)
160160
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
161161
const localVarHeaderParameter = {} as any;
162162
const localVarQueryParameter = {} as any;
163-
const allowsAnonymous = false;
164163

165164
// authentication http_auth required
166165
// http basic authentication required
167-
setBasicAuthToObject(localVarRequestOptions, configuration, allowsAnonymous)
166+
setBasicAuthToObject(localVarRequestOptions, configuration)
168167

169168
localVarHeaderParameter['Accept'] = 'text/plain';
170169

@@ -195,11 +194,10 @@ export const AuthApiAxiosParamCreator = function (configuration?: Configuration)
195194
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
196195
const localVarHeaderParameter = {} as any;
197196
const localVarQueryParameter = {} as any;
198-
const allowsAnonymous = false;
199197

200198
// authentication http_bearer_auth required
201199
// http bearer authentication required
202-
await setBearerAuthToObject(localVarHeaderParameter, configuration, allowsAnonymous)
200+
await setBearerAuthToObject(localVarHeaderParameter, configuration)
203201

204202
localVarHeaderParameter['Accept'] = 'text/plain';
205203

samples/client/echo_api/typescript-axios/build/common.ts

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -29,70 +29,36 @@ export const assertParamExists = function (functionName: string, paramName: stri
2929
}
3030
}
3131

32-
export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration, allowsAnonymous?: boolean) {
32+
export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) {
3333
if (configuration && configuration.apiKey) {
34-
try {
35-
const localVarApiKeyValue = typeof configuration.apiKey === 'function'
36-
? await configuration.apiKey(keyParamName)
37-
: await configuration.apiKey;
38-
if (localVarApiKeyValue) {
39-
object[keyParamName] = localVarApiKeyValue;
40-
}
41-
} catch (error) {
42-
if (!allowsAnonymous) {
43-
throw error;
44-
}
45-
// If anonymous is allowed, silently ignore authentication failures
46-
}
34+
const localVarApiKeyValue = typeof configuration.apiKey === 'function'
35+
? await configuration.apiKey(keyParamName)
36+
: await configuration.apiKey;
37+
object[keyParamName] = localVarApiKeyValue;
4738
}
4839
}
4940

50-
export const setBasicAuthToObject = function (object: any, configuration?: Configuration, allowsAnonymous?: boolean) {
41+
export const setBasicAuthToObject = function (object: any, configuration?: Configuration) {
5142
if (configuration && (configuration.username || configuration.password)) {
52-
try {
53-
object["auth"] = { username: configuration.username, password: configuration.password };
54-
} catch (error) {
55-
if (!allowsAnonymous) {
56-
throw error;
57-
}
58-
// If anonymous is allowed, silently ignore authentication failures
59-
}
43+
object["auth"] = { username: configuration.username, password: configuration.password };
6044
}
6145
}
6246

63-
export const setBearerAuthToObject = async function (object: any, configuration?: Configuration, allowsAnonymous?: boolean) {
47+
export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) {
6448
if (configuration && configuration.accessToken) {
65-
try {
66-
const accessToken = typeof configuration.accessToken === 'function'
67-
? await configuration.accessToken()
68-
: await configuration.accessToken;
69-
if (accessToken) {
70-
object["Authorization"] = "Bearer " + accessToken;
71-
}
72-
} catch (error) {
73-
if (!allowsAnonymous) {
74-
throw error;
75-
}
76-
// If anonymous is allowed, silently ignore authentication failures
77-
}
49+
const accessToken = typeof configuration.accessToken === 'function'
50+
? await configuration.accessToken()
51+
: await configuration.accessToken;
52+
object["Authorization"] = "Bearer " + accessToken;
7853
}
7954
}
8055

81-
export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration, allowsAnonymous?: boolean) {
56+
export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) {
8257
if (configuration && configuration.accessToken) {
83-
try {
84-
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
85-
? await configuration.accessToken(name, scopes)
86-
: await configuration.accessToken;
87-
if (localVarAccessTokenValue) {
88-
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
89-
}
90-
} catch (error) {
91-
if (!allowsAnonymous) {
92-
throw error;
93-
}
94-
// If anonymous is allowed, silently ignore authentication failures
95-
}
58+
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
59+
? await configuration.accessToken(name, scopes)
60+
: await configuration.accessToken;
61+
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
9662
}
9763
}
9864

0 commit comments

Comments
 (0)