Files
speckle-server/modules/core/tests/graphSubs.spec.js
T
Dimitrie Stefanescu e4f213d4f6 test(subscriptions): works with separate run test server, figuring out starting it from test file
doing `npm run dev:server:test` and running the test with that server over port 3000 works. seems
like ws upgrade requests are not honoured when the server is started from the test file (on 3001).
2020-08-20 10:27:48 +03:00

140 lines
5.4 KiB
JavaScript

/* istanbul ignore file */
const crypto = require( 'crypto' )
const chai = require( 'chai' )
const chaiHttp = require( 'chai-http' )
const assert = require( 'assert' )
const appRoot = require( 'app-root-path' )
const gql = require( 'graphql-tag' )
const { execute } = require( 'apollo-link' )
const { WebSocketLink } = require( 'apollo-link-ws' )
const { SubscriptionClient } = require( 'subscriptions-transport-ws' )
const ws = require( 'ws' )
const { init, startHttp } = require( `${appRoot}/app` )
const expect = chai.expect
chai.use( chaiHttp )
const knex = require( `${appRoot}/db/knex` )
const { createUser } = require( '../services/users' )
const { createPersonalAccessToken, validateToken } = require( '../services/tokens' )
const { createObject, createObjects } = require( '../services/objects' )
const addr = `http://localhost:${process.env.PORT || 3000}`
const wsAddr = `ws://localhost:${process.env.PORT || 3000}`
// const addr = `http://localhost:3000/graphql`
// const wsAddr = `ws://localhost:3000/graphql`
describe( 'GraphQL API Subscriptions', ( ) => {
let userA = { name: 'd1', username: 'd1', email: 'd.1@speckle.systems', password: 'wow' }
let userB = { name: 'd2', username: 'd2', email: 'd.2@speckle.systems', password: 'wow' }
let testServer
const getWsClient = ( wsurl, authToken ) => {
const client = new SubscriptionClient( wsAddr, {
reconnect: true,
connectionParams: { headers: { Authorization: authToken } }
},
ws )
return client
}
const createSubscriptionObservable = ( wsurl, authToken, query, variables ) => {
authToken = authToken || userA.token
const link = new WebSocketLink( getWsClient( wsurl, authToken ) )
return execute( link, { query: query, variables: variables } )
}
// set up app & two basic users to ping pong permissions around
before( async ( ) => {
await knex.migrate.rollback( )
await knex.migrate.latest( )
let { app } = await init( )
let { server } = await startHttp( app )
testServer = server
userA.id = await createUser( userA )
let token = await createPersonalAccessToken( userA.id, 'test token user A', [ 'streams:read', 'streams:write', 'users:read', 'users:email', 'tokens:write', 'tokens:read', 'profile:read', 'profile:email' ] )
userA.token = `Bearer ${token}`
userB.id = await createUser( userB )
userB.token = `Bearer ${( await createPersonalAccessToken( userB.id, 'test token user B', [ 'streams:read', 'streams:write', 'users:read', 'users:email', 'tokens:write', 'tokens:read', 'profile:read', 'profile:email' ] ) )}`
} )
after( async ( ) => {
testServer.close( )
} )
describe( 'Streams', ( ) => {
it( 'Should be notified when a stream is created', async ( ) => {
let eventNum = 0
const query = gql `subscription mySub { userStreamCreated ( ownerId: "${userA.id}" ) }`
const client = createSubscriptionObservable( wsAddr, userA.token, query )
const consumer = client.subscribe( eventData => {
// console.log( 'Create subscription log' )
// console.log( eventData )
expect( eventData.data.userStreamCreated ).to.exist
eventNum++
} )
let sc1 = await sendRequest( userA.token, { query: `mutation { streamCreate(stream: { name: "Subs Test (u A) Private", description: "Hello World", isPublic:false } ) }` } )
expect( sc1.body.errors ).to.not.exist
let sc2 = await sendRequest( userA.token, { query: `mutation { streamCreate(stream: { name: "Subs Test (u A) Private", description: "Hello World", isPublic:false } ) }` } )
expect( sc2.body.errors ).to.not.exist
await sleep( 1000 ) // we need to wait up a second here
expect( eventNum ).to.equal( 2 )
consumer.unsubscribe( )
} ).timeout( 2000 )
it( 'Should be notified when a stream is updated', async ( ) => {
const resSC = await sendRequest( userA.token, { query: `mutation { streamCreate(stream: { name: "Subs Test (u A) Private", description: "Hello World", isPublic:false } ) }` } )
const streamId = resSC.body.data.streamCreate
let eventNum = 0
const query = gql `subscription streamUpdated { streamUpdated( streamId: "${streamId}" ) }`
const client = createSubscriptionObservable( wsAddr, userA.token, query )
const consumer = client.subscribe( eventData => {
// console.log( 'update subscription log' )
// console.log( eventData )
expect( eventData.data.streamUpdated ).to.exist
eventNum++
} )
const resSU = await sendRequest( userA.token, { query: `mutation { streamUpdate(stream: { id: "${streamId}", description: "updated this stream" } ) }` } )
expect( resSU.body.errors ).to.not.exist
const resSU_2 = await sendRequest( userA.token, { query: `mutation { streamUpdate(stream: { id: "${streamId}", description: "updated this stream... again!" } ) }` } )
expect( resSU_2.body.errors ).to.not.exist
await sleep( 1000 ) // we need to wait up a second here
expect( eventNum ).to.equal( 2 )
consumer.unsubscribe( )
} )
} )
} )
/**
* Sends a graphql request. Convenience wrapper.
* @param {string} auth the user's token
* @param {string} obj the query/mutation to send
* @return {Promise} the awaitable request
*/
function sendRequest( auth, obj, address = addr ) {
return chai.request( address ).post( '/graphql' ).set( 'Authorization', auth ).send( obj )
}
function sleep( ms ) {
return new Promise( ( resolve ) => {
setTimeout( resolve, ms )
} )
}