@@ -11,62 +11,63 @@ import { DateTransformerGenerator } from '../../src/service/emit/utility/date-tr
1111import { emptySpec , securitySpec } from '../shared/specs.js' ;
1212
1313describe ( 'Emitter: ProviderGenerator' , ( ) => {
14- // This helper function is the key. It simulates the entire generation process
15- // for the provider file and its dependencies.
16- const runGenerator = ( spec : object , configOverrides : Partial < GeneratorConfig [ 'options' ] > = { } ) => {
14+ const runGenerator = ( spec : object , config : Partial < GeneratorConfig > = { } ) => {
1715 const project = new Project ( { useInMemoryFileSystem : true } ) ;
18- const config : GeneratorConfig = {
16+ const fullConfig : GeneratorConfig = {
1917 input : '' ,
2018 output : '/out' ,
21- clientName : 'Test' ,
22- options : { generateServices : true , dateType : 'string' , enumStyle : 'enum' , ...configOverrides } ,
19+ // `clientName` is deliberately omitted from the base to test fallback logic
20+ options : { generateServices : true , dateType : 'string' , enumStyle : 'enum' } ,
21+ ...config
2322 } ;
24- const parser = new SwaggerParser ( spec as any , config ) ;
2523
26- // Generate dependencies that the ProviderGenerator needs to import from.
27- new TokenGenerator ( project , config . clientName ) . generate ( config . output ) ;
28- new BaseInterceptorGenerator ( project , config . clientName ) . generate ( config . output ) ;
24+ const parser = new SwaggerParser ( spec as any , fullConfig ) ;
2925
30- if ( config . options . dateType === 'Date' ) {
31- new DateTransformerGenerator ( project ) . generate ( config . output ) ;
26+ new TokenGenerator ( project , fullConfig . clientName ) . generate ( fullConfig . output ) ;
27+ new BaseInterceptorGenerator ( project , fullConfig . clientName ) . generate ( fullConfig . output ) ;
28+
29+ if ( fullConfig . options . dateType === 'Date' ) {
30+ new DateTransformerGenerator ( project ) . generate ( fullConfig . output ) ;
3231 }
3332
3433 let tokenNames : string [ ] = [ ] ;
35- // This logic mimics the orchestrator to decide if auth files are needed
36- // and to get the `tokenNames` which is crucial for the ProviderGenerator's constructor.
3734 if ( Object . keys ( parser . getSecuritySchemes ( ) ) . length > 0 ) {
38- new AuthTokensGenerator ( project ) . generate ( config . output ) ;
39- const authInterceptorResult = new AuthInterceptorGenerator ( parser , project ) . generate ( config . output ) ;
35+ new AuthTokensGenerator ( project ) . generate ( fullConfig . output ) ;
36+ const authInterceptorResult = new AuthInterceptorGenerator ( parser , project ) . generate ( fullConfig . output ) ;
4037 tokenNames = authInterceptorResult ?. tokenNames || [ ] ;
4138 }
4239
43- // The actual generator under test.
44- new ProviderGenerator ( parser , project , tokenNames ) . generate ( config . output ) ;
40+ new ProviderGenerator ( parser , project , tokenNames ) . generate ( fullConfig . output ) ;
4541 return project . getSourceFile ( '/out/providers.ts' ) ?. getText ( ) ;
4642 } ;
4743
44+ it ( 'should use "Default" client name when none is provided in config' , ( ) => {
45+ // Run with an empty config, so clientName is undefined
46+ const fileContent = runGenerator ( emptySpec , { } ) ;
47+ expect ( fileContent ) . toContain ( 'export function provideDefaultClient(config: DefaultConfig)' ) ;
48+ expect ( fileContent ) . toContain ( 'export interface DefaultConfig' ) ;
49+ } ) ;
50+
4851 it ( 'should not generate if generateServices is false' , ( ) => {
49- const fileContent = runGenerator ( emptySpec , { generateServices : false } ) ;
52+ const fileContent = runGenerator ( emptySpec , { options : { generateServices : false } as any } ) ;
5053 expect ( fileContent ) . toBeUndefined ( ) ;
5154 } ) ;
5255
5356 it ( 'should generate a basic provider without security or date transform' , ( ) => {
54- const fileContent = runGenerator ( emptySpec ) ;
57+ const fileContent = runGenerator ( emptySpec , { clientName : 'Test' } ) ;
5558 expect ( fileContent ) . toBeDefined ( ) ;
5659 expect ( fileContent ) . toContain ( 'export function provideTestClient(config: TestConfig)' ) ;
5760 expect ( fileContent ) . toContain ( 'export interface TestConfig' ) ;
58- // Check interface props
5961 expect ( fileContent ) . toContain ( 'basePath: string' ) ;
6062 expect ( fileContent ) . toContain ( 'enableDateTransform?: boolean' ) ;
6163 expect ( fileContent ) . not . toContain ( 'apiKey?: string' ) ;
6264 expect ( fileContent ) . not . toContain ( 'bearerToken?:' ) ;
63- // Check provider logic
6465 expect ( fileContent ) . not . toContain ( 'AuthInterceptor' ) ;
6566 expect ( fileContent ) . not . toContain ( 'DateInterceptor' ) ;
6667 } ) ;
6768
6869 it ( 'should add providers for both API key and Bearer token when spec contains both' , ( ) => {
69- const fileContent = runGenerator ( securitySpec ) ;
70+ const fileContent = runGenerator ( securitySpec , { clientName : 'Test' } ) ;
7071 expect ( fileContent ) . toContain ( 'apiKey?: string' ) ;
7172 expect ( fileContent ) . toContain ( 'bearerToken?: string | (() => string)' ) ;
7273 expect ( fileContent ) . toContain ( 'if (config.apiKey)' ) ;
@@ -78,60 +79,48 @@ describe('Emitter: ProviderGenerator', () => {
7879
7980 it ( 'should add providers for ONLY API key when spec contains only that' , ( ) => {
8081 const apiKeySpec = { ...emptySpec , components : { securitySchemes : { ApiKeyAuth : { type : 'apiKey' , in : 'header' , name : 'X-API-KEY' } } } } ;
81- const fileContent = runGenerator ( apiKeySpec ) ;
82- // Check interface
82+ const fileContent = runGenerator ( apiKeySpec , { clientName : 'Test' } ) ;
8383 expect ( fileContent ) . toContain ( 'apiKey?: string' ) ;
8484 expect ( fileContent ) . not . toContain ( 'bearerToken?:' ) ;
85- // Check provider function
8685 expect ( fileContent ) . toContain ( 'if (config.apiKey)' ) ;
8786 expect ( fileContent ) . not . toContain ( 'if (config.bearerToken)' ) ;
88- expect ( fileContent ) . toContain ( 'AuthInterceptor' ) ; // Auth interceptor is still needed
87+ expect ( fileContent ) . toContain ( 'AuthInterceptor' ) ;
8988 } ) ;
9089
9190 it ( 'should add providers for ONLY Bearer token when spec contains only that' , ( ) => {
9291 const bearerSpec = { ...emptySpec , components : { securitySchemes : { BearerAuth : { type : 'http' , scheme : 'bearer' } } } } ;
93- const fileContent = runGenerator ( bearerSpec ) ;
94- // Check interface
92+ const fileContent = runGenerator ( bearerSpec , { clientName : 'Test' } ) ;
9593 expect ( fileContent ) . not . toContain ( 'apiKey?: string' ) ;
9694 expect ( fileContent ) . toContain ( 'bearerToken?: string | (() => string)' ) ;
97- // Check provider function
9895 expect ( fileContent ) . not . toContain ( 'if (config.apiKey)' ) ;
9996 expect ( fileContent ) . toContain ( 'if (config.bearerToken)' ) ;
10097 expect ( fileContent ) . toContain ( 'AuthInterceptor' ) ;
10198 } ) ;
10299
103100 it ( 'should add DateInterceptor if dateType is "Date"' , ( ) => {
104- const fileContent = runGenerator ( emptySpec , { dateType : 'Date' } ) ;
101+ const fileContent = runGenerator ( emptySpec , { clientName : 'Test' , options : { dateType : 'Date' } as any } ) ;
105102 expect ( fileContent ) . toContain ( 'if (config.enableDateTransform !== false)' ) ;
106103 expect ( fileContent ) . toContain ( 'customInterceptors.unshift(new DateInterceptor());' ) ;
107104 } ) ;
108105
109106 it ( 'should generate an empty custom interceptors array if none are provided' , ( ) => {
110- const fileContent = runGenerator ( emptySpec ) ;
107+ const fileContent = runGenerator ( emptySpec , { clientName : 'Test' } ) ;
111108 expect ( fileContent ) . toContain (
112109 'const customInterceptors = config.interceptors?.map(InterceptorClass => new InterceptorClass()) || [];' ,
113110 ) ;
114111 expect ( fileContent ) . toContain ( `provide: HTTP_INTERCEPTORS_TEST, useValue: customInterceptors` ) ;
115112 } ) ;
116113
117- it ( 'should handle config.interceptors being an empty array' , ( ) => {
118- // This covers the `?.map` chain where `interceptors` exists but is empty
119- const fileContent = runGenerator ( emptySpec ) ; // The logic is the same as the above test
120- expect ( fileContent ) . toContain ( 'const customInterceptors = config.interceptors?.map' ) ;
121- } ) ;
122-
123114 it ( 'should not include token providers for unsupported security schemes (e.g., cookie)' , ( ) => {
124115 const spec = {
125116 ...emptySpec ,
126117 components : { securitySchemes : { Cookie : { type : 'apiKey' , in : 'cookie' , name : 'sid' } } } ,
127118 } ;
128- const fileContent = runGenerator ( spec ) ;
119+ const fileContent = runGenerator ( spec , { clientName : 'Test' } ) ;
129120
130- // AuthInterceptorGenerator returns undefined, so ProviderGenerator gets an empty tokenNames array
131121 expect ( fileContent ) . not . toContain (
132122 'providers.push({ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true });' ,
133123 ) ;
134124 expect ( fileContent ) . not . toContain ( 'API_KEY_TOKEN' ) ;
135- expect ( fileContent ) . not . toContain ( 'BEARER_TOKEN_TOKEN' ) ;
136125 } ) ;
137126} ) ;
0 commit comments