Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions test/uts/realtime/integration/auth/auth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* UTS Integration: Realtime Auth Tests
*
* Spec points: RTC8a, RTC8c, RSA8, RSA7
* Source: uts/realtime/integration/auth.md
*/

import { expect } from 'chai';
import {
Ably,
SANDBOX_ENDPOINT,
setupSandbox,
teardownSandbox,
getApiKey,
getKeyParts,
trackClient,
connectAndWait,
closeAndWait,
generateJWT,
uniqueChannelName,
} from '../sandbox';

describe('uts/realtime/integration/auth/auth', function () {
this.timeout(30000);

before(async function () {
await setupSandbox();
});

after(async function () {
await teardownSandbox();
});

/**
* RSA8 - Token auth on realtime connection
*/
it('RSA8 - JWT token auth connects successfully', async function () {
const { keyName, keySecret } = getKeyParts(getApiKey());

const client = new Ably.Realtime({
authCallback: (_params: any, cb: any) => {
cb(null, generateJWT({ keyName, keySecret, ttl: 3600000 }));
},
endpoint: SANDBOX_ENDPOINT,
autoConnect: false,
useBinaryProtocol: false,
});
trackClient(client);

await connectAndWait(client);

expect(client.connection.state).to.equal('connected');
expect(client.connection.id).to.not.be.null;
expect(client.connection.errorReason).to.be.null;

await closeAndWait(client);
});

/**
* RTC8a - In-band reauthorization on CONNECTED client
*/
it('RTC8a - authorize on connected client does not disconnect', async function () {
const { keyName, keySecret } = getKeyParts(getApiKey());

const client = new Ably.Realtime({
authCallback: (_params: any, cb: any) => {
cb(null, generateJWT({ keyName, keySecret, ttl: 3600000 }));
},
endpoint: SANDBOX_ENDPOINT,
autoConnect: false,
useBinaryProtocol: false,
});
trackClient(client);

await connectAndWait(client);
const connectionIdBefore = client.connection.id;

const stateChanges: any[] = [];
client.connection.on((change: any) => stateChanges.push(change));

const token = await client.auth.authorize();

expect(token).to.not.be.null;
expect(client.connection.state).to.equal('connected');
expect(client.connection.id).to.equal(connectionIdBefore);

const stateTransitions = stateChanges.filter((c: any) => c.current !== c.previous);
expect(stateTransitions).to.have.length(0);

await closeAndWait(client);
});

/**
* RTC8c - authorize() from INITIALIZED initiates connection
*/
it('RTC8c - authorize from initialized state initiates connection', async function () {
const { keyName, keySecret } = getKeyParts(getApiKey());

const client = new Ably.Realtime({
authCallback: (_params: any, cb: any) => {
cb(null, generateJWT({ keyName, keySecret, ttl: 3600000 }));
},
endpoint: SANDBOX_ENDPOINT,
autoConnect: false,
useBinaryProtocol: false,
});
trackClient(client);

expect(client.connection.state).to.equal('initialized');

const token = await client.auth.authorize();

expect(token).to.not.be.null;
expect(client.connection.state).to.equal('connected');
expect(client.connection.id).to.not.be.null;

await closeAndWait(client);
});

/**
* RSA7 - Matching clientId succeeds
*/
it('RSA7 - matching clientId in JWT and options succeeds', async function () {
const { keyName, keySecret } = getKeyParts(getApiKey());
const testClientId = `test-client-${Math.random().toString(36).substring(2, 8)}`;

const client = new Ably.Realtime({
authCallback: (_params: any, cb: any) => {
cb(null, generateJWT({ keyName, keySecret, clientId: testClientId, ttl: 3600000 }));
},
clientId: testClientId,
endpoint: SANDBOX_ENDPOINT,
autoConnect: false,
useBinaryProtocol: false,
});
trackClient(client);

await connectAndWait(client);

expect(client.connection.state).to.equal('connected');
expect(client.auth.clientId).to.equal(testClientId);

await closeAndWait(client);
});
});
71 changes: 71 additions & 0 deletions test/uts/realtime/integration/auth/token_renewal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* UTS Integration: Token Renewal Tests
*
* Spec points: RSA4b, RTN14b
* Source: uts/realtime/integration/auth/token_renewal_test.md
*/

