UNPKG

@atomicjolt/lti-client

Version:

Client Javascript libraries to handle LTI.

122 lines 4.54 kB
import { describe, expect, beforeEach, afterEach, it, vi } from 'vitest'; import { STATE_KEY_PREFIX } from '../libs/constants'; import { ltiLaunch } from './launch'; import { MESSAGE_TYPE, MessageTypes, LTI_VERSION, LtiVersions, TARGET_LINK_URI_CLAIM, RESOURCE_LINK_CLAIM, DEPLOYMENT_ID, ROLES_CLAIM, } from '@atomicjolt/lti-types'; const resourceLinkClaim = { id: '134', }; const idToken = { sub: '1234567890', name: 'John Doe', email: 'johndoe@example.com', aud: '', azp: '', exp: 0, iat: 0, iss: '', nonce: '12343456', [MESSAGE_TYPE]: MessageTypes.LtiResourceLinkRequest, [LTI_VERSION]: LtiVersions.v1_3_0, [RESOURCE_LINK_CLAIM]: resourceLinkClaim, [DEPLOYMENT_ID]: '', [TARGET_LINK_URI_CLAIM]: '', [ROLES_CLAIM]: [], picture: '', given_name: '', family_name: '', middle_name: '', locale: '', }; describe('launch', () => { const state = 'thestate'; const platformOIDCUrl = 'https://canvas.instructure.com/api/lti/authorize_redirect'; const origin = new URL(platformOIDCUrl).origin; let event; let settings; beforeEach(() => { document.body.innerHTML = ` <form action="https://assessments.atomicjolt.xyz/lti_launches/" method="POST"> <input type="hidden" name="state" id="state" value="state" /> <input type="hidden" name="id_token" id="id_token" value="id_token" /> </form> <div id="error" class="hidden">error</div> `; settings = { idToken, state, stateVerified: false, ltiStorageParams: { target: '_parent', originSupportBroken: true, platformOIDCUrl, }, }; event = { data: { subject: 'lti.get_data.response', message_id: state, value: state, }, origin, }; }); afterEach(() => { vi.restoreAllMocks(); document.cookie = `${STATE_KEY_PREFIX}${state}=;Max-Age=-1`; }); describe('validateLaunch', () => { it('calls postMessage', async () => { // Spy on postMessage to ensure it is called. const postMessageSpy = vi.spyOn(window, 'postMessage'); // Spy on addEventListener mock the response that will be sent to receiveMessage vi.spyOn(window, 'addEventListener').mockImplementation((eventName, func) => { if (eventName === 'message') { const receiveMessage = func; receiveMessage(event); } if (eventName === 'load') { const f = func; f(); } }); await expect(ltiLaunch(settings)).resolves.toBeTruthy(); await new Promise(process.nextTick); expect(postMessageSpy).toHaveBeenCalled(); }); it('returns false if the state is invalid', async () => { // Spy on postMessage to ensure it is called. const postMessageSpy = vi.spyOn(window, 'postMessage'); // Spy on addEventListener mock the response that will be sent to receiveMessage vi.spyOn(window, 'addEventListener').mockImplementation((eventName, func) => { if (eventName === 'message') { const receiveMessage = func; event.data.value = 'badstate'; receiveMessage(event); } if (eventName === 'load') { const f = func; f(); } }); await expect(ltiLaunch(settings)).resolves.toBeFalsy(); await new Promise(process.nextTick); expect(postMessageSpy).toHaveBeenCalled(); }); it('should return false when there is no ltiStorageParams', async () => { const settings = { state: 'testState', idToken, stateVerified: false, }; // Spy on addEventListener mock the response that will be sent to receiveMessage vi.spyOn(window, 'addEventListener').mockImplementation((eventName, func) => { if (eventName === 'load') { const f = func; f(); } }); await expect(ltiLaunch(settings)).resolves.toBeFalsy(); }); }); }); //# sourceMappingURL=launch.test.js.map