/*
 * 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 */
'use strict';

var certificate = require('../lib/index');

describe('The certificate module should be able to ...', function() {
  var certificatePem_ =
      '-----BEGIN CERTIFICATE-----MIIEKjCCAxKgAwIBAgIQQtWFdPN4NAvUIWyyJyUlbTANBgkqhkiG9w0BAQsFADBUMRAwDgYDVQQDDAdSb290IENOMRYwFAYDVQQLDA1Sb290IE9yZyBVbml0MREwDwYDVQQKDAhSb290IE9yZzEVMBMGA1UEBhMMUm9vdCBDb3VudHJ5MB4XDTE0MDYxODEwMjMyOFoXDTE1MDYxODEwMjMyOFowVDEQMA4GA1UEAwwHUm9vdCBDTjEWMBQGA1UECwwNUm9vdCBPcmcgVW5pdDERMA8GA1UECgwIUm9vdCBPcmcxFTATBgNVBAYTDFJvb3QgQ291bnRyeTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ4AidkWId1zr4IZgItjE9uv38eB8fIGJGEts2n/XNh/EJ7NYZyBzvKSJR83v7LVJjc4pup5crWyS0B5lQ7uuD3/XZ9QpQFtnGiqlKOKH45zsw3ekaHEAco07L2dZznBuQTGLTlhrmvkCFRa8b8WYC+k90oUPvSd/9S4kA1Jlo9JDKHLer0SbjZCcVRXoLSBKmGWE0xSNfmNuZNONDRbtHvSA8A10AOtxKii9w464MXYzmPil7uM1Og1HC+FXCmkzLNfqQ31Om0jra3nLmrCpBJjRPX7svVnoxajRqpazVQnmJjjpzV7yNLwnR9W8OPwqanXcbxmTkrXMxfLxiVXDFUCAwEAAaOB9zCB9DAPBgNVHRMBAf8EBTADAQH/MDUGCCsGAQUFBwEBAQH/BCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AudGhhd3RlLmNvbTA0BgNVHR8BAf8EKjAoMCagJKAihiBodHRwOi8vY3JsLnZlcmlzaWduLmNvbS9wY2EzLmNybDArBgNVHREBAf8EITAfpB0wGzEZMBcGA1UEAwwQUHJpdmF0ZUxhYmVsMy0xNTAOBgNVHQ8BAf8EBAMCAQYwNwYDVR0lAQH/BC0wKwYIKwYBBQUHAwEGCCsGAQUFBwMCBgpghkgBhvhFAQgBBglghkgBhvhCBAEwDQYJKoZIhvcNAQELBQADggEBADmtmjApZAXIkGLaZCdkRnhel53BtEdQnG990Oo/tBBboqy2ipum9ByTj3hNWJB3zuPN77rkrek9rbookNcCgVWhHtTk1lUpUK6ZohDsZh8k0MqIhkz+X+HiWGRsEOptjsCaknyWcWb4aXAevMAQMPm/ktkpQ8AOxAq+gtieewWQZP3kGPhBBCfn8TGjdrn9+ymf8EIbAUFXQ8m+oWeNlrdWhqzRXwQbj4EDds1kZdTo0nCYUdH+XEBF9nMyhAxSQWzCKQQTRFWv1dr3dKapzfgrdH8wEgvptiBYCY62O5+3DxiNK/VWquHz6S5GqIwkmSPDPMUU/qK3SNG3xIL1U1k=-----END CERTIFICATE-----';

  var validationData_ = {
    issuer: {
      commonName: 'Test CN',
      organizationalUnit: 'Test Org Unit',
      organization: 'Test Org',
      country: 'Test Country'
    }
  };

  var nonString_ = 999;
  var emptyString_ = [];
  var nonPemString_ = 'Not a PEM string';
  var emptyObject_ = {};
  var nonTwoDimensionalArray_ = '';
  var emptyTwoDimensionalArray_ = [];

  var certificateService_;
  var certificateValidator_;

  beforeAll(function() {
    certificateService_ = certificate.newService();
    certificateValidator_ = certificateService_.newValidator();
  });

  describe('create a certificate service that should be able to ..', function() {
    it('throw an error when creating a new X509Certificate object, using invalid input data',
       function() {
         expect(function() {
           certificateService_.newX509Certificate();
         }).toThrow();

         expect(function() {
           certificateService_.newX509Certificate(undefined);
         }).toThrow();

         expect(function() {
           certificateService_.newX509Certificate(null);
         }).toThrow();

         expect(function() {
           certificateService_.newX509Certificate(nonString_);
         }).toThrow();

         expect(function() {
           certificateService_.newX509Certificate(emptyString_);
         }).toThrow();

         expect(function() {
           certificateService_.newX509Certificate(nonPemString_);
         }).toThrow();
       });

    describe(
        'create a new X509Certificate object that should be able to',
        function() {
          it('throw an error when verifying the signature of another X.509 certificate, using invalid input data',
             function() {
               var certificate =
                   certificateService_.newX509Certificate(certificatePem_);

               expect(function() {
                 certificate.verify();
               }).toThrow();

               expect(function() {
                 certificate.verify(undefined);
               }).toThrow();

               expect(function() {
                 certificate.verify(null);
               }).toThrow();

               expect(function() {
                 certificate.verify(nonString_);
               }).toThrow();

               expect(function() {
                 certificate.verify(nonPemString_);
               }).toThrow();
             });
        });

    describe(
        'create a CertificateValidator object that should be able to ..',
        function() {
          it('throw an error when validating a certificate, using an invalid certificate',
             function() {
               expect(function() {
                 certificateValidator_.validate(undefined, validationData_);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validate(null, validationData_);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validate(nonString_, validationData_);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validate(emptyString_, validationData_);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validate(nonPemString_, validationData_);
               }).toThrow();
             });

          it('throw an error when validating a certificate, using invalid validation data',
             function() {
               expect(function() {
                 certificateValidator_.validate(certificatePem_);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validate(certificatePem_, undefined);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validate(certificatePem_, null);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validate(certificatePem_, emptyObject_);
               }).toThrow();
             });

          it('throw an error when validating a certificate chain, using invalid input data',
             function() {
               expect(function() {
                 certificateValidator_.validateChain();
               }).toThrow();

               expect(function() {
                 certificateValidator_.validateChain(undefined);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validateChain(null);
               }).toThrow();

               expect(function() {
                 certificateValidator_.validateChain(emptyObject_);
               }).toThrow();
             });

          it('throw an error when flattening the failed validations of a certificate chain, using invalid input data',
             function() {
               expect(function() {
                 certificateValidator_.flattenFailedValidations();
               }).toThrow();

               expect(function() {
                 certificateValidator_.flattenFailedValidations(undefined);
               }).toThrow();

               expect(function() {
                 certificateValidator_.flattenFailedValidations(null);
               }).toThrow();

               expect(function() {
                 certificateValidator_.flattenFailedValidations(
                     nonTwoDimensionalArray_);
               }).toThrow();

               expect(function() {
                 certificateValidator_.flattenFailedValidations(
                     emptyTwoDimensionalArray_);
               }).toThrow();
             });
        });
  });
});
