js: more testing
authorMaximilian Krambach <maximilian.krambach@intevation.de>
Fri, 27 Apr 2018 18:03:09 +0000 (20:03 +0200)
committerMaximilian Krambach <maximilian.krambach@intevation.de>
Fri, 27 Apr 2018 18:03:09 +0000 (20:03 +0200)
--

* Tests: initialization of the two modes, encryption

* gpgme.js: reintroduced message check before calling
  Connection.post()

* gpgmejs_openpgp.js: Fixed openpgp mode not passing keys

* index.js: fixed some confusion in parseconfig()

* Inserted some TODO stubs for missing error handling

16 files changed:
lang/js/BrowserTestExtension/tests/encryptTest.js [new file with mode: 0644]
lang/js/BrowserTestExtension/tests/inputvalues.js
lang/js/BrowserTestExtension/tests/startup.js
lang/js/build_extensions.sh
lang/js/src/Connection.js
lang/js/src/Key.js
lang/js/src/Keyring.js
lang/js/src/Message.js
lang/js/src/gpgmejs.js
lang/js/src/gpgmejs_openpgpjs.js
lang/js/src/index.js
lang/js/src/permittedOperations.js
lang/js/test/Helpers.js
lang/js/test/Message.js
lang/js/test/index.js [new file with mode: 0644]
lang/js/test/inputvalues.js

