0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-23 22:27:34 -05:00
verdaccio/packages/plugins/htpasswd/tests/htpasswd.test.ts
Juan Picado b56d5cec39
chore: refactor pkgs location (#2538)
* chore: relocated mock package

* refactor: relocate local-storage htpasswd to plugins

because they are

* chore: format
2021-10-18 22:18:09 +02:00

308 lines
9.2 KiB
TypeScript

/* eslint-disable jest/no-mocks-import */
import crypto from 'crypto';
// @ts-ignore
import fs from 'fs';
import MockDate from 'mockdate';
import HTPasswd, { VerdaccioConfigApp } from '../src/htpasswd';
import { HtpasswdHashAlgorithm } from '../src/utils';
// FIXME: remove this mocks imports
import Logger from './__mocks__/Logger';
import Config from './__mocks__/Config';
const stuff = {
logger: new Logger(),
config: new Config(),
};
const config = {
file: './htpasswd',
max_users: 1000,
};
const getDefaultConfig = (): VerdaccioConfigApp => ({
file: './htpasswd',
max_users: 1000,
});
describe('HTPasswd', () => {
let wrapper;
beforeEach(() => {
wrapper = new HTPasswd(getDefaultConfig(), stuff as unknown as VerdaccioConfigApp);
jest.resetModules();
crypto.randomBytes = jest.fn(() => {
return {
toString: (): string => '$6',
};
});
});
describe('constructor()', () => {
const emptyPluginOptions = { config: {} } as VerdaccioConfigApp;
test('should files whether file path does not exist', () => {
expect(function () {
new HTPasswd({}, emptyPluginOptions);
}).toThrow(/should specify "file" in config/);
});
test('should throw error about incorrect algorithm', () => {
expect(function () {
let config = getDefaultConfig();
config.algorithm = 'invalid' as any;
new HTPasswd(config, emptyPluginOptions);
}).toThrow(/Invalid algorithm "invalid"/);
});
});
describe('authenticate()', () => {
test('it should authenticate user with given credentials', (done) => {
const callbackTest = (a, b): void => {
expect(a).toBeNull();
expect(b).toContain('test');
done();
};
const callbackUsername = (a, b): void => {
expect(a).toBeNull();
expect(b).toContain('username');
done();
};
wrapper.authenticate('test', 'test', callbackTest);
wrapper.authenticate('username', 'password', callbackUsername);
});
test('it should not authenticate user with given credentials', (done) => {
const callback = (a, b): void => {
expect(a).toBeNull();
expect(b).toBeFalsy();
done();
};
wrapper.authenticate('test', 'somerandompassword', callback);
});
});
describe('addUser()', () => {
test('it should not pass sanity check', (done) => {
const callback = (a): void => {
expect(a.message).toEqual('unauthorized access');
done();
};
wrapper.adduser('test', 'somerandompassword', callback);
});
test('it should add the user', (done) => {
let dataToWrite;
// @ts-ignore
fs.writeFile = jest.fn((name, data, callback) => {
dataToWrite = data;
callback();
});
MockDate.set('2018-01-14T11:17:40.712Z');
const callback = (a, b): void => {
expect(a).toBeNull();
expect(b).toBeTruthy();
expect(fs.writeFile).toHaveBeenCalled();
expect(dataToWrite.indexOf('usernotpresent')).not.toEqual(-1);
done();
};
wrapper.adduser('usernotpresent', 'somerandompassword', callback);
});
describe('addUser() error handling', () => {
test('sanityCheck should return an Error', (done) => {
jest.doMock('../src/utils.ts', () => {
return {
sanityCheck: (): Error => Error('some error'),
HtpasswdHashAlgorithm,
};
});
const HTPasswd = require('../src/htpasswd.ts').default;
const wrapper = new HTPasswd(config, stuff);
wrapper.adduser('sanityCheck', 'test', (sanity) => {
expect(sanity.message).toBeDefined();
expect(sanity.message).toMatch('some error');
done();
});
});
test('lockAndRead should return an Error', (done) => {
jest.doMock('../src/utils.ts', () => {
return {
sanityCheck: (): any => null,
lockAndRead: (_a, b): any => b(new Error('lock error')),
HtpasswdHashAlgorithm,
};
});
const HTPasswd = require('../src/htpasswd.ts').default;
const wrapper = new HTPasswd(config, stuff);
wrapper.adduser('lockAndRead', 'test', (sanity) => {
expect(sanity.message).toBeDefined();
expect(sanity.message).toMatch('lock error');
done();
});
});
test('addUserToHTPasswd should return an Error', (done) => {
jest.doMock('../src/utils.ts', () => {
return {
sanityCheck: (): any => null,
parseHTPasswd: (): void => {},
lockAndRead: (_a, b): any => b(null, ''),
unlockFile: (_a, b): any => b(),
HtpasswdHashAlgorithm,
};
});
const HTPasswd = require('../src/htpasswd.ts').default;
const wrapper = new HTPasswd(config, stuff);
wrapper.adduser('addUserToHTPasswd', 'test', () => {
done();
});
});
test('writeFile should return an Error', (done) => {
jest.doMock('../src/utils.ts', () => {
return {
sanityCheck: (): any => null,
parseHTPasswd: (): void => {},
lockAndRead: (_a, b): any => b(null, ''),
addUserToHTPasswd: (): void => {},
HtpasswdHashAlgorithm,
};
});
jest.doMock('fs', () => {
const original = jest.requireActual('fs');
return {
...original,
writeFile: jest.fn((_name, _data, callback) => {
callback(new Error('write error'));
}),
};
});
const HTPasswd = require('../src/htpasswd.ts').default;
const wrapper = new HTPasswd(config, stuff);
wrapper.adduser('addUserToHTPasswd', 'test', (err) => {
expect(err).not.toBeNull();
expect(err.message).toMatch('write error');
done();
});
});
});
describe('reload()', () => {
test('it should read the file and set the users', (done) => {
const output = { test: '$6FrCaT/v0dwE', username: '$66to3JK5RgZM' };
const callback = (): void => {
expect(wrapper.users).toEqual(output);
done();
};
wrapper.reload(callback);
});
test('reload should fails on check file', (done) => {
jest.doMock('fs', () => {
return {
stat: (_name, callback): void => {
callback(new Error('stat error'), null);
},
};
});
const callback = (err): void => {
expect(err).not.toBeNull();
expect(err.message).toMatch('stat error');
done();
};
const HTPasswd = require('../src/htpasswd.ts').default;
const wrapper = new HTPasswd(config, stuff);
wrapper.reload(callback);
});
test('reload times match', (done) => {
jest.doMock('fs', () => {
return {
stat: (_name, callback): void => {
callback(null, {
mtime: null,
});
},
};
});
const callback = (err): void => {
expect(err).toBeUndefined();
done();
};
const HTPasswd = require('../src/htpasswd.ts').default;
const wrapper = new HTPasswd(config, stuff);
wrapper.reload(callback);
});
test('reload should fails on read file', (done) => {
jest.doMock('fs', () => {
return {
stat: jest.requireActual('fs').stat,
readFile: (_name, _format, callback): void => {
callback(new Error('read error'), null);
},
};
});
const callback = (err): void => {
expect(err).not.toBeNull();
expect(err.message).toMatch('read error');
done();
};
const HTPasswd = require('../src/htpasswd.ts').default;
const wrapper = new HTPasswd(config, stuff);
wrapper.reload(callback);
});
});
});
test('changePassword - it should throw an error for user not found', (done) => {
const callback = (error, isSuccess): void => {
expect(error).not.toBeNull();
expect(error.message).toBe('User not found');
expect(isSuccess).toBeFalsy();
done();
};
wrapper.changePassword('usernotpresent', 'oldPassword', 'newPassword', callback);
});
test('changePassword - it should throw an error for wrong password', (done) => {
const callback = (error, isSuccess): void => {
expect(error).not.toBeNull();
expect(error.message).toBe('Invalid old Password');
expect(isSuccess).toBeFalsy();
done();
};
wrapper.changePassword('username', 'wrongPassword', 'newPassword', callback);
});
test('changePassword - it should change password', (done) => {
let dataToWrite;
// @ts-ignore
fs.writeFile = jest.fn((_name, data, callback) => {
dataToWrite = data;
callback();
});
const callback = (error, isSuccess): void => {
expect(error).toBeNull();
expect(isSuccess).toBeTruthy();
expect(fs.writeFile).toHaveBeenCalled();
expect(dataToWrite.indexOf('username')).not.toEqual(-1);
done();
};
wrapper.changePassword('username', 'password', 'newPassword', callback);
});
});