Skip to content

Commit

Permalink
Add project settings to Collect QR codes
Browse files Browse the repository at this point in the history
Closes #474.
  • Loading branch information
matthew-white committed Jun 22, 2021
1 parent cdd4294 commit 3c6f5e5
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 57 deletions.
13 changes: 1 addition & 12 deletions src/components/collect-qr.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import pako from 'pako/lib/deflate';
export default {
name: 'CollectQr',
props: {
// General settings only (not admin settings)
settings: {
type: Object,
required: true
Expand All @@ -36,19 +35,9 @@ export default {
}
},
computed: {
fullSettings() {
return {
general: {
...this.settings,
server_url: `${window.location.origin}${this.settings.server_url}`
},
// Collect requires the settings to have an `admin` property.
admin: {}
};
},
imgHtml() {
const code = qrcode(0, this.errorCorrectionLevel);
const json = JSON.stringify(this.fullSettings);
const json = JSON.stringify(this.settings);
code.addData(btoa(pako.deflate(json, { to: 'string' })));
code.make();
return code.createImgTag(this.cellSize, 0);
Expand Down
23 changes: 14 additions & 9 deletions src/components/field-key/qr-panel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,31 @@ import DocLink from '../doc-link.vue';
import FieldKey from '../../presenters/field-key';
import { apiPaths } from '../../util/request';
import { requestData } from '../../store/modules/request';
export default {
name: 'FieldKeyQrPanel',
components: { CollectQr, DocLink },
props: {
fieldKey: FieldKey, // eslint-disable-line vue/require-default-prop
managed: {
type: Boolean,
default: false
}
fieldKey: FieldKey,
managed: Boolean
},
computed: {
...requestData(['project']),
settings() {
const { token, projectId } = this.fieldKey;
const url = apiPaths.serverUrlForFieldKey(
this.fieldKey.token,
this.project.id
);
const settings = {
server_url: apiPaths.serverUrlForFieldKey(token, projectId)
general: { server_url: `${window.location.origin}${url}` },
project: { name: this.project.name },
// Collect requires the settings to have an `admin` property.
admin: {}
};
if (this.managed) {
settings.form_update_mode = 'match_exactly';
settings.autosend = 'wifi_and_cellular';
settings.general.form_update_mode = 'match_exactly';
settings.general.autosend = 'wifi_and_cellular';
}
return settings;
}
Expand Down
25 changes: 16 additions & 9 deletions src/components/form-draft/testing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,20 @@ export default {
// component is created.
...requestData([{ key: 'formDraft', getOption: true }, 'keys']),
qrSettings() {
const url = apiPaths.serverUrlForFormDraft(
this.formDraft.draftToken,
this.projectId,
this.xmlFormId
);
return {
server_url: apiPaths.serverUrlForFormDraft(
this.formDraft.draftToken,
this.projectId,
this.xmlFormId
)
general: { server_url: `${window.location.origin}${url}` },
project: {
name: this.$t('collectProjectName', this.formDraft),
icon: '📝'
},
// Collect requires the settings to have an `admin` property.
admin: {}
};
},
baseUrl() {
return apiPaths.formDraft(this.projectId, this.xmlFormId);
}
},
created() {
Expand Down Expand Up @@ -152,7 +156,10 @@ export default {
"body": [
"You can use the configuration code to the right to set up a mobile device to download this Draft. You can also click the New button above to create a new Submission from your web browser.",
"Draft Submissions go into the test table below, where you can preview and download them. When you publish this Draft Form, its test Submissions will be permanently removed."
]
],
// This text will be shown in ODK Collect when testing a Draft Form. {name}
// is the title of the Draft Form.
"collectProjectName": "[Draft] {name}"
}
}
</i18n>
Expand Down
35 changes: 15 additions & 20 deletions test/components/collect-qr.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { wait } from '../util/util';

const mountComponent = (propsData) => mount(CollectQr, {
propsData: {
settings: { server_url: '/path' },
settings: {
general: { server_url: 'http://localhost:9876/path' },
admin: {}
},
errorCorrectionLevel: 'L',
cellSize: 1,
...propsData
Expand Down Expand Up @@ -40,28 +43,20 @@ describe('CollectQr', () => {
childNodes[0].tagName.should.equal('IMG');
});

describe('settings', () => {
it('prepends the origin to server_url', async () => {
const component = mountComponent({
settings: { server_url: '/path' }
});
// I think we need to wait for the image to render?
await wait();
qrData(component).should.eql({
it('encodes the settings', async () => {
const component = mountComponent({
settings: {
general: { server_url: 'http://localhost:9876/path' },
project: { name: 'My Project' },
admin: {}
});
}
});

it('encodes other settings', async () => {
const component = mountComponent({
settings: { server_url: '/path', x: 'y' }
});
await wait();
qrData(component).should.eql({
general: { server_url: 'http://localhost:9876/path', x: 'y' },
admin: {}
});
// I think we need to wait for the image to render?
await wait();
qrData(component).should.eql({
general: { server_url: 'http://localhost:9876/path' },
project: { name: 'My Project' },
admin: {}
});
});

Expand Down
20 changes: 15 additions & 5 deletions test/components/field-key/qr-panel.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ const mountComponent = (propsData) => mount(FieldKeyQrPanel, {
propsData: {
fieldKey: new FieldKey(testData.extendedFieldKeys.last()),
...propsData
}
},
requestData: { project: testData.extendedProjects.last() }
});

describe('FieldKeyQrPanel', () => {
beforeEach(() => {
testData.extendedProjects.createPast(1, { name: 'My Project' });
testData.extendedFieldKeys.createPast(1, { displayName: 'My App User' });
});

Expand All @@ -22,17 +24,25 @@ describe('FieldKeyQrPanel', () => {
const panel = mountComponent({ managed: true });
const { token } = testData.extendedFieldKeys.last();
panel.first(CollectQr).getProp('settings').should.eql({
server_url: `/v1/key/${token}/projects/1`,
form_update_mode: 'match_exactly',
autosend: 'wifi_and_cellular'
general: {
server_url: `http://localhost:9876/v1/key/${token}/projects/1`,
form_update_mode: 'match_exactly',
autosend: 'wifi_and_cellular'
},
project: { name: 'My Project' },
admin: {}
});
});

it('shows a legacy QR code with the correct data', () => {
const panel = mountComponent({ managed: false });
const { token } = testData.extendedFieldKeys.last();
panel.first(CollectQr).getProp('settings').should.eql({
server_url: `/v1/key/${token}/projects/1`
general: {
server_url: `http://localhost:9876/v1/key/${token}/projects/1`
},
project: { name: 'My Project' },
admin: {}
});
});
});
Expand Down
8 changes: 6 additions & 2 deletions test/components/form-draft/testing.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ describe('FormDraftTesting', () => {

it('shows a QR code that encodes the correct settings', async () => {
mockLogin();
testData.extendedForms.createPast(1, { draft: true });
testData.extendedForms.createPast(1, { name: 'My Form', draft: true });
const component = await load('/projects/1/forms/f/draft/testing', {
root: false
});
const { draftToken } = testData.extendedFormDrafts.last();
component.first(CollectQr).getProp('settings').should.eql({
server_url: `/v1/test/${draftToken}/projects/1/forms/f/draft`
general: {
server_url: `http://localhost:9876/v1/test/${draftToken}/projects/1/forms/f/draft`
},
project: { name: '[Draft] My Form', icon: '📝' },
admin: {}
});
});

Expand Down
4 changes: 4 additions & 0 deletions transifex/strings_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1790,6 +1790,10 @@
"1": {
"string": "Draft Submissions go into the test table below, where you can preview and download them. When you publish this Draft Form, its test Submissions will be permanently removed."
}
},
"collectProjectName": {
"string": "[Draft] {name}",
"developer_comment": "This text will be shown in ODK Collect when testing a Draft Form. {name} is the title of the Draft Form."
}
},
"FormHead": {
Expand Down

0 comments on commit 3c6f5e5

Please sign in to comment.