feat(gql): implemented resolvers & tests for stream commits & branch commits
This commit is contained in:
@@ -10,7 +10,8 @@ const {
|
||||
updateCommit,
|
||||
deleteCommit,
|
||||
getCommitsByBranchId,
|
||||
getCommitsByBranchName
|
||||
getCommitsByBranchName,
|
||||
getCommitsTotalCountByBranchId
|
||||
} = require( '../../services/commits' )
|
||||
|
||||
const {
|
||||
@@ -42,10 +43,6 @@ module.exports = {
|
||||
|
||||
async author( parent, args, context, info ) {
|
||||
return await getUserById( { userId: parent.authorId } )
|
||||
},
|
||||
|
||||
async commits( parent, args, context, info ) {
|
||||
throw new ApolloError( 'not implemented' )
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
@@ -13,7 +13,10 @@ const {
|
||||
getCommitsByBranchId,
|
||||
getCommitsByBranchName,
|
||||
getCommitsByUserId,
|
||||
getCommitsTotalCountByUserId
|
||||
getCommitsByStreamId,
|
||||
getCommitsTotalCountByStreamId,
|
||||
getCommitsTotalCountByUserId,
|
||||
getCommitsTotalCountByBranchId
|
||||
} = require( '../../services/commits' )
|
||||
|
||||
const {
|
||||
@@ -28,6 +31,13 @@ module.exports = {
|
||||
Query: {},
|
||||
Stream: {
|
||||
|
||||
async commits( parent, args, context, info ) {
|
||||
let { commits: items, cursor } = await getCommitsByStreamId( { streamId: parent.id, limit: args.limit, cursor: args.cursor } )
|
||||
let totalCount = await getCommitsTotalCountByStreamId( { streamId: parent.id } )
|
||||
|
||||
return { items, cursor, totalCount }
|
||||
},
|
||||
|
||||
async commit( parent, args, context, info ) {
|
||||
throw new ApolloError( 'not implemented' )
|
||||
}
|
||||
@@ -46,13 +56,12 @@ module.exports = {
|
||||
|
||||
},
|
||||
Branch: {
|
||||
|
||||
async commits( parent, args, context, info ) {
|
||||
let { commits, cursor } = await getCommitsByBranchId( { branchId: parent.id, limit: args.limit, cursor: args.cursor } )
|
||||
let totalCount = await getCommitsTotalCountByBranchId( { branchId: parent.id } )
|
||||
|
||||
throw new ApolloError( 'not implemented' )
|
||||
|
||||
return { items: commits, totalCount, cursor }
|
||||
}
|
||||
|
||||
},
|
||||
Mutation: {
|
||||
|
||||
|
||||
@@ -22,12 +22,13 @@ type Commit {
|
||||
referencedObject: String!
|
||||
realObject: Object
|
||||
message: String
|
||||
author: String
|
||||
authorName: String
|
||||
authorId: String
|
||||
createdAt: String
|
||||
}
|
||||
|
||||
type CommitCollectionUserNode {
|
||||
commitId: String!
|
||||
id: String!
|
||||
referencedObject: String!
|
||||
realObject: Object
|
||||
message: String
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.up = async knex => {
|
||||
table.boolean( 'completed' ).defaultTo( false )
|
||||
} )
|
||||
|
||||
// Users.
|
||||
// Users.
|
||||
await knex.schema.createTable( 'users', table => {
|
||||
table.string( 'id', 10 ).primary( )
|
||||
table.string( 'username', 20 ).unique( ).notNullable( )
|
||||
@@ -34,8 +34,8 @@ exports.up = async knex => {
|
||||
|
||||
// Roles.
|
||||
// Roles keep track of their name and the target resource they are applied to.
|
||||
// The target resource must be a table name.
|
||||
// The heigher the weight, the bigger the permissions.
|
||||
// The target resource must be a table name.
|
||||
// The heigher the weight, the bigger the permissions.
|
||||
await knex.schema.createTable( 'user_roles', table => {
|
||||
table.string( 'name' ).primary( )
|
||||
table.text( 'description' ).notNullable( )
|
||||
@@ -44,7 +44,7 @@ exports.up = async knex => {
|
||||
table.integer( 'weight' ).defaultTo( 100 ).notNullable( )
|
||||
} )
|
||||
|
||||
// Server-wide access control list.
|
||||
// Server-wide access control list.
|
||||
await knex.schema.createTable( 'server_acl', table => {
|
||||
table.string( 'userId', 10 ).references( 'id' ).inTable( 'users' ).primary( ).onDelete( 'cascade' )
|
||||
table.string( 'role' ).references( 'name' ).inTable( 'user_roles' ).notNullable( ).onDelete( 'cascade' )
|
||||
@@ -70,13 +70,13 @@ exports.up = async knex => {
|
||||
} )
|
||||
|
||||
// Registered application scopes table.
|
||||
// Scopes limit what a token can actually do.
|
||||
// Scopes limit what a token can actually do.
|
||||
await knex.schema.createTable( 'scopes', table => {
|
||||
table.string( 'name' ).primary( )
|
||||
table.text( 'description' ).notNullable( )
|
||||
} )
|
||||
|
||||
// Token >- -< Scopes junction table.
|
||||
// Token >- -< Scopes junction table.
|
||||
await knex.schema.createTable( 'token_scopes', table => {
|
||||
table.string( 'tokenId' ).references( 'id' ).inTable( 'api_tokens' ).notNullable( ).onDelete( 'cascade' ).index( )
|
||||
table.string( 'scopeName' ).references( 'name' ).inTable( 'scopes' ).notNullable( ).onDelete( 'cascade' ).index( )
|
||||
@@ -104,7 +104,7 @@ exports.up = async knex => {
|
||||
table.unique( [ 'userId', 'resourceId' ] )
|
||||
} )
|
||||
|
||||
// Objects Table.
|
||||
// Objects Table.
|
||||
// id - the object's *hash*
|
||||
// totalChildrenCount - how many subchildren, regardless of depth, this object has
|
||||
// totalChildrenCountByDepth - how many subchildren does this object have at a specific nesting depth.
|
||||
@@ -119,11 +119,11 @@ exports.up = async knex => {
|
||||
table.jsonb( 'data' )
|
||||
} )
|
||||
|
||||
// Closure table for tracking the nesting relationships of objects.
|
||||
// Closure table for tracking the nesting relationships of objects.
|
||||
// Note: the usecase optimised for is that when we request an object, we either:
|
||||
// a) interactively request/query for its subchildren (sequentially)
|
||||
// or
|
||||
// b) we want all of it!
|
||||
// b) we want all of it!
|
||||
await knex.schema.createTable( 'object_children_closure', table => {
|
||||
table.string( 'parent' ).notNullable( ).index( )
|
||||
table.string( 'child' ).notNullable( ).index( )
|
||||
@@ -132,8 +132,8 @@ exports.up = async knex => {
|
||||
table.index( [ 'parent', 'minDepth' ], 'full_pcd_index' )
|
||||
} )
|
||||
|
||||
// Commit table.
|
||||
// Any object can be "blessed" as a commit.
|
||||
// Commit table.
|
||||
// Any object can be "blessed" as a commit.
|
||||
await knex.schema.createTable( 'commits', table => {
|
||||
table.string( 'id', 10 ).primary( )
|
||||
table.string( 'referencedObject' ).references( 'id' ).inTable( 'objects' ).notNullable( )
|
||||
@@ -142,7 +142,7 @@ exports.up = async knex => {
|
||||
table.timestamp( 'createdAt' ).defaultTo( knex.fn.now( ) )
|
||||
} )
|
||||
|
||||
// Commit inheritance table.
|
||||
// Commit inheritance table.
|
||||
// Tracks the inheritance of commits. A commit may have:
|
||||
// - one ancestor (simple sequential push)
|
||||
// - more ancestors (result of a merge)
|
||||
@@ -152,7 +152,7 @@ exports.up = async knex => {
|
||||
table.unique( [ 'parent', 'child' ], 'commit_parent_child_index' )
|
||||
} )
|
||||
|
||||
// Branches table.
|
||||
// Branches table.
|
||||
// A branch is a end-user scope-bound collection of commits.
|
||||
await knex.schema.createTable( 'branches', table => {
|
||||
table.string( 'id', 10 ).primary( )
|
||||
@@ -165,7 +165,7 @@ exports.up = async knex => {
|
||||
table.unique( [ 'streamId', 'name' ] )
|
||||
} )
|
||||
|
||||
// Junction Table Branches >- -< Commits
|
||||
// Junction Table Branches >- -< Commits
|
||||
await knex.schema.createTable( 'branch_commits', table => {
|
||||
table.string( 'branchId', 10 ).references( 'id' ).inTable( 'branches' ).notNullable( ).onDelete( 'cascade' )
|
||||
table.string( 'commitId' ).references( 'id' ).inTable( 'commits' ).notNullable( ).onDelete( 'cascade' )
|
||||
@@ -206,4 +206,4 @@ exports.down = async knex => {
|
||||
|
||||
await knex.raw( `DROP TYPE IF EXISTS speckle_reference_type ` )
|
||||
await knex.raw( `DROP TYPE IF EXISTS speckle_acl_role_type ` )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ module.exports = {
|
||||
|
||||
async getCommitsByBranchId( { branchId, limit, cursor } ) {
|
||||
limit = limit || 20
|
||||
let query = BranchCommits( ).columns( [ 'commitId', 'message', 'referencedObject', { author: 'name' }, { authorId: 'users.id' }, 'commits.createdAt' ] ).select( )
|
||||
let query = BranchCommits( ).columns( [ { id: 'commitId' }, 'message', 'referencedObject', { authorName: 'name' }, { authorId: 'users.id' }, 'commits.createdAt' ] ).select( )
|
||||
.join( 'commits', 'commits.id', 'branch_commits.commitId' )
|
||||
.join( 'users', 'commits.author', 'users.id' )
|
||||
.where( 'branchId', branchId )
|
||||
@@ -126,7 +126,7 @@ module.exports = {
|
||||
async getCommitsByStreamId( { streamId, limit, cursor } ) {
|
||||
limit = limit || 20
|
||||
let query = StreamCommits( )
|
||||
.columns( [ 'commitId', 'message', 'referencedObject', { author: 'name' }, { authorId: 'users.id' }, 'commits.createdAt' ] ).select( )
|
||||
.columns( [ { id: 'commitId' }, 'message', 'referencedObject', { authorName: 'name' }, { authorId: 'users.id' }, 'commits.createdAt' ] ).select( )
|
||||
.join( 'commits', 'commits.id', 'stream_commits.commitId' )
|
||||
.join( 'users', 'commits.author', 'users.id' )
|
||||
.where( 'streamId', streamId )
|
||||
@@ -147,7 +147,7 @@ module.exports = {
|
||||
|
||||
let query =
|
||||
Commits( )
|
||||
.columns( [ 'commitId', 'message', 'referencedObject', 'commits.createdAt', { streamId: 'stream_commits.streamId' }, { streamName: 'streams.name' } ] ).select( )
|
||||
.columns( [ { id: 'commitId' }, 'message', 'referencedObject', 'commits.createdAt', { streamId: 'stream_commits.streamId' }, { streamName: 'streams.name' } ] ).select( )
|
||||
.join( 'stream_commits', 'commits.id', 'stream_commits.commitId' )
|
||||
.join( 'streams', 'stream_commits.streamId', 'streams.id' )
|
||||
.where( 'author', userId )
|
||||
|
||||
@@ -453,7 +453,7 @@ describe( 'GraphQL API Core', ( ) => {
|
||||
|
||||
for ( let i = 10; i < 20; i++ ) {
|
||||
let c1 = {
|
||||
message: 'what a message for a first commit',
|
||||
message: `what a message for commit number ${i}`,
|
||||
streamId: ts1,
|
||||
objectId: objIds[ i ],
|
||||
branchName: 'master',
|
||||
@@ -461,14 +461,15 @@ describe( 'GraphQL API Core', ( ) => {
|
||||
let res = await sendRequest( userA.token, { query: `mutation( $myCommit: CommitCreateInput! ) { commitCreate( commit: $myCommit ) }`, variables: { myCommit: c1 } } )
|
||||
}
|
||||
|
||||
const res = await sendRequest( userA.token, { query: `{ user { commits( limit: 3 ) { totalCount cursor items { commitId message referencedObject } } } }` } )
|
||||
const res = await sendRequest( userA.token, { query: `{ user { commits( limit: 3 ) { totalCount cursor items { id message referencedObject } } } }` } )
|
||||
|
||||
expect( res ).to.be.json
|
||||
expect( res.body.errors ).to.not.exist
|
||||
expect( res.body.data.user.commits.totalCount ).to.equal( 11 )
|
||||
expect( res.body.data.user.commits.cursor ).to.exist
|
||||
expect( res.body.data.user.commits.items.length ).to.equal( 3 )
|
||||
|
||||
const res2 = await sendRequest( userA.token, { query: `{ user { commits( limit: 3, cursor: "${res.body.data.user.commits.cursor}") { totalCount cursor items { commitId message referencedObject } } } }` } )
|
||||
const res2 = await sendRequest( userA.token, { query: `{ user { commits( limit: 3, cursor: "${res.body.data.user.commits.cursor}") { totalCount cursor items { id message referencedObject } } } }` } )
|
||||
expect( res2 ).to.be.json
|
||||
expect( res2.body.errors ).to.not.exist
|
||||
expect( res2.body.data.user.commits.totalCount ).to.equal( 11 )
|
||||
@@ -545,6 +546,7 @@ describe( 'GraphQL API Core', ( ) => {
|
||||
expect( stream.collaborators[ 1 ].role ).to.equal( 'stream:owner' )
|
||||
} )
|
||||
|
||||
let bees = [ ]
|
||||
it( 'should retrieve all stream branches', async ( ) => {
|
||||
let query = `
|
||||
query{
|
||||
@@ -573,6 +575,8 @@ describe( 'GraphQL API Core', ( ) => {
|
||||
expect( res.body.data.stream.branches.totalCount ).to.equal( 3 )
|
||||
expect( res.body.data.stream.branches.cursor ).to.exist
|
||||
|
||||
bees = res.body.data.stream.branches.items
|
||||
|
||||
let query2 = `
|
||||
query{
|
||||
stream(id: "${ts1}"){
|
||||
@@ -600,23 +604,123 @@ describe( 'GraphQL API Core', ( ) => {
|
||||
} )
|
||||
|
||||
it( 'should retrieve a stream branch', async ( ) => {
|
||||
// note: adding another commit for the sake of it
|
||||
const res1 = await sendRequest( userA.token, { query: `mutation($branch:BranchUpdateInput!) { branchUpdate(streamId:"${ts1}", branch:$branch) }`, variables: { branch: { id: b1.id, commits: [ c2.id ] } } } )
|
||||
const res = await sendRequest( userA.token, { query: `query { stream(id:"${ts1}") { branch(id:"${retrievedStream.branches.branches[0].id}") { name description commits { totalCount } } } } ` } )
|
||||
|
||||
const res = await sendRequest( userA.token, { query: `query { stream(id:"${ts1}") { branch( name: "${bees[1].name}" ) { name description } } } ` } )
|
||||
|
||||
expect( res ).to.be.json
|
||||
expect( res.body.errors ).to.not.exist
|
||||
expect( res.body.data.stream.branch.name ).to.equal( 'branch 1' )
|
||||
expect( res.body.data.stream.branch.commits.totalCount ).to.equal( 2 )
|
||||
|
||||
expect( res.body.data.stream.branch.name ).to.equal( 'dim/dev' )
|
||||
} )
|
||||
|
||||
it( 'should retrieve a branch`s commits', async ( ) => {
|
||||
assert.fail( 'todo' )
|
||||
let query = `
|
||||
query {
|
||||
stream( id: "${ts1}" ) {
|
||||
branch( name: "master" ) {
|
||||
id
|
||||
name
|
||||
commits( limit: 5 ) {
|
||||
totalCount
|
||||
cursor
|
||||
items {
|
||||
id
|
||||
message
|
||||
createdAt
|
||||
referencedObject
|
||||
authorId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
const res = await sendRequest( userA.token, { query: query } )
|
||||
expect( res.body.data.stream.branch.commits.items.length ).to.equal( 5 )
|
||||
expect( res.body.data.stream.branch.commits.items[ 0 ] ).to.have.property( 'id' )
|
||||
expect( res.body.data.stream.branch.commits.items[ 0 ] ).to.have.property( 'message' )
|
||||
expect( res.body.data.stream.branch.commits.items[ 0 ] ).to.have.property( 'createdAt' )
|
||||
|
||||
let query2 = `
|
||||
query {
|
||||
stream( id: "${ts1}" ) {
|
||||
branch( name: "master" ) {
|
||||
id
|
||||
name
|
||||
commits( limit: 3, cursor: "${res.body.data.stream.branch.commits.cursor}" ) {
|
||||
totalCount
|
||||
cursor
|
||||
items {
|
||||
id
|
||||
message
|
||||
createdAt
|
||||
referencedObject
|
||||
authorId
|
||||
authorName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const res2 = await sendRequest( userA.token, { query: query2 } )
|
||||
// console.log( res2.body.errors )
|
||||
// console.log( res2.body.data.stream.branch.commits )
|
||||
|
||||
expect( res2.body.data.stream.branch.commits.items.length ).to.equal( 3 )
|
||||
expect( res2.body.data.stream.branch.commits.items[ 0 ] ).to.have.property( 'id' )
|
||||
expect( res2.body.data.stream.branch.commits.items[ 0 ] ).to.have.property( 'message' )
|
||||
expect( res2.body.data.stream.branch.commits.items[ 0 ] ).to.have.property( 'createdAt' )
|
||||
} )
|
||||
|
||||
it( 'should retrieve all stream commits', async ( ) => {
|
||||
assert.fail( 'todo' )
|
||||
let query = `
|
||||
query {
|
||||
stream( id: "${ts1}" ) {
|
||||
commits( limit: 10 ) {
|
||||
totalCount
|
||||
cursor
|
||||
items {
|
||||
id
|
||||
message
|
||||
authorId
|
||||
authorName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
const res = await sendRequest( userA.token, { query: query } )
|
||||
|
||||
expect( res ).to.be.json
|
||||
expect( res.body.errors ).to.not.exist
|
||||
expect( res.body.data.stream.commits.items.length ).to.equal( 10 )
|
||||
expect( res.body.data.stream.commits.totalCount ).to.equal( 12 )
|
||||
|
||||
let query2 = `
|
||||
query {
|
||||
stream( id: "${ts1}" ) {
|
||||
commits( limit: 10, cursor: "${res.body.data.stream.commits.cursor}" ) {
|
||||
totalCount
|
||||
cursor
|
||||
items {
|
||||
id
|
||||
message
|
||||
authorId
|
||||
authorName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const res2 = await sendRequest( userA.token, { query: query2 } )
|
||||
console.log( res2.body.errors )
|
||||
console.log( res2.body.data.stream.commits )
|
||||
|
||||
expect( res2 ).to.be.json
|
||||
expect( res2.body.errors ).to.not.exist
|
||||
expect( res2.body.data.stream.commits.items.length ).to.equal( 2 )
|
||||
|
||||
} )
|
||||
|
||||
it( 'should retrieve a stream commit', async ( ) => {
|
||||
|
||||
Reference in New Issue
Block a user