zodHelpers.test.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import { zz } from '../../../zodHelpers'
  2. import { describe, expect, it } from 'vitest'
  3. import mongodb from 'mongodb'
  4. const { ObjectId } = mongodb
  5. describe('zodHelpers', () => {
  6. describe('objectId', () => {
  7. it('fails to parse when provided with an invalid ObjectId', () => {
  8. const parsed = zz.objectId().safeParse('aa')
  9. expect(parsed.success).toBe(false)
  10. expect(parsed.error?.issues).toHaveLength(1)
  11. expect(parsed.error?.issues).toMatchObject([
  12. expect.objectContaining({
  13. message: 'invalid Mongo ObjectId',
  14. }),
  15. ])
  16. })
  17. it('parses successfully when provided with a valid ObjectId', () => {
  18. const parsed = zz.objectId().safeParse('507f1f77bcf86cd799439011')
  19. expect(parsed.success).toBe(true)
  20. expect(parsed.data).toBe('507f1f77bcf86cd799439011')
  21. })
  22. })
  23. describe('coercedObjectId', () => {
  24. it('fails to parse when provided with an invalid ObjectId', () => {
  25. const parsed = zz.coercedObjectId().safeParse('aa')
  26. expect(parsed.success).toBe(false)
  27. expect(parsed.error?.issues).toHaveLength(1)
  28. expect(parsed.error?.issues).toMatchObject([
  29. expect.objectContaining({
  30. message: 'invalid Mongo ObjectId',
  31. }),
  32. ])
  33. })
  34. it('parses to an ObjectId when provided with a valid ObjectId string', () => {
  35. const parsed = zz.coercedObjectId().safeParse('507f1f77bcf86cd799439011')
  36. expect(parsed.success).toBe(true)
  37. expect(parsed.data).toBeInstanceOf(ObjectId)
  38. expect(parsed.data?.toString()).toBe('507f1f77bcf86cd799439011')
  39. })
  40. })
  41. describe('datetime', () => {
  42. it('parses valid ISO 8601 datetime strings', () => {
  43. const parsed = zz.datetime().safeParse('2024-01-01T12:00:00Z')
  44. expect(parsed.success).toBe(true)
  45. expect(parsed.data).toEqual(new Date('2024-01-01T12:00:00Z'))
  46. })
  47. it('parses a valid ISO 8601 datetime with offset', () => {
  48. const parsed = zz
  49. .datetime({ offset: true })
  50. .safeParse('2024-01-01T12:00:00+00:00')
  51. expect(parsed.success).toBe(true)
  52. expect(parsed.data).toEqual(new Date('2024-01-01T12:00:00+00:00'))
  53. })
  54. it('parses a valid Date object', () => {
  55. const date = new Date('2024-01-01T12:00:00Z')
  56. const parsed = zz.datetime().safeParse(date)
  57. expect(parsed.success).toBe(true)
  58. expect(parsed.data).toEqual(date)
  59. })
  60. it('fails to parse datetime with offset when offset option is false', () => {
  61. const parsed = zz
  62. .datetime({ offset: false })
  63. .safeParse('2024-01-01T12:00:00+00:00')
  64. expect(parsed.success).toBe(false)
  65. expect(parsed.error?.issues).toHaveLength(1)
  66. expect(parsed.error?.issues).toMatchObject([
  67. expect.objectContaining({
  68. code: 'invalid_format',
  69. format: 'datetime',
  70. message: 'Invalid ISO datetime',
  71. }),
  72. ])
  73. })
  74. it('fails to parse null when schema is not nullable', () => {
  75. const parsed = zz.datetime().safeParse(null)
  76. expect(parsed.success).toBe(false)
  77. expect(parsed.error?.message).toContain(
  78. 'Invalid input: expected date, received null'
  79. )
  80. })
  81. it('fails to parse invalid datetime strings', () => {
  82. const parsed = zz.datetime().safeParse('invalid-datetime')
  83. expect(parsed.success).toBe(false)
  84. expect(parsed.error?.issues).toHaveLength(1)
  85. expect(parsed.error?.issues).toMatchObject([
  86. expect.objectContaining({
  87. code: 'invalid_format',
  88. format: 'datetime',
  89. message: 'Invalid ISO datetime',
  90. }),
  91. ])
  92. })
  93. })
  94. describe('datetimeNullable', () => {
  95. it('parses valid ISO 8601 datetime strings', () => {
  96. const parsed = zz.datetimeNullable().safeParse('2024-01-01T12:00:00Z')
  97. expect(parsed.success).toBe(true)
  98. expect(parsed.data).toEqual(new Date('2024-01-01T12:00:00Z'))
  99. })
  100. it('parses a valid ISO 8601 datetime with offset', () => {
  101. const parsed = zz
  102. .datetimeNullable({ offset: true })
  103. .safeParse('2024-01-01T12:00:00+00:00')
  104. expect(parsed.success).toBe(true)
  105. expect(parsed.data).toEqual(new Date('2024-01-01T12:00:00+00:00'))
  106. })
  107. it('parses a valid Date object', () => {
  108. const date = new Date('2024-01-01T12:00:00Z')
  109. const parsed = zz.datetimeNullable().safeParse(date)
  110. expect(parsed.success).toBe(true)
  111. expect(parsed.data).toEqual(date)
  112. })
  113. it('fails to parse datetime with offset when offset option is false', () => {
  114. const parsed = zz
  115. .datetimeNullable({ offset: false })
  116. .safeParse('2024-01-01T12:00:00+00:00')
  117. expect(parsed.success).toBe(false)
  118. expect(parsed.error?.issues).toHaveLength(1)
  119. expect(parsed.error?.issues).toMatchObject([
  120. expect.objectContaining({
  121. code: 'invalid_format',
  122. format: 'datetime',
  123. message: 'Invalid ISO datetime',
  124. }),
  125. ])
  126. })
  127. it('parses null when schema is nullable and input is null', () => {
  128. const parsed = zz.datetimeNullable().safeParse(null)
  129. expect(parsed.success).toBe(true)
  130. expect(parsed.data).toBeNull()
  131. })
  132. it('fails to parse invalid datetime strings', () => {
  133. const parsed = zz.datetimeNullable().safeParse('invalid-datetime')
  134. expect(parsed.success).toBe(false)
  135. expect(parsed.error?.issues).toHaveLength(1)
  136. expect(parsed.error?.issues).toMatchObject([
  137. expect.objectContaining({
  138. code: 'invalid_format',
  139. format: 'datetime',
  140. message: 'Invalid ISO datetime',
  141. }),
  142. ])
  143. })
  144. })
  145. describe('datetimeNullish', () => {
  146. it('parses valid ISO 8601 datetime strings', () => {
  147. const parsed = zz.datetimeNullish().safeParse('2024-01-01T12:00:00Z')
  148. expect(parsed.success).toBe(true)
  149. expect(parsed.data).toEqual(new Date('2024-01-01T12:00:00Z'))
  150. })
  151. it('parses a valid ISO 8601 datetime with offset', () => {
  152. const parsed = zz
  153. .datetimeNullish({ offset: true })
  154. .safeParse('2024-01-01T12:00:00+00:00')
  155. expect(parsed.success).toBe(true)
  156. expect(parsed.data).toEqual(new Date('2024-01-01T12:00:00+00:00'))
  157. })
  158. it('parses a valid Date object', () => {
  159. const date = new Date('2024-01-01T12:00:00Z')
  160. const parsed = zz.datetimeNullish().safeParse(date)
  161. expect(parsed.success).toBe(true)
  162. expect(parsed.data).toEqual(date)
  163. })
  164. it('parses null when schema is nullable and input is null', () => {
  165. const parsed = zz.datetimeNullish().safeParse(null)
  166. expect(parsed.success).toBe(true)
  167. expect(parsed.data).toBeNull()
  168. })
  169. it('parses undefined when schema is nullish and input is undefined', () => {
  170. const parsed = zz.datetimeNullish().safeParse(undefined)
  171. expect(parsed.success).toBe(true)
  172. expect(parsed.data).toBeUndefined()
  173. })
  174. it('fails to parse datetime with offset when offset option is false', () => {
  175. const parsed = zz
  176. .datetimeNullish({ offset: false })
  177. .safeParse('2024-01-01T12:00:00+00:00')
  178. expect(parsed.success).toBe(false)
  179. expect(parsed.error?.issues).toHaveLength(1)
  180. expect(parsed.error?.issues).toMatchObject([
  181. expect.objectContaining({
  182. code: 'invalid_format',
  183. format: 'datetime',
  184. message: 'Invalid ISO datetime',
  185. }),
  186. ])
  187. })
  188. it('fails to parse invalid datetime strings', () => {
  189. const parsed = zz.datetimeNullish().safeParse('invalid-datetime')
  190. expect(parsed.success).toBe(false)
  191. expect(parsed.error?.issues).toHaveLength(1)
  192. expect(parsed.error?.issues).toMatchObject([
  193. expect.objectContaining({
  194. code: 'invalid_format',
  195. format: 'datetime',
  196. message: 'Invalid ISO datetime',
  197. }),
  198. ])
  199. })
  200. })
  201. })