|
import gql from 'graphql-tag'; |
|
import { WebSocketLink } from 'apollo-link-ws'; |
|
import { SubscriptionClient } from 'subscriptions-transport-ws'; |
|
import { execute } from 'apollo-link'; |
|
|
|
// This doesn't work with import. No idea why |
|
const ws = require('ws'); |
|
|
|
// How many times to repeat doSubscription |
|
const repetitions = 10; |
|
|
|
// How long to wait until we get through REPETETITIONS times |
|
// calling doSubscription (in ms). On my machine, which also runs graph-node, |
|
// setting this to 250 leads to intermittent failures, bumping it to 2500 |
|
// lets this test pass reliably |
|
const subscription_timeout = 2500; |
|
|
|
// Change these two variables to match whatever you have deployed as a |
|
// subgraph. It does not seem to matter what is used; you will also have |
|
// to adapt the 'expect' below. |
|
// This is based on https://github.com/lutter/dice2win-subgraph |
|
//const subgraph_url = 'ws://127.0.0.1:8001/subgraphs/name/dice2win'; |
|
const subgraph_url = 'wss://api.staging.thegraph.com/subgraphs/name/lutter/dice2win'; |
|
const subgraph_subscr = gql` |
|
subscription js_test { |
|
beneficiaries(where: {jackpots_gt: 0}) { |
|
id |
|
winnings |
|
jackpots |
|
} |
|
}`; |
|
|
|
async function waitUntilTrue(f: () => boolean) { |
|
return new Promise((resolve, reject) => { |
|
(function waitForIt() { |
|
if (f()) { return resolve(); } |
|
setTimeout(waitForIt, 30); |
|
})(); |
|
}); |
|
} |
|
|
|
// Subscribe to a query and wait for the first response. Check that the |
|
// response contains some well-known data. |
|
async function doSubscription(step: number) { |
|
const client = new SubscriptionClient(subgraph_url, { reconnect: true }, ws); |
|
const link = new WebSocketLink(client); |
|
let query : string = subgraph_subscr; |
|
const subscriptionClient = execute(link, { query }); |
|
|
|
let event; |
|
let nextWasCalled = false; |
|
const consumer = await subscriptionClient.subscribe( |
|
(eventData) => { |
|
// Do something on receipt of the event |
|
nextWasCalled = true; |
|
event = eventData.data; |
|
}, |
|
(err) => { |
|
expect(true).toEqual(false); |
|
}, |
|
); |
|
|
|
// wait until the subscription callback has been called |
|
await waitUntilTrue(() => nextWasCalled); |
|
console.log('Step #%d:\n%O', step, event); |
|
expect(event.beneficiaries).toContainEqual({ |
|
id: "0xb461c1ce4b3421b9be916f8a3114865bb5bf9968", |
|
winnings: expect.any(String), |
|
jackpots: expect.any(String) |
|
}); |
|
consumer.unsubscribe(); |
|
client.close(); |
|
}; |
|
|
|
async function doSubscriptions(n: number) { |
|
for (let i = 1; i <= n; i++) { |
|
console.log('Call #%d', i); |
|
await doSubscription(i); |
|
} |
|
}; |
|
|
|
describe('Subscriptions', () => { |
|
it('subscribes', async () => { |
|
console.log('Subscribing to %s', subgraph_url); |
|
await doSubscriptions(repetitions) |
|
}, repetitions*subscription_timeout); |
|
}); |