Skip to content

Commit

Permalink
Add getToken function support to Luigi Container (#3785)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndricimrr authored Jul 4, 2024
1 parent 2fa9970 commit 9e30e36
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 9 deletions.
25 changes: 25 additions & 0 deletions container/cypress/e2e/test-app/iframe/iframe-container.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,29 @@ describe('Iframe Container Test', () => {
});
});
});

it('set auth token', () => {
const stub = cy.stub();
cy.on('window:alert', stub);

cy.visit('http://localhost:8080/iframe/iframeContainer.html');

cy.get('button[id="update-token"]').click();

cy.get('[data-test-id="iframe-based-container-test"]')
.shadow()
.get('iframe')
.then(iframe => {
const $body = iframe.contents().find('body');
cy.wrap($body)
.contains('test get token')
.click()
.then(() => {
cy.wrap(stub).should(
'have.been.calledWith',
'Custom message recieved: {"id":"token.updated","_metaData":{},"data":{"value":"updated token"}}'
);
});
});
});
});
15 changes: 11 additions & 4 deletions container/src/LuigiContainer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
hasBack: { type: 'Boolean', reflect: false, attribute: 'has-back' },
documentTitle: { type: 'String', reflect: false, attribute: 'document-title' },
allowRules: { type: 'Array', reflect: false, attribute: 'allow-rules' },
sandboxRules: { type: 'Array', reflect: false, attribute: 'sandbox-rules' }
sandboxRules: { type: 'Array', reflect: false, attribute: 'sandbox-rules' },
authData: { type: 'Object', reflect: false, attribute: 'auth-data' }
},
extend: customElementConstructor => {
let notInitFn = name => {
Expand All @@ -35,8 +36,13 @@
updateContext = notInitFn('updateContext');
closeAlert = notInitFn('closeAlert');
attributeChangedCallback(name, oldValue, newValue) {
if (this.containerInitialized && name === 'context') {
this.updateContext(JSON.parse(newValue));
if (this.containerInitialized) {
if (name === 'context') {
this.updateContext(JSON.parse(newValue));
}
if (name === 'auth-data') {
ContainerAPI.updateAuthData(this.iframeHandle, JSON.parse(newValue));
}
}
};
getNoShadow(){
Expand Down Expand Up @@ -78,6 +84,7 @@
export let userSettings: any;
export let anchor: string;
export let authData: any;
const iframeHandle:
| {
Expand Down Expand Up @@ -218,4 +225,4 @@
/>
{/if}
{/if}
</main>
</main>
21 changes: 19 additions & 2 deletions container/src/api/container-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { containerService } from '../services/container.service';

export class ContainerAPIFunctions {
/**
* Updates the context of the microfrontend by sending a message to the iframe or webcomponent that sets the context of the microfrontend
* Updates the context of the microfrontend by sending a message to the iframe that sets the context of the microfrontend
* @param contextObj The context data
* @param internal internal luigi legacy data
* @param iframeHandle a reference to the iframe that is needed to send a message to it internally
Expand All @@ -17,7 +17,7 @@ export class ContainerAPIFunctions {
context: contextObj,
internal: internalParameter,
// set withoutSync to true for the container case to avoid browser history changes from luigi client
withoutSync: true
withoutSync: true,
},
LuigiInternalMessageID.SEND_CONTEXT_OBJECT
);
Expand All @@ -26,6 +26,23 @@ export class ContainerAPIFunctions {
}
};

/**
* Updates the auth data of the microfrontend by sending a message to the iframe that sets the authData of the microfrontend
* @param iframeHandle a reference to the iframe that is needed to send a message to it internally
* @param authData the authData object being sent to the microfrontend
*/
updateAuthData = (iframeHandle: any, authData: any) => {
if (iframeHandle && authData) {
containerService.sendCustomMessageToIframe(
iframeHandle,
{authData},
LuigiInternalMessageID.AUTH_SET_TOKEN
);
} else {
console.warn('Attempting to update auth data on inexisting iframe or authData');
}
};

/**
* Send a custom message to the referenced iframe or web component
* @param id a string containing the message id
Expand Down
5 changes: 5 additions & 0 deletions container/src/constants/internal-communication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,9 @@ export namespace LuigiInternalMessageID {
* A message emmitted from the Microfrontend when a request to set the 'dirty status' (ex: avoid closing if usaved changes) is sent
*/
export const SET_DIRTY_STATUS_REQUEST = 'luigi.set-page-dirty';

/**
* A message emmitted from the Microfrontend when a request to set the 'token auth' is sent
*/
export const AUTH_SET_TOKEN = 'luigi.auth.tokenIssued';
}
3 changes: 2 additions & 1 deletion container/src/services/container.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ export class ContainerService {
{
msg: LuigiInternalMessageID.SEND_CONTEXT_HANDSHAKE,
context: targetCnt.context || {},
internal: {}
internal: {},
authData: targetCnt.authData || {},
},
'*'
);
Expand Down
7 changes: 7 additions & 0 deletions container/test-app/iframe/iframeContainer.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ <h3>
</h3>
<button id="btn-1">Send Custom Message to iFrame Container</button>
<button id="update-ctx">Update Ctx</button>
<button id="update-token">Update Access Token</button>

<div style="border:solid 1px blue">
<luigi-container
data-test-id="iframe-based-container-test"
viewURL="./microfrontend.html"
context='{"title": "Projects", "content":" "}'
auth-data='{ "accessToken": "my-token" }'
>
</luigi-container>
</div>
Expand All @@ -38,6 +40,7 @@ <h3>
// Some glue code
const sendCustomMessageBtn = document.getElementById('btn-1');
const updateContextButton = document.getElementById('update-ctx');
const updateAccessTokenButton = document.getElementById('update-token');

// for testing send Custom message functionality
sendCustomMessageBtn.addEventListener('click', () => {
Expand All @@ -50,6 +53,10 @@ <h3>
luigiContainer.updateContext({ myContext: 'some context data' });
});

updateAccessTokenButton.addEventListener('click', () => {
luigiContainer.setAttribute('auth-data', '{"accessToken": "updated token"}');
});

luigiContainer.addEventListener(Events.NAVIGATION_REQUEST, event => {
if (confirm('Do you want to leave this page?')) {
window.location = event.detail.link;
Expand Down
15 changes: 15 additions & 0 deletions container/test-app/iframe/microfrontend.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ <h1 id="title">Multi purpose demo page</h1>
<button onclick="testCheckPathExists()">test check path exists</button>
<button onclick="testSetDirtyStatus()">test set dirty status</button>
<button onclick="testShowAlert()">test show alert</button>
<button onclick="testGetToken()">test get token</button>
</div>
<script>
// List of onclick handlers for client calls
Expand Down Expand Up @@ -153,6 +154,14 @@ <h1 id="title">Multi purpose demo page</h1>
LuigiClient.uxManager().setDirtyStatus(true);
}

function testGetToken() {
// send back message with get Token value
LuigiClient.sendCustomMessage({
id: 'token.updated',
value: LuigiClient.getToken()
});
}

function testShowAlert() {
let dt = new Date();
let time = dt.getMilliseconds() + '';
Expand Down Expand Up @@ -213,6 +222,12 @@ <h1 id="title">Multi purpose demo page</h1>
'Received Custom Message: ' + data.milliseconds;
});

LuigiClient.addCustomMessageListener('update', data => {
console.log('Custom Message Received inside iframe Container', data);
document.getElementById('content').innerHTML =
'Received Custom Message: ' + data.milliseconds;
});

// fallback visibility if no initlistener called for 3 seconds
setTimeout(function() {
document.getElementById('textCnt').classList.add('visible');
Expand Down
70 changes: 69 additions & 1 deletion container/test/api/container-api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,75 @@ describe('Container Service', () => {
});
});

describe('updateAuthData', () => {
let containerAPI = new ContainerAPIFunctions();

it('iframeHandle exists, authData exists', () => {
// mock and spy
const authData = { someData: 'mytoken'};
const iframeHandle = {
data: 'test'
};
containerService.sendCustomMessageToIframe = jest.fn();
const spy = jest.spyOn(containerService, 'sendCustomMessageToIframe');

// act
containerAPI.updateAuthData(iframeHandle, authData);

// assert
expect(spy).toHaveBeenCalledWith(iframeHandle, {authData}, LuigiInternalMessageID.AUTH_SET_TOKEN)
});

it('iframeHandle undefined, authData exists', () => {
// mock and spy
const authData = undefined;
const iframeHandle = undefined;
containerService.sendCustomMessageToIframe = jest.fn();
const sendCustomMSGSpy = jest.spyOn(containerService, 'sendCustomMessageToIframe');
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(jest.fn());

// act
containerAPI.updateAuthData(iframeHandle, authData);

// assert
expect(sendCustomMSGSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalledWith('Attempting to update auth data on inexisting iframe or authData')
});


it('iframeHandle exists, authData undefined', () => {
// mock and spy
const authData = undefined;
const iframeHandle = undefined;
containerService.sendCustomMessageToIframe = jest.fn();
const sendCustomMSGSpy = jest.spyOn(containerService, 'sendCustomMessageToIframe');
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(jest.fn());

// act
containerAPI.updateAuthData(iframeHandle, authData);

// assert
expect(sendCustomMSGSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalledWith('Attempting to update auth data on inexisting iframe or authData')
});

it('iframeHandle undefined, authData undefined', () => {
// mock and spy
const authData = undefined;
const iframeHandle = undefined;
containerService.sendCustomMessageToIframe = jest.fn();
const sendCustomMSGSpy = jest.spyOn(containerService, 'sendCustomMessageToIframe');
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(jest.fn());

// act
containerAPI.updateAuthData(iframeHandle, authData);

// assert
expect(sendCustomMSGSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalledWith('Attempting to update auth data on inexisting iframe or authData')
});
});

describe('closeAlert', () => {
let containerAPI = new ContainerAPIFunctions();

Expand All @@ -80,7 +149,6 @@ describe('Container Service', () => {
});
});


describe('sendCustomMessage', () => {
let containerAPI = new ContainerAPIFunctions();
beforeEach(() => {
Expand Down
2 changes: 1 addition & 1 deletion container/test/services/container.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ describe('getContainerManager messageListener', () => {
cw.postMessage = postMessageMock;

// Define the message to send and target Origin
const message = {"context": {}, "internal": {}, "msg": "luigi.init"};
const message = {"context": {}, "internal": {}, "msg": "luigi.init", "authData":{}};
const targetOrigin = "*";

// Call the method that should trigger postMessage
Expand Down
6 changes: 6 additions & 0 deletions container/typings/LuigiContainer.svelte.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,10 @@ export default class LuigiContainer extends HTMLElement {
* @since 1.0.0
*/
init(): void;

/**
* The authData value to be passed to the iframe-based micro frontend.
* @since NEXT_RELEASE
*/
authData: Object;
}
10 changes: 10 additions & 0 deletions docs/luigi-container-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,13 @@ Returns **void**
**Meta**

- **since**: 1.0.0

### authData

The authData value to be passed to the iframe-based micro frontend.

Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)

**Meta**

- **since**: NEXT_RELEASE

0 comments on commit 9e30e36

Please sign in to comment.