@openmrs/esm-billing-app 1.1.2-pre.9 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/.turbo/cache/31f1dfc7f71601df-meta.json +1 -0
  2. package/.turbo/cache/31f1dfc7f71601df.tar.zst +0 -0
  3. package/.turbo/turbo-build.log +13 -42
  4. package/__mocks__/bills.mock.ts +3 -2
  5. package/dist/1480.js +1 -0
  6. package/dist/1480.js.map +1 -0
  7. package/dist/1564.js +1 -0
  8. package/dist/1564.js.map +1 -0
  9. package/dist/1578.js +1 -0
  10. package/dist/1578.js.map +1 -0
  11. package/dist/1646.js +1 -0
  12. package/dist/1646.js.map +1 -0
  13. package/dist/1869.js +1 -0
  14. package/dist/1869.js.map +1 -0
  15. package/dist/1877.js +1 -0
  16. package/dist/1877.js.map +1 -0
  17. package/dist/1899.js +1 -0
  18. package/dist/1899.js.map +1 -0
  19. package/dist/196.js +2 -0
  20. package/dist/196.js.map +1 -0
  21. package/dist/2250.js +43 -0
  22. package/dist/2250.js.map +1 -0
  23. package/dist/2269.js +1 -0
  24. package/dist/2269.js.map +1 -0
  25. package/dist/2317.js +1 -0
  26. package/dist/2317.js.map +1 -0
  27. package/dist/2416.js +1 -0
  28. package/dist/2416.js.map +1 -0
  29. package/dist/2489.js +1 -0
  30. package/dist/2489.js.map +1 -0
  31. package/dist/282.js +1 -0
  32. package/dist/282.js.map +1 -0
  33. package/dist/2881.js +1 -0
  34. package/dist/2881.js.map +1 -0
  35. package/dist/2997.js +1 -0
  36. package/dist/2997.js.map +1 -0
  37. package/dist/3378.js +1 -0
  38. package/dist/3378.js.map +1 -0
  39. package/dist/3379.js +1 -0
  40. package/dist/3379.js.map +1 -0
  41. package/dist/3784.js +1 -0
  42. package/dist/3784.js.map +1 -0
  43. package/dist/3963.js +1 -0
  44. package/dist/3963.js.map +1 -0
  45. package/dist/4106.js +1 -0
  46. package/dist/4106.js.map +1 -0
  47. package/dist/4111.js +1 -0
  48. package/dist/4111.js.map +1 -0
  49. package/dist/434.js +1 -0
  50. package/dist/434.js.map +1 -0
  51. package/dist/4348.js +1 -0
  52. package/dist/4348.js.map +1 -0
  53. package/dist/4383.js +1 -0
  54. package/dist/4383.js.map +1 -0
  55. package/dist/4658.js +1 -0
  56. package/dist/4658.js.map +1 -0
  57. package/dist/4870.js +1 -0
  58. package/dist/4870.js.map +1 -0
  59. package/dist/4928.js +1 -0
  60. package/dist/4928.js.map +1 -0
  61. package/dist/5098.js +1 -0
  62. package/dist/5098.js.map +1 -0
  63. package/dist/5117.js +1 -0
  64. package/dist/5117.js.map +1 -0
  65. package/dist/5132.js +1 -0
  66. package/dist/5132.js.map +1 -0
  67. package/dist/5145.js +1 -0
  68. package/dist/5145.js.map +1 -0
  69. package/dist/5390.js +1 -0
  70. package/dist/5390.js.map +1 -0
  71. package/dist/5503.js +1 -0
  72. package/dist/5503.js.map +1 -0
  73. package/dist/556.js +1 -0
  74. package/dist/556.js.map +1 -0
  75. package/dist/5644.js +1 -0
  76. package/dist/5644.js.map +1 -0
  77. package/dist/5898.js +1 -0
  78. package/dist/5898.js.map +1 -0
  79. package/dist/5940.js +1 -0
  80. package/dist/5940.js.map +1 -0
  81. package/dist/6047.js +1 -0
  82. package/dist/6047.js.map +1 -0
  83. package/dist/6237.js +1 -0
  84. package/dist/6237.js.map +1 -0
  85. package/dist/6362.js +1 -0
  86. package/dist/6362.js.map +1 -0
  87. package/dist/6371.js +1 -0
  88. package/dist/6371.js.map +1 -0
  89. package/dist/6377.js +1 -0
  90. package/dist/6377.js.map +1 -0
  91. package/dist/6444.js +1 -0
  92. package/dist/6444.js.map +1 -0
  93. package/dist/6508.js +1 -0
  94. package/dist/6508.js.map +1 -0
  95. package/dist/6594.js +1 -0
  96. package/dist/6594.js.map +1 -0
  97. package/dist/6724.js +1 -0
  98. package/dist/6724.js.map +1 -0
  99. package/dist/6904.js +1 -0
  100. package/dist/6904.js.map +1 -0
  101. package/dist/7045.js +1 -0
  102. package/dist/7045.js.map +1 -0
  103. package/dist/7175.js +1 -0
  104. package/dist/7175.js.map +1 -0
  105. package/dist/7182.js +1 -0
  106. package/dist/7182.js.map +1 -0
  107. package/dist/7247.js +1 -0
  108. package/dist/7247.js.map +1 -0
  109. package/dist/7742.js +1 -0
  110. package/dist/7742.js.map +1 -0
  111. package/dist/7912.js +1 -0
  112. package/dist/7912.js.map +1 -0
  113. package/dist/8358.js +1 -0
  114. package/dist/8358.js.map +1 -0
  115. package/dist/8359.js +1 -0
  116. package/dist/8359.js.map +1 -0
  117. package/dist/8695.js +1 -0
  118. package/dist/8695.js.map +1 -0
  119. package/dist/903.js +1 -0
  120. package/dist/903.js.map +1 -0
  121. package/dist/9072.js +1 -0
  122. package/dist/9072.js.map +1 -0
  123. package/dist/9414.js +1 -0
  124. package/dist/9414.js.map +1 -0
  125. package/dist/9655.js +11 -0
  126. package/dist/9655.js.map +1 -0
  127. package/dist/9806.js +1 -0
  128. package/dist/9806.js.map +1 -0
  129. package/dist/990.js +1 -0
  130. package/dist/990.js.map +1 -0
  131. package/dist/main.js +17 -2
  132. package/dist/main.js.map +1 -1
  133. package/dist/openmrs-esm-billing-app.js +6 -1
  134. package/dist/openmrs-esm-billing-app.js.buildmanifest.json +643 -436
  135. package/dist/openmrs-esm-billing-app.js.map +1 -1
  136. package/dist/routes.json +1 -1
  137. package/e2e/commands/billing-operations.ts +21 -0
  138. package/e2e/commands/types.ts +9 -1
  139. package/e2e/pages/discounts-page.ts +75 -0
  140. package/e2e/pages/index.ts +1 -0
  141. package/e2e/pages/invoice-page.ts +7 -7
  142. package/e2e/specs/bill-discounts.spec.ts +255 -0
  143. package/e2e/specs/billing-dashboard.spec.ts +3 -3
  144. package/e2e/specs/billing-patient-chart.spec.ts +2 -2
  145. package/package.json +13 -22
  146. package/rspack.config.js +1 -0
  147. package/src/bill-history/bill-action-menu.component.tsx +20 -2
  148. package/src/bill-history/bill-history.test.tsx +23 -22
  149. package/src/bill-item-actions/edit-bill-item.modal.tsx +1 -1
  150. package/src/bill-item-actions/edit-bill-item.test.tsx +29 -27
  151. package/src/billable-services/billable-service-form/billable-service-form.test.tsx +74 -73
  152. package/src/billable-services/billable-services-home.component.tsx +4 -2
  153. package/src/billable-services/billable-services.test.tsx +8 -7
  154. package/src/billable-services/dashboard/dashboard.test.tsx +3 -2
  155. package/src/billable-services-admin-card-link.test.tsx +2 -1
  156. package/src/billing-dashboard/billing-dashboard.test.tsx +19 -3
  157. package/src/billing-form/billing-checkin-form.component.tsx +7 -3
  158. package/src/billing-form/billing-checkin-form.test.tsx +22 -21
  159. package/src/billing-form/billing-form.resource.test.ts +7 -6
  160. package/src/billing-form/billing-form.test.tsx +77 -40
  161. package/src/billing-form/billing-form.workspace.tsx +25 -6
  162. package/src/billing-form/visit-attributes/visit-attributes-form.component.tsx +6 -2
  163. package/src/billing.resource.test.ts +43 -41
  164. package/src/billing.resource.ts +65 -16
  165. package/src/bills-table/bills-table.component.tsx +15 -4
  166. package/src/bills-table/bills-table.test.tsx +72 -71
  167. package/src/config-schema.ts +0 -7
  168. package/src/discounts/admin/discount-requests-left-panel-link.component.tsx +43 -0
  169. package/src/discounts/admin/discount-requests.component.tsx +316 -0
  170. package/src/discounts/admin/discount-requests.scss +133 -0
  171. package/src/discounts/admin/discount-requests.test.tsx +104 -0
  172. package/src/discounts/admin/review-bill-discounts/bill-line-items-table/bill-line-items-table.component.tsx +42 -0
  173. package/src/discounts/admin/review-bill-discounts/bill-line-items-table/bill-line-items-table.scss +76 -0
  174. package/src/discounts/admin/review-bill-discounts/bill-payments-table/bill-payments-table.component.tsx +50 -0
  175. package/src/discounts/admin/review-bill-discounts/bill-payments-table/bill-payments-table.scss +63 -0
  176. package/src/discounts/admin/review-bill-discounts/bill-receipt-rail/bill-receipt-rail.component.tsx +73 -0
  177. package/src/discounts/admin/review-bill-discounts/bill-receipt-rail/bill-receipt-rail.scss +54 -0
  178. package/src/discounts/admin/review-bill-discounts/bill-totals-summary/bill-totals-summary.component.tsx +95 -0
  179. package/src/discounts/admin/review-bill-discounts/bill-totals-summary/bill-totals-summary.scss +128 -0
  180. package/src/discounts/admin/review-bill-discounts/discount-card/discount-card.component.tsx +158 -0
  181. package/src/discounts/admin/review-bill-discounts/discount-card/discount-card.scss +164 -0
  182. package/src/discounts/admin/review-bill-discounts/discount-review-stack/discount-review-stack.component.tsx +86 -0
  183. package/src/discounts/admin/review-bill-discounts/discount-review-stack/discount-review-stack.scss +40 -0
  184. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.modal.scss +14 -0
  185. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.modal.test.tsx +153 -0
  186. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.modal.tsx +167 -0
  187. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.utils.ts +42 -0
  188. package/src/discounts/discounts-table.component.tsx +109 -0
  189. package/src/discounts/discounts-table.scss +37 -0
  190. package/src/discounts/discounts-table.test.tsx +67 -0
  191. package/src/discounts/discounts.resource.ts +71 -0
  192. package/src/discounts/request-discount.modal.scss +88 -0
  193. package/src/discounts/request-discount.modal.test.tsx +161 -0
  194. package/src/discounts/request-discount.modal.tsx +253 -0
  195. package/src/index.ts +52 -21
  196. package/src/invoice/invoice-table.component.tsx +116 -18
  197. package/src/invoice/invoice-table.test.tsx +165 -13
  198. package/src/invoice/invoice.component.tsx +111 -7
  199. package/src/invoice/invoice.test.tsx +366 -66
  200. package/src/invoice/line-item-action-menu.component.tsx +31 -1
  201. package/src/invoice/payments/payment-form/payment-form.test.tsx +20 -19
  202. package/src/invoice/payments/payment-history/payment-history.test.tsx +13 -10
  203. package/src/invoice/payments/payments.component.tsx +20 -6
  204. package/src/invoice/payments/payments.test.tsx +88 -23
  205. package/src/invoice/printable-invoice/print-receipt.test.tsx +10 -28
  206. package/src/invoice/printable-invoice/printable-footer.test.tsx +5 -4
  207. package/src/invoice/printable-invoice/printable-invoice-header.component.tsx +3 -3
  208. package/src/invoice/printable-invoice/printable-invoice-header.test.tsx +26 -11
  209. package/src/invoice/printable-invoice/printable-invoice.component.tsx +38 -15
  210. package/src/left-panel-link.test.tsx +3 -3
  211. package/src/metrics-cards/metrics-cards.test.tsx +11 -10
  212. package/src/modal/delete-bill-confirmation.modal.test.tsx +134 -0
  213. package/src/modal/delete-bill-confirmation.modal.tsx +98 -0
  214. package/src/modal/delete-line-item-confirmation.modal.test.tsx +11 -9
  215. package/src/modal/finalize-bill-confirmation.modal.test.tsx +10 -8
  216. package/src/modal/require-payment-modal.test.tsx +12 -11
  217. package/src/payment-status-tag/payment-status-tag.component.tsx +50 -0
  218. package/src/payment-status-tag/payment-status-tag.scss +6 -0
  219. package/src/payment-status-tag/payment-status-tag.test.tsx +113 -0
  220. package/src/refunds/admin/refund-requests-left-panel-link.component.tsx +43 -0
  221. package/src/refunds/admin/refund-requests.component.tsx +324 -0
  222. package/src/refunds/admin/refund-requests.scss +133 -0
  223. package/src/refunds/admin/refund-requests.test.tsx +99 -0
  224. package/src/refunds/admin/review-bill-refunds/bill-line-items-table/bill-line-items-table.component.tsx +42 -0
  225. package/src/refunds/admin/review-bill-refunds/bill-line-items-table/bill-line-items-table.scss +76 -0
  226. package/src/refunds/admin/review-bill-refunds/bill-payments-table/bill-payments-table.component.tsx +50 -0
  227. package/src/refunds/admin/review-bill-refunds/bill-payments-table/bill-payments-table.scss +63 -0
  228. package/src/refunds/admin/review-bill-refunds/bill-receipt-rail/bill-receipt-rail.component.tsx +84 -0
  229. package/src/refunds/admin/review-bill-refunds/bill-receipt-rail/bill-receipt-rail.scss +54 -0
  230. package/src/refunds/admin/review-bill-refunds/bill-totals-summary/bill-totals-summary.component.tsx +83 -0
  231. package/src/refunds/admin/review-bill-refunds/bill-totals-summary/bill-totals-summary.scss +65 -0
  232. package/src/refunds/admin/review-bill-refunds/refund-card/refund-card.component.tsx +170 -0
  233. package/src/refunds/admin/review-bill-refunds/refund-card/refund-card.scss +155 -0
  234. package/src/refunds/admin/review-bill-refunds/refund-review-stack/refund-review-stack.component.tsx +86 -0
  235. package/src/refunds/admin/review-bill-refunds/refund-review-stack/refund-review-stack.scss +40 -0
  236. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.modal.scss +14 -0
  237. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.modal.test.tsx +313 -0
  238. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.modal.tsx +188 -0
  239. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.utils.ts +66 -0
  240. package/src/refunds/refunds-table.component.tsx +137 -0
  241. package/src/refunds/refunds-table.scss +37 -0
  242. package/src/refunds/refunds-table.test.tsx +105 -0
  243. package/src/refunds/refunds.resource.test.ts +44 -0
  244. package/src/refunds/refunds.resource.ts +42 -0
  245. package/src/refunds/refunds.types.test.ts +15 -0
  246. package/src/refunds/request-refund.modal.scss +84 -0
  247. package/src/refunds/request-refund.modal.test.tsx +204 -0
  248. package/src/refunds/request-refund.modal.tsx +218 -0
  249. package/src/routes.json +36 -2
  250. package/src/types/index.ts +116 -1
  251. package/src/visit-bills/visit-bills-panel.component.tsx +151 -0
  252. package/src/visit-bills/visit-bills-panel.scss +31 -0
  253. package/src/visit-bills/visit-bills-panel.test.tsx +113 -0
  254. package/tools/empty-module.ts +1 -0
  255. package/tools/setup-tests.ts +9 -9
  256. package/translations/am.json +154 -16
  257. package/translations/ar.json +154 -16
  258. package/translations/ar_SY.json +154 -16
  259. package/translations/bn.json +154 -16
  260. package/translations/cs.json +154 -16
  261. package/translations/de.json +154 -16
  262. package/translations/en.json +154 -16
  263. package/translations/en_US.json +154 -16
  264. package/translations/es.json +154 -16
  265. package/translations/es_MX.json +154 -16
  266. package/translations/fr.json +154 -16
  267. package/translations/he.json +154 -16
  268. package/translations/hi.json +154 -16
  269. package/translations/hi_IN.json +154 -16
  270. package/translations/id.json +154 -16
  271. package/translations/it.json +154 -16
  272. package/translations/ka.json +154 -16
  273. package/translations/km.json +154 -16
  274. package/translations/ku.json +154 -16
  275. package/translations/ky.json +154 -16
  276. package/translations/lg.json +154 -16
  277. package/translations/ne.json +154 -16
  278. package/translations/pl.json +154 -16
  279. package/translations/pt.json +154 -16
  280. package/translations/pt_BR.json +154 -16
  281. package/translations/qu.json +154 -16
  282. package/translations/ro_RO.json +154 -16
  283. package/translations/ru_RU.json +154 -16
  284. package/translations/si.json +154 -16
  285. package/translations/sq.json +154 -16
  286. package/translations/sw.json +154 -16
  287. package/translations/sw_KE.json +154 -16
  288. package/translations/tr.json +154 -16
  289. package/translations/tr_TR.json +154 -16
  290. package/translations/uk.json +154 -16
  291. package/translations/uz.json +154 -16
  292. package/translations/uz@Latn.json +154 -16
  293. package/translations/uz_UZ.json +154 -16
  294. package/translations/vi.json +154 -16
  295. package/translations/zh.json +154 -16
  296. package/translations/zh_CN.json +179 -41
  297. package/translations/zh_TW.json +154 -16
  298. package/tsconfig.json +3 -3
  299. package/vitest.config.js +28 -0
  300. package/.turbo/cache/4e30f71f570fc412-meta.json +0 -1
  301. package/.turbo/cache/4e30f71f570fc412.tar.zst +0 -0
  302. package/dist/1119.js +0 -1
  303. package/dist/1197.js +0 -1
  304. package/dist/1435.js +0 -1
  305. package/dist/1435.js.map +0 -1
  306. package/dist/1807.js +0 -1
  307. package/dist/1807.js.map +0 -1
  308. package/dist/2146.js +0 -1
  309. package/dist/2177.js +0 -2
  310. package/dist/2177.js.LICENSE.txt +0 -9
  311. package/dist/2177.js.map +0 -1
  312. package/dist/2690.js +0 -1
  313. package/dist/2704.js +0 -1
  314. package/dist/2704.js.map +0 -1
  315. package/dist/3002.js +0 -1
  316. package/dist/3002.js.map +0 -1
  317. package/dist/3041.js +0 -1
  318. package/dist/3041.js.map +0 -1
  319. package/dist/3099.js +0 -1
  320. package/dist/3184.js +0 -2
  321. package/dist/3184.js.LICENSE.txt +0 -14
  322. package/dist/3184.js.map +0 -1
  323. package/dist/3584.js +0 -1
  324. package/dist/4055.js +0 -1
  325. package/dist/4132.js +0 -1
  326. package/dist/4225.js +0 -1
  327. package/dist/4225.js.map +0 -1
  328. package/dist/4300.js +0 -1
  329. package/dist/4335.js +0 -1
  330. package/dist/439.js +0 -1
  331. package/dist/4618.js +0 -1
  332. package/dist/4652.js +0 -1
  333. package/dist/4944.js +0 -1
  334. package/dist/5173.js +0 -1
  335. package/dist/5241.js +0 -1
  336. package/dist/5422.js +0 -1
  337. package/dist/5422.js.map +0 -1
  338. package/dist/5442.js +0 -1
  339. package/dist/5661.js +0 -1
  340. package/dist/6022.js +0 -1
  341. package/dist/6404.js +0 -1
  342. package/dist/6404.js.map +0 -1
  343. package/dist/6468.js +0 -1
  344. package/dist/6540.js +0 -2
  345. package/dist/6540.js.LICENSE.txt +0 -9
  346. package/dist/6540.js.map +0 -1
  347. package/dist/6589.js +0 -1
  348. package/dist/6606.js +0 -1
  349. package/dist/6606.js.map +0 -1
  350. package/dist/6679.js +0 -1
  351. package/dist/6792.js +0 -1
  352. package/dist/6792.js.map +0 -1
  353. package/dist/6840.js +0 -1
  354. package/dist/6859.js +0 -1
  355. package/dist/7097.js +0 -1
  356. package/dist/7159.js +0 -1
  357. package/dist/723.js +0 -1
  358. package/dist/7255.js +0 -1
  359. package/dist/7255.js.map +0 -1
  360. package/dist/7617.js +0 -1
  361. package/dist/795.js +0 -1
  362. package/dist/8163.js +0 -1
  363. package/dist/8341.js +0 -2
  364. package/dist/8341.js.LICENSE.txt +0 -52
  365. package/dist/8341.js.map +0 -1
  366. package/dist/8349.js +0 -1
  367. package/dist/8371.js +0 -1
  368. package/dist/8421.js +0 -1
  369. package/dist/8421.js.map +0 -1
  370. package/dist/8618.js +0 -1
  371. package/dist/890.js +0 -1
  372. package/dist/9214.js +0 -1
  373. package/dist/9538.js +0 -1
  374. package/dist/9569.js +0 -1
  375. package/dist/961.js +0 -2
  376. package/dist/961.js.LICENSE.txt +0 -19
  377. package/dist/961.js.map +0 -1
  378. package/dist/986.js +0 -1
  379. package/dist/9879.js +0 -1
  380. package/dist/9895.js +0 -1
  381. package/dist/9900.js +0 -1
  382. package/dist/9913.js +0 -1
  383. package/dist/main.js.LICENSE.txt +0 -62
  384. package/src/billable-services/bill-waiver/bill-selection.component.tsx +0 -76
  385. package/src/billable-services/bill-waiver/bill-waiver-form.component.tsx +0 -107
  386. package/src/billable-services/bill-waiver/bill-waiver-form.scss +0 -34
  387. package/src/billable-services/bill-waiver/bill-waiver.component.tsx +0 -34
  388. package/src/billable-services/bill-waiver/bill-waiver.scss +0 -10
  389. package/src/billable-services/bill-waiver/patient-bills.component.tsx +0 -134
  390. package/webpack.config.js +0 -1
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { describe, expect, it, vi } from 'vitest';
2
3
  import userEvent from '@testing-library/user-event';
