Repository: Yoctol/bottender
Pull request #15 (2017-11-10 07:35:49)

implement thread control methods
- context.passThreadControl(targetAppId, metadata)
- context.passThreadControlToPageInbox
- context.takeThreadControl


Patch:
diff --git a/src/context/MessengerContext.js b/src/context/MessengerContext.js
index 0b5658f0..949ee232 100644
--- a/src/context/MessengerContext.js
+++ b/src/context/MessengerContext.js
@@ -110,6 +110,55 @@ class MessengerContext extends Context implements PlatformContext {
 
     return this._client.markSeen(this._session.user.id);
   }
+
+  async passThreadControl(
+    targetAppId: number,
+    metadata?: string
+  ): Promise<any> {
+    if (!this._session) {
+      warning(
+        false,
+        'passThreadControl: should not be called in context without session'
+      );
+      return;
+    }
+
+    this._isHandled = true;
+
+    return this._client.passThreadControl(
+      this._session.user.id,
+      targetAppId,
+      metadata
+    );
+  }
+
+  async passThreadControlToPageInbox(): Promise<any> {
+    if (!this._session) {
+      warning(
+        false,
+        'passThreadControlToPageInbox: should not be called in context without session'
+      );
+      return;
+    }
+
+    this._isHandled = true;
+
+    return this._client.passThreadControlToPageInbox(this._session.user.id);
+  }
+
+  async takeThreadControl(): Promise<any> {
+    if (!this._session) {
+      warning(
+        false,
+        'takeThreadControl: should not be called in context without session'
+      );
+      return;
+    }
+
+    this._isHandled = true;
+
+    return this._client.takeThreadControl(this._session.user.id);
+  }
 }
 
 const sendMethods = [


Test patch:
diff --git a/src/context/__tests__/MessengerContext.spec.js b/src/context/__tests__/MessengerContext.spec.js
index 2ffa324d..292a7449 100644
--- a/src/context/__tests__/MessengerContext.spec.js
+++ b/src/context/__tests__/MessengerContext.spec.js
@@ -40,6 +40,9 @@ const createMockGraphAPIClient = () => ({
   sendAirlineItineraryTemplate: jest.fn(),
   sendAirlineFlightUpdateTemplate: jest.fn(),
   sendTextWithDelay: jest.fn(),
+  passThreadControl: jest.fn(),
+  passThreadControlToPageInbox: jest.fn(),
+  takeThreadControl: jest.fn(),
 });
 
 const rawEvent = {
@@ -669,3 +672,64 @@ describe('#typing', () => {
     expect(client.typingOff).toBeCalled();
   });
 });
+
+describe('#passThreadControl', () => {
+  it('should call to pass user thread control to other app', async () => {
+    const { context, client, session } = setup();
+
+    await context.passThreadControl(263902037430900, 'metadata');
+
+    expect(client.passThreadControl).toBeCalledWith(
+      session.user.id,
+      263902037430900,
+      'metadata'
+    );
+  });
+
+  it('should call warning if dont have session', async () => {
+    const { context, client } = setup({ session: false });
+
+    await context.passThreadControl(263902037430900, 'metadata');
+
+    expect(warning).toBeCalled();
+    expect(client.passThreadControl).not.toBeCalled();
+  });
+});
+
+describe('#passThreadControlToPageInbox', () => {
+  it('should call to pass user thread control to page inbox', async () => {
+    const { context, client, session } = setup();
+
+    await context.passThreadControlToPageInbox();
+
+    expect(client.passThreadControlToPageInbox).toBeCalledWith(session.user.id);
+  });
+
+  it('should call warning if dont have session', async () => {
+    const { context, client } = setup({ session: false });
+
+    await context.passThreadControlToPageInbox();
+
+    expect(warning).toBeCalled();
+    expect(client.passThreadControlToPageInbox).not.toBeCalled();
+  });
+});
+
+describe('#takeThreadControl', () => {
+  it('should call to take user thread control back', async () => {
+    const { context, client, session } = setup();
+
+    await context.takeThreadControl();
+
+    expect(client.takeThreadControl).toBeCalledWith(session.user.id);
+  });
+
+  it('should call warning if dont have session', async () => {
+    const { context, client } = setup({ session: false });
+
+    await context.takeThreadControl();
+
+    expect(warning).toBeCalled();
+    expect(client.takeThreadControl).not.toBeCalled();
+  });
+});