Skip to content

Commit

Permalink
Merge pull request #104 from rdkcentral/FIRECERT-2100
Browse files Browse the repository at this point in the history
FIRECERT-2100: [POC] FCA implementation for user interest scenarios
  • Loading branch information
Abhishk123 authored Jun 20, 2024
2 parents fe47578 + c727c2c commit b865f47
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 23 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"version": "1.1.0",
"version": "1.2.0",
"name": "firebolt-certification",
"description": "Reference App to demonstrate Firebolt APIs and Lifecycle",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.9",
"@firebolt-js/manage-sdk": "1.1.0",
"@firebolt-js/sdk": "1.1.0",
"@firebolt-js/discovery-sdk": "1.2.0",
"@firebolt-js/manage-sdk": "1.2.0",
"@firebolt-js/sdk": "1.2.0",
"@lightningjs/core": "2.11.0",
"@lightningjs/sdk": "^5.0.1",
"@lightningjs/ui-components": "^2.2.2",
Expand Down
13 changes: 8 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import lng from '@lightningjs/core';
import Menu from './Menu';
import MenuBuilder from './MenuBuilder';
import LifecycleHistory from './LifeCycleHistory';
import { Settings, Accessibility } from '@firebolt-js/sdk';
import { Settings, Accessibility, Discovery } from '@firebolt-js/sdk';
import FireboltExampleInvoker from './FireboltExampleInvoker';
import Modal from './Modal';
import PubSubCommunication from './PubSubCommunication';
Expand All @@ -31,6 +31,7 @@ import { AcknowledgeChallenge, Keyboard, PinChallenge } from '@firebolt-js/manag
import PinChallengeProviderDelegater from './providers/PinChallengeDelegater';
import KeyboardProviderDelegater from './providers/KeyboardProviderDelegater';
import AckChallengeProviderDelegater from './providers/AckChallengeDelegater';
import UserInterestDelegater from './providers/UserInterestDelegater';
const logger = require('./utils/Logger')('App.js');
import FireboltTransportInvoker from './FireboltTransportInvoker';
import { handleAsyncFunction } from './utils/Utils';
Expand Down Expand Up @@ -198,14 +199,16 @@ export default class App extends Base {
if (!this.appContinue) {
const systemui = new URLSearchParams(window.location.search).get('systemui');

if (systemui) {
try {
try {
if (systemui) {
AcknowledgeChallenge.provide('xrn:firebolt:capability:usergrant:acknowledgechallenge', new AckChallengeProviderDelegater(this));
Keyboard.provide('xrn:firebolt:capability:input:keyboard', new KeyboardProviderDelegater(this));
PinChallenge.provide('xrn:firebolt:capability:usergrant:pinchallenge', new PinChallengeProviderDelegater(this));
} catch (err) {
logger.error('Could not set up providers' + err, 'LoadedState');
} else {
Discovery.provide('xrn:firebolt:capability:discovery:interest', new UserInterestDelegater(this));
}
} catch (err) {
logger.error('Could not set up providers' + err, 'LoadedState');
}
process.env.APPOBJECT = this;
const menusBuilder = new MenuBuilder();
Expand Down
8 changes: 7 additions & 1 deletion src/FireboltExampleInvoker.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
AudioDescriptions,
HDMIInput,
} from '@firebolt-js/manage-sdk';
import { Content } from '@firebolt-js/discovery-sdk';
import DiscoveryInvoker from './invokers/DiscoveryInvoker';
const discoveryInvoker = new DiscoveryInvoker();
const logger = require('./utils/Logger')('FireboltExampleInvoker.js');
Expand All @@ -48,7 +49,7 @@ const MAP = {
'discovery.purchasedContent': discoveryInvoker.purchasedContent.bind(discoveryInvoker),
'discovery.entityInfo': discoveryInvoker.entityInfo.bind(discoveryInvoker),
// 'content.purchases': discoveryInvoker.getPurchasedContent.bind(discoveryInvoker),
// 'content.entity': discoveryInvoker.getEntityInfo.bind(discoveryInvoker)
// 'content.entity': discoveryInvoker.getEntityInfo.bind(discoveryInvoker),
};

const CORE_MODULE_MAP = {
Expand Down Expand Up @@ -89,9 +90,14 @@ const MANAGE_MODULE_MAP = {
hdmiinput: HDMIInput,
};

const DISCOVERY_MODULE_MAP = {
content: Content,
};

export const MODULE_MAP = {
core: CORE_MODULE_MAP,
manage: MANAGE_MODULE_MAP,
discovery: DISCOVERY_MODULE_MAP,
};

let instance = null;
Expand Down
10 changes: 5 additions & 5 deletions src/MenuBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,18 +169,18 @@ export default class MenuBuilder {
const certificationMenu = [];

const sdkMenuArray = this.constructMenuBasedOnMode(CONSTANTS.SDK);
const sdkMenuObject = this.createMenuObject(CONSTANTS.SDK, sdkMenuArray);
certificationMenu.push(sdkMenuObject);

const transportMenuArray = this.constructMenuBasedOnMode(CONSTANTS.TRANSPORT);
CONSTANTS.additionalSDKs.forEach(
function (sdkObject) {
const sdkObjectCopy = { ...sdkObject };
// dynamically construct menu items using additionalSDKs config
const menuObject = this.createSubMenuObject(sdkObjectCopy.name, ValidationView, sdkObjectCopy.name, CONSTANTS.SDK);
sdkMenuArray.push(menuObject);
transportMenuArray.push(menuObject);
}.bind(this)
);
const sdkMenuObject = this.createMenuObject(CONSTANTS.SDK, sdkMenuArray);
certificationMenu.push(sdkMenuObject);

const transportMenuArray = this.constructMenuBasedOnMode(CONSTANTS.TRANSPORT);
const transportMenuObject = this.createMenuObject(CONSTANTS.TRANSPORT, transportMenuArray);
certificationMenu.push(transportMenuObject);
return [...certificationMenu];
Expand Down
2 changes: 1 addition & 1 deletion src/Test_Runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ export class Test_Runner {
executionMode = executionMode.toUpperCase();
apiExecutionStartTime = new Date(); // api execution start time

if (executionMode.includes(CONSTANTS.MANAGE) || executionMode.includes(CONSTANTS.CORE)) {
if (executionMode.includes(CONSTANTS.MANAGE) || executionMode.includes(CONSTANTS.CORE) || executionMode.includes(CONSTANTS.DISCOVERY)) {
[response, err] = paramsArray
? await handleAsyncFunction(FireboltTransportInvoker.get().invoke(method, params, paramsArray))
: await handleAsyncFunction(FireboltExampleInvoker.get().invoke(sdk, method, params, null, paramsArray));
Expand Down
10 changes: 10 additions & 0 deletions src/constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import CONFIG_CONSTANTS from 'config';
import CORE_OPEN_RPC from '@firebolt-js/sdk/dist/firebolt-core-open-rpc';
import MANAGE_OPEN_RPC from '@firebolt-js/manage-sdk/dist/firebolt-manage-open-rpc';
import DISCOVERY_OPEN_RPC from '@firebolt-js/discovery-sdk/dist/firebolt-discovery-open-rpc';
export const CONSTANTS = {
ALL_SDKS: 'ALL SDKS',
SDK: 'SDK',
Expand Down Expand Up @@ -106,6 +107,7 @@ export const CONSTANTS = {
EXCEPTION_METHODS: [],
CORE: 'CORE',
MANAGE: 'MANAGE',
DISCOVERY: 'DISCOVERY',
FIREBOLT_ALL: 'FIREBOLT-ALL',
ERROR_MESSAGE_WRONG_METHOD_NAME: { code: -32601, message: 'Wrong Method Name' },
INVALID_REQUEST_TYPE: 'Error: Invalid requestType',
Expand Down Expand Up @@ -155,6 +157,14 @@ export const CONSTANTS = {
},
unavailableMessage: 'MockOs is not running',
},
{
name: 'Discovery',
openRpc: DISCOVERY_OPEN_RPC,
validation: function () {
return !(process.env.MF_VALUE && !process.env.MOCKOS);
},
unavailableMessage: 'MockOs is not running',
},
],

additionalSDKs: [],
Expand Down
1 change: 0 additions & 1 deletion src/invokers/DiscoveryInvoker.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/

import { Discovery } from '@firebolt-js/sdk';
// import { Content } from '@firebolt-js/discovery-sdk'
import { testDataHandler, filterExamples } from '../utils/Utils';

const MOCK_PURCHASED_CONTENT = {
Expand Down
4 changes: 2 additions & 2 deletions src/providers/KeyboardUIProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ export default class KeyboardUIProvider {
session: {
onDone: (keyboard, text) => {
this._app.overlayDismissTimer = setTimeout(() => this._app.$dismissOverlay(), 500); // Try and get lightning-ui component to use onkeyup
responder({ text, canceled: false });
responder(text);
},
onCancel: (keyboard) => {
this._app.$dismissOverlay();
responder({ text: '', canceled: true });
responder('');
},
mask: mask,
title: session.message,
Expand Down
8 changes: 4 additions & 4 deletions src/providers/KeyboardUIProviderTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class KeyboardUIProviderTest {
});
} else {
this._app.$dismissOverlay();
return Promise.resolve({ text: process.env.ApiText, canceled: process.env.isCancelled });
return Promise.resolve(process.env.ApiText);
}
}

Expand All @@ -56,7 +56,7 @@ export default class KeyboardUIProviderTest {
});
} else {
this._app.$dismissOverlay();
return Promise.resolve({ text: process.env.ApiText, canceled: process.env.isCancelled });
return Promise.resolve(process.env.ApiText);
}
}

Expand All @@ -73,7 +73,7 @@ export default class KeyboardUIProviderTest {
});
} else {
this._app.$dismissOverlay();
return Promise.resolve({ text: process.env.ApiText, canceled: process.env.isCancelled });
return Promise.resolve(process.env.ApiText);
}
}

Expand Down Expand Up @@ -108,7 +108,7 @@ export default class KeyboardUIProviderTest {

onDone(responder, text, isCancelled) {
setTimeout(() => this._app.$dismissOverlay(), 500); // Try and get lightning-ui component to use onkeyup
responder({ text, canceled: isCancelled });
responder(text);
}

sleep(ms) {
Expand Down
30 changes: 30 additions & 0 deletions src/providers/UserInterestDelegater.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright 2023 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

import UserIntrestProvider from './UserInterestProvider';

export default class UserIntrestDelegater {
constructor() {
this.delegate = new UserIntrestProvider();
process.env.UserInterestDelegater = this;
}

userInterest() {
return this.delegate.userInterest();
}
}
33 changes: 33 additions & 0 deletions src/providers/UserInterestProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright 2023 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

export default class UserIntrestProvider {
userInterest() {
try {
const USERINTERESTDATA = require('../source/userInterest.json');
if (USERINTERESTDATA.hasOwnProperty(process.env.userInterestKey)) {
const data = USERINTERESTDATA[process.env.userInterestKey];
return Promise.resolve(data);
} else {
return Promise.resolve(null);
}
} catch (err) {
logger.error('Error in userInterest provider: ', err.message);
}
}
}
2 changes: 1 addition & 1 deletion src/pubsub/handlers/RegisterEventHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default class RegisterEventHandler extends BaseHandler {

let validatedMenu;
// Switch creation for the type of invocation that needs to happen.
if ([CONSTANTS.CORE.toLowerCase(), CONSTANTS.MANAGE.toLowerCase()].includes(sdkType)) {
if ([CONSTANTS.CORE.toLowerCase(), CONSTANTS.MANAGE.toLowerCase(), CONSTANTS.DISCOVERY.toLowerCase()].includes(sdkType)) {
validatedMenu = await eventInvokerInfo.northBoundEventHandling(message);
} else {
validatedMenu = {
Expand Down
9 changes: 9 additions & 0 deletions src/pubsub/handlers/setApiResponseHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export default class SetApiResponseHandler extends BaseHandler {
return this.setResponseFederatedDataPurchasedContent(message);
case 'ackchallenge':
return this.setResponseAckChallenge(message);
case 'userinterest':
return this.setResponseUserInterestChallenge(message);
default:
const defaultIdString = JSON.stringify({
report: 'Selected module provider is not available',
Expand Down Expand Up @@ -92,4 +94,11 @@ export default class SetApiResponseHandler extends BaseHandler {

return reportIdString;
}

setResponseUserInterestChallenge(message) {
const userInterestData = message.params.apiResponse.attributes[0];
process.env.userInterestKey = userInterestData.userInterestKey;
const reportIdString = JSON.stringify({ report: 'Received UserInterest apiResponse parameters' });
return reportIdString;
}
}
63 changes: 63 additions & 0 deletions src/source/userInterest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"USERINTEREST_PLAYLIST": {
"identifiers": {
"entityId": "345",
"entityType": "playlist"
},
"info": {
"title": "User Interest",
"synopsis": "User Interest request provider",
"releaseDate": "1993-01-01T00:00:00.000Z",
"contentRatings": [
{
"scheme": "US-Movie",
"rating": "PG"
},
{
"scheme": "CA-Movie",
"rating": "G"
}
]
}
},
"USERINTEREST_REACTION": {
"identifiers": {
"entityId": "123",
"entityType": "channel",
"channelType": "streaming"
},
"info": {
"title": "User Interest",
"synopsis": "User Interest request provider",
"releaseDate": "1993-01-01T00:00:00.000Z",
"contentRatings": [
{
"scheme": "US-Movie",
"rating": "PG"
},
{
"scheme": "CA-Movie",
"rating": "G"
}
]
}
},
"USERINTEREST_RECORDING": {
"identifiers": {
"entityId": "981",
"entityType": "music",
"musicType": "song"
},
"info": {
"title": "User Interest",
"synopsis": "User Interest request provider",
"releaseDate": "1993-01-01T00:00:00.000Z",
"contentRatings": [
{
"scheme": "US-TV",
"rating": "PG"
}
]
}
}
}
3 changes: 3 additions & 0 deletions test/unit/Utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ describe('Utils test cases', () => {
test('validate dereferenceOpenRPC', async () => {
await dereferenceOpenRPC('manage');
});
test('validate dereferenceOpenRPC', async () => {
await dereferenceOpenRPC('discovery');
});
test('validate getschemaValidationDone', async () => {
const name = 'lifecycle.onForeground';
const response = { state: 'foreground', previous: 'inactive' };
Expand Down

0 comments on commit b865f47

Please sign in to comment.