js: implement import/delete Key, some fixes
[gpgme.git] / lang / js / unittests.js
1 /* gpgme.js - Javascript integration for gpgme
2  * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
3  *
4  * This file is part of GPGME.
5  *
6  * GPGME is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * GPGME is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  * SPDX-License-Identifier: LGPL-2.1+
19  */
20
21 import './node_modules/mocha/mocha'; /*global mocha, it, describe*/
22 import './node_modules/chai/chai';/*global chai*/
23 import { helper_params as hp } from './unittest_inputvalues';
24 import { message_params as mp } from './unittest_inputvalues';
25 import { whatever_params as wp } from './unittest_inputvalues';
26 import { key_params as kp } from './unittest_inputvalues';
27 import { Connection } from './src/Connection';
28 import { gpgme_error } from './src/Errors';
29 import { toKeyIdArray , isFingerprint } from './src/Helpers';
30 import { GPGME_Key , createKey } from './src/Key';
31 import { GPGME_Keyring } from './src/Keyring';
32 import {GPGME_Message, createMessage} from './src/Message';
33
34 mocha.setup('bdd');
35 var expect = chai.expect;
36 chai.config.includeStack = true;
37
38 function unittests (){
39     describe('Connection testing', function(){
40
41         it('Connecting', function(done) {
42             let conn0 = new Connection;
43             conn0.checkConnection().then(function(answer) {
44                 expect(answer).to.not.be.empty;
45                 expect(answer.gpgme).to.not.be.undefined;
46                 expect(answer.gpgme).to.be.a('string');
47                 expect(answer.info).to.be.an('Array');
48                 expect(conn0.disconnect).to.be.a('function');
49                 expect(conn0.post).to.be.a('function');
50                 done();
51             });
52
53         });
54
55         it('Disconnecting', function(done) {
56             let conn0 = new Connection;
57             conn0.checkConnection(false).then(function(answer) {
58                 expect(answer).to.be.true;
59                 conn0.disconnect();
60                 conn0.checkConnection(false).then(function(result) {
61                     expect(result).to.be.false;
62                     done();
63                 });
64             });
65         });
66     });
67
68     describe('Error Object handling', function(){
69         // TODO: new GPGME_Error codes
70         it('check the Timeout error', function(){
71             let test0 = gpgme_error('CONN_TIMEOUT');
72
73             expect(test0).to.be.an.instanceof(Error);
74             expect(test0.code).to.equal('CONN_TIMEOUT');
75         });
76
77         it('Error Object returns generic code if code is not listed',
78             function(){
79                 let test0 = gpgme_error(hp.invalidErrorCode);
80
81                 expect(test0).to.be.an.instanceof(Error);
82                 expect(test0.code).to.equal('GENERIC_ERROR');
83             }
84         );
85
86         it('Warnings like PARAM_IGNORED should not return errors', function(){
87             let test0 = gpgme_error('PARAM_IGNORED');
88
89             expect(test0).to.be.null;
90         });
91     });
92
93     describe('Fingerprint checking', function(){
94
95         it('isFingerprint(): valid Fingerprint', function(){
96             let test0  = isFingerprint(hp.validFingerprint);
97
98             expect(test0).to.be.true;
99         });
100
101         it('isFingerprint(): invalid Fingerprints', function(){
102             for (let i=0; i < hp.invalidFingerprints.length; i++){
103                 let test0 = isFingerprint(hp.invalidFingerprints[i]);
104
105                 expect(test0).to.be.false;
106             }
107         });
108     });
109
110     describe('toKeyIdArray() (converting input to fingerprint)', function(){
111
112         it('Correct fingerprint string', function(){
113             let test0 = toKeyIdArray(hp.validFingerprint);
114
115             expect(test0).to.be.an('array');
116             expect(test0).to.include(hp.validFingerprint);
117         });
118
119         it('correct GPGME_Key', function(){
120             expect(hp.validGPGME_Key).to.be.an.instanceof(GPGME_Key);
121             let test0 = toKeyIdArray(hp.validGPGME_Key);
122
123             expect(test0).to.be.an('array');
124             expect(test0).to.include(hp.validGPGME_Key.fingerprint);
125         });
126
127         it('openpgpjs-like object', function(){
128             let test0 = toKeyIdArray(hp.valid_openpgplike);
129
130             expect(test0).to.be.an('array').with.lengthOf(1);
131             expect(test0).to.include(
132                 hp.valid_openpgplike.primaryKey.getFingerprint());
133         });
134
135         it('Array of valid inputs', function(){
136             let test0 = toKeyIdArray(hp.validKeys);
137             expect(test0).to.be.an('array');
138             expect(test0).to.have.lengthOf(hp.validKeys.length);
139         });
140
141         it('Incorrect inputs', function(){
142
143             it('valid Long ID', function(){
144                 let test0 = toKeyIdArray(hp.validLongId);
145
146                 expect(test0).to.be.empty;
147             });
148
149             it('invalidFingerprint', function(){
150                 let test0 = toKeyIdArray(hp.invalidFingerprint);
151
152                 expect(test0).to.be.empty;
153             });
154
155             it('invalidKeyArray', function(){
156                 let test0 = toKeyIdArray(hp.invalidKeyArray);
157
158                 expect(test0).to.be.empty;
159             });
160
161             it('Partially invalid array', function(){
162                 let test0 = toKeyIdArray(hp.invalidKeyArray_OneBad);
163
164                 expect(test0).to.be.an('array');
165                 expect(test0).to.have.lengthOf(
166                     hp.invalidKeyArray_OneBad.length - 1);
167             });
168         });
169     });
170
171     describe('GPGME_Key', function(){
172
173         it('correct Key initialization', function(){
174             let key = createKey(kp.validKeyFingerprint);
175             expect(key).to.be.an.instanceof(GPGME_Key);
176         });
177         it('Key has data after a first refresh', function(done) {
178             let key = createKey(kp.validKeyFingerprint);
179             key.refreshKey().then(function(key2){
180                 expect(key2).to.be.an.instanceof(GPGME_Key);
181                 expect(key2.get).to.be.a('function');
182                 for (let i=0; i < kp.validKeyProperties.length; i++) {
183                     let prop = key2.get(kp.validKeyProperties[i]);
184                     expect(prop).to.not.be.undefined;
185                     expect(prop).to.be.a('boolean');
186                 }
187                 expect(isFingerprint(key2.get('fingerprint'))).to.be.true;
188                 expect(
189                     key2.get('fingerprint')).to.equal(kp.validKeyFingerprint);
190                 expect(
191                     key2.get('fingerprint')).to.equal(key.fingerprint);
192                 done();
193             });
194         });
195
196         it('Non-cached key async data retrieval', function (done){
197             let key = createKey(kp.validKeyFingerprint);
198             key.get('can_authenticate',false).then(function(result){
199                 expect(result).to.be.a('boolean');
200                 done();
201             });
202         });
203
204         it('Non-cached key async armored Key', function (done){
205             let key = createKey(kp.validKeyFingerprint);
206             key.get('armored', false).then(function(result){
207                 expect(result).to.be.a('string');
208                 expect(result).to.include('KEY BLOCK-----');
209                 done();
210             });
211         });
212
213         it('Non-cached key async hasSecret', function (done){
214             let key = createKey(kp.validKeyFingerprint);
215             key.get('hasSecret', false).then(function(result){
216                 expect(result).to.be.a('boolean');
217                 done();
218             });
219         });
220
221         it('Non-cached key async hasSecret (no secret in Key)', function (done){
222             let key = createKey(kp.validFingerprintNoSecret);
223             expect(key).to.be.an.instanceof(GPGME_Key);
224             key.get('hasSecret', false).then(function(result){
225                 expect(result).to.be.a('boolean');
226                 expect(result).to.equal(false);
227                 done();
228             });
229         });
230
231         it('Querying non-existing Key returns an error', function(done) {
232             let key = createKey(kp.invalidKeyFingerprint);
233             key.refreshKey().then(function(){},
234                 function(error){
235                     expect(error).to.be.an.instanceof(Error);
236                     expect(error.code).to.equal('KEY_NOKEY');
237                     done();
238                 });
239         });
240
241         it('createKey returns error if parameters are wrong', function(){
242             for (let i=0; i< 4; i++){
243                 let key0 = createKey(wp.four_invalid_params[i]);
244                 expect(key0).to.be.an.instanceof(Error);
245                 expect(key0.code).to.equal('PARAM_WRONG');
246             }
247         });
248
249         it('malformed GPGME_Key cannot be used', function(){
250             for (let i=0; i < 4; i++){
251                 let key = new GPGME_Key(wp.four_invalid_params[i]);
252                 expect(key.fingerprint).to.be.an.instanceof(Error);
253                 expect(key.fingerprint.code).to.equal('KEY_INVALID');
254             }
255         });
256         // TODO: tests for subkeys
257         // TODO: tests for userids
258         // TODO: some invalid tests for key/keyring
259     });
260
261     describe('GPGME_Keyring', function(){
262
263         it('correct Keyring initialization', function(){
264             let keyring = new GPGME_Keyring;
265             expect(keyring).to.be.an.instanceof(GPGME_Keyring);
266             expect(keyring.getKeys).to.be.a('function');
267         });
268
269         it('Loading Keys from Keyring, to be used synchronously', function(done){
270             let keyring = new GPGME_Keyring;
271             keyring.getKeys(null, true).then(function(result){
272                 expect(result).to.be.an('array');
273                 expect(result[0]).to.be.an.instanceof(GPGME_Key);
274                 expect(result[0].get('armored')).to.be.a('string');
275                 expect(result[0].get('armored')).to.include(
276                     '-----END PGP PUBLIC KEY BLOCK-----');
277                 done();
278             });
279         });
280
281         it('Loading specific Key from Keyring, to be used synchronously', function(done){
282             let keyring = new GPGME_Keyring;
283             keyring.getKeys(kp.validKeyFingerprint, true).then(function(result){
284                 expect(result).to.be.an('array');
285                 expect(result[0]).to.be.an.instanceof(GPGME_Key);
286                 expect(result[0].get('armored')).to.be.a('string');
287                 expect(result[0].get('armored')).to.include(
288                     '-----END PGP PUBLIC KEY BLOCK-----');
289                 done();
290             });
291         });
292
293         it('Querying non-existing Key from Keyring', function(done){
294             let keyring = new GPGME_Keyring;
295             keyring.getKeys(kp.invalidKeyFingerprint, true).then(function(result){
296                 expect(result).to.be.an('array');
297                 expect(result.length).to.equal(0);
298                 done();
299             });
300         });
301     });
302
303     // describe('Keyring import/export', function(){
304     //     before(function(done) {
305     //         let keyring = new GPGME_Keyring;
306
307     //         keyring.getKeys(ak.fingerprint, false).then(function(result){
308     //             if (result.length === 1){
309     //                 result[0].delete().then(function(delete_result){
310     //                     if (delete_result === true){
311     //                         done();
312     //                     }
313     //                 });
314     //             } else {
315     //                 done();
316     //             }
317     //         });
318     //     });
319     //     it('Import Public Key', function(done){
320     //         keyring.importKey(ak.key).then(function(result){
321     //             expect(result).to.be.an('array');
322     //             expect(result[0].key).to.be.an.instanceof(GPGME_Key);
323     //             expect(result[0].changed).to.equal('newkey');
324     //             expect(result[0].key.keyring).to.equal(ak.fingerprint);
325     //             done();
326     //         });
327     //     });
328
329     //     it('Update Public Key', function(done){
330     //         keyring.importKey(ak.key).then(function(result){
331     //             expect(result).to.be.an('array');
332     //             expect(result[0].key).to.be.an.instanceof(GPGME_Key);
333     //             expect(result[0].changed).to.equal('change');
334     //             expect(result[0].changes.userId).to.be.true;
335     //             expect(result[0].changes.subkeys).to.be.false;
336     //             expect(result[0].key.keyring).to.equal(ak.fingerprint);
337     //             done();
338     //         });
339     //     });
340     // });
341
342     describe('GPGME_Message', function(){
343
344         it('creating encrypt Message', function(){
345             let test0 = createMessage('encrypt');
346
347             expect(test0).to.be.an.instanceof(GPGME_Message);
348             expect(test0.isComplete).to.be.false;
349         });
350
351         it('Message is complete after setting mandatory data', function(){
352             let test0 = createMessage('encrypt');
353             test0.setParameter('data', mp.valid_encrypt_data);
354             test0.setParameter('keys', hp.validFingerprints);
355
356             expect(test0.isComplete).to.be.true;
357         });
358
359         it('Message is not complete after mandatory data is empty', function(){
360             let test0 = createMessage('encrypt');
361             test0.setParameter('data', '');
362             test0.setParameter('keys', hp.validFingerprints);
363             expect(test0.isComplete).to.be.false;
364         });
365
366         it('Complete Message contains the data that was set', function(){
367             let test0 = createMessage('encrypt');
368             test0.setParameter('data', mp.valid_encrypt_data);
369             test0.setParameter('keys', hp.validFingerprints);
370
371             expect(test0.message).to.not.be.null;
372             expect(test0.message).to.have.keys('op', 'data', 'keys');
373             expect(test0.message.op).to.equal('encrypt');
374             expect(test0.message.data).to.equal(
375                 mp.valid_encrypt_data);
376         });
377
378         it ('Not accepting non-allowed operation', function(){
379             let test0 = createMessage(mp.invalid_op_action);
380
381             expect(test0).to.be.an.instanceof(Error);
382             expect(test0.code).to.equal('MSG_WRONG_OP');
383         });
384         it('Not accepting wrong parameter type', function(){
385             let test0 = createMessage(mp.invalid_op_type);
386
387             expect(test0).to.be.an.instanceof(Error);
388             expect(test0.code).to.equal('PARAM_WRONG');
389         });
390
391         it('Not accepting wrong parameter name', function(){
392             let test0 = createMessage(mp.invalid_param_test.valid_op);
393             for (let i=0;
394                 i < mp.invalid_param_test.invalid_param_names.length; i++){
395                 let ret = test0.setParameter(
396                     mp.invalid_param_test.invalid_param_names[i],
397                     'Somevalue');
398
399                 expect(ret).to.be.an.instanceof(Error);
400                 expect(ret.code).to.equal('PARAM_WRONG');
401             }
402         });
403
404         it('Not accepting wrong parameter value', function(){
405             let test0 = createMessage(mp.invalid_param_test.valid_op);
406             for (let j=0;
407                 j < mp.invalid_param_test.invalid_values_0.length; j++){
408                 let ret = test0.setParameter(
409                     mp.invalid_param_test.validparam_name_0,
410                     mp.invalid_param_test.invalid_values_0[j]);
411
412                 expect(ret).to.be.an.instanceof(Error);
413                 expect(ret.code).to.equal('PARAM_WRONG');
414             }
415         });
416     });
417
418 }
419
420 export default {unittests};