{"size": 16037, "ext": "js", "max_stars_repo_path": "lib/sanitize-config.test.js", "max_stars_repo_name": "VIDY/ethereum-connect", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "lib/sanitize-config.test.js", "max_issues_repo_name": "VIDY/ethereum-connect", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "lib/sanitize-config.test.js", "max_forks_repo_name": "VIDY/ethereum-connect", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 43.1102150538, "max_line_length": 144, "alphanum_fraction": 0.6588514061}
'use strict'

const sinon = require('sinon')
const assert = require('chai').assert
const assertThrowsAsync = require('assert-throws-async')
const sanitizeConfig = require('./sanitize-config')

describe('sanitize-config.js', () => {
  const sandbox = sinon.createSandbox()

  describe('sanitizeConfig', () => {
    beforeEach(() => {
      sandbox.stub(sanitizeConfig, 'getRpc')
      sandbox.stub(sanitizeConfig, 'getPort')
      sandbox.stub(sanitizeConfig, 'getAddress')
      sandbox.stub(sanitizeConfig, 'getInfura')
      sandbox.stub(sanitizeConfig, 'getInfuraProjectId')
      sandbox.stub(sanitizeConfig, 'getInfuraProjectSecret')
      sandbox.stub(sanitizeConfig, 'getInfuraNetwork')
      sandbox.stub(sanitizeConfig, 'getLogging')
      sandbox.stub(sanitizeConfig, 'getContracts')
      sandbox.stub(sanitizeConfig, 'getAccount')
    })

    afterEach(() => {
      sandbox.reset()
      sandbox.restore()
    })

    it('should create and return a configuration object using sanitized values and structure', async () => {
      sanitizeConfig.getInfura.callsFake(() => 'infura')
      sanitizeConfig.getRpc.callsFake(() => 'rpc')
      sanitizeConfig.getLogging.callsFake(() => 'logging')
      sanitizeConfig.getContracts.callsFake(() => 'contracts')
      sanitizeConfig.getAccount.callsFake(() => 'account');

      assert.deepEqual(await sanitizeConfig({ test: 'test' }), {
        ethereum: {
          rpc: 'rpc',
          logging: 'logging',
          contracts: 'contracts',
          account: 'account'
        }
      })

      assert.deepEqual(sanitizeConfig.getRpc.args[0][0], { test: 'test' })
      assert.deepEqual(sanitizeConfig.getLogging.args[0][0], { test: 'test' })
      assert.deepEqual(sanitizeConfig.getContracts.args[0][0], { test: 'test' })
      assert.deepEqual(sanitizeConfig.getAccount.args[0][0], { test: 'test' })
    })

    it('should create and return a configuration object using sanitized values and structure for Infura connections', async () => {
      sanitizeConfig.getInfura.callsFake(() => 'infura')
      sanitizeConfig.getRpc.callsFake(() => 'rpc')
      sanitizeConfig.getLogging.callsFake(() => 'logging')
      sanitizeConfig.getContracts.callsFake(() => 'contracts')
      sanitizeConfig.getAccount.callsFake(() => 'account');

      assert.deepEqual(await sanitizeConfig({ ethereum: { infura: 'test'} }), {
        ethereum: {
          infura: 'infura',
          rpc: 'rpc',
          logging: 'logging',
          contracts: 'contracts',
          account: 'account'
        }
      })
    })
  })

  describe('sanitizeConfig.getInfura', () => {
    beforeEach(() => {
      sandbox.stub(sanitizeConfig, 'getInfuraNetwork')
      sandbox.stub(sanitizeConfig, 'getInfuraProjectId')
      sandbox.stub(sanitizeConfig, 'getInfuraProjectSecret')
    })

    afterEach(() => {
      sandbox.reset()
      sandbox.restore()
    })

    it('should return Infura configuration', async () => {
      sanitizeConfig.getInfuraNetwork.callsFake(() => 'network')
      sanitizeConfig.getInfuraProjectId.callsFake(() => 'id')
      sanitizeConfig.getInfuraProjectSecret.callsFake(() => 'secret')

      assert.deepEqual(await sanitizeConfig.getInfura('config'), {
        network: 'network',
        id: 'id',
        secret: 'secret'
      })

      assert.strictEqual(sanitizeConfig.getInfuraNetwork.args[0][0], 'config')
      assert.strictEqual(sanitizeConfig.getInfuraProjectId.args[0][0], 'config')
      assert.strictEqual(sanitizeConfig.getInfuraProjectSecret.args[0][0], 'config')
    })
  })

  describe('sanitizeConfig.getInfuraNetwork', () => {
    it('should default to "mainnet"', async () => {
      assert.deepEqual(await sanitizeConfig.getInfuraNetwork('config'), 'mainnet')
    });

    it('should successfully read network name "mainnet"', async () => {
      const config = {ethereum: {infura: {network: 'mainnet'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraNetwork(config), 'mainnet')
    });

    it('should successfully read network name "rinkeby"', async () => {
      const config = {ethereum: {infura: {network: 'rinkeby'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraNetwork(config), 'rinkeby')
    });

    it('should successfully read network name "RiNkEbY"', async () => {
      const config = {ethereum: {infura: {network: 'RiNkEbY'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraNetwork(config), 'rinkeby')
    });

    it('should successfully read network number "1"', async () => {
      const config = {ethereum: {infura: {network: '1'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraNetwork(config), 'mainnet')
    });

    it('should successfully read network number "4"', async () => {
      const config = {ethereum: {infura: {network: '4'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraNetwork(config), 'rinkeby')
    });

    it('should raise an exception for invalid network', async () => {
      const config = {ethereum: {infura: {network: 'invalid'}}};
      assertThrowsAsync(async () => { await sanitizeConfig.getInfuraNetwork(config) })
    });
  })

  describe('sanitizeConfig.getInfuraProjectId', () => {
    it('should read project id', async () => {
      const config = {ethereum: {infura: {id: 'id'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraProjectId(config), 'id')
    });

    it('should raise an exception if no project id is available', async () => {
      const config = {ethereum: {infura: {network: 'rinkeby'}}};
      assertThrowsAsync(async () => { await sanitizeConfig.getInfuraProjectId({}) })
      assertThrowsAsync(async () => { await sanitizeConfig.getInfuraProjectId({ ethereum: {}}) })
      assertThrowsAsync(async () => { await sanitizeConfig.getInfuraProjectId({ ethereum: { infura: {}}}) })
    });
  })

  describe('sanitizeConfig.getInfuraProjectSecret', () => {
    it('should read project secret', async () => {
      const config = {ethereum: {infura: {secret: 'secret'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraProjectSecret(config), 'secret')
    });

    it('should return undefined if no secret is available', async () => {
      const config = {ethereum: {infura: {secret: 'secret'}}};
      assert.deepEqual(await sanitizeConfig.getInfuraProjectSecret({}), undefined)
      assert.deepEqual(await sanitizeConfig.getInfuraProjectSecret({ ethereum: {}}), undefined)
      assert.deepEqual(await sanitizeConfig.getInfuraProjectSecret({ ethereum: { infura: {}}}), undefined)
    });
  })

  describe('sanitizeConfig.getRpc', () => {
    beforeEach(() => {
      sandbox.stub(sanitizeConfig, 'getInfuraNetwork')
      sandbox.stub(sanitizeConfig, 'getInfuraProjectId')
      sandbox.stub(sanitizeConfig, 'getPort')
      sandbox.stub(sanitizeConfig, 'getAddress')
    })

    afterEach(() => {
      sandbox.reset()
      sandbox.restore()
    })

    it('should provide address, port, and combined URL for standard RPC', async () => {
      sanitizeConfig.getPort.callsFake(() => 1234)
      sanitizeConfig.getAddress.callsFake(() => 'address.com')

      assert.deepEqual(await sanitizeConfig.getRpc('config'), { port: 1234, address: 'address.com', url: 'http://address.com:1234'});

      assert.deepEqual(sanitizeConfig.getPort.args[0], ['config', 'rpc'])
      assert.deepEqual(sanitizeConfig.getAddress.args[0], ['config', 'rpc'])
    })

    it('should return Infura API path for Infura', async () => {
      sanitizeConfig.getInfuraProjectId.callsFake(() => 'abc123')
      sanitizeConfig.getInfuraNetwork.callsFake(() => 'network')

      const config = {ethereum: {infura: 'infura'}}
      assert.deepEqual(await sanitizeConfig.getRpc(config), { url: "https://network.infura.io/v3/abc123" })

      assert.deepEqual(sanitizeConfig.getInfuraProjectId.args[0][0], config)
      assert.deepEqual(sanitizeConfig.getInfuraNetwork.args[0][0], config)
    })
  })

  describe('sanitizeConfig.getAddress', () => {
    beforeEach(() => {
      sandbox.stub(sanitizeConfig, 'getPort')
      sandbox.stub(sanitizeConfig, 'detectDomain')
      sandbox.stub(sanitizeConfig, 'pingDomain')
    })

    afterEach(() => {
      sandbox.reset()
      sandbox.restore()
    })

    it('should return configuration rpc address if ping is successful', async () => {
      sanitizeConfig.getPort.callsFake(() => 1234)
      sanitizeConfig.pingDomain.callsFake(() => true)

      const config = {ethereum: {rpc: {address: 'address'}}}

      assert.strictEqual(await sanitizeConfig.getAddress(config, 'rpc'), 'address')
      assert.deepEqual(sanitizeConfig.getPort.args, [[config, 'rpc']])
      assert.deepEqual(sanitizeConfig.pingDomain.args, [['address', 1234]])
    })

    it('should reject if configuration rpc address ping is unsuccessful', async () => {
      sanitizeConfig.getPort.callsFake(() => 1234)
      sanitizeConfig.pingDomain.callsFake(() => false)

      const config = {ethereum: {rpc: {address: 'address'}}}

      assertThrowsAsync(async () => { await sanitizeConfig.getAddress(config, 'rpc') })
      assert.deepEqual(sanitizeConfig.getPort.args, [[config, 'rpc']])
    })

    it('should use detected domain if no rpc address specified by configuration', async () => {
      sanitizeConfig.getPort.callsFake(() => 1234)
      sanitizeConfig.pingDomain.callsFake(() => false)
      sanitizeConfig.detectDomain.callsFake(() => 'detected domain')

      const config = {ethereum: {rpc: {address: undefined}}}

      assert.strictEqual(await sanitizeConfig.getAddress(config, 'rpc'), 'detected domain')
      assert.deepEqual(sanitizeConfig.getPort.args, [[config, 'rpc']])
      assert.deepEqual(sanitizeConfig.detectDomain.args, [[1234, config]])
    })

    it('should use localhost if domain detection rejects and localhost ping succeeds', async () => {
      sanitizeConfig.getPort.callsFake(() => 1234)
      sanitizeConfig.pingDomain.callsFake(() => true)
      sanitizeConfig.detectDomain.callsFake(() => { throw new Error('no domain detected') })

      const config = {ethereum: {rpc: {address: undefined}}}

      assert.strictEqual(await sanitizeConfig.getAddress(config, 'rpc'), 'localhost')
      assert.deepEqual(sanitizeConfig.getPort.args, [[config, 'rpc']])
      assert.deepEqual(sanitizeConfig.pingDomain.args, [['localhost', 1234]])
    })

    it('should reject if domain detection rejects and localhost ping fails', async () => {
      sanitizeConfig.getPort.callsFake(() => 1234)
      sanitizeConfig.pingDomain.callsFake(() => false)
      sanitizeConfig.detectDomain.callsFake(() => { throw new Error('no domain detected') })

      const config = {ethereum: {rpc: {address: undefined}}}

      assertThrowsAsync(async () => { await sanitizeConfig.getAddress(config, 'rpc') })
      assert.deepEqual(sanitizeConfig.getPort.args, [[config, 'rpc']])
    })
  })

  describe('sanitizeConfig.getPort', () => {
    it('should return configuration rpc port if present', async () => {
      assert.strictEqual(await sanitizeConfig.getPort({ethereum: {rpc: {port: 7357}}}, 'rpc'), 7357)
      assert.strictEqual(await sanitizeConfig.getPort({ethereum: {rpc: {port: 'port'}}}, 'rpc'), 'port')
    })

    it('should return configuration ws port if present', async () => {
      assert.strictEqual(await sanitizeConfig.getPort({ethereum: {ws: {port: 7357}}}, 'ws'), 7357)
      assert.strictEqual(await sanitizeConfig.getPort({ethereum: {ws: {port: 'port'}}}, 'ws'), 'port')
    })

    it('should return 8545 if the configuration does not specify rpc port', async () => {
      assert.deepEqual(await sanitizeConfig.getPort(undefined, 'rpc'), 8545)
      assert.deepEqual(await sanitizeConfig.getPort({}, 'rpc'), 8545)
      assert.deepEqual(await sanitizeConfig.getPort({ethereum: {}}, 'rpc'), 8545)
      assert.deepEqual(await sanitizeConfig.getPort({ethereum: {rpc: {}}}, 'rpc'), 8545)
      assert.deepEqual(await sanitizeConfig.getPort({ethereum: {rpc: {port: undefined}}}, 'rpc'), 8545)
      assert.strictEqual(await sanitizeConfig.getPort({ethereum: {ws: {port: 7357}}}, 'rpc'), 8545)
    })

    it('should return 8546 if the configuration does not specify ws port', async () => {
      assert.deepEqual(await sanitizeConfig.getPort(undefined, 'ws'), 8546)
      assert.deepEqual(await sanitizeConfig.getPort({}, 'ws'), 8546)
      assert.deepEqual(await sanitizeConfig.getPort({ethereum: {}}, 'ws'), 8546)
      assert.deepEqual(await sanitizeConfig.getPort({ethereum: {ws: {}}}, 'ws'), 8546)
      assert.deepEqual(await sanitizeConfig.getPort({ethereum: {ws: {port: undefined}}}, 'ws'), 8546)
      assert.strictEqual(await sanitizeConfig.getPort({ethereum: {rpc: {port: 7357}}}, 'ws'), 8546)
    })
  })

  describe('sanitizeConfig.getLogging', () => {
    it('should return configuration logging setting if present', async () => {
      assert.strictEqual(await sanitizeConfig.getLogging({ethereum: {logging: true}}), true)
      assert.strictEqual(await sanitizeConfig.getLogging({ethereum: {logging: false}}), false)
    })

    it('should return false if the configuration does not specify logging', async () => {
      assert.deepEqual(await sanitizeConfig.getLogging(), false)
      assert.deepEqual(await sanitizeConfig.getLogging({}), false)
      assert.deepEqual(await sanitizeConfig.getLogging({ethereum: {}}), false)
      assert.deepEqual(await sanitizeConfig.getLogging({ethereum: {logging: undefined}}), false)
    })
  })

  describe('sanitizeConfig.getContracts', () => {
    it('should return configuration contracts if present', async () => {
      assert.deepEqual(await sanitizeConfig.getContracts({ethereum: {contracts: 'contracts'}}), 'contracts')
      assert.deepEqual(await sanitizeConfig.getContracts({ethereum: {contracts: ['contractsA', 'contractsB']}}), ['contractsA', 'contractsB'])
    })

    it('should return an empty list if the configuration does not specify contracts', async () => {
      assert.deepEqual(await sanitizeConfig.getContracts(), [])
      assert.deepEqual(await sanitizeConfig.getContracts({}), [])
      assert.deepEqual(await sanitizeConfig.getContracts({ethereum: {}}), [])
      assert.deepEqual(await sanitizeConfig.getContracts({ethereum: {contracts: undefined}}), [])
    })
  })

  describe('sanitizeConfig.getAccount', () => {
    beforeEach(() => {
      sandbox.stub(sanitizeConfig, 'readJson')
    })

    afterEach(() => {
      sandbox.reset()
      sandbox.restore()
    })

    it('should return empty if omitted', async () => {
      assert.deepEqual(await sanitizeConfig.getAccount(), {})
      assert.deepEqual(await sanitizeConfig.getAccount({}), {})
      assert.deepEqual(await sanitizeConfig.getAccount({ ethereum: {}}), {})
      assert.deepEqual(await sanitizeConfig.getAccount({ ethereum: { account: {} } }), {})
    })

    it('should return address if specified as a string', async () => {
      const address = '0x931D387731bBbC988B312206c74F77D004D6B84b'
      assert.deepEqual(await sanitizeConfig.getAccount({ ethereum: { account: address }}), { address })
    })

    it('should return address if nested', async () => {
      const address = '0x931D387731bBbC988B312206c74F77D004D6B84b'
      assert.deepEqual(await sanitizeConfig.getAccount({ ethereum: { account: { address } }}), { address })
    })

    it('should return wallet and password', async () => {
      const address = 'address';
      const wallet = { address, test: 'test' }
      const password = '1234'
      assert.deepEqual(await sanitizeConfig.getAccount({ ethereum: { account: { wallet, password } }}), { address, wallet, password })
    })

    it('should return wallet and password if wallet must be loaded', async () => {
      const address = 'address';
      const wallet = { address, test: 'test' }
      const password = '1234'
      sanitizeConfig.readJson.callsFake(() => wallet)

      assert.deepEqual(await sanitizeConfig.getAccount({ ethereum: { account: { wallet: 'wallet', password } }}), { address, wallet, password })

      assert.deepEqual(sanitizeConfig.readJson.args[0][0], 'wallet');
    })
  })
})
