/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
/* jshint node:true, jasmine:true */
'use strict';

var symmetric = require('../lib/index');
var codec = require('scytl-codec');

describe('The symmetric cryptography module should be able to ...', function() {
  var data_ = codec.utf8Encode('anyString');

  var service = symmetric.newService();
  var keyGenerator = service.newKeyGenerator();
  var cipher_ = service.newCipher().init(keyGenerator.nextEncryptionKey());
  var macHandler_ = service.newMacHandler().init(keyGenerator.nextMacKey());
  var mac_ = macHandler_.generate(data_);

  var nonObject_ = 999;
  var emptyObject_ = {};
  var nonUint8Array_ = [];

  describe(
      'create a symmetric cryptography service that should be able to ..',
      function() {
        it('throw an error when being created, using an invalid cryptographic policy',
           function() {
             expect(function() {
               Object.create(symmetric.newService({policy: null}));
             }).toThrow();

             expect(function() {
               Object.create(symmetric.newService({policy: nonObject_}));
             }).toThrow();

             expect(function() {
               Object.create(symmetric.newService({policy: emptyObject_}));
             }).toThrow();
           });

        it('throw an error when being created, using an invalid secure random service object',
           function() {
             expect(function() {
               Object.create(symmetric.newService({secureRandomService: null}));
             }).toThrow();

             expect(function() {
               Object.create(
                   symmetric.newService({secureRandomService: nonObject_}));
             }).toThrow();

             expect(function() {
               Object.create(
                   symmetric.newService({secureRandomService: emptyObject_}));
             }).toThrow();
           });

        describe(
            'create a symmetric cipher that should be able to ...', function() {
              it('throw an error when being initialized, using invalid input data',
                 function() {
                   expect(function() {
                     cipher_.init();
                   }).toThrow();

                   expect(function() {
                     cipher_.init(undefined);
                   }).toThrow();

                   expect(function() {
                     cipher_.init(null);
                   }).toThrow();

                   expect(function() {
                     cipher_.init(nonUint8Array_);
                   }).toThrow();
                 });

              it('throw an error when encrypting, using invalid input data',
                 function() {
                   expect(function() {
                     cipher_.encrypt();
                   }).toThrow();

                   expect(function() {
                     cipher_.encrypt(undefined);
                   }).toThrow();

                   expect(function() {
                     cipher_.encrypt(null);
                   }).toThrow();

                   expect(function() {
                     cipher_.encrypt(nonUint8Array_);
                   }).toThrow();
                 });

              it('throw an error when decrypting, using invalid input data',
                 function() {
                   expect(function() {
                     cipher_.decrypt();
                   }).toThrow();

                   expect(function() {
                     cipher_.decrypt(undefined);
                   }).toThrow();

                   expect(function() {
                     cipher_.decrypt(null);
                   }).toThrow();

                   expect(function() {
                     cipher_.decrypt(nonUint8Array_);
                   }).toThrow();
                 });
            });

        describe('create a MAC handler that should be able to ...', function() {
          it('throw an error when being initialized, using invalid input data',
             function() {
               expect(function() {
                 macHandler_.init();
               }).toThrow();

               expect(function() {
                 macHandler_.init(undefined);
               }).toThrow();

               expect(function() {
                 macHandler_.init(null);
               }).toThrow();

               expect(function() {
                 macHandler_.init(nonUint8Array_);
               }).toThrow();
             });

          it('throw an error when generating a MAC, using invalid input data',
             function() {
               expect(function() {
                 macHandler_.generate(null);
               }).toThrow();

               expect(function() {
                 macHandler_.generate(nonUint8Array_);
               }).toThrow();
             });

          it('throw an error when verifying a MAC, using an invalid MAC',
             function() {
               expect(function() {
                 macHandler_.verify();
               }).toThrow();

               expect(function() {
                 macHandler_.verify(undefined, data_);
               }).toThrow();

               expect(function() {
                 macHandler_.verify(null, data_);
               }).toThrow();

               expect(function() {
                 macHandler_.verify(nonUint8Array_, data_);
               }).toThrow();
             });

          it('throw an error when verifying a MAC, using an invalid verification data',
             function() {
               expect(function() {
                 macHandler_.verify(mac_, null);
               }).toThrow();

               expect(function() {
                 macHandler_.verify(mac_, nonUint8Array_);
               }).toThrow();
             });

          it('throw an error when being updated, using invalid input data',
             function() {
               expect(function() {
                 macHandler_.update();
               }).toThrow();

               expect(function() {
                 macHandler_.update(undefined);
               }).toThrow();

               expect(function() {
                 macHandler_.update(null);
               }).toThrow();

               expect(function() {
                 macHandler_.update(nonUint8Array_);
               }).toThrow();
             });
        });
      });
});
