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:
alangsto
2021-04-15 13:36:19 -04:00
committed by GitHub
9 changed files with 38 additions and 8 deletions

View File

@@ -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,
};

View File

@@ -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 {

View File

@@ -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,
};

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 () => {

View File

@@ -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,
};