feat(client): show and execute backend project tests (#35673)
This commit is contained in:
parent
1abe4971f4
commit
839e81426e
@ -12,6 +12,7 @@ import {
|
||||
consoleOutputSelector,
|
||||
initTests,
|
||||
updateChallengeMeta,
|
||||
updateProjectFormValues,
|
||||
backendNS
|
||||
} from '../redux';
|
||||
import { createGuideUrl } from '../utils';
|
||||
@ -24,6 +25,7 @@ import Output from '../components/Output';
|
||||
import CompletionModal from '../components/CompletionModal';
|
||||
import HelpModal from '../components/HelpModal';
|
||||
import ProjectToolPanel from '../project/Tool-Panel';
|
||||
import ProjectForm from '../project/ProjectForm';
|
||||
import {
|
||||
createFormValidator,
|
||||
isValidURL,
|
||||
@ -32,6 +34,8 @@ import {
|
||||
} from '../../../components/formHelpers';
|
||||
import Spacer from '../../../components/helpers/Spacer';
|
||||
|
||||
import { backend } from '../../../../utils/challengeTypes';
|
||||
|
||||
import '../components/test-frame.css';
|
||||
|
||||
// provided by redux form
|
||||
@ -52,6 +56,7 @@ const propTypes = {
|
||||
tests: PropTypes.array,
|
||||
title: PropTypes.string,
|
||||
updateChallengeMeta: PropTypes.func.isRequired,
|
||||
updateProjectFormValues: PropTypes.func.isRequired,
|
||||
...reduxFormPropTypes
|
||||
};
|
||||
|
||||
@ -74,7 +79,8 @@ const mapDispatchToActions = {
|
||||
challengeMounted,
|
||||
executeChallenge,
|
||||
initTests,
|
||||
updateChallengeMeta
|
||||
updateChallengeMeta,
|
||||
updateProjectFormValues
|
||||
};
|
||||
|
||||
const formFields = ['solution'];
|
||||
@ -150,6 +156,7 @@ export class BackEnd extends Component {
|
||||
data: {
|
||||
challengeNode: {
|
||||
fields: { blockName, slug },
|
||||
challengeType,
|
||||
title,
|
||||
description,
|
||||
instructions
|
||||
@ -158,7 +165,8 @@ export class BackEnd extends Component {
|
||||
output,
|
||||
tests,
|
||||
submitting,
|
||||
executeChallenge
|
||||
executeChallenge,
|
||||
updateProjectFormValues
|
||||
} = this.props;
|
||||
|
||||
// TODO: Should be tied to user.isSignedIn
|
||||
@ -177,13 +185,21 @@ export class BackEnd extends Component {
|
||||
description={description}
|
||||
instructions={instructions}
|
||||
/>
|
||||
<Form
|
||||
buttonText={`${buttonCopy} (Ctrl + Enter)`}
|
||||
formFields={formFields}
|
||||
id={backendNS}
|
||||
options={options}
|
||||
submit={executeChallenge}
|
||||
/>
|
||||
{challengeType === backend ? (
|
||||
<Form
|
||||
buttonText={`${buttonCopy}`}
|
||||
formFields={formFields}
|
||||
id={backendNS}
|
||||
options={options}
|
||||
submit={executeChallenge}
|
||||
/>
|
||||
) : (
|
||||
<ProjectForm
|
||||
isFrontEnd={false}
|
||||
onSubmit={executeChallenge}
|
||||
updateProjectForm={updateProjectFormValues}
|
||||
/>
|
||||
)}
|
||||
<ProjectToolPanel guideUrl={createGuideUrl(slug)} />
|
||||
<br />
|
||||
<Output
|
||||
|
@ -1,32 +1,18 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
Form
|
||||
// isValidURL,
|
||||
// makeRequired,
|
||||
// createFormValidator
|
||||
} from '../../../components/formHelpers';
|
||||
import { Form } from '../../../components/formHelpers';
|
||||
|
||||
const propTypes = {
|
||||
isFrontEnd: PropTypes.bool,
|
||||
isSubmitting: PropTypes.bool,
|
||||
openModal: PropTypes.func.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
updateProjectForm: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const frontEndFields = ['solution'];
|
||||
const backEndFields = ['solution', 'githubLink'];
|
||||
|
||||
// const fieldValidators = {
|
||||
// solution: makeRequired(isValidURL)
|
||||
// };
|
||||
|
||||
// const backEndFieldValidators = {
|
||||
// ...fieldValidators,
|
||||
// githubLink: makeRequired(isValidURL)
|
||||
// };
|
||||
|
||||
const options = {
|
||||
types: {
|
||||
solution: 'url',
|
||||
@ -38,64 +24,20 @@ const options = {
|
||||
export class ProjectForm extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
keysDown: {
|
||||
Control: false,
|
||||
Enter: false
|
||||
}
|
||||
};
|
||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||
this.handleKeyUp = this.handleKeyUp.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
}
|
||||
componentDidMount() {
|
||||
this.props.updateProjectForm({});
|
||||
window.addEventListener('keydown', this.handleKeyDown);
|
||||
window.addEventListener('keyup', this.handleKeyUp);
|
||||
}
|
||||
componentDidUpdate() {
|
||||
this.props.updateProjectForm({});
|
||||
}
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('keydown', this.handleKeyDown);
|
||||
window.removeEventListener('keyup', this.handleKeyUp);
|
||||
}
|
||||
handleKeyDown(e) {
|
||||
if (e.key === 'Control') {
|
||||
this.setState(state => ({
|
||||
...state,
|
||||
keysDown: { ...state.keysDown, Control: true }
|
||||
}));
|
||||
}
|
||||
if (e.key === 'Enter') {
|
||||
this.setState(state => ({
|
||||
...state,
|
||||
keysDown: { ...state.keysDown, Enter: true }
|
||||
}));
|
||||
}
|
||||
}
|
||||
handleKeyUp(e) {
|
||||
if (e.key === 'Control') {
|
||||
this.setState(state => ({
|
||||
...state,
|
||||
keysDown: { ...state.keysDown, Control: false }
|
||||
}));
|
||||
}
|
||||
if (e.key === 'Enter') {
|
||||
this.setState(state => ({
|
||||
...state,
|
||||
keysDown: { ...state.keysDown, Enter: false }
|
||||
}));
|
||||
}
|
||||
this.props.updateProjectForm({});
|
||||
}
|
||||
handleSubmit(values) {
|
||||
const {
|
||||
keysDown: { Control, Enter }
|
||||
} = this.state;
|
||||
if ((Control && Enter) || !Enter) {
|
||||
this.props.openModal('completion');
|
||||
this.props.updateProjectForm(values);
|
||||
}
|
||||
this.props.updateProjectForm(values);
|
||||
this.props.onSubmit();
|
||||
}
|
||||
render() {
|
||||
const { isSubmitting, isFrontEnd } = this.props;
|
||||
@ -104,14 +46,11 @@ export class ProjectForm extends Component {
|
||||
: "I've completed this challenge";
|
||||
return (
|
||||
<Form
|
||||
buttonText={`${buttonCopy} (Ctrl + Enter)`}
|
||||
buttonText={`${buttonCopy}`}
|
||||
formFields={isFrontEnd ? frontEndFields : backEndFields}
|
||||
id={isFrontEnd ? 'front-end-form' : 'back-end-form'}
|
||||
options={options}
|
||||
submit={this.handleSubmit}
|
||||
// validate={createFormValidator(
|
||||
// isFrontEnd ? fieldValidators : backEndFieldValidators
|
||||
// )}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ export class Project extends Component {
|
||||
/>
|
||||
<ProjectForm
|
||||
isFrontEnd={isFrontEnd}
|
||||
openModal={openCompletionModal}
|
||||
onSubmit={openCompletionModal}
|
||||
updateProjectForm={updateProjectFormValues}
|
||||
/>
|
||||
<ToolPanel guideUrl={createGuideUrl(slug)} />
|
||||
|
@ -192,10 +192,15 @@ export const challengeDataSelector = state => {
|
||||
...challengeData,
|
||||
url
|
||||
};
|
||||
} else if (
|
||||
challengeType === challengeTypes.frontEndProject ||
|
||||
challengeType === challengeTypes.backendEndProject
|
||||
) {
|
||||
} else if (challengeType === challengeTypes.backEndProject) {
|
||||
const values = projectFormValuesSelector(state);
|
||||
const { solution: url } = values;
|
||||
challengeData = {
|
||||
...challengeData,
|
||||
...values,
|
||||
url
|
||||
};
|
||||
} else if (challengeType === challengeTypes.frontEndProject) {
|
||||
challengeData = {
|
||||
...challengeData,
|
||||
...projectFormValuesSelector(state)
|
||||
|
@ -61,7 +61,8 @@ const buildFunctions = {
|
||||
[challengeTypes.bonfire]: buildJSChallenge,
|
||||
[challengeTypes.html]: buildDOMChallenge,
|
||||
[challengeTypes.modern]: buildDOMChallenge,
|
||||
[challengeTypes.backend]: buildBackendChallenge
|
||||
[challengeTypes.backend]: buildBackendChallenge,
|
||||
[challengeTypes.backEndProject]: buildBackendChallenge
|
||||
};
|
||||
|
||||
export async function buildChallenge(challengeData) {
|
||||
|
@ -40,7 +40,7 @@ exports.viewTypes = {
|
||||
[js]: 'classic',
|
||||
[bonfire]: 'classic',
|
||||
[frontEndProject]: 'project',
|
||||
[backEndProject]: 'project',
|
||||
[backEndProject]: 'backend',
|
||||
[modern]: 'modern',
|
||||
[step]: 'step',
|
||||
[quiz]: 'quiz',
|
||||
|
Loading…
x
Reference in New Issue
Block a user