Test_MediaTypes.dpr 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088
  1. (* _ _
  2. * | |__ _ __ ___ ___ | | __
  3. * | '_ \| '__/ _ \ / _ \| |/ /
  4. * | |_) | | | (_) | (_) | <
  5. * |_.__/|_| \___/ \___/|_|\_\
  6. *
  7. * Microframework which helps to develop web Pascal applications.
  8. *
  9. * Copyright (c) 2012-2020 Silvio Clecio <[email protected]>
  10. *
  11. * Brook framework is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation; either
  14. * version 2.1 of the License, or (at your option) any later version.
  15. *
  16. * Brook framework is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with Brook framework; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *)
  25. program Test_MediaTypes;
  26. {$I Tests.inc}
  27. uses
  28. RTLConsts,
  29. SysUtils,
  30. {$IFDEF FPC}
  31. FileUtil,
  32. {$ELSE}
  33. IOUtils,
  34. {$ENDIF}
  35. Classes,
  36. BrookExtra,
  37. BrookLibraryLoader,
  38. BrookReader,
  39. BrookMediaTypes,
  40. Test;
  41. const
  42. MIME_TYPES_FILE = '../Examples/Common/mime.types';
  43. FAKE_MIME_TYPES_FILE = 'fakemime.types';
  44. var
  45. MIMEFileName: TFileName;
  46. type
  47. { TFakeMediaTypes }
  48. TFakeMediaTypes = class(TBrookMediaTypes)
  49. private
  50. FPrepared: Boolean;
  51. protected
  52. function IsPrepared: Boolean; override;
  53. public
  54. class function GetDescription: string; override;
  55. procedure Prepare; override;
  56. property Cache;
  57. end;
  58. { TFakeMediaTypes }
  59. class function TFakeMediaTypes.GetDescription: string;
  60. begin
  61. Result := 'Fake';
  62. end;
  63. procedure TFakeMediaTypes.Prepare;
  64. begin
  65. FPrepared := True;
  66. end;
  67. function TFakeMediaTypes.IsPrepared: Boolean;
  68. begin
  69. Result := FPrepared;
  70. end;
  71. { MediaTypes }
  72. procedure Test_MediaTypesCreate;
  73. var
  74. MT: TFakeMediaTypes;
  75. begin
  76. MT := TFakeMediaTypes.Create;
  77. try
  78. Assert(Assigned(MT.Cache));
  79. Assert(MT.DefaultType = BROOK_CT_OCTET_STREAM);
  80. finally
  81. MT.Free;
  82. end;
  83. end;
  84. procedure Test_MediaTypesGetRegisterAlias;
  85. begin
  86. Assert(TFakeMediaTypes.GetRegisterAlias = 'BrookMIME_Fake');
  87. end;
  88. procedure Test_MediaTypesGetDescription;
  89. begin
  90. Assert(TFakeMediaTypes.GetDescription = 'Fake');
  91. end;
  92. procedure Test_MediaTypesIsValid;
  93. begin
  94. Assert(not TBrookMediaTypes.IsValid(''));
  95. Assert(not TBrookMediaTypes.IsValid('abc'));
  96. Assert(TBrookMediaTypes.IsValid('abc/'));
  97. Assert(TBrookMediaTypes.IsValid('/abc'));
  98. Assert(TBrookMediaTypes.IsValid('abc/def'));
  99. Assert(TBrookMediaTypes.IsValid('/abc/def/def'));
  100. end;
  101. procedure Test_MediaTypesIsText;
  102. begin
  103. Assert(not TBrookMediaTypes.IsText(''));
  104. Assert(not TBrookMediaTypes.IsText('abc'));
  105. Assert(not TBrookMediaTypes.IsText('abc/'));
  106. Assert(not TBrookMediaTypes.IsText('/abc'));
  107. Assert(not TBrookMediaTypes.IsText('/abc/def/def'));
  108. Assert(not TBrookMediaTypes.IsText('abc/def'));
  109. Assert(not TBrookMediaTypes.IsText('application/xml'));
  110. Assert(TBrookMediaTypes.IsText('text/html'));
  111. end;
  112. procedure Test_MediaTypesIsExt;
  113. begin
  114. Assert(not TBrookMediaTypes.IsExt(''));
  115. Assert(not TBrookMediaTypes.IsExt('.'));
  116. Assert(not TBrookMediaTypes.IsExt('..'));
  117. Assert(TBrookMediaTypes.IsExt('js'));
  118. Assert(TBrookMediaTypes.IsExt('.js'));
  119. end;
  120. procedure Test_MediaTypesNormalizeExt;
  121. begin
  122. Assert(TBrookMediaTypes.NormalizeExt('') = '');
  123. Assert(TBrookMediaTypes.NormalizeExt('.') = '.');
  124. Assert(TBrookMediaTypes.NormalizeExt('a') = '.a');
  125. Assert(TBrookMediaTypes.NormalizeExt('.a') = '.a');
  126. Assert(TBrookMediaTypes.NormalizeExt('a.b') = '.a.b');
  127. Assert(TBrookMediaTypes.NormalizeExt('.abc') = '.abc');
  128. end;
  129. procedure Test_MediaTypesPrepare;
  130. var
  131. MT: TFakeMediaTypes;
  132. begin
  133. MT := TFakeMediaTypes.Create;
  134. try
  135. Assert(not MT.IsPrepared);
  136. MT.Prepare;
  137. Assert(MT.IsPrepared);
  138. finally
  139. MT.Free;
  140. end;
  141. end;
  142. procedure DoMediaTypesAddEmptyMediaExt(const AArgs: array of const);
  143. begin
  144. TFakeMediaTypes(AArgs[0].VObject).Add('', 'bar/foo');
  145. end;
  146. procedure DoMediaTypesAddInvalidMediaExt(const AArgs: array of const);
  147. begin
  148. TFakeMediaTypes(AArgs[0].VObject).Add('.', 'bar/foo');
  149. end;
  150. procedure DoMediaTypesAddEmptyMediaType(const AArgs: array of const);
  151. begin
  152. TFakeMediaTypes(AArgs[0].VObject).Add('.foo', '');
  153. end;
  154. procedure DoMediaTypesAddInvalidMediaType(const AArgs: array of const);
  155. begin
  156. TFakeMediaTypes(AArgs[0].VObject).Add('.foo', 'bar');
  157. end;
  158. procedure Test_MediaTypesAdd;
  159. var
  160. MT: TFakeMediaTypes;
  161. begin
  162. MT := TFakeMediaTypes.Create;
  163. try
  164. Assert(not MT.Prepared);
  165. Assert(MT.Count = 0);
  166. MT.Add('.foo', 'bar/foo');
  167. MT.Add('.bar', 'foo/bar');
  168. Assert(MT.Count = 2);
  169. MT.Clear;
  170. AssertExcept(DoMediaTypesAddEmptyMediaExt,
  171. EArgumentException, SBrookEmptyMediaExt, [MT]);
  172. AssertExcept(DoMediaTypesAddInvalidMediaExt,
  173. EBrookMediaTypes, Format(SBrookInvalidMediaExt, ['.']), [MT]);
  174. AssertExcept(DoMediaTypesAddEmptyMediaType,
  175. EArgumentException, SBrookEmptyMediaType, [MT]);
  176. AssertExcept(DoMediaTypesAddInvalidMediaType,
  177. EBrookMediaTypes, Format(SBrookInvalidMediaType, ['bar']), [MT]);
  178. finally
  179. MT.Free;
  180. end;
  181. end;
  182. procedure DoMediaTypesRemoveEmptyMediaExt(const AArgs: array of const);
  183. begin
  184. TFakeMediaTypes(AArgs[0].VObject).Remove('');
  185. end;
  186. procedure DoMediaTypesRemoveInvalidMediaExt(const AArgs: array of const);
  187. begin
  188. TFakeMediaTypes(AArgs[0].VObject).Remove('.');
  189. end;
  190. procedure Test_MediaTypesRemove;
  191. var
  192. MT: TFakeMediaTypes;
  193. begin
  194. MT := TFakeMediaTypes.Create;
  195. try
  196. MT.Add('.foo', 'bar/foo');
  197. MT.Add('.bar', 'foo/bar');
  198. Assert(MT.Count = 2);
  199. MT.Remove('.foo');
  200. Assert(MT.Count = 1);
  201. MT.Remove('.bar');
  202. Assert(MT.Count = 0);
  203. AssertExcept(DoMediaTypesRemoveEmptyMediaExt,
  204. EArgumentException, SBrookEmptyMediaExt, [MT]);
  205. AssertExcept(DoMediaTypesRemoveInvalidMediaExt,
  206. EBrookMediaTypes, Format(SBrookInvalidMediaExt, ['.']), [MT]);
  207. finally
  208. MT.Free;
  209. end;
  210. end;
  211. procedure DoMediaTypesTryTypeEmptyMediaExt(const AArgs: array of const);
  212. var
  213. D: string;
  214. begin
  215. TFakeMediaTypes(AArgs[0].VObject).TryType('', D);
  216. end;
  217. procedure DoMediaTypesTryTypeInvalidMediaExt(const AArgs: array of const);
  218. var
  219. D: string;
  220. begin
  221. TFakeMediaTypes(AArgs[0].VObject).TryType('.', D);
  222. end;
  223. procedure Test_MediaTypesTryType;
  224. var
  225. MT: TFakeMediaTypes;
  226. T: string;
  227. begin
  228. MT := TFakeMediaTypes.Create;
  229. try
  230. Assert(not MT.Prepared);
  231. Assert(not MT.TryType('.foo', T));
  232. Assert(not MT.TryType('.bar', T));
  233. MT.Add('.foo', 'bar/foo');
  234. MT.Add('.bar', 'foo/bar');
  235. Assert(MT.TryType('.foo', T));
  236. Assert(T = 'bar/foo');
  237. Assert(MT.TryType('.bar', T));
  238. Assert(T = 'foo/bar');
  239. Assert(MT.Prepared);
  240. AssertExcept(DoMediaTypesTryTypeEmptyMediaExt,
  241. EArgumentException, SBrookEmptyMediaExt, [MT]);
  242. AssertExcept(DoMediaTypesTryTypeInvalidMediaExt,
  243. EBrookMediaTypes, Format(SBrookInvalidMediaExt, ['.']), [MT]);
  244. finally
  245. MT.Free;
  246. end;
  247. end;
  248. procedure DoMediaTypesFindEmptyMediaExt(const AArgs: array of const);
  249. begin
  250. TFakeMediaTypes(AArgs[0].VObject).Find('');
  251. end;
  252. procedure DoMediaTypesFindInvalidMediaExt(const AArgs: array of const);
  253. begin
  254. TFakeMediaTypes(AArgs[0].VObject).Find('.');
  255. end;
  256. procedure DoMediaTypesFindEmptyMediaType(const AArgs: array of const);
  257. begin
  258. TFakeMediaTypes(AArgs[0].VObject).Find('.foo', '');
  259. end;
  260. procedure DoMediaTypesFindInvalidMediaType(const AArgs: array of const);
  261. begin
  262. TFakeMediaTypes(AArgs[0].VObject).Find('.foo', 'bar');
  263. end;
  264. procedure Test_MediaTypesFind;
  265. var
  266. MT: TFakeMediaTypes;
  267. begin
  268. MT := TFakeMediaTypes.Create;
  269. try
  270. Assert(not MT.Prepared);
  271. Assert(MT.Find('.foo') = MT.DefaultType);
  272. Assert(MT.Find('.foo', 'bar/foo') = 'bar/foo');
  273. Assert(MT.Find('.bar') = MT.DefaultType);
  274. Assert(MT.Find('.bar', 'bar/foo') = 'bar/foo');
  275. MT.Add('.foo', 'bar/foo');
  276. MT.Add('.bar', 'foo/bar');
  277. Assert(MT.Find('.foo') = 'bar/foo');
  278. Assert(MT.Find('.bar') = 'foo/bar');
  279. Assert(MT.Prepared);
  280. AssertExcept(DoMediaTypesFindEmptyMediaExt,
  281. EArgumentException, SBrookEmptyMediaExt, [MT]);
  282. AssertExcept(DoMediaTypesFindInvalidMediaExt,
  283. EBrookMediaTypes, Format(SBrookInvalidMediaExt, ['.']), [MT]);
  284. AssertExcept(DoMediaTypesFindEmptyMediaType,
  285. EArgumentException, SBrookEmptyMediaType, [MT]);
  286. AssertExcept(DoMediaTypesFindInvalidMediaType,
  287. EBrookMediaTypes, Format(SBrookInvalidMediaType, ['bar']), [MT]);
  288. finally
  289. MT.Free;
  290. end;
  291. end;
  292. procedure Test_MediaTypesCount;
  293. var
  294. MT: TFakeMediaTypes;
  295. begin
  296. MT := TFakeMediaTypes.Create;
  297. try
  298. Assert(MT.Count = 0);
  299. MT.Add('.foo', 'bar/foo');
  300. MT.Add('.bar', 'foo/bar');
  301. Assert(MT.Count = 2);
  302. finally
  303. MT.Free;
  304. end;
  305. end;
  306. procedure Test_MediaTypesClear;
  307. var
  308. MT: TFakeMediaTypes;
  309. begin
  310. MT := TFakeMediaTypes.Create;
  311. try
  312. Assert(MT.Count = 0);
  313. MT.Add('.foo', 'bar/foo');
  314. MT.Add('.bar', 'foo/bar');
  315. Assert(MT.Count = 2);
  316. MT.Clear;
  317. Assert(MT.Count = 0);
  318. finally
  319. MT.Free;
  320. end;
  321. end;
  322. procedure DoMediaTypesDefaultTypeEmptyMediaType(const AArgs: array of const);
  323. begin
  324. TFakeMediaTypes(AArgs[0].VObject).DefaultType := '';
  325. end;
  326. procedure DoMediaTypesDefaultTypeInvalidMediaType(const AArgs: array of const);
  327. begin
  328. TFakeMediaTypes(AArgs[0].VObject).DefaultType := 'bar';
  329. end;
  330. procedure Test_MediaTypesDefaultType;
  331. var
  332. MT: TFakeMediaTypes;
  333. begin
  334. MT := TFakeMediaTypes.Create;
  335. try
  336. Assert(MT.DefaultType = BROOK_CT_OCTET_STREAM);
  337. MT.DefaultType := 'foo/bar';
  338. Assert(MT.DefaultType = 'foo/bar');
  339. AssertExcept(DoMediaTypesDefaultTypeEmptyMediaType,
  340. EArgumentException, SBrookEmptyMediaType, [MT]);
  341. AssertExcept(DoMediaTypesDefaultTypeInvalidMediaType,
  342. EBrookMediaTypes, Format(SBrookInvalidMediaType, ['bar']), [MT]);
  343. finally
  344. MT.Free;
  345. end;
  346. end;
  347. procedure Test_MediaTypesPrepared;
  348. var
  349. MT: TFakeMediaTypes;
  350. begin
  351. MT := TFakeMediaTypes.Create;
  352. try
  353. Assert(not MT.Prepared);
  354. MT.Prepare;
  355. Assert(MT.Prepared);
  356. finally
  357. MT.Free;
  358. end
  359. end;
  360. procedure DoMediaTypesParserCreateParamIsNilReader(const AArgs: array of const);
  361. begin
  362. TBrookMediaTypesParser.Create(nil, TBrookMediaTypes(AArgs[0].VObject));
  363. end;
  364. procedure DoMediaTypesParserCreateParamIsNilTypes(const AArgs: array of const);
  365. begin
  366. TBrookMediaTypesParser.Create(TBrookTextReader(AArgs[0].VObject), nil);
  367. end;
  368. procedure Test_MediaTypesParserCreate;
  369. var
  370. R: TBrookTextReader;
  371. T: TBrookMediaTypes;
  372. P: TBrookMediaTypesParser;
  373. begin
  374. R := TBrookStringReader.Create('');
  375. T := TFakeMediaTypes.Create;
  376. P := TBrookMediaTypesParser.Create(R, T);
  377. try
  378. Assert(Assigned(P.Reader) and (P.Reader = R));
  379. Assert(Assigned(P.Types) and (P.Types = T));
  380. AssertExcept(DoMediaTypesParserCreateParamIsNilReader,
  381. EArgumentNilException, Format(SParamIsNil, ['AReader']), [T]);
  382. AssertExcept(DoMediaTypesParserCreateParamIsNilTypes,
  383. EArgumentNilException, Format(SParamIsNil, ['ATypes']), [R]);
  384. finally
  385. T.Free;
  386. R.Free;
  387. P.Free;
  388. end;
  389. end;
  390. procedure DoMediaTypesParserParseInvalidMediaType(const AArgs: array of const);
  391. begin
  392. TBrookMediaTypesParser(AArgs[0].VObject).Parse;
  393. end;
  394. procedure DoMediaTypesParserParseInvalidMediaExt(const AArgs: array of const);
  395. begin
  396. TBrookMediaTypesParser(AArgs[0].VObject).Parse;
  397. end;
  398. procedure Test_MediaTypesParserParse;
  399. var
  400. R: TBrookTextReader;
  401. T: TBrookMediaTypes;
  402. P: TBrookMediaTypesParser;
  403. begin
  404. R := TBrookFileReader.Create(FAKE_MIME_TYPES_FILE);
  405. T := TFakeMediaTypes.Create;
  406. P := TBrookMediaTypesParser.Create(R, T);
  407. try
  408. Assert(P.Types.Count = 0);
  409. P.Parse;
  410. Assert(P.Types.Count = 7);
  411. Assert(P.Types.Find('.json') = 'application/json');
  412. Assert(P.Types.Find('.html') = 'text/html');
  413. Assert(P.Types.Find('.htm') = 'text/html');
  414. Assert(P.Types.Find('.pas') = 'text/x-pascal');
  415. Assert(P.Types.Find('.p') = 'text/x-pascal');
  416. Assert(P.Types.Find('.jpgv') = 'video/jpeg');
  417. Assert(P.Types.Find('.foobar') = P.Types.DefaultType);
  418. finally
  419. T.Free;
  420. R.Free;
  421. P.Free;
  422. end;
  423. R := TBrookFileReader.Create(MIME_TYPES_FILE);
  424. T := TFakeMediaTypes.Create;
  425. P := TBrookMediaTypesParser.Create(R, T);
  426. try
  427. Assert(P.Types.Count = 0);
  428. P.Parse;
  429. Assert(P.Types.Count = 1239);
  430. Assert(P.Types.Find('.txt') = 'text/plain');
  431. Assert(P.Types.Find('.html') = 'text/html');
  432. Assert(P.Types.Find('.htm') = 'text/html');
  433. Assert(P.Types.Find('.pas') = 'text/x-pascal');
  434. Assert(P.Types.Find('.p') = 'text/x-pascal');
  435. Assert(P.Types.Find('.xhtml') = 'application/xhtml+xml');
  436. Assert(P.Types.Find('.json') = 'application/json');
  437. Assert(P.Types.Find('.pdf') = 'application/pdf');
  438. Assert(P.Types.Find('.foobar') = P.Types.DefaultType);
  439. finally
  440. T.Free;
  441. R.Free;
  442. P.Free;
  443. end;
  444. R := TBrookStringReader.Create(Concat(
  445. 'text/plain', #9, #9, #9,'txt', sLineBreak,
  446. 'text/html', #9, #9, #9,'html htm xhtml', sLineBreak,
  447. 'application/json', #9, #9, #9,'json', sLineBreak,
  448. '#application/docbook+xml', #9, #9, #9,'docbook dbk', sLineBreak,
  449. 'application/pdf', #9, #9, #9,'pdf', sLineBreak,
  450. 'foo bar', sLineBreak,
  451. 'foo=bar'
  452. ));
  453. T := TFakeMediaTypes.Create;
  454. P := TBrookMediaTypesParser.Create(R, T);
  455. try
  456. Assert(P.Types.Count = 0);
  457. P.Parse;
  458. Assert(P.Types.Count = 6);
  459. Assert(P.Types.Find('.txt') = 'text/plain');
  460. Assert(P.Types.Find('.html') = 'text/html');
  461. Assert(P.Types.Find('.htm') = 'text/html');
  462. Assert(P.Types.Find('.xhtml') = 'text/html');
  463. Assert(P.Types.Find('.json') = 'application/json');
  464. Assert(P.Types.Find('.docbook') = P.Types.DefaultType);
  465. Assert(P.Types.Find('.pdf') = 'application/pdf');
  466. finally
  467. T.Free;
  468. R.Free;
  469. P.Free;
  470. end;
  471. R := TBrookStringReader.Create(Concat(
  472. 'text/plain', #9, 'txt', sLineBreak,
  473. 'application/json', #9, 'json', sLineBreak,
  474. 'foo', #9, 'bar'
  475. ));
  476. T := TFakeMediaTypes.Create;
  477. P := TBrookMediaTypesParser.Create(R, T);
  478. try
  479. Assert(P.Types.Count = 0);
  480. AssertExcept(DoMediaTypesParserParseInvalidMediaType,
  481. EBrookMediaTypes, Format(SBrookInvalidMediaType, ['foo']), [P]);
  482. Assert(P.Types.Count = 2);
  483. finally
  484. T.Free;
  485. R.Free;
  486. P.Free;
  487. end;
  488. R := TBrookStringReader.Create(Concat(
  489. 'text/plain', #9, 'txt', sLineBreak,
  490. 'application/json', #9, 'json', sLineBreak,
  491. 'foo/bar', #9, '.'
  492. ));
  493. T := TFakeMediaTypes.Create;
  494. P := TBrookMediaTypesParser.Create(R, T);
  495. try
  496. Assert(P.Types.Count = 0);
  497. AssertExcept(DoMediaTypesParserParseInvalidMediaExt,
  498. EBrookMediaTypes, Format(SBrookInvalidMediaExt, ['.']), [P]);
  499. Assert(P.Types.Count = 2);
  500. finally
  501. T.Free;
  502. R.Free;
  503. P.Free;
  504. end;
  505. end;
  506. procedure Test_MediaTypesParserReader;
  507. var
  508. R: TBrookTextReader;
  509. T: TBrookMediaTypes;
  510. P: TBrookMediaTypesParser;
  511. begin
  512. R := TBrookStringReader.Create('');
  513. T := TFakeMediaTypes.Create;
  514. P := TBrookMediaTypesParser.Create(R, T);
  515. try
  516. Assert(Assigned(P.Reader) and (P.Reader = R));
  517. finally
  518. T.Free;
  519. R.Free;
  520. P.Free;
  521. end;
  522. end;
  523. procedure Test_MediaTypesParserTypes;
  524. var
  525. R: TBrookTextReader;
  526. T: TBrookMediaTypes;
  527. P: TBrookMediaTypesParser;
  528. begin
  529. R := TBrookStringReader.Create('');
  530. T := TFakeMediaTypes.Create;
  531. P := TBrookMediaTypesParser.Create(R, T);
  532. try
  533. Assert(Assigned(P.Types) and (P.Types = T));
  534. finally
  535. T.Free;
  536. R.Free;
  537. P.Free;
  538. end;
  539. end;
  540. procedure DoMediaTypesParserNginxParseInvalidMediaType(const AArgs: array of const);
  541. begin
  542. TBrookMediaTypesParserNginx(AArgs[0].VObject).Parse;
  543. end;
  544. procedure DoMediaTypesParserNginxParseInvalidMediaExt(const AArgs: array of const);
  545. begin
  546. TBrookMediaTypesParserNginx(AArgs[0].VObject).Parse;
  547. end;
  548. procedure Test_MediaTypesParserNginxParse;
  549. var
  550. R: TBrookTextReader;
  551. T: TBrookMediaTypes;
  552. P: TBrookMediaTypesParser;
  553. begin
  554. R := TBrookStringReader.Create(Concat(
  555. sLineBreak,
  556. 'types {', sLineBreak,
  557. ' text/html html htm shtml;', sLineBreak,
  558. sLineBreak,
  559. ' text/css css;', sLineBreak,
  560. '# text/xml xml;', sLineBreak,
  561. ' application/javascript js;', sLineBreak,
  562. '# application/atom+xml atom;', sLineBreak,
  563. ' application/rss+xml rss;', sLineBreak,
  564. '}', sLineBreak
  565. ));
  566. T := TFakeMediaTypes.Create;
  567. P := TBrookMediaTypesParserNginx.Create(R, T);
  568. try
  569. Assert(P.Types.Count = 0);
  570. P.Parse;
  571. Assert(P.Types.Count = 6);
  572. Assert(P.Types.Find('.html') = 'text/html');
  573. Assert(P.Types.Find('.htm') = 'text/html');
  574. Assert(P.Types.Find('.shtml') = 'text/html');
  575. Assert(P.Types.Find('.js') = 'application/javascript');
  576. Assert(P.Types.Find('.xml') = P.Types.DefaultType);
  577. Assert(P.Types.Find('.rss') = 'application/rss+xml');
  578. finally
  579. T.Free;
  580. R.Free;
  581. P.Free;
  582. end;
  583. R := TBrookStringReader.Create(Concat(
  584. 'types {', sLineBreak,
  585. ' text/html html;', sLineBreak,
  586. ' text/css css;', sLineBreak,
  587. ' foo bar;', sLineBreak,
  588. '}'
  589. ));
  590. T := TFakeMediaTypes.Create;
  591. P := TBrookMediaTypesParserNginx.Create(R, T);
  592. try
  593. Assert(P.Types.Count = 0);
  594. AssertExcept(DoMediaTypesParserNginxParseInvalidMediaType,
  595. EBrookMediaTypes, Format(SBrookInvalidMediaType, ['foo']), [P]);
  596. Assert(P.Types.Count = 2);
  597. finally
  598. T.Free;
  599. R.Free;
  600. P.Free;
  601. end;
  602. R := TBrookStringReader.Create(Concat(
  603. 'types {', sLineBreak,
  604. ' text/html html;', sLineBreak,
  605. ' text/css css;', sLineBreak,
  606. ' foo .;', sLineBreak,
  607. '}'
  608. ));
  609. T := TFakeMediaTypes.Create;
  610. P := TBrookMediaTypesParserNginx.Create(R, T);
  611. try
  612. Assert(P.Types.Count = 0);
  613. AssertExcept(DoMediaTypesParserNginxParseInvalidMediaExt,
  614. EBrookMediaTypes, Format(SBrookInvalidMediaExt, ['.']), [P]);
  615. Assert(P.Types.Count = 2);
  616. finally
  617. T.Free;
  618. R.Free;
  619. P.Free;
  620. end;
  621. end;
  622. procedure DoMediaTypesPathCreateFOpenError(const AArgs: array of const);
  623. begin
  624. TBrookMediaTypesPath.Create(string(AArgs[0].VPChar));
  625. end;
  626. procedure Test_MediaTypesPathCreate;
  627. var
  628. MT: TBrookMediaTypesPath;
  629. begin
  630. MT := TBrookMediaTypesPath.Create(MIME_TYPES_FILE);
  631. try
  632. Assert(MT.FileName = MIME_TYPES_FILE);
  633. Assert(Assigned(MT.Reader));
  634. Assert(Assigned(MT.Parser));
  635. finally
  636. MT.Free;
  637. end;
  638. MT := TBrookMediaTypesPath.Create;
  639. try
  640. Assert(MT.FileName = MIMEFileName);
  641. Assert(Assigned(MT.Reader));
  642. Assert(Assigned(MT.Parser));
  643. finally
  644. MT.Free;
  645. end;
  646. AssertExcept(DoMediaTypesPathCreateFOpenError, EFOpenError, [PChar('')]);
  647. DeleteFile('foo');
  648. AssertExcept(DoMediaTypesPathCreateFOpenError, EFOpenError, [PChar('foo')]);
  649. end;
  650. procedure Test_MediaTypesPathGetDescription;
  651. begin
  652. Assert(TBrookMediaTypesPath.GetDescription = 'Path');
  653. end;
  654. procedure Test_MediaTypesPathGetFileName;
  655. begin
  656. Assert(TBrookMediaTypesPath.GetFileName = MIMEFileName);
  657. end;
  658. procedure Test_MediaTypesPathPrepare;
  659. var
  660. MT: TBrookMediaTypesPath;
  661. begin
  662. MT := TBrookMediaTypesPath.Create(MIME_TYPES_FILE);
  663. try
  664. Assert(not MT.Prepared);
  665. MT.Prepare;
  666. Assert(MT.Prepared);
  667. Assert(MT.Find('.txt') = 'text/plain');
  668. Assert(MT.Find('.html') = 'text/html');
  669. Assert(MT.Find('.json') = 'application/json');
  670. Assert(MT.Find('.pdf') = 'application/pdf');
  671. Assert(MT.Find('.xxx') = MT.DefaultType);
  672. finally
  673. MT.Free;
  674. end;
  675. end;
  676. procedure Test_MediaTypesPathClear;
  677. var
  678. MT: TBrookMediaTypesPath;
  679. begin
  680. MT := TBrookMediaTypesPath.Create(MIME_TYPES_FILE);
  681. try
  682. Assert(MT.Count = 0);
  683. MT.Prepare;
  684. Assert(MT.Count > 0);
  685. MT.Clear;
  686. Assert(MT.Count = 0);
  687. finally
  688. MT.Free;
  689. end;
  690. end;
  691. procedure Test_MediaTypesPathReader;
  692. var
  693. MT: TBrookMediaTypesPath;
  694. begin
  695. MT := TBrookMediaTypesPath.Create(MIME_TYPES_FILE);
  696. try
  697. Assert(Assigned(MT.Reader));
  698. finally
  699. MT.Free;
  700. end;
  701. end;
  702. procedure Test_MediaTypesPathParser;
  703. var
  704. MT: TBrookMediaTypesPath;
  705. begin
  706. MT := TBrookMediaTypesPath.Create(MIME_TYPES_FILE);
  707. try
  708. Assert(Assigned(MT.Parser));
  709. finally
  710. MT.Free;
  711. end;
  712. end;
  713. procedure Test_MediaTypesPathFileName;
  714. var
  715. MT: TBrookMediaTypesPath;
  716. begin
  717. MT := TBrookMediaTypesPath.Create(MIMEFileName);
  718. try
  719. Assert(MT.FileName = MIMEFileName);
  720. finally
  721. MT.Free;
  722. end;
  723. end;
  724. procedure Test_MediaTypesApacheGetDescription;
  725. begin
  726. Assert(TBrookMediaTypesApache.GetDescription = 'Apache');
  727. end;
  728. procedure Test_MediaTypesNginxGetDescription;
  729. begin
  730. Assert(TBrookMediaTypesNginx.GetDescription = 'Nginx');
  731. end;
  732. procedure Test_MediaTypesNginxGetFileName;
  733. begin
  734. Assert(TBrookMediaTypesNginx.GetFileName = Concat(
  735. {$IFDEF UNIX}'/etc/nginx/'{$ELSE}ExtractFilePath(ParamStr(0)){$ENDIF},
  736. BROOK_MIME_FILE));
  737. end;
  738. procedure Test_MediaTypesWindowsGetDescription;
  739. begin
  740. Assert(TBrookMediaTypesWindows.GetDescription = 'Windows');
  741. end;
  742. procedure Test_MediaTypesUnixGetDescription;
  743. begin
  744. Assert(TBrookMediaTypesUnix.GetDescription = 'Unix');
  745. end;
  746. function LocalMediaTypesUnixGetFileName: TFileName;
  747. var
  748. FNs: TArray<TFileName>;
  749. FN: TFileName;
  750. begin
  751. FNs := TArray<TFileName>.Create(
  752. Concat('/etc/', BROOK_MIME_FILE)
  753. // Put other 'mime.types' paths here...
  754. );
  755. for FN in FNs do
  756. if FileExists(FN) then
  757. Exit(FN);
  758. Result := BROOK_MIME_FILE;
  759. end;
  760. procedure Test_MediaTypesUnixGetFileName;
  761. begin
  762. Assert(TBrookMediaTypesUnix.GetFileName = LocalMediaTypesUnixGetFileName);
  763. end;
  764. procedure Test_MIMECreate;
  765. var
  766. M: TBrookMIME;
  767. C: TComponent;
  768. begin
  769. C := TComponent.Create(nil);
  770. M := TBrookMIME.Create(C);
  771. try
  772. Assert(M.Owner = C);
  773. M.Open;
  774. Assert(M.Active);
  775. TBrookLibraryLoader.Unload;
  776. Assert(not M.Active);
  777. TBrookLibraryLoader.Load;
  778. Assert(M.DefaultType = BROOK_CT_OCTET_STREAM);
  779. Assert(M.FileName = MIMEFileName);
  780. Assert(M.Provider = BROOK_MIME_PROVIDER);
  781. finally
  782. M.Free;
  783. C.Free;
  784. end;
  785. end;
  786. procedure Test_MIMEGetProviderClass;
  787. var
  788. M: TBrookMIME;
  789. begin
  790. M := TBrookMIME.Create(nil);
  791. try
  792. M.Provider := 'Nginx';
  793. M.Open;
  794. Assert(M.GetProviderClass = TBrookMediaTypesNginx);
  795. M.Close;
  796. M.Provider := 'Apache';
  797. M.Open;
  798. Assert(M.GetProviderClass = TBrookMediaTypesApache);
  799. finally
  800. M.Free;
  801. end;
  802. end;
  803. procedure Test_MIMEOpen;
  804. var
  805. M: TBrookMIME;
  806. begin
  807. M := TBrookMIME.Create(nil);
  808. try
  809. Assert(not M.Active);
  810. M.Open;
  811. Assert(M.Active);
  812. finally
  813. M.Free;
  814. end;
  815. end;
  816. procedure Test_MIMEClose;
  817. var
  818. M: TBrookMIME;
  819. begin
  820. M := TBrookMIME.Create(nil);
  821. try
  822. Assert(not M.Active);
  823. M.Open;
  824. Assert(M.Active);
  825. M.Close;
  826. Assert(not M.Active);
  827. finally
  828. M.Free;
  829. end;
  830. end;
  831. procedure Test_MIMETypes;
  832. var
  833. M: TBrookMIME;
  834. begin
  835. M := TBrookMIME.Create(nil);
  836. try
  837. M.Provider := BROOK_MIME_PROVIDER;
  838. M.Open;
  839. {$IF DEFINED(MSWINDOWS)}
  840. Assert(M.Types is TBrookMediaTypesWindows);
  841. {$ELSEIF DEFINED(UNIX)}
  842. Assert(M.Types is TBrookMediaTypesUnix);
  843. {$ELSE}
  844. Assert(M.Types is TBrookMediaTypesPath);
  845. {$ENDIF}
  846. finally
  847. M.Free;
  848. end;
  849. end;
  850. procedure Test_MIMEActive;
  851. var
  852. M: TBrookMIME;
  853. begin
  854. M := TBrookMIME.Create(nil);
  855. try
  856. Assert(not M.Active);
  857. M.Active := not M.Active;
  858. Assert(M.Active);
  859. M.Active := False;
  860. M.Provider := 'Fake';
  861. RegisterClassAlias(TFakeMediaTypes, TFakeMediaTypes.GetRegisterAlias);
  862. M.Active := True;
  863. Assert(M.Types is TFakeMediaTypes);
  864. UnRegisterClass(TFakeMediaTypes);
  865. M.Active := False;
  866. M.Provider := 'Unix';
  867. M.Active := True;
  868. Assert(M.Types is TBrookMediaTypesUnix);
  869. Assert(M.DefaultType = BROOK_CT_OCTET_STREAM);
  870. finally
  871. M.Free;
  872. end;
  873. end;
  874. procedure Test_MIMEDefaultType;
  875. var
  876. M: TBrookMIME;
  877. begin
  878. M := TBrookMIME.Create(nil);
  879. try
  880. Assert(M.DefaultType = BROOK_CT_OCTET_STREAM);
  881. M.DefaultType := '';
  882. Assert(M.DefaultType = BROOK_CT_OCTET_STREAM);
  883. M.DefaultType := 'abc';
  884. Assert(M.DefaultType = BROOK_CT_OCTET_STREAM);
  885. M.DefaultType := 'text/plain';
  886. Assert(M.DefaultType = 'text/plain');
  887. finally
  888. M.Free;
  889. end;
  890. end;
  891. procedure Test_MIMEFileName;
  892. var
  893. M: TBrookMIME;
  894. begin
  895. M := TBrookMIME.Create(nil);
  896. try
  897. Assert(M.FileName = MIMEFileName);
  898. M.FileName := '';
  899. Assert(M.FileName = MIMEFileName);
  900. M.FileName := 'abc';
  901. Assert(M.FileName = 'abc');
  902. M.FileName := MIME_TYPES_FILE;
  903. Assert(M.FileName = MIME_TYPES_FILE);
  904. finally
  905. M.Free;
  906. end;
  907. end;
  908. procedure Test_MIMEProvider;
  909. var
  910. M: TBrookMIME;
  911. begin
  912. M := TBrookMIME.Create(nil);
  913. try
  914. Assert(M.Provider = BROOK_MIME_PROVIDER);
  915. M.Provider := '';
  916. Assert(M.Provider = BROOK_MIME_PROVIDER);
  917. M.Provider := 'abc';
  918. Assert(M.Provider = 'abc');
  919. M.Provider := 'Unix';
  920. Assert(M.Provider = 'Unix');
  921. finally
  922. M.Free;
  923. end;
  924. end;
  925. var
  926. F: TFileName;
  927. begin
  928. {$IF (NOT DEFINED(FPC)) AND DEFINED(DEBUG)}
  929. ReportMemoryLeaksOnShutdown := True;
  930. {$ENDIF}
  931. MIMEFileName := Concat(
  932. {$IFDEF UNIX}'/etc/'{$ELSE}ExtractFilePath(ParamStr(0)){$ENDIF},
  933. BROOK_MIME_FILE);
  934. TBrookLibraryLoader.Load;
  935. F := Concat(ExtractFilePath(ParamStr(0)), BROOK_MIME_FILE);
  936. {$IFDEF FPC}
  937. CopyFile(MIME_TYPES_FILE, F);
  938. {$ELSE}
  939. TFile.Copy(MIME_TYPES_FILE, F, True);
  940. {$ENDIF}
  941. try
  942. Test_MediaTypesCreate;
  943. // Test_MediaTypesDestroy - not required
  944. Test_MediaTypesGetRegisterAlias;
  945. Test_MediaTypesGetDescription;
  946. Test_MediaTypesIsValid;
  947. Test_MediaTypesIsText;
  948. Test_MediaTypesIsExt;
  949. Test_MediaTypesNormalizeExt;
  950. Test_MediaTypesPrepare;
  951. Test_MediaTypesAdd;
  952. Test_MediaTypesRemove;
  953. Test_MediaTypesTryType;
  954. Test_MediaTypesFind;
  955. Test_MediaTypesCount;
  956. Test_MediaTypesClear;
  957. Test_MediaTypesDefaultType;
  958. Test_MediaTypesPrepared;
  959. Test_MediaTypesParserCreate;
  960. Test_MediaTypesParserParse;
  961. Test_MediaTypesParserReader;
  962. Test_MediaTypesParserTypes;
  963. Test_MediaTypesParserNginxParse;
  964. Test_MediaTypesPathCreate;
  965. // Test_MediaTypesPathDestroy - not required
  966. Test_MediaTypesPathGetDescription;
  967. Test_MediaTypesPathGetFileName;
  968. Test_MediaTypesPathPrepare;
  969. Test_MediaTypesPathClear;
  970. Test_MediaTypesPathReader;
  971. Test_MediaTypesPathParser;
  972. Test_MediaTypesPathFileName;
  973. Test_MediaTypesApacheGetDescription;
  974. Test_MediaTypesNginxGetDescription;
  975. Test_MediaTypesNginxGetFileName;
  976. Test_MediaTypesWindowsGetDescription;
  977. Test_MediaTypesUnixGetDescription;
  978. Test_MediaTypesUnixGetFileName;
  979. Test_MIMECreate;
  980. // Test_MIMEDestroy - not required
  981. Test_MIMEGetProviderClass;
  982. Test_MIMEOpen;
  983. Test_MIMEClose;
  984. Test_MIMETypes;
  985. Test_MIMEActive;
  986. Test_MIMEDefaultType;
  987. Test_MIMEFileName;
  988. Test_MIMEProvider;
  989. finally
  990. DeleteFile(F);
  991. end;
  992. end.