@nlabs/reaktor 0.10.0 → 0.10.1

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 (314) hide show
  1. package/.env +1 -0
  2. package/.env.example +1 -0
  3. package/DATABASE_I18N_GUIDE.md +434 -0
  4. package/TEST_UTILITIES_GUIDE.md +360 -0
  5. package/coverage/index.html +46 -76
  6. package/index.js +1 -1
  7. package/jest.config.js +17 -0
  8. package/jest.setup.js +36 -0
  9. package/lex.config.cjs +2 -2
  10. package/lib/actions/apps.js +17 -239
  11. package/lib/actions/connections.js +6 -89
  12. package/lib/actions/content.js +17 -0
  13. package/lib/actions/conversations.js +19 -336
  14. package/lib/actions/dynamodb.js +2 -150
  15. package/lib/actions/email.js +2 -152
  16. package/lib/actions/files.js +5 -283
  17. package/lib/actions/groups.js +19 -259
  18. package/lib/actions/images.js +31 -700
  19. package/lib/actions/index.js +2 -66
  20. package/lib/actions/ios.js +9 -162
  21. package/lib/actions/locations.js +7 -122
  22. package/lib/actions/messages.js +21 -196
  23. package/lib/actions/notifications.js +2 -59
  24. package/lib/actions/payments.js +11 -464
  25. package/lib/actions/posts.js +75 -527
  26. package/lib/actions/profiles.js +8 -0
  27. package/lib/actions/reactions.js +25 -312
  28. package/lib/actions/s3.js +2 -133
  29. package/lib/actions/search.js +5 -90
  30. package/lib/actions/sms.js +2 -108
  31. package/lib/actions/statistics.js +6 -60
  32. package/lib/actions/subscriptions.js +12 -0
  33. package/lib/actions/tags.js +19 -287
  34. package/lib/actions/users.js +64 -764
  35. package/lib/actions/websockets.js +14 -158
  36. package/lib/adapters/arangoAdapter.js +2 -46
  37. package/lib/adapters/contentAdapter.js +2 -0
  38. package/lib/adapters/fileAdapter.js +2 -76
  39. package/lib/adapters/imageAdapter.js +2 -40
  40. package/lib/adapters/messageAdapter.js +2 -49
  41. package/lib/adapters/postAdapter.js +2 -70
  42. package/lib/adapters/reaktorAdapter.js +2 -44
  43. package/lib/adapters/tagAdapter.js +2 -50
  44. package/lib/adapters/userAdapter.js +2 -115
  45. package/lib/config.js +2 -125
  46. package/lib/handlers/graphqlHandler.js +2 -0
  47. package/lib/index.js +2 -66
  48. package/lib/lambdas/actions/websockets.js +14 -116
  49. package/lib/lambdas/authorizer.js +2 -67
  50. package/lib/lambdas/connection.js +2 -91
  51. package/lib/lambdas/utils/message.js +2 -42
  52. package/lib/lambdas/utils/websocket.js +2 -105
  53. package/lib/mocks/conversation.js +2 -35
  54. package/lib/mocks/file.js +2 -38
  55. package/lib/mocks/group.js +2 -47
  56. package/lib/mocks/image.js +2 -44
  57. package/lib/mocks/post.js +2 -55
  58. package/lib/mocks/tag.js +2 -37
  59. package/lib/mocks/user.js +2 -88
  60. package/lib/mutations/index.js +2 -26
  61. package/lib/mutations/locations.integration.js +2 -0
  62. package/lib/mutations/locations.js +2 -44
  63. package/lib/mutations/messages.integration.js +2 -0
  64. package/lib/mutations/messages.js +2 -86
  65. package/lib/mutations/posts.integration.js +2 -0
  66. package/lib/mutations/posts.js +2 -53
  67. package/lib/mutations/profiles.integration.js +2 -0
  68. package/lib/mutations/profiles.js +2 -0
  69. package/lib/mutations/reactions.integration.js +2 -0
  70. package/lib/mutations/reactions.js +2 -51
  71. package/lib/mutations/statistics.integration.js +2 -0
  72. package/lib/mutations/statistics.js +2 -39
  73. package/lib/mutations/subscriptions.integration.js +2 -0
  74. package/lib/mutations/subscriptions.js +2 -56
  75. package/lib/mutations/tags.integration.js +2 -0
  76. package/lib/mutations/tags.js +2 -120
  77. package/lib/mutations/users.integration.js +2 -0
  78. package/lib/mutations/users.js +2 -116
  79. package/lib/objectTypes/app.js +2 -173
  80. package/lib/objectTypes/bankAccount.js +2 -76
  81. package/lib/objectTypes/connection.js +2 -48
  82. package/lib/objectTypes/conversation.js +2 -77
  83. package/lib/objectTypes/creditCard.js +2 -86
  84. package/lib/objectTypes/document.js +2 -46
  85. package/lib/objectTypes/error.js +2 -46
  86. package/lib/objectTypes/external.js +2 -74
  87. package/lib/objectTypes/file.js +2 -100
  88. package/lib/objectTypes/filter.js +2 -43
  89. package/lib/objectTypes/group.js +2 -123
  90. package/lib/objectTypes/iapSubscription.js +2 -40
  91. package/lib/objectTypes/image.js +2 -129
  92. package/lib/objectTypes/index.js +2 -68
  93. package/lib/objectTypes/location.js +2 -109
  94. package/lib/objectTypes/message.js +2 -96
  95. package/lib/objectTypes/passcode.js +2 -42
  96. package/lib/objectTypes/plan.js +2 -95
  97. package/lib/objectTypes/post.js +2 -125
  98. package/lib/objectTypes/profile.js +2 -0
  99. package/lib/objectTypes/reaction.js +2 -61
  100. package/lib/objectTypes/relation.js +2 -49
  101. package/lib/objectTypes/search.js +2 -72
  102. package/lib/objectTypes/statistics.js +2 -39
  103. package/lib/objectTypes/subscription.js +2 -117
  104. package/lib/objectTypes/tag.js +2 -65
  105. package/lib/objectTypes/user.js +2 -144
  106. package/lib/queries/index.js +2 -33
  107. package/lib/queries/locations.integration.js +2 -0
  108. package/lib/queries/locations.js +2 -45
  109. package/lib/queries/messages.integration.js +2 -0
  110. package/lib/queries/messages.js +2 -52
  111. package/lib/queries/posts.integration.js +2 -0
  112. package/lib/queries/posts.js +2 -154
  113. package/lib/queries/reactions.integration.js +2 -0
  114. package/lib/queries/reactions.js +2 -56
  115. package/lib/queries/statistics.js +2 -39
  116. package/lib/queries/subscriptions.js +2 -44
  117. package/lib/queries/tags.integration.js +2 -0
  118. package/lib/queries/tags.js +2 -75
  119. package/lib/queries/users.integration.js +2 -0
  120. package/lib/queries/users.js +2 -64
  121. package/lib/templates/email/layout.js +3 -25
  122. package/lib/templates/email/passwordForgot.js +3 -25
  123. package/lib/templates/email/passwordRecovery.js +3 -25
  124. package/lib/templates/email/verifyEmail.js +3 -25
  125. package/lib/templates/email/welcome.js +3 -25
  126. package/lib/templates/sms/passwordForgot.js +2 -24
  127. package/lib/templates/sms/passwordRecovery.js +2 -24
  128. package/lib/templates/sms/verifyEmail.js +2 -24
  129. package/lib/templates/sms/verifyPhone.js +2 -24
  130. package/lib/templates/sms/welcome.js +2 -24
  131. package/lib/types/apps.types.js +2 -32
  132. package/lib/types/arangodb.types.js +1 -16
  133. package/lib/types/auth.types.js +1 -16
  134. package/lib/types/connections.types.js +1 -16
  135. package/lib/types/content.types.js +1 -0
  136. package/lib/types/conversations.types.js +1 -16
  137. package/lib/types/email.types.js +1 -16
  138. package/lib/types/error.types.js +2 -44
  139. package/lib/types/files.types.js +1 -16
  140. package/lib/types/google.types.js +1 -16
  141. package/lib/types/groups.types.js +1 -16
  142. package/lib/types/images.types.js +1 -16
  143. package/lib/types/index.js +2 -60
  144. package/lib/types/locations.types.js +1 -16
  145. package/lib/types/messages.types.js +1 -16
  146. package/lib/types/notifications.types.js +1 -16
  147. package/lib/types/payments.types.js +1 -16
  148. package/lib/types/posts.types.js +1 -16
  149. package/lib/types/profiles.types.js +1 -0
  150. package/lib/types/statistics.types.js +1 -16
  151. package/lib/types/tags.types.js +1 -16
  152. package/lib/types/users.types.js +1 -16
  153. package/lib/types/websockets.types.js +1 -16
  154. package/lib/utils/adapterUtils.js +2 -45
  155. package/lib/utils/analyticsUtils.js +2 -72
  156. package/lib/utils/arangodbUtils.js +5 -163
  157. package/lib/utils/authUtils.js +2 -0
  158. package/lib/utils/contextUtils.js +2 -0
  159. package/lib/utils/dbI18n.example.js +6 -0
  160. package/lib/utils/dbI18n.js +2 -0
  161. package/lib/utils/googleTranslate.js +2 -0
  162. package/lib/utils/graphqlUtils.js +2 -0
  163. package/lib/utils/index.js +2 -30
  164. package/lib/utils/languageDetection.js +2 -0
  165. package/lib/utils/localeUtils.example.js +2 -0
  166. package/lib/utils/localeUtils.js +2 -0
  167. package/lib/utils/middlewareUtils.js +2 -0
  168. package/lib/utils/sessionUtils.js +2 -0
  169. package/lib/utils/stripeUtils.js +2 -43
  170. package/lib/utils/templateUtils.js +2 -0
  171. package/lib/utils/testUtils.js +2 -0
  172. package/lib/utils/translationQueue.example.js +2 -0
  173. package/lib/utils/translationQueue.js +2 -0
  174. package/package.json +27 -24
  175. package/.prettierrc.js +0 -4
  176. package/lib/actions/apps.d.ts +0 -25
  177. package/lib/actions/connections.d.ts +0 -4
  178. package/lib/actions/conversations.d.ts +0 -14
  179. package/lib/actions/dynamodb.d.ts +0 -8
  180. package/lib/actions/email.d.ts +0 -5
  181. package/lib/actions/files.d.ts +0 -19
  182. package/lib/actions/groups.d.ts +0 -14
  183. package/lib/actions/images.d.ts +0 -26
  184. package/lib/actions/index.d.ts +0 -23
  185. package/lib/actions/ios.d.ts +0 -7
  186. package/lib/actions/locations.d.ts +0 -6
  187. package/lib/actions/messages.d.ts +0 -14
  188. package/lib/actions/notifications.d.ts +0 -5
  189. package/lib/actions/payments.d.ts +0 -10
  190. package/lib/actions/personas.d.ts +0 -3
  191. package/lib/actions/personas.js +0 -110
  192. package/lib/actions/posts.d.ts +0 -22
  193. package/lib/actions/reactions.d.ts +0 -30
  194. package/lib/actions/s3.d.ts +0 -7
  195. package/lib/actions/search.d.ts +0 -3
  196. package/lib/actions/sms.d.ts +0 -9
  197. package/lib/actions/statistics.d.ts +0 -3
  198. package/lib/actions/subscription.d.ts +0 -7
  199. package/lib/actions/subscription.js +0 -208
  200. package/lib/actions/tags.d.ts +0 -34
  201. package/lib/actions/users.d.ts +0 -72
  202. package/lib/actions/websockets.d.ts +0 -20
  203. package/lib/adapters/arangoAdapter.d.ts +0 -2
  204. package/lib/adapters/fileAdapter.d.ts +0 -3
  205. package/lib/adapters/imageAdapter.d.ts +0 -2
  206. package/lib/adapters/messageAdapter.d.ts +0 -2
  207. package/lib/adapters/postAdapter.d.ts +0 -2
  208. package/lib/adapters/reaktorAdapter.d.ts +0 -6
  209. package/lib/adapters/tagAdapter.d.ts +0 -2
  210. package/lib/adapters/userAdapter.d.ts +0 -2
  211. package/lib/config.d.ts +0 -20
  212. package/lib/index.d.ts +0 -12
  213. package/lib/lambdas/actions/websockets.d.ts +0 -7
  214. package/lib/lambdas/authorizer.d.ts +0 -20
  215. package/lib/lambdas/connection.d.ts +0 -12
  216. package/lib/lambdas/utils/message.d.ts +0 -1
  217. package/lib/lambdas/utils/websocket.d.ts +0 -7
  218. package/lib/mocks/conversation.d.ts +0 -8
  219. package/lib/mocks/file.d.ts +0 -11
  220. package/lib/mocks/group.d.ts +0 -17
  221. package/lib/mocks/image.d.ts +0 -3
  222. package/lib/mocks/post.d.ts +0 -38
  223. package/lib/mocks/tag.d.ts +0 -2
  224. package/lib/mocks/user.d.ts +0 -4
  225. package/lib/mutations/index.d.ts +0 -3
  226. package/lib/mutations/locations.d.ts +0 -2
  227. package/lib/mutations/messages.d.ts +0 -2
  228. package/lib/mutations/personas.d.ts +0 -2
  229. package/lib/mutations/personas.js +0 -100
  230. package/lib/mutations/posts.d.ts +0 -2
  231. package/lib/mutations/reactions.d.ts +0 -2
  232. package/lib/mutations/statistics.d.ts +0 -2
  233. package/lib/mutations/subscriptions.d.ts +0 -2
  234. package/lib/mutations/tags.d.ts +0 -2
  235. package/lib/mutations/users.d.ts +0 -1
  236. package/lib/objectTypes/app.d.ts +0 -3
  237. package/lib/objectTypes/bankAccount.d.ts +0 -1
  238. package/lib/objectTypes/connection.d.ts +0 -1
  239. package/lib/objectTypes/conversation.d.ts +0 -2
  240. package/lib/objectTypes/creditCard.d.ts +0 -1
  241. package/lib/objectTypes/document.d.ts +0 -1
  242. package/lib/objectTypes/error.d.ts +0 -1
  243. package/lib/objectTypes/external.d.ts +0 -1
  244. package/lib/objectTypes/file.d.ts +0 -2
  245. package/lib/objectTypes/filter.d.ts +0 -1
  246. package/lib/objectTypes/group.d.ts +0 -3
  247. package/lib/objectTypes/iapSubscription.d.ts +0 -1
  248. package/lib/objectTypes/image.d.ts +0 -2
  249. package/lib/objectTypes/index.d.ts +0 -24
  250. package/lib/objectTypes/location.d.ts +0 -2
  251. package/lib/objectTypes/message.d.ts +0 -2
  252. package/lib/objectTypes/passcode.d.ts +0 -1
  253. package/lib/objectTypes/persona.d.ts +0 -3
  254. package/lib/objectTypes/persona.js +0 -87
  255. package/lib/objectTypes/plan.d.ts +0 -2
  256. package/lib/objectTypes/post.d.ts +0 -2
  257. package/lib/objectTypes/reaction.d.ts +0 -2
  258. package/lib/objectTypes/relation.d.ts +0 -1
  259. package/lib/objectTypes/search.d.ts +0 -1
  260. package/lib/objectTypes/statistics.d.ts +0 -1
  261. package/lib/objectTypes/subscription.d.ts +0 -2
  262. package/lib/objectTypes/tag.d.ts +0 -2
  263. package/lib/objectTypes/user.d.ts +0 -4
  264. package/lib/queries/index.d.ts +0 -3
  265. package/lib/queries/locations.d.ts +0 -2
  266. package/lib/queries/messages.d.ts +0 -2
  267. package/lib/queries/posts.d.ts +0 -2
  268. package/lib/queries/reactions.d.ts +0 -2
  269. package/lib/queries/statistics.d.ts +0 -2
  270. package/lib/queries/subscriptions.d.ts +0 -2
  271. package/lib/queries/tags.d.ts +0 -2
  272. package/lib/queries/users.d.ts +0 -1
  273. package/lib/templates/email/layout.d.ts +0 -2
  274. package/lib/templates/email/passwordForgot.d.ts +0 -2
  275. package/lib/templates/email/passwordRecovery.d.ts +0 -2
  276. package/lib/templates/email/verifyEmail.d.ts +0 -2
  277. package/lib/templates/email/welcome.d.ts +0 -2
  278. package/lib/templates/sms/passwordForgot.d.ts +0 -2
  279. package/lib/templates/sms/passwordRecovery.d.ts +0 -2
  280. package/lib/templates/sms/verifyEmail.d.ts +0 -2
  281. package/lib/templates/sms/verifyPhone.d.ts +0 -2
  282. package/lib/templates/sms/welcome.d.ts +0 -2
  283. package/lib/types/apps.types.d.ts +0 -46
  284. package/lib/types/arangodb.types.d.ts +0 -34
  285. package/lib/types/auth.types.d.ts +0 -9
  286. package/lib/types/connections.types.d.ts +0 -5
  287. package/lib/types/conversations.types.d.ts +0 -27
  288. package/lib/types/email.types.d.ts +0 -13
  289. package/lib/types/error.types.d.ts +0 -20
  290. package/lib/types/files.types.d.ts +0 -23
  291. package/lib/types/google.types.d.ts +0 -29
  292. package/lib/types/groups.types.d.ts +0 -18
  293. package/lib/types/images.types.d.ts +0 -52
  294. package/lib/types/index.d.ts +0 -20
  295. package/lib/types/locations.types.d.ts +0 -18
  296. package/lib/types/messages.types.d.ts +0 -16
  297. package/lib/types/notifications.types.d.ts +0 -19
  298. package/lib/types/payments.types.d.ts +0 -109
  299. package/lib/types/personas.types.d.ts +0 -32
  300. package/lib/types/personas.types.js +0 -16
  301. package/lib/types/posts.types.d.ts +0 -28
  302. package/lib/types/statistics.types.d.ts +0 -3
  303. package/lib/types/tags.types.d.ts +0 -15
  304. package/lib/types/users.types.d.ts +0 -79
  305. package/lib/types/websockets.types.d.ts +0 -18
  306. package/lib/utils/adapterUtils.d.ts +0 -1
  307. package/lib/utils/analyticsUtils.d.ts +0 -21
  308. package/lib/utils/arangodbUtils.d.ts +0 -66
  309. package/lib/utils/auth.d.ts +0 -21
  310. package/lib/utils/auth.js +0 -57
  311. package/lib/utils/index.d.ts +0 -5
  312. package/lib/utils/session.d.ts +0 -18
  313. package/lib/utils/session.js +0 -60
  314. package/lib/utils/stripeUtils.d.ts +0 -3
