Skellington-Closet / slack-mock

A Slack API mocker for Slack bot integration tests.
MIT License
64 stars 15 forks source link

Missing bot Identity when mocking slack api #22

Closed L0wry closed 7 years ago

L0wry commented 7 years ago

Hey guys,

Having some trouble mocking out the slack api and would really appreciate some help! I've pretty much copied your example test for a slack app.

describe('Slack Controller', function () {

let slackMock;
const botToken = 'xoxb-XXXXXXXXXXXX-TTTTTTTTTTTTTT'
this.timeout(10000);

before(() => {
    slackMock = require('slack-mock')({
        rtmPort: 9001,
        logLevel: 'debug'
    });
});

it('should start an rtm connection', (done) => {
    slackController.init(botToken);
    return slackMock.rtm.send(botToken, {
            type: 'message',
            channel: 'mockChannel',
            user: 'usr',
            text: 'hello',
        })

    .then(delay(20))
    .then(() => {
        expect(slackMock.rtm.calls).to.have.length(1)           
    })
})
});

My problem is that when the bot gets spawned and i call startRTM() (using botkit npm package) I get this exception slack-mock ERROR uncaughtException: Cannot read property 'name' of undefined

I can see that if i log out the bot that there is an identity object set to id:null and name:'' and have tried to hack my way around it with no luck.

Am I missing something here? You can see how I spawn the bot below

 const controller = BotKit.slackbot({
    debug: true,
    scopes: ['bot'],
    send_via_rtm: true
});
const bot = controller.spawn({
    debug: true,
    token: botToken,
}).startRTM(function (err, bot, payload) {
    if (err) {
        throw new Error(err)
    }
});

Thank you!!

colestrode commented 7 years ago

Hey @Lowry99 :) Thanks for giving slack-mock a try :)

Underneath the hood, Botkit calls the Web API rtm.start method before starting the RTM connection. You'll need to mock the response to that endpoint. Take a look at this example test where I do something similar: https://github.com/Skellington-Closet/slack-mock/blob/master/examples/test/slack-app.spec.js#L25

L0wry commented 7 years ago

Hey man,

Thanks for the help. Managed to make a fair bit of progress. Unfortunately this is a side project so I don't very often get the time to spend on it that I would like.

Botkit seems to now use rtm.connect which is cool. I've mocked the response out, but the part that has now got me is in the response for rtm.connect you need to provide a websocket url for your app to connect to. Not totally sure what to put here. I've tried various things and added a responses for it, but no luck

Does Slack-Mock support the rtm.connect websocket or should I go ahead and mock it out myself? You can find the debug below

Cheers!

slack-mock DEBUG intercepted web request: https://slack.com/api/rtm.connect
slack-mock DEBUG responding to web with override
{
  "statusCode": 200,
  "body": {
    "ok": true,
    "url": "????",
    "team": {
      "id": "T654321",
      "name": "team",
      "domain": "libsocos"
    },
    "self": {
      "id": "mockBotId",
      "name": "mockBot"
    }
  },
  "headers": {}
}
debug: Got response null {"ok":true,"url":"????","team":{"id":"T654321","name":"team","domain":"libsocos"},"self":{"id":"mockBotId","name":"mockBot"}}
notice: ** BOT ID: mockBot ...attempting to connect to RTM!
error: RTM websocket error! { Error: socket hang up
    at createHangUpError (_http_client.js:343:15)
    at Socket.socketOnEnd (_http_client.js:435:23)
    at emitNone (events.js:110:20)
    at Socket.emit (events.js:207:7)
    at endReadableNT (_stream_readable.js:1045:12)
    at _combinedTickCallback (internal/process/next_tick.js:102:11)
    at process._tickCallback (internal/process/next_tick.js:161:9) code: 'ECONNRESET' }
notice: RTM close event: 1006 :
error: Abnormal websocket close event, attempting to reconnect
L0wry commented 7 years ago

just spent some time looking at slack-mock

I think the problem might possibly come from here

  const body = response[1]
  if (/rtm\.start/.test(url) && body.ok) {
    const rtmUrl = rtm._.addToken(params.token)
    body.url = rtmUrl
  }

I don't think we call rtm._addToken if rtm.connect is used

colestrode commented 7 years ago

No problem about the lag :) I think you're right, this is a bug in slack-mock. Are you interested in submitting a PR? Otherwise I can take a look some time this week.

Thanks again for reporting!

L0wry commented 7 years ago

adding rtm.connect