import { Credentials } from '../src';

describe('Credentials', () => {

    describe('without nodeType set', () => {

        test('should be able to set and read key data without initial data set', () => {

            const credentials = new Credentials('testName', 'testType', []);

            const key = 'key1';
            const password = 'password';
            // const nodeType = 'base.noOp';
            const newData = 1234;

            credentials.setDataKey(key, newData, password);

            expect(credentials.getDataKey(key, password)).toEqual(newData);
        });

        test('should be able to set and read key data with initial data set', () => {

            const key = 'key2';
            const password = 'password';

            // Saved under "key1"
            const initialData = 4321;
            const initialDataEncoded = 'U2FsdGVkX1+0baznXt+Ag/ub8A2kHLyoLxn/rR9h4XQ=';

            const credentials = new Credentials('testName', 'testType', [], initialDataEncoded);

            const newData = 1234;

            // Set and read new data
            credentials.setDataKey(key, newData, password);
            expect(credentials.getDataKey(key, password)).toEqual(newData);

            // Read the data which got provided encrypted on init
            expect(credentials.getDataKey('key1', password)).toEqual(initialData);
        });

    });

    describe('with nodeType set', () => {

        test('should be able to set and read key data without initial data set', () => {

            const nodeAccess = [
                {
                    nodeType: 'base.noOp',
                    user: 'userName',
                    date: new Date(),
                }
            ];

            const credentials = new Credentials('testName', 'testType', nodeAccess);

            const key = 'key1';
            const password = 'password';
            const nodeType = 'base.noOp';
            const newData = 1234;

            credentials.setDataKey(key, newData, password);

            // Should be able to read with nodeType which has access
            expect(credentials.getDataKey(key, password, nodeType)).toEqual(newData);

            // Should not be able to read with nodeType which does NOT have access
            // expect(credentials.getDataKey(key, password, 'base.otherNode')).toThrowError(Error);
            try {
                credentials.getDataKey(key, password, 'base.otherNode');
                expect(true).toBe(false);
            } catch (e) {
                expect(e.message).toBe('The node of type "base.otherNode" does not have access to credentials "testName" of type "testType".');
            }

            // Get the data which will be saved in database
            const dbData = credentials.getDataToSave();
            expect(dbData.name).toEqual('testName');
            expect(dbData.type).toEqual('testType');
            expect(dbData.nodesAccess).toEqual(nodeAccess);
            // Compare only the first 6 characters as the rest seems to change with each execution
            expect(dbData.data!.slice(0, 6)).toEqual('U2FsdGVkX1+wpQWkj+YTzaPSNTFATjnlmFKIsUTZdhk='.slice(0, 6));
        });
    });

});