Skip to content

Commit 0bac410

Browse files
introduce formatBulkOperationStatus helper to print nice progress messages
1 parent f1e08f7 commit 0bac410

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import {formatBulkOperationStatus} from './format-bulk-operation-status.js'
2+
import {GetBulkOperationByIdQuery} from '../../api/graphql/bulk-operations/generated/get-bulk-operation-by-id.js'
3+
import {describe, test, expect} from 'vitest'
4+
5+
type BulkOperation = NonNullable<GetBulkOperationByIdQuery['bulkOperation']> & {
6+
status: string
7+
objectCount: unknown
8+
}
9+
10+
function createMockOperation(overrides: Partial<BulkOperation> = {}): BulkOperation {
11+
return {
12+
id: 'gid://shopify/BulkOperation/123',
13+
status: 'CREATED',
14+
errorCode: null,
15+
createdAt: '2024-01-01T00:00:00Z',
16+
objectCount: '0',
17+
fileSize: '0',
18+
url: null,
19+
query: 'query { products { edges { node { id } } } }',
20+
rootObjectCount: '0',
21+
type: 'QUERY',
22+
...overrides,
23+
}
24+
}
25+
26+
describe('formatBulkOperationStatus', () => {
27+
test('formats RUNNING status with object count', () => {
28+
const result = formatBulkOperationStatus(createMockOperation({status: 'RUNNING', objectCount: 42}))
29+
expect(result.value).toContain('Bulk operation in progress...')
30+
expect(result.value).toContain('(42 objects)')
31+
})
32+
33+
test('formats CREATED status', () => {
34+
const result = formatBulkOperationStatus(createMockOperation({status: 'CREATED'}))
35+
expect(result.value).toBe('Starting...')
36+
})
37+
38+
test('formats COMPLETED status', () => {
39+
const result = formatBulkOperationStatus(createMockOperation({status: 'COMPLETED', objectCount: 100}))
40+
expect(result.value).toContain('Bulk operation succeeded.')
41+
expect(result.value).toContain('(100 objects)')
42+
})
43+
44+
test('formats FAILED status with error code', () => {
45+
const result = formatBulkOperationStatus(
46+
createMockOperation({status: 'FAILED', objectCount: 10, errorCode: 'ACCESS_DENIED'}),
47+
)
48+
expect(result.value).toContain('Bulk operation failed.')
49+
expect(result.value).toContain('(error: ACCESS_DENIED)')
50+
})
51+
52+
test('formats FAILED status without error code', () => {
53+
const result = formatBulkOperationStatus(createMockOperation({status: 'FAILED', objectCount: 10, errorCode: null}))
54+
expect(result.value).toContain('Bulk operation failed.')
55+
expect(result.value).toContain('(error: unknown)')
56+
})
57+
58+
test('formats CANCELING status', () => {
59+
const result = formatBulkOperationStatus(createMockOperation({status: 'CANCELING', objectCount: 5}))
60+
expect(result.value).toBe('Bulk operation canceling...')
61+
})
62+
63+
test('formats CANCELED status', () => {
64+
const result = formatBulkOperationStatus(createMockOperation({status: 'CANCELED', objectCount: 5}))
65+
expect(result.value).toBe('Bulk operation canceled.')
66+
})
67+
68+
test('formats EXPIRED status', () => {
69+
const result = formatBulkOperationStatus(createMockOperation({status: 'EXPIRED'}))
70+
expect(result.value).toBe('Bulk operation expired.')
71+
})
72+
73+
test('formats unknown status', () => {
74+
const result = formatBulkOperationStatus({
75+
...createMockOperation(),
76+
status: 'UNKNOWN_STATUS',
77+
} as unknown as BulkOperation)
78+
expect(result.value).toBe('Bulk operation status: UNKNOWN_STATUS')
79+
})
80+
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {GetBulkOperationByIdQuery} from '../../api/graphql/bulk-operations/generated/get-bulk-operation-by-id.js'
2+
import {outputContent, outputToken, TokenizedString} from '@shopify/cli-kit/node/output'
3+
4+
type BulkOperation = NonNullable<GetBulkOperationByIdQuery['bulkOperation']> & {
5+
status: string
6+
objectCount: unknown
7+
}
8+
9+
export function formatBulkOperationStatus(operation: BulkOperation): TokenizedString {
10+
switch (operation.status) {
11+
case 'RUNNING':
12+
return outputContent`Bulk operation in progress... ${outputToken.gray(
13+
`(${String(operation.objectCount)} objects)`,
14+
)}`
15+
case 'CREATED':
16+
return outputContent`Starting...`
17+
case 'COMPLETED':
18+
return outputContent`Bulk operation succeeded. ${outputToken.gray(`(${String(operation.objectCount)} objects)`)}`
19+
case 'FAILED':
20+
return outputContent`Bulk operation failed. ${outputToken.gray(`(error: ${operation.errorCode ?? 'unknown'})`)}`
21+
case 'CANCELING':
22+
return outputContent`Bulk operation canceling...`
23+
case 'CANCELED':
24+
return outputContent`Bulk operation canceled.`
25+
case 'EXPIRED':
26+
return outputContent`Bulk operation expired.`
27+
default:
28+
return outputContent`Bulk operation status: ${operation.status}`
29+
}
30+
}

0 commit comments

Comments
 (0)