/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
 
import KeyStoreInMemory from '../../../src/crypto/keyStore/KeyStoreInMemory';
import RsaPublicKey from '../../../src/crypto/keys/rsa/RsaPublicKey';
import { KeyType } from '../../../src/crypto/keys/KeyTypeFactory';
import PublicKey from '../../../src/crypto/keys/PublicKey';
import KeyContainer from '../../../src/crypto/keys/KeyContainer';
import { OctKey } from '../../../src';

describe('KeyStoreInMemory', () => {

  it('should list all keys in the store', async () => {
    const keyStore = new KeyStoreInMemory();
    const key1: RsaPublicKey = {
      kty: KeyType.RSA,
      kid: 'kid1',
      e: 'AAEE',
      n: 'xxxxxxxxx',
      alg: 'none'
    };
    const key2: RsaPublicKey = {
      kty: KeyType.RSA,
      kid: 'kid2',
      e: 'AAEE',
      n: 'xxxxxxxxx',
      alg: 'none'
    };
    const key3: RsaPublicKey = {
      kty: KeyType.RSA,
      kid: 'kid3',
      e: 'AAEE',
      n: 'xxxxxxxxx',
      alg: 'none'
    };
    const container = new KeyContainer(key1);
    container.add(key2);
    await keyStore.save('1', container);
    await keyStore.save('2', new KeyContainer(<PublicKey>key3));
    let list = await keyStore.list();
    // tslint:disable-next-line: no-backbone-get-set-outside-model
    expect(list['1'].kids.length).toEqual(2);
    expect(list['1'].kty).toEqual(KeyType.RSA);
    expect(list['1'].kids[0]).toEqual('kid1');
    expect(list['1'].kids[1]).toEqual('kid2');
    // tslint:disable-next-line: no-backbone-get-set-outside-model
    expect(list['2'].kids.length).toEqual(1);
    expect(list['2'].kty).toEqual(KeyType.RSA);
    expect(list['2'].kids[0]).toEqual('kid3');
});

  it('should throw because an oct key does not have a public key', async () => {

    // Setup registration environment
    const jwk: any = new OctKey('AAEE');

    const keyStore = new KeyStoreInMemory();
    await keyStore.save('key', new KeyContainer(jwk));
    let throwCaught = false;
    const signature = await keyStore.get('key', true)
    .catch((err) => {
      throwCaught = true;
      expect(err.message).toBe('A secret does not has a public key');
    });
    expect(signature).toBeUndefined();
    expect(throwCaught).toBe(true);
  });

  it('should throw because the key does not exist', async () => {

  // Setup registration environment
  const jwk: any = {
    kty: 'oct',
    use: 'sig',
    k: 'AAEE'
  };

  const keyStore = new KeyStoreInMemory();
  await keyStore.save('key', jwk);
  let throwCaught = false;
  const signature = await keyStore.get('key1', true)
  .catch((err) => {
    throwCaught = true;
    expect(err).toBe('key1 not found');
  });
  expect(signature).toBeUndefined();
  expect(throwCaught).toBe(true);
  });
});
