How to do integration test with chai for internal and nock for external api call

Viewed 149

I have an app for Slack Interactivity Handling, what I'd like to do is just to receive webhook from the slack button and update the message via Slack API.

I use express on my server, and core https module for my API call, here's my server.js

const https = require('https')
const express = require('express')
const app = express()

app.use(express.json())
app.post('/slack/actions', (req, res) => {
  const payload = JSON.parse(JSON.stringify(req.body.payload))
  const { status, message } = process(payload)

  res.status(status).json({ 'message': message })
})

function process(payload) => {
  const action = payload.actions.value
  if (action == 'ack') {
    return ack(payload)
  } else {
    return { status: 400, message: 'Action invalid' }
  }
}

function ack(payload) => {
  const userId = payload.user.id
  const updatedMessage = {
    type: 'section',
    text: { type: 'mrkdwn', text: `Approved by <@${userId}>` }
  }

  const token = payload.token
  const channel = payload.container.channel_id
  const messageId = payload.container.message_ts
  const message = payload.message.blocks
  message.splice(-1, 1, updatedMessage)

  api('https://slack.com/api/chat.update', 'POST', {
    token: token,
    channel: channel,
    ts: messageId,
    blocks: message
  })

  return { status: 200, message: 'Package received' }
}

function api(){
  const opts = {
    uri: url,
    method: method,
    headers: { 'Content-type': 'application/json' },
    json: data
  }
  const req = https.request(opts, res => {
    console.log(`statusCode: ${res.statusCode}`)
    console.log(res.body)
  })
  req.on('error', error => {
    console.error(`Error: ${error}`)
  })
  req.end()
}

I don't have a problem with the App, but I'd like to do integration testing to test success & failed slack API calls.

Here's my server.spec.js

const app = require('../server')
const chai = require('chai')
const chaiHttp = require('chai-http')
const nock = require('nock')

chai.use(chaiHttp)
chai.should()
describe('Slack App', () => {
  describe("POST /slack/actions", () => {
    it("should update message on ack", (done) => {
      const blocks = [
        { "type": "section", "text": { "type": "mrkdwn", "text": "Title", } },
        { "type": "section", "text": { "type": "mrkdwn", "text": "Info" } },
        { "type": "actions", "elements": [{
          "type": "button",
          "text": { "type": "plain_text", "text": "Approve", },
          "value": "ack"
        }]
      }]
      const data = {
        payload: {
          token: 'token',
          container: { channel_id: 'CH4NN3L', message_ts: '1626196341.000900' },
          message: { blocks: blocks },
          actions: { value: 'ack' },
          user: { id: 'US3R1D' }
        }
      }
      const expectedBlocks = [
        { "type": "section", "text": { "type": "mrkdwn", "text": "Title", } },
        { "type": "section", "text": { "type": "mrkdwn", "text": "Info" } },
        { type: 'section', text: { type: 'mrkdwn', text: 'Approved by <@US3R1D>' } }
      ]
      const expectedParams = { token: 'token', channel: 'CH4NN3L', ts: '1626196341.000900', blocks: expectedBlocks }
      const expectedNock = nock('https://slack.com/api',
        { reqheaders: { 'Content-type': 'application/json' } }
      )
        .post('/chat.update', expectedParams)
        .reply(200, {})

      chai.request(app)
          .post('/slack/actions')
          .set('content-type', 'application/json')
          .send(data)
          .end((err, res) => {
            expectedNock.isDone().should.be.true
            res.should.have.status(200)
            res.body.should.be.a('object')
            res.body.should.include({ message: 'Package received' })
            done()
          })
    })
  })
})

It seems the test still calls the real API, because there's an error log Error: Error: connect ECONNREFUSED 127.0.0.1:443

Also, the nock interceptor doesn't seem to intercept the https.request call as the test failed with Uncaught AssertionError: expected false to be true

Is nock the correct lib to test this? Also is this the correct way to test this?

0 Answers
Related