1
0
mirror of https://github.com/actions/upload-artifact.git synced 2026-02-26 13:42:35 +00:00
Files
upload-artifact/__tests__/search.test.ts
Daniel Kennedy 589182c5a4 Upgrade the module to ESM and bump dependencies (#762)
* Upgrade the module to ESM and bump dependencies

* CI: bump node versions

* Push build files

* Fix linting issues

* Bump the package version

* Cache licenses

* Bump minimatch to 10.1.1

* Try fixing licenced issues

* More licensed fixes

* eslint: don't allow common-js imports
2026-02-25 14:01:53 -05:00

400 lines
14 KiB
TypeScript

import {jest, describe, test, expect, beforeAll} from '@jest/globals'
import * as path from 'path'
import * as io from '@actions/io'
import {promises as fs} from 'fs'
import {fileURLToPath} from 'url'
// Mock @actions/core to suppress output during tests
jest.unstable_mockModule('@actions/core', () => ({
getInput: jest.fn(),
getBooleanInput: jest.fn(),
setOutput: jest.fn(),
setFailed: jest.fn(),
setSecret: jest.fn(),
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
startGroup: jest.fn(),
endGroup: jest.fn(),
isDebug: jest.fn(() => false),
getState: jest.fn(),
saveState: jest.fn(),
exportVariable: jest.fn(),
addPath: jest.fn(),
group: jest.fn((name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}))
const {findFilesToUpload} = await import('../src/shared/search.js')
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const root = path.join(__dirname, '_temp', 'search')
const searchItem1Path = path.join(
root,
'folder-a',
'folder-b',
'folder-c',
'search-item1.txt'
)
const searchItem2Path = path.join(root, 'folder-d', 'search-item2.txt')
const searchItem3Path = path.join(root, 'folder-d', 'search-item3.txt')
const searchItem4Path = path.join(root, 'folder-d', 'search-item4.txt')
const searchItem5Path = path.join(root, 'search-item5.txt')
const extraSearchItem1Path = path.join(
root,
'folder-a',
'folder-b',
'folder-c',
'extraSearch-item1.txt'
)
const extraSearchItem2Path = path.join(
root,
'folder-d',
'extraSearch-item2.txt'
)
const extraSearchItem3Path = path.join(
root,
'folder-f',
'extraSearch-item3.txt'
)
const extraSearchItem4Path = path.join(
root,
'folder-h',
'folder-i',
'extraSearch-item4.txt'
)
const extraSearchItem5Path = path.join(
root,
'folder-h',
'folder-i',
'extraSearch-item5.txt'
)
const extraFileInFolderCPath = path.join(
root,
'folder-a',
'folder-b',
'folder-c',
'extra-file-in-folder-c.txt'
)
const amazingFileInFolderHPath = path.join(root, 'folder-h', 'amazing-item.txt')
const lonelyFilePath = path.join(
root,
'folder-h',
'folder-j',
'folder-k',
'lonely-file.txt'
)
const hiddenFile = path.join(root, '.hidden-file.txt')
const fileInHiddenFolderPath = path.join(
root,
'.hidden-folder',
'folder-in-hidden-folder',
'file.txt'
)
const fileInHiddenFolderInFolderA = path.join(
root,
'folder-a',
'.hidden-folder-in-folder-a',
'file.txt'
)
describe('Search', () => {
beforeAll(async () => {
// mock console.log to reduce noise
jest.spyOn(console, 'log').mockImplementation(() => {})
// clear temp directory
await io.rmRF(root)
await fs.mkdir(path.join(root, 'folder-a', 'folder-b', 'folder-c'), {
recursive: true
})
await fs.mkdir(path.join(root, 'folder-a', 'folder-b', 'folder-e'), {
recursive: true
})
await fs.mkdir(path.join(root, 'folder-d'), {
recursive: true
})
await fs.mkdir(path.join(root, 'folder-f'), {
recursive: true
})
await fs.mkdir(path.join(root, 'folder-g'), {
recursive: true
})
await fs.mkdir(path.join(root, 'folder-h', 'folder-i'), {
recursive: true
})
await fs.mkdir(path.join(root, 'folder-h', 'folder-j', 'folder-k'), {
recursive: true
})
await fs.mkdir(
path.join(root, '.hidden-folder', 'folder-in-hidden-folder'),
{recursive: true}
)
await fs.mkdir(path.join(root, 'folder-a', '.hidden-folder-in-folder-a'), {
recursive: true
})
await fs.writeFile(searchItem1Path, 'search item1 file')
await fs.writeFile(searchItem2Path, 'search item2 file')
await fs.writeFile(searchItem3Path, 'search item3 file')
await fs.writeFile(searchItem4Path, 'search item4 file')
await fs.writeFile(searchItem5Path, 'search item5 file')
await fs.writeFile(extraSearchItem1Path, 'extraSearch item1 file')
await fs.writeFile(extraSearchItem2Path, 'extraSearch item2 file')
await fs.writeFile(extraSearchItem3Path, 'extraSearch item3 file')
await fs.writeFile(extraSearchItem4Path, 'extraSearch item4 file')
await fs.writeFile(extraSearchItem5Path, 'extraSearch item5 file')
await fs.writeFile(extraFileInFolderCPath, 'extra file')
await fs.writeFile(amazingFileInFolderHPath, 'amazing file')
await fs.writeFile(lonelyFilePath, 'all by itself')
await fs.writeFile(hiddenFile, 'hidden file')
await fs.writeFile(fileInHiddenFolderPath, 'file in hidden directory')
await fs.writeFile(fileInHiddenFolderInFolderA, 'file in hidden directory')
})
test('Single file search - Absolute Path', async () => {
const searchResult = await findFilesToUpload(extraFileInFolderCPath)
expect(searchResult.filesToUpload.length).toEqual(1)
expect(searchResult.filesToUpload[0]).toEqual(extraFileInFolderCPath)
expect(searchResult.rootDirectory).toEqual(
path.join(root, 'folder-a', 'folder-b', 'folder-c')
)
})
test('Single file search - Relative Path', async () => {
const relativePath = path.join(
'__tests__',
'_temp',
'search',
'folder-a',
'folder-b',
'folder-c',
'search-item1.txt'
)
const searchResult = await findFilesToUpload(relativePath)
expect(searchResult.filesToUpload.length).toEqual(1)
expect(searchResult.filesToUpload[0]).toEqual(searchItem1Path)
expect(searchResult.rootDirectory).toEqual(
path.join(root, 'folder-a', 'folder-b', 'folder-c')
)
})
test('Single file using wildcard', async () => {
const expectedRoot = path.join(root, 'folder-h')
const searchPath = path.join(root, 'folder-h', '**/*lonely*')
const searchResult = await findFilesToUpload(searchPath)
expect(searchResult.filesToUpload.length).toEqual(1)
expect(searchResult.filesToUpload[0]).toEqual(lonelyFilePath)
expect(searchResult.rootDirectory).toEqual(expectedRoot)
})
test('Single file using directory', async () => {
const searchPath = path.join(root, 'folder-h', 'folder-j')
const searchResult = await findFilesToUpload(searchPath)
expect(searchResult.filesToUpload.length).toEqual(1)
expect(searchResult.filesToUpload[0]).toEqual(lonelyFilePath)
expect(searchResult.rootDirectory).toEqual(searchPath)
})
test('Directory search - Absolute Path', async () => {
const searchPath = path.join(root, 'folder-h')
const searchResult = await findFilesToUpload(searchPath)
expect(searchResult.filesToUpload.length).toEqual(4)
expect(
searchResult.filesToUpload.includes(amazingFileInFolderHPath)
).toEqual(true)
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
expect(searchResult.rootDirectory).toEqual(searchPath)
})
test('Directory search - Relative Path', async () => {
const searchPath = path.join('__tests__', '_temp', 'search', 'folder-h')
const expectedRootDirectory = path.join(root, 'folder-h')
const searchResult = await findFilesToUpload(searchPath)
expect(searchResult.filesToUpload.length).toEqual(4)
expect(
searchResult.filesToUpload.includes(amazingFileInFolderHPath)
).toEqual(true)
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
expect(searchResult.rootDirectory).toEqual(expectedRootDirectory)
})
test('Wildcard search - Absolute Path', async () => {
const searchPath = path.join(root, '**/*[Ss]earch*')
const searchResult = await findFilesToUpload(searchPath)
expect(searchResult.filesToUpload.length).toEqual(10)
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem5Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(extraSearchItem1Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem3Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
true
)
expect(searchResult.rootDirectory).toEqual(root)
})
test('Wildcard search - Relative Path', async () => {
const searchPath = path.join(
'__tests__',
'_temp',
'search',
'**/*[Ss]earch*'
)
const searchResult = await findFilesToUpload(searchPath)
expect(searchResult.filesToUpload.length).toEqual(10)
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem5Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(extraSearchItem1Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem3Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
true
)
expect(searchResult.rootDirectory).toEqual(root)
})
test('Multi path search - root directory', async () => {
const searchPath1 = path.join(root, 'folder-a')
const searchPath2 = path.join(root, 'folder-d')
const searchPaths = `${searchPath1}\n${searchPath2}`
const searchResult = await findFilesToUpload(searchPaths)
expect(searchResult.rootDirectory).toEqual(root)
expect(searchResult.filesToUpload.length).toEqual(7)
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(extraSearchItem1Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraFileInFolderCPath)).toEqual(
true
)
})
test('Multi path search - with exclude character', async () => {
const searchPath1 = path.join(root, 'folder-a')
const searchPath2 = path.join(root, 'folder-d')
const searchPath3 = path.join(root, 'folder-a', 'folder-b', '**/extra*.txt')
// negating the third search path
const searchPaths = `${searchPath1}\n${searchPath2}\n!${searchPath3}`
const searchResult = await findFilesToUpload(searchPaths)
expect(searchResult.rootDirectory).toEqual(root)
expect(searchResult.filesToUpload.length).toEqual(5)
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
true
)
})
test('Multi path search - non root directory', async () => {
const searchPath1 = path.join(root, 'folder-h', 'folder-i')
const searchPath2 = path.join(root, 'folder-h', 'folder-j', 'folder-k')
const searchPath3 = amazingFileInFolderHPath
const searchPaths = [searchPath1, searchPath2, searchPath3].join('\n')
const searchResult = await findFilesToUpload(searchPaths)
expect(searchResult.rootDirectory).toEqual(path.join(root, 'folder-h'))
expect(searchResult.filesToUpload.length).toEqual(4)
expect(
searchResult.filesToUpload.includes(amazingFileInFolderHPath)
).toEqual(true)
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
true
)
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
})
test('Hidden files ignored by default', async () => {
const searchPath = path.join(root, '**/*')
const searchResult = await findFilesToUpload(searchPath)
expect(searchResult.filesToUpload).not.toContain(hiddenFile)
expect(searchResult.filesToUpload).not.toContain(fileInHiddenFolderPath)
expect(searchResult.filesToUpload).not.toContain(
fileInHiddenFolderInFolderA
)
})
test('Hidden files included', async () => {
const searchPath = path.join(root, '**/*')
const searchResult = await findFilesToUpload(searchPath, true)
expect(searchResult.filesToUpload).toContain(hiddenFile)
expect(searchResult.filesToUpload).toContain(fileInHiddenFolderPath)
expect(searchResult.filesToUpload).toContain(fileInHiddenFolderInFolderA)
})
})