Skip to content

Commit e092a90

Browse files
authored
Merge pull request #31 from CloudBoltSoftware/feature/server-resource-apis
Feature/server resource apis
2 parents e35932a + 1137776 commit e092a90

12 files changed

+220
-16
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@cloudbolt/cb-api-helper",
3-
"version": "0.3.9",
3+
"version": "0.4.0-0",
44
"scripts": {
55
"co:login": "aws sso login && aws codeartifact login --tool npm --repository cloudbolt-npm --domain cloudbolt --domain-owner 499620025628",
66
"husky:install": "husky install",

src/api/services/v3/cmp/ResourceActionsService.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export default {
4242
* Run a Resource Action
4343
* @param {string} id or global_id
4444
* @param {object} runResourceAction Resource Action object definition
45-
* @param {string} runResourceAction.resource required
45+
* @param {array} runResourceAction.resources List of resource hrefs to run the Resource Action on
46+
* @param {object} runResourceAction.parameters Action input parameters
4647
* @returns {Promise} resolves with a cloudbolt API Run Resource Action Success Response
4748
*/
4849
run: (id, runResourceAction) =>

src/api/services/v3/cmp/ResourceActionsService.test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ test('run calls the correct endpoint', async () => {
7676
data: { hello: 'world' }
7777
})
7878
const mockResourceAction = {
79-
resource: 'world'
79+
resources: ['resource-href'],
80+
parameters: {
81+
param1: 'value1'
82+
}
8083
}
8184
await ResourceActionsService.run('resourceAction-id', mockResourceAction)
8285
expect(mockFn).toHaveBeenCalledWith(
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import crud from '../../../crudOperations'
2+
3+
const URL = 'v3/cmp/resourcesStructured'
4+
5+
export default {
6+
/**
7+
* Retrieve a list of existing Structured Resources
8+
* @param options anything parsable by URLSearchParams. See useful options here https://docs.cloudbolt.io/articles/#!cloudbolt-latest-docs/api-conventions/a/h2__904191799
9+
* @returns {Promise} resolves with a list of existing Structured Resources
10+
*/
11+
list: (options) => crud.getItems(URL, options),
12+
13+
/**
14+
* Retrieve an existing Structured Resource by idd
15+
* @param {string} id or global_id
16+
* @returns {Promise} resolves with a cloudbolt API Response object of the Structured Resource object
17+
*/
18+
get: (id) => crud.getItemById(URL, id)
19+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { baseApi } from '../../../baseApi'
2+
import ResourcesStructuredService from './ResourcesStructuredService'
3+
4+
const RESOURCES_STRUCTURED_ENDPOINT = '/v3/cmp/resourcesStructured/'
5+
6+
test('list calls the correct endpoint', async () => {
7+
const mockFn = jest.spyOn(baseApi, 'get').mockResolvedValue({
8+
data: { hello: 'world' }
9+
})
10+
await ResourcesStructuredService.list()
11+
expect(mockFn).toHaveBeenCalledWith(RESOURCES_STRUCTURED_ENDPOINT)
12+
})
13+
14+
test('get calls the correct endpoint', async () => {
15+
const mockFn = jest.spyOn(baseApi, 'get').mockResolvedValue({
16+
data: { hello: 'world' }
17+
})
18+
await ResourcesStructuredService.get('resource-id')
19+
expect(mockFn).toHaveBeenCalledWith(
20+
`${RESOURCES_STRUCTURED_ENDPOINT}resource-id/`
21+
)
22+
})
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import crud from '../../../crudOperations'
2+
3+
const URL = 'v3/cmp/serverActions'
4+
5+
export default {
6+
/**
7+
* Retrieve a list of existing Server Actions
8+
* @param options anything parsable by URLSearchParams. See useful options here https://docs.cloudbolt.io/articles/#!cloudbolt-latest-docs/api-conventions/a/h2__904191799
9+
* @returns {Promise} resolves with a list of existing Server Actions
10+
*/
11+
list: (options) => crud.getItems(URL, options),
12+
13+
/**
14+
* Retrieve an existing Server Action by id
15+
* @param {string} id or global_id
16+
* @returns {Promise} resolves with a cloudbolt API Response object of the Server Action object
17+
*/
18+
get: (id) => crud.getItemById(URL, id),
19+
20+
/**
21+
* Create a new Server Action
22+
* @param {object} newServerAction new Server Action object definition
23+
* @param {string} newServerAction.zipFile required
24+
* @param {boolean} [newServerAction.replaceExisting] determines whether or not to replace an existing server action
25+
* @param {string} [newServerAction.password] password to use to password-protect the zip file
26+
* @returns {Promise} resolves with a new Server Action object with all server-filled fields
27+
*/
28+
create: (newServerAction) => crud.createNewItem(URL, newServerAction),
29+
30+
/**
31+
* Export an existing Server Action as a zipfile for a given id
32+
* @param {string} id or global_id
33+
* @param {object} serverActionOptions
34+
* @param {string} [serverActionOptions.password] password to the zip if it's password-protected
35+
* @param {boolean} [serverActionOptions.instanceSpecificInfo=false] determines if the Server Action should include info specific to the CloudBolt instance
36+
* @returns {Promise} resolves with a cloudbolt API Export Server Action Success Response and zip file
37+
*/
38+
export: (id, serverActionOptions) =>
39+
crud.downloadWithPayload(URL, id, serverActionOptions),
40+
41+
/**
42+
* Run a Server Action
43+
* @param {string} id or global_id
44+
* @param {object} runServerAction Server Action object definition
45+
* @param {array} runServerAction.servers List of server hrefs to run the Server Action on
46+
* @param {object} runServerAction.parameters Action input parameters
47+
* @returns {Promise} resolves with a cloudbolt API Run Server Action Success Response
48+
*/
49+
run: (id, runServerAction) =>
50+
crud.postItem(`${URL}/${id}/runAction`, runServerAction)
51+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { baseApi } from '../../../baseApi'
2+
import ServerActionsService from './ServerActionsService'
3+
4+
test('list calls the correct endpoint', async () => {
5+
const mockFn = jest.spyOn(baseApi, 'get').mockResolvedValue({
6+
data: { hello: 'world' }
7+
})
8+
await ServerActionsService.list()
9+
expect(mockFn).toHaveBeenCalledWith('/v3/cmp/serverActions/')
10+
})
11+
12+
test('get calls the correct endpoint', async () => {
13+
const mockFn = jest.spyOn(baseApi, 'get').mockResolvedValue({
14+
data: { hello: 'world' }
15+
})
16+
await ServerActionsService.get('serverAction-id')
17+
expect(mockFn).toHaveBeenCalledWith('/v3/cmp/serverActions/serverAction-id/')
18+
})
19+
20+
test('create calls the correct endpoint', async () => {
21+
const mockFn = jest.spyOn(baseApi, 'post').mockResolvedValue({
22+
data: { hello: 'world' }
23+
})
24+
const mockServerAction = {
25+
zipFile: 'world.zip'
26+
}
27+
await ServerActionsService.create(mockServerAction)
28+
expect(mockFn).toHaveBeenCalledWith(
29+
'/v3/cmp/serverActions/',
30+
mockServerAction
31+
)
32+
})
33+
34+
test('export calls the correct endpoint', async () => {
35+
const mockFn = jest.spyOn(baseApi, 'post').mockResolvedValue({
36+
data: { hello: 'world' },
37+
headers: {
38+
'content-disposition': 'attachment; filename=action.zip'
39+
}
40+
})
41+
42+
await ServerActionsService.export('serverAction-id')
43+
expect(mockFn).toHaveBeenCalledWith(
44+
'/v3/cmp/serverActions/serverAction-id/export/',
45+
{},
46+
{ responseType: 'blob' }
47+
)
48+
})
49+
50+
test('export with options calls the correct endpoint', async () => {
51+
const mockFn = jest.spyOn(baseApi, 'post').mockResolvedValue({
52+
data: { hello: 'world' },
53+
headers: {
54+
'content-disposition': 'attachment; filename=action.zip'
55+
}
56+
})
57+
const mockServerActionsOptions = {
58+
password: 'worldServerActions',
59+
instanceSpecificInfo: true
60+
}
61+
await ServerActionsService.export('serverAction-id', mockServerActionsOptions)
62+
expect(mockFn).toHaveBeenCalledWith(
63+
'/v3/cmp/serverActions/serverAction-id/export/',
64+
mockServerActionsOptions,
65+
{ responseType: 'blob' }
66+
)
67+
})
68+
69+
test('run calls the correct endpoint', async () => {
70+
const mockFn = jest.spyOn(baseApi, 'post').mockResolvedValue({
71+
data: { hello: 'world' }
72+
})
73+
const mockServerAction = {
74+
servers: ['server-href'],
75+
parameters: {
76+
param1: 'value1'
77+
}
78+
}
79+
await ServerActionsService.run('serverAction-id', mockServerAction)
80+
expect(mockFn).toHaveBeenCalledWith(
81+
'/v3/cmp/serverActions/serverAction-id/runAction/',
82+
mockServerAction
83+
)
84+
})

src/api/services/v3/cmp/UserService.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import crud from '../../../crudOperations'
22
import { camelCaseKeys } from '../../../helpers/textUtils'
33

4+
const URL = 'v3/cmp/users/'
5+
46
export default {
7+
/**
8+
* Retrieve a list of existing Server Actions
9+
* @param options anything parsable by URLSearchParams. See useful options here https://docs.cloudbolt.io/articles/#!cloudbolt-latest-docs/api-conventions/a/h2__904191799
10+
* @returns {Promise} resolves with a list of existing Server Actions
11+
*/
12+
list: (options) => crud.getItems(URL, options),
13+
514
/**
615
* Retrieves the requesting user's information
716
* @param {Object} [options] - query parameters to be sent with the request. Defaults to {includeCMPCatalogFields: true}
@@ -17,7 +26,7 @@ export default {
1726
*/
1827
getWidgets: async (userId) => {
1928
const data = await crud.getItemByEndpoint(
20-
`v3/cmp/users/${userId}/dashboardWidgets`
29+
`${URL}${userId}/dashboardWidgets`
2130
)
2231
const widgets = JSON.parse(data?.widgetsJson || '[]')
2332
return widgets
@@ -30,7 +39,7 @@ export default {
3039
* @returns
3140
*/
3241
updateWidgets: async (userId, widgets) =>
33-
await crud.updateItemByEndpoint(`v3/cmp/users/${userId}/dashboardWidgets`, {
42+
await crud.updateItemByEndpoint(`${URL}${userId}/dashboardWidgets`, {
3443
widgetsJson: widgets
3544
}),
3645

@@ -40,9 +49,7 @@ export default {
4049
* @returns
4150
*/
4251
getDashboard: async (userId) => {
43-
const data = await crud.getItemByEndpoint(
44-
`v3/cmp/users/${userId}/cuiDashboard`
45-
)
52+
const data = await crud.getItemByEndpoint(`${URL}${userId}/cuiDashboard`)
4653
const rawDashboard = JSON.parse(data?.cuiDashboard || '{}')
4754
const dashboard = camelCaseKeys(rawDashboard)
4855
return dashboard
@@ -57,7 +64,7 @@ export default {
5764
*/
5865
updateDashboard: async (userId, dashboard) => {
5966
const rawUpdatedDashboard = await crud.updateItemByEndpoint(
60-
`v3/cmp/users/${userId}/cuiDashboard`,
67+
`${URL}${userId}/cuiDashboard`,
6168
{
6269
cuiDashboard: dashboard
6370
}

src/api/services/v3/cmp/UserService.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import crud from '../../../crudOperations'
22
import UserService from './UserService'
33

4+
const USERS_URL = 'v3/cmp/users/'
45
const USER_URL = 'v3/cmp/user'
56
const WIDGETS_URL = 'v3/cmp/users/1/dashboardWidgets'
67
const DASHBOARD_URL = 'v3/cmp/users/1/cuiDashboard'
78

89
describe('UserService', () => {
10+
it('gets a list of users', async () => {
11+
const mockFn = jest.spyOn(crud, 'getItems').mockResolvedValue({
12+
data: { hello: 'world' }
13+
})
14+
await UserService.list({})
15+
expect(mockFn).toHaveBeenCalledWith(USERS_URL, {})
16+
})
17+
918
it('getCurrentUser calls crud.getItemByEndpoint and returns result', async () => {
1019
jest.spyOn(crud, 'getItemByEndpoint').mockResolvedValue('dummyResponse')
1120

0 commit comments

Comments
 (0)