@@ -0,0 +1,360 @@
1
+ # Test Utilities Guide
2
+
3
+ This guide explains how to use the test utilities in `src/utils/testUtils.ts` to optimize and consolidate your GraphQL query and mutation tests.
4
+
5
+ ## Overview
6
+
7
+ The test utilities provide a standardized way to create tests for GraphQL resolvers, reducing code duplication and improving maintainability. They abstract common testing patterns into reusable functions.
8
+
9
+ ## Available Utilities
10
+
11
+ ### 1. Mock Context and Resolve Info
12
+
13
+ ```typescript
14
+ import { createMockContext, createMockResolveInfo } from '../utils/testUtils';
15
+
16
+ // Create a standard mock context
17
+ const context = createMockContext();
18
+
19
+ // Create a custom context with overrides
20
+ const customContext = createMockContext({
21
+ databaseName: 'custom-db',
22
+ session: { userId: 'custom-user' }
23
+ });
24
+
25
+ // Create mock resolve info for GraphQL resolvers
26
+ const resolveInfo = createMockResolveInfo('fieldName');
27
+ ```
28
+
29
+ ### 2. Mock Data Generators
30
+
31
+ ```typescript
32
+ import {
33
+ createMockUser,
34
+ createMockPost,
35
+ createMockMessage,
36
+ createMockReaction,
37
+ createMockTag
38
+ } from '../utils/testUtils';
39
+
40
+ // Create mock data with defaults
41
+ const user = createMockUser();
42
+ const post = createMockPost();
43
+
44
+ // Create mock data with custom values
45
+ const customUser = createMockUser({
46
+ userId: 'custom-id',
47
+ email: 'custom@example.com'
48
+ });
49
+ ```
50
+
51
+ ### 3. Mock Setup Utilities
52
+
53
+ ```typescript
54
+ import { mockActionsModule, mockObjectType, setupCommonMocks } from '../utils/testUtils';
55
+
56
+ // Mock actions module
57
+ mockActionsModule('../actions/users', {
58
+ getUser: jest.fn(),
59
+ getSessionUser: jest.fn()
60
+ });
61
+
62
+ // Mock object types
63
+ mockObjectType('../objectTypes/user', 'user');
64
+
65
+ // Setup common mocks (auth utils, etc.)
66
+ setupCommonMocks();
67
+ ```
68
+
69
+ ## Test Suite Creators
70
+
71
+ ### 1. Query Test Suite
72
+
73
+ Use `createQueryTestSuite` for testing GraphQL query resolvers:
74
+
75
+ ```typescript
76
+ import { createQueryTestSuite, createMockUser } from '../utils/testUtils';
77
+
78
+ // Mock dependencies
79
+ mockActionsModule('../actions/users', {
80
+ getUser: jest.fn(),
81
+ getSessionUser: jest.fn()
82
+ });
83
+ mockObjectType('../objectTypes/user', 'user');
84
+
85
+ // Define test cases
86
+ const testCases = [
87
+ {
88
+ name: 'getUserByEmail',
89
+ actionName: 'getUser',
90
+ args: { email: 'test@example.com' },
91
+ expectedCall: (context: any, args: any) => ({ email: args.email }),
92
+ mockReturnValue: createMockUser(),
93
+ errorCase: true
94
+ },
95
+ {
96
+ name: 'getUserById',
97
+ actionName: 'getUser',
98
+ args: { userId: 'user1' },
99
+ expectedCall: (context: any, args: any) => ({ userId: args.userId }),
100
+ mockReturnValue: createMockUser(),
101
+ errorCase: true
102
+ }
103
+ ];
104
+
105
+ // Create the test suite
106
+ createQueryTestSuite(
107
+ 'User Queries',
108
+ '../actions/users',
109
+ '../objectTypes/user',
110
+ 'user',
111
+ testCases
112
+ );
113
+ ```
114
+
115
+ ### 2. Mutation Test Suite
116
+
117
+ Use `createMutationTestSuite` for testing GraphQL mutation resolvers:
118
+
119
+ ```typescript
120
+ import { createMutationTestSuite, createMockUser, setupCommonMocks } from '../utils/testUtils';
121
+
122
+ // Setup common mocks
123
+ setupCommonMocks();
124
+
125
+ // Mock mutations module (complex setup)
126
+ jest.mock('./users', () => ({
127
+ userMutations: {
128
+ getField: jest.fn((fieldName) => ({
129
+ resolve: jest.fn(async (context, args) => {
130
+ const actions = require('../actions/users');
131
+ return await actions[fieldName](context, args);
132
+ })
133
+ }))
134
+ }
135
+ }));
136
+
137
+ // Define test cases
138
+ const testCases = [
139
+ {
140
+ name: 'addUser',
141
+ actionName: 'addUser',
142
+ args: { username: 'testuser', email: 'test@example.com' },
143
+ expectedCall: (context: any, args: any) => args,
144
+ mockReturnValue: createMockUser()
145
+ },
146
+ {
147
+ name: 'deactivateUser',
148
+ actionName: 'deactivateUser',
149
+ args: { userId: 'user1' },
150
+ expectedCall: (context: any, args: any) => args,
151
+ mockReturnValue: createMockUser(),
152
+ requiresAuth: true,
153
+ authUserId: 'user1'
154
+ }
155
+ ];
156
+
157
+ // Create the test suite
158
+ createMutationTestSuite(
159
+ 'User',
160
+ '../actions/users',
161
+ './users',
162
+ testCases
163
+ );
164
+ ```
165
+
166
+ ### 3. Integration Test Suite
167
+
168
+ Use `createIntegrationTestSuite` for testing integration scenarios:
169
+
170
+ ```typescript
171
+ import { createIntegrationTestSuite, createMockUser } from '../utils/testUtils';
172
+
173
+ // Define test cases
174
+ const testCases = [
175
+ {
176
+ name: 'getUserByEmail',
177
+ actionName: 'getUser',
178
+ args: { email: 'test@example.com' },
179
+ expectedCall: (context: any, args: any) => ({ email: args.email }),
180
+ successReturnValue: createMockUser(),
181
+ errorReturnValue: null,
182
+ testErrorCase: true
183
+ }
184
+ ];
185
+
186
+ // Create the integration test suite
187
+ createIntegrationTestSuite(
188
+ 'User',
189
+ '../actions/users',
190
+ '../objectTypes/user',
191
+ 'user',
192
+ testCases
193
+ );
194
+ ```
195
+
196
+ ## Test Case Configuration
197
+
198
+ ### Query Test Cases
199
+
200
+ ```typescript
201
+ {
202
+ name: string; // Test name
203
+ actionName: string; // Action function name
204
+ args: any; // Arguments to pass
205
+ expectedCall: (context: any, args: any) => any; // Expected call parameters
206
+ mockReturnValue?: any; // Mock return value
207
+ errorCase?: boolean; // Whether to test error handling
208
+ }
209
+ ```
210
+
211
+ ### Mutation Test Cases
212
+
213
+ ```typescript
214
+ {
215
+ name: string; // Test name
216
+ actionName: string; // Action function name
217
+ args: any; // Arguments to pass
218
+ expectedCall: (context: any, args: any) => any; // Expected call parameters
219
+ mockReturnValue?: any; // Mock return value
220
+ requiresAuth?: boolean; // Whether authentication is required
221
+ authUserId?: string; // User ID for auth check
222
+ errorCase?: boolean; // Whether to test error handling
223
+ }
224
+ ```
225
+
226
+ ### Integration Test Cases
227
+
228
+ ```typescript
229
+ {
230
+ name: string; // Test name
231
+ actionName: string; // Action function name
232
+ args: any; // Arguments to pass
233
+ expectedCall: (context: any, args: any) => any; // Expected call parameters
234
+ successReturnValue?: any; // Success case return value
235
+ errorReturnValue?: any; // Error case return value
236
+ testErrorCase?: boolean; // Whether to test error scenarios
237
+ }
238
+ ```
239
+
240
+ ## Migration Guide
241
+
242
+ ### From Manual Tests to Utilities
243
+
244
+ **Before (Manual):**
245
+ ```typescript
246
+ describe('User Queries', () => {
247
+ const mockContext = {
248
+ databaseName: 'test',
249
+ session: { userId: 'user1', username: 'testuser', userAccess: 1 }
250
+ };
251
+
252
+ beforeEach(() => {
253
+ jest.clearAllMocks();
254
+ });
255
+
256
+ describe('getUserByEmail', () => {
257
+ it('should call getUser action with email parameter', async () => {
258
+ const mockUser = { userId: 'user1', email: 'test@example.com' };
259
+ const { getUser } = require('../actions/users');
260
+ getUser.mockResolvedValue(mockUser);
261
+
262
+ const result = await getUser(mockContext, { email: 'test@example.com' });
263
+
264
+ expect(getUser).toHaveBeenCalledWith(mockContext, { email: 'test@example.com' });
265
+ expect(result).toEqual(mockUser);
266
+ });
267
+ });
268
+ });
269
+ ```
270
+
271
+ **After (Using Utilities):**
272
+ ```typescript
273
+ import { createQueryTestSuite, createMockUser } from '../utils/testUtils';
274
+
275
+ const testCases = [
276
+ {
277
+ name: 'getUserByEmail',
278
+ actionName: 'getUser',
279
+ args: { email: 'test@example.com' },
280
+ expectedCall: (context: any, args: any) => ({ email: args.email }),
281
+ mockReturnValue: createMockUser()
282
+ }
283
+ ];
284
+
285
+ createQueryTestSuite('User Queries', '../actions/users', '../objectTypes/user', 'user', testCases);
286
+ ```
287
+
288
+ ## Benefits
289
+
290
+ 1. **Reduced Code Duplication**: Common test patterns are abstracted into reusable functions
291
+ 2. **Consistent Testing**: All tests follow the same structure and patterns
292
+ 3. **Easier Maintenance**: Changes to test patterns only need to be made in one place
293
+ 4. **Better Readability**: Test intentions are clearer with declarative test case definitions
294
+ 5. **Faster Development**: New tests can be created quickly by defining test cases
295
+
296
+ ## Best Practices
297
+
298
+ 1. **Use Descriptive Names**: Make test case names clear and descriptive
299
+ 2. **Group Related Tests**: Use the suite name to group related functionality
300
+ 3. **Test Both Success and Error Cases**: Include error handling tests where appropriate
301
+ 4. **Use Mock Data Generators**: Use the provided mock data generators for consistent test data
302
+ 5. **Keep Test Cases Focused**: Each test case should test one specific scenario
303
+
304
+ ## Example: Complete Optimized Test File
305
+
306
+ ```typescript
307
+ import {
308
+ createQueryTestSuite,
309
+ createMockUser,
310
+ mockActionsModule,
311
+ mockObjectType
312
+ } from '../utils/testUtils';
313
+
314
+ // Mock dependencies
315
+ mockActionsModule('../actions/users', {
316
+ getUser: jest.fn(),
317
+ getSessionUser: jest.fn()
318
+ });
319
+
320
+ mockObjectType('../objectTypes/user', 'user');
321
+
322
+ // Define test cases
323
+ const userQueryTestCases = [
324
+ {
325
+ name: 'getUserByEmail',
326
+ actionName: 'getUser',
327
+ args: { email: 'test@example.com' },
328
+ expectedCall: (context: any, args: any) => ({ email: args.email }),
329
+ mockReturnValue: createMockUser(),
330
+ errorCase: true
331
+ },
332
+ {
333
+ name: 'getUserById',
334
+ actionName: 'getUser',
335
+ args: { userId: 'user1' },
336
+ expectedCall: (context: any, args: any) => ({ userId: args.userId }),
337
+ mockReturnValue: createMockUser(),
338
+ errorCase: true
339
+ },
340
+ {
341
+ name: 'getUserBySession',
342
+ actionName: 'getSessionUser',
343
+ args: {},
344
+ expectedCall: (context: any, args: any) => ({}),
345
+ mockReturnValue: createMockUser(),
346
+ errorCase: true
347
+ }
348
+ ];
349
+
350
+ // Create the test suite
351
+ createQueryTestSuite(
352
+ 'User Queries',
353
+ '../actions/users',
354
+ '../objectTypes/user',
355
+ 'user',
356
+ userQueryTestCases
357
+ );
358
+ ```
359
+
360
+ This approach reduces the original 130-line test file to just 40 lines while maintaining the same test coverage and functionality.
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">89.23% </span>
26
+ <span class="strong">78.94% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>1981/2220</span>
28
+ <span class='fraction'>2414/3058</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">80.16% </span>
33
+ <span class="strong">64.96% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>570/711</span>
35
+ <span class='fraction'>777/1196</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">89.48% </span>
40
+ <span class="strong">75.51% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>434/485</span>
42
+ <span class='fraction'>512/678</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">88.18% </span>
47
+ <span class="strong">77.19% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>1776/2014</span>
49
+ <span class='fraction'>2126/2754</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line high'></div>
64
+ <div class='status-line medium'></div>
65
65
  <div class="pad1">
