Skip to content

Commit e0f8f2b

Browse files
authored
Merge pull request #12 from OpenPathfinder/feat/bulk-import
2 parents 0a70924 + 99ce934 commit e0f8f2b

File tree

6 files changed

+127
-7
lines changed

6 files changed

+127
-7
lines changed

src/__tests__/cli-commands.test.ts

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* eslint-env jest */
22

3-
import { getVersion, runDoctor, addProjectWithGithubOrgs, printChecklists, printChecks, printWorkflows, executeWorkflow } from '../cli-commands.js'
3+
import { getVersion, runDoctor, addProjectWithGithubOrgs, printChecklists, printChecks, printWorkflows, executeWorkflow, printBulkImportOperations } from '../cli-commands.js'
44
import { getPackageJson } from '../utils.js'
5-
import { APIHealthResponse, APIProjectDetails, APIGithubOrgDetails, APIErrorResponse, APIChecklistItem, APICheckItem, APIWorkflowItem, APIWorkflowRunItem } from '../types.js'
6-
import { mockApiHealthResponse, mockAPIProjectResponse, mockAPIGithubOrgResponse, mockAPIChecklistResponse, mockAPICheckResponse, mockAPIWorkflowResponse, mockAPIWorkflowRunResponse } from './fixtures.js'
5+
import { APIHealthResponse, APIProjectDetails, APIGithubOrgDetails, APIErrorResponse, APIChecklistItem, APICheckItem, APIWorkflowItem, APIWorkflowRunItem, APIBulkImportOperationItem } from '../types.js'
6+
import { mockApiHealthResponse, mockAPIProjectResponse, mockAPIGithubOrgResponse, mockAPIChecklistResponse, mockAPICheckResponse, mockAPIWorkflowResponse, mockAPIWorkflowRunResponse, mockAPIBulkImportOperationResponse } from './fixtures.js'
77
import nock from 'nock'
88

99
const pkg = getPackageJson()
@@ -586,4 +586,61 @@ describe('CLI Commands', () => {
586586
expect(result.messages).toHaveLength(1)
587587
})
588588
})
589+
590+
describe('printBulkImportOperations', () => {
591+
let mockBulkImportOperations: APIBulkImportOperationItem[]
592+
593+
beforeEach(() => {
594+
nock.cleanAll()
595+
mockBulkImportOperations = [...mockAPIBulkImportOperationResponse]
596+
})
597+
598+
it('should retrieve and format bulk import operations successfully', async () => {
599+
// Mock API call
600+
nock('http://localhost:3000')
601+
.get('/api/v1/bulk-import')
602+
.reply(200, mockBulkImportOperations)
603+
604+
// Execute the function
605+
const result = await printBulkImportOperations()
606+
607+
// Verify the result
608+
expect(result.success).toBe(true)
609+
expect(result.messages[0]).toBe('Bulk import operations available:')
610+
expect(result.messages[1]).toContain(mockBulkImportOperations[0].id)
611+
expect(result.messages[1]).toContain(mockBulkImportOperations[0].description)
612+
expect(result.messages).toHaveLength(2) // Header + 1 bulk import operation
613+
expect(nock.isDone()).toBe(true) // Verify all mocked endpoints were called
614+
})
615+
616+
it('should handle empty bulk import operations response', async () => {
617+
// Mock empty response
618+
nock('http://localhost:3000')
619+
.get('/api/v1/bulk-import')
620+
.reply(200, [])
621+
622+
// Execute the function
623+
const result = await printBulkImportOperations()
624+
625+
// Verify the result
626+
expect(result.success).toBe(true)
627+
expect(result.messages).toHaveLength(1) // Only the header message
628+
expect(result.messages[0]).toBe('No bulk import operations found')
629+
})
630+
631+
it('should handle network errors gracefully', async () => {
632+
// Mock network error
633+
nock('http://localhost:3000')
634+
.get('/api/v1/bulk-import')
635+
.replyWithError('Network error')
636+
637+
// Execute the function
638+
const result = await printBulkImportOperations()
639+
640+
// Verify the result
641+
expect(result.success).toBe(false)
642+
expect(result.messages[0]).toContain('❌ Failed to retrieve bulk import operation items: Network error')
643+
expect(result.messages).toHaveLength(1)
644+
})
645+
})
589646
})

src/__tests__/fixtures.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { APIHealthResponse, APIProjectDetails, APIGithubOrgDetails, APIChecklistItem, APICheckItem, APIWorkflowItem, APIWorkflowRunItem } from '../types.js'
1+
import { APIHealthResponse, APIProjectDetails, APIGithubOrgDetails, APIChecklistItem, APICheckItem, APIWorkflowItem, APIWorkflowRunItem, APIBulkImportOperationItem } from '../types.js'
22