import { expect } from 'chai';
import {
Ably,
SANDBOX_ENDPOINT,
setupSandbox,
teardownSandbox,
getApiKey,
getKeyParts,
trackClient,
connectAndWait,
closeAndWait,
generateJWT,
pollUntil,
} from '../sandbox';

describe('uts/realtime/integration/auth/token_renewal', function () {
this.timeout(60000);

before(async function () {
await setupSandbox();
});

after(async function () {
await teardownSandbox();
});

/**
* RSA4b, RTN14b - Token renewal on expiry
*/
it('RSA4b/RTN14b - token renewal on expiry', async function () {
const { keyName, keySecret } = getKeyParts(getApiKey());
let callbackCount = 0;

const client = new Ably.Realtime({
authCallback: (_params: any, cb: any) => {
callbackCount++;
if (callbackCount === 1) {
cb(null, generateJWT({ keyName, keySecret, ttl: 5000 }));
} else {
cb(null, generateJWT({ keyName, keySecret, ttl: 3600000 }));
}
},
endpoint: SANDBOX_ENDPOINT,
autoConnect: false,
useBinaryProtocol: false,
});
trackClient(client);

await connectAndWait(client);
expect(callbackCount).to.equal(1);

await pollUntil(() => (callbackCount >= 2 ? true : null), {
interval: 1000,
timeout: 30000,
});

await connectAndWait(client);

expect(callbackCount).to.be.at.least(2);
expect(client.connection.state).to.equal('connected');

await closeAndWait(client);
});
});
98 changes: 98 additions & 0 deletions test/uts/realtime/integration/auth/token_request.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* UTS Integration: Token Request Tests
*
* Spec points: RSA9, RSA9a, RSA9g
* Source: uts/realtime/integration/auth/token_request_test.md
*/

import { expect } from 'chai';
import {
Ably,
SANDBOX_ENDPOINT,
setupSandbox,
teardownSandbox,
getApiKey,
trackClient,
connectAndWait,
closeAndWait,
} from '../sandbox';

describe('uts/realtime/integration/auth/token_request', function () {
this.timeout(30000);

before(async function () {
await setupSandbox();
});

after(async function () {
await teardownSandbox();
});

/**
* RSA9a, RSA9g - createTokenRequest produces server-accepted token
*/
it('RSA9a/RSA9g - createTokenRequest produces server-accepted token', async function () {
const creator = new Ably.Rest({
key: getApiKey(),
endpoint: SANDBOX_ENDPOINT,
});

const client = new Ably.Realtime({
authCallback: async (_params: any, cb: any) => {
try {
const tokenRequest = await creator.auth.createTokenRequest();
cb(null, tokenRequest);
} catch (err) {
cb(err, null);
}
},
endpoint: SANDBOX_ENDPOINT,
autoConnect: false,
useBinaryProtocol: false,
});
trackClient(client);

await connectAndWait(client);

expect(client.connection.state).to.equal('connected');
expect(client.connection.id).to.not.be.null;
expect(client.connection.errorReason).to.be.null;

await closeAndWait(client);
});

/**
* RSA9 - createTokenRequest with clientId
*/
it('RSA9 - createTokenRequest with clientId', async function () {
const testClientId = `token-request-client-${Math.random().toString(36).substring(2, 10)}`;

const creator = new Ably.Rest({
key: getApiKey(),
endpoint: SANDBOX_ENDPOINT,
});

const client = new Ably.Realtime({
authCallback: async (_params: any, cb: any) => {
try {
const tokenRequest = await creator.auth.createTokenRequest({ clientId: testClientId });
cb(null, tokenRequest);
} catch (err) {
cb(err, null);
}
},
clientId: testClientId,
endpoint: SANDBOX_ENDPOINT,
autoConnect: false,
useBinaryProtocol: false,
});
trackClient(client);

await connectAndWait(client);

expect(client.connection.state).to.equal('connected');
expect(client.auth.clientId).to.equal(testClientId);

await closeAndWait(client);
});
});
Loading
Loading