summaryrefslogtreecommitdiff
path: root/test/streaming.ts
diff options
context:
space:
mode:
Diffstat (limited to 'test/streaming.ts')
-rw-r--r--test/streaming.ts913
1 files changed, 807 insertions, 106 deletions
diff --git a/test/streaming.ts b/test/streaming.ts
index 500324d520..74a5aaa0b4 100644
--- a/test/streaming.ts
+++ b/test/streaming.ts
@@ -6,143 +6,844 @@
*
* To specify test:
* > mocha test/streaming.ts --require ts-node/register -g 'test name'
+ *
+ * If the tests not start, try set following enviroment variables:
+ * TS_NODE_FILES=true and TS_NODE_TRANSPILE_ONLY=true
+ * for more details, please see: https://github.com/TypeStrong/ts-node/issues/754
*/
-import * as http from 'http';
-import * as WebSocket from 'ws';
+process.env.NODE_ENV = 'test';
+
import * as assert from 'assert';
-import { _signup, _request, _uploadFile, _post, _react, resetDb } from './utils';
+import * as childProcess from 'child_process';
+import { connectStream, signup, request, post } from './utils';
+import { Following } from '../built/models/entities/following';
+const initDb = require('../built/db/postgre.js').initDb;
-//#region process
-Error.stackTraceLimit = Infinity;
+describe('Streaming', () => {
+ let p: childProcess.ChildProcess;
+ let Followings: any;
-// During the test the env variable is set to test
-process.env.NODE_ENV = 'test';
+ beforeEach(done => {
+ p = childProcess.spawn('node', [__dirname + '/../index.js'], {
+ stdio: ['inherit', 'inherit', 'ipc'],
+ env: { NODE_ENV: 'test' }
+ });
+ p.on('message', message => {
+ if (message === 'ok') {
+ (p.channel as any).onread = () => {};
+ initDb(true).then(async connection => {
+ Followings = connection.getRepository(Following);
+ done();
+ });
+ }
+ });
+ });
-// Display detail of unhandled promise rejection
-process.on('unhandledRejection', console.dir);
-//#endregion
+ afterEach(() => {
+ p.kill();
+ });
-const app = require('../built/server/api').default;
-const server = require('../built/server').startServer();
-const db = require('../built/db/mongodb').default;
+ const follow = async (follower, followee) => {
+ await Followings.save({
+ id: 'a',
+ createdAt: new Date(),
+ followerId: follower.id,
+ followeeId: followee.id,
+ followerHost: follower.host,
+ followerInbox: null,
+ followerSharedInbox: null,
+ followeeHost: followee.host,
+ followeeInbox: null,
+ followeeSharedInbox: null
+ });
+ };
-const apiServer = http.createServer(app.callback());
+ it('mention event', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
-//#region Utilities
-const request = _request(apiServer);
-const signup = _signup(request);
-const post = _post(request);
-//#endregion
+ const ws = await connectStream(bob, 'main', ({ type, body }) => {
+ if (type == 'mention') {
+ assert.deepStrictEqual(body.userId, alice.id);
+ ws.close();
+ done();
+ }
+ });
-describe('Streaming', () => {
- // Reset database each test
- beforeEach(resetDb(db));
+ post(alice, {
+ text: 'foo @bob bar'
+ });
+ }));
+
+ it('renote event', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+ const bobNote = await post(bob, {
+ text: 'foo'
+ });
+
+ const ws = await connectStream(bob, 'main', ({ type, body }) => {
+ if (type == 'renote') {
+ assert.deepStrictEqual(body.renoteId, bobNote.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(alice, {
+ renoteId: bobNote.id
+ });
+ }));
+
+ describe('Home Timeline', () => {
+ it('自分の投稿が流れる', () => new Promise(async done => {
+ const post = {
+ text: 'foo'
+ };
+
+ const me = await signup();
+
+ const ws = await connectStream(me, 'homeTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.text, post.text);
+ ws.close();
+ done();
+ }
+ });
+
+ request('/notes/create', post, me);
+ }));
+
+ it('フォローしているユーザーの投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ // Alice が Bob をフォロー
+ await request('/following/create', {
+ userId: bob.id
+ }, alice);
+
+ const ws = await connectStream(alice, 'homeTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+ }));
+
+ it('フォローしていないユーザーの投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'homeTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
+ }
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+
+ it('フォローしているユーザーのダイレクト投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ // Alice が Bob をフォロー
+ await request('/following/create', {
+ userId: bob.id
+ }, alice);
+
+ const ws = await connectStream(alice, 'homeTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ assert.deepStrictEqual(body.text, 'foo');
+ ws.close();
+ done();
+ }
+ });
+
+ // Bob が Alice 宛てのダイレクト投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'specified',
+ visibleUserIds: [alice.id]
+ });
+ }));
+
+ it('フォローしているユーザーでも自分が指定されていないダイレクト投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+ const carol = await signup({ username: 'carol' });
+
+ // Alice が Bob をフォロー
+ await request('/following/create', {
+ userId: bob.id
+ }, alice);
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'homeTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
+ }
+ });
- after(() => {
- server.close();
+ // Bob が Carol 宛てのダイレクト投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'specified',
+ visibleUserIds: [carol.id]
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
});
- it('投稿がタイムラインに流れる', () => new Promise(async done => {
- const post = {
- text: 'foo'
- };
+ describe('Local Timeline', () => {
+ it('自分の投稿が流れる', () => new Promise(async done => {
+ const me = await signup();
+
+ const ws = await connectStream(me, 'localTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, me.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(me, {
+ text: 'foo'
+ });
+ }));
- const me = await signup();
- const ws = new WebSocket(`ws://localhost/streaming?i=${me.token}`);
+ it('フォローしていないローカルユーザーの投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
- ws.on('open', () => {
- ws.on('message', data => {
- const msg = JSON.parse(data.toString());
- if (msg.type == 'channel' && msg.body.id == 'a') {
- if (msg.body.type == 'note') {
- assert.deepStrictEqual(msg.body.body.text, post.text);
- ws.close();
- done();
- }
- } else if (msg.type == 'connected' && msg.body.id == 'a') {
- request('/notes/create', post, me);
+ const ws = await connectStream(alice, 'localTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ ws.close();
+ done();
}
});
- ws.send(JSON.stringify({
- type: 'connect',
- body: {
- channel: 'homeTimeline',
- id: 'a',
- pong: true
+ post(bob, {
+ text: 'foo'
+ });
+ }));
+
+ it('リモートユーザーの投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob', host: 'example.com' });
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'localTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
}
- }));
- });
- }));
+ });
- it('mention event', () => new Promise(async done => {
- const alice = await signup({ username: 'alice' });
- const bob = await signup({ username: 'bob' });
- const aliceNote = {
- text: 'foo @bob bar'
- };
+ post(bob, {
+ text: 'foo'
+ });
- const ws = new WebSocket(`ws://localhost/streaming?i=${bob.token}`);
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
- ws.on('open', () => {
- ws.on('message', data => {
- const msg = JSON.parse(data.toString());
- if (msg.type == 'channel' && msg.body.id == 'a') {
- if (msg.body.type == 'mention') {
- assert.deepStrictEqual(msg.body.body.text, aliceNote.text);
- ws.close();
- done();
- }
- } else if (msg.type == 'connected' && msg.body.id == 'a') {
- request('/notes/create', aliceNote, alice);
+ it('フォローしてたとしてもリモートユーザーの投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob', host: 'example.com' });
+
+ // Alice が Bob をフォロー
+ await request('/following/create', {
+ userId: bob.id
+ }, alice);
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'localTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
}
});
- ws.send(JSON.stringify({
- type: 'connect',
- body: {
- channel: 'main',
- id: 'a',
- pong: true
+ post(bob, {
+ text: 'foo'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+
+ it('ホーム指定の投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'localTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
}
- }));
- });
- }));
+ });
- it('renote event', () => new Promise(async done => {
- const alice = await signup({ username: 'alice' });
- const bob = await signup({ username: 'bob' });
- const bobNote = await post(bob, {
- text: 'foo'
- });
+ // ホーム指定
+ post(bob, {
+ text: 'foo',
+ visibility: 'home'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+
+ it('フォローしているローカルユーザーのダイレクト投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
- const ws = new WebSocket(`ws://localhost/streaming?i=${bob.token}`);
+ // Alice が Bob をフォロー
+ await request('/following/create', {
+ userId: bob.id
+ }, alice);
- ws.on('open', () => {
- ws.on('message', data => {
- const msg = JSON.parse(data.toString());
- if (msg.type == 'channel' && msg.body.id == 'a') {
- if (msg.body.type == 'renote') {
- assert.deepStrictEqual(msg.body.body.renoteId, bobNote.id);
- ws.close();
- done();
- }
- } else if (msg.type == 'connected' && msg.body.id == 'a') {
- request('/notes/create', {
- renoteId: bobNote.id
- }, alice);
+ const ws = await connectStream(alice, 'localTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ assert.deepStrictEqual(body.text, 'foo');
+ ws.close();
+ done();
}
});
- ws.send(JSON.stringify({
- type: 'connect',
- body: {
- channel: 'main',
- id: 'a',
- pong: true
+ // Bob が Alice 宛てのダイレクト投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'specified',
+ visibleUserIds: [alice.id]
+ });
+ }));
+
+ it('フォローしていないローカルユーザーのフォロワー宛て投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'localTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
}
- }));
- });
- }));
+ });
+
+ // フォロワー宛て投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'followers'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+ });
+
+ describe('Social Timeline', () => {
+ it('自分の投稿が流れる', () => new Promise(async done => {
+ const me = await signup();
+
+ const ws = await connectStream(me, 'socialTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, me.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(me, {
+ text: 'foo'
+ });
+ }));
+
+ it('フォローしていないローカルユーザーの投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ const ws = await connectStream(alice, 'socialTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+ }));
+
+ it('フォローしているリモートユーザーの投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob', host: 'example.com' });
+
+ // Alice が Bob をフォロー
+ await follow(alice, bob);
+
+ const ws = await connectStream(alice, 'socialTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+ }));
+
+ it('フォローしていないリモートユーザーの投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob', host: 'example.com' });
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'socialTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
+ }
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+
+ it('フォローしているユーザーのダイレクト投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ // Alice が Bob をフォロー
+ await request('/following/create', {
+ userId: bob.id
+ }, alice);
+
+ const ws = await connectStream(alice, 'socialTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ assert.deepStrictEqual(body.text, 'foo');
+ ws.close();
+ done();
+ }
+ });
+
+ // Bob が Alice 宛てのダイレクト投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'specified',
+ visibleUserIds: [alice.id]
+ });
+ }));
+
+ it('フォローしていないローカルユーザーのフォロワー宛て投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'socialTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
+ }
+ });
+
+ // フォロワー宛て投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'followers'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+ });
+
+ describe('Global Timeline', () => {
+ it('フォローしていないローカルユーザーの投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ const ws = await connectStream(alice, 'globalTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+ }));
+
+ it('フォローしていないリモートユーザーの投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob', host: 'example.com' });
+
+ const ws = await connectStream(alice, 'globalTimeline', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ ws.close();
+ done();
+ }
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+ }));
+ });
+
+ describe('UserList Timeline', () => {
+ it('リストに入れているユーザーの投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ // リスト作成
+ const list = await request('/users/lists/create', {
+ title: 'my list'
+ }, alice).then(x => x.body);
+
+ // Alice が Bob をリスイン
+ await request('/users/lists/push', {
+ listId: list.id,
+ userId: bob.id
+ }, alice);
+
+ const ws = await connectStream(alice, 'userList', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ ws.close();
+ done();
+ }
+ }, {
+ listId: list.id
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+ }));
+
+ it('リストに入れていないユーザーの投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ // リスト作成
+ const list = await request('/users/lists/create', {
+ title: 'my list'
+ }, alice).then(x => x.body);
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'userList', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
+ }
+ }, {
+ listId: list.id
+ });
+
+ post(bob, {
+ text: 'foo'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+
+ // #4471
+ it('リストに入れているユーザーのダイレクト投稿が流れる', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ // リスト作成
+ const list = await request('/users/lists/create', {
+ title: 'my list'
+ }, alice).then(x => x.body);
+
+ // Alice が Bob をリスイン
+ await request('/users/lists/push', {
+ listId: list.id,
+ userId: bob.id
+ }, alice);
+
+ const ws = await connectStream(alice, 'userList', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.userId, bob.id);
+ assert.deepStrictEqual(body.text, 'foo');
+ ws.close();
+ done();
+ }
+ }, {
+ listId: list.id
+ });
+
+ // Bob が Alice 宛てのダイレクト投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'specified',
+ visibleUserIds: [alice.id]
+ });
+ }));
+
+ // #4335
+ it('リストに入れているがフォローはしてないユーザーのフォロワー宛て投稿は流れない', () => new Promise(async done => {
+ const alice = await signup({ username: 'alice' });
+ const bob = await signup({ username: 'bob' });
+
+ // リスト作成
+ const list = await request('/users/lists/create', {
+ title: 'my list'
+ }, alice).then(x => x.body);
+
+ // Alice が Bob をリスイン
+ await request('/users/lists/push', {
+ listId: list.id,
+ userId: bob.id
+ }, alice);
+
+ let fired = false;
+
+ const ws = await connectStream(alice, 'userList', ({ type, body }) => {
+ if (type == 'note') {
+ fired = true;
+ }
+ }, {
+ listId: list.id
+ });
+
+ // フォロワー宛て投稿
+ post(bob, {
+ text: 'foo',
+ visibility: 'followers'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fired, false);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+ });
+
+ describe('Hashtag Timeline', () => {
+ it('指定したハッシュタグの投稿が流れる', () => new Promise(async done => {
+ const me = await signup();
+
+ const ws = await connectStream(me, 'hashtag', ({ type, body }) => {
+ if (type == 'note') {
+ assert.deepStrictEqual(body.text, '#foo');
+ ws.close();
+ done();
+ }
+ }, {
+ q: [
+ ['foo']
+ ]
+ });
+
+ post(me, {
+ text: '#foo'
+ });
+ }));
+
+ it('指定したハッシュタグの投稿が流れる (AND)', () => new Promise(async done => {
+ const me = await signup();
+
+ let fooCount = 0;
+ let barCount = 0;
+ let fooBarCount = 0;
+
+ const ws = await connectStream(me, 'hashtag', ({ type, body }) => {
+ if (type == 'note') {
+ if (body.text === '#foo') fooCount++;
+ if (body.text === '#bar') barCount++;
+ if (body.text === '#foo #bar') fooBarCount++;
+ }
+ }, {
+ q: [
+ ['foo', 'bar']
+ ]
+ });
+
+ post(me, {
+ text: '#foo'
+ });
+
+ post(me, {
+ text: '#bar'
+ });
+
+ post(me, {
+ text: '#foo #bar'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fooCount, 0);
+ assert.strictEqual(barCount, 0);
+ assert.strictEqual(fooBarCount, 1);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+
+ it('指定したハッシュタグの投稿が流れる (OR)', () => new Promise(async done => {
+ const me = await signup();
+
+ let fooCount = 0;
+ let barCount = 0;
+ let fooBarCount = 0;
+ let piyoCount = 0;
+
+ const ws = await connectStream(me, 'hashtag', ({ type, body }) => {
+ if (type == 'note') {
+ if (body.text === '#foo') fooCount++;
+ if (body.text === '#bar') barCount++;
+ if (body.text === '#foo #bar') fooBarCount++;
+ if (body.text === '#piyo') piyoCount++;
+ }
+ }, {
+ q: [
+ ['foo'],
+ ['bar']
+ ]
+ });
+
+ post(me, {
+ text: '#foo'
+ });
+
+ post(me, {
+ text: '#bar'
+ });
+
+ post(me, {
+ text: '#foo #bar'
+ });
+
+ post(me, {
+ text: '#piyo'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fooCount, 1);
+ assert.strictEqual(barCount, 1);
+ assert.strictEqual(fooBarCount, 1);
+ assert.strictEqual(piyoCount, 0);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+
+ it('指定したハッシュタグの投稿が流れる (AND + OR)', () => new Promise(async done => {
+ const me = await signup();
+
+ let fooCount = 0;
+ let barCount = 0;
+ let fooBarCount = 0;
+ let piyoCount = 0;
+ let waaaCount = 0;
+
+ const ws = await connectStream(me, 'hashtag', ({ type, body }) => {
+ if (type == 'note') {
+ if (body.text === '#foo') fooCount++;
+ if (body.text === '#bar') barCount++;
+ if (body.text === '#foo #bar') fooBarCount++;
+ if (body.text === '#piyo') piyoCount++;
+ if (body.text === '#waaa') waaaCount++;
+ }
+ }, {
+ q: [
+ ['foo', 'bar'],
+ ['piyo']
+ ]
+ });
+
+ post(me, {
+ text: '#foo'
+ });
+
+ post(me, {
+ text: '#bar'
+ });
+
+ post(me, {
+ text: '#foo #bar'
+ });
+
+ post(me, {
+ text: '#piyo'
+ });
+
+ post(me, {
+ text: '#waaa'
+ });
+
+ setTimeout(() => {
+ assert.strictEqual(fooCount, 0);
+ assert.strictEqual(barCount, 0);
+ assert.strictEqual(fooBarCount, 1);
+ assert.strictEqual(piyoCount, 1);
+ assert.strictEqual(waaaCount, 0);
+ ws.close();
+ done();
+ }, 3000);
+ }));
+ });
});