1
1
import { KiotaLogEntry , KiotaTreeResult , KiotaOpenApiNode , LogLevel , SecurityRequirementObject , OAuth2SecurityScheme , HttpSecurityScheme , ApiKeySecurityScheme , OpenIdSecurityScheme } from "../../types" ;
2
2
import { getKiotaTree } from "../../lib/getKiotaTree" ;
3
- import { LogLevel } from "../../types" ;
4
3
5
4
function existsGreaterThanLevelLogs ( logs : KiotaLogEntry [ ] | undefined , level : LogLevel ) : boolean {
6
5
if ( ! logs ) return false ;
@@ -22,12 +21,6 @@ function flattenKiotaTree(tree: KiotaOpenApiNode): KiotaOpenApiNode[] {
22
21
return result ;
23
22
}
24
23
25
- function findSecurityRequirementByName ( node : KiotaOpenApiNode | undefined , security_requirement_name : string ) : SecurityRequirementObject | undefined {
26
- if ( ! node ) return undefined ;
27
- if ( ! node . security ) return undefined ;
28
- return node . security [ security_requirement_name ] ;
29
- }
30
-
31
24
describe ( "getKiotaTree" , ( ) => {
32
25
test ( 'testGetKiotaTree_from_valid_File' , async ( ) => {
33
26
const descriptionUrl = '../../tests/Kiota.Builder.IntegrationTests/DiscriminatorSample.yaml' ;
@@ -51,22 +44,33 @@ describe("getKiotaTree", () => {
51
44
expect ( existsGreaterThanLevelLogs ( actual ?. logs , LogLevel . warning ) ) . toBeFalsy ( ) ;
52
45
expect ( existsGreaterThanLevelLogs ( actual ?. logs , LogLevel . information ) ) . toBeTruthy ( ) ;
53
46
47
+ // Check if the security requirements are defined correctly for get operation
48
+ // It should have one security requirement: oAuth2AuthCode
54
49
const actualListOperationNode = findOperationByPath ( actual , '\\repairs#GET' ) ;
55
50
expect ( actualListOperationNode ) . toBeDefined ( ) ;
56
51
expect ( actualListOperationNode ?. operationId ) . toEqual ( 'listRepairs' ) ;
57
52
expect ( actualListOperationNode ?. security ) . toBeDefined ( ) ;
58
- const actualListSecurityRequirement = findSecurityRequirementByName ( actualListOperationNode , 'oAuth2AuthCode' ) ;
59
- expect ( actualListSecurityRequirement ) . toBeDefined ( ) ;
60
- expect ( actualListSecurityRequirement ?. [ 0 ] ) . toEqual ( 'api://sample/repairs_read' ) ;
61
-
53
+ expect ( actualListOperationNode ?. security ?. length ) . toEqual ( 1 ) ;
54
+ const firstSecurityRequirementInGet = actualListOperationNode ?. security ?. [ 0 ] ;
55
+ const oAuth2AuthCodeSecurityRequirementInGet = firstSecurityRequirementInGet ?. [ 'oAuth2AuthCode' ] ;
56
+ expect ( oAuth2AuthCodeSecurityRequirementInGet ) . toBeDefined ( ) ;
57
+ expect ( oAuth2AuthCodeSecurityRequirementInGet ?. length ) . toEqual ( 1 ) ;
58
+ expect ( oAuth2AuthCodeSecurityRequirementInGet ?. [ 0 ] ) . toEqual ( 'api://sample/repairs_read' ) ;
59
+
60
+ // Check if the security requirements are defined correctly for post operation
61
+ // It should have two security requirements: oAuth2AuthCode and httpAuth
62
62
const actualPostOperationNode = findOperationByPath ( actual , '\\repairs#POST' ) ;
63
63
expect ( actualPostOperationNode ) . toBeDefined ( ) ;
64
64
expect ( actualPostOperationNode ?. operationId ) . toEqual ( 'repairs_post' ) ;
65
65
expect ( actualPostOperationNode ?. security ) . toBeDefined ( ) ;
66
- const actualPostSecurityRequirement = findSecurityRequirementByName ( actualPostOperationNode , 'oAuth2AuthCode' ) ;
67
- expect ( actualPostSecurityRequirement ) . toBeDefined ( ) ;
68
- expect ( actualPostSecurityRequirement ?. [ 0 ] ) . toEqual ( 'api://sample/repairs_write' ) ;
69
-
66
+ expect ( actualPostOperationNode ?. security ?. length ) . toEqual ( 1 ) ;
67
+ const firstSecurityRequirementInPost = actualPostOperationNode ?. security ?. [ 0 ] ;
68
+ const oAuth2AuthCodeSecurityRequirementInPost = firstSecurityRequirementInPost ?. [ 'oAuth2AuthCode' ] ;
69
+ expect ( oAuth2AuthCodeSecurityRequirementInPost ) . toBeDefined ( ) ;
70
+ expect ( oAuth2AuthCodeSecurityRequirementInPost ?. length ) . toEqual ( 1 ) ;
71
+ expect ( oAuth2AuthCodeSecurityRequirementInPost ?. [ 0 ] ) . toEqual ( 'api://sample/repairs_write' ) ;
72
+
73
+ // Check if the security schemes are defined correctly for post operation
70
74
const actualOAuthSecuritySchema = actual ?. securitySchemes ?. [ "oAuth2AuthCode" ] as OAuth2SecurityScheme ;
71
75
expect ( actualOAuthSecuritySchema ) . toBeDefined ( ) ;
72
76
expect ( actualOAuthSecuritySchema . flows ) . toBeDefined ( ) ;
@@ -121,6 +125,116 @@ describe("getKiotaTree", () => {
121
125
122
126
} ) ;
123
127
128
+ test ( 'testGetKiotaTree_withMultipleSecurity' , async ( ) => {
129
+ const descriptionUrl = '../../tests/Kiota.Builder.IntegrationTests/ModelWithMultipleSecurity.yaml' ;
130
+
131
+ const actual = await getKiotaTree ( { includeFilters : [ ] , descriptionPath : descriptionUrl , excludeFilters : [ ] , clearCache : false } ) ;
132
+
133
+ expect ( actual ) . toBeDefined ( ) ;
134
+ expect ( existsGreaterThanLevelLogs ( actual ?. logs , LogLevel . warning ) ) . toBeFalsy ( ) ;
135
+ expect ( existsGreaterThanLevelLogs ( actual ?. logs , LogLevel . information ) ) . toBeTruthy ( ) ;
136
+
137
+ // Check if the security requirements are defined correctly for get operation
138
+ // It should have one security requirement: oAuth2AuthCode
139
+ const actualListOperationNode = findOperationByPath ( actual , '\\repairs#GET' ) ;
140
+ expect ( actualListOperationNode ) . toBeDefined ( ) ;
141
+ expect ( actualListOperationNode ?. operationId ) . toEqual ( 'listRepairs' ) ;
142
+ expect ( actualListOperationNode ?. security ) . toBeDefined ( ) ;
143
+ expect ( actualListOperationNode ?. security ?. length ) . toEqual ( 1 ) ;
144
+ const firstSecurityRequirementInGet = actualListOperationNode ?. security ?. [ 0 ] ;
145
+ const oAuth2AuthCodeSecurityRequirementInGet = firstSecurityRequirementInGet ?. [ 'oAuth2AuthCode' ] ;
146
+ expect ( oAuth2AuthCodeSecurityRequirementInGet ) . toBeDefined ( ) ;
147
+ expect ( oAuth2AuthCodeSecurityRequirementInGet ?. length ) . toEqual ( 1 ) ;
148
+ expect ( oAuth2AuthCodeSecurityRequirementInGet ?. [ 0 ] ) . toEqual ( 'api://sample/repairs_read' ) ;
149
+
150
+ // Check if the security requirements are defined correctly for post operation
151
+ // It should have two security requirements: oAuth2AuthCode and httpAuth
152
+ const actualPostOperationNode = findOperationByPath ( actual , '\\repairs#POST' ) ;
153
+ expect ( actualPostOperationNode ) . toBeDefined ( ) ;
154
+ expect ( actualPostOperationNode ?. operationId ) . toEqual ( 'repairs_post' ) ;
155
+ expect ( actualPostOperationNode ?. security ) . toBeDefined ( ) ;
156
+ expect ( actualPostOperationNode ?. security ?. length ) . toEqual ( 2 ) ;
157
+ const firstSecurityRequirementInPost = actualPostOperationNode ?. security ?. [ 0 ] ;
158
+ const oAuth2AuthCodeSecurityRequirementInPost = firstSecurityRequirementInPost ?. [ 'oAuth2AuthCode' ] ;
159
+ expect ( oAuth2AuthCodeSecurityRequirementInPost ) . toBeDefined ( ) ;
160
+ expect ( oAuth2AuthCodeSecurityRequirementInPost ?. length ) . toEqual ( 1 ) ;
161
+ expect ( oAuth2AuthCodeSecurityRequirementInPost ?. [ 0 ] ) . toEqual ( 'api://sample/repairs_write' ) ;
162
+ const secondSecurityRequirementInPost = actualPostOperationNode ?. security ?. [ 1 ] ;
163
+ expect ( secondSecurityRequirementInPost ) . toBeDefined ( ) ;
164
+ const httpAuthSecurityRequirementInPost = secondSecurityRequirementInPost ?. [ 'httpAuth' ] ;
165
+ expect ( httpAuthSecurityRequirementInPost ) . toBeDefined ( ) ;
166
+ expect ( httpAuthSecurityRequirementInPost ?. length ) . toEqual ( 0 ) ;
167
+
168
+ // Check if the security requirements are defined correctly for post operation
169
+ // It should have two security requirements: oAuth2AuthCode and httpAuth
170
+ const actualPutOperationNode = findOperationByPath ( actual , '\\repairs#PUT' ) ;
171
+ expect ( actualPutOperationNode ) . toBeDefined ( ) ;
172
+ expect ( actualPutOperationNode ?. operationId ) . toEqual ( 'repairs_put' ) ;
173
+ expect ( actualPutOperationNode ?. security ) . toBeDefined ( ) ;
174
+ expect ( actualPutOperationNode ?. security ?. length ) . toEqual ( 1 ) ;
175
+ const firstSecurityRequirementInPut = actualPutOperationNode ?. security ?. [ 0 ] ;
176
+ const oAuth2AuthCodeSecurityRequirementInPut = firstSecurityRequirementInPut ?. [ 'oAuth2AuthCode' ] ;
177
+ expect ( oAuth2AuthCodeSecurityRequirementInPut ) . toBeDefined ( ) ;
178
+ expect ( oAuth2AuthCodeSecurityRequirementInPut ?. length ) . toEqual ( 1 ) ;
179
+ expect ( oAuth2AuthCodeSecurityRequirementInPut ?. [ 0 ] ) . toEqual ( 'api://sample/repairs_write' ) ;
180
+ const httpAuthSecurityRequirementInPut = firstSecurityRequirementInPut ?. [ 'httpAuth' ] ;
181
+ expect ( httpAuthSecurityRequirementInPut ) . toBeDefined ( ) ;
182
+ expect ( httpAuthSecurityRequirementInPut ?. length ) . toEqual ( 0 ) ;
183
+
184
+ // Check if the security schemes are defined correctly for post operation
185
+ const actualOAuthSecuritySchema = actual ?. securitySchemes ?. [ "oAuth2AuthCode" ] as OAuth2SecurityScheme ;
186
+ expect ( actualOAuthSecuritySchema ) . toBeDefined ( ) ;
187
+ expect ( actualOAuthSecuritySchema . flows ) . toBeDefined ( ) ;
188
+ const actualAuthorizationCodeFlow = actualOAuthSecuritySchema . flows . authorizationCode ;
189
+ expect ( actualAuthorizationCodeFlow ) . toBeDefined ( ) ;
190
+ expect ( actualAuthorizationCodeFlow ?. authorizationUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' ) ;
191
+ expect ( actualAuthorizationCodeFlow ?. tokenUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/token' ) ;
192
+ expect ( actualAuthorizationCodeFlow ?. refreshUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/refresh' ) ;
193
+ expect ( actualAuthorizationCodeFlow ?. scopes ) . toBeDefined ( ) ;
194
+ expect ( actualAuthorizationCodeFlow ?. scopes [ 'api://sample/repairs_read' ] ) . toEqual ( 'Read repair records' ) ;
195
+ expect ( actualAuthorizationCodeFlow ?. scopes [ 'api://sample/repairs_write' ] ) . toEqual ( 'Write repair records' ) ;
196
+ const actualImplicitFlow = actualOAuthSecuritySchema . flows . implicit ;
197
+ expect ( actualImplicitFlow ) . toBeDefined ( ) ;
198
+ expect ( actualImplicitFlow ?. authorizationUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' ) ;
199
+ expect ( actualImplicitFlow ?. refreshUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/refresh' ) ;
200
+ expect ( actualImplicitFlow ?. scopes ) . toBeDefined ( ) ;
201
+ expect ( actualImplicitFlow ?. scopes [ 'api://sample/repairs_read' ] ) . toEqual ( 'Read repair records' ) ;
202
+ expect ( actualImplicitFlow ?. scopes [ 'api://sample/repairs_write' ] ) . toEqual ( 'Write repair records' ) ;
203
+ const actualClientCredentialsFlow = actualOAuthSecuritySchema . flows . clientCredentials ;
204
+ expect ( actualClientCredentialsFlow ) . toBeDefined ( ) ;
205
+ expect ( actualClientCredentialsFlow ?. tokenUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/token' ) ;
206
+ expect ( actualClientCredentialsFlow ?. refreshUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/refresh' ) ;
207
+ expect ( actualClientCredentialsFlow ?. scopes ) . toBeDefined ( ) ;
208
+ expect ( actualClientCredentialsFlow ?. scopes [ 'api://sample/repairs_read' ] ) . toEqual ( 'Read repair records' ) ;
209
+ expect ( actualClientCredentialsFlow ?. scopes [ 'api://sample/repairs_write' ] ) . toEqual ( 'Write repair records' ) ;
210
+ const actualPasswordFlow = actualOAuthSecuritySchema . flows . password ;
211
+ expect ( actualPasswordFlow ) . toBeDefined ( ) ;
212
+ expect ( actualPasswordFlow ?. tokenUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/token' ) ;
213
+ expect ( actualPasswordFlow ?. refreshUrl ) . toEqual ( 'https://login.microsoftonline.com/common/oauth2/v2.0/refresh' ) ;
214
+ expect ( actualPasswordFlow ?. scopes ) . toBeDefined ( ) ;
215
+ expect ( actualPasswordFlow ?. scopes [ 'api://sample/repairs_read' ] ) . toEqual ( 'Read repair records' ) ;
216
+ expect ( actualPasswordFlow ?. scopes [ 'api://sample/repairs_write' ] ) . toEqual ( 'Write repair records' ) ;
217
+
218
+ const actualHttpSecuritySchema = actual ?. securitySchemes ?. [ "httpAuth" ] as HttpSecurityScheme ;
219
+ expect ( actualHttpSecuritySchema ) . toBeDefined ( ) ;
220
+ expect ( actualHttpSecuritySchema . type ) . toEqual ( 'http' ) ;
221
+ expect ( actualHttpSecuritySchema . scheme ) . toEqual ( 'basic' ) ;
222
+ expect ( actualHttpSecuritySchema . description ) . toEqual ( 'HTTP basic authentication' ) ;
223
+
224
+ const actualApiKeySecuritySchema = actual ?. securitySchemes ?. [ "apiKeyAuth" ] as ApiKeySecurityScheme ;
225
+ expect ( actualApiKeySecuritySchema ) . toBeDefined ( ) ;
226
+ expect ( actualApiKeySecuritySchema . type ) . toEqual ( 'apiKey' ) ;
227
+ expect ( actualApiKeySecuritySchema . name ) . toEqual ( 'X-API-Key' ) ;
228
+ expect ( actualApiKeySecuritySchema . in ) . toEqual ( 'header' ) ;
229
+ expect ( actualApiKeySecuritySchema . description ) . toEqual ( 'API key authentication' ) ;
230
+
231
+ const actualOpenIdConnectSecuritySchema = actual ?. securitySchemes ?. [ "openIdConnectAuth" ] as OpenIdSecurityScheme ;
232
+ expect ( actualOpenIdConnectSecuritySchema ) . toBeDefined ( ) ;
233
+ expect ( actualOpenIdConnectSecuritySchema . type ) . toEqual ( 'openIdConnect' ) ;
234
+ expect ( actualOpenIdConnectSecuritySchema . description ) . toEqual ( 'OpenID Connect authentication' ) ;
235
+ expect ( actualOpenIdConnectSecuritySchema . openIdConnectUrl ) . toEqual ( 'https://login.microsoftonline.com/common/.well-known/openid-configuration' ) ;
236
+ } ) ;
237
+
124
238
test ( 'testGetKiotaTree_withReferenceIdExtension' , async ( ) => {
125
239
const descriptionUrl = '../../tests/Kiota.Builder.IntegrationTests/ModelWithRefIdExtension.yaml' ;
126
240
const actual = await getKiotaTree ( { includeFilters : [ ] , descriptionPath : descriptionUrl , excludeFilters : [ ] , clearCache : false } ) ;
0 commit comments