1+ import { OpenAPIGenerator } from '../../generators/OpenAPIGenerator' ;
2+ import { EntityClass } from '../../interfaces/EntityClass' ;
3+ import { ApiMethodsFile } from '../../interfaces/ApiMethodsFile' ;
4+
5+ describe ( 'OpenAPIGenerator' , ( ) => {
6+ let generator : OpenAPIGenerator ;
7+
8+ beforeEach ( ( ) => {
9+ generator = new OpenAPIGenerator ( ) ;
10+ } ) ;
11+
12+ describe ( 'generateSchema' , ( ) => {
13+ it ( 'should generate a valid OpenAPI spec with entities and methods' , ( ) => {
14+ const entities : EntityClass [ ] = [
15+ {
16+ name : 'TestEntity' ,
17+ description : 'A test entity' ,
18+ attributes : [
19+ {
20+ name : 'id' ,
21+ type : 'Integer' ,
22+ description : 'The ID of the entity'
23+ } ,
24+ {
25+ name : 'name' ,
26+ type : 'String' ,
27+ description : 'The name of the entity' ,
28+ optional : true
29+ } ,
30+ {
31+ name : 'active' ,
32+ type : 'Boolean' ,
33+ description : 'Whether the entity is active' ,
34+ deprecated : true
35+ }
36+ ]
37+ }
38+ ] ;
39+
40+ const methodFiles : ApiMethodsFile [ ] = [
41+ {
42+ name : 'test API methods' ,
43+ description : 'Test API methods' ,
44+ methods : [
45+ {
46+ name : 'Get test entity' ,
47+ httpMethod : 'GET' ,
48+ endpoint : '/api/v1/test/:id' ,
49+ description : 'Retrieve a test entity' ,
50+ returns : 'TestEntity' ,
51+ oauth : 'User token + read'
52+ } ,
53+ {
54+ name : 'Create test entity' ,
55+ httpMethod : 'POST' ,
56+ endpoint : '/api/v1/test' ,
57+ description : 'Create a new test entity' ,
58+ parameters : [
59+ {
60+ name : 'name' ,
61+ description : 'Name of the entity' ,
62+ required : true
63+ } ,
64+ {
65+ name : 'active' ,
66+ description : 'Whether entity is active'
67+ }
68+ ] ,
69+ oauth : 'User token + write'
70+ }
71+ ]
72+ }
73+ ] ;
74+
75+ const spec = generator . generateSchema ( entities , methodFiles ) ;
76+
77+ // Check basic structure
78+ expect ( spec . openapi ) . toBe ( '3.0.3' ) ;
79+ expect ( spec . info . title ) . toBe ( 'Mastodon API' ) ;
80+ expect ( spec . paths ) . toBeDefined ( ) ;
81+ expect ( spec . components ?. schemas ) . toBeDefined ( ) ;
82+
83+ // Check entity conversion
84+ expect ( spec . components ?. schemas ?. [ 'TestEntity' ] ) . toBeDefined ( ) ;
85+ const entitySchema = spec . components ! . schemas ! [ 'TestEntity' ] ;
86+ expect ( entitySchema . type ) . toBe ( 'object' ) ;
87+ expect ( entitySchema . description ) . toBe ( 'A test entity' ) ;
88+ expect ( entitySchema . properties ?. [ 'id' ] ) . toBeDefined ( ) ;
89+ expect ( entitySchema . properties ?. [ 'id' ] . type ) . toBe ( 'integer' ) ;
90+ expect ( entitySchema . properties ?. [ 'name' ] ) . toBeDefined ( ) ;
91+ expect ( entitySchema . properties ?. [ 'name' ] . type ) . toBe ( 'string' ) ;
92+ expect ( entitySchema . properties ?. [ 'active' ] ) . toBeDefined ( ) ;
93+ expect ( entitySchema . properties ?. [ 'active' ] . deprecated ) . toBe ( true ) ;
94+
95+ // Check required fields (should include non-optional fields)
96+ expect ( entitySchema . required ) . toContain ( 'id' ) ;
97+ expect ( entitySchema . required ) . toContain ( 'active' ) ;
98+ expect ( entitySchema . required ) . not . toContain ( 'name' ) ; // optional
99+
100+ // Check path conversion
101+ expect ( spec . paths [ '/api/v1/test/{id}' ] ) . toBeDefined ( ) ;
102+ expect ( spec . paths [ '/api/v1/test/{id}' ] . get ) . toBeDefined ( ) ;
103+ expect ( spec . paths [ '/api/v1/test' ] ) . toBeDefined ( ) ;
104+ expect ( spec . paths [ '/api/v1/test' ] . post ) . toBeDefined ( ) ;
105+
106+ // Check GET operation
107+ const getOp = spec . paths [ '/api/v1/test/{id}' ] . get ! ;
108+ expect ( getOp . summary ) . toBe ( 'Get test entity' ) ;
109+ expect ( getOp . description ) . toBe ( 'Retrieve a test entity' ) ;
110+ expect ( getOp . tags ) . toEqual ( [ 'test API methods' ] ) ;
111+ expect ( getOp . security ) . toEqual ( [ { OAuth2 : [ ] } ] ) ;
112+ expect ( getOp . parameters ) . toBeDefined ( ) ;
113+ expect ( getOp . parameters ! [ 0 ] . name ) . toBe ( 'id' ) ;
114+ expect ( getOp . parameters ! [ 0 ] . in ) . toBe ( 'path' ) ;
115+ expect ( getOp . parameters ! [ 0 ] . required ) . toBe ( true ) ;
116+
117+ // Check POST operation
118+ const postOp = spec . paths [ '/api/v1/test' ] . post ! ;
119+ expect ( postOp . summary ) . toBe ( 'Create test entity' ) ;
120+ expect ( postOp . requestBody ) . toBeDefined ( ) ;
121+ expect ( postOp . requestBody ?. content [ 'application/x-www-form-urlencoded' ] ) . toBeDefined ( ) ;
122+ } ) ;
123+
124+ it ( 'should handle empty inputs' , ( ) => {
125+ const spec = generator . generateSchema ( [ ] , [ ] ) ;
126+
127+ expect ( spec . openapi ) . toBe ( '3.0.3' ) ;
128+ expect ( spec . paths ) . toEqual ( { } ) ;
129+ expect ( spec . components ?. schemas ) . toEqual ( { } ) ;
130+ } ) ;
131+ } ) ;
132+
133+ describe ( 'toJSON' , ( ) => {
134+ it ( 'should return valid JSON string' , ( ) => {
135+ const entities : EntityClass [ ] = [ ] ;
136+ const methodFiles : ApiMethodsFile [ ] = [ ] ;
137+
138+ generator . generateSchema ( entities , methodFiles ) ;
139+ const json = generator . toJSON ( ) ;
140+
141+ expect ( ( ) => JSON . parse ( json ) ) . not . toThrow ( ) ;
142+ const parsed = JSON . parse ( json ) ;
143+ expect ( parsed . openapi ) . toBe ( '3.0.3' ) ;
144+ } ) ;
145+ } ) ;
146+ } ) ;
0 commit comments