Skip to content
This repository has been archived by the owner on Apr 11, 2023. It is now read-only.

feat: pagination #12

Merged
merged 5 commits into from
Dec 16, 2020
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
3 changes: 2 additions & 1 deletion packages/brokeneck-fastify/.taprc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
100: true
100: true
reporter: spec
16 changes: 14 additions & 2 deletions packages/brokeneck-fastify/lib/plugins/auth/auth0/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,20 @@ function Auth0Provider(options, logger) {

return {
name: 'auth0',
async listUsers() {
const users = await auth0.getUsers({})
async listUsers({ pageNumber, pageSize, search }) {
const page = pageNumber ? Number(pageNumber) - 1 : 0

const data = await auth0.getUsers({
page: page,
per_page: pageSize,
include_totals: true,
q: search ? `name:*${search}*` : undefined
})

const users = {
data: data.users,
nextPage: data.length === data.limit ? (page + 2).toString() : ''
}

logger.debug({ users }, 'loaded users')

Expand Down
58 changes: 53 additions & 5 deletions packages/brokeneck-fastify/lib/plugins/auth/auth0/provider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,61 @@ tap.test('auth0 provider', async t => {
t.equal(provider.name, 'auth0')
})

t.test('returns users', async t => {
const users = faker.random.arrayElements()
auth0.getUsers = sinon.stub().resolves(users)
t.test('users', async t => {
t.test('no page', async t => {
const users = faker.random.arrayElements()
auth0.getUsers = sinon.stub().resolves({ users })

const result = await provider.listUsers()
const result = await provider.listUsers({
pageSize: 2,
search: 'search'
})

t.equal(result, users)
console.log(result)

t.deepEqual(result, { data: users, nextPage: 2 })
})

t.test('no search', async t => {
const users = faker.random.arrayElements()
auth0.getUsers = sinon.stub().resolves({ users })

const result = await provider.listUsers({
pageSize: 2
})

console.log(result)

t.deepEqual(result, { data: users, nextPage: 2 })
})

t.test('pagination', async t => {
const users = faker.random.arrayElements()
auth0.getUsers = sinon.stub().resolves({ users, length: users.length })

const result = await provider.listUsers({
pageSize: 2
})

console.log(result)

t.deepEqual(result, { data: users, nextPage: '' })
})

t.test('page 1', async t => {
const users = faker.random.arrayElements()
auth0.getUsers = sinon.stub().resolves({ users })

const result = await provider.listUsers({
pageNumber: 1,
pageSize: 2,
search: 'search'
})

console.log(result)

t.deepEqual(result, { data: users, nextPage: 2 })
})
})

t.test('returns user', async t => {
Expand Down
52 changes: 52 additions & 0 deletions packages/brokeneck-fastify/lib/plugins/auth/azure/operations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict'

const { Serializer } = require('@azure/ms-rest-js')
const { GraphRbacManagementMappers: Mappers } = require('@azure/graph')

const Parameters = require('./parameters')

const serializer = new Serializer(Mappers)

const listOperationSpec = {
httpMethod: 'GET',
path: '{tenantID}/users',
urlParameters: [Parameters.tenantID],
queryParameters: [
Parameters.filter,
Parameters.top,
Parameters.apiVersion,
Parameters.search
],
headerParameters: [Parameters.acceptLanguage],
responses: {
200: {
bodyMapper: Mappers.UserListResult
},
default: {
bodyMapper: Mappers.GraphError
}
},
serializer
}

const listNextOperationSpec = {
httpMethod: 'GET',
path: '{tenantID}/{nextLink}',
urlParameters: [Parameters.nextLink, Parameters.tenantID],
queryParameters: [Parameters.apiVersion, Parameters.top, Parameters.search],
headerParameters: [Parameters.acceptLanguage],
responses: {
200: {
bodyMapper: Mappers.UserListResult
},
default: {
bodyMapper: Mappers.GraphError
}
},
serializer
}

module.exports = {
listOperationSpec,
listNextOperationSpec
}
83 changes: 83 additions & 0 deletions packages/brokeneck-fastify/lib/plugins/auth/azure/parameters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'use strict'

const acceptLanguage = {
parameterPath: 'acceptLanguage',
mapper: {
serializedName: 'accept-language',
defaultValue: 'en-US',
type: {
name: 'String'
}
}
}
const apiVersion = {
parameterPath: 'apiVersion',
mapper: {
required: true,
serializedName: 'api-version',
type: {
name: 'String'
}
}
}
const filter = {
parameterPath: ['options', 'filter'],
mapper: {
serializedName: '$filter',
type: {
name: 'String'
}
}
}

const top = {
parameterPath: ['options', 'top'],
mapper: {
serializedName: '$top',
type: {
name: 'Number'
}
}
}

const search = {
parameterPath: ['options', 'search'],
mapper: {
serializedName: '$search',
type: {
name: 'String'
}
}
}

const nextLink = {
parameterPath: 'nextLink',
mapper: {
required: true,
serializedName: 'nextLink',
type: {
name: 'String'
}
},
skipEncoding: true
}
const tenantID = {
parameterPath: 'tenantID',
mapper: {
required: true,
serializedName: 'tenantID',
type: {
name: 'String'
}
}
}

module.exports = {
tenantID,
acceptLanguage,
filter,
apiVersion,
top,
search,
nextLink
}
18 changes: 16 additions & 2 deletions packages/brokeneck-fastify/lib/plugins/auth/azure/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@

const { GraphRbacManagementClient } = require('@azure/graph')

const { listNextOperationSpec, listOperationSpec } = require('./operations')

function AzureProvider(options, credentials, logger) {
const azure = new GraphRbacManagementClient(credentials, options.tenantId)

return {
name: 'azure',
async listUsers() {
const users = await azure.users.list()
async listUsers({ pageNumber, pageSize, search }) {
const options = { top: pageSize, search: `"displayName:${search}"` }

const result = await (pageNumber
? azure.sendOperationRequest(
{
nextLink: pageNumber,
options
},
listNextOperationSpec
)
: azure.sendOperationRequest({ options }, listOperationSpec))

const users = { data: result, nextPage: result.odatanextLink }

logger.debug({ users }, 'loaded users')

Expand Down
28 changes: 23 additions & 5 deletions packages/brokeneck-fastify/lib/plugins/auth/azure/provider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,31 @@ tap.test('azure provider', async t => {
t.equal(provider.name, 'azure')
})

t.test('returns users', async t => {
const users = faker.random.arrayElements()
azure.users.list = sinon.stub().resolves(users)
t.test('users', async t => {
t.test('without page', async t => {
const users = faker.random.arrayElements()
azure.sendOperationRequest = sinon.stub().resolves(users)

const result = await provider.listUsers({
pageSize: 2,
search: 'search'
})

const result = await provider.listUsers()
t.deepEqual(result, { data: users, nextPage: undefined })
})

t.equal(result, users)
t.test('returns users', async t => {
const users = faker.random.arrayElements()
azure.sendOperationRequest = sinon.stub().resolves(users)

const result = await provider.listUsers({
pageNumber: 1,
pageSize: 2,
search: 'search'
})

t.deepEqual(result, { data: users, nextPage: undefined })
})
})

t.test('returns user', async t => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ function CognitoProvider(options, logger) {

return {
name: 'cognito',
async listUsers() {
async listUsers({ pageNumber, pageSize, search }) {
const result = await cognito
.listUsers({
UserPoolId
UserPoolId,
Limit: pageSize,
PaginationToken: pageNumber || undefined,
Filter: search ? `username ^= "${search}"` : undefined
})
.promise()

const users = result.Users
const users = { data: result.Users, nextPage: result.PaginationToken }

logger.debug({ users })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,42 @@ tap.test('cognito provider', async t => {
t.equal(provider.name, 'cognito')
})

t.test('returns users', async t => {
const users = faker.random.arrayElements()
awsCognito.listUsers = stubAws(p => p.resolves({ Users: users }))

const result = await provider.listUsers()

t.equal(result, users)
t.test('users', async t => {
t.test('without page', async t => {
const users = faker.random.arrayElements()
awsCognito.listUsers = stubAws(p => p.resolves({ Users: users }))

const result = await provider.listUsers({
pageSize: 2,
search: 'search'
})

t.deepEqual(result, { data: users, nextPage: undefined })
})

t.test('without search', async t => {
const users = faker.random.arrayElements()
awsCognito.listUsers = stubAws(p => p.resolves({ Users: users }))

const result = await provider.listUsers({
pageSize: 2
})

t.deepEqual(result, { data: users, nextPage: undefined })
})

t.test('returns users', async t => {
const users = faker.random.arrayElements()
awsCognito.listUsers = stubAws(p => p.resolves({ Users: users }))

const result = await provider.listUsers({
pageNumber: 1,
pageSize: 2,
search: 'search'
})

t.deepEqual(result, { data: users, nextPage: undefined })
})
})

t.test('returns user', async t => {
Expand Down
4 changes: 2 additions & 2 deletions packages/brokeneck-fastify/lib/plugins/graphql/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
module.exports = function makeResolvers(fastify) {
return {
Query: {
users() {
return fastify.provider.listUsers()
users(_, { pageNumber, pageSize, search }) {
return fastify.provider.listUsers({ pageNumber, pageSize, search })
},
user(_, { id }) {
return fastify.provider.getUser(id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ tap.test('resolvers', async t => {

fastify.provider.listUsers = sinon.stub().resolves(users)

const result = await resolvers.Query.users()
const args = {
pageNumber: 1,
pageSize: 2,
search: 'search'
}
const result = await resolvers.Query.users(null, args)

sinon.assert.calledWith(fastify.provider.listUsers, args)

t.equal(result, users)
})
Expand Down
Loading