Skip to content

Commit f209aa5

Browse files
Copilotabraham
andcommitted
Improve request body enum names to use entity-attribute pattern
Co-authored-by: abraham <3341+abraham@users.noreply.github.com>
1 parent 51bb375 commit f209aa5

File tree

3 files changed

+333
-8
lines changed

3 files changed

+333
-8
lines changed

dist/schema.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16186,7 +16186,7 @@
1618616186
"type": "array",
1618716187
"description": "Types to exclude from the results.",
1618816188
"items": {
16189-
"$ref": "#/components/schemas/GetApiV1NotificationsParamTypesEnum"
16189+
"$ref": "#/components/schemas/NotificationTypeParameterEnum"
1619016190
}
1619116191
}
1619216192
},
@@ -16245,7 +16245,7 @@
1624516245
"type": "array",
1624616246
"description": "Types to include in the result.",
1624716247
"items": {
16248-
"$ref": "#/components/schemas/GetApiV1NotificationsParamTypesEnum"
16248+
"$ref": "#/components/schemas/NotificationTypeParameterEnum"
1624916249
}
1625016250
}
1625116251
}
@@ -17970,7 +17970,7 @@
1797017970
"type": "array",
1797117971
"description": "Types to exclude from the results.",
1797217972
"items": {
17973-
"$ref": "#/components/schemas/GetApiV1NotificationsParamTypesEnum"
17973+
"$ref": "#/components/schemas/NotificationTypeParameterEnum"
1797417974
}
1797517975
}
1797617976
},
@@ -17991,7 +17991,7 @@
1799117991
"type": "array",
1799217992
"description": "Restrict which notification types can be grouped. Use this if there are notification types for which your client does not support grouping. If omitted, the server will group notifications of all types it supports (currently, `favourite`, `follow`, `reblog` and `admin.sign_up`). If you do not want any notification grouping, use [GET `/api/v1/notifications`] instead. Notifications that would be grouped if not for this parameter will instead be returned as individual single-notification groups with a unique `group_key` that can be assumed to be of the form `ungrouped-{notification_id}`. Please note that neither the streaming API nor the individual notification APIs are aware of this parameter and will always include a “proper” `group_key` that can be different from what is returned here, meaning that you may have to ignore `group_key` for such notifications that you do not want grouped and use `ungrouped-{notification_id}` instead for consistency.",
1799317993
"items": {
17994-
"$ref": "#/components/schemas/GetApiV1NotificationsParamTypesEnum"
17994+
"$ref": "#/components/schemas/NotificationTypeParameterEnum"
1799517995
}
1799617996
}
1799717997
},
@@ -18050,7 +18050,7 @@
1805018050
"type": "array",
1805118051
"description": "Types to include in the result.",
1805218052
"items": {
18053-
"$ref": "#/components/schemas/GetApiV1NotificationsParamTypesEnum"
18053+
"$ref": "#/components/schemas/NotificationTypeParameterEnum"
1805418054
}
1805518055
}
1805618056
}
@@ -38709,7 +38709,7 @@
3870938709
"account_suspension"
3871038710
]
3871138711
},
38712-
"GetApiV1NotificationsParamTypesEnum": {
38712+
"NotificationTypeParameterEnum": {
3871338713
"type": "string",
3871438714
"enum": [
3871538715
"mention",
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
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]+Api[VR][0-9]+.*Enum$/)
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

Comments
 (0)