66
66
  <table class="coverage-summary">
67
67
  <thead>
@@ -84,43 +84,43 @@
84
84
  <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
85
85
  </td>
86
86
  <td data-value="100" class="pct high">100%</td>
87
- <td data-value="8" class="abs high">8/8</td>
87
+ <td data-value="17" class="abs high">17/17</td>
88
+ <td data-value="86.66" class="pct high">86.66%</td>
89
+ <td data-value="15" class="abs high">13/15</td>
88
90
  <td data-value="100" class="pct high">100%</td>
89
- <td data-value="2" class="abs high">2/2</td>
90
- <td data-value="100" class="pct high">100%</td>
91
- <td data-value="2" class="abs high">2/2</td>
91
+ <td data-value="4" class="abs high">4/4</td>
92
92
  <td data-value="100" class="pct high">100%</td>
93
- <td data-value="8" class="abs high">8/8</td>
93
+ <td data-value="17" class="abs high">17/17</td>
94
94
  </tr>
95
95
 
96
96
  <tr>
97
97
  <td class="file high" data-value="src/actions"><a href="src/actions/index.html">src/actions</a></td>
98
- <td data-value="88.4" class="pic high">
99
- <div class="chart"><div class="cover-fill" style="width: 88%"></div><div class="cover-empty" style="width: 12%"></div></div>
98
+ <td data-value="80.23" class="pic high">
99
+ <div class="chart"><div class="cover-fill" style="width: 80%"></div><div class="cover-empty" style="width: 20%"></div></div>
100
100
  </td>
