mirror of
				https://github.com/actions/download-artifact.git
				synced 2025-10-31 09:33:41 +00:00 
			
		
		
		
	Lint
This commit is contained in:
		
							parent
							
								
									96a6f165f4
								
							
						
					
					
						commit
						9a869e9c49
					
				| @ -1,19 +1,8 @@ | ||||
| import * as core from '@actions/core' | ||||
| import * as github from '@actions/github' | ||||
| import * as os from 'os' | ||||
| import artifact, {ArtifactNotFoundError} from '@actions/artifact' | ||||
| import {run} from '../src/download-artifact' | ||||
| import {Inputs} from '../src/constants' | ||||
| 
 | ||||
| const fixtures = { | ||||
|   artifactName: 'artifact-name', | ||||
|   rootDirectory: '/some/artifact/path', | ||||
|   filesToUpload: [ | ||||
|     '/some/artifact/path/file1.txt', | ||||
|     '/some/artifact/path/file2.txt' | ||||
|   ] | ||||
| } | ||||
| 
 | ||||
| jest.mock('@actions/github', () => ({ | ||||
|   context: { | ||||
|     repo: { | ||||
| @ -27,7 +16,7 @@ jest.mock('@actions/github', () => ({ | ||||
| 
 | ||||
| jest.mock('@actions/core') | ||||
| 
 | ||||
| /* eslint-disable no-unused-vars */ | ||||
| /* eslint-disable no-unused-vars */ /* eslint-disable  @typescript-eslint/no-explicit-any */ | ||||
| const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => { | ||||
|   const inputs = { | ||||
|     [Inputs.Name]: 'artifact-name', | ||||
| @ -50,177 +39,177 @@ const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => { | ||||
| } | ||||
| 
 | ||||
| describe('download', () => { | ||||
|     beforeEach(async () => { | ||||
|       mockInputs() | ||||
|       jest.clearAllMocks() | ||||
|        | ||||
|       // Mock artifact client methods
 | ||||
|       jest.spyOn(artifact, 'listArtifacts').mockImplementation(() =>  | ||||
|         Promise.resolve({ artifacts: [] }) | ||||
|       ) | ||||
|       jest.spyOn(artifact, 'getArtifact').mockImplementation((name) => { | ||||
|         throw new ArtifactNotFoundError(`Artifact '${name}' not found`) | ||||
|   beforeEach(async () => { | ||||
|     mockInputs() | ||||
|     jest.clearAllMocks() | ||||
| 
 | ||||
|     // Mock artifact client methods
 | ||||
|     jest | ||||
|       .spyOn(artifact, 'listArtifacts') | ||||
|       .mockImplementation(() => Promise.resolve({artifacts: []})) | ||||
|     jest.spyOn(artifact, 'getArtifact').mockImplementation(name => { | ||||
|       throw new ArtifactNotFoundError(`Artifact '${name}' not found`) | ||||
|     }) | ||||
|     jest | ||||
|       .spyOn(artifact, 'downloadArtifact') | ||||
|       .mockImplementation(() => Promise.resolve({digestMismatch: false})) | ||||
|   }) | ||||
| 
 | ||||
|   test('downloads a single artifact by name', async () => { | ||||
|     const mockArtifact = { | ||||
|       id: 123, | ||||
|       name: 'artifact-name', | ||||
|       size: 1024, | ||||
|       digest: 'abc123' | ||||
|     } | ||||
| 
 | ||||
|     jest | ||||
|       .spyOn(artifact, 'getArtifact') | ||||
|       .mockImplementation(() => Promise.resolve({artifact: mockArtifact})) | ||||
| 
 | ||||
|     await run() | ||||
| 
 | ||||
|     expect(artifact.downloadArtifact).toHaveBeenCalledWith( | ||||
|       mockArtifact.id, | ||||
|       expect.objectContaining({ | ||||
|         expectedHash: mockArtifact.digest | ||||
|       }) | ||||
|       jest.spyOn(artifact, 'downloadArtifact').mockImplementation(() =>  | ||||
|         Promise.resolve({ digestMismatch: false }) | ||||
|       ) | ||||
|     ) | ||||
|     expect(core.info).toHaveBeenCalledWith('Total of 1 artifact(s) downloaded') | ||||
|   }) | ||||
| 
 | ||||
|   test('downloads multiple artifacts when no name or pattern provided', async () => { | ||||
|     jest.clearAllMocks() | ||||
|     mockInputs({ | ||||
|       [Inputs.Name]: '', | ||||
|       [Inputs.Pattern]: '' | ||||
|     }) | ||||
| 
 | ||||
|     test('downloads a single artifact by name', async () => { | ||||
|       const mockArtifact = {  | ||||
|         id: 123,  | ||||
|         name: 'artifact-name',  | ||||
|         size: 1024,  | ||||
|         digest: 'abc123'  | ||||
|       } | ||||
|        | ||||
|       jest.spyOn(artifact, 'getArtifact').mockImplementation(() =>  | ||||
|         Promise.resolve({ artifact: mockArtifact }) | ||||
|       ) | ||||
|        | ||||
|       await run() | ||||
|        | ||||
|       expect(artifact.downloadArtifact).toHaveBeenCalledWith( | ||||
|         mockArtifact.id,  | ||||
|         expect.objectContaining({ | ||||
|           expectedHash: mockArtifact.digest | ||||
|         }) | ||||
|       ) | ||||
|       expect(core.info).toHaveBeenCalledWith('Total of 1 artifact(s) downloaded') | ||||
|     const mockArtifacts = [ | ||||
|       {id: 123, name: 'artifact1', size: 1024, digest: 'abc123'}, | ||||
|       {id: 456, name: 'artifact2', size: 2048, digest: 'def456'} | ||||
|     ] | ||||
| 
 | ||||
|     // Set up artifact mock after clearing mocks
 | ||||
|     jest | ||||
|       .spyOn(artifact, 'listArtifacts') | ||||
|       .mockImplementation(() => Promise.resolve({artifacts: mockArtifacts})) | ||||
| 
 | ||||
|     // Reset downloadArtifact mock as well
 | ||||
|     jest | ||||
|       .spyOn(artifact, 'downloadArtifact') | ||||
|       .mockImplementation(() => Promise.resolve({digestMismatch: false})) | ||||
| 
 | ||||
|     await run() | ||||
| 
 | ||||
|     expect(core.info).toHaveBeenCalledWith( | ||||
|       'No input name or pattern filtered specified, downloading all artifacts' | ||||
|     ) | ||||
| 
 | ||||
|     expect(core.info).toHaveBeenCalledWith('Total of 2 artifact(s) downloaded') | ||||
|     expect(artifact.downloadArtifact).toHaveBeenCalledTimes(2) | ||||
|   }) | ||||
| 
 | ||||
|   test('sets download path output even when no artifacts are found', async () => { | ||||
|     mockInputs({[Inputs.Name]: ''}) | ||||
| 
 | ||||
|     await run() | ||||
| 
 | ||||
|     expect(core.setOutput).toHaveBeenCalledWith( | ||||
|       'download-path', | ||||
|       expect.any(String) | ||||
|     ) | ||||
| 
 | ||||
|     expect(core.info).toHaveBeenCalledWith( | ||||
|       'Download artifact has finished successfully' | ||||
|     ) | ||||
| 
 | ||||
|     expect(core.info).toHaveBeenCalledWith('Total of 0 artifact(s) downloaded') | ||||
|   }) | ||||
| 
 | ||||
|   test('filters artifacts by pattern', async () => { | ||||
|     const mockArtifacts = [ | ||||
|       {id: 123, name: 'test-artifact', size: 1024, digest: 'abc123'}, | ||||
|       {id: 456, name: 'prod-artifact', size: 2048, digest: 'def456'} | ||||
|     ] | ||||
| 
 | ||||
|     jest | ||||
|       .spyOn(artifact, 'listArtifacts') | ||||
|       .mockImplementation(() => Promise.resolve({artifacts: mockArtifacts})) | ||||
| 
 | ||||
|     mockInputs({ | ||||
|       [Inputs.Name]: '', | ||||
|       [Inputs.Pattern]: 'test-*' | ||||
|     }) | ||||
| 
 | ||||
|     test('downloads multiple artifacts when no name or pattern provided', async () => { | ||||
|       jest.clearAllMocks() | ||||
|       mockInputs({  | ||||
|         [Inputs.Name]: '',  | ||||
|         [Inputs.Pattern]: ''  | ||||
|     await run() | ||||
| 
 | ||||
|     expect(artifact.downloadArtifact).toHaveBeenCalledTimes(1) | ||||
|     expect(artifact.downloadArtifact).toHaveBeenCalledWith( | ||||
|       123, | ||||
|       expect.anything() | ||||
|     ) | ||||
|   }) | ||||
| 
 | ||||
|   test('uses token and repository information when provided', async () => { | ||||
|     const token = 'ghp_testtoken123' | ||||
| 
 | ||||
|     mockInputs({ | ||||
|       [Inputs.Name]: '', | ||||
|       [Inputs.GitHubToken]: token, | ||||
|       [Inputs.Repository]: 'myorg/myrepo', | ||||
|       [Inputs.RunID]: '789' | ||||
|     }) | ||||
| 
 | ||||
|     jest | ||||
|       .spyOn(artifact, 'listArtifacts') | ||||
|       .mockImplementation(() => Promise.resolve({artifacts: []})) | ||||
| 
 | ||||
|     await run() | ||||
| 
 | ||||
|     expect(artifact.listArtifacts).toHaveBeenCalledWith( | ||||
|       expect.objectContaining({ | ||||
|         findBy: { | ||||
|           token, | ||||
|           workflowRunId: 789, | ||||
|           repositoryName: 'myrepo', | ||||
|           repositoryOwner: 'myorg' | ||||
|         } | ||||
|       }) | ||||
|        | ||||
|       const mockArtifacts = [ | ||||
|         { id: 123, name: 'artifact1', size: 1024, digest: 'abc123' }, | ||||
|         { id: 456, name: 'artifact2', size: 2048, digest: 'def456' } | ||||
|       ] | ||||
|        | ||||
|       // Set up artifact mock after clearing mocks
 | ||||
|       jest.spyOn(artifact, 'listArtifacts').mockImplementation(() =>  | ||||
|         Promise.resolve({ artifacts: mockArtifacts }) | ||||
|       ) | ||||
|        | ||||
|       // Reset downloadArtifact mock as well
 | ||||
|       jest.spyOn(artifact, 'downloadArtifact').mockImplementation(() =>  | ||||
|         Promise.resolve({ digestMismatch: false }) | ||||
|       ) | ||||
|        | ||||
|       await run() | ||||
|     ) | ||||
|   }) | ||||
| 
 | ||||
|       expect(core.info).toHaveBeenCalledWith('No input name or pattern filtered specified, downloading all artifacts') | ||||
|        | ||||
|       expect(core.info).toHaveBeenCalledWith('Total of 2 artifact(s) downloaded') | ||||
|       expect(artifact.downloadArtifact).toHaveBeenCalledTimes(2) | ||||
|     }) | ||||
|      | ||||
|     test('sets download path output even when no artifacts are found', async () => { | ||||
|       mockInputs({ [Inputs.Name]: '' }) | ||||
|        | ||||
|       await run() | ||||
|        | ||||
|       expect(core.setOutput).toHaveBeenCalledWith( | ||||
|         'download-path', | ||||
|         expect.any(String) | ||||
|       ) | ||||
| 
 | ||||
|       expect(core.info).toHaveBeenCalledWith( | ||||
|         'Download artifact has finished successfully' | ||||
|       ) | ||||
|        | ||||
|       expect(core.info).toHaveBeenCalledWith( | ||||
|         'Total of 0 artifact(s) downloaded' | ||||
|       ) | ||||
|   test('throws error when repository format is invalid', async () => { | ||||
|     mockInputs({ | ||||
|       [Inputs.GitHubToken]: 'some-token', | ||||
|       [Inputs.Repository]: 'invalid-format' // Missing the owner/repo format
 | ||||
|     }) | ||||
| 
 | ||||
|     test('filters artifacts by pattern', async () => { | ||||
|       const mockArtifacts = [ | ||||
|         { id: 123, name: 'test-artifact', size: 1024, digest: 'abc123' }, | ||||
|         { id: 456, name: 'prod-artifact', size: 2048, digest: 'def456' } | ||||
|       ] | ||||
|        | ||||
|       jest.spyOn(artifact, 'listArtifacts').mockImplementation(() =>  | ||||
|         Promise.resolve({ artifacts: mockArtifacts }) | ||||
|       ) | ||||
|        | ||||
|       mockInputs({  | ||||
|         [Inputs.Name]: '', | ||||
|         [Inputs.Pattern]: 'test-*'  | ||||
|       }) | ||||
|        | ||||
|       await run() | ||||
|        | ||||
|       expect(artifact.downloadArtifact).toHaveBeenCalledTimes(1) | ||||
|       expect(artifact.downloadArtifact).toHaveBeenCalledWith( | ||||
|         123, | ||||
|         expect.anything() | ||||
|       ) | ||||
|     }) | ||||
|     await expect(run()).rejects.toThrow( | ||||
|       "Invalid repository: 'invalid-format'. Must be in format owner/repo" | ||||
|     ) | ||||
|   }) | ||||
| 
 | ||||
|     test('uses token and repository information when provided', async () => { | ||||
|       const token = 'ghp_testtoken123' | ||||
|        | ||||
|       mockInputs({ | ||||
|         [Inputs.Name]: '', | ||||
|         [Inputs.GitHubToken]: token, | ||||
|         [Inputs.Repository]: 'myorg/myrepo', | ||||
|         [Inputs.RunID]: '789' | ||||
|       }) | ||||
|        | ||||
|       jest.spyOn(artifact, 'listArtifacts').mockImplementation(() =>  | ||||
|         Promise.resolve({ artifacts: [] }) | ||||
|       ) | ||||
|        | ||||
|       await run() | ||||
|        | ||||
|       expect(artifact.listArtifacts).toHaveBeenCalledWith( | ||||
|         expect.objectContaining({ | ||||
|           findBy: { | ||||
|             token, | ||||
|             workflowRunId: 789, | ||||
|             repositoryName: 'myrepo', | ||||
|             repositoryOwner: 'myorg' | ||||
|           } | ||||
|         }) | ||||
|       ) | ||||
|     }) | ||||
|   test('warns when digest validation fails', async () => { | ||||
|     const mockArtifact = { | ||||
|       id: 123, | ||||
|       name: 'corrupted-artifact', | ||||
|       size: 1024, | ||||
|       digest: 'abc123' | ||||
|     } | ||||
| 
 | ||||
|     test('throws error when repository format is invalid', async () => { | ||||
|       mockInputs({ | ||||
|         [Inputs.GitHubToken]: 'some-token', | ||||
|         [Inputs.Repository]: 'invalid-format'  // Missing the owner/repo format
 | ||||
|       }) | ||||
|        | ||||
|       await expect(run()).rejects.toThrow( | ||||
|         "Invalid repository: 'invalid-format'. Must be in format owner/repo" | ||||
|       ) | ||||
|     }) | ||||
|      | ||||
|     test('warns when digest validation fails', async () => { | ||||
|       const mockArtifact = {  | ||||
|         id: 123,  | ||||
|         name: 'corrupted-artifact',  | ||||
|         size: 1024,  | ||||
|         digest: 'abc123'  | ||||
|       } | ||||
|        | ||||
|       jest.spyOn(artifact, 'getArtifact').mockImplementation(() =>  | ||||
|         Promise.resolve({ artifact: mockArtifact }) | ||||
|       ) | ||||
|        | ||||
|       jest.spyOn(artifact, 'downloadArtifact').mockImplementation(() =>  | ||||
|         Promise.resolve({ digestMismatch: true }) | ||||
|       ) | ||||
|        | ||||
|       await run() | ||||
|        | ||||
|       expect(core.warning).toHaveBeenCalledWith( | ||||
|         expect.stringContaining('digest validation failed') | ||||
|       ) | ||||
|     }) | ||||
|   }) | ||||
|     jest | ||||
|       .spyOn(artifact, 'getArtifact') | ||||
|       .mockImplementation(() => Promise.resolve({artifact: mockArtifact})) | ||||
| 
 | ||||
|     jest | ||||
|       .spyOn(artifact, 'downloadArtifact') | ||||
|       .mockImplementation(() => Promise.resolve({digestMismatch: true})) | ||||
| 
 | ||||
|     await run() | ||||
| 
 | ||||
|     expect(core.warning).toHaveBeenCalledWith( | ||||
|       expect.stringContaining('digest validation failed') | ||||
|     ) | ||||
|   }) | ||||
| }) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user