Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undocumented survey select widget bug #1866

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 109 additions & 10 deletions integrationTesting/tests/organize/surveys/submitting-survey.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import RosaLuxemburg from '../../../mockData/orgs/KPD/people/RosaLuxemburg';
import RosaLuxemburgUser from '../../../mockData/users/RosaLuxemburgUser';
import test from '../../../fixtures/next';
import {
ELEMENT_TYPE,
RESPONSE_TYPE,
ZetkinSurveyApiSubmission,
ZetkinSurveyQuestionResponse,
ZetkinSurveySignaturePayload,
} from 'utils/types/zetkin';

test.describe('User submitting a survey', () => {
const apiPostPath = `/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}/submissions`;

test.beforeEach(async ({ appUri, login, moxy, page }) => {
test.beforeEach(async ({ login, moxy }) => {
moxy.setZetkinApiMock(
`/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`,
'get',
Expand All @@ -30,17 +33,17 @@ test.describe('User submitting a survey', () => {
role: null,
},
]);

await page.goto(
`${appUri}/o/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`
);
});

test.afterEach(({ moxy }) => {
moxy.teardown();
});

test('submits responses', async ({ moxy, page }) => {
test('submits responses', async ({ appUri, moxy, page }) => {
await page.goto(
`${appUri}/o/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`
);

moxy.setZetkinApiMock(
`/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}/submissions`,
'post',
Expand Down Expand Up @@ -77,7 +80,11 @@ test.describe('User submitting a survey', () => {
]);
});

test('submits email signature', async ({ moxy, page }) => {
test('submits email signature', async ({ appUri, moxy, page }) => {
await page.goto(
`${appUri}/o/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`
);

moxy.setZetkinApiMock(
`/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}/submissions`,
'post',
Expand Down Expand Up @@ -111,7 +118,11 @@ test.describe('User submitting a survey', () => {
});
});

test('submits user signature', async ({ moxy, page }) => {
test('submits user signature', async ({ appUri, moxy, page }) => {
await page.goto(
`${appUri}/o/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`
);

moxy.setZetkinApiMock(
`/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}/submissions`,
'post',
Expand All @@ -138,7 +149,11 @@ test.describe('User submitting a survey', () => {
expect(data.signature).toBe('user');
});

test('submits anonymous signature', async ({ moxy, page }) => {
test('submits anonymous signature', async ({ appUri, moxy, page }) => {
await page.goto(
`${appUri}/o/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`
);

moxy.setZetkinApiMock(
`/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}/submissions`,
'post',
Expand All @@ -165,7 +180,91 @@ test.describe('User submitting a survey', () => {
expect(data.signature).toBe(null);
});

test('preserves inputs on error', async ({ page }) => {
test('submits untouched "select" widget as []', async ({
appUri,
moxy,
page,
}) => {
// Include a select-widget element in the survey
moxy.setZetkinApiMock(
`/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`,
'get',
{
...KPDMembershipSurvey,
elements: [
...KPDMembershipSurvey.elements,
{
hidden: false,
id: 3,
question: {
description: '',
options: [
{
id: 1,
text: 'Yes',
},
{
id: 2,
text: 'No',
},
],
question: 'Is this a select box?',
required: false,
response_config: {
widget_type: 'select',
},
response_type: RESPONSE_TYPE.OPTIONS,
},
type: ELEMENT_TYPE.QUESTION,
},
],
}
);

// Respond when survey is submitted
moxy.setZetkinApiMock(
`/orgs/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}/submissions`,
'post',
{
timestamp: '1857-05-07T13:37:00.000Z',
}
);

// Navigate to survey and submit without touching the select widget (or any)
await page.goto(
`${appUri}/o/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`
);
await page.click('input[name="sig"][value="anonymous"]');
await page.click('data-testid=Survey-acceptTerms');
await Promise.all([
page.waitForResponse((res) => res.request().method() == 'POST'),
await page.click('data-testid=Survey-submit'),
]);

const log = moxy.log(`/v1${apiPostPath}`);
expect(log.length).toBe(1);

const data = log[0].data as ZetkinSurveyApiSubmission;
expect(data).toEqual({
responses: [
{
question_id: 2,
response: '',
},
{
options: [],
question_id: 3,
},
],
signature: null,
});
});

test('preserves inputs on error', async ({ appUri, page }) => {
await page.goto(
`${appUri}/o/${KPDMembershipSurvey.organization.id}/surveys/${KPDMembershipSurvey.id}`
);

await page.click('input[name="1.options"][value="1"]');
await page.fill('[name="2.text"]', 'Topple capitalism');
await page.click('input[name="sig"][value="anonymous"]');
Expand Down
22 changes: 22 additions & 0 deletions src/features/surveys/utils/prepareSurveyApiSubmission.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,28 @@ describe('prepareSurveyApiSubmission()', () => {
]);
});

it('formats a select widget response', () => {
formData['123.options'] = '234';
const submission = prepareSurveyApiSubmission(formData);
expect(submission.responses).toMatchObject([
{
options: [234],
question_id: 123,
},
]);
});

it('formats empty select response', () => {
formData['123.options'] = '';
const submission = prepareSurveyApiSubmission(formData);
expect(submission.responses).toMatchObject([
{
options: [],
question_id: 123,
},
]);
});

it('signs as the logged-in account when a logged-in user requests to sign as themself', () => {
formData['sig'] = 'user';
const submission = prepareSurveyApiSubmission(formData, true);
Expand Down
2 changes: 1 addition & 1 deletion src/features/surveys/utils/prepareSurveyApiSubmission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function prepareSurveyApiSubmission(

if (type === 'options' && typeof value === 'string') {
responses.push({
options: [parseInt(value, 10)],
options: value == '' ? [] : [parseInt(value, 10)],
question_id: parseInt(id, 10),
});
}
Expand Down
Loading