Merge pull request #430 from edx/alangsto/add_photo_mode_to_submit
Add additional post parameters to track photo modes
This commit is contained in:
@@ -262,6 +262,7 @@ class Camera extends React.Component {
|
||||
const dataUri = this.cameraPhoto.getDataUri(config);
|
||||
this.setState({ dataUri });
|
||||
this.props.onImageCapture(dataUri);
|
||||
this.props.setPhotoMode('camera');
|
||||
}
|
||||
|
||||
playShutterClick() {
|
||||
@@ -359,6 +360,7 @@ class Camera extends React.Component {
|
||||
Camera.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
onImageCapture: PropTypes.func.isRequired,
|
||||
setPhotoMode: PropTypes.func.isRequired,
|
||||
isPortrait: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
|
||||
@@ -79,6 +79,10 @@ export default function IdVerificationContextProvider({ children }) {
|
||||
const [optimizelyExperimentName, setOptimizelyExperimentName] = useState('');
|
||||
const [shouldUseCamera, setShouldUseCamera] = useState(false);
|
||||
|
||||
// The following are used to keep track of how a user has submitted photos
|
||||
const [portraitPhotoMode, setPortraitPhotoMode] = useState('');
|
||||
const [idPhotoMode, setIdPhotoMode] = useState('');
|
||||
|
||||
// If the user reaches the end of the flow and goes back to retake their photos,
|
||||
// this flag ensures that they are directed straight back to the summary panel
|
||||
const [reachedSummary, setReachedSummary] = useState(false);
|
||||
@@ -95,6 +99,8 @@ export default function IdVerificationContextProvider({ children }) {
|
||||
profileDataManager,
|
||||
optimizelyExperimentName,
|
||||
shouldUseCamera,
|
||||
portraitPhotoMode,
|
||||
idPhotoMode,
|
||||
reachedSummary,
|
||||
setExistingIdVerification,
|
||||
setFacePhotoFile,
|
||||
@@ -102,6 +108,8 @@ export default function IdVerificationContextProvider({ children }) {
|
||||
setIdPhotoName,
|
||||
setOptimizelyExperimentName,
|
||||
setShouldUseCamera,
|
||||
setPortraitPhotoMode,
|
||||
setIdPhotoMode,
|
||||
setReachedSummary,
|
||||
tryGetUserMedia: async () => {
|
||||
try {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Alert } from '@edx/paragon';
|
||||
import messages from './IdVerification.messages';
|
||||
import SupportedMediaTypes from './SupportedMediaTypes';
|
||||
|
||||
export default function ImageFileUpload({ onFileChange, intl }) {
|
||||
export default function ImageFileUpload({ onFileChange, setPhotoMode, intl }) {
|
||||
const [error, setError] = useState(null);
|
||||
const errorTypes = {
|
||||
invalidFileType: 'invalidFileType',
|
||||
@@ -26,7 +26,10 @@ export default function ImageFileUpload({ onFileChange, intl }) {
|
||||
} else {
|
||||
setError(null);
|
||||
const fileReader = new FileReader();
|
||||
fileReader.addEventListener('load', () => onFileChange(fileReader.result));
|
||||
fileReader.addEventListener('load', () => {
|
||||
onFileChange(fileReader.result);
|
||||
setPhotoMode('upload');
|
||||
});
|
||||
fileReader.readAsDataURL(fileObject);
|
||||
}
|
||||
}, []);
|
||||
@@ -56,5 +59,6 @@ export default function ImageFileUpload({ onFileChange, intl }) {
|
||||
|
||||
ImageFileUpload.propTypes = {
|
||||
onFileChange: PropTypes.func.isRequired,
|
||||
setPhotoMode: PropTypes.func.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
@@ -65,6 +65,8 @@ export async function submitIdVerification(verificationData) {
|
||||
idPhotoFile: 'photo_id_image',
|
||||
idPhotoName: 'full_name',
|
||||
optimizelyExperimentName: 'experiment_name',
|
||||
portraitPhotoMode: 'portrait_photo_mode',
|
||||
idPhotoMode: 'id_photo_mode',
|
||||
};
|
||||
const postData = {};
|
||||
// Don't include blank/null/undefined values.
|
||||
|
||||
@@ -28,6 +28,8 @@ function SummaryPanel(props) {
|
||||
stopUserMedia,
|
||||
optimizelyExperimentName,
|
||||
setReachedSummary,
|
||||
portraitPhotoMode,
|
||||
idPhotoMode,
|
||||
} = useContext(IdVerificationContext);
|
||||
const nameToBeUsed = idPhotoName || nameOnAccount || '';
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
@@ -73,6 +75,8 @@ function SummaryPanel(props) {
|
||||
}
|
||||
if (optimizelyExperimentName) {
|
||||
verificationData.optimizelyExperimentName = optimizelyExperimentName;
|
||||
verificationData.portraitPhotoMode = portraitPhotoMode;
|
||||
verificationData.idPhotoMode = idPhotoMode;
|
||||
}
|
||||
const result = await submitIdVerification(verificationData);
|
||||
if (result.success) {
|
||||
|
||||
@@ -18,7 +18,7 @@ function TakeIdPhotoPanel(props) {
|
||||
const panelSlug = 'take-id-photo';
|
||||
const nextPanelSlug = useNextPanelSlug(panelSlug);
|
||||
const {
|
||||
setIdPhotoFile, idPhotoFile, optimizelyExperimentName, shouldUseCamera,
|
||||
setIdPhotoFile, idPhotoFile, optimizelyExperimentName, shouldUseCamera, setIdPhotoMode,
|
||||
} = useContext(IdVerificationContext);
|
||||
|
||||
return (
|
||||
@@ -34,7 +34,7 @@ function TakeIdPhotoPanel(props) {
|
||||
<p>
|
||||
{props.intl.formatMessage(messages['id.verification.id.photo.instructions.camera'])}
|
||||
</p>
|
||||
<Camera onImageCapture={setIdPhotoFile} isPortrait={false} />
|
||||
<Camera onImageCapture={setIdPhotoFile} setPhotoMode={setIdPhotoMode} isPortrait={false} />
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ marginBottom: '1.25rem' }}>
|
||||
@@ -42,7 +42,7 @@ function TakeIdPhotoPanel(props) {
|
||||
{props.intl.formatMessage(messages['id.verification.id.photo.instructions.upload'])}
|
||||
<SupportedMediaTypes />
|
||||
</p>
|
||||
<ImageFileUpload onFileChange={setIdPhotoFile} intl={props.intl} />
|
||||
<ImageFileUpload onFileChange={setIdPhotoFile} setPhotoMode={setIdPhotoMode} intl={props.intl} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ function TakePortraitPhotoPanel(props) {
|
||||
const panelSlug = 'take-portrait-photo';
|
||||
const nextPanelSlug = useNextPanelSlug(panelSlug);
|
||||
const {
|
||||
setFacePhotoFile, facePhotoFile, shouldUseCamera, optimizelyExperimentName,
|
||||
setFacePhotoFile, facePhotoFile, shouldUseCamera, optimizelyExperimentName, setPortraitPhotoMode,
|
||||
} = useContext(IdVerificationContext);
|
||||
|
||||
return (
|
||||
@@ -34,7 +34,7 @@ function TakePortraitPhotoPanel(props) {
|
||||
<p>
|
||||
{props.intl.formatMessage(messages['id.verification.portrait.photo.instructions.camera'])}
|
||||
</p>
|
||||
<Camera onImageCapture={setFacePhotoFile} isPortrait />
|
||||
<Camera onImageCapture={setFacePhotoFile} setPhotoMode={setPortraitPhotoMode} isPortrait />
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ marginBottom: '1.25rem' }}>
|
||||
@@ -42,7 +42,7 @@ function TakePortraitPhotoPanel(props) {
|
||||
{props.intl.formatMessage(messages['id.verification.portrait.photo.instructions.upload'])}
|
||||
<SupportedMediaTypes />
|
||||
</p>
|
||||
<ImageFileUpload onFileChange={setFacePhotoFile} intl={props.intl} />
|
||||
<ImageFileUpload onFileChange={setFacePhotoFile} setPhotoMode={setPortraitPhotoMode} intl={props.intl} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -28,6 +28,7 @@ describe('SubmittedPanel', () => {
|
||||
const defaultProps = {
|
||||
intl: {},
|
||||
onImageCapture: jest.fn(),
|
||||
setPhotoMode: jest.fn(),
|
||||
isPortrait: true,
|
||||
};
|
||||
|
||||
@@ -57,6 +58,7 @@ describe('SubmittedPanel', () => {
|
||||
expect(button).toHaveTextContent('Take Photo');
|
||||
fireEvent.click(button);
|
||||
expect(defaultProps.onImageCapture).toHaveBeenCalled();
|
||||
expect(defaultProps.setPhotoMode).toHaveBeenCalledWith('camera');
|
||||
});
|
||||
|
||||
it('shows correct help text for portrait photo capture', async () => {
|
||||
|
||||
@@ -33,6 +33,8 @@ describe('SummaryPanel', () => {
|
||||
nameOnAccount: 'test name',
|
||||
idPhotoName: 'test name',
|
||||
optimizelyExperimentName: 'test-experiment',
|
||||
portraitPhotoMode: 'camera',
|
||||
idPhotoMode: 'upload',
|
||||
stopUserMedia: jest.fn(),
|
||||
setReachedSummary: jest.fn(),
|
||||
};
|
||||
@@ -92,6 +94,8 @@ describe('SummaryPanel', () => {
|
||||
idPhotoFile: contextValue.idPhotoFile,
|
||||
idPhotoName: contextValue.idPhotoName,
|
||||
optimizelyExperimentName: contextValue.optimizelyExperimentName,
|
||||
portraitPhotoMode: contextValue.portraitPhotoMode,
|
||||
idPhotoMode: contextValue.idPhotoMode,
|
||||
courseRunKey: null,
|
||||
};
|
||||
await getPanel();
|
||||
@@ -106,6 +110,8 @@ describe('SummaryPanel', () => {
|
||||
const verificationData = {
|
||||
facePhotoFile: contextValue.facePhotoFile,
|
||||
idPhotoFile: contextValue.idPhotoFile,
|
||||
portraitPhotoMode: contextValue.portraitPhotoMode,
|
||||
idPhotoMode: contextValue.idPhotoMode,
|
||||
optimizelyExperimentName: contextValue.optimizelyExperimentName,
|
||||
courseRunKey: null,
|
||||
};
|
||||
@@ -120,6 +126,8 @@ describe('SummaryPanel', () => {
|
||||
const verificationData = {
|
||||
facePhotoFile: contextValue.facePhotoFile,
|
||||
idPhotoFile: contextValue.idPhotoFile,
|
||||
portraitPhotoMode: contextValue.portraitPhotoMode,
|
||||
idPhotoMode: contextValue.idPhotoMode,
|
||||
optimizelyExperimentName: contextValue.optimizelyExperimentName,
|
||||
courseRunKey: null,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user