mirror of
https://github.com/actualbudget/actual.git
synced 2026-04-30 10:14:53 -05:00
✅ (adding jest for unit/integration tests) (#91)
This commit is contained in:
committed by
GitHub
parent
9fc9d5c642
commit
f0772b147f
@@ -3,7 +3,8 @@ module.exports = {
|
|||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
amd: true,
|
amd: true,
|
||||||
node: true
|
node: true,
|
||||||
|
jest: true
|
||||||
},
|
},
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
plugins: ['@typescript-eslint', 'prettier'],
|
plugins: ['@typescript-eslint', 'prettier'],
|
||||||
|
|||||||
29
.github/workflows/test.yml
vendored
Normal file
29
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches: '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
- name: Cache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
id: cache
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: yarn-v1-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
- name: Install
|
||||||
|
run: yarn --immutable
|
||||||
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
|
- name: Test
|
||||||
|
run: yarn test
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,6 +7,8 @@ supervise
|
|||||||
bin/large-sync-data.txt
|
bin/large-sync-data.txt
|
||||||
user-files
|
user-files
|
||||||
server-files
|
server-files
|
||||||
|
test-user-files
|
||||||
|
test-server-files
|
||||||
fly.toml
|
fly.toml
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
|||||||
77
app-sync.test.js
Normal file
77
app-sync.test.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const request = require('supertest');
|
||||||
|
const { handlers: app } = require('./app-sync');
|
||||||
|
const { getAccountDb } = require('./account-db');
|
||||||
|
const { getPathForUserFile } = require('./util/paths');
|
||||||
|
|
||||||
|
describe('/download-user-file', () => {
|
||||||
|
describe('default version', () => {
|
||||||
|
it('returns 401 if the user is not authenticated', async () => {
|
||||||
|
const res = await request(app).get('/download-user-file');
|
||||||
|
|
||||||
|
expect(res.statusCode).toEqual(401);
|
||||||
|
expect(res.body).toEqual({
|
||||||
|
details: 'token-not-found',
|
||||||
|
reason: 'unauthorized',
|
||||||
|
status: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns 401 if the user is invalid', async () => {
|
||||||
|
const res = await request(app)
|
||||||
|
.get('/download-user-file')
|
||||||
|
.set('x-actual-token', 'invalid-token');
|
||||||
|
|
||||||
|
expect(res.statusCode).toEqual(401);
|
||||||
|
expect(res.body).toEqual({
|
||||||
|
details: 'token-not-found',
|
||||||
|
reason: 'unauthorized',
|
||||||
|
status: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns 400 error if the file does not exist in the database', async () => {
|
||||||
|
const res = await request(app)
|
||||||
|
.get('/download-user-file')
|
||||||
|
.set('x-actual-token', 'valid-token')
|
||||||
|
.set('x-actual-file-id', 'non-existing-file-id');
|
||||||
|
|
||||||
|
expect(res.statusCode).toEqual(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns 500 error if the file does not exist on the filesystem', async () => {
|
||||||
|
getAccountDb().mutate(
|
||||||
|
'INSERT INTO files (id, deleted) VALUES (?, FALSE)',
|
||||||
|
['missing-fs-file']
|
||||||
|
);
|
||||||
|
|
||||||
|
const res = await request(app)
|
||||||
|
.get('/download-user-file')
|
||||||
|
.set('x-actual-token', 'valid-token')
|
||||||
|
.set('x-actual-file-id', 'missing-fs-file');
|
||||||
|
|
||||||
|
expect(res.statusCode).toEqual(500);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns an attachment file', async () => {
|
||||||
|
fs.writeFileSync(getPathForUserFile('file-id'), 'content');
|
||||||
|
getAccountDb().mutate(
|
||||||
|
'INSERT INTO files (id, deleted) VALUES (?, FALSE)',
|
||||||
|
['file-id']
|
||||||
|
);
|
||||||
|
|
||||||
|
const res = await request(app)
|
||||||
|
.get('/download-user-file')
|
||||||
|
.set('x-actual-token', 'valid-token')
|
||||||
|
.set('x-actual-file-id', 'file-id');
|
||||||
|
|
||||||
|
expect(res.statusCode).toEqual(200);
|
||||||
|
expect(res.headers).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
'content-disposition': 'attachment;filename=file-id',
|
||||||
|
'content-type': 'application/octet-stream'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
4
jest.config.json
Normal file
4
jest.config.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"setupFiles": ["./jest.setup.js"],
|
||||||
|
"testPathIgnorePatterns": ["/node_modules/", "/build/"]
|
||||||
|
}
|
||||||
17
jest.setup.js
Normal file
17
jest.setup.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { join } = require('path');
|
||||||
|
const { getAccountDb } = require('./account-db');
|
||||||
|
const config = require('./load-config');
|
||||||
|
|
||||||
|
// Delete previous test database (force creation of a new one)
|
||||||
|
const dbPath = join(config.serverFiles, 'account.sqlite');
|
||||||
|
if (fs.existsSync(dbPath)) fs.unlinkSync(dbPath);
|
||||||
|
|
||||||
|
// Create path for test user files and delete previous files there
|
||||||
|
if (fs.existsSync(config.userFiles))
|
||||||
|
fs.rmdirSync(config.userFiles, { recursive: true });
|
||||||
|
fs.mkdirSync(config.userFiles);
|
||||||
|
|
||||||
|
// Insert a fake "valid-token" fixture that can be reused
|
||||||
|
const db = getAccountDb();
|
||||||
|
db.mutate('INSERT INTO sessions (token) VALUES (?)', ['valid-token']);
|
||||||
@@ -7,13 +7,23 @@ try {
|
|||||||
let { join } = require('path');
|
let { join } = require('path');
|
||||||
let root = fs.existsSync('/data') ? '/data' : __dirname;
|
let root = fs.existsSync('/data') ? '/data' : __dirname;
|
||||||
|
|
||||||
config = {
|
if (process.env.NODE_ENV === 'test') {
|
||||||
mode: 'development',
|
config = {
|
||||||
port: 5006,
|
mode: 'test',
|
||||||
hostname: '0.0.0.0',
|
port: 5006,
|
||||||
serverFiles: join(root, 'server-files'),
|
hostname: '0.0.0.0',
|
||||||
userFiles: join(root, 'user-files')
|
serverFiles: join(__dirname, 'test-server-files'),
|
||||||
};
|
userFiles: join(__dirname, 'test-user-files')
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
config = {
|
||||||
|
mode: 'development',
|
||||||
|
port: 5006,
|
||||||
|
hostname: '0.0.0.0',
|
||||||
|
serverFiles: join(root, 'server-files'),
|
||||||
|
userFiles: join(root, 'user-files')
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The env variable always takes precedence
|
// The env variable always takes precedence
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"start": "node app",
|
"start": "node app",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
|
"test": "jest",
|
||||||
"types": "tsc --noEmit --incremental",
|
"types": "tsc --noEmit --incremental",
|
||||||
"verify": "yarn -s lint && yarn types"
|
"verify": "yarn -s lint && yarn types"
|
||||||
},
|
},
|
||||||
@@ -26,12 +27,16 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/better-sqlite3": "^7.5.0",
|
"@types/better-sqlite3": "^7.5.0",
|
||||||
|
"@types/jest": "^29.2.3",
|
||||||
"@types/node": "^17.0.31",
|
"@types/node": "^17.0.31",
|
||||||
|
"@types/supertest": "^2.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.23.0",
|
"@typescript-eslint/eslint-plugin": "^5.23.0",
|
||||||
"@typescript-eslint/parser": "^5.23.0",
|
"@typescript-eslint/parser": "^5.23.0",
|
||||||
"eslint": "^8.15.0",
|
"eslint": "^8.15.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"jest": "^29.3.1",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^2.6.2",
|
||||||
|
"supertest": "^6.3.1",
|
||||||
"typescript": "^4.6.4"
|
"typescript": "^4.6.4"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@3.2.1"
|
"packageManager": "yarn@3.2.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user