(adding jest for unit/integration tests) (#91)

This commit is contained in:
Matiss Janis Aboltins
2023-01-28 17:56:37 +00:00
committed by GitHub
parent 9fc9d5c642
commit f0772b147f
9 changed files with 2751 additions and 29 deletions

View File

@@ -3,7 +3,8 @@ module.exports = {
env: {
browser: true,
amd: true,
node: true
node: true,
jest: true
},
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'prettier'],

29
.github/workflows/test.yml vendored Normal file
View 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
View File

@@ -7,6 +7,8 @@ supervise
bin/large-sync-data.txt
user-files
server-files
test-user-files
test-server-files
fly.toml
build/

77
app-sync.test.js Normal file
View 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
View File

@@ -0,0 +1,4 @@
{
"setupFiles": ["./jest.setup.js"],
"testPathIgnorePatterns": ["/node_modules/", "/build/"]
}

17
jest.setup.js Normal file
View 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']);

View File

@@ -7,13 +7,23 @@ try {
let { join } = require('path');
let root = fs.existsSync('/data') ? '/data' : __dirname;
config = {
mode: 'development',
port: 5006,
hostname: '0.0.0.0',
serverFiles: join(root, 'server-files'),
userFiles: join(root, 'user-files')
};
if (process.env.NODE_ENV === 'test') {
config = {
mode: 'test',
port: 5006,
hostname: '0.0.0.0',
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

View File

@@ -8,6 +8,7 @@
"start": "node app",
"lint": "eslint .",
"build": "tsc",
"test": "jest",
"types": "tsc --noEmit --incremental",
"verify": "yarn -s lint && yarn types"
},
@@ -26,12 +27,16 @@
},
"devDependencies": {
"@types/better-sqlite3": "^7.5.0",
"@types/jest": "^29.2.3",
"@types/node": "^17.0.31",
"@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"eslint": "^8.15.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^29.3.1",
"prettier": "^2.6.2",
"supertest": "^6.3.1",
"typescript": "^4.6.4"
},
"packageManager": "yarn@3.2.1"

2619
yarn.lock

File diff suppressed because it is too large Load Diff