Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

adding codec and encoding tests #381

Merged
merged 6 commits into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
110 changes: 110 additions & 0 deletions packages/teleport/src/lib/tdp/codec.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
const { TextEncoder } = require('util');
import Codec, { MessageType, ButtonState, MouseButton } from './codec';

// Use nodejs TextEncoder until jsdom adds support for TextEncoder (https://github.com/jsdom/jsdom/issues/2524)
window.TextEncoder = TextEncoder;
ibeckermayer marked this conversation as resolved.
Show resolved Hide resolved
const codec = new Codec();

test('encodes the screen spec', () => {
const w = 1800;
const h = 1200;
const message = codec.encodeScreenSpec(w, h);
const view = new DataView(message);
expect(view.getUint8(0)).toEqual(MessageType.CLIENT_SCREEN_SPEC);
expect(view.getUint32(1)).toEqual(w);
expect(view.getUint32(5)).toEqual(h);
});

test('encodes mouse moves', () => {
const x = 0;
const y = Math.pow(2, 32) - 1;
const message = codec.encodeMouseMove(x, y);
const view = new DataView(message);
expect(view.getUint8(0)).toEqual(MessageType.MOUSE_MOVE);
expect(view.getUint32(1)).toEqual(x);
expect(view.getUint32(5)).toEqual(y);
});

test('encodes mouse buttons', () => {
[0, 1, 2].forEach(button => {
[ButtonState.DOWN, ButtonState.UP].forEach(state => {
const message = codec.encodeMouseButton(button as MouseButton, state);
const view = new DataView(message);
expect(view.getUint8(0)).toEqual(MessageType.MOUSE_BUTTON);
expect(view.getUint8(1)).toEqual(button);
expect(view.getUint8(2)).toEqual(state);
});
});
});

// Username/password tests inspired by https://github.com/google/closure-library/blob/master/closure/goog/crypt/crypt_test.js (Apache License)
test('encodes typical characters for username and password', () => {
// Create test vals + known UTF8 encodings
ibeckermayer marked this conversation as resolved.
Show resolved Hide resolved
const username = 'Helloworld!*@123';
const usernameUTF8 = [
0x0048,
0x0065,
0x006c,
0x006c,
0x006f,
0x0077,
0x006f,
0x0072,
0x006c,
0x0064,
0x0021,
0x002a,
0x0040,
0x0031,
0x0032,
0x0033,
];

// Encode test vals
const message = codec.encodeUsername(username);
const view = new DataView(message);

// Walk through output
let offset = 0;
expect(view.getUint8(offset++)).toEqual(MessageType.CLIENT_USERNAME);
expect(view.getUint32(offset)).toEqual(usernameUTF8.length);
offset += 4;
usernameUTF8.forEach(byte => {
expect(view.getUint8(offset++)).toEqual(byte);
});
});

// Test skipped until jsdom adds support for TextEncoder (https://github.com/jsdom/jsdom/issues/2524)
ibeckermayer marked this conversation as resolved.
Show resolved Hide resolved
// eslint-disable-next-line jest/no-disabled-tests
test('encodes utf8 characters correctly up to 3 bytes for username and password', () => {
const first3RangesString = '\u0000\u007F\u0080\u07FF\u0800\uFFFF';
const first3RangesUTF8 = [
0x00,
0x7f,
0xc2,
0x80,
0xdf,
0xbf,
0xe0,
0xa0,
0x80,
0xef,
0xbf,
0xbf,
];
const message = codec.encodeUsername(first3RangesString);
const view = new DataView(message);
let offset = 0;
expect(view.getUint8(offset++)).toEqual(MessageType.CLIENT_USERNAME);
expect(view.getUint32(offset)).toEqual(first3RangesUTF8.length);
offset += 4;
first3RangesUTF8.forEach(byte => {
expect(view.getUint8(offset++)).toEqual(byte);
});
});

// todo until jsdom adds support for Blob.arrayBuffer() (https://github.com/jsdom/jsdom/issues/2555)
test.todo(`TODO: decoding -- jest uses jsdom to emulate a browser environment during the tests, but jsdom does not currently
support Blob.arrayBuffer() (used in our decoding functions) and thus it is difficult to test.
I think I've come up with a hacky workaround but @awly and I agreed to put this aside
for the time being; all will be tested manually for now by necessity during development.`);