notification_factory_renderer_test.rb 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. require 'test_helper'
  2. class NotificationFactoryRendererTest < ActiveSupport::TestCase
  3. # RSpec incoming!
  4. def described_class
  5. NotificationFactory::Renderer
  6. end
  7. group = Group.new(name: 'Users')
  8. owner = User.new(firstname: 'Owner<b>xxx</b>', lastname: 'Agent1<b>yyy</b>')
  9. current_user = User.new(firstname: 'CurrentUser<b>xxx</b>', lastname: 'Agent2<b>yyy</b>')
  10. state = Ticket::State.new(name: 'new')
  11. ticket = Ticket.new(
  12. id: 1,
  13. title: '<b>Welcome to Zammad!</b>',
  14. group: group,
  15. owner: owner,
  16. state: state,
  17. created_by: current_user,
  18. updated_by: current_user,
  19. created_at: Time.zone.parse('2016-11-12 12:00:00 UTC'),
  20. updated_at: Time.zone.parse('2016-11-12 14:00:00 UTC'),
  21. )
  22. article_html1 = Ticket::Article.new(
  23. body: 'test <b>hello</b><br>some new line',
  24. content_type: 'text/html',
  25. )
  26. article_plain1 = Ticket::Article.new(
  27. body: "test <b>hello</b>\nsome new line",
  28. content_type: 'text/plain',
  29. )
  30. article_plain2 = Ticket::Article.new(
  31. body: "test <b>hello</b>\nsome new line",
  32. )
  33. test 'replace object attribute' do
  34. template = "\#{ticket.title}"
  35. result = described_class.new(
  36. objects: {
  37. ticket: ticket,
  38. },
  39. locale: 'en-us',
  40. timezone: 'Europe/Berlin',
  41. template: template,
  42. ).render
  43. assert_equal(CGI.escapeHTML(ticket.title), result)
  44. template = "\#{ticket.created_at}"
  45. result = described_class.new(
  46. objects: {
  47. ticket: ticket,
  48. },
  49. locale: 'en-us',
  50. timezone: 'Europe/Berlin',
  51. template: template,
  52. ).render
  53. assert_equal('11/12/2016 13:00 (Europe/Berlin)', result)
  54. template = "\#{ticket.created_by.firstname}"
  55. result = described_class.new(
  56. objects: {
  57. ticket: ticket,
  58. },
  59. locale: 'en-us',
  60. timezone: 'Europe/Berlin',
  61. template: template,
  62. ).render
  63. assert_equal('CurrentUser&lt;b&gt;xxx&lt;/b&gt;', result)
  64. template = "\#{ticket.updated_at}"
  65. result = described_class.new(
  66. objects: {
  67. ticket: ticket,
  68. },
  69. locale: 'en-us',
  70. timezone: 'Europe/Berlin',
  71. template: template,
  72. ).render
  73. assert_equal('11/12/2016 15:00 (Europe/Berlin)', result)
  74. template = "\#{ticket.updated_by.firstname}"
  75. result = described_class.new(
  76. objects: {
  77. ticket: ticket,
  78. },
  79. locale: 'en-us',
  80. timezone: 'Europe/Berlin',
  81. template: template,
  82. ).render
  83. assert_equal('CurrentUser&lt;b&gt;xxx&lt;/b&gt;', result)
  84. template = "\#{ticket.owner.firstname}"
  85. result = described_class.new(
  86. objects: {
  87. ticket: ticket,
  88. },
  89. locale: 'en-us',
  90. timezone: 'Europe/Berlin',
  91. template: template,
  92. ).render
  93. assert_equal('Owner&lt;b&gt;xxx&lt;/b&gt;', result)
  94. template = "\#{ticket. title}"
  95. result = described_class.new(
  96. objects: {
  97. ticket: ticket,
  98. },
  99. locale: 'en-us',
  100. timezone: 'Europe/Berlin',
  101. template: template,
  102. ).render
  103. assert_equal(CGI.escapeHTML(ticket.title), result)
  104. template = "\#{ticket.\n title}"
  105. result = described_class.new(
  106. objects: {
  107. ticket: ticket,
  108. },
  109. locale: 'en-us',
  110. timezone: 'Europe/Berlin',
  111. template: template,
  112. ).render
  113. assert_equal(CGI.escapeHTML(ticket.title), result)
  114. template = "\#{ticket.\t title}"
  115. result = described_class.new(
  116. objects: {
  117. ticket: ticket,
  118. },
  119. locale: 'en-us',
  120. timezone: 'Europe/Berlin',
  121. template: template,
  122. ).render
  123. assert_equal(CGI.escapeHTML(ticket.title), result)
  124. template = "\#{ticket.\t\n title\t}"
  125. result = described_class.new(
  126. objects: {
  127. ticket: ticket,
  128. },
  129. locale: 'en-us',
  130. timezone: 'Europe/Berlin',
  131. template: template,
  132. ).render
  133. assert_equal(CGI.escapeHTML(ticket.title), result)
  134. template = "\#{ticket.\" title\t}"
  135. result = described_class.new(
  136. objects: {
  137. ticket: ticket,
  138. },
  139. locale: 'en-us',
  140. timezone: 'Europe/Berlin',
  141. template: template,
  142. ).render
  143. assert_equal(CGI.escapeHTML(ticket.title), result)
  144. template = "\#{<a href=\"/test123\">ticket.\" title</a>}"
  145. result = described_class.new(
  146. objects: {
  147. ticket: ticket,
  148. },
  149. locale: 'en-us',
  150. timezone: 'Europe/Berlin',
  151. template: template,
  152. ).render
  153. assert_equal(CGI.escapeHTML(ticket.title), result)
  154. template = "some test<br>\#{article.body}"
  155. result = described_class.new(
  156. objects: {
  157. article: article_html1,
  158. },
  159. locale: 'en-us',
  160. timezone: 'Europe/Berlin',
  161. template: template,
  162. ).render
  163. assert_equal('some test<br>&gt; test hello<br>&gt; some new line<br>', result)
  164. result = described_class.new(
  165. objects: {
  166. article: article_plain1,
  167. },
  168. locale: 'en-us',
  169. timezone: 'Europe/Berlin',
  170. template: template,
  171. ).render
  172. assert_equal('some test<br>&gt; test &lt;b&gt;hello&lt;/b&gt;<br>&gt; some new line<br>', result)
  173. result = described_class.new(
  174. objects: {
  175. article: article_plain2,
  176. },
  177. locale: 'en-us',
  178. timezone: 'Europe/Berlin',
  179. template: template,
  180. ).render
  181. assert_equal('some test<br>&gt; test &lt;b&gt;hello&lt;/b&gt;<br>&gt; some new line<br>', result)
  182. end
  183. test 'config' do
  184. setting = 'fqdn'
  185. template = "\#{config.#{setting}}"
  186. result = described_class.new(
  187. objects: {
  188. ticket: ticket,
  189. },
  190. locale: 'en-us',
  191. timezone: 'Europe/Berlin',
  192. template: template,
  193. ).render
  194. assert_equal(Setting.get(setting), result)
  195. setting1 = 'fqdn'
  196. setting2 = 'product_name'
  197. template = "some \#{config.#{setting1}} and \#{config.#{setting2}}"
  198. result = described_class.new(
  199. objects: {
  200. ticket: ticket,
  201. },
  202. locale: 'en-us',
  203. timezone: 'Europe/Berlin',
  204. template: template,
  205. ).render
  206. assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
  207. setting1 = 'fqdn'
  208. setting2 = 'product_name'
  209. template = "some \#{ config.#{setting1}} and \#{\tconfig.#{setting2}}"
  210. result = described_class.new(
  211. objects: {
  212. ticket: ticket,
  213. },
  214. locale: 'en-us',
  215. timezone: 'Europe/Berlin',
  216. template: template,
  217. ).render
  218. assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
  219. end
  220. test 'translation' do
  221. #template = "<%= t 'new' %>"
  222. template = "\#{t('new')}"
  223. result = described_class.new(
  224. objects: {
  225. ticket: ticket,
  226. },
  227. locale: 'de-de',
  228. timezone: 'Europe/Berlin',
  229. template: template,
  230. ).render
  231. assert_equal('neu', result)
  232. template = "some text \#{t('new')} and \#{t('open')}"
  233. result = described_class.new(
  234. objects: {
  235. ticket: ticket,
  236. },
  237. locale: 'de-de',
  238. timezone: 'Europe/Berlin',
  239. template: template,
  240. ).render
  241. assert_equal('some text neu and offen', result)
  242. template = "some text \#{t('new') } and \#{ t('open')}"
  243. result = described_class.new(
  244. objects: {
  245. ticket: ticket,
  246. },
  247. locale: 'de-de',
  248. timezone: 'Europe/Berlin',
  249. template: template,
  250. ).render
  251. assert_equal('some text neu and offen', result)
  252. template = "some text \#{\nt('new') } and \#{ t('open')\t}"
  253. result = described_class.new(
  254. objects: {
  255. ticket: ticket,
  256. },
  257. locale: 'de-de',
  258. timezone: 'Europe/Berlin',
  259. template: template,
  260. ).render
  261. assert_equal('some text neu and offen', result)
  262. end
  263. test 'chained function calls' do
  264. template = "\#{t(ticket.state.name)}"
  265. result = described_class.new(
  266. objects: {
  267. ticket: ticket,
  268. },
  269. locale: 'de-de',
  270. timezone: 'Europe/Berlin',
  271. template: template,
  272. ).render
  273. assert_equal('neu', result)
  274. end
  275. test 'not existing object and attribute' do
  276. template = "\#{}"
  277. result = described_class.new(
  278. objects: {
  279. ticket: ticket,
  280. },
  281. locale: 'en-us',
  282. timezone: 'Europe/Berlin',
  283. template: template,
  284. ).render
  285. assert_equal(CGI.escapeHTML('#{no such object}'), result)
  286. template = "\#{notexsiting.notexsiting}"
  287. result = described_class.new(
  288. objects: {
  289. ticket: ticket,
  290. },
  291. locale: 'en-us',
  292. timezone: 'Europe/Berlin',
  293. template: template,
  294. ).render
  295. assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
  296. template = "\#{ticket.notexsiting}"
  297. result = described_class.new(
  298. objects: {
  299. ticket: ticket,
  300. },
  301. locale: 'en-us',
  302. timezone: 'Europe/Berlin',
  303. template: template,
  304. ).render
  305. assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
  306. template = "\#{ticket.}"
  307. result = described_class.new(
  308. objects: {
  309. ticket: ticket,
  310. },
  311. locale: 'en-us',
  312. timezone: 'Europe/Berlin',
  313. template: template,
  314. ).render
  315. assert_equal(CGI.escapeHTML('#{ticket. / no such method}'), result)
  316. template = "\#{ticket.title.notexsiting}"
  317. result = described_class.new(
  318. objects: {
  319. ticket: ticket,
  320. },
  321. locale: 'en-us',
  322. timezone: 'Europe/Berlin',
  323. template: template,
  324. ).render
  325. assert_equal(CGI.escapeHTML('#{ticket.title.notexsiting / no such method}'), result)
  326. template = "\#{ticket.notexsiting.notexsiting}"
  327. result = described_class.new(
  328. objects: {
  329. ticket: ticket,
  330. },
  331. locale: 'en-us',
  332. timezone: 'Europe/Berlin',
  333. template: template,
  334. ).render
  335. assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
  336. template = "\#{notexsiting}"
  337. result = described_class.new(
  338. objects: {
  339. ticket: ticket,
  340. },
  341. locale: 'en-us',
  342. timezone: 'Europe/Berlin',
  343. template: template,
  344. ).render
  345. assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
  346. template = "\#{notexsiting.}"
  347. result = described_class.new(
  348. objects: {
  349. ticket: ticket,
  350. },
  351. locale: 'en-us',
  352. timezone: 'Europe/Berlin',
  353. template: template,
  354. ).render
  355. assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
  356. template = "\#{string}"
  357. result = described_class.new(
  358. objects: {
  359. string: 'some string',
  360. },
  361. locale: 'en-us',
  362. timezone: 'Europe/Berlin',
  363. template: template,
  364. ).render
  365. assert_equal(CGI.escapeHTML('some string'), result)
  366. template = "\#{fixum}"
  367. result = described_class.new(
  368. objects: {
  369. fixum: 123,
  370. },
  371. locale: 'en-us',
  372. timezone: 'Europe/Berlin',
  373. template: template,
  374. ).render
  375. assert_equal(CGI.escapeHTML('123'), result)
  376. template = "\#{float}"
  377. result = described_class.new(
  378. objects: {
  379. float: 123.99,
  380. },
  381. locale: 'en-us',
  382. timezone: 'Europe/Berlin',
  383. template: template,
  384. ).render
  385. assert_equal(CGI.escapeHTML('123.99'), result)
  386. end
  387. test 'data key validation' do
  388. template = "\#{ticket.title `echo 1`}"
  389. result = described_class.new(
  390. objects: {
  391. ticket: ticket,
  392. },
  393. locale: 'en-us',
  394. timezone: 'Europe/Berlin',
  395. template: template,
  396. ).render
  397. assert_equal(CGI.escapeHTML('#{ticket.title`echo1` / not allowed}'), result)
  398. template = "\#{ticket.destroy}"
  399. result = described_class.new(
  400. objects: {
  401. ticket: ticket,
  402. },
  403. locale: 'en-us',
  404. timezone: 'Europe/Berlin',
  405. template: template,
  406. ).render
  407. assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
  408. template = "\#{ticket.save}"
  409. result = described_class.new(
  410. objects: {
  411. ticket: ticket,
  412. },
  413. locale: 'en-us',
  414. timezone: 'Europe/Berlin',
  415. template: template,
  416. ).render
  417. assert_equal(CGI.escapeHTML('#{ticket.save / not allowed}'), result)
  418. template = "\#{ticket.update}"
  419. result = described_class.new(
  420. objects: {
  421. ticket: ticket,
  422. },
  423. locale: 'en-us',
  424. timezone: 'Europe/Berlin',
  425. template: template,
  426. ).render
  427. assert_equal(CGI.escapeHTML('#{ticket.update / not allowed}'), result)
  428. template = "\#{ticket.create}"
  429. result = described_class.new(
  430. objects: {
  431. ticket: ticket,
  432. },
  433. locale: 'en-us',
  434. timezone: 'Europe/Berlin',
  435. template: template,
  436. ).render
  437. assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
  438. template = "\#{ticket.delete}"
  439. result = described_class.new(
  440. objects: {
  441. ticket: ticket,
  442. },
  443. locale: 'en-us',
  444. timezone: 'Europe/Berlin',
  445. template: template,
  446. ).render
  447. assert_equal(CGI.escapeHTML('#{ticket.delete / not allowed}'), result)
  448. template = "\#{ticket.remove}"
  449. result = described_class.new(
  450. objects: {
  451. ticket: ticket,
  452. },
  453. locale: 'en-us',
  454. timezone: 'Europe/Berlin',
  455. template: template,
  456. ).render
  457. assert_equal(CGI.escapeHTML('#{ticket.remove / not allowed}'), result)
  458. template = "\#{ticket.drop}"
  459. result = described_class.new(
  460. objects: {
  461. ticket: ticket,
  462. },
  463. locale: 'en-us',
  464. timezone: 'Europe/Berlin',
  465. template: template,
  466. ).render
  467. assert_equal(CGI.escapeHTML('#{ticket.drop / not allowed}'), result)
  468. template = "\#{ticket.create}"
  469. result = described_class.new(
  470. objects: {
  471. ticket: ticket,
  472. },
  473. locale: 'en-us',
  474. timezone: 'Europe/Berlin',
  475. template: template,
  476. ).render
  477. assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
  478. template = "\#{ticket.new}"
  479. result = described_class.new(
  480. objects: {
  481. ticket: ticket,
  482. },
  483. locale: 'en-us',
  484. timezone: 'Europe/Berlin',
  485. template: template,
  486. ).render
  487. assert_equal(CGI.escapeHTML('#{ticket.new / not allowed}'), result)
  488. template = "\#{ticket.update_att}"
  489. result = described_class.new(
  490. objects: {
  491. ticket: ticket,
  492. },
  493. locale: 'en-us',
  494. timezone: 'Europe/Berlin',
  495. template: template,
  496. ).render
  497. assert_equal(CGI.escapeHTML('#{ticket.update_att / not allowed}'), result)
  498. template = "\#{ticket.all}"
  499. result = described_class.new(
  500. objects: {
  501. ticket: ticket,
  502. },
  503. locale: 'en-us',
  504. timezone: 'Europe/Berlin',
  505. template: template,
  506. ).render
  507. assert_equal(CGI.escapeHTML('#{ticket.all / not allowed}'), result)
  508. template = "\#{ticket.find}"
  509. result = described_class.new(
  510. objects: {
  511. ticket: ticket,
  512. },
  513. locale: 'en-us',
  514. timezone: 'Europe/Berlin',
  515. template: template,
  516. ).render
  517. assert_equal(CGI.escapeHTML('#{ticket.find / not allowed}'), result)
  518. template = "\#{ticket.where}"
  519. result = described_class.new(
  520. objects: {
  521. ticket: ticket,
  522. },
  523. locale: 'en-us',
  524. timezone: 'Europe/Berlin',
  525. template: template,
  526. ).render
  527. assert_equal(CGI.escapeHTML('#{ticket.where / not allowed}'), result)
  528. template = "\#{ticket. destroy}"
  529. result = described_class.new(
  530. objects: {
  531. ticket: ticket,
  532. },
  533. locale: 'en-us',
  534. timezone: 'Europe/Berlin',
  535. template: template,
  536. ).render
  537. assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
  538. template = "\#{ticket.\n destroy}"
  539. result = described_class.new(
  540. objects: {
  541. ticket: ticket,
  542. },
  543. locale: 'en-us',
  544. timezone: 'Europe/Berlin',
  545. template: template,
  546. ).render
  547. assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
  548. template = "\#{ticket.\t destroy}"
  549. result = described_class.new(
  550. objects: {
  551. ticket: ticket,
  552. },
  553. locale: 'en-us',
  554. timezone: 'Europe/Berlin',
  555. template: template,
  556. ).render
  557. assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
  558. template = "\#{ticket.\r destroy}"
  559. result = described_class.new(
  560. objects: {
  561. ticket: ticket,
  562. },
  563. locale: 'en-us',
  564. timezone: 'Europe/Berlin',
  565. template: template,
  566. ).render
  567. assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
  568. end
  569. test 'methods with single Integer parameter' do
  570. template = "\#{ticket.title.first(3)}"
  571. result = described_class.new(
  572. objects: {
  573. ticket: ticket,
  574. },
  575. locale: 'en-us',
  576. timezone: 'Europe/Berlin',
  577. template: template,
  578. ).render
  579. assert_equal(CGI.escapeHTML('<b>'), result)
  580. template = "\#{ticket.title.last(4)}"
  581. result = described_class.new(
  582. objects: {
  583. ticket: ticket,
  584. },
  585. locale: 'en-us',
  586. timezone: 'Europe/Berlin',
  587. template: template,
  588. ).render
  589. assert_equal(CGI.escapeHTML('</b>'), result)
  590. template = "\#{ticket.title.slice(3, 4)}"
  591. result = described_class.new(
  592. objects: {
  593. ticket: ticket,
  594. },
  595. locale: 'en-us',
  596. timezone: 'Europe/Berlin',
  597. template: template,
  598. ).render
  599. assert_equal(CGI.escapeHTML("\#{ticket.title.slice(3,4) / invalid parameter: 3,4}"), result)
  600. template = "\#{ticket.title.first('some invalid parameter')}"
  601. result = described_class.new(
  602. objects: {
  603. ticket: ticket,
  604. },
  605. locale: 'en-us',
  606. timezone: 'Europe/Berlin',
  607. template: template,
  608. ).render
  609. assert_equal("\#{ticket.title.first(someinvalidparameter) / invalid parameter: someinvalidparameter}", result)
  610. template = "\#{ticket.title.chomp(`cat /etc/passwd`)}"
  611. result = described_class.new(
  612. objects: {
  613. ticket: ticket,
  614. },
  615. locale: 'en-us',
  616. timezone: 'Europe/Berlin',
  617. template: template,
  618. ).render
  619. assert_equal("\#{ticket.title.chomp(`cat/etc/passwd`) / not allowed}", result)
  620. end
  621. end