mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-18 10:22:00 -05:00
Compare commits
1 Commits
cursor/ent
...
cursor/sla
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc4c42e9de |
518
apps/sim/app/api/tools/slack/add-reaction/route.test.ts
Normal file
518
apps/sim/app/api/tools/slack/add-reaction/route.test.ts
Normal file
@@ -0,0 +1,518 @@
|
||||
/**
|
||||
* Tests for Slack Add Reaction API route
|
||||
*
|
||||
* @vitest-environment node
|
||||
*/
|
||||
import {
|
||||
createMockFetch,
|
||||
createMockLogger,
|
||||
createMockRequest,
|
||||
createMockResponse,
|
||||
} from '@sim/testing'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
describe('Slack Add Reaction API Route', () => {
|
||||
const mockLogger = createMockLogger()
|
||||
const mockCheckInternalAuth = vi.fn()
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules()
|
||||
|
||||
vi.doMock('@sim/logger', () => ({
|
||||
createLogger: vi.fn().mockReturnValue(mockLogger),
|
||||
}))
|
||||
|
||||
vi.doMock('@/lib/auth/hybrid', () => ({
|
||||
checkInternalAuth: mockCheckInternalAuth,
|
||||
}))
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.unstubAllGlobals()
|
||||
})
|
||||
|
||||
it('should add reaction successfully', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: true },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(data.success).toBe(true)
|
||||
expect(data.output.content).toBe('Successfully added :thumbsup: reaction')
|
||||
expect(data.output.metadata).toEqual({
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
reaction: 'thumbsup',
|
||||
})
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://slack.com/api/reactions.add',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
headers: expect.objectContaining({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Bearer xoxb-test-token',
|
||||
}),
|
||||
body: JSON.stringify({
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
}),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('should handle emoji name without colons', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: true },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'eyes',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(data.success).toBe(true)
|
||||
expect(data.output.content).toBe('Successfully added :eyes: reaction')
|
||||
})
|
||||
|
||||
it('should handle unauthenticated request', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: false,
|
||||
error: 'Authentication required',
|
||||
})
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(401)
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('Authentication required')
|
||||
})
|
||||
|
||||
it('should handle missing access token', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(400)
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('Invalid request data')
|
||||
})
|
||||
|
||||
it('should handle missing channel', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(400)
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('Invalid request data')
|
||||
})
|
||||
|
||||
it('should handle missing timestamp', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(400)
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('Invalid request data')
|
||||
})
|
||||
|
||||
it('should handle missing emoji name', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(400)
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('Invalid request data')
|
||||
})
|
||||
|
||||
it('should handle Slack API missing_scope error', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: false, error: 'missing_scope' },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('missing_scope')
|
||||
})
|
||||
|
||||
it('should handle Slack API channel_not_found error', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: false, error: 'channel_not_found' },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'CINVALID',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('channel_not_found')
|
||||
})
|
||||
|
||||
it('should handle Slack API message_not_found error', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: false, error: 'message_not_found' },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '0000000000.000000',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('message_not_found')
|
||||
})
|
||||
|
||||
it('should handle Slack API invalid_name error for invalid emoji', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: false, error: 'invalid_name' },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'not_a_valid_emoji',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('invalid_name')
|
||||
})
|
||||
|
||||
it('should handle Slack API already_reacted error', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: false, error: 'already_reacted' },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('already_reacted')
|
||||
})
|
||||
|
||||
it('should handle network error when calling Slack API', async () => {
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockRejectedValueOnce(new Error('Network error'))
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(500)
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBe('Network error')
|
||||
})
|
||||
|
||||
it('should handle various emoji names correctly', async () => {
|
||||
const emojiNames = ['heart', 'fire', 'rocket', '+1', '-1', 'tada', 'eyes', 'thinking_face']
|
||||
|
||||
for (const emojiName of emojiNames) {
|
||||
vi.resetModules()
|
||||
|
||||
vi.doMock('@sim/logger', () => ({
|
||||
createLogger: vi.fn().mockReturnValue(mockLogger),
|
||||
}))
|
||||
|
||||
vi.doMock('@/lib/auth/hybrid', () => ({
|
||||
checkInternalAuth: mockCheckInternalAuth,
|
||||
}))
|
||||
|
||||
mockCheckInternalAuth.mockResolvedValueOnce({
|
||||
success: true,
|
||||
userId: 'user-123',
|
||||
authType: 'api-key',
|
||||
})
|
||||
|
||||
const mockSlackResponse = createMockResponse({
|
||||
status: 200,
|
||||
json: { ok: true },
|
||||
})
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(mockSlackResponse)
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const req = createMockRequest(
|
||||
'POST',
|
||||
{
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: emojiName,
|
||||
},
|
||||
{},
|
||||
'http://localhost:3000/api/tools/slack/add-reaction'
|
||||
)
|
||||
|
||||
const { POST } = await import('@/app/api/tools/slack/add-reaction/route')
|
||||
const response = await POST(req as any)
|
||||
const data = await response.json()
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(data.success).toBe(true)
|
||||
expect(data.output.metadata.reaction).toBe(emojiName)
|
||||
}
|
||||
})
|
||||
})
|
||||
222
apps/sim/blocks/blocks/slack.test.ts
Normal file
222
apps/sim/blocks/blocks/slack.test.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* Tests for Slack Block configuration
|
||||
*
|
||||
* @vitest-environment node
|
||||
*/
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { SlackBlock } from './slack'
|
||||
|
||||
describe('SlackBlock', () => {
|
||||
describe('basic configuration', () => {
|
||||
it('should have correct type and name', () => {
|
||||
expect(SlackBlock.type).toBe('slack')
|
||||
expect(SlackBlock.name).toBe('Slack')
|
||||
})
|
||||
|
||||
it('should have slack_add_reaction in tools access', () => {
|
||||
expect(SlackBlock.tools.access).toContain('slack_add_reaction')
|
||||
})
|
||||
|
||||
it('should have tools.config.tool function', () => {
|
||||
expect(typeof SlackBlock.tools.config?.tool).toBe('function')
|
||||
})
|
||||
|
||||
it('should have tools.config.params function', () => {
|
||||
expect(typeof SlackBlock.tools.config?.params).toBe('function')
|
||||
})
|
||||
})
|
||||
|
||||
describe('tools.config.tool', () => {
|
||||
const getToolName = SlackBlock.tools.config?.tool
|
||||
|
||||
it('should return slack_add_reaction for react operation', () => {
|
||||
expect(getToolName?.({ operation: 'react' })).toBe('slack_add_reaction')
|
||||
})
|
||||
|
||||
it('should return slack_message for send operation', () => {
|
||||
expect(getToolName?.({ operation: 'send' })).toBe('slack_message')
|
||||
})
|
||||
|
||||
it('should return slack_delete_message for delete operation', () => {
|
||||
expect(getToolName?.({ operation: 'delete' })).toBe('slack_delete_message')
|
||||
})
|
||||
|
||||
it('should return slack_update_message for update operation', () => {
|
||||
expect(getToolName?.({ operation: 'update' })).toBe('slack_update_message')
|
||||
})
|
||||
})
|
||||
|
||||
describe('tools.config.params for react operation', () => {
|
||||
const getParams = SlackBlock.tools.config?.params
|
||||
|
||||
it('should map reaction params correctly with OAuth auth', () => {
|
||||
const inputParams = {
|
||||
operation: 'react',
|
||||
authMethod: 'oauth',
|
||||
credential: 'oauth-credential-123',
|
||||
channel: 'C1234567890',
|
||||
reactionTimestamp: '1405894322.002768',
|
||||
emojiName: 'thumbsup',
|
||||
}
|
||||
|
||||
const result = getParams?.(inputParams)
|
||||
|
||||
expect(result).toEqual({
|
||||
credential: 'oauth-credential-123',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'thumbsup',
|
||||
})
|
||||
})
|
||||
|
||||
it('should map reaction params correctly with bot token auth', () => {
|
||||
const inputParams = {
|
||||
operation: 'react',
|
||||
authMethod: 'bot_token',
|
||||
botToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
reactionTimestamp: '1405894322.002768',
|
||||
emojiName: 'eyes',
|
||||
}
|
||||
|
||||
const result = getParams?.(inputParams)
|
||||
|
||||
expect(result).toEqual({
|
||||
accessToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
timestamp: '1405894322.002768',
|
||||
name: 'eyes',
|
||||
})
|
||||
})
|
||||
|
||||
it('should handle various emoji names', () => {
|
||||
const emojiNames = ['heart', 'fire', 'rocket', '+1', '-1', 'tada', 'thinking_face']
|
||||
|
||||
for (const emoji of emojiNames) {
|
||||
const inputParams = {
|
||||
operation: 'react',
|
||||
authMethod: 'bot_token',
|
||||
botToken: 'xoxb-test-token',
|
||||
channel: 'C1234567890',
|
||||
reactionTimestamp: '1405894322.002768',
|
||||
emojiName: emoji,
|
||||
}
|
||||
|
||||
const result = getParams?.(inputParams)
|
||||
|
||||
expect(result?.name).toBe(emoji)
|
||||
}
|
||||
})
|
||||
|
||||
it('should handle channel from trigger data', () => {
|
||||
const inputParams = {
|
||||
operation: 'react',
|
||||
authMethod: 'bot_token',
|
||||
botToken: 'xoxb-test-token',
|
||||
channel: 'C9876543210',
|
||||
reactionTimestamp: '1234567890.123456',
|
||||
emojiName: 'white_check_mark',
|
||||
}
|
||||
|
||||
const result = getParams?.(inputParams)
|
||||
|
||||
expect(result?.channel).toBe('C9876543210')
|
||||
expect(result?.timestamp).toBe('1234567890.123456')
|
||||
})
|
||||
|
||||
it('should trim whitespace from channel', () => {
|
||||
const inputParams = {
|
||||
operation: 'react',
|
||||
authMethod: 'bot_token',
|
||||
botToken: 'xoxb-test-token',
|
||||
channel: ' C1234567890 ',
|
||||
reactionTimestamp: '1405894322.002768',
|
||||
emojiName: 'thumbsup',
|
||||
}
|
||||
|
||||
const result = getParams?.(inputParams)
|
||||
|
||||
expect(result?.channel).toBe('C1234567890')
|
||||
})
|
||||
})
|
||||
|
||||
describe('subBlocks for react operation', () => {
|
||||
it('should have reactionTimestamp subBlock with correct condition', () => {
|
||||
const reactionTimestampSubBlock = SlackBlock.subBlocks.find(
|
||||
(sb) => sb.id === 'reactionTimestamp'
|
||||
)
|
||||
|
||||
expect(reactionTimestampSubBlock).toBeDefined()
|
||||
expect(reactionTimestampSubBlock?.type).toBe('short-input')
|
||||
expect(reactionTimestampSubBlock?.required).toBe(true)
|
||||
expect(reactionTimestampSubBlock?.condition).toEqual({
|
||||
field: 'operation',
|
||||
value: 'react',
|
||||
})
|
||||
})
|
||||
|
||||
it('should have emojiName subBlock with correct condition', () => {
|
||||
const emojiNameSubBlock = SlackBlock.subBlocks.find((sb) => sb.id === 'emojiName')
|
||||
|
||||
expect(emojiNameSubBlock).toBeDefined()
|
||||
expect(emojiNameSubBlock?.type).toBe('short-input')
|
||||
expect(emojiNameSubBlock?.required).toBe(true)
|
||||
expect(emojiNameSubBlock?.condition).toEqual({
|
||||
field: 'operation',
|
||||
value: 'react',
|
||||
})
|
||||
})
|
||||
|
||||
it('should have channel subBlock that shows for react operation', () => {
|
||||
const channelSubBlock = SlackBlock.subBlocks.find((sb) => sb.id === 'channel')
|
||||
|
||||
expect(channelSubBlock).toBeDefined()
|
||||
|
||||
const condition = channelSubBlock?.condition as {
|
||||
field: string
|
||||
value: string[]
|
||||
not: boolean
|
||||
and: { field: string; value: string; not: boolean }
|
||||
}
|
||||
|
||||
expect(condition.field).toBe('operation')
|
||||
expect(condition.value).not.toContain('react')
|
||||
expect(condition.not).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('inputs configuration', () => {
|
||||
it('should have timestamp input for reaction', () => {
|
||||
expect(SlackBlock.inputs.timestamp).toBeDefined()
|
||||
expect(SlackBlock.inputs.timestamp.type).toBe('string')
|
||||
})
|
||||
|
||||
it('should have name input for emoji', () => {
|
||||
expect(SlackBlock.inputs.name).toBeDefined()
|
||||
expect(SlackBlock.inputs.name.type).toBe('string')
|
||||
})
|
||||
|
||||
it('should have reactionTimestamp input', () => {
|
||||
expect(SlackBlock.inputs.reactionTimestamp).toBeDefined()
|
||||
expect(SlackBlock.inputs.reactionTimestamp.type).toBe('string')
|
||||
})
|
||||
|
||||
it('should have emojiName input', () => {
|
||||
expect(SlackBlock.inputs.emojiName).toBeDefined()
|
||||
expect(SlackBlock.inputs.emojiName.type).toBe('string')
|
||||
})
|
||||
})
|
||||
|
||||
describe('operation dropdown', () => {
|
||||
it('should include Add Reaction option', () => {
|
||||
const operationSubBlock = SlackBlock.subBlocks.find((sb) => sb.id === 'operation')
|
||||
expect(operationSubBlock?.type).toBe('dropdown')
|
||||
|
||||
const options = operationSubBlock?.options as Array<{ label: string; id: string }>
|
||||
const reactOption = options?.find((opt) => opt.id === 'react')
|
||||
|
||||
expect(reactOption).toBeDefined()
|
||||
expect(reactOption?.label).toBe('Add Reaction')
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user