Skip to content

Commit 30c18fe

Browse files
committed
Add json toggle
1 parent 0539cf6 commit 30c18fe

2 files changed

Lines changed: 149 additions & 3 deletions

File tree

packages/blocks/store/src/lib/actions/store-get-action.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createAction, Property, Validators } from '@openops/blocks-framework';
2+
import { tryParseJson } from '@openops/common';
23
import { common, getScopeAndKey } from './common';
34

45
export const storageGetAction = createAction({
@@ -25,6 +26,12 @@ export const storageGetAction = createAction({
2526
required: false,
2627
}),
2728
store_scope: common.store_scope,
29+
parseJSON: Property.Checkbox({
30+
displayName: 'Parse as JSON',
31+
description: 'Convert output into a JSON object',
32+
required: false,
33+
defaultValue: false,
34+
}),
2835
},
2936
async run(context) {
3037
const { key, scope } = getScopeAndKey({
@@ -33,9 +40,15 @@ export const storageGetAction = createAction({
3340
key: context.propsValue['key'],
3441
scope: context.propsValue.store_scope,
3542
});
36-
return (
43+
44+
const value =
3745
(await context.store.get(key, scope)) ??
38-
context.propsValue['defaultValue']
39-
);
46+
context.propsValue['defaultValue'];
47+
48+
if (context.propsValue['parseJSON']) {
49+
return tryParseJson(value);
50+
}
51+
52+
return value;
4053
},
4154
});
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import { BlockStoreScope } from '../../src/lib/actions/common';
2+
import { storageGetAction } from '../../src/lib/actions/store-get-action';
3+
4+
type StorageGetContext = Parameters<typeof storageGetAction.run>[0];
5+
6+
describe('Storage Get Action', () => {
7+
const createMockContext = (isTest = false): StorageGetContext => {
8+
return {
9+
run: {
10+
id: 'test-run-id',
11+
isTest,
12+
},
13+
propsValue: {
14+
key: 'test-key',
15+
store_scope: BlockStoreScope.RUN,
16+
parseJSON: false,
17+
},
18+
store: {
19+
get: jest.fn(),
20+
put: jest.fn(),
21+
delete: jest.fn(),
22+
list: jest.fn(),
23+
},
24+
} as unknown as StorageGetContext;
25+
};
26+
27+
beforeEach(() => {
28+
jest.clearAllMocks();
29+
});
30+
31+
describe('Store get action', () => {
32+
test('should create action with correct properties', () => {
33+
expect(storageGetAction.props).toMatchObject({
34+
key: {
35+
displayName: 'Key',
36+
required: true,
37+
},
38+
defaultValue: {
39+
displayName: 'Default Value',
40+
required: false,
41+
},
42+
store_scope: expect.anything(),
43+
parseJSON: {
44+
displayName: 'Parse as JSON',
45+
required: false,
46+
defaultValue: false,
47+
},
48+
});
49+
});
50+
51+
test('should get value from store with correct key and scope (RUN scope)', async () => {
52+
const mockContext = createMockContext();
53+
const mockValue = 'test-value';
54+
(mockContext.store.get as jest.Mock).mockResolvedValue(mockValue);
55+
56+
const result = await storageGetAction.run(mockContext);
57+
58+
expect(mockContext.store.get).toHaveBeenCalledWith(
59+
'run_test-run-id/test-key',
60+
'FLOW',
61+
);
62+
expect(result).toBe(mockValue);
63+
});
64+
65+
test('should return defaultValue if store returns null', async () => {
66+
const mockContext = createMockContext();
67+
mockContext.propsValue['defaultValue'] = 'default-val';
68+
(mockContext.store.get as jest.Mock).mockResolvedValue(null);
69+
70+
const result = await storageGetAction.run(mockContext);
71+
72+
expect(result).toBe('default-val');
73+
});
74+
75+
test('should parse JSON if parseJSON is true', async () => {
76+
const mockContext = createMockContext();
77+
mockContext.propsValue['parseJSON'] = true;
78+
const jsonValue = '{"a": 1}';
79+
(mockContext.store.get as jest.Mock).mockResolvedValue(jsonValue);
80+
81+
const result = await storageGetAction.run(mockContext);
82+
83+
expect(result).toEqual({ a: 1 });
84+
});
85+
86+
test('should return raw value if parseJSON is true but value is not valid JSON', async () => {
87+
const mockContext = createMockContext();
88+
mockContext.propsValue['parseJSON'] = true;
89+
const nonJsonValue = 'not-json';
90+
(mockContext.store.get as jest.Mock).mockResolvedValue(nonJsonValue);
91+
92+
const result = await storageGetAction.run(mockContext);
93+
94+
expect(result).toBe('not-json');
95+
});
96+
97+
test('should use correct scope for PROJECT scope', async () => {
98+
const mockContext = createMockContext();
99+
mockContext.propsValue.store_scope = BlockStoreScope.PROJECT;
100+
(mockContext.store.get as jest.Mock).mockResolvedValue('val');
101+
102+
await storageGetAction.run(mockContext);
103+
104+
expect(mockContext.store.get).toHaveBeenCalledWith(
105+
'test-key',
106+
'COLLECTION',
107+
);
108+
});
109+
110+
test('should use correct scope for FLOW scope', async () => {
111+
const mockContext = createMockContext();
112+
mockContext.propsValue.store_scope = BlockStoreScope.FLOW;
113+
(mockContext.store.get as jest.Mock).mockResolvedValue('val');
114+
115+
await storageGetAction.run(mockContext);
116+
117+
expect(mockContext.store.get).toHaveBeenCalledWith('test-key', 'FLOW');
118+
});
119+
120+
test('should use test-run prefix when isTest is true in RUN scope', async () => {
121+
const mockContext = createMockContext(true);
122+
mockContext.propsValue.store_scope = BlockStoreScope.RUN;
123+
(mockContext.store.get as jest.Mock).mockResolvedValue('val');
124+
125+
await storageGetAction.run(mockContext);
126+
127+
expect(mockContext.store.get).toHaveBeenCalledWith(
128+
'run_test-run/test-key',
129+
'FLOW',
130+
);
131+
});
132+
});
133+
});

0 commit comments

Comments
 (0)