diff --git a/lang/js/BrowserTestExtension/tests/encryptTest.js b/lang/js/BrowserTestExtension/tests/encryptTest.js
new file mode 100644 (file)
index 0000000..e600000
--- /dev/null
@@ -0,0 +1,71 @@
+/* gpgme.js - Javascript integration for gpgme
+ * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+describe('Encryption', function(){
+
+    it('Successfull encrypt', function(done){
+        let prm = Gpgmejs.init();
+        prm.then(function(context){
+            context.encrypt(
+            inputvalues.encrypt.good.data,
+            inputvalues.encrypt.good.fingerprint).then(function(answer){
+                    expect(answer).to.not.be.empty;
+                    expect(answer.data).to.be.a("string");
+                    expect(answer.data).to.include('BEGIN PGP MESSAGE');
+                    expect(answer.data).to.include('END PGP MESSAGE');
+                    done();
+                }, function(err){
+                    expect(err).to.be.undefined;
+                    done();
+                });
+        });
+    });
+
+    it('Sending encryption without keys fails', function(){
+        let prm = Gpgmejs.init();
+        prm.then(function(context){
+            context.encrypt(
+                inputvalues.encrypt.good.data,
+                null).then(function(answer){
+                    expect(answer).to.be.undefined;
+                    done();
+                }, function(error){
+                    expect(error).to.be.an('Error');
+                    expect(error.code).to.equal('MSG_INCOMPLETE');
+                    done()
+                });
+        });
+    });
+
+    it('Sending encryption without data fails', function(){
+        let prm = Gpgmejs.init();
+        prm.then(function(context){
+            context.encrypt(
+                null,inputvalues.encrypt.good.keyid).then(function(answer){
+                    expect(answer).to.be.undefined;
+                }, function(error){
+                    expect(error).to.be.an.instanceof(Error);
+                    expect(error.code).to.equal('MSG_INCOMPLETE');
+                    done();
+                });
+        });
+    });
+
+    // TODO check different valid parameter
+});
index 47600c8..1761c82 100644 (file)
@@ -22,7 +22,11 @@ var inputvalues = {
     encrypt: {
         good:{
             data : 'Hello World.',
-            keyid : 'CDC3A2B2860625CCBFC5A5A9FC6D1B604967FC40'
+            fingerprint : 'CDC3A2B2860625CCBFC5A5A9FC6D1B604967FC40'
         }
+    },
+    init: {
+        invalid_startups: [{all_passwords: true}, 'openpgpmode', {api_style:"frankenstein"}]
     }
+
 };
index 14d12c0..a5614a8 100644 (file)
 
  describe('GPGME context', function(){
     it('Starting a GpgME instance', function(done){
-        Gpgmejs.init().then(
+        let prm = Gpgmejs.init();
+        prm.then(
          function(context){
-             expect(context.connection).to.not.be.undefined;
-             expect(context).to.be.an('object');
-             expect(context.connection).to.be.an('object');
-             expect(context.Keyring).to.be.undefined;
-             expect(context.encrypt).to.be.a('function');
-             expect(context.decrypt).to.be.a('function');
-         done();
-        }, function(err){
-        done(err);
+            expect(context.connection).to.not.be.undefined;
+            expect(context).to.be.an('object');
+            expect(context.connection).to.be.an('object');
+            expect(context.Keyring).to.be.undefined;
+            expect(context.encrypt).to.be.a('function');
+            expect(context.decrypt).to.be.a('function');
+            done();
+        }, function(errorr){
+             expect(error).to.be.undefined;
+             done();
         });
     });
-    it('Starting an openpgp mode GPGME instance', function(done){
-        Gpgmejs.init({api_style:"gpgme_openpgpjs"}).then(
-         function(context){
-             console.log(context);
-             done();
-        //      expect(context).to.be.an('object');
-        //      expect(context.connection).to.be.undefined;
-        //      expect(context.Keyring).to.be.an('object');
-        //      expect(context.encrypt).to.be.a('function');
-        //      expect(context.decrypt).to.be.a('function');
-        //  done();
-        }, function(err){
-        done(err);
+});
+describe('openpgp mode', function(){
+    it('startup of openpgp mode returns the correct parameters', function(done){
+        let prm = Gpgmejs.init({api_style:"gpgme_openpgpjs"});
+        prm.then(function(context){
+            expect(context).to.be.an('object');
+            expect(context.connection).to.be.undefined;
+            expect(context.Keyring).to.be.an('object');
+            expect(context.encrypt).to.be.a('function');
+            expect(context.decrypt).to.be.a('function');
+            done();
+        }, function(error){
+            expect(error).to.be.undefined;
+            done();
         });
     });
- });
+});
+
+describe('GPGME does not start with invalid parameters', function(){
+    for (let i=0; i < inputvalues.init.invalid_startups.length; i++){
+        it('Parameter '+ i, function(done){
+        let prm = Gpgmejs.init(inputvalues.init.invalid_startups[i]);
+            prm.then(function(context){
+                expect(context).to.be.undefined;
+                done();
+            }, function(error){
+                expect(error).to.be.an.instanceof(Error);
+                expect(error.code).to.equal('PARAM_WRONG');
+                done();
+            });
+        })
+    }
+});
\ No newline at end of file
index be7b058..b99a362 100755 (executable)
@@ -6,6 +6,7 @@ cp node_modules/chai/chai.js \
     node_modules/mocha/mocha.css \
     node_modules/mocha/mocha.js \
     build/gpgmejs.bundle.js BrowserTestExtension/libs
+rm -rf build/extensions
 mkdir -p build/extensions
 zip -r build/extensions/browsertest.zip BrowserTestExtension
 
index a10f9d9..a198bdc 100644 (file)
@@ -100,9 +100,7 @@ export class Connection{
                     reject(gpgme_error('CONN_EMPTY_GPG_ANSWER'));
                 } else if (msg.type === "error"){
                     me._connection.onMessage.removeListener(listener)
-                    reject(
-                        {code: 'GNUPG_ERROR',
-                         msg: msg.msg} );
+                    reject(gpgme_error('GNUPG_ERROR', msg.msg));
                 } else {
                     let answer_result = answer.add(msg);
                     if (answer_result !== true){
@@ -129,6 +127,8 @@ export class Connection{
                         }, 5000);
                     }]).then(function(result){
                     return result;
+                }, function(error){
+                    return error;
                 });
             }
         });
index 0b44b24..30449d6 100644 (file)
@@ -51,10 +51,7 @@ export class GPGME_Key {
      * hasSecret returns true if a secret subkey is included in this Key
      */
     get hasSecret(){
-        checkKey(this._fingerprint, 'secret').then( function(result){
-            return Promise.resolve(result);
-        });
-
+        return checkKey(this._fingerprint, 'secret');
     }
 
     get isRevoked(){
@@ -130,6 +127,8 @@ export class GPGME_Key {
                 }
             }
             return Promise.resolve(resultset);
