utOpenAPIWriter.pp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. unit utOpenAPIWriter;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, testregistry, fpjson, fpjson.schema.schema, fpopenapi.objects, fpopenapi.writer;
  6. type
  7. { TTestOpenApiWriterBase }
  8. TTestOpenApiWriterBase = class(TTestCase)
  9. private
  10. FDocument: TJSONObject;
  11. FOpenAPI: TOpenAPI;
  12. procedure AddSource(Const aFmt : string; aArgs : Array of const);
  13. Procedure AddSource(Const aLine : string);
  14. procedure AddDecl(Const aFmt : string; aArgs : Array of const);
  15. protected
  16. procedure SetUp; override;
  17. procedure TearDown; override;
  18. Procedure WriteOpenAPI;
  19. procedure CheckJSON(const Msg: String; aJSON: TJSONStringType);
  20. procedure TestWrite(const Msg: String; aJSON: TJSONStringType);
  21. Public
  22. Property OpenApi : TOpenAPI Read FOpenAPI;
  23. Property Document : TJSONObject Read FDocument;
  24. published
  25. procedure TestHookUp;
  26. end;
  27. { TTestOpenApiWriter }
  28. TTestOpenApiWriterOpenAPI = class(TTestOpenApiWriterBase)
  29. Published
  30. procedure TestEmpty;
  31. Procedure TestOpenAPI;
  32. Procedure TestJSONSchemaDialect;
  33. end;
  34. TTestOpenApiWriterInfo = class(TTestOpenApiWriterBase)
  35. Published
  36. procedure TestVersion;
  37. procedure TestTitle;
  38. procedure TestSummary;
  39. procedure TestDescription;
  40. procedure TestTermsOfService;
  41. procedure TestContactEmail;
  42. procedure TestContactName;
  43. procedure TestContactURL;
  44. procedure TestLicenseUrl;
  45. procedure TestLicenseIdentifier;
  46. procedure TestLicenseName;
  47. end;
  48. TTestOpenApiWriterTags = class(TTestOpenApiWriterBase)
  49. Published
  50. Procedure TestName;
  51. Procedure TestDescription;
  52. Procedure TestExternalDocs;
  53. Procedure Test2Tags;
  54. end;
  55. TTestOpenApiWriterExternalDocs = class(TTestOpenApiWriterBase)
  56. Published
  57. procedure TestUrl;
  58. procedure TestDescription;
  59. end;
  60. { TTestOpenApiWriterServers }
  61. TTestOpenApiWriterServers = class(TTestOpenApiWriterBase)
  62. Published
  63. Procedure TestUrl;
  64. Procedure TestDescription;
  65. procedure TestVariablesDefault;
  66. procedure TestVariablesDescription;
  67. procedure TestVariablesEnum;
  68. Procedure Test2Url;
  69. end;
  70. { TTestOpenApiWriterPaths }
  71. TTestOpenApiWriterPathBase = class(TTestOpenApiWriterBase)
  72. Public
  73. Function AddPath(aPath : String) : TPathItem;
  74. end;
  75. TTestOpenApiWriterPaths = class(TTestOpenApiWriterPathBase)
  76. Published
  77. Procedure TestEmpty;
  78. Procedure TestRef;
  79. Procedure TestSummary;
  80. Procedure TestDescription;
  81. Procedure TestGetEmpty;
  82. Procedure TestGetSummary;
  83. Procedure TestGetDescription;
  84. Procedure TestGetOperationId;
  85. Procedure TestGetDeprecated;
  86. Procedure TestGetExternalDocsEmpty;
  87. Procedure TestGetExternalDocsURL;
  88. Procedure TestGetServers;
  89. end;
  90. { TTestOpenApiWriterPathRequestBody }
  91. TTestOpenApiWriterPathRequestBody = class(TTestOpenApiWriterPathBase)
  92. Public
  93. Function AddBody(aPath : String) : TRequestBody;
  94. Published
  95. procedure TestEmpty;
  96. procedure TestDescription;
  97. procedure TestRequired;
  98. procedure TestContent;
  99. procedure TestContentSchema;
  100. procedure TestContentExample;
  101. procedure TestContentExamples;
  102. procedure TestContentEncodingContentType;
  103. procedure TestContentEncodingExplode;
  104. procedure TestContentEncodingStyle;
  105. procedure TestContentEncodingAllowReserved;
  106. procedure TestContentEncodingHeaders;
  107. end;
  108. { TTestOpenApiWriterPathParameters }
  109. TTestOpenApiWriterPathParameters = class(TTestOpenApiWriterPathBase)
  110. Public
  111. Function AddParam(aPath : String) : TParameter;
  112. Published
  113. Procedure TestGetParametersEmpty;
  114. end;
  115. { TTestOpenApiWriterPathResponses }
  116. TTestOpenApiWriterPathResponses = class(TTestOpenApiWriterPathBase)
  117. Public
  118. Function AddResponse(aPath : String) : TResponse;
  119. Published
  120. procedure TestEmpty;
  121. procedure TestHeaders;
  122. procedure TestDescription;
  123. procedure TestContentEmpty;
  124. procedure TestContentSchema;
  125. procedure TestContentExample;
  126. procedure TestContentExamples;
  127. procedure TestContentEncodingEmpty;
  128. procedure TestContentEncodingContentType;
  129. end;
  130. { TTestOpenApiWriterPathResponsesLinks }
  131. TTestOpenApiWriterPathResponsesLinks = class(TTestOpenApiWriterPathBase)
  132. Public
  133. Function AddLink(aPath : String) : TLink;
  134. Published
  135. procedure TestEmpty;
  136. Procedure TestOperatonRef;
  137. Procedure TestOperatonId;
  138. Procedure TestParameters;
  139. Procedure TestRequestBody;
  140. Procedure TestDescription;
  141. Procedure TestServer;
  142. end;
  143. { TTestOpenApiWriterPathSecurity }
  144. TTestOpenApiWriterPathSecurity = class(TTestOpenApiWriterPathBase)
  145. Published
  146. Procedure TestEmpty;
  147. Procedure TestAPIKey;
  148. end;
  149. { TTestOpenApiWriterWebHooks }
  150. TTestOpenApiWriterWebHooks = class(TTestOpenApiWriterBase)
  151. Public
  152. function AddWebHook(const aname : string) : TPathItem;
  153. Published
  154. procedure TestEmpty;
  155. procedure TestSummary;
  156. // At the moment, no more tests needed: the items are identical to path items.
  157. end;
  158. { TTestOpenApiWriterComponents }
  159. TTestOpenApiWriterComponents = class(TTestOpenApiWriterBase)
  160. Public
  161. function AddComponentSchema(const aname: string): TJSONSchema;
  162. Published
  163. procedure TestSchemaEmpty;
  164. procedure TestSchemaContentEncoding;
  165. end;
  166. { TTestOpenApiWriterOAuth2Scopes }
  167. TTestOpenApiWriterOAuth2Scopes = class(TTestOpenApiWriterBase)
  168. Published
  169. procedure TestOAuth2ScopesAsObject;
  170. procedure TestOAuth2ScopesEmpty;
  171. end;
  172. { TTestOpenApiWriterSecurity }
  173. TTestOpenApiWriterSecurity = class(TTestOpenApiWriterBase)
  174. Published
  175. procedure TestOne;
  176. end;
  177. (*
  178. property Components: TComponents Read Get_Components write Set_Components;
  179. property Security: TSecurityRequirementList Read Get_Security write Set_Security;
  180. *)
  181. implementation
  182. uses jsoncomparer;
  183. var
  184. _Sources : TStrings;
  185. _Decl : TStrings;
  186. _LastClass : String;
  187. function ChangeRead(S : String) : String;
  188. begin
  189. Result:=StringReplace(S,'Write','Reade',[rfReplaceAll,rfIgnoreCase]);
  190. end;
  191. procedure StartSources; forward;
  192. Procedure AddMethod(aClassName,aTestName : string; const aJSON : String);
  193. var
  194. lClass,lTest : String;
  195. J,S : TJSONObject;
  196. D : TJSONData;
  197. P,N : String;
  198. begin
  199. lClass:=ChangeRead(aClassName);
  200. lTest:=ChangeRead(aTestName);
  201. if lClass<>_LastClass then
  202. begin
  203. if _LastClass<>'' then
  204. _Decl.Add(' end;');
  205. _Decl.Add('');
  206. _Decl.Add(' %s = Class(TOpenAPITestRead)',[lClass]);
  207. _LastClass:=lClass;
  208. end;
  209. _Decl.Add(' Procedure %s;',[lTest]);
  210. _Sources.Add('');
  211. _Sources.Add('procedure %s.%s;',[lClass,lTest]);
  212. _Sources.Add('');
  213. _Sources.Add('begin');
  214. _Sources.Add(' TestRead(''%s'');',[aJSON]);
  215. J:=GetJSON(aJSON) as TJSONObject;
  216. P:='OpenAPI';
  217. S:=Nil;
  218. try
  219. if J.Count>0 then
  220. begin
  221. D:=J.Items[0];
  222. if D is TJSONObject then
  223. S:=TJSONObject(D);
  224. N:=J.Names[0];
  225. While S is TJSONObject do
  226. begin
  227. P:=P+'.'+N;
  228. _Sources.Add(' AssertNotNull(''%s'',%s);',[P,P]);
  229. if S.Count=0 then
  230. begin
  231. D:=Nil;
  232. S:=Nil;
  233. Continue;
  234. end;
  235. D:=S.Items[0];
  236. N:=S.Names[0];
  237. if (D is TJSONArray) and (TJSONArray(D).Count>0) then
  238. begin
  239. D:=TJSONArray(D)[0];
  240. N:=N+'[0]';
  241. end;
  242. if D is TJSONObject then
  243. S:=TJSONObject(D)
  244. else
  245. S:=Nil;
  246. end;
  247. P:=P+'.'+N;
  248. if assigned(D) then
  249. Case D.JSONType of
  250. jtString : _Sources.Add(' AssertEquals(''%s'',''%s'',%s);',[P,D.AsString,P]);
  251. jtBoolean : _Sources.Add(' AssertEquals(''%s'',%s,%s);',[P,D.AsString,P]);
  252. jtNumber : _Sources.Add(' AssertEquals(''%s'',%s,%s);',[P,D.AsString,P]);
  253. end;
  254. end;
  255. finally
  256. J.Free;
  257. end;
  258. _Sources.Add('end;');
  259. _Sources.Add('');
  260. end;
  261. procedure TTestOpenApiWriterBase.AddSource(const aFmt: string; aArgs: array of const);
  262. begin
  263. AddSource(Format(aFmt,aArgs));
  264. end;
  265. procedure TTestOpenApiWriterBase.AddSource(const aLine: string);
  266. begin
  267. _Sources.Add(aLine);
  268. end;
  269. procedure TTestOpenApiWriterBase.AddDecl(const aFmt: string; aArgs: array of const);
  270. begin
  271. _Decl.Add(aFmt,aArgs);
  272. end;
  273. procedure TTestOpenApiWriterBase.SetUp;
  274. begin
  275. FOpenAPI:=TOpenAPI.Create;
  276. if _Decl=Nil then
  277. StartSources;
  278. end;
  279. procedure TTestOpenApiWriterBase.TearDown;
  280. begin
  281. FreeAndNil(FOpenAPI);
  282. FreeAndNil(FDocument);
  283. end;
  284. procedure TTestOpenApiWriterBase.WriteOpenAPI;
  285. var
  286. W : TOpenAPIWriter;
  287. begin
  288. W:=TOpenAPIWriter.Create(Nil);
  289. try
  290. FDocument:=W.WriteToJSON(OpenAPI);
  291. finally
  292. W.Free;
  293. end;
  294. end;
  295. procedure TTestOpenApiWriterBase.CheckJSON(const Msg: String; aJSON: TJSONStringType);
  296. var
  297. Data : TJSONData;
  298. Obj : TJSONObject absolute data;
  299. Errors : TStrings;
  300. begin
  301. Errors:=Nil;
  302. Data:=GetJSON(aJSON,true) as TJSONObject;
  303. try
  304. AssertEquals('Json object',TJSONObject,Data.ClassType);
  305. Errors:=TStringList.Create;
  306. // Writeln('Comparing ',Obj.AsJSON,' === ',Document.AsJSON);
  307. TJSONComparer.Compare(Obj,Document,Errors);
  308. if (Errors.Count<>0) then
  309. Fail(Msg+':'#10+Errors.Text);
  310. finally
  311. Errors.Free;
  312. Data.Free;
  313. end;
  314. end;
  315. procedure TTestOpenApiWriterBase.TestWrite(const Msg: String; aJSON: TJSONStringType);
  316. begin
  317. AddMethod(ClassName,TestName,aJSON);
  318. WriteOpenAPI;
  319. CheckJSON(msg,aJSON);
  320. end;
  321. procedure TTestOpenApiWriterBase.TestHookUp;
  322. begin
  323. AssertNotNull('have openapi',OpenAPI);
  324. AssertNull('have no document',Document);
  325. end;
  326. procedure TTestopenApiWriterOpenApi.TestEmpty;
  327. begin
  328. WriteOpenApi;
  329. CheckJSON('Empty','{}');
  330. end;
  331. procedure TTestopenApiWriterOpenAPI.TestOpenAPI;
  332. begin
  333. OpenAPI.OpenAPI:='123';
  334. TestWrite('openapi version','{ "openapi" : "123" }');
  335. end;
  336. procedure TTestopenApiWriterOpenAPI.TestJSONSchemaDialect;
  337. begin
  338. OpenAPI.JSONSchemaDialect:='123';
  339. TestWrite('json schema dialect','{ "jsonSchemaDialect" : "123" }');
  340. end;
  341. procedure TTestopenApiWriterInfo.TestVersion;
  342. begin
  343. OpenAPI.Info.Version:='123';
  344. TestWrite('Version','{ "info" : { "version" : "123" } }');
  345. end;
  346. procedure TTestopenApiWriterInfo.TestTitle;
  347. begin
  348. OpenAPI.Info.title:='123';
  349. TestWrite('Title','{ "info" : { "title" : "123" } }');
  350. end;
  351. procedure TTestopenApiWriterInfo.TestSummary;
  352. begin
  353. OpenAPI.Info.summary:='123';
  354. TestWrite('Summary','{ "info" : { "summary" : "123" } }');
  355. end;
  356. procedure TTestopenApiWriterInfo.TestDescription;
  357. begin
  358. OpenAPI.Info.Description:='123';
  359. TestWrite('Description','{ "info" : { "description" : "123" } }');
  360. end;
  361. procedure TTestopenApiWriterInfo.TestTermsOfService;
  362. begin
  363. OpenAPI.Info.TermsOfService:='123';
  364. TestWrite('TermsOfService','{ "info" : { "termsOfService" : "123" } }');
  365. end;
  366. procedure TTestopenApiWriterInfo.TestContactEmail;
  367. begin
  368. OpenAPI.Info.Contact.Email:='123';
  369. TestWrite('Contact mail','{ "info" : { "contact" : { "email" : "123" } } }');
  370. end;
  371. procedure TTestopenApiWriterInfo.TestContactName;
  372. begin
  373. OpenAPI.Info.Contact.Name:='123';
  374. TestWrite('Contact name','{ "info" : { "contact" : { "name" : "123" } } }');
  375. end;
  376. procedure TTestopenApiWriterInfo.TestContactURL;
  377. begin
  378. OpenAPI.Info.Contact.URL:='123';
  379. TestWrite('Contact url','{ "info" : { "contact" : { "url" : "123" } } }');
  380. end;
  381. procedure TTestopenApiWriterInfo.TestLicenseUrl;
  382. begin
  383. OpenAPI.Info.License.Url:='123';
  384. TestWrite('license url','{ "info" : { "license" : { "url" : "123" } } }');
  385. end;
  386. procedure TTestopenApiWriterInfo.TestLicenseName;
  387. begin
  388. OpenAPI.Info.License.Name:='123';
  389. TestWrite('license name','{ "info" : { "license" : { "name" : "123" } } }');
  390. end;
  391. procedure TTestopenApiWriterInfo.TestLicenseIdentifier;
  392. begin
  393. OpenAPI.Info.License.Identifier:='123';
  394. TestWrite('license name','{ "info" : { "license" : { "identifier" : "123" } } }');
  395. end;
  396. procedure TTestopenApiWriterTags.TestName;
  397. var
  398. T : TTag;
  399. begin
  400. T:=TTag.Create(OpenAPI,'tags[0]');
  401. T.Name:='123';
  402. OpenAPI.Tags.Add(T);
  403. TestWrite('name','{ "tags" : [ { "name" : "123" } ] }');
  404. end;
  405. procedure TTestopenApiWriterTags.TestDescription;
  406. var
  407. T : TTag;
  408. begin
  409. T:=TTag.Create(OpenAPI,'tags[1]');
  410. T.Description:='123';
  411. OpenAPI.Tags.Add(T);
  412. TestWrite('description','{ "tags" : [ { "description" : "123" } ] }');
  413. end;
  414. procedure TTestopenApiWriterTags.TestExternalDocs;
  415. var
  416. T : TTag;
  417. begin
  418. T:=TTag.Create(OpenAPI,'tags[1]');
  419. T.ExternalDocs.Url:='123';
  420. OpenAPI.Tags.Add(T);
  421. TestWrite('externaldocs','{ "tags" : [ { "externalDocs" : { "url" :"123" } } ] }');
  422. end;
  423. procedure TTestopenApiWriterTags.Test2Tags;
  424. var
  425. T : TTag;
  426. begin
  427. T:=TTag.Create(OpenAPI,'tags[0]');
  428. T.Name:='123';
  429. OpenAPI.Tags.Add(T);
  430. T:=TTag.Create(OpenAPI,'tags[1]');
  431. T.Name:='456';
  432. OpenAPI.Tags.Add(T);
  433. TestWrite('multi','{ "tags" : [ { "name" : "123" }, { "name" : "456" } ] }');
  434. end;
  435. procedure TTestopenApiWriterExternalDocs.TestUrl;
  436. begin
  437. OpenAPI.ExternalDocs.Url:='123';
  438. TestWrite('Url','{ "externalDocs" : { "url" :"123" } }');
  439. end;
  440. procedure TTestopenApiWriterExternalDocs.TestDescription;
  441. begin
  442. OpenAPI.ExternalDocs.Description:='123';
  443. TestWrite('description','{ "externalDocs" : { "description" :"123" } }');
  444. end;
  445. { TTestOpenApiWriterServers }
  446. procedure TTestOpenApiWriterServers.TestUrl;
  447. var
  448. Server : TServer;
  449. begin
  450. Server:=TServer.Create(OpenAPI,'servers[0]');
  451. Server.Url:='123';
  452. OpenAPI.Servers.Add(Server);
  453. TestWrite('url','{ "servers" : [ { "url" :"123" } ] }');
  454. end;
  455. procedure TTestOpenApiWriterServers.TestDescription;
  456. var
  457. Server : TServer;
  458. begin
  459. Server:=TServer.Create(OpenAPI,'servers[0]');
  460. Server.description:='123';
  461. OpenAPI.Servers.Add(Server);
  462. TestWrite('url','{ "servers" : [ { "description" :"123" } ] }');
  463. end;
  464. procedure TTestOpenApiWriterServers.TestVariablesDefault;
  465. var
  466. Server : TServer;
  467. ServerVar : TServerVariable;
  468. begin
  469. Server:=TServer.Create(OpenAPI,'servers[0]');
  470. ServerVar:=Server.Variables.AddItem('user');
  471. ServerVar.Default:='123';
  472. OpenAPI.Servers.Add(Server);
  473. TestWrite('var.default','{ "servers" : [ { "variables" : { "user": { "default": "123" } } } ] }');
  474. end;
  475. procedure TTestOpenApiWriterServers.TestVariablesDescription;
  476. var
  477. Server : TServer;
  478. ServerVar : TServerVariable;
  479. begin
  480. Server:=TServer.Create(OpenAPI,'servers[0]');
  481. ServerVar:=Server.Variables.AddItem('user');
  482. ServerVar.Description:='123';
  483. OpenAPI.Servers.Add(Server);
  484. TestWrite('var.description','{ "servers" : [ { "variables" : { "user": { "description": "123" } } } ] }');
  485. end;
  486. procedure TTestOpenApiWriterServers.TestVariablesEnum;
  487. var
  488. Server : TServer;
  489. ServerVar : TServerVariable;
  490. begin
  491. Server:=TServer.Create(OpenAPI,'servers[0]');
  492. ServerVar:=Server.Variables.AddItem('user');
  493. ServerVar.Enum.Add('123');
  494. ServerVar.Enum.Add('456');
  495. OpenAPI.Servers.Add(Server);
  496. TestWrite('var.enum','{ "servers" : [ { "variables" : { "user": { "enum": [ "123", "456" ] } } } ] }');
  497. end;
  498. procedure TTestOpenApiWriterServers.Test2Url;
  499. var
  500. Server : TServer;
  501. begin
  502. Server:=TServer.Create(OpenAPI,'servers[0]');
  503. Server.Url:='123';
  504. OpenAPI.Servers.Add(Server);
  505. Server:=TServer.Create(OpenAPI,'servers[0]');
  506. Server.Url:='456';
  507. OpenAPI.Servers.Add(Server);
  508. TestWrite('url','{ "servers" : [ { "url" :"123" }, { "url" :"456" } ] }');
  509. end;
  510. { TTestOpenApiWriterPaths }
  511. function TTestOpenApiWriterPathBase.AddPath(aPath: String): TPathItem;
  512. begin
  513. Result:=OpenAPI.Paths.AddItem(aPath);
  514. end;
  515. procedure TTestOpenApiWriterPaths.TestEmpty;
  516. var
  517. P : TPathItem;
  518. begin
  519. P:=AddPath('api');
  520. AssertNotNull('Have path',P);
  521. TestWrite('Path','{ "paths" : { "api" : {} } }');
  522. end;
  523. procedure TTestOpenApiWriterPaths.TestRef;
  524. var
  525. P : TPathItem;
  526. begin
  527. P:=AddPath('api');
  528. P.Ref:='abc';
  529. TestWrite('Path ref','{ "paths" : { "api" : { "$ref": "abc"} } }');
  530. end;
  531. procedure TTestOpenApiWriterPaths.TestSummary;
  532. var
  533. P : TPathItem;
  534. begin
  535. P:=AddPath('api');
  536. P.Summary:='abc';
  537. TestWrite('Path summary','{ "paths" : { "api" : { "summary": "abc"} } }');
  538. end;
  539. procedure TTestOpenApiWriterPaths.TestDescription;
  540. var
  541. P : TPathItem;
  542. begin
  543. P:=AddPath('api');
  544. P.description:='abc';
  545. TestWrite('Path description','{ "paths" : { "api" : { "description": "abc"} } }');
  546. end;
  547. procedure TTestOpenApiWriterPaths.TestGetServers;
  548. var
  549. P : TPathItem;
  550. S : TServer;
  551. begin
  552. P:=AddPath('api');
  553. S:=TServer.Create(P,'servers[0]');
  554. P.Servers.Add(S);
  555. TestWrite('Path description','{ "paths" : { "api" : { "servers": [ {} ] } } }');
  556. end;
  557. procedure TTestOpenApiWriterPaths.TestGetEmpty;
  558. var
  559. P : TPathItem;
  560. begin
  561. P:=AddPath('api');
  562. AssertEquals('Empty','',P.Get.Summary);
  563. TestWrite('Path get','{ "paths" : { "api" : { "get": { } } } }');
  564. end;
  565. procedure TTestOpenApiWriterPaths.TestGetSummary;
  566. var
  567. P : TPathItem;
  568. begin
  569. P:=AddPath('api');
  570. P.Get.Summary:='123';
  571. TestWrite('Path get summary','{ "paths" : { "api" : { "get": { "summary" : "123" } } } }');
  572. end;
  573. procedure TTestOpenApiWriterPaths.TestGetDescription;
  574. var
  575. P : TPathItem;
  576. begin
  577. P:=AddPath('api');
  578. P.Get.Description:='123';
  579. TestWrite('Path get description','{ "paths" : { "api" : { "get": { "description" : "123" } } } }');
  580. end;
  581. procedure TTestOpenApiWriterPaths.TestGetOperationId;
  582. var
  583. P : TPathItem;
  584. begin
  585. P:=AddPath('api');
  586. P.Get.operationId:='123';
  587. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "operationId" : "123" } } } }');
  588. end;
  589. procedure TTestOpenApiWriterPaths.TestGetDeprecated;
  590. var
  591. P : TPathItem;
  592. begin
  593. P:=AddPath('api');
  594. P.Get.Deprecated:=True;
  595. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "deprecated" : true } } } }');
  596. end;
  597. procedure TTestOpenApiWriterPaths.TestGetExternalDocsEmpty;
  598. var
  599. P : TPathItem;
  600. begin
  601. P:=AddPath('api');
  602. AssertNotNull('Get creates',P.Get.ExternalDocs);
  603. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "externalDocs" : { } } } } }');
  604. end;
  605. procedure TTestOpenApiWriterPaths.TestGetExternalDocsURL;
  606. var
  607. P : TPathItem;
  608. begin
  609. P:=AddPath('api');
  610. P.Get.ExternalDocs.Url:='123';
  611. TestWrite('Path get externaldocs','{ "paths" : { "api" : { "get": { "externalDocs" : { "url" : "123" } } } } }');
  612. end;
  613. { TTestOpenApiWriterPathRequestBody }
  614. function TTestOpenApiWriterPathRequestBody.AddBody(aPath: String): TRequestBody;
  615. begin
  616. Result:=AddPath(aPath).Get.RequestBody;
  617. end;
  618. procedure TTestOpenApiWriterPathRequestBody.TestEmpty;
  619. var
  620. R : TRequestBody;
  621. begin
  622. R:=AddBody('api');
  623. AssertNotNull('Get creates',R);
  624. TestWrite('Path get requestbody','{ "paths" : { "api" : { "get": { "requestBody" : { } } } } }');
  625. end;
  626. procedure TTestOpenApiWriterPathRequestBody.TestDescription;
  627. var
  628. R : TRequestBody;
  629. begin
  630. R:=AddBody('api');
  631. R.Description:='123';
  632. TestWrite('Path get requestbody','{ "paths" : { "api" : { "get": { "requestBody" : { "description" : "123" } } } } }');
  633. end;
  634. procedure TTestOpenApiWriterPathRequestBody.TestRequired;
  635. var
  636. R : TRequestBody;
  637. begin
  638. R:=AddBody('api');
  639. R.Required:=True;
  640. TestWrite('Path get requestbody','{ "paths" : { "api" : { "get": { "requestBody" : { "required" : true} } } } }');
  641. end;
  642. procedure TTestOpenApiWriterPathRequestBody.TestContent;
  643. var
  644. R : TRequestBody;
  645. begin
  646. R:=AddBody('api');
  647. R.Content.AddItem('123');
  648. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { } } } } } } }');
  649. end;
  650. procedure TTestOpenApiWriterPathRequestBody.TestContentSchema;
  651. var
  652. R : TRequestBody;
  653. begin
  654. R:=AddBody('api');
  655. R.Content.AddItem('123').Schema:=TJSONSchema.Create();
  656. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "schema" : true } } } } } } }');
  657. end;
  658. procedure TTestOpenApiWriterPathRequestBody.TestContentExample;
  659. var
  660. R : TRequestBody;
  661. begin
  662. R:=AddBody('api');
  663. R.Content.AddItem('123').example:=TJSONObject.Create;
  664. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "example" : { } } } } } } } }');
  665. end;
  666. procedure TTestOpenApiWriterPathRequestBody.TestContentExamples;
  667. var
  668. R : TRequestBody;
  669. begin
  670. R:=AddBody('api');
  671. R.Content.AddItem('123').examples.AddItem('abc').Summary:='x';
  672. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "examples" : { "abc" : { "summary": "x"} } } } } } } } }');
  673. end;
  674. procedure TTestOpenApiWriterPathRequestBody.TestContentEncodingContentType;
  675. var
  676. R : TRequestBody;
  677. begin
  678. R:=AddBody('api');
  679. R.Content.AddItem('123').Encoding.AddItem('abc').ContentType:='def';
  680. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "encoding" : { "abc" : { "contentType": "def"} } } } } } } } }');
  681. end;
  682. procedure TTestOpenApiWriterPathRequestBody.TestContentEncodingExplode;
  683. var
  684. R : TRequestBody;
  685. begin
  686. R:=AddBody('api');
  687. R.Content.AddItem('123').Encoding.AddItem('abc').Explode:=True;
  688. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "encoding" : { "abc" : { "explode": true} } } } } } } } }');
  689. end;
  690. procedure TTestOpenApiWriterPathRequestBody.TestContentEncodingStyle;
  691. var
  692. R : TRequestBody;
  693. begin
  694. R:=AddBody('api');
  695. R.Content.AddItem('123').Encoding.AddItem('abc').Style:='def';
  696. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "encoding" : { "abc" : { "style": "def"} } } } } } } } }');
  697. end;
  698. procedure TTestOpenApiWriterPathRequestBody.TestContentEncodingAllowReserved;
  699. var
  700. R : TRequestBody;
  701. begin
  702. R:=AddBody('api');
  703. R.Content.AddItem('123').Encoding.AddItem('abc').AllowReserved:=True;
  704. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "encoding" : { "abc" : { "allowReserved": true} } } } } } } } }');
  705. end;
  706. procedure TTestOpenApiWriterPathRequestBody.TestContentEncodingHeaders;
  707. var
  708. R : TRequestBody;
  709. begin
  710. R:=AddBody('api');
  711. R.Content.AddItem('123').Encoding.AddItem('abc').Headers.AddItem('def').Explode:=True;
  712. TestWrite('Path get operationId','{ "paths" : { "api" : { "get": { "requestBody" : { "content" : { "123" : { "encoding" : { "abc" : { "headers": { "def" : { "explode" : true } } } } } } } } } } }');
  713. end;
  714. function TTestOpenApiWriterPathParameters.AddParam(aPath: String): TParameter;
  715. var
  716. P : TPathItem;
  717. begin
  718. P:=addPath(aPath);
  719. Result:=P.Parameters.AddParam(P);
  720. end;
  721. procedure TTestOpenApiWriterPathParameters.TestGetParametersEmpty;
  722. var
  723. P : TParameter;
  724. begin
  725. P:=AddParam('api');
  726. AssertNotNull('have p',p);
  727. TestWrite('Path param','{ "paths" : { "api" : { "parameters": [ {} ] } } }');
  728. end;
  729. function TTestOpenApiWriterPathResponses.AddResponse(aPath: String): TResponse;
  730. begin
  731. Result:=AddPath(aPath).Get.Responses.AddItem('default');
  732. end;
  733. procedure TTestOpenApiWriterPathResponses.TestEmpty;
  734. begin
  735. AssertNotNull('Have response',AddResponse('api'));
  736. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : {} } } } } }');
  737. end;
  738. procedure TTestOpenApiWriterPathResponses.TestHeaders;
  739. begin
  740. AddResponse('api').Headers.AddItem('x-content');
  741. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "headers" : { "x-content" : { } } } } } } } }');
  742. end;
  743. procedure TTestOpenApiWriterPathResponses.TestDescription;
  744. begin
  745. AddResponse('api').Description:='abc';
  746. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "description" : "abc" } } } } } }');
  747. end;
  748. procedure TTestOpenApiWriterPathResponses.TestContentEmpty;
  749. begin
  750. AddResponse('api').content.AddItem('application/json');
  751. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "content" : { "application/json" : { } } } } } } } }');
  752. end;
  753. procedure TTestOpenApiWriterPathResponses.TestContentSchema;
  754. begin
  755. AssertNotNull('Have schema',AddResponse('api').content.AddItem('application/json').Schema);
  756. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "content" : { "application/json" : { "schema" : true } } } } } } } }');
  757. end;
  758. procedure TTestOpenApiWriterPathResponses.TestContentExample;
  759. begin
  760. AddResponse('api').content.AddItem('application/json').Example:=TJSONObject.Create;
  761. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "content" : { "application/json" : { "example" : {} } } } } } } } }');
  762. end;
  763. procedure TTestOpenApiWriterPathResponses.TestContentExamples;
  764. begin
  765. AddResponse('api').content.AddItem('application/json').Examples.AddItem('abc').Summary:='x';
  766. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "content" : { "application/json" : { "examples" : { "abc" : { "summary": "x"} } } } } } } } } }');
  767. end;
  768. procedure TTestOpenApiWriterPathResponses.TestContentEncodingEmpty;
  769. begin
  770. AddResponse('api').content.AddItem('application/json').Encoding.AddItem('abc'); //.ContentType:='application/json';
  771. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "content" : { "application/json" : { "encoding" : { "abc" : { } } } } } } } } } }');
  772. end;
  773. procedure TTestOpenApiWriterPathResponses.TestContentEncodingContentType;
  774. begin
  775. AddResponse('api').content.AddItem('application/json').Encoding.AddItem('abc').ContentType:='application/json';
  776. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses": { "default" : { "content" : { "application/json" : { "encoding" : { "abc" : { "contentType" : "application/json" } } } } } } } } } }');
  777. end;
  778. { TTestOpenApiWriterPathResponsesLinks }
  779. function TTestOpenApiWriterPathResponsesLinks.AddLink(aPath: String): TLink;
  780. begin
  781. Result:=AddPath(aPath).Get.Responses.AddItem('default').links.AddItem('abc');
  782. end;
  783. procedure TTestOpenApiWriterPathResponsesLinks.TestEmpty;
  784. begin
  785. AddLink('api');
  786. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses" : { "default" : { "links": { "abc" : { } } } } } } } }');
  787. end;
  788. procedure TTestOpenApiWriterPathResponsesLinks.TestOperatonRef;
  789. begin
  790. AddLink('api').OperationRef:='123';
  791. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses" : { "default" : { "links": { "abc" : { "operationRef" : "123" } } } } } } } }');
  792. end;
  793. procedure TTestOpenApiWriterPathResponsesLinks.TestOperatonId;
  794. begin
  795. AddLink('api').OperationId:='123';
  796. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses" : { "default" : { "links": { "abc" : { "operationId" : "123" } } } } } } } }');
  797. end;
  798. procedure TTestOpenApiWriterPathResponsesLinks.TestParameters;
  799. begin
  800. AddLink('api').Parameters.Add('x','y');
  801. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses" : { "default" : { "links": { "abc" : { "parameters" : { "x" : "y" } } } } } } } } }');
  802. end;
  803. procedure TTestOpenApiWriterPathResponsesLinks.TestRequestBody;
  804. begin
  805. AddLink('api').RequestBody:=TJSONObject.Create();
  806. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses" : { "default" : { "links": { "abc" : { "requestBody" : {} } } } } } } } }');
  807. end;
  808. procedure TTestOpenApiWriterPathResponsesLinks.TestDescription;
  809. begin
  810. AddLink('api').Description:='123';
  811. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses" : { "default" : { "links": { "abc" : { "description" : "123" } } } } } } } }');
  812. end;
  813. procedure TTestOpenApiWriterPathResponsesLinks.TestServer;
  814. begin
  815. AddLink('api').Server.Url:='123';
  816. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "responses" : { "default" : { "links": { "abc" : { "server" : { "url" : "123" } } } } } } } } }');
  817. end;
  818. procedure TTestOpenApiWriterPathSecurity.TestEmpty;
  819. var
  820. O : TAPIOperation;
  821. begin
  822. O:=AddPath('api').Get;
  823. O.Security.AddSecurity(O);
  824. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "security" : [ {} ] } } } }');
  825. end;
  826. procedure TTestOpenApiWriterPathSecurity.TestAPIKey;
  827. var
  828. O : TAPIOperation;
  829. begin
  830. O:=AddPath('api').Get;
  831. O.Security.AddSecurity(O).AddItem('api_key').Add('akey');
  832. TestWrite('Path param','{ "paths" : { "api" : { "get" : { "security" : [ { "api_key" : ["akey"] } ] } } } }');
  833. end;
  834. { TTestOpenApiWriterWebHooks }
  835. function TTestOpenApiWriterWebHooks.AddWebHook(const aname: string): TPathItem;
  836. begin
  837. Result:=OpenAPI.WebHooks.AddItem(aName);
  838. end;
  839. procedure TTestOpenApiWriterWebHooks.TestEmpty;
  840. begin
  841. AssertNotNull(OpenAPI.WebHooks.AddItem('newitem'));
  842. TestWrite('Path param','{ "webhooks" : { "newitem" : { } } }');
  843. end;
  844. procedure TTestOpenApiWriterWebHooks.TestSummary;
  845. begin
  846. OpenAPI.WebHooks.AddItem('newitem').Summary:='abc';
  847. TestWrite('Path param','{ "webhooks" : { "newitem" : { "summary" : "abc" } } }');
  848. end;
  849. { TTestOpenApiWriterComponents }
  850. function TTestOpenApiWriterComponents.AddComponentSchema(const aname: string): TJSONSchema;
  851. begin
  852. Result:=OpenAPI.Components.Schemas.Add(aName);
  853. end;
  854. procedure TTestOpenApiWriterComponents.TestSchemaEmpty;
  855. begin
  856. AssertNotNull('Schema',AddComponentSchema('abc'));
  857. TestWrite('Path componentschema','{ "components" : { "schemas" : { "abc" : true } } }');
  858. end;
  859. procedure TTestOpenApiWriterComponents.TestSchemaContentEncoding;
  860. begin
  861. AddComponentSchema('abc').Validations.contentEncoding:='utf8';
  862. TestWrite('Path componentschema','{ "components" : { "schemas" : { "abc" : { "contentEncoding" : "utf8" } } } }');
  863. end;
  864. { TTestOpenApiWriterOAuth2Scopes }
  865. procedure TTestOpenApiWriterOAuth2Scopes.TestOAuth2ScopesAsObject;
  866. var
  867. Scheme: TSecuritySchemeOrReference;
  868. Flow: TOAuthFlow;
  869. begin
  870. Scheme := OpenAPI.Components.SecuritySchemes.AddItem('oauth2');
  871. Scheme.Type_ := 'oauth2';
  872. Flow := Scheme.Flows.ClientAuthorizationCode;
  873. Flow.AuthorizationUrl := 'https://example.com/auth';
  874. Flow.TokenURL := 'https://example.com/token';
  875. Flow.Scopes.Add('read:user=Read user data');
  876. Flow.Scopes.Add('write:user=Write user data');
  877. TestWrite('OAuth2 scopes as object','{ "components" : { "securitySchemes" : { "oauth2" : { "type" : "oauth2", "flows" : { "authorizationCode" : { "authorizationUrl" : "https://example.com/auth", "tokenUrl" : "https://example.com/token", "scopes" : { "read:user" : "Read user data", "write:user" : "Write user data" } } } } } } }');
  878. end;
  879. procedure TTestOpenApiWriterOAuth2Scopes.TestOAuth2ScopesEmpty;
  880. var
  881. Scheme: TSecuritySchemeOrReference;
  882. Flow: TOAuthFlow;
  883. begin
  884. Scheme := OpenAPI.Components.SecuritySchemes.AddItem('oauth2');
  885. Scheme.Type_ := 'oauth2';
  886. Flow := Scheme.Flows.ClientAuthorizationCode;
  887. Flow.AuthorizationUrl := 'https://example.com/auth';
  888. Flow.TokenURL := 'https://example.com/token';
  889. // Access Scopes to ensure it's initialized but leave it empty
  890. AssertEquals('Scopes count', 0, Flow.Scopes.Count);
  891. TestWrite('OAuth2 empty scopes','{ "components" : { "securitySchemes" : { "oauth2" : { "type" : "oauth2", "flows" : { "authorizationCode" : { "authorizationUrl" : "https://example.com/auth", "tokenUrl" : "https://example.com/token", "scopes" : { } } } } } } }');
  892. end;
  893. { TTestOpenApiWriterSecurity }
  894. procedure TTestOpenApiWriterSecurity.TestOne;
  895. begin
  896. OpenAPI.Security.AddSecurity(OpenAPI).AddItem('abc');
  897. TestWrite('Security','{ "security" : [ { "abc" : [] } ] }');
  898. end;
  899. procedure StartSources;
  900. begin
  901. _Sources:=TStringList.Create;
  902. _Decl:=TStringList.Create;
  903. _Decl.Add('unit ReadTests;');
  904. _Decl.Add('');
  905. _Decl.Add('interface');
  906. _Decl.Add('');
  907. _Decl.Add('uses fpcunit;');
  908. _Decl.Add('');
  909. _Decl.Add('type');
  910. _Decl.Add('');
  911. end;
  912. procedure WriteSources;
  913. begin
  914. _Decl.Add(' end;');
  915. _Decl.Add('');
  916. _Decl.Add('implementation');
  917. _Decl.Add('');
  918. _Decl.AddStrings(_Sources);
  919. _Decl.Add('');
  920. _Decl.Add('end.');
  921. _Decl.SaveToFile('ReadTests.pp');
  922. _Sources.Free;
  923. _Decl.Free;
  924. end;
  925. initialization
  926. // StartSources;
  927. RegisterTests('Writer',[
  928. TTestopenApiWriterOpenAPI,
  929. TTestopenApiWriterInfo,
  930. TTestopenApiWriterTags,
  931. TTestOpenApiWriterExternalDocs,
  932. TTestOpenApiWriterServers,
  933. TTestOpenApiWriterPaths,
  934. TTestOpenApiWriterPathRequestBody,
  935. TTestOpenApiWriterPathParameters,
  936. TTestOpenApiWriterPathResponses,
  937. TTestOpenApiWriterPathSecurity,
  938. TTestOpenApiWriterPathResponsesLinks,
  939. TTestOpenApiWriterWebHooks,
  940. TTestOpenApiWriterComponents,
  941. TTestOpenApiWriterOAuth2Scopes,
  942. TTestOpenApiWriterSecurity
  943. ]);
  944. finalization
  945. if assigned(_Decl) then
  946. WriteSources;
  947. end.