@forgehive/hive-sdk 0.0.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.
- package/LICENSE +21 -0
- package/README.md +357 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +123 -0
- package/dist/test/getLog.test.d.ts +1 -0
- package/dist/test/getLog.test.js +144 -0
- package/dist/test/index.test.d.ts +1 -0
- package/dist/test/index.test.js +96 -0
- package/dist/test/sendLog.test.d.ts +1 -0
- package/dist/test/sendLog.test.js +111 -0
- package/dist/test/setQuality.test.d.ts +1 -0
- package/dist/test/setQuality.test.js +192 -0
- package/jest.config.js +11 -0
- package/package.json +25 -0
- package/src/index.ts +168 -0
- package/src/test/getLog.test.ts +181 -0
- package/src/test/index.test.ts +126 -0
- package/src/test/sendLog.test.ts +148 -0
- package/src/test/setQuality.test.ts +268 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import { HiveLogClient, LogApiResponse, ApiError, isApiError } from '../index'
|
|
3
|
+
|
|
4
|
+
// Mock axios
|
|
5
|
+
jest.mock('axios')
|
|
6
|
+
const mockedAxios = axios as jest.Mocked<typeof axios>
|
|
7
|
+
|
|
8
|
+
describe('HiveLogClient getLog', () => {
|
|
9
|
+
const originalEnv = process.env
|
|
10
|
+
let client: HiveLogClient
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.resetModules()
|
|
14
|
+
process.env = { ...originalEnv }
|
|
15
|
+
|
|
16
|
+
// Set up environment variables
|
|
17
|
+
process.env.HIVE_API_KEY = 'test-api-key'
|
|
18
|
+
process.env.HIVE_API_SECRET = 'test-api-secret'
|
|
19
|
+
process.env.HIVE_HOST = 'https://test-host.com'
|
|
20
|
+
|
|
21
|
+
// Create client instance
|
|
22
|
+
client = new HiveLogClient('test-project')
|
|
23
|
+
|
|
24
|
+
// Clear all mocks
|
|
25
|
+
jest.clearAllMocks()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
afterAll(() => {
|
|
29
|
+
process.env = originalEnv
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
describe('successful getLog', () => {
|
|
33
|
+
it('should fetch log successfully and return LogApiResponse', async () => {
|
|
34
|
+
const mockLogResponse: LogApiResponse = {
|
|
35
|
+
uuid: 'test-uuid-123',
|
|
36
|
+
taskName: 'test-task',
|
|
37
|
+
projectName: 'test-project',
|
|
38
|
+
logItem: {
|
|
39
|
+
input: { userId: 123, action: 'login' },
|
|
40
|
+
output: { success: true, sessionId: 'abc123' },
|
|
41
|
+
error: null,
|
|
42
|
+
boundaries: {
|
|
43
|
+
database: [{ input: 'SELECT * FROM users', output: [{ id: 123 }], error: null }]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
replayFrom: 'some-replay-id',
|
|
47
|
+
createdAt: '2023-12-01T10:00:00Z'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Mock successful axios response
|
|
51
|
+
mockedAxios.get.mockResolvedValueOnce({ data: mockLogResponse })
|
|
52
|
+
|
|
53
|
+
const result = await client.getLog('test-task', 'test-uuid-123')
|
|
54
|
+
|
|
55
|
+
expect(result).toEqual(mockLogResponse)
|
|
56
|
+
expect(mockedAxios.get).toHaveBeenCalledTimes(1)
|
|
57
|
+
expect(mockedAxios.get).toHaveBeenCalledWith(
|
|
58
|
+
'https://test-host.com/api/tasks/test-task/logs/test-uuid-123',
|
|
59
|
+
{
|
|
60
|
+
headers: {
|
|
61
|
+
Authorization: 'Bearer test-api-key:test-api-secret',
|
|
62
|
+
'Content-Type': 'application/json'
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('should handle API error response', async () => {
|
|
69
|
+
const mockErrorResponse: ApiError = {
|
|
70
|
+
error: 'Log not found'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
mockedAxios.get.mockResolvedValueOnce({ data: mockErrorResponse })
|
|
74
|
+
|
|
75
|
+
const result = await client.getLog('test-task', 'non-existent-uuid')
|
|
76
|
+
|
|
77
|
+
expect(result).toEqual(mockErrorResponse)
|
|
78
|
+
expect(isApiError(result)).toBe(true)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('should handle minimal log response', async () => {
|
|
82
|
+
const mockMinimalResponse: LogApiResponse = {
|
|
83
|
+
uuid: 'minimal-uuid',
|
|
84
|
+
taskName: 'minimal-task',
|
|
85
|
+
projectName: 'test-project',
|
|
86
|
+
logItem: {
|
|
87
|
+
input: 'simple input'
|
|
88
|
+
},
|
|
89
|
+
createdAt: '2023-12-01T10:00:00Z'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
mockedAxios.get.mockResolvedValueOnce({ data: mockMinimalResponse })
|
|
93
|
+
|
|
94
|
+
const result = await client.getLog('minimal-task', 'minimal-uuid')
|
|
95
|
+
|
|
96
|
+
expect(result).toEqual(mockMinimalResponse)
|
|
97
|
+
expect(isApiError(result)).toBe(false)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
describe('failed getLog', () => {
|
|
102
|
+
it('should return null when axios throws an error', async () => {
|
|
103
|
+
// Mock axios to throw an error
|
|
104
|
+
mockedAxios.get.mockRejectedValueOnce(new Error('Network error'))
|
|
105
|
+
|
|
106
|
+
const result = await client.getLog('test-task', 'test-uuid')
|
|
107
|
+
|
|
108
|
+
expect(result).toBeNull()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('should return null when server returns 404', async () => {
|
|
112
|
+
// Mock axios to throw a 404 error
|
|
113
|
+
const notFoundError = new Error('Request failed with status code 404')
|
|
114
|
+
mockedAxios.get.mockRejectedValueOnce(notFoundError)
|
|
115
|
+
|
|
116
|
+
const result = await client.getLog('test-task', 'non-existent-uuid')
|
|
117
|
+
|
|
118
|
+
expect(result).toBeNull()
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should return null when server returns 500', async () => {
|
|
122
|
+
// Mock axios to throw a server error
|
|
123
|
+
const serverError = new Error('Server Error')
|
|
124
|
+
mockedAxios.get.mockRejectedValueOnce(serverError)
|
|
125
|
+
|
|
126
|
+
const result = await client.getLog('test-task', 'test-uuid')
|
|
127
|
+
|
|
128
|
+
expect(result).toBeNull()
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
describe('getLog parameters', () => {
|
|
133
|
+
it('should handle special characters in taskName and uuid', async () => {
|
|
134
|
+
const mockResponse: LogApiResponse = {
|
|
135
|
+
uuid: 'uuid-with-special-chars-!@#',
|
|
136
|
+
taskName: 'task-with-special-chars-!@#',
|
|
137
|
+
projectName: 'test-project',
|
|
138
|
+
logItem: { input: 'test' },
|
|
139
|
+
createdAt: '2023-12-01T10:00:00Z'
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
mockedAxios.get.mockResolvedValueOnce({ data: mockResponse })
|
|
143
|
+
|
|
144
|
+
const result = await client.getLog('task-with-special-chars-!@#', 'uuid-with-special-chars-!@#')
|
|
145
|
+
|
|
146
|
+
expect(result).toEqual(mockResponse)
|
|
147
|
+
expect(mockedAxios.get).toHaveBeenCalledWith(
|
|
148
|
+
'https://test-host.com/api/tasks/task-with-special-chars-!@#/logs/uuid-with-special-chars-!@#',
|
|
149
|
+
expect.any(Object)
|
|
150
|
+
)
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
describe('isApiError type guard', () => {
|
|
156
|
+
it('should return true for ApiError objects', () => {
|
|
157
|
+
const apiError: ApiError = { error: 'Something went wrong' }
|
|
158
|
+
expect(isApiError(apiError)).toBe(true)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it('should return false for LogApiResponse objects', () => {
|
|
162
|
+
const logResponse: LogApiResponse = {
|
|
163
|
+
uuid: 'test-uuid',
|
|
164
|
+
taskName: 'test-task',
|
|
165
|
+
projectName: 'test-project',
|
|
166
|
+
logItem: { input: 'test' },
|
|
167
|
+
createdAt: '2023-12-01T10:00:00Z'
|
|
168
|
+
}
|
|
169
|
+
expect(isApiError(logResponse)).toBe(false)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('should return false for null or undefined', () => {
|
|
173
|
+
expect(isApiError(null)).toBeFalsy()
|
|
174
|
+
expect(isApiError(undefined)).toBeFalsy()
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('should return false for objects without error property', () => {
|
|
178
|
+
expect(isApiError({ success: true })).toBe(false)
|
|
179
|
+
expect(isApiError({ data: 'some data' })).toBe(false)
|
|
180
|
+
})
|
|
181
|
+
})
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { HiveLogClient, createHiveLogClient } from '../index'
|
|
2
|
+
|
|
3
|
+
describe('Hive SDK', () => {
|
|
4
|
+
const originalEnv = process.env
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
jest.resetModules()
|
|
8
|
+
process.env = { ...originalEnv }
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
afterAll(() => {
|
|
12
|
+
process.env = originalEnv
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
describe('HiveLogClient constructor', () => {
|
|
16
|
+
it('should create client in silent mode when HIVE_API_KEY is missing', () => {
|
|
17
|
+
delete process.env.HIVE_API_KEY
|
|
18
|
+
process.env.HIVE_API_SECRET = 'test-secret'
|
|
19
|
+
process.env.HIVE_HOST = 'https://test.com'
|
|
20
|
+
|
|
21
|
+
expect(() => new HiveLogClient('test-project')).not.toThrow()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('should create client in silent mode when HIVE_API_SECRET is missing', () => {
|
|
25
|
+
process.env.HIVE_API_KEY = 'test-key'
|
|
26
|
+
delete process.env.HIVE_API_SECRET
|
|
27
|
+
process.env.HIVE_HOST = 'https://test.com'
|
|
28
|
+
|
|
29
|
+
expect(() => new HiveLogClient('test-project')).not.toThrow()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('should create client in silent mode when HIVE_HOST is missing', () => {
|
|
33
|
+
process.env.HIVE_API_KEY = 'test-key'
|
|
34
|
+
process.env.HIVE_API_SECRET = 'test-secret'
|
|
35
|
+
delete process.env.HIVE_HOST
|
|
36
|
+
|
|
37
|
+
expect(() => new HiveLogClient('test-project')).not.toThrow()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('should create client in silent mode when all environment variables are missing', () => {
|
|
41
|
+
delete process.env.HIVE_API_KEY
|
|
42
|
+
delete process.env.HIVE_API_SECRET
|
|
43
|
+
delete process.env.HIVE_HOST
|
|
44
|
+
|
|
45
|
+
expect(() => new HiveLogClient('test-project')).not.toThrow()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('should create client successfully when all environment variables are present', () => {
|
|
49
|
+
process.env.HIVE_API_KEY = 'test-key'
|
|
50
|
+
process.env.HIVE_API_SECRET = 'test-secret'
|
|
51
|
+
process.env.HIVE_HOST = 'https://test.com'
|
|
52
|
+
|
|
53
|
+
expect(() => new HiveLogClient('test-project')).not.toThrow()
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
describe('isActive method', () => {
|
|
58
|
+
it('should return false when credentials are missing', () => {
|
|
59
|
+
delete process.env.HIVE_API_KEY
|
|
60
|
+
delete process.env.HIVE_API_SECRET
|
|
61
|
+
delete process.env.HIVE_HOST
|
|
62
|
+
|
|
63
|
+
const client = new HiveLogClient('test-project')
|
|
64
|
+
expect(client.isActive()).toBe(false)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('should return true when all credentials are present', () => {
|
|
68
|
+
process.env.HIVE_API_KEY = 'test-key'
|
|
69
|
+
process.env.HIVE_API_SECRET = 'test-secret'
|
|
70
|
+
process.env.HIVE_HOST = 'https://test.com'
|
|
71
|
+
|
|
72
|
+
const client = new HiveLogClient('test-project')
|
|
73
|
+
expect(client.isActive()).toBe(true)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('createHiveLogClient factory function', () => {
|
|
78
|
+
it('should create HiveLogClient instance when env vars are present', () => {
|
|
79
|
+
process.env.HIVE_API_KEY = 'test-key'
|
|
80
|
+
process.env.HIVE_API_SECRET = 'test-secret'
|
|
81
|
+
process.env.HIVE_HOST = 'https://test.com'
|
|
82
|
+
|
|
83
|
+
const client = createHiveLogClient('test-project')
|
|
84
|
+
|
|
85
|
+
expect(client).toBeInstanceOf(HiveLogClient)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should create client in silent mode when env vars are missing', () => {
|
|
89
|
+
delete process.env.HIVE_API_KEY
|
|
90
|
+
delete process.env.HIVE_API_SECRET
|
|
91
|
+
delete process.env.HIVE_HOST
|
|
92
|
+
|
|
93
|
+
expect(() => createHiveLogClient('test-project')).not.toThrow()
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('Silent mode behavior', () => {
|
|
98
|
+
let silentClient: HiveLogClient
|
|
99
|
+
|
|
100
|
+
beforeEach(() => {
|
|
101
|
+
delete process.env.HIVE_API_KEY
|
|
102
|
+
delete process.env.HIVE_API_SECRET
|
|
103
|
+
delete process.env.HIVE_HOST
|
|
104
|
+
|
|
105
|
+
silentClient = new HiveLogClient('silent-project')
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('should return "silent" for sendLog in silent mode', async () => {
|
|
109
|
+
const result = await silentClient.sendLog('test-task', { data: 'test' })
|
|
110
|
+
expect(result).toBe('silent')
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('should throw error for getLog in silent mode', async () => {
|
|
114
|
+
await expect(silentClient.getLog('test-task', 'test-uuid')).rejects.toThrow(
|
|
115
|
+
'Missing Hive API credentials or host, get them at https://forgehive.dev'
|
|
116
|
+
)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('should throw error for setQuality in silent mode', async () => {
|
|
120
|
+
const quality = { score: 8, reason: 'test', suggestions: 'test' }
|
|
121
|
+
await expect(silentClient.setQuality('test-task', 'test-uuid', quality)).rejects.toThrow(
|
|
122
|
+
'Missing Hive API credentials or host, get them at https://forgehive.dev'
|
|
123
|
+
)
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
})
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import { HiveLogClient } from '../index'
|
|
3
|
+
|
|
4
|
+
// Mock axios
|
|
5
|
+
jest.mock('axios')
|
|
6
|
+
const mockedAxios = axios as jest.Mocked<typeof axios>
|
|
7
|
+
|
|
8
|
+
describe('HiveLogClient sendLog', () => {
|
|
9
|
+
const originalEnv = process.env
|
|
10
|
+
let client: HiveLogClient
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.resetModules()
|
|
14
|
+
process.env = { ...originalEnv }
|
|
15
|
+
|
|
16
|
+
// Set up environment variables
|
|
17
|
+
process.env.HIVE_API_KEY = 'test-api-key'
|
|
18
|
+
process.env.HIVE_API_SECRET = 'test-api-secret'
|
|
19
|
+
process.env.HIVE_HOST = 'https://test-host.com'
|
|
20
|
+
|
|
21
|
+
// Create client instance
|
|
22
|
+
client = new HiveLogClient('test-project')
|
|
23
|
+
|
|
24
|
+
// Clear all mocks
|
|
25
|
+
jest.clearAllMocks()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
afterAll(() => {
|
|
29
|
+
process.env = originalEnv
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
describe('successful sendLog', () => {
|
|
33
|
+
it('should send log successfully and return true', async () => {
|
|
34
|
+
// Mock successful axios response
|
|
35
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } })
|
|
36
|
+
|
|
37
|
+
const logItem = { input: 'test-input', output: 'test-output' }
|
|
38
|
+
const result = await client.sendLog('test-task', logItem)
|
|
39
|
+
|
|
40
|
+
expect(result).toBe('success')
|
|
41
|
+
expect(mockedAxios.post).toHaveBeenCalledTimes(1)
|
|
42
|
+
expect(mockedAxios.post).toHaveBeenCalledWith(
|
|
43
|
+
'https://test-host.com/api/tasks/log-ingest',
|
|
44
|
+
{
|
|
45
|
+
projectName: 'test-project',
|
|
46
|
+
taskName: 'test-task',
|
|
47
|
+
logItem: JSON.stringify(logItem)
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
headers: {
|
|
51
|
+
Authorization: 'Bearer test-api-key:test-api-secret',
|
|
52
|
+
'Content-Type': 'application/json'
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should handle complex log items', async () => {
|
|
59
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } })
|
|
60
|
+
|
|
61
|
+
const complexLogItem = {
|
|
62
|
+
input: { userId: 123, action: 'login' },
|
|
63
|
+
output: { success: true, sessionId: 'abc123' },
|
|
64
|
+
error: null,
|
|
65
|
+
boundaries: {
|
|
66
|
+
database: [{ input: 'SELECT * FROM users', output: [{ id: 123 }], error: null }]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const result = await client.sendLog('complex-task', complexLogItem)
|
|
71
|
+
|
|
72
|
+
expect(result).toBe('success')
|
|
73
|
+
expect(mockedAxios.post).toHaveBeenCalledWith(
|
|
74
|
+
'https://test-host.com/api/tasks/log-ingest',
|
|
75
|
+
{
|
|
76
|
+
projectName: 'test-project',
|
|
77
|
+
taskName: 'complex-task',
|
|
78
|
+
logItem: JSON.stringify(complexLogItem)
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: 'Bearer test-api-key:test-api-secret',
|
|
83
|
+
'Content-Type': 'application/json'
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('failed sendLog', () => {
|
|
91
|
+
it('should return false when axios throws an error', async () => {
|
|
92
|
+
// Mock axios to throw an error
|
|
93
|
+
mockedAxios.post.mockRejectedValueOnce(new Error('Network error'))
|
|
94
|
+
|
|
95
|
+
const logItem = { input: 'test-input' }
|
|
96
|
+
const result = await client.sendLog('test-task', logItem)
|
|
97
|
+
|
|
98
|
+
expect(result).toBe('error')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should return false when server returns 500', async () => {
|
|
102
|
+
// Mock axios to throw a server error
|
|
103
|
+
const serverError = new Error('Server Error')
|
|
104
|
+
mockedAxios.post.mockRejectedValueOnce(serverError)
|
|
105
|
+
|
|
106
|
+
const result = await client.sendLog('test-task', { input: 'test' })
|
|
107
|
+
|
|
108
|
+
expect(result).toBe('error')
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
describe('sendLog parameters', () => {
|
|
113
|
+
it('should handle empty log items', async () => {
|
|
114
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } })
|
|
115
|
+
|
|
116
|
+
const result = await client.sendLog('empty-task', {})
|
|
117
|
+
|
|
118
|
+
expect(result).toBe('success')
|
|
119
|
+
expect(mockedAxios.post).toHaveBeenCalledWith(
|
|
120
|
+
'https://test-host.com/api/tasks/log-ingest',
|
|
121
|
+
{
|
|
122
|
+
projectName: 'test-project',
|
|
123
|
+
taskName: 'empty-task',
|
|
124
|
+
logItem: JSON.stringify({})
|
|
125
|
+
},
|
|
126
|
+
expect.any(Object)
|
|
127
|
+
)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should handle null/undefined values in log items', async () => {
|
|
131
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } })
|
|
132
|
+
|
|
133
|
+
const logItem = { input: null, output: undefined, error: 'some error' }
|
|
134
|
+
const result = await client.sendLog('null-task', logItem)
|
|
135
|
+
|
|
136
|
+
expect(result).toBe('success')
|
|
137
|
+
expect(mockedAxios.post).toHaveBeenCalledWith(
|
|
138
|
+
'https://test-host.com/api/tasks/log-ingest',
|
|
139
|
+
{
|
|
140
|
+
projectName: 'test-project',
|
|
141
|
+
taskName: 'null-task',
|
|
142
|
+
logItem: JSON.stringify(logItem)
|
|
143
|
+
},
|
|
144
|
+
expect.any(Object)
|
|
145
|
+
)
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
})
|