101
- <td data-value="88.4" class="pct high">88.4%</td>
102
- <td data-value="1992" class="abs high">1761/1992</td>
103
- <td data-value="75.91" class="pct medium">75.91%</td>
104
- <td data-value="548" class="abs medium">416/548</td>
105
- <td data-value="88.98" class="pct high">88.98%</td>
106
- <td data-value="445" class="abs high">396/445</td>
107
- <td data-value="87.39" class="pct high">87.39%</td>
108
- <td data-value="1825" class="abs high">1595/1825</td>
101
+ <td data-value="80.23" class="pct high">80.23%</td>
102
+ <td data-value="2181" class="abs high">1750/2181</td>
103
+ <td data-value="64.36" class="pct medium">64.36%</td>
104
+ <td data-value="623" class="abs medium">401/623</td>
105
+ <td data-value="78.57" class="pct medium">78.57%</td>
106
+ <td data-value="490" class="abs medium">385/490</td>
107
+ <td data-value="78.57" class="pct medium">78.57%</td>
108
+ <td data-value="2002" class="abs medium">1573/2002</td>
109
109
  </tr>
110
110
 
111
111
  <tr>
112
- <td class="file high" data-value="src/adapters"><a href="src/adapters/index.html">src/adapters</a></td>
113
- <td data-value="100" class="pic high">
114
- <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
112
+ <td class="file medium" data-value="src/adapters"><a href="src/adapters/index.html">src/adapters</a></td>
113
+ <td data-value="61.71" class="pic medium">
114
+ <div class="chart"><div class="cover-fill" style="width: 61%"></div><div class="cover-empty" style="width: 39%"></div></div>
115
115
  </td>
