@@ -2,34 +2,38 @@ import { expect, describe, it } from 'vitest';
2
2
import { exec } from './exec.js' ;
3
3
import type { NangoProps , SyncConfig } from '@nangohq/shared' ;
4
4
5
+ function getNangoProps ( ) : NangoProps {
6
+ return {
7
+ scriptType : 'sync' ,
8
+ host : 'http://localhost:3003' ,
9
+ connectionId : 'connection-id' ,
10
+ environmentId : 1 ,
11
+ providerConfigKey : 'provider-config-key' ,
12
+ provider : 'provider' ,
13
+ activityLogId : '1' ,
14
+ secretKey : 'secret-key' ,
15
+ nangoConnectionId : 1 ,
16
+ syncId : 'sync-id' ,
17
+ syncJobId : 1 ,
18
+ lastSyncDate : new Date ( ) ,
19
+ dryRun : true ,
20
+ attributes : { } ,
21
+ track_deletes : false ,
22
+ logMessages : {
23
+ counts : { updated : 0 , added : 0 , deleted : 0 } ,
24
+ messages : [ ]
25
+ } ,
26
+ syncConfig : { } as SyncConfig ,
27
+ debug : false ,
28
+ startedAt : new Date ( ) ,
29
+ runnerFlags : { } as any ,
30
+ stubbedMetadata : { }
31
+ } ;
32
+ }
33
+
5
34
describe ( 'Exec' , ( ) => {
6
35
it ( 'execute code' , async ( ) => {
7
- const nangoProps : NangoProps = {
8
- scriptType : 'sync' ,
9
- host : 'http://localhost:3003' ,
10
- connectionId : 'connection-id' ,
11
- environmentId : 1 ,
12
- providerConfigKey : 'provider-config-key' ,
13
- provider : 'provider' ,
14
- activityLogId : '1' ,
15
- secretKey : 'secret-key' ,
16
- nangoConnectionId : 1 ,
17
- syncId : 'sync-id' ,
18
- syncJobId : 1 ,
19
- lastSyncDate : new Date ( ) ,
20
- dryRun : true ,
21
- attributes : { } ,
22
- track_deletes : false ,
23
- logMessages : {
24
- counts : { updated : 0 , added : 0 , deleted : 0 } ,
25
- messages : [ ]
26
- } ,
27
- syncConfig : { } as SyncConfig ,
28
- debug : false ,
29
- startedAt : new Date ( ) ,
30
- runnerFlags : { } as any ,
31
- stubbedMetadata : { }
32
- } ;
36
+ const nangoProps = getNangoProps ( ) ;
33
37
const jsCode = `
34
38
f = async (nango) => {
35
39
const s = nango.lastSyncDate.toISOString();
@@ -42,4 +46,107 @@ describe('Exec', () => {
42
46
expect ( res . error ) . toEqual ( null ) ;
43
47
expect ( res . success ) . toEqual ( true ) ;
44
48
} ) ;
49
+
50
+ it ( 'should return a formatted error when receiving an Error' , async ( ) => {
51
+ const nangoProps = getNangoProps ( ) ;
52
+ const jsCode = `
53
+ fn = async (nango) => {
54
+ throw new Error('foobar')
55
+ };
56
+ exports.default = fn
57
+ ` ;
58
+ const res = await exec ( nangoProps , jsCode ) ;
59
+ expect ( res . error ) . toEqual ( {
60
+ payload : {
61
+ message : 'foobar' ,
62
+ name : 'Error'
63
+ } ,
64
+ status : 500 ,
65
+ type : 'script_internal_error'
66
+ } ) ;
67
+ expect ( res . success ) . toEqual ( false ) ;
68
+ } ) ;
69
+
70
+ it ( 'should return a formatted error when receiving an ActionError' , async ( ) => {
71
+ const nangoProps = getNangoProps ( ) ;
72
+ const jsCode = `
73
+ fn = async (nango) => {
74
+ throw new nango.ActionError({ message: 'foobar', prop: 'foobar' })
75
+ };
76
+ exports.default = fn
77
+ ` ;
78
+ const res = await exec ( nangoProps , jsCode ) ;
79
+ expect ( res . error ) . toEqual ( {
80
+ payload : {
81
+ message : 'foobar' ,
82
+ prop : 'foobar'
83
+ } ,
84
+ status : 500 ,
85
+ type : 'action_script_runtime_error'
86
+ } ) ;
87
+ expect ( res . success ) . toEqual ( false ) ;
88
+ } ) ;
89
+
90
+ it ( 'should return a formatted error when receiving an ActionError with an array' , async ( ) => {
91
+ const nangoProps = getNangoProps ( ) ;
92
+ const jsCode = `
93
+ fn = async (nango) => {
94
+ throw new nango.ActionError([{id: "foobar"}])
95
+ };
96
+ exports.default = fn
97
+ ` ;
98
+ const res = await exec ( nangoProps , jsCode ) ;
99
+ expect ( res . error ) . toEqual ( {
100
+ payload : {
101
+ message : [ { id : 'foobar' } ]
102
+ } ,
103
+ status : 500 ,
104
+ type : 'action_script_runtime_error'
105
+ } ) ;
106
+ expect ( res . success ) . toEqual ( false ) ;
107
+ } ) ;
108
+
109
+ it ( 'should return a formatted error when receiving an invalid error' , async ( ) => {
110
+ const nangoProps = getNangoProps ( ) ;
111
+ const jsCode = `
112
+ fn = async (nango) => {
113
+ throw new Object({})
114
+ };
115
+ exports.default = fn
116
+ ` ;
117
+ const res = await exec ( nangoProps , jsCode ) ;
118
+ expect ( res . error ) . toEqual ( {
119
+ payload : {
120
+ name : 'Error'
121
+ } ,
122
+ status : 500 ,
123
+ type : 'script_internal_error'
124
+ } ) ;
125
+ expect ( res . success ) . toEqual ( false ) ;
126
+ } ) ;
127
+
128
+ it ( 'should return a formatted error when receiving an AxiosError (without a body)' , async ( ) => {
129
+ const nangoProps = getNangoProps ( ) ;
130
+ const jsCode = `
131
+ fn = async (nango) => {
132
+ await nango.get({
133
+ endpoint: '/',
134
+ baseUrl: 'https://example.dev/'
135
+ })
136
+ };
137
+ exports.default = fn
138
+ ` ;
139
+ const res = await exec ( nangoProps , jsCode ) ;
140
+
141
+ // NB: it will fail because Nango is not running not because the website is not reachable
142
+ // NB2: the message is different depending on the system running Node
143
+ expect ( res . error ) . toMatchObject ( {
144
+ payload : {
145
+ code : 'ECONNREFUSED'
146
+ } ,
147
+ status : 500 ,
148
+ type : 'script_http_error'
149
+ } ) ;
150
+ expect ( res . success ) . toEqual ( false ) ;
151
+ } ) ;
45
152
} ) ;
0 commit comments