HATEOAS-first backend framework.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
4.5 KiB

  1. import {describe, expect, it} from 'vitest';
  2. import { queryMediaTypes } from '../../src/common';
  3. describe('query', () => {
  4. it('returns a data source query collection from search params', () => {
  5. const q = new URLSearchParams();
  6. const collection = queryMediaTypes.applicationXWwwFormUrlencoded.deserialize(q.toString());
  7. expect(collection.expressions).toBeInstanceOf(Array);
  8. });
  9. it('coerces a numeric value', () => {
  10. const q = new URLSearchParams({
  11. attr: '2',
  12. attr2: '2',
  13. });
  14. const collection = queryMediaTypes.applicationXWwwFormUrlencoded.deserialize(
  15. q.toString(),
  16. {
  17. processEntries: {
  18. attr: {
  19. type: 'number'
  20. }
  21. },
  22. },
  23. );
  24. expect(collection).toEqual({
  25. type: 'and',
  26. expressions: [
  27. {
  28. type: 'or',
  29. expressions: [
  30. {
  31. lhs: 'attr',
  32. operator: '=',
  33. rhs: 2,
  34. },
  35. ],
  36. },
  37. {
  38. type: 'or',
  39. expressions: [
  40. {
  41. lhs: 'attr2',
  42. operator: '=',
  43. rhs: '2',
  44. },
  45. ],
  46. },
  47. ],
  48. });
  49. });
  50. it('coerces a boolean value', () => {
  51. const q = new URLSearchParams({
  52. attr: 'true',
  53. attr2: 'false',
  54. attr3: 'true',
  55. attr4: 'false',
  56. });
  57. const collection = queryMediaTypes.applicationXWwwFormUrlencoded.deserialize(
  58. q.toString(),
  59. {
  60. processEntries: {
  61. attr: {
  62. type: 'boolean',
  63. },
  64. attr2: {
  65. type: 'boolean',
  66. }
  67. },
  68. },
  69. );
  70. expect(collection).toEqual({
  71. type: 'and',
  72. expressions: [
  73. {
  74. type: 'or',
  75. expressions: [
  76. {
  77. lhs: 'attr',
  78. operator: '=',
  79. rhs: true,
  80. },
  81. ],
  82. },
  83. {
  84. type: 'or',
  85. expressions: [
  86. {
  87. lhs: 'attr2',
  88. operator: '=',
  89. rhs: false,
  90. },
  91. ],
  92. },
  93. {
  94. type: 'or',
  95. expressions: [
  96. {
  97. lhs: 'attr3',
  98. operator: '=',
  99. rhs: 'true',
  100. },
  101. ],
  102. },
  103. {
  104. type: 'or',
  105. expressions: [
  106. {
  107. lhs: 'attr4',
  108. operator: '=',
  109. rhs: 'false',
  110. },
  111. ],
  112. },
  113. ],
  114. });
  115. });
  116. it('returns an equal query', () => {
  117. const q = new URLSearchParams({
  118. attr: 'foo'
  119. });
  120. const collection = queryMediaTypes.applicationXWwwFormUrlencoded.deserialize(
  121. q.toString()
  122. );
  123. expect(collection).toEqual({
  124. type: 'and',
  125. expressions: [
  126. {
  127. type: 'or',
  128. expressions: [
  129. {
  130. lhs: 'attr',
  131. operator: '=',
  132. rhs: 'foo',
  133. },
  134. ],
  135. },
  136. ],
  137. });
  138. });
  139. it('returns an AND operator query', () => {
  140. const q = new URLSearchParams([
  141. ['attr', 'foo'],
  142. ['attr2', 'bar'],
  143. ]);
  144. const collection = queryMediaTypes.applicationXWwwFormUrlencoded.deserialize(
  145. q.toString()
  146. );
  147. expect(collection).toEqual({
  148. type: 'and',
  149. expressions: [
  150. {
  151. type: 'or',
  152. expressions: [
  153. {
  154. lhs: 'attr',
  155. operator: '=',
  156. rhs: 'foo',
  157. },
  158. ],
  159. },
  160. {
  161. type: 'or',
  162. expressions: [
  163. {
  164. lhs: 'attr2',
  165. operator: '=',
  166. rhs: 'bar',
  167. },
  168. ],
  169. },
  170. ],
  171. });
  172. });
  173. it('returns an OR operator query', () => {
  174. const q = new URLSearchParams([
  175. ['attr', 'foo'],
  176. ['attr', 'bar'],
  177. ]);
  178. const collection = queryMediaTypes.applicationXWwwFormUrlencoded.deserialize(
  179. q.toString()
  180. );
  181. expect(collection).toEqual({
  182. type: 'and',
  183. expressions: [
  184. {
  185. type: 'or',
  186. expressions: [
  187. {
  188. lhs: 'attr',
  189. operator: '=',
  190. rhs: 'foo',
  191. },
  192. {
  193. lhs: 'attr',
  194. operator: '=',
  195. rhs: 'bar',
  196. }
  197. ]
  198. },
  199. ],
  200. });
  201. });
  202. it('returns an query with appropriate grouping', () => {
  203. const q = new URLSearchParams([
  204. ['attr3', 'quux'],
  205. ['attr', 'foo'],
  206. ['attr4', 'quuux'],
  207. ['attr', 'bar'],
  208. ['attr2', 'baz'],
  209. ]);
  210. const collection = queryMediaTypes.applicationXWwwFormUrlencoded.deserialize(
  211. q.toString()
  212. );
  213. expect(collection).toEqual({
  214. type: 'and',
  215. expressions: [
  216. {
  217. type: 'or',
  218. expressions: [
  219. {
  220. lhs: 'attr3',
  221. operator: '=',
  222. rhs: 'quux',
  223. },
  224. ],
  225. },
  226. {
  227. type: 'or',
  228. expressions: [
  229. {
  230. lhs: 'attr',
  231. operator: '=',
  232. rhs: 'foo',
  233. },
  234. {
  235. lhs: 'attr',
  236. operator: '=',
  237. rhs: 'bar',
  238. }
  239. ]
  240. },
  241. {
  242. type: 'or',
  243. expressions: [
  244. {
  245. lhs: 'attr4',
  246. operator: '=',
  247. rhs: 'quuux',
  248. },
  249. ],
  250. },
  251. {
  252. type: 'or',
  253. expressions: [
  254. {
  255. lhs: 'attr2',
  256. operator: '=',
  257. rhs: 'baz',
  258. },
  259. ],
  260. },
  261. ],
  262. });
  263. });
  264. });