Skip to content

Commit

Permalink
[TEST] Add tests for copyRecursiveAsync function and update Jest conf…
Browse files Browse the repository at this point in the history
…iguration
  • Loading branch information
flavioislima committed Dec 10, 2024
1 parent f635bbe commit d70b650
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 9 deletions.
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module.exports = {
globals: {
'ts-jest': {}
},

testTimeout: 35000,
setupFilesAfterEnv: ['./jest.setup.ts'],
collectCoverageFrom: ['**/*.{js,jsx,ts,tsx}', '!**/*.config.js'],
coverageDirectory: '<rootDir>/coverage',
coveragePathIgnorePatterns: [
Expand Down
1 change: 1 addition & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jest.setTimeout(35000)
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@
"@types/express": "^4.17.21",
"@types/i18next-fs-backend": "^1.1.5",
"@types/ini": "^1.3.34",
"@types/jest": "^29.5.12",
"@types/jest": "^29.5.14",
"@types/jsdom": "^20.0.1",
"@types/mime": "^3.0.2",
"@types/node": "^20.16.2",
Expand All @@ -334,6 +334,7 @@
"@types/react-blockies": "^1.4.1",
"@types/react-dom": "^18.0.8",
"@types/react-router-dom": "^5.3.3",
"@types/rimraf": "^4.0.5",
"@types/tmp": "^0.2.6",
"@types/ws": "^8.5.12",
"@typescript-eslint/eslint-plugin": "^6.21.0",
Expand All @@ -357,9 +358,10 @@
"prettier": "^2.8.8",
"pretty-quick": "^4.0.0",
"react-markdown": "^9.0.1",
"rimraf": "^6.0.1",
"sass": "^1.55.0",
"tmp": "^0.2.3",
"ts-jest": "^29.1.1",
"ts-jest": "^29.2.5",
"type-fest": "^3.2.0",
"typescript": "5.3.3",
"vite": "^5.4.0",
Expand Down
103 changes: 102 additions & 1 deletion src/backend/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import * as utils from '../utils'
import { getExecutableAndArgs } from '../utils'
import { getExecutableAndArgs, copyRecursiveAsync } from '../utils'
import { mkdir, writeFile, symlink } from 'fs/promises'
import { join } from 'path'
import { chmod, existsSync } from 'fs'
import { rimraf } from 'rimraf'
import os from 'os'
import * as fs from 'fs'

jest.mock('electron')
jest.mock('../logger/logger')
Expand Down Expand Up @@ -261,4 +267,99 @@ describe('backend/utils.ts', () => {
expect(getExecutableAndArgs(input)).toEqual(expected)
})
})

describe.only('copyRecursiveAsync', () => {
const testDir = join(os.tmpdir(), `test-copy-${Date.now()}`)
const sourceDir = join(testDir, 'source')
const destDir = join(testDir, 'dest')

beforeEach(async () => {
// Setup test directories
await mkdir(sourceDir, { recursive: true })
await mkdir(destDir, { recursive: true })
})

afterEach(async () => {
// Cleanup test directories
await rimraf(testDir)
})

it('should copy a single file', async () => {
const testFile = join(sourceDir, 'test.txt')
const destFile = join(destDir, 'test.txt')
await writeFile(testFile, 'test content')

await copyRecursiveAsync(testFile, destFile)

expect(existsSync(destFile)).toBe(true)
})

it('should copy a directory recursively', async () => {
const subDir = join(sourceDir, 'subdir')
const testFile = join(subDir, 'test.txt')
await mkdir(subDir, { recursive: true })
await writeFile(testFile, 'test content')

await copyRecursiveAsync(sourceDir, join(destDir, 'source'))

expect(existsSync(join(destDir, 'source/subdir/test.txt'))).toBe(true)
})

it('should skip symbolic links', async () => {
const testFile = join(sourceDir, 'test.txt')
const linkFile = join(sourceDir, 'link.txt')
await writeFile(testFile, 'test content')
await symlink(testFile, linkFile)

await copyRecursiveAsync(linkFile, join(destDir, 'link.txt'))

expect(existsSync(join(destDir, 'link.txt'))).toBe(false)
})

it('should handle invalid source path', async () => {
const result = await copyRecursiveAsync('nonexistent', destDir)
expect(result).toBeUndefined()
})

it('should throw on permission error', async () => {
const testFile = join(sourceDir, 'test.txt')
await writeFile(testFile, 'test content')

// Make destination directory read-only
await new Promise((resolve) => chmod(destDir, '444', resolve))

await expect(
copyRecursiveAsync(testFile, join(destDir, 'test.txt'))
).rejects.toThrow('Permission error')
})

it('should throw on timeout', async () => {
const COPY_TIMEOUT_MS = 30000
const testFile = join(sourceDir, 'test.txt')
await writeFile(testFile, 'test content')

// Mock the copyFile function to simulate a slow operation
const mockCopyFile = jest
.spyOn(fs.promises, 'copyFile')
.mockImplementation(async () => {
return new Promise((resolve) => {
setTimeout(resolve, COPY_TIMEOUT_MS + 1000) // Wait longer than timeout
})
})

const destFile = join(destDir, 'test.txt')

await expect(copyRecursiveAsync(testFile, destFile)).rejects.toThrow(
'Timeout'
)

// Restore original implementation
mockCopyFile.mockRestore()
})

it('should handle empty source and destination', async () => {
const result = await copyRecursiveAsync('', '')
expect(result).toBeUndefined()
})
})
})
64 changes: 59 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3435,10 +3435,10 @@
dependencies:
"@types/istanbul-lib-report" "*"