+        }, function(error){
+            //TODO checkKey fails
         });
     }
 
@@ -175,8 +174,7 @@ export class GPGME_Key {
  */
 function checkKey(fingerprint, property){
     return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
-    if (!property ||
-        permittedOperations[keyinfo].indexOf(property) < 0){
+    if (!property || !permittedOperations[keyinfo].hasOwnProperty(property)){
             return Promise.reject(gpgme_error('PARAM_WRONG'));
     }
     return new Promise(function(resolve, reject){
@@ -188,19 +186,20 @@ function checkKey(fingerprint, property){
             reject(gpgme_error('PARAM_WRONG'));
         }
         msg.setParameter('fingerprint', this.fingerprint);
-        return (this.connection.post(msg)).then(function(result){
-            if (result.hasOwnProperty(property)){
+        return (this.connection.post(msg)).then(function(result, error){
+            if (error){
+                reject(gpgme_error('GNUPG_ERROR',error.msg));
+            } else if (result.hasOwnProperty(property)){
                 resolve(result[property]);
             }
             else if (property == 'secret'){
-                // TBD property undefined means "not true" in case of secret?
-                resolve(false);
+                    // TBD property undefined means "not true" in case of secret?
+                    resolve(false);
             } else {
                 reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
             }
         }, function(error){
-            reject({code: 'GNUPG_ERROR',
-                         msg: error.msg});
+            //TODO error handling
         });
     });
 };
\ No newline at end of file
index 364bfb4..d1f4122 100644 (file)
@@ -78,6 +78,8 @@ export class GPGME_Keyring {
                 }
             }
             return Promise.resolve(resultset);
+        }, function(error){
+            //TODO error handling
         });
     }
 
@@ -151,6 +153,8 @@ export class GPGME_Keyring {
                 }
             }
             return Promise.resolve(resultset);
+        }, function(error){
+            //TODO error handling
         });
     }
 