116
- <td data-value="100" class="pct high">100%</td>
117
- <td data-value="75" class="abs high">75/75</td>
118
- <td data-value="98.21" class="pct high">98.21%</td>
119
- <td data-value="112" class="abs high">110/112</td>
120
- <td data-value="100" class="pct high">100%</td>
121
- <td data-value="16" class="abs high">16/16</td>
122
- <td data-value="100" class="pct high">100%</td>
123
- <td data-value="57" class="abs high">57/57</td>
116
+ <td data-value="61.71" class="pct medium">61.71%</td>
117
+ <td data-value="431" class="abs medium">266/431</td>
118
+ <td data-value="62.26" class="pct medium">62.26%</td>
119
+ <td data-value="424" class="abs medium">264/424</td>
120
+ <td data-value="40" class="pct low">40%</td>
121
+ <td data-value="75" class="abs low">30/75</td>
122
+ <td data-value="58.99" class="pct medium">58.99%</td>
123
+ <td data-value="378" class="abs medium">223/378</td>
124
124
  </tr>
125
125
 
126
126
  <tr>
@@ -138,36 +138,6 @@
138
138
  <td data-value="20" class="abs high">20/20</td>
139
139
  </tr>
140
140
 
141
- <tr>
142
- <td class="file high" data-value="src/templates/email"><a href="src/templates/email/index.html">src/templates/email</a></td>
143
- <td data-value="100" class="pic high">
144
- <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
145
- </td>
146
- <td data-value="100" class="pct high">100%</td>
147
- <td data-value="5" class="abs high">5/5</td>
148
- <td data-value="100" class="pct high">100%</td>
149
- <td data-value="0" class="abs high">0/0</td>
150
- <td data-value="100" class="pct high">100%</td>
151
- <td data-value="0" class="abs high">0/0</td>
152
- <td data-value="100" class="pct high">100%</td>
153
- <td data-value="5" class="abs high">5/5</td>
154
- </tr>
155
-
156
- <tr>
157
- <td class="file high" data-value="src/templates/sms"><a href="src/templates/sms/index.html">src/templates/sms</a></td>
158
- <td data-value="100" class="pic high">
159
- <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
160
- </td>
161
- <td data-value="100" class="pct high">100%</td>
162
- <td data-value="4" class="abs high">4/4</td>
163
- <td data-value="100" class="pct high">100%</td>
164
- <td data-value="0" class="abs high">0/0</td>
165
- <td data-value="100" class="pct high">100%</td>
166
- <td data-value="0" class="abs high">0/0</td>
167
- <td data-value="100" class="pct high">100%</td>
168
- <td data-value="4" class="abs high">4/4</td>
169
- </tr>
170
-
171
141
  <tr>
