'use strict'

/**
 * Test dependencies
 */
const chai = require('chai')

/**
 * Assertions
 */
chai.should()
let expect = chai.expect

/**
 * Code under test
 */
const {NotSupportedError} = require('../../src/errors')
const SupportedAlgorithms = require('../../src/algorithms/SupportedAlgorithms')

/**
 * Tests
 */
describe('SupportedAlgorithms', () => {
  describe('constructor', () => {
    it('should initialize registers', () => {
      let operations = SupportedAlgorithms.operations
      let supportedAlgorithms = new SupportedAlgorithms()
      operations.forEach(op => {
        supportedAlgorithms[op].should.eql({})
      })
    })
  })

  describe('static get operations', () => {
    it('should be an array of operations', () => {
      SupportedAlgorithms.operations.should.eql([
        'sign',
        'verify',
        'encrypt',
        'decrypt',
        'generateKey',
        'importKey'
      ])
    })
  })

  describe('define', () => {
    it('should register an algorithm for an operation', () => {
      let supportedAlgorithms = new SupportedAlgorithms()
      let argument = {}
      supportedAlgorithms.define('RS256', 'verify', argument)
      supportedAlgorithms.verify['RS256'].should.equal(argument)
    })
  })

  describe('normalize', () => {
    it('should return SyntaxError for an invalid operation', () => {
      let supportedAlgorithms = new SupportedAlgorithms()
      supportedAlgorithms.normalize('encode', 'RS256')
        .should.be.instanceof(SyntaxError)
    })

    it('should return a registered algorithm for an operation by name', () => {
      let supportedAlgorithms = new SupportedAlgorithms()
      let argument = {}
      supportedAlgorithms.define('RS256', 'verify', argument)
      supportedAlgorithms.normalize('verify', 'RS256').should.equal(argument)
    })

    it('should return NotSupportedError for unknown algorithms', () => {
      let supportedAlgorithms = new SupportedAlgorithms()
      let argument = {}

      supportedAlgorithms.normalize('verify', 'RS256')
        .should.be.instanceof(NotSupportedError)
    })
  })
})