index 95d043b..c42480f 100644 (file)
@@ -73,11 +73,60 @@ export class GPGME_Message {
         if (!po){
             return gpgme_error('MSG_WRONG_OP');
         }
-        if (po.required.indexOf(param) >= 0 || po.optional.indexOf(param) >= 0){
-            this._msg[param] = value;
-            return true;
+        let poparam = null;
+        if (po.required.hasOwnProperty(param)){
+            poparam = po.required[param];
+        } else if (po.optional.hasOwnProperty(param)){
+            poparam = po.optional[param];
+        } else {
+            return gpgme_error('PARAM_WRONG');
         }
-        return gpgme_error('PARAM_WRONG');
+        let checktype = function(val){
+            switch(typeof(val)){
+                case 'string':
+                case 'number':
+                case 'boolean':
+                    if (poparam.allowed.indexOf(typeof(val)) >= 0){
+                        return true;
+                    }
+                    return gpgme_error('PARAM_WRONG');
+                    break;
+                case 'object':
+                    if (Array.isArray(val)){
+                        if (poparam.array_allowed !== true){
+                            return gpgme_error('PARAM_WRONG');
+                        }
+                        for (let i=0; i < val.length; i++){
+                            let res = checktype(val[i]);
+                            if (res !== true){
+                                return res;
+                            }
+                        }
+                        return true;
+                    } else if (val instanceof Uint8Array){
+                        if (poparam.allowed.indexOf('Uint8Array') >= 0){
+                            return true;
+                        }
+                        return gpgme_error('PARAM_WRONG');
+                    } else {
+                        return gpgme_error('PARAM_WRONG');
+                    }
+                    break;
+                default:
+                    return gpgme_error('PARAM_WRONG');
+            }
+        };
+        let typechecked = checktype(value);
+        if (typechecked !== true){
+            return typechecked;
+        }
+        if (poparam.hasOwnProperty('allowed_data')){
+            if (poparam.allowed_data.indexOf(value) < 0){
+                return gpgme_error('PARAM_WRONG');
+            }
+        }
+        this._msg[param] = value;
+        return true;
     }
 
     /**
@@ -89,11 +138,12 @@ export class GPGME_Message {
         if (!this._msg.op){
             return false;
         }
-        let reqParams = permittedOperations[this._msg.op].required;
+        let reqParams = Object.keys(
+            permittedOperations[this._msg.op].required);
+        let msg_params = Object.keys(this._msg);
         for (let i=0; i < reqParams.length; i++){
-
-            if (!this._msg.hasOwnProperty(reqParams[i])){
-                console.log(reqParams[i] + 'missing');
+            if (msg_params.indexOf(reqParams[i]) < 0){
+                console.log(reqParams[i] + ' missing');
                 return false;
             }
         }
index 2ddf296..9475b2b 100644 (file)
@@ -33,25 +33,24 @@ export class GpgME {
         this.connection = connection;
     }
 
-    set connection(connection){
+    set connection(conn){
         if (this._connection instanceof Connection){
             gpgme_error('CONN_ALREADY_CONNECTED');
-        }
-        if (connection instanceof Connection){
-            this._connection = connection;
+        } else if (conn instanceof Connection){
+            this._connection = conn;
         } else {
             gpgme_error('PARAM_WRONG');
         }
     }
 
     get connection(){
-        if (this._connection instanceof Connection){
-            if (this._connection.isConnected){
+        if (this._connection){
+            if (this._connection.isConnected === true){
                 return this._connection;
             }
-            return undefined; //TODO: connection was lost!
+            return undefined;
         }
-        return undefined; //TODO: no connection there
+        return undefined;
     }
 
     set Keyring(keyring){
@@ -85,8 +84,11 @@ export class GpgME {
         putData(msg, data);
         if (wildcard === true){msg.setParameter('throw-keyids', true);
         };
-
-        return (this.connection.post(msg));
+        if (msg.isComplete === true){
+            return this.connection.post(msg);
+        } else {
+            return Promise.reject(gpgme_error('MSG_INCOMPLETE'));
+        }
     }
 
     /**
@@ -133,20 +135,24 @@ export class GpgME {
             msg.setParameter('delete_force', true);
             // TBD
         }
-        this.connection.post(msg).then(function(success){
-            // TODO: it seems that there is always errors coming back:
-        }, function(error){
-            switch (error.msg){
-            case 'ERR_NO_ERROR':
-                return Promise.resolve('okay'); //TBD
-            default:
-                return Promise.reject(gpgme_error('TODO') ); //
-                // INV_VALUE,
-                // GPG_ERR_NO_PUBKEY,
-                // GPG_ERR_AMBIGUOUS_NAME,
-                // GPG_ERR_CONFLICT
-            }
-        });
+        if (msg.isComplete === true){
+            this.connection.post(msg).then(function(success){
+                // TODO: it seems that there is always errors coming back:
+            }, function(error){
+                switch (error.msg){
+                case 'ERR_NO_ERROR':
+                    return Promise.resolve('okay'); //TBD
+                default:
+                    return Promise.reject(gpgme_error('TODO') ); //
+                    // INV_VALUE,
+                    // GPG_ERR_NO_PUBKEY,
+                    // GPG_ERR_AMBIGUOUS_NAME,
+                    // GPG_ERR_CONFLICT
+                }
+            });
+        } else {
+            return Promise.reject(gpgme_error('MSG_INCOMPLETE'));
+        }
     }
 }
 
@@ -162,7 +168,7 @@ function putData(message, data){
         return gpgme_error('PARAM_WRONG');
     }
     if (!data){
-        message.setParameter('data', '');
+        return gpgme_error('PARAM_WRONG');
     } else if (data instanceof Uint8Array){
         let decoder = new TextDecoder('utf8');
         message.setParameter('base64', true);
index cc2afde..c80d5a8 100644 (file)
                 return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED'));
             }
         }
-        return this._GpgME.encrypt(data, translateKeyInput(publicKeys), wildcard);
+        return this._GpgME.encrypt(data, translateKeys(publicKeys), wildcard);
     }
 
     /** Decrypt Message
@@ -201,6 +201,8 @@ class GPGME_Keyring_openpgpmode {
                 // TODO: Can there be several default keys?
                 return gpgme_error('TODO');
             }
+        }, function(error){
+            //TODO
         });
     }
 
@@ -264,6 +266,9 @@ class GPGME_Key_openpgpmode {
  * creates GPGME_Key_openpgpmode from GPGME_Keys
  */
 function translateKeys(input){
+    if (!input){
+        return null;
+    }
     if (!Array.isArray(input)){
         input = [input];
     }
index 4de9845..90fe99e 100644 (file)
@@ -53,18 +53,17 @@ function init(config){
     });
 }
 