33
export const mockApiHealthResponse: APIHealthResponse = {
44
status: 'ok',
@@ -138,3 +138,9 @@ export const mockAPIWorkflowRunResponse: APIWorkflowRunItem = {
138138
completed: '2025-06-21T10:05:02.500Z',
139139
result: { success: true, message: 'Workflow completed successfully' }
140140
}
141+
142+
export const mockAPIBulkImportOperationResponse: APIBulkImportOperationItem[] = [{
143+
id: 'import-data',
144+
description: 'Test bulk import operation description',
145+
schema: 'test-bulk-import-operation'
146+
}]

src/api-client.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getConfig } from './utils.js'
22
import { got } from 'got'
3-
import { APIHealthResponse, APIProjectDetails, APIGithubOrgDetails, APIChecklistItem, APICheckItem, APIWorkflowItem, APIWorkflowRunItem } from './types.js'
3+
import { APIHealthResponse, APIProjectDetails, APIGithubOrgDetails, APIChecklistItem, APICheckItem, APIWorkflowItem, APIWorkflowRunItem, APIBulkImportOperationItem } from './types.js'
44

55
export const apiClient = () => {
66
const config = getConfig()
@@ -92,3 +92,12 @@ export const runWorkflow = async (workflowId: string, data: any): Promise<APIWor
9292
}
9393
return response.body as APIWorkflowRunItem
9494
}
95+
96+
export const getAllBulkImportOperations = async (): Promise<APIBulkImportOperationItem[]> => {
97+
const client = apiClient()
98+
const response = await client.get('bulk-import', { responseType: 'json' })
99+
if (response.statusCode !== 200) {
100+
throw new Error(`Failed to get the data from the API: ${response.statusCode} ${response.body}`)
101+
}
102+
return response.body as APIBulkImportOperationItem[]
103+
}

src/cli-commands.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CommandResult } from './types.js'
22
import { isApiAvailable, isApiCompatible, getPackageJson } from './utils.js'
3-
import { getAPIDetails, createProject, addGithubOrgToProject, getAllChecklistItems, getAllChecks, getAllWorkflows, runWorkflow } from './api-client.js'
3+
import { getAPIDetails, createProject, addGithubOrgToProject, getAllChecklistItems, getAllChecks, getAllWorkflows, getAllBulkImportOperations, runWorkflow } from './api-client.js'
44

55
const pkg = getPackageJson()
66

@@ -165,3 +165,30 @@ export const executeWorkflow = async (workflowId: string, data: any): Promise<Co
165165
success
166166
}
167167
}
168+
169+
export const printBulkImportOperations = async (): Promise<CommandResult> => {
170+
const messages: string[] = []
171+
let success = true
172+
try {
173+
const operations = await getAllBulkImportOperations()
174+
if (operations.length === 0) {
175+
messages.push('No bulk import operations found')
176+
return {
177+
messages,
178+
success
179+
}
180+
}
181+
messages.push('Bulk import operations available:')
182+
operations.forEach((operation) => {
183+
messages.push(`- ${operation.id}: ${operation.description}`)
184+
})
185+
} catch (error) {
186+
messages.push(`❌ Failed to retrieve bulk import operation items: ${error instanceof Error ? error.message : 'Unknown error'}`)
187+
success = false
188+
}
189+
190+
return {
191+
messages,
192+
success
193+
}
194+
}

src/index.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { stringToArray } from '@ulisesgascon/string-to-array'
66
import { handleCommandResult, validateData } from './utils.js'
77
import { getAllWorkflows } from './api-client.js'
88
import fs from 'fs'
9-
import { getVersion, runDoctor, addProjectWithGithubOrgs, printChecklists, printChecks, printWorkflows, executeWorkflow } from './cli-commands.js'
9+
import { getVersion, runDoctor, addProjectWithGithubOrgs, printChecklists, printChecks, printWorkflows, executeWorkflow, printBulkImportOperations } from './cli-commands.js'
1010

1111
const program = new Command()
1212

@@ -25,6 +25,18 @@ program
2525
handleCommandResult(result)
2626
})
2727

28+
const bulkImport = program
29+
.command('bulk-import')
30+
.description('Bulk import management')
31+
32+
bulkImport
33+
.command('list')
34+
.description('Print all available bulk import operations')
35+
.action(async () => {
36+
const result = await printBulkImportOperations()
37+
handleCommandResult(result)
38+
})
39+
2840
const workflow = program
2941
.command('workflow')
3042
.description('Compliance workflow management')

src/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ export type APICheckItem = {
141141
updated_at: string;
142142
};
143143

144+
/**
145+
* Bulk Import Operation Schema
146+
*/
147+
export interface APIBulkImportOperationItem {
148+
id: string;
149+
description: string;
150+
schema: string;
151+
}
152+
144153
/**
145154
* Workflow Operation Schema
146155
* @TODO: Move or reuse with bulk-import endpoint is created.

0 commit comments

Comments
 (0)