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?