-function parseconfiguration(config){
-    if (!config){
-        return defaultConf;
-    }
-    if ( typeof(config) !== 'object'){
+function parseconfiguration(rawconfig = {}){
+    if ( typeof(rawconfig) !== 'object'){
         return gpgme_error('PARAM_WRONG');
     };
-    let result_config = defaultConf;
-    let conf_keys = Object.keys(config);
-    for (let i=0; i < conf_keys; i++){
+    let result_config = {};
+    let conf_keys = Object.keys(rawconfig);
+
+    for (let i=0; i < conf_keys.length; i++){
+
         if (availableConf.hasOwnProperty(conf_keys[i])){
-            let value = config[conf_keys[i]];
+            let value = rawconfig[conf_keys[i]];
             if (availableConf[conf_keys[i]].indexOf(value) < 0){
                 return gpgme_error('PARAM_WRONG');
             } else {
@@ -75,6 +74,12 @@ function parseconfiguration(config){
             return gpgme_error('PARAM_WRONG');
         }
     }
+    let default_keys = Object.keys(defaultConf);
+    for (let j=0; j < default_keys.length; j++){
+        if (!result_config.hasOwnProperty(default_keys[j])){
+            result_config[default_keys[j]] = defaultConf[default_keys[j]];
+        }
+    }
     return result_config;
 };
 
index 79e7422..274e037 100644 (file)
  /**
   * Definition of the possible interactions with gpgme-json.
   * operation: <Object>
-      required: Array<String>
-      optional: Array<String>
-      pinentry: Boolean If a pinentry dialog is expected, and a timeout of
+      required: Array<Object>
+            <String> name The name of the property
+            allowed: Array of allowed types. Currently accepted values:
+                ['number', 'string', 'boolean', 'Uint8Array']
+            array_allowed: Boolean. If the value can be an array of the above
+            allowed_data: <Array> If present, restricts to the given value
+      optional: Array<Object>
+            see 'required', with these parameters not being mandatory for a
+            complete message
+      pinentry: boolean If a pinentry dialog is expected, and a timeout of
                 5000 ms would be too short
       answer: <Object>
           type: <String< The content type of answer expected
 
 export const permittedOperations = {
     encrypt: {
-        required: ['keys', 'data'],
-        optional: [
-            'protocol',
-            'chunksize',
-            'base64',
-            'mime',
-            'armor',
-            'always-trust',
-            'no-encrypt-to',
-            'no-compress',
-            'throw-keyids',
-            'want-address',
-            'wrap'
-        ],
+        required: {
+            'keys': {
+                allowed: ['string'],
+                array_allowed: true
+            },
+            'data': {
+                allowed: ['string', 'Uint8Array']
+            }
+        },
+        optional: {
+            'protocol': {
+                allowed: ['string'],
+                allowed_data: ['cms', 'openpgp']
+            },
+                'chunksize': {
+                    allowed: ['number']
+                },
+                'base64': {
+                    allowed: ['boolean']
+                },
+                'mime': {
+                    allowed: ['boolean']
+                },
+                'armor': {
+                    allowed: ['boolean']
+                },
+                'always-trust': {
+                    allowed: ['boolean']
+                },
+                'no-encrypt-to': {
+                    allowed: ['string'],
+                    array_allowed: true
+                },
+                'no-compress': {
+                    allowed: ['boolean']
+                },
+                'throw-keyids': {
+                    allowed: ['boolean']
+                },
+                'want-address': {
+                    allowed: ['boolean']
+                },
+                'wrap': {
+                    allowed: ['boolean']
+                },
+            },
         answer: {
             type: ['ciphertext'],
             data: ['data'],
@@ -62,18 +101,29 @@ export const permittedOperations = {
 
     decrypt: {
         pinentry: true,
-        required: ['data'],
-        optional: [
-            'protocol',
-            'chunksize',
-            'base64'
-        ],
+        required: {
+            'data': {
+                allowed: ['string', 'Uint8Array']
+            }
+        },
+        optional: {
+            'protocol': {
+                allowed: ['string'],
+                allowed_data: ['cms', 'openpgp']
+            },
+            'chunksize': {
+                allowed: ['number'],
+            },
+            'base64': {
+                allowed: ['boolean']
+            }
+        },
         answer: {
             type: ['plaintext'],
             data: ['data'],
             params: ['base64', 'mime'],
             infos: [] // pending. Info about signatures and validity
-                    //signature: [{Key Fingerprint, valid Boolean}]
+                    //signature: [{Key Fingerprint, valid boolean}]
         }
     },
     /**
index 5d8909f..6b5a538 100644 (file)
@@ -24,7 +24,7 @@ import { GPGME_Key } from "../src/Key";
 import { isLongId, isFingerprint, toKeyIdArray } from "../src/Helpers"
 import { helper_params } from "./inputvalues";
 
-function Helpertest(){
+export function Helpertest(){
     describe('Error Object handling', function(){
         it('check the Timeout error', function(){
             let test0 = gpgme_error('CONN_TIMEOUT');
index 44206fb..a7dd3af 100644 (file)
 import { expect } from "../node_modules/chai/chai";
 import { GPGME_Message, createMessage } from "../src/Message";
 
-import { message_params } from "./inputvalues";
+import { message_params as mp, helper_params as hp} from "./inputvalues";
 
-function Messagetest(){
+export function Messagetest(){
 
     describe('Message Object', function(){
-        describe('incorrect initialization', function(){
+        describe('correct initialization of an encrypt Message', function(){
+            it('creating Message', function(){
+                let test0 = createMessage('encrypt');
+                expect(test0).to.be.an.instanceof(GPGME_Message);
+                expect(test0.isComplete).to.be.false;
+            });
+            it('Message is complete after setting mandatoy data', function(){
+                let test0 = createMessage('encrypt');
+                test0.setParameter('data', mp.valid_encrypt_data);
+                test0.setParameter('keys', hp.validFingerprints);
+                expect(test0.isComplete).to.be.true;
+            });
+            it('Complete Message contains the data that was set', function(){
+                let test0 = createMessage('encrypt');
+                test0.setParameter('data', mp.valid_encrypt_data);
+                test0.setParameter('keys', hp.validFingerprints);
+
+                expect(test0.message).to.not.be.null;
+                expect(test0.message).to.have.keys('op', 'data', 'keys');
+                expect(test0.message.op).to.equal('encrypt');
+                expect(test0.message.data).to.equal(
+                    mp.valid_encrypt_data);
+            });
+        });
+
+        describe('Incorrect initialization', function(){
             it('non-allowed operation', function(){
-                let test0 = createMessage(message_params.invalid_op_action);
+                let test0 = createMessage(mp.invalid_op_action);
                 expect(test0).to.be.an.instanceof(Error);
                 expect(test0.code).to.equal('MSG_WRONG_OP');
             });
             it('wrong parameter type in constructor', function(){
-                let test0 = createMessage(message_params.invalid_op_type);
+                let test0 = createMessage(mp.invalid_op_type);
                 expect(test0).to.be.an.instanceof(Error);
                 expect(test0.code).to.equal('PARAM_WRONG');
             });
         });
+
+        describe('Setting wrong parameters', function(){
+            it('Wrong parameter name', function(){
+                let test0 = createMessage(mp.invalid_param_test.valid_op);
+                for (let i=0; i < mp.invalid_param_test.invalid_param_names.length; i++){
+                    let ret = test0.setParameter(
+                        mp.invalid_param_test.invalid_param_names[i],
+                        'Somevalue');
+                    expect(ret).to.be.an.instanceof(Error);
+                    expect(ret.code).to.equal('PARAM_WRONG');
+                }
+            });
+            it('Wrong parameter value', function(){
+                let test0 = createMessage(mp.invalid_param_test.valid_op);
+                for (let j=0;
+                    j < mp.invalid_param_test.invalid_values_0.length;
+                    j++){
+                        let ret = test0.setParameter(
+                            mp.invalid_param_test.validparam_name_0,
+                            mp.invalid_param_test.invalid_values_0[j]);
+                        expect(ret).to.be.an.instanceof(Error);
+                        expect(ret.code).to.equal('PARAM_WRONG');
+                }
+            });
+        });
     });
-};
+}
 export default Messagetest;
\ No newline at end of file
diff --git a/lang/js/test/index.js b/lang/js/test/index.js
new file mode 100644 (file)
index 0000000..b852051
--- /dev/null
@@ -0,0 +1,28 @@
+/* gpgme.js - Javascript integration for gpgme
+ * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+import { Helpertest } from "./Helpers";
+import { Messagetest } from "./Message";
+
+/**
+ * Unit tests.
+ */
+
+Helpertest();
+Messagetest();
index a50c816..f6cd75a 100644 (file)
@@ -8,6 +8,8 @@ export const helper_params = {
         'ADDBC303B6D31026F5EB4591A27EABDF283121BB',
         new GPGME_Key('EE17AEE730F88F1DE7713C54BBE0A4FF7851650A')],
     validFingerprint: '9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A',
+    validFingerprints: ['9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A',
+        '9AAE7A338A9A9A7A7A8A9A9A7A7A8A9A9A7A7DDA'],
     invalidLongId: '9A9A7A7A8A9A9A7A7A8A',
     invalidFingerprint: [{hello:'World'}],
     invalidKeyArray: {curiosity:'uncat'},
@@ -21,8 +23,16 @@ export const helper_params = {
 export const message_params = {
     invalid_op_action : 'dance',
     invalid_op_type : [234, 34, '<>'],
+    valid_encrypt_data: "مرحبا بالعالم",
+    invalid_param_test: {
+        valid_op: 'encrypt',
+        invalid_param_names: [22,'dance', {}],
+        validparam_name_0: 'mime',
+        invalid_values_0: [2134, 'All your passwords', new GPGME_Key('12AE9F3E41B33BF77DF52B6BE8EE1992D7909B08'), null]
+    }
 }
 
+
 export default {
     helper_params: helper_params,
     message_params: message_params