"@types/jest@^29.5.12":
version "29.5.12"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544"
integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==
"@types/jest@^29.5.14":
version "29.5.14"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5"
integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==
dependencies:
expect "^29.0.0"
pretty-format "^29.0.0"
Expand Down Expand Up @@ -3608,6 +3608,13 @@
dependencies:
"@types/node" "*"

"@types/rimraf@^4.0.5":
version "4.0.5"
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-4.0.5.tgz#7a59be11605c22ea3959c21ff8b28b9df1bae1b2"
integrity sha512-DTCZoIQotB2SUJnYgrEx43cQIUYOlNZz0AZPbKU4PSLYTUdML5Gox0++z4F9kQocxStrCmRNhi4x5x/UlwtKUA==
dependencies:
rimraf "*"

"@types/secp256k1@^4.0.6":
version "4.0.6"
resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.6.tgz#d60ba2349a51c2cbc5e816dcd831a42029d376bf"
Expand Down Expand Up @@ -7897,6 +7904,18 @@ glob@^10.2.2, glob@^10.3.10:
package-json-from-dist "^1.0.0"
path-scurry "^1.11.1"

glob@^11.0.0:
version "11.0.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.0.tgz#6031df0d7b65eaa1ccb9b29b5ced16cea658e77e"
integrity sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==
dependencies:
foreground-child "^3.1.0"
jackspeak "^4.0.1"
minimatch "^10.0.0"
minipass "^7.1.2"
package-json-from-dist "^1.0.0"
path-scurry "^2.0.0"

glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
Expand Down Expand Up @@ -8966,6 +8985,13 @@ jackspeak@^3.1.2:
optionalDependencies:
"@pkgjs/parseargs" "^0.11.0"

jackspeak@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.2.tgz#11f9468a3730c6ff6f56823a820d7e3be9bef015"
integrity sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==
dependencies:
"@isaacs/cliui" "^8.0.2"

jake@^10.8.5:
version "10.9.2"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f"
Expand Down Expand Up @@ -9888,6 +9914,11 @@ lru-cache@^10.0.1, lru-cache@^10.2.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==

lru-cache@^11.0.0:
version "11.0.2"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.2.tgz#fbd8e7cf8211f5e7e5d91905c415a3f55755ca39"
integrity sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==

lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
Expand Down Expand Up @@ -10400,6 +10431,13 @@ [email protected]:
dependencies:
brace-expansion "^2.0.1"

minimatch@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b"
integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==
dependencies:
brace-expansion "^2.0.1"

minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
Expand Down Expand Up @@ -11193,6 +11231,14 @@ path-scurry@^1.11.1:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"

path-scurry@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580"
integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==
dependencies:
lru-cache "^11.0.0"
minipass "^7.1.2"

[email protected]:
version "0.1.10"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b"
Expand Down Expand Up @@ -12131,6 +12177,14 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==

rimraf@*, rimraf@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e"
integrity sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==
dependencies:
glob "^11.0.0"
package-json-from-dist "^1.0.0"

rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
Expand Down Expand Up @@ -13272,7 +13326,7 @@ ts-api-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1"
integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==

ts-jest@^29.1.1:
ts-jest@^29.2.5:
version "29.2.5"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.5.tgz#591a3c108e1f5ebd013d3152142cb5472b399d63"
integrity sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==
Expand Down

0 comments on commit d70b650

Please sign in to comment.