172
142
  <td class="file high" data-value="src/types"><a href="src/types/index.html">src/types</a></td>
173
143
  <td data-value="100" class="pic high">
@@ -185,17 +155,17 @@
185
155
 
186
156
  <tr>
187
157
  <td class="file high" data-value="src/utils"><a href="src/utils/index.html">src/utils</a></td>
188
- <td data-value="93.04" class="pic high">
189
- <div class="chart"><div class="cover-fill" style="width: 93%"></div><div class="cover-empty" style="width: 7%"></div></div>
158
+ <td data-value="88.23" class="pic high">
159
+ <div class="chart"><div class="cover-fill" style="width: 88%"></div><div class="cover-empty" style="width: 12%"></div></div>
190
160
  </td>
191
- <td data-value="93.04" class="pct high">93.04%</td>
192
- <td data-value="115" class="abs high">107/115</td>
193
- <td data-value="85.71" class="pct high">85.71%</td>
194
- <td data-value="49" class="abs high">42/49</td>
195
- <td data-value="90.9" class="pct high">90.9%</td>
196
- <td data-value="22" class="abs high">20/22</td>
197
- <td data-value="91.48" class="pct high">91.48%</td>
198
- <td data-value="94" class="abs high">86/94</td>
161
+ <td data-value="88.23" class="pct high">88.23%</td>
162
+ <td data-value="408" class="abs high">360/408</td>
163
+ <td data-value="73.88" class="pct medium">73.88%</td>
164
+ <td data-value="134" class="abs medium">99/134</td>
165
+ <td data-value="85.32" class="pct high">85.32%</td>
166
+ <td data-value="109" class="abs high">93/109</td>
167
+ <td data-value="86.9" class="pct high">86.9%</td>
168
+ <td data-value="336" class="abs high">292/336</td>
199
169
  </tr>
