Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions skills/twist-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ tw search "query" --cursor <cur> # Pagination cursor

```bash
tw user # Show current user info
tw user --json # JSON output
tw user --json --full # Include all fields in JSON output
tw users # List workspace users
tw users --search <text> # Filter by name/email
tw channels # List active joined workspace channels
Expand Down
60 changes: 59 additions & 1 deletion src/__tests__/user.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { Command } from 'commander'
import { beforeEach, describe, expect, it, vi } from 'vitest'

vi.mock('../lib/api.js', () => ({
const apiMocks = vi.hoisted(() => ({
getCurrentWorkspaceId: vi.fn().mockResolvedValue(1),
getSessionUser: vi.fn(),
getWorkspaceUsers: vi.fn(),
}))

vi.mock('../lib/api.js', () => ({
getCurrentWorkspaceId: apiMocks.getCurrentWorkspaceId,
getSessionUser: apiMocks.getSessionUser,
getWorkspaceUsers: apiMocks.getWorkspaceUsers,
}))

vi.mock('../lib/refs.js', () => ({
resolveWorkspaceRef: vi.fn(),
}))
Expand Down Expand Up @@ -35,3 +41,55 @@ describe('users --workspace conflict', () => {
).rejects.toThrow('Cannot specify workspace both as argument and --workspace flag')
})
})

describe('user --json', () => {
const sampleUser = {
id: 42,
name: 'Jane Smith',
email: 'jane@example.com',
timezone: 'America/New_York',
userType: 'regular',
awayMode: null,
defaultWorkspace: 1,
lang: 'en',
shortName: 'Jane',
}

beforeEach(() => {
vi.clearAllMocks()
apiMocks.getSessionUser.mockResolvedValue(sampleUser)
})

it('outputs essential user fields as JSON', async () => {
const program = createProgram()
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})

await program.parseAsync(['node', 'tw', 'user', '--json'])

expect(consoleSpy).toHaveBeenCalledTimes(1)
const jsonOutput = JSON.parse(consoleSpy.mock.calls[0][0])
expect(jsonOutput.id).toBe(42)
expect(jsonOutput.name).toBe('Jane Smith')
expect(jsonOutput.email).toBe('jane@example.com')
expect(jsonOutput.timezone).toBe('America/New_York')
expect(jsonOutput).not.toHaveProperty('lang')
expect(jsonOutput).not.toHaveProperty('shortName')

consoleSpy.mockRestore()
})

it('outputs full user fields with --full', async () => {
const program = createProgram()
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})

await program.parseAsync(['node', 'tw', 'user', '--json', '--full'])

expect(consoleSpy).toHaveBeenCalledTimes(1)
const jsonOutput = JSON.parse(consoleSpy.mock.calls[0][0])
expect(jsonOutput).toHaveProperty('lang', 'en')
expect(jsonOutput).toHaveProperty('shortName', 'Jane')
expect(jsonOutput).toHaveProperty('defaultWorkspace', 1)

consoleSpy.mockRestore()
})
})
12 changes: 10 additions & 2 deletions src/commands/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ import { resolveWorkspaceRef } from '../lib/refs.js'

type UsersOptions = ViewOptions & { workspace?: string; search?: string }

async function showCurrentUser(): Promise<void> {
async function showCurrentUser(options: ViewOptions): Promise<void> {
const user = await getSessionUser()

if (options.json) {
console.log(formatJson(user, 'user', options.full))
return
}

console.log(chalk.bold(user.name))
console.log('')
console.log(`ID: ${user.id}`)
Expand Down Expand Up @@ -77,11 +82,14 @@ export function registerUserCommand(program: Command): void {
program
.command('user')
.description('Show current user info')
.option('--json', 'Output as JSON')
.option('--full', 'Include all fields in JSON output')
.addHelpText(
'after',
`
Examples:
tw user`,
tw user
tw user --json`,
)
.action(showCurrentUser)

Expand Down
2 changes: 2 additions & 0 deletions src/lib/skills/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ tw search "query" --cursor <cur> # Pagination cursor

\`\`\`bash
tw user # Show current user info
tw user --json # JSON output
tw user --json --full # Include all fields in JSON output
tw users # List workspace users
tw users --search <text> # Filter by name/email
tw channels # List active joined workspace channels
Expand Down
Loading