11import { describe , it , expect } from 'vitest' ;
2- import { ActionSchema , ActionParamSchema , type Action } from './action.zod' ;
2+ import { ActionSchema , ActionParamSchema , Action , type Action as ActionType } from './action.zod' ;
33
44describe ( 'ActionParamSchema' , ( ) => {
55 it ( 'should accept minimal action parameter' , ( ) => {
@@ -43,7 +43,7 @@ describe('ActionParamSchema', () => {
4343describe ( 'ActionSchema' , ( ) => {
4444 describe ( 'Basic Action Properties' , ( ) => {
4545 it ( 'should accept minimal action' , ( ) => {
46- const action : Action = {
46+ const action : ActionType = {
4747 name : 'approve' ,
4848 label : 'Approve' ,
4949 } ;
@@ -66,7 +66,7 @@ describe('ActionSchema', () => {
6666 } ) ;
6767
6868 it ( 'should accept action with icon' , ( ) => {
69- const action : Action = {
69+ const action : ActionType = {
7070 name : 'delete_record' ,
7171 label : 'Delete' ,
7272 icon : 'trash-2' ,
@@ -81,7 +81,7 @@ describe('ActionSchema', () => {
8181 const types = [ 'script' , 'url' , 'modal' , 'flow' , 'api' ] as const ;
8282
8383 types . forEach ( type => {
84- const action : Action = {
84+ const action : ActionType = {
8585 name : 'test_action' ,
8686 label : 'Test' ,
8787 type,
@@ -112,7 +112,7 @@ describe('ActionSchema', () => {
112112 'global_nav' ,
113113 ] as const ;
114114
115- const action : Action = {
115+ const action : ActionType = {
116116 name : 'multi_location' ,
117117 label : 'Multi Location' ,
118118 locations,
@@ -122,7 +122,7 @@ describe('ActionSchema', () => {
122122 } ) ;
123123
124124 it ( 'should accept single location' , ( ) => {
125- const action : Action = {
125+ const action : ActionType = {
126126 name : 'toolbar_action' ,
127127 label : 'Toolbar Action' ,
128128 locations : [ 'list_toolbar' ] ,
@@ -134,7 +134,7 @@ describe('ActionSchema', () => {
134134
135135 describe ( 'Action Targets' , ( ) => {
136136 it ( 'should accept URL action with target' , ( ) => {
137- const action : Action = {
137+ const action : ActionType = {
138138 name : 'open_external' ,
139139 label : 'Open External' ,
140140 type : 'url' ,
@@ -145,7 +145,7 @@ describe('ActionSchema', () => {
145145 } ) ;
146146
147147 it ( 'should accept flow action with target' , ( ) => {
148- const action : Action = {
148+ const action : ActionType = {
149149 name : 'run_approval_flow' ,
150150 label : 'Run Approval' ,
151151 type : 'flow' ,
@@ -156,7 +156,7 @@ describe('ActionSchema', () => {
156156 } ) ;
157157
158158 it ( 'should accept API action with target' , ( ) => {
159- const action : Action = {
159+ const action : ActionType = {
160160 name : 'call_api' ,
161161 label : 'Call API' ,
162162 type : 'api' ,
@@ -169,7 +169,7 @@ describe('ActionSchema', () => {
169169
170170 describe ( 'Action Parameters' , ( ) => {
171171 it ( 'should accept action with parameters' , ( ) => {
172- const action : Action = {
172+ const action : ActionType = {
173173 name : 'transfer_ownership' ,
174174 label : 'Transfer Ownership' ,
175175 type : 'script' ,
@@ -193,7 +193,7 @@ describe('ActionSchema', () => {
193193 } ) ;
194194
195195 it ( 'should accept action with select parameter' , ( ) => {
196- const action : Action = {
196+ const action : ActionType = {
197197 name : 'change_status' ,
198198 label : 'Change Status' ,
199199 params : [
@@ -216,7 +216,7 @@ describe('ActionSchema', () => {
216216
217217 describe ( 'UX Behavior' , ( ) => {
218218 it ( 'should accept action with confirmation' , ( ) => {
219- const action : Action = {
219+ const action : ActionType = {
220220 name : 'delete_all' ,
221221 label : 'Delete All' ,
222222 confirmText : 'Are you sure you want to delete all records? This cannot be undone.' ,
@@ -226,7 +226,7 @@ describe('ActionSchema', () => {
226226 } ) ;
227227
228228 it ( 'should accept action with success message' , ( ) => {
229- const action : Action = {
229+ const action : ActionType = {
230230 name : 'send_notification' ,
231231 label : 'Send Notification' ,
232232 successMessage : 'Notification sent successfully!' ,
@@ -236,7 +236,7 @@ describe('ActionSchema', () => {
236236 } ) ;
237237
238238 it ( 'should accept action that refreshes view' , ( ) => {
239- const action : Action = {
239+ const action : ActionType = {
240240 name : 'update_status' ,
241241 label : 'Update Status' ,
242242 refreshAfter : true ,
@@ -246,7 +246,7 @@ describe('ActionSchema', () => {
246246 } ) ;
247247
248248 it ( 'should accept action with all UX properties' , ( ) => {
249- const action : Action = {
249+ const action : ActionType = {
250250 name : 'complete_task' ,
251251 label : 'Complete Task' ,
252252 confirmText : 'Mark this task as complete?' ,
@@ -260,7 +260,7 @@ describe('ActionSchema', () => {
260260
261261 describe ( 'Visibility Control' , ( ) => {
262262 it ( 'should accept action with visibility formula' , ( ) => {
263- const action : Action = {
263+ const action : ActionType = {
264264 name : 'approve' ,
265265 label : 'Approve' ,
266266 visible : 'status == "pending" && user.can_approve' ,
@@ -272,7 +272,7 @@ describe('ActionSchema', () => {
272272
273273 describe ( 'Real-World Action Examples' , ( ) => {
274274 it ( 'should accept approve opportunity action' , ( ) => {
275- const approveAction : Action = {
275+ const approveAction : ActionType = {
276276 name : 'approve_opportunity' ,
277277 label : 'Approve' ,
278278 icon : 'check-circle' ,
@@ -289,7 +289,7 @@ describe('ActionSchema', () => {
289289 } ) ;
290290
291291 it ( 'should accept transfer case action with parameters' , ( ) => {
292- const transferAction : Action = {
292+ const transferAction : ActionType = {
293293 name : 'transfer_case' ,
294294 label : 'Transfer Case' ,
295295 icon : 'arrow-right' ,
@@ -323,7 +323,7 @@ describe('ActionSchema', () => {
323323 } ) ;
324324
325325 it ( 'should accept send email action' , ( ) => {
326- const emailAction : Action = {
326+ const emailAction : ActionType = {
327327 name : 'send_quote' ,
328328 label : 'Send Quote' ,
329329 icon : 'mail' ,
@@ -355,7 +355,7 @@ describe('ActionSchema', () => {
355355 } ) ;
356356
357357 it ( 'should accept export to Excel action' , ( ) => {
358- const exportAction : Action = {
358+ const exportAction : ActionType = {
359359 name : 'export_excel' ,
360360 label : 'Export to Excel' ,
361361 icon : 'file-spreadsheet' ,
@@ -369,7 +369,7 @@ describe('ActionSchema', () => {
369369 } ) ;
370370
371371 it ( 'should accept delete action with confirmation' , ( ) => {
372- const deleteAction : Action = {
372+ const deleteAction : ActionType = {
373373 name : 'delete_record' ,
374374 label : 'Delete' ,
375375 icon : 'trash-2' ,
@@ -386,7 +386,7 @@ describe('ActionSchema', () => {
386386 } ) ;
387387
388388 it ( 'should accept clone record action' , ( ) => {
389- const cloneAction : Action = {
389+ const cloneAction : ActionType = {
390390 name : 'clone_record' ,
391391 label : 'Clone' ,
392392 icon : 'copy' ,
@@ -409,7 +409,7 @@ describe('ActionSchema', () => {
409409 } ) ;
410410
411411 it ( 'should accept open external link action' , ( ) => {
412- const linkAction : Action = {
412+ const linkAction : ActionType = {
413413 name : 'view_on_map' ,
414414 label : 'View on Map' ,
415415 icon : 'map-pin' ,
@@ -423,3 +423,50 @@ describe('ActionSchema', () => {
423423 } ) ;
424424 } ) ;
425425} ) ;
426+
427+ describe ( 'Action Factory' , ( ) => {
428+ it ( 'should create action with default values via factory' , ( ) => {
429+ const action = Action . create ( {
430+ name : 'test_action' ,
431+ label : 'Test Action' ,
432+ } ) ;
433+
434+ expect ( action . name ) . toBe ( 'test_action' ) ;
435+ expect ( action . label ) . toBe ( 'Test Action' ) ;
436+ expect ( action . type ) . toBe ( 'script' ) ;
437+ expect ( action . refreshAfter ) . toBe ( false ) ;
438+ } ) ;
439+
440+ it ( 'should create action without refreshAfter property (uses default)' , ( ) => {
441+ const action = Action . create ( {
442+ name : 'send_email' ,
443+ label : 'Send Email' ,
444+ type : 'flow' ,
445+ target : 'email_flow' ,
446+ } ) ;
447+
448+ expect ( action . refreshAfter ) . toBe ( false ) ;
449+ } ) ;
450+
451+ it ( 'should create action with explicit refreshAfter' , ( ) => {
452+ const action = Action . create ( {
453+ name : 'update_record' ,
454+ label : 'Update' ,
455+ refreshAfter : true ,
456+ } ) ;
457+
458+ expect ( action . refreshAfter ) . toBe ( true ) ;
459+ } ) ;
460+
461+ it ( 'should validate snake_case name in factory' , ( ) => {
462+ expect ( ( ) => Action . create ( {
463+ name : 'invalidName' ,
464+ label : 'Invalid' ,
465+ } ) ) . toThrow ( ) ;
466+
467+ expect ( ( ) => Action . create ( {
468+ name : 'valid_name' ,
469+ label : 'Valid' ,
470+ } ) ) . not . toThrow ( ) ;
471+ } ) ;
472+ } ) ;
0 commit comments