Skip to content

Commit 0e19ebe

Browse files
committed
added more tests to cover edge cases
1 parent cdedcf6 commit 0e19ebe

4 files changed

Lines changed: 195 additions & 0 deletions

File tree

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/jaxrs/JavaJAXRSSpecServerCodegenTest.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,4 +1803,88 @@ public void quarkusEmitsAuthenticatedAnnotationForOpenIdConnect(String specPath,
18031803
final String content = Files.readString(output.toPath().resolve("src/gen/java/org/openapitools/api/ItemsApi.java"));
18041804
Assert.assertEquals(TestUtils.countOccurrences(content, "@io\\.quarkus\\.security\\.Authenticated"), expectedCount);
18051805
}
1806+
1807+
/**
1808+
* Parameterized test for global security inheritance and per-operation security: [] override.
1809+
* Each row: (spec path, interfaceOnly, useQuarkusSecurityAnnotations, expected count).
1810+
*/
1811+
@DataProvider(name = "quarkusGlobalSecurityCases")
1812+
public Object[][] quarkusGlobalSecurityCases() {
1813+
return new Object[][] {
1814+
// global HTTP Basic + Bearer; GET inherits (→ @Authenticated), POST has security:[] (→ none)
1815+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-security-one-op-disabled.yaml", true, true, 1},
1816+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-security-one-op-disabled.yaml", true, false, 0},
1817+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-security-one-op-disabled.yaml", false, true, 1},
1818+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-security-one-op-disabled.yaml", false, false, 0},
1819+
// global OR: unscoped OAuth2 + scoped OAuth2; both ops inherit → both get @Authenticated
1820+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-oauth2-or-scoped-and-unscoped.yaml", true, true, 2},
1821+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-oauth2-or-scoped-and-unscoped.yaml", true, false, 0},
1822+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-oauth2-or-scoped-and-unscoped.yaml", false, true, 2},
1823+
{"src/test/resources/3_0/jaxrs-spec/quarkus-global-oauth2-or-scoped-and-unscoped.yaml", false, false, 0},
1824+
};
1825+
}
1826+
1827+
@Test(dataProvider = "quarkusGlobalSecurityCases")
1828+
public void quarkusHandlesGlobalSecurityScenarios(String specPath, boolean interfaceOnly, boolean useFlag, int expectedCount) throws Exception {
1829+
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
1830+
output.deleteOnExit();
1831+
1832+
final OpenAPI openAPI = new OpenAPIParser()
1833+
.readLocation(specPath, null, new ParseOptions()).getOpenAPI();
1834+
1835+
codegen.setOutputDir(output.getAbsolutePath());
1836+
codegen.setLibrary(QUARKUS_LIBRARY);
1837+
codegen.additionalProperties().put(INTERFACE_ONLY, interfaceOnly);
1838+
codegen.additionalProperties().put(USE_JAKARTA_EE, true);
1839+
codegen.additionalProperties().put(USE_QUARKUS_SECURITY_ANNOTATIONS, useFlag);
1840+
1841+
final DefaultGenerator generator = new DefaultGenerator();
1842+
final List<File> files = generator.opts(new ClientOptInput().openAPI(openAPI).config(codegen)).generate();
1843+
1844+
validateJavaSourceFiles(files);
1845+
1846+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/ItemsApi.java");
1847+
final String content = Files.readString(output.toPath().resolve("src/gen/java/org/openapitools/api/ItemsApi.java"));
1848+
Assert.assertEquals(TestUtils.countOccurrences(content, "@io\\.quarkus\\.security\\.Authenticated"), expectedCount);
1849+
}
1850+
1851+
/**
1852+
* Parameterized test for cross-type OR lists where the qualifying scheme is not the first entry.
1853+
* Each row: (interfaceOnly, useQuarkusSecurityAnnotations, expected count).
1854+
* Spec: GET has scoped OAuth2 OR API Key — API Key qualifies even though OAuth2 alone would not.
1855+
* POST has scoped OAuth2 only — no qualifying scheme.
1856+
*/
1857+
@DataProvider(name = "quarkusMixedTypeOrCases")
1858+
public Object[][] quarkusMixedTypeOrCases() {
1859+
return new Object[][] {
1860+
{true, true, 1},
1861+
{true, false, 0},
1862+
{false, true, 1},
1863+
{false, false, 0},
1864+
};
1865+
}
1866+
1867+
@Test(dataProvider = "quarkusMixedTypeOrCases")
1868+
public void quarkusEmitsAuthenticatedForMixedTypeOrList(boolean interfaceOnly, boolean useFlag, int expectedCount) throws Exception {
1869+
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
1870+
output.deleteOnExit();
1871+
1872+
final OpenAPI openAPI = new OpenAPIParser()
1873+
.readLocation("src/test/resources/3_0/jaxrs-spec/quarkus-oauth2-scoped-or-api-key.yaml", null, new ParseOptions()).getOpenAPI();
1874+
1875+
codegen.setOutputDir(output.getAbsolutePath());
1876+
codegen.setLibrary(QUARKUS_LIBRARY);
1877+
codegen.additionalProperties().put(INTERFACE_ONLY, interfaceOnly);
1878+
codegen.additionalProperties().put(USE_JAKARTA_EE, true);
1879+
codegen.additionalProperties().put(USE_QUARKUS_SECURITY_ANNOTATIONS, useFlag);
1880+
1881+
final DefaultGenerator generator = new DefaultGenerator();
1882+
final List<File> files = generator.opts(new ClientOptInput().openAPI(openAPI).config(codegen)).generate();
1883+
1884+
validateJavaSourceFiles(files);
1885+
1886+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/ItemsApi.java");
1887+
final String content = Files.readString(output.toPath().resolve("src/gen/java/org/openapitools/api/ItemsApi.java"));
1888+
Assert.assertEquals(TestUtils.countOccurrences(content, "@io\\.quarkus\\.security\\.Authenticated"), expectedCount);
1889+
}
18061890
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
openapi: 3.0.1
2+
info:
3+
title: Quarkus global OAuth2 OR — unscoped and scoped entries
4+
version: '1.0'
5+
servers:
6+
- url: 'http://localhost:8080/'
7+
security:
8+
- oauth2_no_scope: []
9+
- oauth2_with_scope:
10+
- admin
11+
paths:
12+
/items:
13+
get:
14+
operationId: getItems
15+
summary: Inherits global security — unscoped entry in OR list makes it least-restrictive
16+
responses:
17+
'200':
18+
description: OK
19+
post:
20+
operationId: createItem
21+
summary: Also inherits global security — same OR reasoning applies
22+
responses:
23+
'201':
24+
description: Created
25+
components:
26+
securitySchemes:
27+
oauth2_no_scope:
28+
type: oauth2
29+
flows:
30+
clientCredentials:
31+
tokenUrl: https://example.com/oauth/token
32+
scopes: {}
33+
oauth2_with_scope:
34+
type: oauth2
35+
flows:
36+
clientCredentials:
37+
tokenUrl: https://example.com/oauth/token
38+
scopes:
39+
admin: Admin access
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
openapi: 3.0.1
2+
info:
3+
title: Quarkus global security with one operation explicitly disabled
4+
version: '1.0'
5+
servers:
6+
- url: 'http://localhost:8080/'
7+
security:
8+
- basic_auth: []
9+
- bearer_auth: []
10+
paths:
11+
/items:
12+
get:
13+
operationId: getItems
14+
summary: Inherits global security (HTTP Basic OR Bearer) — should get @Authenticated
15+
responses:
16+
'200':
17+
description: OK
18+
post:
19+
operationId: createItem
20+
summary: Explicitly disables security with security:[] — should NOT get @Authenticated
21+
security: []
22+
responses:
23+
'201':
24+
description: Created
25+
components:
26+
securitySchemes:
27+
basic_auth:
28+
type: http
29+
scheme: basic
30+
bearer_auth:
31+
type: http
32+
scheme: bearer
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
openapi: 3.0.1
2+
info:
3+
title: Quarkus OAuth2 scoped OR API Key — API Key qualifies for @Authenticated
4+
version: '1.0'
5+
servers:
6+
- url: 'http://localhost:8080/'
7+
paths:
8+
/items:
9+
get:
10+
operationId: getItems
11+
summary: Scoped OAuth2 alone would not qualify, but API Key in the OR list does
12+
security:
13+
- oauth2_with_scope:
14+
- admin
15+
- api_key: []
16+
responses:
17+
'200':
18+
description: OK
19+
post:
20+
operationId: createItem
21+
summary: Scoped OAuth2 only — no qualifying scheme
22+
security:
23+
- oauth2_with_scope:
24+
- admin
25+
responses:
26+
'201':
27+
description: Created
28+
components:
29+
securitySchemes:
30+
oauth2_with_scope:
31+
type: oauth2
32+
flows:
33+
clientCredentials:
34+
tokenUrl: https://example.com/oauth/token
35+
scopes:
36+
admin: Admin access
37+
api_key:
38+
type: apiKey
39+
in: header
40+
name: X-API-Key

0 commit comments

Comments
 (0)