Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions packages/lib-js-core/src/groups.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import QueryBuilder from './query-builder'

/**
* Syncano groups
* @property {Function}
*/
class Groups extends QueryBuilder {
url () {
const {instanceName} = this.instance

return `${this._getInstanceURL(instanceName)}/groups/`
}

/**
* Groups list helper
*
* @param {string} url
*
* @return {Array}
*/
async _getGroups (url) {
const fetch = this.fetch.bind(this)
const options = {
method: 'GET',
}

try {
const res = await fetch(url, options)
const groups = res.objects

if(res.next) {
groups.concat(await this._getGroups(res.next))
}

return groups
} catch(err) {
throw err
}
}

/**
* Get group with users list
*
* @param {string} label - group name
*
* @return {Promise}
*
* @example [@lang javascript]
* const group = await get('admin')
*/
async get (label) {
const fetch = this.fetch.bind(this)
const options = {
method: 'GET',
}

const groups = await this.list()
const group = groups.find(elem => elem.label === label)
if(group) {
const res = await fetch(`${this.url()}${group.id}/users/`, options)
group.users = res.objects
}

return group
}

/**
* Get groups list
*
* @returns {Promise}
*
* @example {@lang javascript}
* const groupsList = await groups.list()
*/
async list() {
try {
return await this._getGroups(this.url())
} catch (err) {
throw err
}
}

/**
* Create new group
*
* @param {string} label - group name
*
* @return {Promise}
*
* @example [@lang javascript]
* const adminGroup = await groups.create('admin')
*/
async create (label, description = '') {
const fetch = this.fetch.bind(this)
const options = {
method: 'POST',
body: JSON.stringify({label, description})
}

try {
const group = await this.get(label)

if(!group) {
return await fetch(this.url(), options)
} else {
throw new Error('Group already exist')
}
} catch (err) {
throw err
}
}

/**
* Delete group
*
* @param {string} label - group name
*
* @return {Promise}
*
* @example [@lang javascript]
* groups.delete('admin')
*/
async delete (label) {
const fetch = this.fetch.bind(this)
const options = {
method: 'DELETE'
}

try {
const group = await this.get(label)

return await fetch(`${this.url()}${group.id}/`, options)
} catch (err) {
throw err
}
}

/**
* Get user groups list
*
* @param {number} user - user id
*
* @return {Promise}
*
* @example [@lang javascript]
* const userGroups = await groups.user(1)
*/
async user (user) {
const {instanceName} = this.instance
const fetch = this.fetch.bind(this)
const options = {
method: 'GET'
}

try {
const res = await fetch(`${this._getInstanceURL(instanceName)}/users/${user}/groups/`, options)

return res.objects.map(elem => elem.group)
} catch (err) {
throw err
}
}

/**
* Add user to group
*
* @param {string} label - group name
* @param {number} user - user id
*
* @return {Promise}
*
* @example [@lang javascript]
* groups.addUser('admin', 1)
*/
async addUser (label, user) {
const fetch = this.fetch.bind(this)
const options = {
method: 'POST',
body: JSON.stringify({user})
}

try {
const group = await this.get(label)

return await fetch(`${this.url()}${group.id}/users/`, options)
} catch (err) {
throw err
}
}

/**
* Remove user from group
*
* @param {string} label - group name
* @param {number} user - user id
*
* @return {Promise}
*
* @example [@lang javascript]
* groups.removeUser('admin', 1)
*/
async removeUser (label, user) {
const fetch = this.fetch.bind(this)
const options = {
method: 'DELETE'
}

try {
const group = await this.get(label)

return await fetch(`${this.url()}${group.id}/users/${user}/`, options)
} catch (err) {
throw err
}
}
}

export default Groups
2 changes: 2 additions & 0 deletions packages/lib-js-core/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Logger from './logger'
import Channel from './channel'
import Class from './class'
import Settings from './settings'
import Groups from './groups'

class Server {
constructor (ctx = {}) {
Expand All @@ -35,6 +36,7 @@ class Server {
this.instance = new Instance(config)
this.logger = Logger(config)
this.users = new Users(config)
this.groups = new Groups(config)
this.data = new Proxy(new Data(settings), {
get (target, className) {
return new Data(getConfig(className))
Expand Down
136 changes: 136 additions & 0 deletions packages/lib-js-core/test/unit/groups.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import nock from 'nock'
import Server from '../../src'
import chai from 'chai'
import chaiAsPromised from 'chai-as-promised'

chai.use(chaiAsPromised)
chai.should()

describe('Groups', () => {
const instanceName = 'testInstance'
const user = {
id: 1,
username: 'testUser',
}
const testGroup = {
id: 1,
label: "testGroup",
description: ''
}
const GROUPS_URL = `/v2/instances/${instanceName}/groups/`
const USER_GROUPS_URL = `/v2/instances/${instanceName}/users/${user.id}/groups/`
let api
let groups

beforeEach(() => {
const server = new Server({
token: 'testKey',
instanceName
})
groups = server.groups
api = nock(`https://${process.env.SYNCANO_HOST || 'api.syncano.io'}`)
})

describe('#list', () => {
it('get list of groups', async () => {
api.get(GROUPS_URL).reply(200, {next: null, objects: ['admin', 'mod']})

const list = await groups.list()

list.should.be.a('array')
list.should.have.lengthOf(2)
})
})

describe('#get', () => {
it('get group', async () => {
api.get(`${GROUPS_URL}1/users/`).reply(200, {objects: []})
api.get(GROUPS_URL).reply(200, {
next: null,
objects: [testGroup]
})

const group = await groups.get(testGroup.label)

group.should.have.property('id')
group.should.have.property('label').equal(testGroup.label)
group.should.have.property('users')
})
})

describe('#create', () => {
it('create group', async () => {
api.get(GROUPS_URL).reply(200, {next: null, objects: []})
api.post(GROUPS_URL, body => {
return body.label && body.description
}).reply(200, (url, {label, description}) => ({
id: 1,
label,
description
}))

const group = await groups.create(testGroup.label, 'Test group')

group.should.be.a('object')
group.should.have.property('id')
group.should.have.property('label').equal(testGroup.label)
})
})

describe('#delete', () => {
it('delete group', () => {
api.delete(`${GROUPS_URL}1/`).reply(200)
api.get(`${GROUPS_URL}1/users/`).reply(200, {objects: []})
api.get(GROUPS_URL).reply(200, {
next: null,
objects: [testGroup]
})

groups.delete(testGroup.label)
})
})

describe('#user', () => {
it('get user groups', async () => {
api.get(USER_GROUPS_URL).reply(200, {
objects: [testGroup]
})
const userGroups = await groups.user(1)

userGroups.should.be.a('array')
})
})

describe('#addUser', () => {
it('add user to group', async () => {
api.get(`${GROUPS_URL}1/users/`).reply(200, {objects: []})
api.get(GROUPS_URL).reply(200, {
next: null,
objects: [testGroup]
})
api.post(`${GROUPS_URL}1/users/`, body => body.user).reply(200, {
user: {
id: 1,
username: 'user'
}
})

const user = await groups.addUser(testGroup.label, 1)

user.should.have.property('user')
})
})

describe('#removeUser', () => {
it('remove user from group', () => {
api.delete(`${GROUPS_URL}1/users/1/`).reply(200)
api.get(`${GROUPS_URL}1/users/`).reply(200, {objects: []})
api.get(GROUPS_URL).reply(200, {
next: null,
objects: [testGroup]
})

groups.removeUser(testGroup.label, 1)
})
})
})