forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
API Integration Tests via jest (grafana#10899)
* tests: experiment with api tests * api tests are getting nice * api: api testing ready for feedback
- Loading branch information
Showing
11 changed files
with
373 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import * as setup from './setup'; | ||
|
||
describe.skip('clear state', () => { | ||
it('will clear state', () => { | ||
return setup.clearState(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const axios = require('axios'); | ||
|
||
export function getClient(options) { | ||
return axios.create({ | ||
baseURL: 'http://localhost:3000', | ||
timeout: 1000, | ||
auth: { | ||
username: options.username, | ||
password: options.password, | ||
}, | ||
}); | ||
} | ||
|
||
export function getAdminClient() { | ||
return getClient({ | ||
username: 'admin', | ||
password: 'admin', | ||
}); | ||
} | ||
|
||
let client = getAdminClient(); | ||
|
||
client.callAs = function(user) { | ||
return getClient({ | ||
username: user.login, | ||
password: 'password', | ||
}); | ||
}; | ||
|
||
export default client; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import client from './client'; | ||
import * as setup from './setup'; | ||
|
||
describe('/api/dashboards', () => { | ||
let state: any = {}; | ||
|
||
beforeAll(async () => { | ||
state = await setup.ensureState({ | ||
orgName: 'api-test-org', | ||
users: [ | ||
{ user: setup.admin, role: 'Admin' }, | ||
{ user: setup.editor, role: 'Editor' }, | ||
{ user: setup.viewer, role: 'Viewer' }, | ||
], | ||
admin: setup.admin, | ||
dashboards: [ | ||
{ | ||
title: 'aaa', | ||
uid: 'aaa', | ||
}, | ||
{ | ||
title: 'bbb', | ||
uid: 'bbb', | ||
}, | ||
], | ||
}); | ||
}); | ||
|
||
describe('With admin user', () => { | ||
it('can delete dashboard', async () => { | ||
let rsp = await client.callAs(setup.admin).delete(`/api/dashboards/uid/aaa`); | ||
expect(rsp.data.title).toBe('aaa'); | ||
}); | ||
}); | ||
|
||
describe('With viewer user', () => { | ||
it('Cannot delete dashboard', async () => { | ||
let rsp = await setup.expectError(() => { | ||
return client.callAs(setup.viewer).delete(`/api/dashboards/uid/bbb`); | ||
}); | ||
|
||
expect(rsp.response.status).toBe(403); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module.exports = { | ||
verbose: true, | ||
"globals": { | ||
"ts-jest": { | ||
"tsConfigFile": "tsconfig.json" | ||
} | ||
}, | ||
"transform": { | ||
"^.+\\.tsx?$": "<rootDir>/../../node_modules/ts-jest/preprocessor.js" | ||
}, | ||
"moduleDirectories": ["node_modules"], | ||
"testRegex": "(\\.|/)(test)\\.ts$", | ||
"testEnvironment": "node", | ||
"moduleFileExtensions": [ | ||
"ts", | ||
"js", | ||
"json" | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import client from './client'; | ||
import * as setup from './setup'; | ||
|
||
describe('GET /api/search', () => { | ||
const state = {}; | ||
|
||
beforeAll(async () => { | ||
state = await setup.ensureState({ | ||
orgName: 'api-test-org', | ||
users: [{ user: setup.admin, role: 'Admin' }], | ||
admin: setup.admin, | ||
dashboards: [ | ||
{ | ||
title: 'Dashboard in root no permissions', | ||
uid: 'AAA', | ||
}, | ||
], | ||
}); | ||
}); | ||
|
||
describe('With admin user', () => { | ||
it('should return all dashboards', async () => { | ||
let rsp = await client.callAs(state.admin).get('/api/search'); | ||
expect(rsp.data).toHaveLength(1); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import client from './client'; | ||
import _ from 'lodash;'; | ||
|
||
export const editor = { | ||
email: '[email protected]', | ||
login: 'api-test-editor', | ||
password: 'password', | ||
name: 'Api Test Editor', | ||
}; | ||
|
||
export const admin = { | ||
email: '[email protected]', | ||
login: 'api-test-admin', | ||
password: 'password', | ||
name: 'Api Test Super', | ||
}; | ||
|
||
export const viewer = { | ||
email: '[email protected]', | ||
login: 'api-test-viewer', | ||
password: 'password', | ||
name: 'Api Test Viewer', | ||
}; | ||
|
||
export async function expectError(callback) { | ||
try { | ||
let rsp = await callback(); | ||
return rsp; | ||
} catch (err) { | ||
return err; | ||
} | ||
|
||
return rsp; | ||
} | ||
|
||
// deletes org if it's already there | ||
export async function getOrg(orgName) { | ||
try { | ||
const rsp = await client.get(`/api/orgs/name/${orgName}`); | ||
await client.delete(`/api/orgs/${rsp.data.id}`); | ||
} catch {} | ||
|
||
const rsp = await client.post(`/api/orgs`, { name: orgName }); | ||
return { name: orgName, id: rsp.data.orgId }; | ||
} | ||
|
||
export async function getUser(user) { | ||
const search = await client.get('/api/users/search', { | ||
params: { query: user.login }, | ||
}); | ||
|
||
if (search.data.totalCount === 1) { | ||
user.id = search.data.users[0].id; | ||
return user; | ||
} | ||
|
||
const rsp = await client.post('/api/admin/users', user); | ||
user.id = rsp.data.id; | ||
|
||
return user; | ||
} | ||
|
||
export async function addUserToOrg(org, user, role) { | ||
const rsp = await client.post(`/api/orgs/${org.id}/users`, { | ||
loginOrEmail: user.login, | ||
role: role, | ||
}); | ||
|
||
return rsp.data; | ||
} | ||
|
||
export async function clearState() { | ||
const admin = await getUser(adminUser); | ||
const rsp = await client.delete(`/api/admin/users/${admin.id}`); | ||
return rsp.data; | ||
} | ||
|
||
export async function setUsingOrg(user, org) { | ||
await client.callAs(user).post(`/api/user/using/${org.id}`); | ||
} | ||
|
||
export async function createDashboard(user, dashboard) { | ||
const rsp = await client.callAs(user).post(`/api/dashboards/db`, { | ||
dashboard: dashboard, | ||
overwrite: true, | ||
}); | ||
dashboard.id = rsp.data.id; | ||
dashboard.url = rsp.data.url; | ||
|
||
return dashboard; | ||
} | ||
|
||
export async function ensureState(state) { | ||
const org = await getOrg(state.orgName); | ||
|
||
for (let orgUser of state.users) { | ||
const user = await getUser(orgUser.user); | ||
await addUserToOrg(org, user, orgUser.role); | ||
await setUsingOrg(user, org); | ||
} | ||
|
||
for (let dashboard of state.dashboards) { | ||
await createDashboard(state.admin, dashboard); | ||
} | ||
|
||
return state; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"compilerOptions": { | ||
"moduleResolution": "node", | ||
"target": "es6", | ||
"lib": ["es6"], | ||
"module": "commonjs", | ||
"declaration": false, | ||
"allowSyntheticDefaultImports": true, | ||
"inlineSourceMap": false, | ||
"sourceMap": true, | ||
"noEmitOnError": false, | ||
"emitDecoratorMetadata": false, | ||
"experimentalDecorators": true, | ||
"noImplicitReturns": true, | ||
"noImplicitThis": false, | ||
"noImplicitUseStrict":false, | ||
"noImplicitAny": false, | ||
"noUnusedLocals": true | ||
}, | ||
"include": [ | ||
"*.ts", | ||
"**/*.ts" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import client from './client'; | ||
import * as setup from './setup'; | ||
|
||
describe('GET /api/user', () => { | ||
it('should return current authed user', async () => { | ||
let rsp = await client.get('/api/user'); | ||
expect(rsp.data.login).toBe('admin'); | ||
}); | ||
}); | ||
|
||
describe('PUT /api/user', () => { | ||
it('should update current authed user', async () => { | ||
const user = await setup.getUser(setup.editor); | ||
user.name = 'Updated via test'; | ||
|
||
const rsp = await client.callAs(user).put('/api/user', user); | ||
expect(rsp.data.message).toBe('User updated'); | ||
|
||
const updated = await client.callAs(user).get('/api/user'); | ||
expect(updated.data.name).toBe('Updated via test'); | ||
}); | ||
}); |
Oops, something went wrong.