mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
* feat(logs): add additional metadata for workflow execution logs
* Revert "Feat(logs) upgrade mothership chat messages to error (#3772)"
This reverts commit 9d1b9763c5.
* Fix lint, address greptile comments
* improvement(sidebar): expand sidebar by hovering and clicking the edge (#3830)
* improvement(sidebar): expand sidebar by hovering and clicking the edge
* improvement(sidebar): add keyboard shortcuts for new workflow/task, center search modal, fix edge ARIA
* improvement(sidebar): use Tooltip.Shortcut for inline shortcut display
* fix(sidebar): change new workflow shortcut from Mod+Shift+W to Mod+Shift+P to avoid browser close-window conflict
* fix(hotkeys): fall back to event.code for international keyboard layout compatibility
* fix(sidebar): guard add-workflow shortcut with canEdit and isCreatingWorkflow checks
* feat(ui): handle image paste (#3826)
* feat(ui): handle image paste
* Fix lint
* Fix type error
---------
Co-authored-by: Theodore Li <theo@sim.ai>
* feat(files): interactive markdown checkbox toggling in preview (#3829)
* feat(files): interactive markdown checkbox toggling in preview
* fix(files): handle ordered-list checkboxes and fix index drift
* lint
* fix(files): remove counter offset that prevented checkbox toggling
* fix(files): apply task-list styling to ordered lists too
* fix(files): render single pass when interactive to avoid index drift
* fix(files): move useMemo above conditional return to fix Rules of Hooks
* fix(files): pass content directly to preview when not streaming to avoid stale frame
* improvement(home): position @ mention popup at caret and fix icon consistency (#3831)
* improvement(home): position @ mention popup at caret and fix icon consistency
* fix(home): pin mirror div to document origin and guard button anchor
* chore(auth): restore hybrid.ts to staging
* improvement(ui): sidebar (#3832)
* Fix logger tests
* Add metadata to mothership logs
---------
Co-authored-by: Theodore Li <theo@sim.ai>
Co-authored-by: Waleed <walif6@gmail.com>
Co-authored-by: Theodore Li <theo@sim.ai>
106 lines
3.2 KiB
TypeScript
106 lines
3.2 KiB
TypeScript
/**
|
|
* @vitest-environment node
|
|
*/
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
vi.mock('@sim/logger', () => {
|
|
const createMockLogger = (): Record<string, any> => ({
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
withMetadata: vi.fn(() => createMockLogger()),
|
|
})
|
|
return { createLogger: vi.fn(() => createMockLogger()) }
|
|
})
|
|
|
|
vi.mock('@/lib/billing/core/subscription', () => ({
|
|
getUserSubscriptionState: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/lib/copilot/chat-context', () => ({
|
|
processFileAttachments: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/lib/core/config/feature-flags', () => ({
|
|
isHosted: false,
|
|
}))
|
|
|
|
vi.mock('@/lib/mcp/utils', () => ({
|
|
createMcpToolId: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/lib/workflows/utils', () => ({
|
|
getWorkflowById: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/tools/registry', () => ({
|
|
tools: {
|
|
gmail_send: {
|
|
id: 'gmail_send',
|
|
name: 'Gmail Send',
|
|
description: 'Send emails using Gmail',
|
|
},
|
|
brandfetch_search: {
|
|
id: 'brandfetch_search',
|
|
name: 'Brandfetch Search',
|
|
description: 'Search for brands by company name',
|
|
},
|
|
},
|
|
}))
|
|
|
|
vi.mock('@/tools/utils', () => ({
|
|
getLatestVersionTools: vi.fn((input) => input),
|
|
stripVersionSuffix: vi.fn((toolId: string) => toolId),
|
|
}))
|
|
|
|
vi.mock('@/tools/params', () => ({
|
|
createUserToolSchema: vi.fn(() => ({ type: 'object', properties: {} })),
|
|
}))
|
|
|
|
import { getUserSubscriptionState } from '@/lib/billing/core/subscription'
|
|
import { buildIntegrationToolSchemas } from '@/lib/copilot/chat-payload'
|
|
|
|
const mockedGetUserSubscriptionState = getUserSubscriptionState as unknown as {
|
|
mockResolvedValue: (value: unknown) => void
|
|
mockRejectedValue: (value: unknown) => void
|
|
mockClear: () => void
|
|
}
|
|
|
|
describe('buildIntegrationToolSchemas', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('appends the email footer prompt for free users', async () => {
|
|
mockedGetUserSubscriptionState.mockResolvedValue({ isFree: true })
|
|
|
|
const toolSchemas = await buildIntegrationToolSchemas('user-free')
|
|
const gmailTool = toolSchemas.find((tool) => tool.name === 'gmail_send')
|
|
|
|
expect(getUserSubscriptionState).toHaveBeenCalledWith('user-free')
|
|
expect(gmailTool?.description).toContain('sent with sim ai')
|
|
})
|
|
|
|
it('does not append the email footer prompt for paid users', async () => {
|
|
mockedGetUserSubscriptionState.mockResolvedValue({ isFree: false })
|
|
|
|
const toolSchemas = await buildIntegrationToolSchemas('user-paid')
|
|
const gmailTool = toolSchemas.find((tool) => tool.name === 'gmail_send')
|
|
|
|
expect(getUserSubscriptionState).toHaveBeenCalledWith('user-paid')
|
|
expect(gmailTool?.description).toBe('Send emails using Gmail')
|
|
})
|
|
|
|
it('still builds integration tools when subscription lookup fails', async () => {
|
|
mockedGetUserSubscriptionState.mockRejectedValue(new Error('db unavailable'))
|
|
|
|
const toolSchemas = await buildIntegrationToolSchemas('user-error')
|
|
const gmailTool = toolSchemas.find((tool) => tool.name === 'gmail_send')
|
|
const brandfetchTool = toolSchemas.find((tool) => tool.name === 'brandfetch_search')
|
|
|
|
expect(getUserSubscriptionState).toHaveBeenCalledWith('user-error')
|
|
expect(gmailTool?.description).toBe('Send emails using Gmail')
|
|
expect(brandfetchTool?.description).toBe('Search for brands by company name')
|
|
})
|
|
})
|