const test = require('ava') const Either = require('fp-ts/Either') const { pipe } = require('fp-ts/function') const Config = require('../src/config.js') const fail = (t, cfg) => { const res = Config.parse(cfg) t.assert(Either.isLeft(res), 'parsing erroneously succeeded') } const pass = (t, cfg, { ret } = { ret: false }) => { const res = Config.parse(cfg) const parsed = Either.getOrElse(e => { throw e })(res) if (ret) { return parsed } else { t.pass() } } test('config fails when top-level node is not array', t => { fail(t, `foo: 'bar'`) fail(t, `'bar'`) pass(t, '[]') }) test('config fails when service unknown', t => { fail(t, `- foo`) fail( t, ` - foo: bar: 'baz' `, ) }) test('config fails when linux_user bad', t => { const rest = `network: interface: 'public' port: 1 domain: 'db.foo.org' ssl: false postgres: username: 'postgres' password: 'password'` fail( t, ` - db: ${rest} `, ) fail( t, ` - db: linux_user: persist: [] ${rest} `, ) pass( t, ` - db: linux_user: username: 'foo' ${rest} `, ) }) test('config fails when linux_user.persist is not subpath of homedir', t => { const rest = `network: interface : 'public' port: 1 domain: 'db.foo.org' ssl: false postgres: username: 'postgres' password: 'password'` fail( t, ` - db: linux_user: username: 'foo' persist: ['/tmp'] ${rest}`, ) fail( t, ` - db: linux_user: username: 'foo' persist: ['../tmp'] ${rest}`, ) const parsed = pass( t, ` - db: linux_user: username: 'foo' persist: - '/home/foo/bar' - './bar/baz' - './tmp' ${rest}`, { ret: true }, ) t.deepEqual(parsed[0].linuxUser.persist, [ '/home/foo/bar', '/home/foo/bar/baz', '/home/foo/tmp', ]) }) test('config fails when bad combo of network.interface and network.domain', t => { const rest = `linux_user: username: 'foo' postgres: username: 'postgres' password: 'password'` fail( t, ` - db: network: interface: 'public' port: 1 ssl: false ${rest}`, ) fail( t, ` - db: network: interface: 'local' domain: 'foo.org' port: 1 ssl: false ${rest}`, ) pass( t, ` - db: network: interface: 'public' domain: 'foo.org' port: 1 ssl: false ${rest}`, ) pass( t, ` - db: network: interface: 'local' port: 1 ssl: false ${rest}`, ) }) test('config fails when postgres bad', t => { const rest = `linux_user: username: 'foo' network: interface: 'local' port: 1 ssl: false` fail( t, ` - db: ${rest} `, ) fail( t, ` - db: postgres: username: 'foo' ${rest} `, ) fail( t, ` - db: postgres: password: 'foo' ${rest} `, ) fail( t, ` - db: postgres: username: 'foo' password: 'foo' data_dir: '/tmp' ${rest}`, ) fail( t, ` - db: postgres: username: 'foo' password: 'foo' data_dir: '/tmp' ${rest}`, ) pass( t, ` - db: postgres: username: 'foo' password: 'foo' data_dir: 'data' ${rest} `, ) pass( t, ` - db: postgres: username: 'foo' password: 'foo' data_dir: '/home/foo/data' ${rest} `, ) pass( t, ` - db: postgres: username: 'foo' password: 'foo' ${rest} `, ) }) test('config allows multiple services', t => { const one = (un, port) => ` - db: postgres: username: 'foo' password: 'bar' linux_user: username: '${un}' network: interface: 'local' port: ${port} ssl: false` pass( t, ` ${one('a', 0)} ${one('b', 1)} `, ) }) test('config fails when port, linux_user.username, or domain reused', t => { const one = (un, port, domain) => ` - db: postgres: username: 'foo' password: 'bar' linux_user: username: '${un}' network: interface: 'public' port: ${port} domain: ${domain} ssl: false` fail( t, ` ${one('a', 0, 'foo.org')} ${one('b', 1, 'foo.org')} `, ) fail( t, ` ${one('a', 1, 'foo.baz.org')} ${one('b', 1, 'foo.org')} `, ) fail( t, ` ${one('a', 0, 'foo.baz.org')} ${one('a', 1, 'foo.org')} `, ) pass( t, ` ${one('a', 0, 'foo.baz.org')} ${one('b', 1, 'foo.org')} `, ) })