200
170
 
201
171
  </tbody>
@@ -206,7 +176,7 @@
206
176
  <div class='footer quiet pad2 space-top1 center small'>
207
177
  Code coverage generated by
208
178
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
209
- at 2025-06-17T18:38:18.536Z
179
+ at 2025-07-02T05:49:37.404Z
210
180
  </div>
211
181
  <script src="prettify.js"></script>
212
182
  <script>
package/index.js CHANGED
@@ -2,4 +2,4 @@
2
2
  * Copyright (c) 2019-Present, Nitrogen Labs, Inc.
3
3
  * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
4
  */
5
- module.exports = require('./lib');
5
+ export * from './lib/index.js';
package/jest.config.js ADDED
@@ -0,0 +1,17 @@
1
+ module.exports = {
2
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
3
+ testEnvironment: 'node',
4
+ transform: {
5
+ '^.+\\.ts$': 'ts-jest'
6
+ },
7
+ moduleFileExtensions: ['ts', 'js', 'json'],
8
+ transformIgnorePatterns: [
9
+ 'node_modules/(?!(zod)/)'
10
+ ],
11
+ extensionsToTreatAsEsm: ['.ts'],
12
+ globals: {
13
+ 'ts-jest': {
14
+ useESM: true
15
+ }
16
+ }
17
+ };
package/jest.setup.js CHANGED
@@ -0,0 +1,36 @@
1
+ // Centralized ArangoDB mock for all tests
2
+ jest.mock('arangojs', () => ({
3
+ ...jest.requireActual('arangojs'),
4
+ aql: jest.fn((templateStrings, ...args) => {
5
+ // Concatenate template strings and interpolate arguments
6
+ let result = '';
7
+ for (let i = 0; i < templateStrings.length; i++) {
8
+ result += templateStrings[i];
9
+ if (i < args.length) {
10
+ // Add the actual value to the template
11
+ result += args[i];
12
+ }
13
+ }
14
+ // Normalize to single line: remove newlines and normalize whitespace
15
+ const singleLine = result.replace(/\s+/g, ' ').trim();
16
+ return [singleLine, ...args];
17
+ })
18
+ }));
19
+
20
+ // Mock the useDb function from arangodbUtils with a basic default
21
+ const mockUseDb = jest.fn(() => ({
22
+ collection: jest.fn(() => ({
23
+ save: jest.fn(() => Promise.resolve()),
24
+ remove: jest.fn(() => Promise.resolve()),
25
+ update: jest.fn(() => Promise.resolve())
26
+ })),
27
+ query: jest.fn(() => Promise.resolve({
28
+ all: jest.fn(() => Promise.resolve([])),
29
+ next: jest.fn(() => Promise.resolve({}))
30
+ }))
31
+ }));
32
+
33
+ jest.mock('./src/utils/arangodbUtils', () => ({
34
+ ...jest.requireActual('./src/utils/arangodbUtils'),
35
+ useDb: mockUseDb
36
+ }));
package/lex.config.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  module.exports = {
2
2
  ai: {
3
- provider: 'cursor',
4
- model: 'cursor-code',
5
3
  maxTokens: 4000,
4
+ model: 'cursor-code',
5
+ provider: 'cursor',
6
6
  temperature: 0.1
7
7
  },
8
8
  outputPath: 'lib',