3
4
  import { render, screen, waitFor } from '@testing-library/react';
4
5
  import { type Workspace2DefinitionProps, type FetchResponse } from '@openmrs/esm-framework';
@@ -18,20 +19,20 @@ import BillableServiceFormWorkspace, {
18
19
  } from './billable-service-form.workspace';
19
20
  import type { BillableService } from '../../types';
20
21
 
21
- const mockUseBillableServices = jest.mocked(useBillableServices);
22
- const mockUsePaymentModes = jest.mocked(usePaymentModes);
23
- const mockUseServiceTypes = jest.mocked(useServiceTypes);
24
- const mockCreateBillableService = jest.mocked(createBillableService);
25
- const mockUpdateBillableService = jest.mocked(updateBillableService);
26
- const mockUseConceptsSearch = jest.mocked(useConceptsSearch);
27
-
28
- jest.mock('../billable-service.resource', () => ({
29
- useBillableServices: jest.fn(),
30
- usePaymentModes: jest.fn(),
31
- useServiceTypes: jest.fn(),
32
- createBillableService: jest.fn(),
33
- updateBillableService: jest.fn(),
34
- useConceptsSearch: jest.fn(),
22
+ const mockUseBillableServices = vi.mocked(useBillableServices);
23
+ const mockUsePaymentModes = vi.mocked(usePaymentModes);
24
+ const mockUseServiceTypes = vi.mocked(useServiceTypes);
25
+ const mockCreateBillableService = vi.mocked(createBillableService);
26
+ const mockUpdateBillableService = vi.mocked(updateBillableService);
27
+ const mockUseConceptsSearch = vi.mocked(useConceptsSearch);
28
+
29
+ vi.mock('../billable-service.resource', () => ({
30
+ useBillableServices: vi.fn(),
31
+ usePaymentModes: vi.fn(),
32
+ useServiceTypes: vi.fn(),
33
+ createBillableService: vi.fn(),
34
+ updateBillableService: vi.fn(),
35
+ useConceptsSearch: vi.fn(),
35
36
  }));
36
37
 
37
38
  const mockPaymentModes = [
@@ -66,14 +67,14 @@ const setupMocks = () => {
66
67
  billableServices: [],
67
68
  isLoading: false,
68
69
  error: null,
69
- mutate: jest.fn(),
70
+ mutate: vi.fn(),
70
71
  isValidating: false,
71
72
  });
72
73
  mockUsePaymentModes.mockReturnValue({
73
74
  paymentModes: mockPaymentModes,
74
75
  error: null,
75
76
  isLoadingPaymentModes: false,
76
- mutate: jest.fn(),
77
+ mutate: vi.fn(),
77
78
  });
78
79
  mockUseServiceTypes.mockReturnValue({ serviceTypes: mockServiceTypes, error: false, isLoadingServiceTypes: false });
79
80
  mockUseConceptsSearch.mockReturnValue({ searchResults: [], isSearching: false, error: null });
@@ -82,7 +83,7 @@ const setupMocks = () => {
82
83
  const renderBillableServicesForm = (
83
84
  props: Partial<Workspace2DefinitionProps<Partial<BillableServiceFormWorkspaceProps>>> = {},
84
85
  ) => {
85
- const closeWorkspace = props.closeWorkspace || jest.fn();
86
+ const closeWorkspace = props.closeWorkspace || vi.fn();
86
87
  const workspaceProps: BillableServiceFormWorkspaceProps = {
87
88
  serviceToEdit: props.workspaceProps?.serviceToEdit,
88
89
  closeWorkspaceWithSavedChanges: props.workspaceProps?.closeWorkspaceWithSavedChanges,
@@ -98,7 +99,7 @@ const renderBillableServicesForm = (
98
99
  groupProps: props.groupProps || {},
99
100
  windowProps: props.windowProps || {},
100
101
  workspaceName: props.workspaceName || 'billable-service-form-workspace',
101
- launchChildWorkspace: jest.fn(),
102
+ launchChildWorkspace: vi.fn(),
102
103
  windowName: 'billable-service-form-window',
103
104
  isRootWorkspace: false,
104
105
  showActionMenu: true,
@@ -142,9 +143,9 @@ const submitForm = async () => {
142
143
  };
143
144
 
144
145
  describe('BillableServiceFormWorkspace', () => {
145
- test('should render billable services form and generate correct payload', async () => {
146
+ it('should render billable services form and generate correct payload', async () => {
146
147
  const user = userEvent.setup();
147
- const mockCloseWorkspace = jest.fn();
148
+ const mockCloseWorkspace = vi.fn();
148
149
  renderBillableServicesForm({ closeWorkspace: mockCloseWorkspace });
149
150
 
150
151
  await fillRequiredFields(user);
@@ -170,9 +171,9 @@ describe('BillableServiceFormWorkspace', () => {
170
171
  });
171
172
 
172
173
  describe('Workspace Interactions', () => {
173
- test('should call closeWorkspace when Cancel button is clicked', async () => {
174
+ it('should call closeWorkspace when Cancel button is clicked', async () => {
174
175
  const user = userEvent.setup();
175
- const mockCloseWorkspace = jest.fn();
176
+ const mockCloseWorkspace = vi.fn();
176
177
  renderBillableServicesForm({ closeWorkspace: mockCloseWorkspace });
177
178
 
178
179
  const cancelButton = screen.getByRole('button', { name: /cancel/i });
@@ -181,9 +182,9 @@ describe('BillableServiceFormWorkspace', () => {
181
182
  expect(mockCloseWorkspace).toHaveBeenCalledTimes(1);
182
183
  });
183
184
 
184
- test('should call closeWorkspaceWithSavedChanges after successful save', async () => {
185
+ it('should call closeWorkspaceWithSavedChanges after successful save', async () => {
185
186
  const user = userEvent.setup();
186
- const mockCloseWorkspaceWithSavedChanges = jest.fn();
187
+ const mockCloseWorkspaceWithSavedChanges = vi.fn();
187
188
  renderBillableServicesForm({
188
189
  workspaceProps: { closeWorkspaceWithSavedChanges: mockCloseWorkspaceWithSavedChanges },
189
190
  });
@@ -197,7 +198,7 @@ describe('BillableServiceFormWorkspace', () => {
197
198
  });
198
199
  });
199
200
 
200
- test('should disable buttons during submission', async () => {
201
+ it('should disable buttons during submission', async () => {
201
202
  const user = userEvent.setup();
202
203
  let resolveCreate: (value: any) => void;
203
204
  const createPromise = new Promise((resolve) => {
@@ -224,7 +225,7 @@ describe('BillableServiceFormWorkspace', () => {
224
225
  });
225
226
  });
226
227
 
227
- test('should show loading indicator in save button during submission', async () => {
228
+ it('should show loading indicator in save button during submission', async () => {
228
229
  const user = userEvent.setup();
229
230
  let resolveCreate: (value: any) => void;
230
231
  const createPromise = new Promise((resolve) => {
@@ -249,8 +250,8 @@ describe('BillableServiceFormWorkspace', () => {
249
250
  });
250
251
  });
251
252
 
252
- test('should call onWorkspaceClose callback after successful edit', async () => {
253
- const mockOnWorkspaceClose = jest.fn();
253
+ it('should call onWorkspaceClose callback after successful edit', async () => {
254
+ const mockOnWorkspaceClose = vi.fn();
254
255
  const mockServiceToEdit: BillableService = {
255
256
  uuid: 'test-uuid',
256
257
  name: 'Test Service',
@@ -289,7 +290,7 @@ describe('BillableServiceFormWorkspace', () => {
289
290
  });
290
291
 
291
292
  describe('Form Validation', () => {
292
- test('should accept form submission without short name (short name is optional)', async () => {
293
+ it('should accept form submission without short name (short name is optional)', async () => {
293
294
  const user = userEvent.setup();
294
295
  renderBillableServicesForm();
295
296
 
@@ -317,7 +318,7 @@ describe('BillableServiceFormWorkspace', () => {
317
318
  );
318
319
  });
319
320
 
320
- test('should trim leading and trailing whitespace from service name and short name', async () => {
321
+ it('should trim leading and trailing whitespace from service name and short name', async () => {
321
322
  const user = userEvent.setup();
322
323
  renderBillableServicesForm();
323
324
 
@@ -347,7 +348,7 @@ describe('BillableServiceFormWorkspace', () => {
347
348
  );
348
349
  });
349
350
 
350
- test('should enforce 255 character limit on service name input', async () => {
351
+ it('should enforce 255 character limit on service name input', async () => {
351
352
  const user = userEvent.setup();
352
353
  renderBillableServicesForm();
353
354
 
@@ -359,7 +360,7 @@ describe('BillableServiceFormWorkspace', () => {
359
360
  expect(input).toHaveValue('A'.repeat(255));
360
361
  });
361
362
 
362
- test('should enforce 255 character limit on short name input', async () => {
363
+ it('should enforce 255 character limit on short name input', async () => {
363
364
  const user = userEvent.setup();
364
365
  renderBillableServicesForm();
365
366
 
@@ -371,7 +372,7 @@ describe('BillableServiceFormWorkspace', () => {
371
372
  expect(input).toHaveValue('B'.repeat(255));
372
373
  });
373
374
 
374
- test('should show "Price must be greater than 0" error for zero price', async () => {
375
+ it('should show "Price must be greater than 0" error for zero price', async () => {
375
376
  const user = userEvent.setup();
376
377
  renderBillableServicesForm();
377
378
 
@@ -386,7 +387,7 @@ describe('BillableServiceFormWorkspace', () => {
386
387
  expect(mockCreateBillableService).not.toHaveBeenCalled();
387
388
  });
388
389
 
389
- test('should show "Price must be greater than 0" error for negative price', async () => {
390
+ it('should show "Price must be greater than 0" error for negative price', async () => {
390
391
  const user = userEvent.setup();
391
392
  renderBillableServicesForm();
392
393
 
@@ -401,7 +402,7 @@ describe('BillableServiceFormWorkspace', () => {
401
402
  expect(mockCreateBillableService).not.toHaveBeenCalled();
402
403
  });
403
404
 
404
- test('should show "Service name is required" error when service name is empty', async () => {
405
+ it('should show "Service name is required" error when service name is empty', async () => {
405
406
  const user = userEvent.setup();
406
407
  renderBillableServicesForm();
407
408
 
@@ -423,7 +424,7 @@ describe('BillableServiceFormWorkspace', () => {
423
424
  expect(mockCreateBillableService).not.toHaveBeenCalled();
424
425
  });
425
426
 
426
- test('should accept valid decimal price values', async () => {
427
+ it('should accept valid decimal price values', async () => {
427
428
  const user = userEvent.setup();
428
429
  renderBillableServicesForm();
429
430
 
@@ -455,7 +456,7 @@ describe('BillableServiceFormWorkspace', () => {
455
456
  });
456
457
  });
457
458
 
458
- test('should show "Service type is required" error when not selected', async () => {
459
+ it('should show "Service type is required" error when not selected', async () => {
459
460
  const user = userEvent.setup();
460
461
  renderBillableServicesForm();
461
462
 
@@ -474,7 +475,7 @@ describe('BillableServiceFormWorkspace', () => {
474
475
  expect(mockCreateBillableService).not.toHaveBeenCalled();
475
476
  });
476
477
 
477
- test('should show "Payment mode is required" error when not selected', async () => {
478
+ it('should show "Payment mode is required" error when not selected', async () => {
478
479
  const user = userEvent.setup();
479
480
  renderBillableServicesForm();
480
481
 
@@ -493,7 +494,7 @@ describe('BillableServiceFormWorkspace', () => {
493
494
  expect(mockCreateBillableService).not.toHaveBeenCalled();
494
495
  });
495
496
 
496
- test('should show "Price is required" error when price field is empty', async () => {
497
+ it('should show "Price is required" error when price field is empty', async () => {
497
498
  const user = userEvent.setup();
498
499
  renderBillableServicesForm();
499
500
 
@@ -530,16 +531,16 @@ describe('BillableServiceFormWorkspace', () => {
530
531
  ],
531
532
  };
532
533
 
533
- test('should populate form with existing service data', () => {
534
+ it('should populate form with existing service data', () => {
534
535
  renderBillableServicesForm({ workspaceProps: { serviceToEdit: mockServiceToEdit } });
535
536
 
536
537
  expect(screen.getByText('X-Ray Service')).toBeInTheDocument(); // Service name shown as label
537
538
  expect(screen.getByDisplayValue('XRay')).toBeInTheDocument(); // Short name
538
539
  });
539
540
 
540
- test('should call updateBillableService instead of createBillableService', async () => {
541
+ it('should call updateBillableService instead of createBillableService', async () => {
541
542
  const user = userEvent.setup();
542
- const mockCloseWorkspace = jest.fn();
543
+ const mockCloseWorkspace = vi.fn();
543
544
  renderBillableServicesForm({
544
545
  closeWorkspace: mockCloseWorkspace,
545
546
  workspaceProps: { serviceToEdit: mockServiceToEdit },
@@ -571,9 +572,9 @@ describe('BillableServiceFormWorkspace', () => {
571
572
  expect(mockCreateBillableService).not.toHaveBeenCalled();
572
573
  });
573
574
 
574
- test('should trim whitespace from short name when updating service', async () => {
575
+ it('should trim whitespace from short name when updating service', async () => {
575
576
  const user = userEvent.setup();
576
- const mockCloseWorkspace = jest.fn();
577
+ const mockCloseWorkspace = vi.fn();
577
578
  renderBillableServicesForm({
578
579
  closeWorkspace: mockCloseWorkspace,
579
580
  workspaceProps: { serviceToEdit: mockServiceToEdit },
@@ -596,8 +597,8 @@ describe('BillableServiceFormWorkspace', () => {
596
597
  );
597
598
  });
598
599
 
599
- test('should call onWorkspaceClose callback after successful edit', async () => {
600
- const mockOnWorkspaceClose = jest.fn();
600
+ it('should call onWorkspaceClose callback after successful edit', async () => {
601
+ const mockOnWorkspaceClose = vi.fn();
601
602
  renderBillableServicesForm({
602
603
  workspaceProps: { serviceToEdit: mockServiceToEdit, onWorkspaceClose: mockOnWorkspaceClose },
603
604
  });
@@ -609,7 +610,7 @@ describe('BillableServiceFormWorkspace', () => {
609
610
  expect(mockOnWorkspaceClose).toHaveBeenCalledTimes(1);
610
611
  });
611
612
 
612
- test('should not allow editing service name in edit mode', () => {
613
+ it('should not allow editing service name in edit mode', () => {
613
614
  renderBillableServicesForm({ workspaceProps: { serviceToEdit: mockServiceToEdit } });
614
615
 
615
616
  // Service name should be displayed as a label, not an editable input
@@ -617,7 +618,7 @@ describe('BillableServiceFormWorkspace', () => {
617
618
  expect(screen.queryByRole('textbox', { name: /Service name/i })).not.toBeInTheDocument();
618
619
  });
619
620
 
620
- test('should handle asynchronous loading of dependencies and populate form correctly', async () => {
621
+ it('should handle asynchronous loading of dependencies and populate form correctly', async () => {
621
622
  // Scenario: User opens edit form, but payment modes/service types haven't loaded yet
622
623
  // The form should wait for dependencies to load, then populate correctly
623
624
 
@@ -635,7 +636,7 @@ describe('BillableServiceFormWorkspace', () => {
635
636
  });
636
637
 
637
638
  describe('Dynamic Payment Options', () => {
638
- test('should add new payment option when clicking "Add payment option" button', async () => {
639
+ it('should add new payment option when clicking "Add payment option" button', async () => {
639
640
  const user = userEvent.setup();
640
641
  renderBillableServicesForm();
641
642
 
@@ -646,7 +647,7 @@ describe('BillableServiceFormWorkspace', () => {
646
647
  expect(paymentModeDropdowns).toHaveLength(2);
647
648
  });
648
649
 
649
- test('should be able to add multiple payment options', async () => {
650
+ it('should be able to add multiple payment options', async () => {
650
651
  const user = userEvent.setup();
651
652
  renderBillableServicesForm();
652
653
 
@@ -658,7 +659,7 @@ describe('BillableServiceFormWorkspace', () => {
658
659
  expect(paymentModeDropdowns).toHaveLength(2);
659
660
  });
660
661
 
661
- test('should allow adding multiple payment options with different payment modes', async () => {
662
+ it('should allow adding multiple payment options with different payment modes', async () => {
662
663
  const user = userEvent.setup();
663
664
  renderBillableServicesForm();
664
665
 
@@ -706,7 +707,7 @@ describe('BillableServiceFormWorkspace', () => {
706
707
  );
707
708
  });
708
709
 
709
- test('should validate each payment option independently', async () => {
710
+ it('should validate each payment option independently', async () => {
710
711
  const user = userEvent.setup();
711
712
  renderBillableServicesForm();
712
713
 
@@ -740,7 +741,7 @@ describe('BillableServiceFormWorkspace', () => {
740
741
  expect(mockCreateBillableService).not.toHaveBeenCalled();
741
742
  });
742
743
 
743
- test('should allow selecting different payment modes in multiple fields', async () => {
744
+ it('should allow selecting different payment modes in multiple fields', async () => {
744
745
  const user = userEvent.setup();
745
746
  renderBillableServicesForm();
746
747
 
@@ -801,7 +802,7 @@ describe('BillableServiceFormWorkspace', () => {
801
802
  });
802
803
 
803
804
  describe('Error Handling', () => {
804
- test('should display error snackbar when create API call fails', async () => {
805
+ it('should display error snackbar when create API call fails', async () => {
805
806
  const user = userEvent.setup();
806
807
  renderBillableServicesForm();
807
808
 
@@ -818,7 +819,7 @@ describe('BillableServiceFormWorkspace', () => {
818
819
  expect(mockCreateBillableService).toHaveBeenCalledTimes(1);
819
820
  });
820
821
 
821
- test('should display error snackbar when update API call fails', async () => {
822
+ it('should display error snackbar when update API call fails', async () => {
822
823
  const mockServiceToEdit: BillableService = {
823
824
  uuid: 'service-uuid',
824
825
  name: 'Test Service',
@@ -859,7 +860,7 @@ describe('BillableServiceFormWorkspace', () => {
859
860
 
860
861
  describe('Helper Functions', () => {
861
862
  describe('transformServiceToFormData', () => {
862
- test('should return default form data when no service is provided', () => {
863
+ it('should return default form data when no service is provided', () => {
863
864
  const result = transformServiceToFormData();
864
865
 
865
866
  expect(result).toEqual({
@@ -871,7 +872,7 @@ describe('Helper Functions', () => {
871
872
  });
872
873
  });
873
874
 
874
- test('should return default form data when undefined service is provided', () => {
875
+ it('should return default form data when undefined service is provided', () => {
875
876
  const result = transformServiceToFormData(undefined);
876
877
 
877
878
  expect(result).toEqual({
@@ -883,7 +884,7 @@ describe('Helper Functions', () => {
883
884
  });
884
885
  });
885
886
 
886
- test('should transform a complete service to form data', () => {
887
+ it('should transform a complete service to form data', () => {
887
888
  const service: BillableService = {
888
889
  uuid: 'service-uuid',
889
890
  name: 'X-Ray',
@@ -949,7 +950,7 @@ describe('Helper Functions', () => {
949
950
  });
950
951
  });
951
952
 
952
- test('should handle service without concept', () => {
953
+ it('should handle service without concept', () => {
953
954
  const service: BillableService = {
954
955
  uuid: 'service-uuid',
955
956
  name: 'Basic Service',
@@ -978,7 +979,7 @@ describe('Helper Functions', () => {
978
979
  expect(result.concept).toBeNull();
979
980
  });
980
981
 
981
- test('should handle service with missing or empty price using nullish coalescing', () => {
982
+ it('should handle service with missing or empty price using nullish coalescing', () => {
982
983
  const service: BillableService = {
983
984
  uuid: 'service-uuid',
984
985
  name: 'Test Service',
@@ -1010,32 +1011,32 @@ describe('Helper Functions', () => {
1010
1011
  });
1011
1012
 
1012
1013
  describe('normalizePrice', () => {
1013
- test('should return number as-is', () => {
1014
+ it('should return number as-is', () => {
1014
1015
  expect(normalizePrice(100)).toBe(100);
1015
1016
  expect(normalizePrice(10.5)).toBe(10.5);
1016
1017
  expect(normalizePrice(0)).toBe(0);
1017
1018
  });
1018
1019
 
1019
- test('should convert string to number', () => {
1020
+ it('should convert string to number', () => {
1020
1021
  expect(normalizePrice('100')).toBe(100);
1021
1022
  expect(normalizePrice('10.5')).toBe(10.5);
1022
1023
  expect(normalizePrice('0')).toBe(0);
1023
1024
  });
1024
1025
 
1025
- test('should handle decimal strings correctly', () => {
1026
+ it('should handle decimal strings correctly', () => {
1026
1027
  expect(normalizePrice('10.99')).toBe(10.99);
1027
1028
  expect(normalizePrice('0.50')).toBe(0.5);
1028
1029
  });
1029
1030
 
1030
- test('should handle undefined by converting to NaN', () => {
1031
+ it('should handle undefined by converting to NaN', () => {
1031
1032
  expect(normalizePrice(undefined)).toBeNaN();
1032
1033
  });
1033
1034
 
1034
- test('should handle empty string by converting to NaN', () => {
1035
+ it('should handle empty string by converting to NaN', () => {
1035
1036
  expect(normalizePrice('')).toBeNaN();
1036
1037
  });
1037
1038
 
1038
- test('should handle invalid string by converting to NaN', () => {
1039
+ it('should handle invalid string by converting to NaN', () => {
1039
1040
  expect(normalizePrice('invalid')).toBeNaN();
1040
1041
  });
1041
1042
  });
@@ -1047,14 +1048,14 @@ describe('Helper Functions', () => {
1047
1048
  { uuid: 'mpesa-uuid', name: 'MPESA' },
1048
1049
  ];
1049
1050
 
1050
- test('should return all payment modes when no modes are selected', () => {
1051
+ it('should return all payment modes when no modes are selected', () => {
1051
1052
  const fields = [{ paymentMode: '', price: '' }];
1052
1053
  const result = getAvailablePaymentModes(allPaymentModes, fields, 0, '');
1053
1054
 
1054
1055
  expect(result).toEqual(allPaymentModes);
1055
1056
  });
1056
1057
 
1057
- test('should exclude already-selected payment modes from other fields', () => {
1058
+ it('should exclude already-selected payment modes from other fields', () => {
1058
1059
  const fields = [
1059
1060
  { paymentMode: 'cash-uuid', price: '100' },
1060
1061
  { paymentMode: '', price: '' },
@@ -1068,7 +1069,7 @@ describe('Helper Functions', () => {
1068
1069
  expect(result).not.toContainEqual({ uuid: 'cash-uuid', name: 'Cash' });
1069
1070
  });
1070
1071
 
1071
- test('should keep current field selection visible even if selected elsewhere', () => {
1072
+ it('should keep current field selection visible even if selected elsewhere', () => {
1072
1073
  const fields = [
1073
1074
  { paymentMode: 'cash-uuid', price: '100' },
1074
1075
  { paymentMode: 'insurance-uuid', price: '80' },
@@ -1081,7 +1082,7 @@ describe('Helper Functions', () => {
1081
1082
  expect(result).toContainEqual({ uuid: 'mpesa-uuid', name: 'MPESA' });
1082
1083
  });
1083
1084
 
1084
- test('should filter multiple selected payment modes', () => {
1085
+ it('should filter multiple selected payment modes', () => {
1085
1086
  const fields = [
1086
1087
  { paymentMode: 'cash-uuid', price: '100' },
1087
1088
  { paymentMode: 'insurance-uuid', price: '80' },
@@ -1092,7 +1093,7 @@ describe('Helper Functions', () => {
1092
1093
  expect(result).toEqual([{ uuid: 'mpesa-uuid', name: 'MPESA' }]);
1093
1094
  });
1094
1095
 
1095
- test('should handle empty payment mode values correctly', () => {
1096
+ it('should handle empty payment mode values correctly', () => {
1096
1097
  const fields = [
1097
1098
  { paymentMode: '', price: '' },
1098
1099
  { paymentMode: 'cash-uuid', price: '100' },
@@ -1107,7 +1108,7 @@ describe('Helper Functions', () => {
1107
1108
  ]);
1108
1109
  });
1109
1110
 
1110
- test('should work with generic types having uuid property', () => {
1111
+ it('should work with generic types having uuid property', () => {
1111
1112
  const customModes = [
1112
1113
  { uuid: 'a', customProp: 'value1' },
1113
1114
  { uuid: 'b', customProp: 'value2' },
@@ -1122,7 +1123,7 @@ describe('Helper Functions', () => {
1122
1123
  expect(result).toEqual([{ uuid: 'b', customProp: 'value2' }]);
1123
1124
  });
1124
1125
 
1125
- test('should return all modes when only current field has a selection', () => {
1126
+ it('should return all modes when only current field has a selection', () => {
1126
1127
  const fields = [{ paymentMode: 'cash-uuid', price: '100' }];
1127
1128
  const result = getAvailablePaymentModes(allPaymentModes, fields, 0, 'cash-uuid');
1128
1129
 
@@ -3,11 +3,12 @@ import classNames from 'classnames';
3
3
  import { BrowserRouter, Routes, Route } from 'react-router-dom';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { useLeftNav, WorkspaceContainer, useLayoutType, isDesktop } from '@openmrs/esm-framework';
6
- // import BillWaiver from './bill-waiver/bill-waiver.component';
7
6
  import BillableServicesDashboard from './dashboard/dashboard.component';
8
7
  import BillingHeader from '../billing-header/billing-header.component';
9
8
  import CashPointConfiguration from './cash-point/cash-point-configuration.component';
10
9
  import PaymentModesConfig from './payment-modes/payment-modes-config.component';
10
+ import DiscountRequests from '../discounts/admin/discount-requests.component';
11
+ import RefundRequests from '../refunds/admin/refund-requests.component';
11
12
  import styles from './billable-services.scss';
12
13
 
13
14
  const BillableServiceHome: React.FC = () => {
@@ -26,7 +27,8 @@ const BillableServiceHome: React.FC = () => {
26
27
  <Route path="/" element={<BillableServicesDashboard />} />
27
28
  <Route path="/cash-point-config" element={<CashPointConfiguration />} />
28
29
  <Route path="/payment-modes-config" element={<PaymentModesConfig />} />
29
- {/* <Route path="/waive-bill" element={<BillWaiver />} /> */}
30
+ <Route path="/discount-requests" element={<DiscountRequests />} />
31
+ <Route path="/refund-requests" element={<RefundRequests />} />
30
32
  </Routes>
31
33
  </main>
32
34
  </div>
@@ -1,15 +1,16 @@
1
1
  import React from 'react';
2
+ import { describe, expect, type Mock, it, vi } from 'vitest';
2
3
  import { render, screen } from '@testing-library/react';
3
4
  import userEvent from '@testing-library/user-event';
4
5
  import BillableServices from './billable-services.component';
5
6
  import { useBillableServices } from './billable-service.resource';
6
7
 
7
- jest.mock('./billable-service.resource', () => ({
8
- useBillableServices: jest.fn(),
8
+ vi.mock('./billable-service.resource', () => ({
9
+ useBillableServices: vi.fn(),
9
10
  }));
10
11
 
11
12
  describe('BillableService', () => {
12
- const mockedUseBillableServices = useBillableServices as jest.Mock;
13
+ const mockedUseBillableServices = useBillableServices as Mock;
13
14
 
14
15
  it('renders an empty state when there are no billable services', () => {
15
16
  mockedUseBillableServices.mockReturnValue({
@@ -17,7 +18,7 @@ describe('BillableService', () => {
17
18
  isLoading: false,
18
19
  isValidating: false,
19
20
  error: null,
20
- mutate: jest.fn(),
21
+ mutate: vi.fn(),
21
22
  });
22
23
 
23
24
  render(<BillableServices />);
@@ -51,7 +52,7 @@ describe('BillableService', () => {
51
52
  isLoading: false,
52
53
  isValidating: false,
53
54
  error: null,
54
- mutate: jest.fn(),
55
+ mutate: vi.fn(),
55
56
  });
56
57
 
57
58
  render(<BillableServices />);
@@ -92,7 +93,7 @@ describe('BillableService', () => {
92
93
  isLoading: false,
93
94
  isValidating: false,
94
95
  error: null,
95
- mutate: jest.fn(),
96
+ mutate: vi.fn(),
96
97
  });
97
98
 
98
99
  const user = userEvent.setup();
@@ -122,7 +123,7 @@ describe('BillableService', () => {
122
123
  isLoading: false,
123
124
  isValidating: false,
124
125
  error: null,
125
- mutate: jest.fn(),
126
+ mutate: vi.fn(),
126
127
  });
127
128
 
128
129
  const user = userEvent.setup();
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
+ import { it } from 'vitest';
3
+ import { waitForLoadingToFinish } from '@tools/test-helpers';
2
4
  import { render } from '@testing-library/react';
3
- import { waitForLoadingToFinish } from 'tools/test-helpers';
4
5
  import BillableServicesDashboard from './dashboard.component';
5
6
 
6
- test('renders an empty state when there are no services', async () => {
7
+ it('renders an empty state when there are no services', async () => {
7
8
  renderBillingDashboard();
8
9
  await waitForLoadingToFinish();
9
10
  });
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
+ import { describe, expect, it } from 'vitest';
2
3
  import { render, screen } from '@testing-library/react';
3
4
  import BillableServicesCardLink from './billable-services-admin-card-link.component';
4
5
 
5
6
  describe('BillableServicesCardLink', () => {
6
- test('should render billable services admin link', () => {
7
+ it('should render billable services admin link', () => {
7
8
  renderBillableServicesCardLink();
8
9
  const manageBillableServicesText = screen.getByText('Manage billable services');
9
10
  expect(manageBillableServicesText).toHaveClass('heading');
@@ -1,11 +1,27 @@
1
1
  import React from 'react';
2
+ import { describe, expect, it, vi } from 'vitest';
2
3
  import { screen, render } from '@testing-library/react';
3
4
  import { BillingDashboard } from './billing-dashboard.component';
4
5
 
5
- test('renders an empty state when there are no billing records', () => {
6
- renderBillingDashboard();
6
+ vi.mock('../billing.resource', () => ({
7
+ usePaginatedBills: vi.fn(() => ({
8
+ bills: [],
9
+ error: null,
10
+ isLoading: false,
11
+ isValidating: false,
12
+ mutate: vi.fn(),
13
+ currentPage: 1,
14
+ totalCount: 0,
15
+ goTo: vi.fn(),
16
+ })),
17
+ }));
7
18
 
8
- expect(screen.getByTitle(/billing module illustration/i)).toBeInTheDocument();
19
+ describe('BillingDashboard', () => {
20
+ it('renders an empty state when there are no billing records', () => {
21
+ renderBillingDashboard();
22
+
23
+ expect(screen.getByTitle(/billing module illustration/i)).toBeInTheDocument();
24
+ });
9
25
  });
10
26
 
11
27
  function renderBillingDashboard() {