Skip to content

Commit

Permalink
Merge branch 'master' into inspectorBgone
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-henz committed Jun 21, 2021
2 parents 6016643 + 65db52c commit 59dc382
Show file tree
Hide file tree
Showing 30 changed files with 881 additions and 1,032 deletions.
13 changes: 3 additions & 10 deletions src/commons/application/Application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import Academy from '../../pages/academy/AcademyContainer';
import Achievement from '../../pages/achievement/AchievementContainer';
import Contributors from '../../pages/contributors/Contributors';
import Disabled from '../../pages/disabled/Disabled';
import GitHubAssessmentWorkspaceContainer from '../../pages/githubAssessments/GitHubAssessmentWorkspaceContainer';
import GitHubMissionListing from '../../pages/githubAssessments/GitHubMissionListing';
import GitHubClassroom from '../../pages/githubAssessments/GitHubClassroom';
import GitHubCallback from '../../pages/githubCallback/GitHubCallback';
import Login from '../../pages/login/LoginContainer';
import MissionControlContainer from '../../pages/missionControl/MissionControlContainer';
Expand Down Expand Up @@ -149,21 +148,15 @@ const Application: React.FC<ApplicationProps> = props => {
<Route path="/sourcecast/:sourcecastId?" component={SourcecastContainer} />
{Constants.enableGitHubAssessments && (
<Route
path="/githubassessments/missions"
path="/githubassessments"
component={() => (
<GitHubMissionListing
<GitHubClassroom
handleGitHubLogIn={props.handleGitHubLogIn}
handleGitHubLogOut={props.handleGitHubLogOut}
/>
)}
/>
)}
{Constants.enableGitHubAssessments && (
<Route
path="/githubassessments/editor"
component={GitHubAssessmentWorkspaceContainer}
/>
)}
<Route path="/callback/github" component={GitHubCallback} />
<Route exact path="/interactive-sicp" render={redirectToSicp} />
<Route path="/interactive-sicp/:section" component={Sicp} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ exports[`Application renders correctly 1`] = `
<Route path=\\"/playground\\" component={[Function: C] { displayName: 'withRouter(Connect(Playground))', WrappedComponent: [Function: Playground], propTypes: { wrappedComponentRef: [Function: bound checkType] { isRequired: [Function: bound checkType] } } }} />
<Route path=\\"/contributors\\" component={[function]} />
<Route path=\\"/sourcecast/:sourcecastId?\\" component={[Function: C] { displayName: 'withRouter(Connect(Sourcecast))', WrappedComponent: [Function: Sourcecast], propTypes: { wrappedComponentRef: [Function: bound checkType] { isRequired: [Function: bound checkType] } } }} />
<Route path=\\"/githubassessments/missions\\" component={[Function: component]} />
<Route path=\\"/githubassessments/editor\\" component={[Function: C] { displayName: 'withRouter(Connect(GitHubAssessmentWorkspace))', WrappedComponent: [Function: GitHubAssessmentWorkspace], propTypes: { wrappedComponentRef: [Function: bound checkType] { isRequired: [Function: bound checkType] } } }} />
<Route path=\\"/githubassessments\\" component={[Function: component]} />
<Route path=\\"/callback/github\\" component={[Function: GitHubCallback]} />
<Route exact={true} path=\\"/interactive-sicp\\" render={[Function: redirectToSicp]} />
<Route path=\\"/interactive-sicp/:section\\" component={[Function: Sicp]} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as React from 'react';
import { useSelector } from 'react-redux';
import { useMediaQuery } from 'react-responsive';

import { OverallState } from '../../application/ApplicationTypes';
import controlButton from '../../ControlButton';
import Constants from '../../utils/Constants';

Expand All @@ -20,7 +21,7 @@ export type ControlBarGitHubLoginButtonProps = {
export const ControlBarGitHubLoginButton: React.FC<ControlBarGitHubLoginButtonProps> = props => {
const isMobileBreakpoint = useMediaQuery({ maxWidth: Constants.mobileBreakpoint });
const isLoggedIn =
useSelector((store: any) => store.session.githubOctokitObject).octokit !== undefined;
useSelector((store: OverallState) => store.session.githubOctokitObject).octokit !== undefined;

const loginButton = isLoggedIn
? controlButton('Log Out', IconNames.GIT_BRANCH, props.onClickLogOut)
Expand Down
91 changes: 9 additions & 82 deletions src/commons/githubAssessments/GitHubMissionDataUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,91 +265,18 @@ export async function getContentAsString(
* @param metadataString The file contents of the '.metadata' file of a mission repository
*/
function convertMetadataStringToMissionMetadata(metadataString: string) {
const missionMetadata: MissionMetadata = {
coverImage: '',
type: '',
id: '',
title: '',
sourceVersion: 1,
dueDate: new Date(8640000000000000),
reading: '',
webSummary: ''
};
const stringPropsToExtract = ['coverImage', 'type', 'id', 'title', 'reading', 'webSummary'];
const numPropsToExtract = ['sourceVersion'];
const datePropsToExtract = ['dueDate'];

const retVal = parseMetadataProperties<MissionMetadata>(
missionMetadata,
stringPropsToExtract,
numPropsToExtract,
datePropsToExtract,
metadataString
);

return retVal;
try {
return JSON.parse(metadataString) as MissionMetadata;
} catch (err) {
console.error(err);
return {
sourceVersion: 4
} as MissionMetadata;
}
}

function convertMissionMetadataToMetadataString(missionMetadata: MissionMetadata) {
const properties: string[] = [
'title',
'coverImage',
'webSummary',
'dueDate',
'type',
'id',
'sourceVersion',
'reading'
];
const propertyValuePairs = properties.map(property => property + '=' + missionMetadata[property]);
return propertyValuePairs.join('\n');
}

/**
* Converts the contents of a '.metadata' file into an object of type R.
*
* @param propertyContainer The object of which properties will be set
* @param stringProps An array containing the names of properties with string values
* @param numProps An array containing the names of properties with numerical values
* @param dateProps An array containing the names of properties with date values
* @param metadataString The content of the '.metadata' file to be parsed
*/
export function parseMetadataProperties<R>(
propertyContainer: R,
stringProps: string[],
numProps: string[],
dateProps: string[],
metadataString: string
) {
const lines = metadataString.replace(/\r/g, '').split(/\n/);

lines.forEach(line => {
for (let i = 0; i < stringProps.length; i++) {
const propName = stringProps[i];
if (line.startsWith(propName)) {
propertyContainer[propName] = line.substr(propName.length + 1);
return;
}
}

for (let i = 0; i < numProps.length; i++) {
const propName = numProps[i];
if (line.startsWith(propName)) {
propertyContainer[propName] = parseInt(line.substr(propName.length + 1), 10);
return;
}
}

for (let i = 0; i < dateProps.length; i++) {
const propName = dateProps[i];
if (line.startsWith(propName)) {
propertyContainer[propName] = new Date(line.substr(propName.length + 1));
return;
}
}
});

return propertyContainer;
return jsonStringify(missionMetadata);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as React from 'react';
import { useSelector } from 'react-redux';
import { useMediaQuery } from 'react-responsive';

import { OverallState } from '../application/ApplicationTypes';
import controlButton from '../ControlButton';
import Constants from '../utils/Constants';

Expand All @@ -21,7 +22,7 @@ export const ControlBarGitHubMobileLoginButton: React.FC<ControlBarGitHubMobileL
props => {
const isMobileBreakpoint = useMediaQuery({ maxWidth: Constants.mobileBreakpoint });
const isLoggedIn =
useSelector((store: any) => store.session.githubOctokitObject).octokit !== undefined;
useSelector((store: OverallState) => store.session.githubOctokitObject).octokit !== undefined;

const loginButton = isLoggedIn
? controlButton('Log Out', IconNames.GIT_BRANCH, props.onClickLogOut)
Expand Down
8 changes: 0 additions & 8 deletions src/commons/githubAssessments/GitHubMissionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,7 @@ export type TaskData = {
* An code representation of a GitHub-hosted mission's '.metadata' file.
*/
export type MissionMetadata = {
coverImage: string;
type: string;
id: string;
title: string;
sourceVersion: number;
dueDate: Date;

reading: string;
webSummary: string;
};

/**
Expand Down
62 changes: 5 additions & 57 deletions src/commons/githubAssessments/__tests__/GitHubMissionDataUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Octokit } from '@octokit/rest';

import { IMCQQuestion } from '../../assessment/AssessmentTypes';
import * as GitHubMissionDataUtils from '../GitHubMissionDataUtils';
import { MissionMetadata, MissionRepoData } from '../GitHubMissionTypes';
import { MissionRepoData } from '../GitHubMissionTypes';

test('getContentAsString correctly gets content and translates from Base64 to utf-8', async () => {
const octokit = new Octokit();
Expand All @@ -23,40 +23,6 @@ test('getContentAsString correctly gets content and translates from Base64 to ut
expect(content).toBe('Hello World!');
});

test('parseMetadataProperties correctly discovers properties', () => {
const missionMetadata = Object.assign({}, dummyMissionMetadata);
const stringPropsToExtract = ['coverImage', 'type', 'id', 'title', 'reading', 'webSummary'];
const numPropsToExtract = ['sourceVersion'];
const datePropsToExtract = ['dueDate'];

const metadataString =
'coverImage=www.somelink.com\n' +
'type=Mission\n' +
'id=M3\n' +
'title=Dummy Mission\n' +
'reading=Textbook Pages 1 to 234763\n' +
'dueDate=December 17, 1995 03:24:00\n' +
'webSummary=no\n' +
'sourceVersion=3';

const retVal = GitHubMissionDataUtils.parseMetadataProperties<MissionMetadata>(
missionMetadata,
stringPropsToExtract,
numPropsToExtract,
datePropsToExtract,
metadataString
);

expect(retVal.coverImage).toBe('www.somelink.com');
expect(retVal.type).toBe('Mission');
expect(retVal.id).toBe('M3');
expect(retVal.title).toBe('Dummy Mission');
expect(retVal.reading).toBe('Textbook Pages 1 to 234763');
expect(retVal.webSummary).toBe('no');
expect(retVal.sourceVersion).toBe(3);
expect(retVal.dueDate).toStrictEqual(new Date('December 17, 1995 03:24:00'));
});

test('getMissionData works properly', async () => {
const missionRepoData: MissionRepoData = {
repoOwner: 'Pain',
Expand All @@ -79,13 +45,9 @@ test('getMissionData works properly', async () => {
// Metadata String
const contentResponse = generateGetContentResponse();
(contentResponse.data as any).content = Buffer.from(
'coverImage=www.somelink.com\n' +
'type=Mission\n' +
'id=M3\n' +
'title=Dummy Mission\n' +
'reading=Textbook Pages 1 to 234763\n' +
'webSummary=no\n' +
'sourceVersion=3',
`{
"sourceVersion": 3
}`,
'utf-8'
).toString('base64');
return contentResponse;
Expand Down Expand Up @@ -183,13 +145,6 @@ test('getMissionData works properly', async () => {
expect(missionData.missionRepoData.repoName).toBe('Peko');

expect(missionData.missionBriefing).toBe('Briefing Content');

expect(missionData.missionMetadata.coverImage).toBe('www.somelink.com');
expect(missionData.missionMetadata.type).toBe('Mission');
expect(missionData.missionMetadata.id).toBe('M3');
expect(missionData.missionMetadata.title).toBe('Dummy Mission');
expect(missionData.missionMetadata.reading).toBe('Textbook Pages 1 to 234763');
expect(missionData.missionMetadata.webSummary).toBe('no');
expect(missionData.missionMetadata.sourceVersion).toBe(3);

expect(missionData.tasksData.length).toBe(2);
Expand Down Expand Up @@ -932,14 +887,7 @@ function generateGetContentResponse() {
}

const dummyMissionMetadata = {
coverImage: 'www.eh',
type: 'mission',
id: 'M2',
title: 'Dummy',
sourceVersion: 1,
dueDate: new Date('December 17, 1996 03:24:00'),
reading: 'none',
webSummary: 'no'
sourceVersion: 1
};

const defaultMissionMetadata = {
Expand Down
14 changes: 4 additions & 10 deletions src/commons/navigationBar/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ import classNames from 'classnames';
import * as React from 'react';
import { useMediaQuery } from 'react-responsive';
import { NavLink, Route, Switch } from 'react-router-dom';
import SicpNavigationBar from 'src/commons/navigationBar/subcomponents/SicpNavigationBar';

import SicpNavigationBar from '../../commons/navigationBar/subcomponents/SicpNavigationBar';
import { Role } from '../application/ApplicationTypes';
import Dropdown from '../dropdown/Dropdown';
import Constants from '../utils/Constants';
import AcademyNavigationBar from './subcomponents/AcademyNavigationBar';
import GitHubAssessmentsNavigationBar from './subcomponents/GitHubAssessmentsNavigationBar';
import NavigationBarMobileSideMenu from './subcomponents/NavigationBarMobileSideMenu';

type NavigationBarProps = DispatchProps & StateProps;
Expand Down Expand Up @@ -129,7 +128,7 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
<NavLink
activeClassName={Classes.ACTIVE}
className={classNames('NavigationBar__link__mobile', Classes.BUTTON, Classes.MINIMAL)}
to="/githubassessments/missions"
to="/githubassessments"
>
<Icon icon={IconNames.BRIEFCASE} />
<div>GitHub Assessments</div>
Expand Down Expand Up @@ -225,10 +224,10 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
<NavLink
activeClassName={Classes.ACTIVE}
className={classNames('NavigationBar__link', Classes.BUTTON, Classes.MINIMAL)}
to="/githubassessments/missions"
to="/githubassessments"
>
<Icon icon={IconNames.BRIEFCASE} />
<div className="navbar-button-text">GitHub Assessments</div>
<div className="navbar-button-text">Classroom</div>
</NavLink>
)}

Expand Down Expand Up @@ -302,11 +301,6 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
</Navbar>

<Switch>
<Route path="/githubassessments">
{Constants.enableGitHubAssessments && !isMobileBreakpoint && desktopMenuOpen && (
<GitHubAssessmentsNavigationBar {...props} />
)}
</Route>
<Route path="/interactive-sicp/:section?">
<SicpNavigationBar />
</Route>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ exports[`NavigationBar renders "Not logged in" correctly 1`] = `
Playground
</div>
</NavLink>
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/githubassessments/missions\\">
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/githubassessments\\">
<Blueprint3.Icon icon=\\"briefcase\\" />
<div className=\\"navbar-button-text\\">
GitHub Assessments
Classroom
</div>
</NavLink>
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/interactive-sicp/index\\">
Expand All @@ -52,9 +52,6 @@ exports[`NavigationBar renders "Not logged in" correctly 1`] = `
</Blueprint3.NavbarGroup>
</Blueprint3.Navbar>
<Switch>
<Route path=\\"/githubassessments\\">
<GitHubAssessmentsNavigationBar handleLogOut={[Function: handleLogOut]} handleGitHubLogIn={[Function: handleGitHubLogIn]} handleGitHubLogOut={[Function: handleGitHubLogOut]} title=\\"Source Academy\\" />
</Route>
<Route path=\\"/interactive-sicp/:section?\\">
<SicpNavigationBar />
</Route>
Expand Down Expand Up @@ -85,10 +82,10 @@ exports[`NavigationBar renders correctly with student role 1`] = `
Playground
</div>
</NavLink>
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/githubassessments/missions\\">
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/githubassessments\\">
<Blueprint3.Icon icon=\\"briefcase\\" />
<div className=\\"navbar-button-text\\">
GitHub Assessments
Classroom
</div>
</NavLink>
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/interactive-sicp/index\\">
Expand Down Expand Up @@ -125,9 +122,6 @@ exports[`NavigationBar renders correctly with student role 1`] = `
</Blueprint3.NavbarGroup>
</Blueprint3.Navbar>
<Switch>
<Route path=\\"/githubassessments\\">
<GitHubAssessmentsNavigationBar handleLogOut={[Function: handleLogOut]} handleGitHubLogIn={[Function: handleGitHubLogIn]} handleGitHubLogOut={[Function: handleGitHubLogOut]} role=\\"student\\" title=\\"Source Academy\\" />
</Route>
<Route path=\\"/interactive-sicp/:section?\\">
<SicpNavigationBar />
</Route>
Expand Down
Loading

0 comments on commit 59dc382

Please sign in to comment.