biz-a-cli 2.3.72 → 2.3.74

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.
@@ -1,231 +0,0 @@
1
- import { Server as ioServer } from "socket.io";
2
- import { createServer } from "node:http";
3
- import { io as ioClient } from "socket.io-client";
4
- import { jest } from "@jest/globals";
5
-
6
- const mockAddApp = jest.fn().mockResolvedValue({ success: true, data: { uploaded: true } });
7
- jest.unstable_mockModule("../bin/app.js", () => ({
8
- addApp: mockAddApp,
9
- }));
10
-
11
- const { streamEvent } = await import("../bin/hubEvent.js");
12
-
13
- let socketsBySubdomain = {};
14
-
15
- const createSockTunnel2CLI = (socket) => {
16
- return (subdomain, responseCb) => {
17
- const responseCallback = (error) => {
18
- if (responseCb) responseCb(error);
19
- };
20
- let subdomainStr = subdomain.toString();
21
-
22
- socketsBySubdomain[subdomainStr] = socket;
23
- socket.subdomain = subdomainStr;
24
-
25
- responseCallback(null);
26
- };
27
- };
28
-
29
- const deleteSubdomain = (socket) => () => {
30
- if (socket.subdomain) {
31
- delete socketsBySubdomain[socket.subdomain];
32
- }
33
- };
34
-
35
- const toPromise = (cb) =>
36
- new Promise((resolve, reject) => {
37
- cb(resolve);
38
- setTimeout(() => reject(new Error("timeout")), 1000);
39
- });
40
-
41
- describe("Hub publish request tests", () => {
42
- let bizAServerSocket, httpServer, port, logSpy;
43
-
44
- beforeAll((done) => {
45
- logSpy = jest.spyOn(console, "log").mockImplementation(() => {});
46
- httpServer = createServer();
47
- bizAServerSocket = new ioServer(httpServer);
48
- bizAServerSocket.on("connection", (socket) => {
49
- socket.on("createTunnel", createSockTunnel2CLI(socket));
50
- socket.on("disconnect", deleteSubdomain(socket));
51
- });
52
- httpServer.listen(() => {
53
- port = httpServer.address().port;
54
- done();
55
- });
56
- });
57
-
58
- beforeEach(() => {
59
- mockAddApp.mockClear();
60
- delete process.env.BIZA_APP_SKIP_PARSE;
61
- });
62
-
63
- afterAll(() => {
64
- bizAServerSocket.close();
65
- httpServer.close();
66
- logSpy.mockRestore();
67
- });
68
-
69
- test("publish-req should execute addApp and pass body scripts", async () => {
70
- const subdomain = "publish-room";
71
- const socket = ioClient(`http://localhost:${port}`);
72
- await streamEvent(socket, {
73
- server: `http://localhost:${port}`,
74
- subdomain,
75
- hostname: "localhost",
76
- port: 212,
77
- serverport: 3002,
78
- dbindex: 7,
79
- });
80
-
81
- const publishBody = {
82
- options: {
83
- workingDir: "c:/tmp/app",
84
- verbose: true,
85
- server: "https://srv",
86
- apiPort: "1205",
87
- dbIndex: "2",
88
- sub: "unit-sub",
89
- files: [{ name: "a.js" }],
90
- },
91
- scripts: {
92
- "a.js": "get = function () { return {unit: true} }",
93
- },
94
- };
95
-
96
- const response = await toPromise((resolve) =>
97
- socketsBySubdomain[subdomain].emit(
98
- "publish-req",
99
- {
100
- path: "/publish",
101
- method: "POST",
102
- query: { subdomain },
103
- body: publishBody,
104
- headers: { "content-type": "application/json" },
105
- },
106
- (cb) => resolve(cb)
107
- )
108
- );
109
-
110
- expect(mockAddApp).toHaveBeenCalledTimes(1);
111
- expect(mockAddApp).toHaveBeenCalledWith({
112
- workingDir: "c:/tmp/app",
113
- verbose: true,
114
- server: "https://srv",
115
- apiPort: 1205,
116
- dbIndex: 2,
117
- sub: "unit-sub",
118
- files: [{ name: "a.js" }],
119
- body: publishBody,
120
- });
121
- expect(response).toStrictEqual({ success: true, data: { uploaded: true } });
122
- expect(process.env.BIZA_APP_SKIP_PARSE).toBeUndefined();
123
-
124
- socket.disconnect();
125
- });
126
-
127
- test("publish-req should treat data.body as direct addApp http payload", async () => {
128
- const subdomain = "publish-room-http";
129
- const socket = ioClient(`http://localhost:${port}`);
130
- await streamEvent(socket, {
131
- server: `http://localhost:${port}`,
132
- subdomain,
133
- hostname: "localhost",
134
- port: 212,
135
- serverport: 3002,
136
- dbindex: 7,
137
- });
138
-
139
- const publishBody = {
140
- verbose: false,
141
- fileList: [{ name: "a.js" }],
142
- scripts: {
143
- "a.js": "get = function () { return {direct: true} }",
144
- },
145
- };
146
-
147
- const response = await toPromise((resolve) =>
148
- socketsBySubdomain[subdomain].emit(
149
- "publish-req",
150
- {
151
- path: "/publish",
152
- method: "POST",
153
- query: { subdomain },
154
- body: publishBody,
155
- headers: { "content-type": "application/json" },
156
- },
157
- (cb) => resolve(cb)
158
- )
159
- );
160
-
161
- expect(mockAddApp).toHaveBeenCalledTimes(1);
162
- expect(mockAddApp).toHaveBeenCalledWith({
163
- workingDir: expect.any(String),
164
- verbose: false,
165
- server: `http://localhost:${port}`,
166
- apiPort: 212,
167
- dbIndex: 7,
168
- sub: subdomain,
169
- files: [{ name: "a.js" }],
170
- body: publishBody,
171
- });
172
- expect(response).toStrictEqual({ success: true, data: { uploaded: true } });
173
- expect(process.env.BIZA_APP_SKIP_PARSE).toBeUndefined();
174
-
175
- socket.disconnect();
176
- });
177
-
178
- test("publish-req should support double-wrapper payload from HTTP client", async () => {
179
- const subdomain = "publish-room-double-wrapper";
180
- const socket = ioClient(`http://localhost:${port}`);
181
- await streamEvent(socket, {
182
- server: `http://localhost:${port}`,
183
- subdomain,
184
- hostname: "localhost",
185
- port: 212,
186
- serverport: 3002,
187
- dbindex: 7,
188
- });
189
-
190
- const publishBody = {
191
- fileList: [{ name: "menu.json" }, { name: "loginform.js" }],
192
- scripts: {
193
- "menu.json": '[{"menuName":"","caption":"Home","link":["./main"],"subMenu":[]}]',
194
- "loginform.js": 'get = function () { return {model:{}, tableName:"", fields:[], functions:{ beforeLoadData: function (id) {} }}; };',
195
- },
196
- };
197
-
198
- const response = await toPromise((resolve) =>
199
- socketsBySubdomain[subdomain].emit(
200
- "publish-req",
201
- {
202
- path: "/publish",
203
- method: "POST",
204
- query: { subdomain },
205
- headers: { "content-type": "application/json" },
206
- body: {
207
- method: "POST",
208
- query: { subdomain },
209
- body: publishBody,
210
- },
211
- },
212
- (cb) => resolve(cb)
213
- )
214
- );
215
-
216
- expect(mockAddApp).toHaveBeenCalledTimes(1);
217
- expect(mockAddApp).toHaveBeenCalledWith({
218
- workingDir: expect.any(String),
219
- verbose: false,
220
- server: `http://localhost:${port}`,
221
- apiPort: 212,
222
- dbIndex: 7,
223
- sub: subdomain,
224
- files: [{ name: "menu.json" }, { name: "loginform.js" }],
225
- body: publishBody,
226
- });
227
- expect(response).toStrictEqual({ success: true, data: { uploaded: true } });
228
-
229
- socket.disconnect();
230
- });
231
- });
@@ -1,44 +0,0 @@
1
-
2
- import { jest } from '@jest/globals'
3
-
4
- let mockSendMail = jest.fn();
5
- const mockCreateTransport = jest.fn();
6
- mockCreateTransport.mockImplementation(() => ({
7
- sendMail: mockSendMail
8
- }))
9
-
10
- jest.unstable_mockModule('nodemailer', () => ({
11
- createTransport: (data) => mockCreateTransport(data)
12
- }))
13
-
14
- const { sendMailCliScript } = await import('../mailController.js');
15
-
16
- describe('Mail Controller', () => {
17
- let req;
18
-
19
- test('transporter.sendMailCliScript is called', async () => {
20
- const logSpy = jest.spyOn(console, 'log').mockImplementation();
21
-
22
- req = {
23
- body: {
24
- companyname: 'abc',
25
- smtpConfig: {
26
- smtp: 'test'
27
- }
28
- },
29
- }
30
-
31
- mockSendMail.mockResolvedValue('OK');
32
- expect(await sendMailCliScript(req)).toEqual('OK');
33
- expect(mockSendMail).toBeCalledTimes(1);
34
- expect(mockCreateTransport).toHaveBeenCalledWith({ smtp: 'test' });
35
-
36
- mockSendMail.mockRejectedValue({ message: 'error' });
37
- expect(await sendMailCliScript(req)).toEqual('error');
38
-
39
- expect(mockSendMail).toBeCalledTimes(2);
40
- expect(logSpy).toHaveBeenCalledWith('Error: error');
41
-
42
- logSpy.mockRestore();
43
- })
44
- })
@@ -1,187 +0,0 @@
1
- import { jest } from '@jest/globals'
2
- const { ObjectId } = await import('mongodb');
3
-
4
- const CONFIGS = [{
5
- companyObjectId: new ObjectId('62948492f7d559fba6f32196')
6
- }]
7
-
8
- const RAW_WATCHERS = [{
9
- watcher_id: 1,
10
- company_id: '62948492f7d559fba6f32196',
11
- timer_id: 1,
12
- timer_watcher_id: 1,
13
- name: 'New Watcher 1',
14
- active: true,
15
- timezone: 'Asia/Jakarta',
16
- templateName: 'cekUser.js',
17
- seq: 0,
18
- daily_days: '0,1,2,3,4,5,6',
19
- weekly_ordinal: '',
20
- weekly_days: '',
21
- monthly_days: '',
22
- minutely_everymin: 1,
23
- minutely_time_from: '08:00',
24
- minutely_time_to: '22:00',
25
- hourly_hours: '',
26
- scriptid: 1,
27
- cli_script: 'abc'
28
- }];
29
-
30
- const mockCheckSchedule = jest.fn();
31
- jest.unstable_mockModule("../scheduler/datalib.js", () => ({
32
- checkSchedule: mockCheckSchedule.mockResolvedValue('OK'),
33
- queryData: jest.fn().mockResolvedValue('OK'),
34
- crudData: jest.fn().mockResolvedValue('OK'),
35
- genId: jest.fn().mockResolvedValue('OK'),
36
- delay: jest.fn().mockResolvedValue('OK')
37
- }))
38
-
39
- jest.unstable_mockModule("../scheduler/watcherController.js", () => ({
40
- getWatchers: jest.fn(async () => {
41
- await new Promise((resolve) => setTimeout(resolve, 10));
42
- return RAW_WATCHERS;
43
- }),
44
- getHistories: jest.fn().mockResolvedValue('OK')
45
- }))
46
-
47
- const mockLoopTimer = jest.fn();
48
- jest.unstable_mockModule("../scheduler/watcherLib.js", () => ({
49
- loopTimer: mockLoopTimer.mockResolvedValue('OK'),
50
- isItTime: jest.fn().mockResolvedValue('OK'),
51
- }))
52
-
53
- const {
54
- // SCHEDULE_INTERVAL,
55
- getSelectedData,
56
- increaseInterval,
57
- runHistory,
58
- runRecentSchedule,
59
- setConstantInterval
60
- } = await import('../scheduler/timer.js');
61
-
62
-
63
- describe('timer and mitigation test', () => {
64
- test('increase interval', async () => {
65
- const nextTime = increaseInterval('2024-02-16T10:30:10.593Z');
66
- expect(new Date(nextTime).toISOString()).toStrictEqual('2024-02-16T10:31:10.593Z');
67
- });
68
-
69
- test('get selected data from array', async () => {
70
- const SELECTED_HISTORY = {
71
- _id: new ObjectId('65c34df55e7c9d9448804738'),
72
- timerObjectId: new ObjectId('65c34bd774ae2595b5efb5a9'),
73
- latestRun: '2024-02-03T10:30:10.593Z'
74
- };
75
- const HISTORIES = [
76
- {
77
- _id: new ObjectId('65c34df55e7c9d9448804737'),
78
- timerObjectId: new ObjectId('65c34bd774ae2595b5efb5a8'),
79
- latestRun: '2024-02-16T10:30:10.593Z'
80
- },
81
- SELECTED_HISTORY,
82
- {
83
- _id: new ObjectId('65c3613d5e7c9d94489a32d2'),
84
- timerObjectId: new ObjectId('65c35aa937be3a626388ba6e'),
85
- latestRun: '2024-02-04T11:00:26.783Z'
86
- }
87
- ]
88
- expect(getSelectedData(HISTORIES, 'timerObjectId', '65c34bd774ae2595b5efb5a9')).toStrictEqual(SELECTED_HISTORY);
89
- });
90
-
91
- test('run history', async () => {
92
- // function decreaseInterval(now) {
93
- // const subtractInterval = new Date(now).getMilliseconds() - (3 * SCHEDULE_INTERVAL);
94
- // return new Date(now).setMilliseconds(subtractInterval);
95
- // }
96
-
97
- // const NOW = new Date('2024-02-29T07:00:00.000Z');
98
- const HISTORIES = [
99
- {
100
- _id: new ObjectId('65c34df55e7c9d9448804737'),
101
- timerObjectId: new ObjectId('65c34bd774ae2595b5efb5a8'),
102
- latestRun: '2024-02-29 6:56:30 AM'
103
- // latestRun: new Date(decreaseInterval(NOW)).toISOString()
104
- }
105
- ]
106
-
107
- const WATCHERS = [
108
- {
109
- _id: new ObjectId('65c34bd674ae2595b5efb5a7'),
110
- companyObjectId: new ObjectId('62948492f7d559fba6f32196'),
111
- timer: [
112
- {
113
- _id: new ObjectId('65c34bd774ae2595b5efb5a8'),
114
- name: 'New Watcher 1',
115
- active: true,
116
- timezone: 'Asia/Jakarta',
117
- templateName: 'cekUser.js',
118
- daily: [
119
- 0, 1, 2, 3,
120
- 4, 5, 6
121
- ],
122
- minutely: { everyMin: 1, from: '09:00', to: '18:00' },
123
- watcherObjectId: new ObjectId('65c34bd674ae2595b5efb5a7'),
124
- seq: 0,
125
- }
126
- ]
127
- }
128
- ]
129
-
130
- await runHistory(HISTORIES, CONFIGS, WATCHERS, new Date('2024-02-29T07:00:00.000Z'));
131
- expect(mockCheckSchedule).toBeCalledTimes(3);
132
- });
133
-
134
- test('run recent schedule with delay functions', async () => {
135
- const startTime = Date.now();
136
-
137
- const WATCHER_CONVERTED = [{
138
- "_id": 1,
139
- "watcherObjectId": 1,
140
- "name": "New Watcher 1",
141
- "active": true,
142
- "timezone": "Asia/Jakarta",
143
- "templateName": "cekUser.js",
144
- "seq": 0,
145
- "scriptid": 1,
146
- "script": "\"abc\"",
147
- "daily": [0, 1, 2, 3, 4, 5, 6],
148
- "minutely": {
149
- "everyMin": 1,
150
- "from": "08:00",
151
- "to": "22:00"
152
- }
153
- }];
154
-
155
- await runRecentSchedule(startTime, CONFIGS[0]);
156
- expect(mockLoopTimer).toHaveBeenCalledWith(WATCHER_CONVERTED, startTime, CONFIGS[0], true);
157
- });
158
-
159
- test('constant interval', async () => {
160
- jest.useFakeTimers();
161
- jest.spyOn(global, 'setTimeout');
162
-
163
- const interval = 1000;
164
- const startTime = Date.now();
165
- const generator = setConstantInterval(interval, startTime);
166
-
167
- let results = [];
168
-
169
- const fetchNextValue = async () => {
170
- const next = generator.next();
171
- jest.advanceTimersByTime(interval);
172
-
173
- return (await next).value;
174
- };
175
-
176
- results.push(await fetchNextValue());
177
- results.push(await fetchNextValue());
178
- results.push(await fetchNextValue());
179
-
180
- expect(results[0]).toBe(startTime);
181
- expect(results[1]).toBe(startTime + interval);
182
- expect(results[2]).toBe(startTime + 2 * interval);
183
- expect(results[3]).toBe(undefined);
184
-
185
- jest.useRealTimers();
186
- });
187
- })