mirror of https://github.com/actions/toolkit
354 lines
12 KiB
TypeScript
354 lines
12 KiB
TypeScript
|
import * as io from '../../io/src/io'
|
||
|
import * as path from 'path'
|
||
|
import {promises as fs} from 'fs'
|
||
|
import * as core from '@actions/core'
|
||
|
import {getUploadSpecification} from '../src/internal-upload-specification'
|
||
|
|
||
|
const artifactName = 'my-artifact'
|
||
|
const root = path.join(__dirname, '_temp', 'upload-specification')
|
||
|
const goodItem1Path = path.join(
|
||
|
root,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'folder-c',
|
||
|
'good-item1.txt'
|
||
|
)
|
||
|
const goodItem2Path = path.join(root, 'folder-d', 'good-item2.txt')
|
||
|
const goodItem3Path = path.join(root, 'folder-d', 'good-item3.txt')
|
||
|
const goodItem4Path = path.join(root, 'folder-d', 'good-item4.txt')
|
||
|
const goodItem5Path = path.join(root, 'good-item5.txt')
|
||
|
const badItem1Path = path.join(
|
||
|
root,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'folder-c',
|
||
|
'bad-item1.txt'
|
||
|
)
|
||
|
const badItem2Path = path.join(root, 'folder-d', 'bad-item2.txt')
|
||
|
const badItem3Path = path.join(root, 'folder-f', 'bad-item3.txt')
|
||
|
const badItem4Path = path.join(root, 'folder-h', 'folder-i', 'bad-item4.txt')
|
||
|
const badItem5Path = path.join(root, 'folder-h', 'folder-i', 'bad-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 artifactFilesToUpload = [
|
||
|
goodItem1Path,
|
||
|
goodItem2Path,
|
||
|
goodItem3Path,
|
||
|
goodItem4Path,
|
||
|
goodItem5Path,
|
||
|
extraFileInFolderCPath,
|
||
|
amazingFileInFolderHPath
|
||
|
]
|
||
|
|
||
|
describe('Search', () => {
|
||
|
beforeAll(async () => {
|
||
|
// mock all output so that there is less noise when running tests
|
||
|
jest.spyOn(console, 'log').mockImplementation(() => {})
|
||
|
jest.spyOn(core, 'debug').mockImplementation(() => {})
|
||
|
jest.spyOn(core, 'info').mockImplementation(() => {})
|
||
|
jest.spyOn(core, 'warning').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.writeFile(goodItem1Path, 'good item1 file')
|
||
|
await fs.writeFile(goodItem2Path, 'good item2 file')
|
||
|
await fs.writeFile(goodItem3Path, 'good item3 file')
|
||
|
await fs.writeFile(goodItem4Path, 'good item4 file')
|
||
|
await fs.writeFile(goodItem5Path, 'good item5 file')
|
||
|
|
||
|
await fs.writeFile(badItem1Path, 'bad item1 file')
|
||
|
await fs.writeFile(badItem2Path, 'bad item2 file')
|
||
|
await fs.writeFile(badItem3Path, 'bad item3 file')
|
||
|
await fs.writeFile(badItem4Path, 'bad item4 file')
|
||
|
await fs.writeFile(badItem5Path, 'bad item5 file')
|
||
|
|
||
|
await fs.writeFile(extraFileInFolderCPath, 'extra file')
|
||
|
|
||
|
await fs.writeFile(amazingFileInFolderHPath, 'amazing file')
|
||
|
/*
|
||
|
Directory structure of files that get created:
|
||
|
root/
|
||
|
folder-a/
|
||
|
folder-b/
|
||
|
folder-c/
|
||
|
good-item1.txt
|
||
|
bad-item1.txt
|
||
|
extra-file-in-folder-c.txt
|
||
|
folder-e/
|
||
|
folder-d/
|
||
|
good-item2.txt
|
||
|
good-item3.txt
|
||
|
good-item4.txt
|
||
|
bad-item2.txt
|
||
|
folder-f/
|
||
|
bad-item3.txt
|
||
|
folder-g/
|
||
|
folder-h/
|
||
|
amazing-item.txt
|
||
|
folder-i/
|
||
|
bad-item4.txt
|
||
|
bad-item5.txt
|
||
|
good-item5.txt
|
||
|
*/
|
||
|
})
|
||
|
|
||
|
it('Upload Specification - Fail non-existent rootDirectory', async () => {
|
||
|
const invalidRootDirectory = path.join(
|
||
|
__dirname,
|
||
|
'_temp',
|
||
|
'upload-specification-invalid'
|
||
|
)
|
||
|
expect(() => {
|
||
|
getUploadSpecification(
|
||
|
artifactName,
|
||
|
invalidRootDirectory,
|
||
|
artifactFilesToUpload
|
||
|
)
|
||
|
}).toThrow(`Provided rootDirectory ${invalidRootDirectory} does not exist`)
|
||
|
})
|
||
|
|
||
|
it('Upload Specification - Fail invalid rootDirectory', async () => {
|
||
|
expect(() => {
|
||
|
getUploadSpecification(artifactName, goodItem1Path, artifactFilesToUpload)
|
||
|
}).toThrow(
|
||
|
`Provided rootDirectory ${goodItem1Path} is not a valid directory`
|
||
|
)
|
||
|
})
|
||
|
|
||
|
it('Upload Specification - File does not exist', async () => {
|
||
|
const fakeFilePath = path.join(
|
||
|
artifactName,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'non-existent-file.txt'
|
||
|
)
|
||
|
expect(() => {
|
||
|
getUploadSpecification(artifactName, root, [fakeFilePath])
|
||
|
}).toThrow(`File ${fakeFilePath} does not exist`)
|
||
|
})
|
||
|
|
||
|
it('Upload Specification - Non parent directory', async () => {
|
||
|
const folderADirectory = path.join(root, 'folder-a')
|
||
|
const artifactFiles = [
|
||
|
goodItem1Path,
|
||
|
badItem1Path,
|
||
|
extraFileInFolderCPath,
|
||
|
goodItem5Path
|
||
|
]
|
||
|
expect(() => {
|
||
|
getUploadSpecification(artifactName, folderADirectory, artifactFiles)
|
||
|
}).toThrow(
|
||
|
`The rootDirectory: ${folderADirectory} is not a parent directory of the file: ${goodItem5Path}`
|
||
|
)
|
||
|
})
|
||
|
|
||
|
it('Upload Specification - Success', async () => {
|
||
|
const specifications = getUploadSpecification(
|
||
|
artifactName,
|
||
|
root,
|
||
|
artifactFilesToUpload
|
||
|
)
|
||
|
expect(specifications.length).toEqual(7)
|
||
|
|
||
|
const absolutePaths = specifications.map(item => item.absoluteFilePath)
|
||
|
expect(absolutePaths).toContain(goodItem1Path)
|
||
|
expect(absolutePaths).toContain(goodItem2Path)
|
||
|
expect(absolutePaths).toContain(goodItem3Path)
|
||
|
expect(absolutePaths).toContain(goodItem4Path)
|
||
|
expect(absolutePaths).toContain(goodItem5Path)
|
||
|
expect(absolutePaths).toContain(extraFileInFolderCPath)
|
||
|
expect(absolutePaths).toContain(amazingFileInFolderHPath)
|
||
|
|
||
|
for (const specification of specifications) {
|
||
|
if (specification.absoluteFilePath === goodItem1Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(
|
||
|
artifactName,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'folder-c',
|
||
|
'good-item1.txt'
|
||
|
)
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem2Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item2.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem3Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item3.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem4Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item4.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem5Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'good-item5.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === extraFileInFolderCPath) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(
|
||
|
artifactName,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'folder-c',
|
||
|
'extra-file-in-folder-c.txt'
|
||
|
)
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === amazingFileInFolderHPath) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-h', 'amazing-item.txt')
|
||
|
)
|
||
|
} else {
|
||
|
throw new Error(
|
||
|
'Invalid specification found. This should never be reached'
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
it('Upload Specification - Success with extra slash', async () => {
|
||
|
const rootWithSlash = `${root}/`
|
||
|
const specifications = getUploadSpecification(
|
||
|
artifactName,
|
||
|
rootWithSlash,
|
||
|
artifactFilesToUpload
|
||
|
)
|
||
|
expect(specifications.length).toEqual(7)
|
||
|
|
||
|
const absolutePaths = specifications.map(item => item.absoluteFilePath)
|
||
|
expect(absolutePaths).toContain(goodItem1Path)
|
||
|
expect(absolutePaths).toContain(goodItem2Path)
|
||
|
expect(absolutePaths).toContain(goodItem3Path)
|
||
|
expect(absolutePaths).toContain(goodItem4Path)
|
||
|
expect(absolutePaths).toContain(goodItem5Path)
|
||
|
expect(absolutePaths).toContain(extraFileInFolderCPath)
|
||
|
expect(absolutePaths).toContain(amazingFileInFolderHPath)
|
||
|
|
||
|
for (const specification of specifications) {
|
||
|
if (specification.absoluteFilePath === goodItem1Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(
|
||
|
artifactName,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'folder-c',
|
||
|
'good-item1.txt'
|
||
|
)
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem2Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item2.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem3Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item3.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem4Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item4.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem5Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'good-item5.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === extraFileInFolderCPath) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(
|
||
|
artifactName,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'folder-c',
|
||
|
'extra-file-in-folder-c.txt'
|
||
|
)
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === amazingFileInFolderHPath) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-h', 'amazing-item.txt')
|
||
|
)
|
||
|
} else {
|
||
|
throw new Error(
|
||
|
'Invalid specification found. This should never be reached'
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
it('Upload Specification - Directories should not be included', async () => {
|
||
|
const folderEPath = path.join(root, 'folder-a', 'folder-b', 'folder-e')
|
||
|
const filesWithDirectory = [
|
||
|
goodItem1Path,
|
||
|
goodItem4Path,
|
||
|
folderEPath,
|
||
|
badItem3Path
|
||
|
]
|
||
|
const specifications = getUploadSpecification(
|
||
|
artifactName,
|
||
|
root,
|
||
|
filesWithDirectory
|
||
|
)
|
||
|
expect(specifications.length).toEqual(3)
|
||
|
const absolutePaths = specifications.map(item => item.absoluteFilePath)
|
||
|
expect(absolutePaths).toContain(goodItem1Path)
|
||
|
expect(absolutePaths).toContain(goodItem4Path)
|
||
|
expect(absolutePaths).toContain(badItem3Path)
|
||
|
|
||
|
for (const specification of specifications) {
|
||
|
if (specification.absoluteFilePath === goodItem1Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(
|
||
|
artifactName,
|
||
|
'folder-a',
|
||
|
'folder-b',
|
||
|
'folder-c',
|
||
|
'good-item1.txt'
|
||
|
)
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem2Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item2.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === goodItem4Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-d', 'good-item4.txt')
|
||
|
)
|
||
|
} else if (specification.absoluteFilePath === badItem3Path) {
|
||
|
expect(specification.uploadFilePath).toEqual(
|
||
|
path.join(artifactName, 'folder-f', 'bad-item3.txt')
|
||
|
)
|
||
|
} else {
|
||
|
throw new Error(
|
||
|
'Invalid specification found. This should never be reached'
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
})
|