1+ import { OpenAPIGenerator } from '../../generators/OpenAPIGenerator' ;
2+ import { ApiMethodsFile } from '../../interfaces/ApiMethodsFile' ;
3+ import { EntityClass } from '../../interfaces/EntityClass' ;
4+
5+ describe ( 'OpenAPIGenerator improved parameter enum naming' , ( ) => {
6+ let generator : OpenAPIGenerator ;
7+
8+ beforeEach ( ( ) => {
9+ generator = new OpenAPIGenerator ( ) ;
10+ } ) ;
11+
12+ it ( 'should use entity-attribute pattern for parameter enums' , ( ) => {
13+ // Create entity with enum attribute
14+ const entities : EntityClass [ ] = [
15+ {
16+ name : 'Notification' ,
17+ description : 'A notification' ,
18+ attributes : [
19+ {
20+ name : 'type' ,
21+ type : 'String (Enumerable)' ,
22+ description : 'The type of notification' ,
23+ enumValues : [
24+ 'mention' ,
25+ 'status' ,
26+ 'reblog' ,
27+ 'follow' ,
28+ 'follow_request' ,
29+ 'favourite' ,
30+ 'poll' ,
31+ 'update' ,
32+ 'admin.sign_up' ,
33+ 'admin.report' ,
34+ 'severed_relationships' ,
35+ 'moderation_warning' ,
36+ 'quote' ,
37+ 'quoted_update'
38+ ] ,
39+ } ,
40+ ] ,
41+ } ,
42+ ] ;
43+
44+ // Create method with parameter that has enum values (different from entity)
45+ const methodFiles : ApiMethodsFile [ ] = [
46+ {
47+ name : 'notifications' ,
48+ description : 'Notification endpoints' ,
49+ methods : [
50+ {
51+ name : 'Get notifications' ,
52+ httpMethod : 'GET' ,
53+ endpoint : '/api/v1/notifications' ,
54+ description : 'Get notifications' ,
55+ parameters : [
56+ {
57+ name : 'types' ,
58+ description : 'Types to include in the result' ,
59+ in : 'query' ,
60+ enumValues : [
61+ 'mention' ,
62+ 'status' ,
63+ 'reblog' ,
64+ 'follow' ,
65+ 'follow_request' ,
66+ 'favourite' ,
67+ 'poll' ,
68+ 'update' ,
69+ 'admin.sign_up' ,
70+ 'admin.report'
71+ ] ,
72+ schema : {
73+ type : 'array' ,
74+ items : { type : 'string' } ,
75+ } ,
76+ } ,
77+ {
78+ name : 'exclude_types' ,
79+ description : 'Types to exclude from the results' ,
80+ in : 'query' ,
81+ enumValues : [
82+ 'mention' ,
83+ 'status' ,
84+ 'reblog' ,
85+ 'follow' ,
86+ 'follow_request' ,
87+ 'favourite' ,
88+ 'poll' ,
89+ 'update' ,
90+ 'admin.sign_up' ,
91+ 'admin.report'
92+ ] ,
93+ schema : {
94+ type : 'array' ,
95+ items : { type : 'string' } ,
96+ } ,
97+ } ,
98+ ] ,
99+ } ,
100+ ] ,
101+ } ,
102+ ] ;
103+
104+ const spec = generator . generateSchema ( entities , methodFiles ) ;
105+
106+ // Should have entity enum with all values
107+ expect ( spec . components ?. schemas ?. NotificationTypeEnum ) . toBeDefined ( ) ;
108+ const entityEnum = spec . components ! . schemas ! . NotificationTypeEnum as any ;
109+ expect ( entityEnum . enum . length ) . toBe ( 14 ) ; // Entity has all 14 types
110+
111+ // Should have parameter enum with subset of values and better naming
112+ expect ( spec . components ?. schemas ?. NotificationTypeParameterEnum ) . toBeDefined ( ) ;
113+ const paramEnum = spec . components ! . schemas ! . NotificationTypeParameterEnum as any ;
114+ expect ( paramEnum . enum . length ) . toBe ( 10 ) ; // Parameter has only 10 types
115+ expect ( paramEnum . enum ) . toEqual ( [
116+ 'mention' ,
117+ 'status' ,
118+ 'reblog' ,
119+ 'follow' ,
120+ 'follow_request' ,
121+ 'favourite' ,
122+ 'poll' ,
123+ 'update' ,
124+ 'admin.sign_up' ,
125+ 'admin.report'
126+ ] ) ;
127+
128+ // Check that the old problematic naming is not used
129+ expect ( spec . components ?. schemas ?. GetApiV1NotificationsParamTypesEnum ) . toBeUndefined ( ) ;
130+
131+ // Check that parameters reference the new parameter enum
132+ const operation = spec . paths ?. [ '/api/v1/notifications' ] ?. get ;
133+ const typesParam = operation ?. parameters ?. find ( ( p : any ) => p . name === 'types' ) ;
134+ const excludeTypesParam = operation ?. parameters ?. find ( ( p : any ) => p . name === 'exclude_types' ) ;
135+
136+ expect ( typesParam ?. schema ?. items ?. $ref ) . toBe ( '#/components/schemas/NotificationTypeParameterEnum' ) ;
137+ expect ( excludeTypesParam ?. schema ?. items ?. $ref ) . toBe ( '#/components/schemas/NotificationTypeParameterEnum' ) ;
138+
139+ // Check that entity still uses entity enum
140+ const notificationSchema = spec . components ?. schemas ?. Notification as any ;
141+ expect ( notificationSchema ?. properties ?. type ?. $ref ) . toBe ( '#/components/schemas/NotificationTypeEnum' ) ;
142+ } ) ;
143+
144+ it ( 'should improve naming compared to old problematic patterns' , ( ) => {
145+ const methodFiles : ApiMethodsFile [ ] = [
146+ {
147+ name : 'notifications' ,
148+ description : 'Notification endpoints' ,
149+ methods : [
150+ {
151+ name : 'Get notifications v1' ,
152+ httpMethod : 'GET' ,
153+ endpoint : '/api/v1/notifications' ,
154+ description : 'Get notifications v1' ,
155+ parameters : [
156+ {
157+ name : 'types' ,
158+ description : 'Types to include' ,
159+ in : 'query' ,
160+ enumValues : [ 'mention' , 'reblog' , 'favourite' ] ,
161+ schema : {
162+ type : 'array' ,
163+ items : { type : 'string' } ,
164+ } ,
165+ } ,
166+ ] ,
167+ } ,
168+ {
169+ name : 'Get notifications v2' ,
170+ httpMethod : 'GET' ,
171+ endpoint : '/api/v2/notifications' ,
172+ description : 'Get notifications v2' ,
173+ parameters : [
174+ {
175+ name : 'grouped_types' ,
176+ description : 'Types that can be grouped' ,
177+ in : 'query' ,
178+ enumValues : [ 'mention' , 'reblog' , 'favourite' ] ,
179+ schema : {
180+ type : 'array' ,
181+ items : { type : 'string' } ,
182+ } ,
183+ } ,
184+ ] ,
185+ } ,
186+ ] ,
187+ } ,
188+ ] ;
189+
190+ const spec = generator . generateSchema ( [ ] , methodFiles ) ;
191+
192+ // Should not have the old problematic naming pattern
193+ const enumNames = Object . keys ( spec . components ?. schemas || { } ) ;
194+
195+ const hasProblematicNaming = enumNames . some ( name =>
196+ name . includes ( 'GetApiV1NotificationsParamTypesEnum' ) ||
197+ name . includes ( 'GetApiV2NotificationsParamGroupedTypesEnum' ) ||
198+ name . match ( / ^ [ A - Z ] [ a - z ] + A p i [ V R ] [ 0 - 9 ] + .* E n u m $ / )
199+ ) ;
200+
201+ expect ( hasProblematicNaming ) . toBe ( false ) ;
202+
203+ // Should have better naming that follows entity-attribute pattern
204+ const hasNotificationTypeParameterEnum = enumNames . includes ( 'NotificationTypeParameterEnum' ) ;
205+ expect ( hasNotificationTypeParameterEnum ) . toBe ( true ) ;
206+ } ) ;
207+ } ) ;
0 commit comments