Skip to content

Commit

Permalink
feat: [FC-0006] add Verifiable Credentials optional feature
Browse files Browse the repository at this point in the history
  • Loading branch information
wowkalucky committed Apr 13, 2023
1 parent 48973fe commit f2b7990
Show file tree
Hide file tree
Showing 30 changed files with 1,104 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ USER_INFO_COOKIE_NAME=''
SUPPORT_URL_LEARNER_RECORDS=''
APP_ID=''
MFE_CONFIG_API_URL=''
ENABLE_VERIFIABLE_CREDENTIALS=''
SUPPORT_URL_VERIFIABLE_CREDENTIALS=''
2 changes: 2 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ SUPPORT_URL_LEARNER_RECORDS='https://support.edx.org/hc/en-us/sections/360001216
USE_LR_MFE='true'
APP_ID=''
MFE_CONFIG_API_URL=''
ENABLE_VERIFIABLE_CREDENTIALS='true'
SUPPORT_URL_VERIFIABLE_CREDENTIALS=''
2 changes: 2 additions & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ SEGMENT_KEY=''
SITE_NAME=localhost
USER_INFO_COOKIE_NAME='edx-user-info'
SUPPORT_URL_LEARNER_RECORDS=''
ENABLE_VERIFIABLE_CREDENTIALS='true'
SUPPORT_URL_VERIFIABLE_CREDENTIALS=''
23 changes: 21 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ frontend-app-learner-record
Purpose
*******

The Learner Record provides information about the enrolled programs for a user.
The Learner Record provides information about the enrolled programs for a user.
It contains views for a learners current status in a program, their current grade, and the ability to share any earned credentials either publically or with institutions.

Verifiable Credentials
======================

Optionally, this micro-frontend allows `verifiable credentials`_ creation for already achieved Open edX credentials (currently, program certificates only).

This is the Learner Record micro-frontend, currently under development by `edX <https://www.edx.org>`_.

.. _verifiable credentials: https://en.wikipedia.org/wiki/Verifiable_credentials

Getting Started
***************

Expand Down Expand Up @@ -52,7 +59,7 @@ Every time you develop something in this repo
# Start the Learner Record MFE
npm start
# Using your favorite editor, edit the code to make your change.
vim ...
Expand Down Expand Up @@ -81,6 +88,18 @@ This MFE has 2 flags of its own:
* ``SUPPORT_URL_LEARNER_RECORDS`` -- A link to a help/support center for learners who run into problems whilst trying to share their records
* ``USE_LR_MFE`` -- A toggle that when on, uses the MFE to host shared records instead of the the old UI inside of credentials

Verifiable Credentials
......................

An optional feature. It is behind a feature flag.
The feature introduces a couple of enviroment variables:

* ``ENABLE_VERIFIABLE_CREDENTIALS`` -- Toggles the Verifiable Credentials feature (used by the Credentials IDA and this micro-frontend)
* ``SUPPORT_URL_VERIFIABLE_CREDENTIALS`` -- A link to a help/support center for learners who run into problems whilst trying to create verifiable credentials

The Verifiable Credentials UI is a functional addition to the corresponding backend app (it will use a REST API from the Credentials IDA located at `credentials/apps/verifiable_credentials/rest_api`.


Project Structure
-----------------

Expand Down
57 changes: 57 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"lodash": "4.17.21",
"prop-types": "15.8.1",
"react": "16.14.0",
"react-device-detect": "^2.2.3",
"react-dom": "16.14.0",
"react-helmet-async": "^1.3.0",
"react-redux": "7.2.9",
Expand All @@ -69,6 +70,7 @@
"glob": "7.2.3",
"husky": "7.0.4",
"jest": "27.5.1",
"resize-observer-polyfill": "^1.5.1",
"rosie": "2.1.0"
}
}
Binary file added src/assets/images/appStore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/googleplay.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions src/components/NavigationBar/NavigationBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import { useHistory, useLocation } from 'react-router-dom';

import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Tabs, Tab } from '@edx/paragon';
import { getConfig } from '@edx/frontend-platform';
import { ROUTES } from '../../constants';

import messages from './messages';

function NavigationBar({ intl }) {
const NavigationTabs = [
{
id: 'learnerRecords',
path: ROUTES.PROGRAM_RECORDS,
},
];

if (getConfig().ENABLE_VERIFIABLE_CREDENTIALS) {
NavigationTabs.push({
id: 'verifiableCredentials',
path: ROUTES.VERIFIABLE_CREDENTIALS,
});
}

const history = useHistory();
const location = useLocation();

return NavigationTabs.length > 1 ? (
<Tabs
className="mt-1 mb-5"
defaultActiveKey={location.pathname}
onSelect={path => history.push(path)}
>
{NavigationTabs.map(tab => (
<Tab
key={tab.id}
eventKey={tab.path}
title={intl.formatMessage(messages[tab.id])}
/>
))}
</Tabs>
) : null;
}

NavigationBar.propTypes = {
intl: intlShape.isRequired,
};

export default injectIntl(NavigationBar);
2 changes: 2 additions & 0 deletions src/components/NavigationBar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-restricted-exports
export { default } from './NavigationBar';
16 changes: 16 additions & 0 deletions src/components/NavigationBar/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineMessages } from '@edx/frontend-platform/i18n';

const messages = defineMessages({
learnerRecords: {
id: 'learnerRecords',
defaultMessage: 'My Learner Records',
description: 'A message of Learner Records navigation tab',
},
verifiableCredentials: {
id: 'verifiableCredentials',
defaultMessage: 'Verifiable Credentials',
description: 'A message of Verifiable Credentials navigation tab',
},
});

export default messages;
48 changes: 48 additions & 0 deletions src/components/NavigationBar/test/NavigationBar.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @jest-environment jsdom
*/
import React from 'react';
import { mergeConfig } from '@edx/frontend-platform';
import {
render, screen, cleanup, initializeMockApp, fireEvent,
} from '../../../setupTest';
import NavigationBar from '..';

const mockHistoryPush = jest.fn();
global.ResizeObserver = require('resize-observer-polyfill');

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: () => ({
push: mockHistoryPush,
}),
}));

describe('navigation-bar', () => {
beforeAll(async () => {
await initializeMockApp();
});
beforeEach(() => {
mergeConfig({ ENABLE_VERIFIABLE_CREDENTIALS: 'true' });
return jest.resetModules;
});
afterEach(cleanup);

it('not renders the component with disabled the Verifiable Credentials functionality', () => {
mergeConfig({ ENABLE_VERIFIABLE_CREDENTIALS: false });
const { container } = render(<NavigationBar />);
expect(container.innerHTML).toHaveLength(0);
});

it('renders the component with enabled the Verifiable Credentials functionality', () => {
render(<NavigationBar />);
expect(screen.getByText('My Learner Records')).toBeTruthy();
expect(screen.getByText('Verifiable Credentials')).toBeTruthy();
});

it('redirects the appropriate route on tab click', () => {
render(<NavigationBar />);
fireEvent.click(screen.getByText('Verifiable Credentials'));
expect(mockHistoryPush).toHaveBeenCalledWith('/verifiable-credentials');
});
});
Loading

0 comments on commit f2b7990

Please sign in to comment.