quby 4.0.3 → 5.0.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/quby/questionnaires.rb +1 -0
- data/lib/quby/questionnaires/api.rb +5 -1
- data/lib/quby/questionnaires/deserializer.rb +433 -0
- data/lib/quby/questionnaires/dsl.rb +10 -15
- data/lib/quby/questionnaires/entities.rb +1 -0
- data/lib/quby/questionnaires/entities/charting/line_chart.rb +23 -0
- data/lib/quby/questionnaires/entities/charting/overview_chart.rb +3 -1
- data/lib/quby/questionnaires/entities/definition.rb +3 -5
- data/lib/quby/questionnaires/entities/fields.rb +0 -15
- data/lib/quby/questionnaires/entities/question.rb +9 -32
- data/lib/quby/questionnaires/entities/questionnaire.rb +4 -15
- data/lib/quby/questionnaires/entities/questions/checkbox_question.rb +0 -24
- data/lib/quby/questionnaires/entities/questions/date_question.rb +0 -8
- data/lib/quby/questionnaires/entities/score_calculation.rb +36 -3
- data/lib/quby/questionnaires/repos.rb +1 -0
- data/lib/quby/questionnaires/repos/bundle_disk_repo.rb +51 -0
- data/lib/quby/version.rb +1 -1
- data/spec/internal/log/test-events.log +166 -0
- data/spec/internal/log/test.log +6170 -0
- data/spec/internal/tmp/capybara/screenshot_2020-10-27-14-25-21.063.html +207 -0
- data/spec/internal/tmp/capybara/screenshot_2020-10-27-14-25-21.063.png +0 -0
- data/spec/quby/answers/services/answer_validations_spec.rb +8 -8
- data/spec/quby/questionnaires/deserializer/questionnaire_spec.rb +237 -0
- data/spec/quby/questionnaires/dsl_spec.rb +0 -9
- data/spec/quby/questionnaires/entities/fields_spec.rb +3 -3
- data/spec/quby/questionnaires/entities/question_spec.rb +0 -8
- data/spec/quby/questionnaires/entities/questionnaire_spec.rb +2 -26
- data/spec/quby/table_backend/range_tree_spec.rb +7 -0
- data/spec/spec_helper.rb +1 -0
- metadata +25 -46
- data/lib/quby/questionnaires/dsl/base.rb +0 -20
- data/lib/quby/questionnaires/dsl/calls_custom_methods.rb +0 -29
- data/lib/quby/questionnaires/dsl/charting/bar_chart_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/charting/chart_builder.rb +0 -91
- data/lib/quby/questionnaires/dsl/charting/line_chart_builder.rb +0 -57
- data/lib/quby/questionnaires/dsl/charting/overview_chart_builder.rb +0 -31
- data/lib/quby/questionnaires/dsl/charting/radar_chart_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/helpers.rb +0 -51
- data/lib/quby/questionnaires/dsl/panel_builder.rb +0 -80
- data/lib/quby/questionnaires/dsl/question_builder.rb +0 -40
- data/lib/quby/questionnaires/dsl/questionnaire_builder.rb +0 -252
- data/lib/quby/questionnaires/dsl/questions/base.rb +0 -179
- data/lib/quby/questionnaires/dsl/questions/checkbox_question_builder.rb +0 -20
- data/lib/quby/questionnaires/dsl/questions/date_question_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/questions/deprecated_question_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/questions/float_question_builder.rb +0 -21
- data/lib/quby/questionnaires/dsl/questions/integer_question_builder.rb +0 -21
- data/lib/quby/questionnaires/dsl/questions/radio_question_builder.rb +0 -20
- data/lib/quby/questionnaires/dsl/questions/select_question_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/questions/string_question_builder.rb +0 -20
- data/lib/quby/questionnaires/dsl/questions/text_question_builder.rb +0 -22
- data/lib/quby/questionnaires/dsl/score_builder.rb +0 -22
- data/lib/quby/questionnaires/dsl/standardized_panel_generators.rb +0 -33
- data/lib/quby/questionnaires/dsl/table_builder.rb +0 -48
- data/lib/quby/questionnaires/services/definition_validator.rb +0 -298
- data/spec/quby/questionnaires/dsl/calls_custom_methods_spec.rb +0 -38
- data/spec/quby/questionnaires/dsl/charting/bar_chart_builder_spec.rb +0 -41
- data/spec/quby/questionnaires/dsl/charting/chart_builder_spec.rb +0 -127
- data/spec/quby/questionnaires/dsl/charting/line_chart_builder_spec.rb +0 -66
- data/spec/quby/questionnaires/dsl/charting/radar_chart_builder_spec.rb +0 -41
- data/spec/quby/questionnaires/dsl/helpers_spec.rb +0 -80
- data/spec/quby/questionnaires/dsl/questionnaire_builder_spec.rb +0 -480
- data/spec/quby/questionnaires/services/definition_validator_spec.rb +0 -793
- data/spec/support/examples_for_chart_builders.rb +0 -59
@@ -1,793 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
module Quby::Questionnaires::Services
|
6
|
-
describe DefinitionValidator do
|
7
|
-
let(:questionnaire) { Quby::Questionnaires::DSL.build('test', 'title "Test"') }
|
8
|
-
|
9
|
-
def make_definition(definition = 'title "Test"')
|
10
|
-
Quby::Questionnaires::Entities::Definition.new(key: 'test', sourcecode: definition, path: 'fake definition test')
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "fields#answer_keys and fields#input_keys need to be symbols" do
|
14
|
-
before do
|
15
|
-
allow(Quby::Questionnaires::DSL).to receive(:build_from_definition).and_return(questionnaire)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'passes when answer_keys and input_keys are symbols' do
|
19
|
-
valid_definition = make_definition
|
20
|
-
questionnaire.fields.answer_keys << :v_foo
|
21
|
-
questionnaire.fields.input_keys << :v_foo_a1
|
22
|
-
valid_definition.valid?
|
23
|
-
expect(valid_definition.errors).to be_empty
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'fails when an answer_keys is not a symbol' do
|
27
|
-
invalid_definition = make_definition
|
28
|
-
questionnaire.fields.answer_keys << 'v_foo'
|
29
|
-
invalid_definition.valid?
|
30
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
31
|
-
.to include("Answer key v_foo is not a symbol")
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'fails when an input_keys is not a symbol' do
|
35
|
-
invalid_definition = make_definition
|
36
|
-
questionnaire.fields.input_keys << 'v_foo_a1'
|
37
|
-
invalid_definition.valid?
|
38
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
39
|
-
.to include("Input key v_foo_a1 is not a symbol")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe "questionnaire needs a title" do
|
44
|
-
it "throws an error if the questionnaire does not have a title" do
|
45
|
-
invalid_definition = make_definition("")
|
46
|
-
invalid_definition.valid?
|
47
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
48
|
-
.to include("Questionnaire title is missing.")
|
49
|
-
end
|
50
|
-
|
51
|
-
it "throws an error if the title is empty" do
|
52
|
-
invalid_definition = make_definition(<<-END)
|
53
|
-
title ""
|
54
|
-
END
|
55
|
-
invalid_definition.valid?
|
56
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
57
|
-
.to include("Questionnaire title is missing.")
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe 'questions with activemodel validation errors' do
|
62
|
-
it "throws an error if the question to be hidden does not exist" do
|
63
|
-
invalid_definition = make_definition(<<-END)
|
64
|
-
title "Test"
|
65
|
-
question :v_1, type: :string, show_values: :error do
|
66
|
-
title "Testvraag"
|
67
|
-
end
|
68
|
-
END
|
69
|
-
invalid_definition.valid?
|
70
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
71
|
-
.to include("Question v_1 is invalid: Show values option invalid: error.")
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe ":hides_questions" do
|
76
|
-
it "throws an error if the question to be hidden does not exist" do
|
77
|
-
invalid_definition = make_definition(<<-END)
|
78
|
-
title "Test"
|
79
|
-
question :v_1, type: :radio do
|
80
|
-
title "Testvraag"
|
81
|
-
option :a1, value: 0, hides_questions: [:v_2]
|
82
|
-
end
|
83
|
-
END
|
84
|
-
invalid_definition.valid?
|
85
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
86
|
-
.to include("Question v_1 option a1 hides_questions references nonexistent question v_2")
|
87
|
-
end
|
88
|
-
|
89
|
-
it "throws an error if the question to be hidden is a subquestion" do
|
90
|
-
invalid_definition = make_definition(<<-END)
|
91
|
-
title "Test"
|
92
|
-
question :v_1, type: :radio do
|
93
|
-
title "Testvraag"
|
94
|
-
option :a1, value: 0, hides_questions: [:v_1_a1_sq] do
|
95
|
-
question :v_1_a1_sq, type: :string
|
96
|
-
end
|
97
|
-
end
|
98
|
-
END
|
99
|
-
invalid_definition.valid?
|
100
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
101
|
-
.to include("Question v_1 option a1 hides_questions references subquestion v_1_a1_sq")
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'does not throw an error when the question to be hidden exists' do
|
105
|
-
definition = make_definition(<<-END)
|
106
|
-
title "Test"
|
107
|
-
question :v_1, type: :radio do
|
108
|
-
title "Testvraag"
|
109
|
-
option :a1, value: 0, hides_questions: [:v_2]
|
110
|
-
end
|
111
|
-
|
112
|
-
question :v_2, type: :textarea do
|
113
|
-
title "Testvraag"
|
114
|
-
end
|
115
|
-
END
|
116
|
-
expect(definition.valid?).to be_truthy
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe ":shows_questions" do
|
121
|
-
it "throws an error if the question to be shown does not exist" do
|
122
|
-
invalid_definition = make_definition(<<-END)
|
123
|
-
title "Test"
|
124
|
-
question :v_1, type: :radio do
|
125
|
-
title "Testvraag"
|
126
|
-
option :a1, value: 0, shows_questions: [:v_2]
|
127
|
-
end
|
128
|
-
END
|
129
|
-
invalid_definition.valid?
|
130
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
131
|
-
.to include("Question v_1 option a1 shows_questions references nonexistent question v_2")
|
132
|
-
end
|
133
|
-
|
134
|
-
it "throws an error if the question to be shown is a subquestion" do
|
135
|
-
invalid_definition = make_definition(<<-END)
|
136
|
-
title "Test"
|
137
|
-
question :v_1, type: :radio do
|
138
|
-
title "Testvraag"
|
139
|
-
option :a1, value: 0, shows_questions: [:v_1_a1_sq] do
|
140
|
-
question :v_1_a1_sq, type: :string
|
141
|
-
end
|
142
|
-
end
|
143
|
-
END
|
144
|
-
invalid_definition.valid?
|
145
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
146
|
-
.to include("Question v_1 option a1 shows_questions references subquestion v_1_a1_sq")
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'does not throw an error when the question to be shown exists' do
|
150
|
-
definition = make_definition(<<-END)
|
151
|
-
title "Test"
|
152
|
-
question :v_1, type: :radio do
|
153
|
-
title "Testvraag"
|
154
|
-
option :a1, value: 0, shows_questions: [:v_2]
|
155
|
-
end
|
156
|
-
|
157
|
-
question :v_2, type: :textarea do
|
158
|
-
title 'Testvraag'
|
159
|
-
end
|
160
|
-
END
|
161
|
-
expect(definition.valid?).to be_truthy
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
describe ":default_invisible" do
|
166
|
-
it 'throws an error if a subquestion has default_invisible set' do
|
167
|
-
invalid_definition = make_definition(<<-END)
|
168
|
-
title "Test"
|
169
|
-
question :v_1, type: :radio do
|
170
|
-
title "Testvraag"
|
171
|
-
option :a1
|
172
|
-
option :a2, shows_questions: [:v_1_a1_sq] do
|
173
|
-
question :v_1_a1_sq, type: :string, default_invisible: true
|
174
|
-
end
|
175
|
-
end
|
176
|
-
END
|
177
|
-
invalid_definition.valid?
|
178
|
-
expect(invalid_definition.errors[:sourcecode].first[:message])
|
179
|
-
.to include("Question v_1_a1_sq is a subquestion with default_invisible")
|
180
|
-
end
|
181
|
-
|
182
|
-
it 'does not throw an error if a non-subquestion has default_invisible set' do
|
183
|
-
valid_definition = make_definition(<<-END)
|
184
|
-
title "Test"
|
185
|
-
question :v_1, type: :string default_invisible: true
|
186
|
-
END
|
187
|
-
valid_definition.valid?
|
188
|
-
expect(valid_definition.errors[:sourcecode].first[:message]).to be_truthy
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe ":validates_question_key_format" do
|
193
|
-
it "validates length of the question keys" do
|
194
|
-
long_key = make_definition(<<-END)
|
195
|
-
title "Test"
|
196
|
-
question :questionthree, type: :radio do
|
197
|
-
title "Testvraag"
|
198
|
-
option :a1, value: 0, description: 'some_description'
|
199
|
-
end
|
200
|
-
END
|
201
|
-
valid_key = make_definition(<<-END)
|
202
|
-
title "Test"
|
203
|
-
question :v_12345678901, type: :radio do
|
204
|
-
title "Testvraag"
|
205
|
-
option :a1, value: 0, description: 'some_description'
|
206
|
-
end
|
207
|
-
END
|
208
|
-
expect(long_key.valid?).to be_falsey
|
209
|
-
expect(valid_key.valid?).to be_truthy
|
210
|
-
end
|
211
|
-
|
212
|
-
it "validates that question key starts with a `v_`" do
|
213
|
-
invalid_key = make_definition(<<-END)
|
214
|
-
title "Test"
|
215
|
-
question :one, type: :radio do
|
216
|
-
title "Testvraag"
|
217
|
-
option :a1, value: 0, description: 'some_description', hides_questions: [:two]
|
218
|
-
end
|
219
|
-
END
|
220
|
-
valid_key = make_definition(<<-END)
|
221
|
-
title "Test"
|
222
|
-
question :v_2, type: :radio do
|
223
|
-
title "Testvraag"
|
224
|
-
option :a1, value: 0, description: 'some_description'
|
225
|
-
end
|
226
|
-
END
|
227
|
-
expect(invalid_key.valid?).to be_falsey
|
228
|
-
expect(valid_key.valid?).to be_truthy
|
229
|
-
end
|
230
|
-
|
231
|
-
it "validates check_box question options start with `v_`" do
|
232
|
-
invalid_keys = make_definition(<<-END)
|
233
|
-
title "Test"
|
234
|
-
question :v_4, type: :check_box do
|
235
|
-
title "Testvraag met een check_box"
|
236
|
-
option :q1, description: 'some_description'
|
237
|
-
end
|
238
|
-
END
|
239
|
-
valid_keys = make_definition(<<-END)
|
240
|
-
title "Test"
|
241
|
-
question :v_4, type: :check_box do
|
242
|
-
title "Testvraag met een check_box"
|
243
|
-
option :v_q1, description: 'some_description'
|
244
|
-
inner_title 'blaat'
|
245
|
-
option :v_q2, description: 'more_description'
|
246
|
-
end
|
247
|
-
END
|
248
|
-
expect(invalid_keys.valid?).to be_falsey
|
249
|
-
expect(valid_keys.valid?).to be_truthy
|
250
|
-
end
|
251
|
-
|
252
|
-
it "validates check_box question options length" do
|
253
|
-
invalid_keys = make_definition(<<-END)
|
254
|
-
title "Test"
|
255
|
-
question :v_4, type: :check_box do
|
256
|
-
title "Testvraag met een check_box"
|
257
|
-
option :v_q1_has_a_very_long_key, description: 'some_description'
|
258
|
-
end
|
259
|
-
END
|
260
|
-
valid_keys = make_definition(<<-END)
|
261
|
-
title "Test"
|
262
|
-
question :v_4, type: :check_box do
|
263
|
-
title "Testvraag met een check_box"
|
264
|
-
option :v_q1, description: 'some_description'
|
265
|
-
end
|
266
|
-
END
|
267
|
-
expect(invalid_keys.valid?).to be_falsey
|
268
|
-
expect(valid_keys.valid?).to be_truthy
|
269
|
-
end
|
270
|
-
|
271
|
-
it "validates question date keys" do
|
272
|
-
invalid_keys = make_definition(<<-END)
|
273
|
-
title "Test"
|
274
|
-
question :v_6, type: :date, year_key: :invalid_key, month_key: :v_62, day_key: :v_63 do
|
275
|
-
title "Testvraag met een datum"
|
276
|
-
end
|
277
|
-
END
|
278
|
-
valid_keys = make_definition(<<-END)
|
279
|
-
title "Test"
|
280
|
-
question :v_6, type: :date, year_key: :v_61, month_key: :v_62, day_key: :v_63 do
|
281
|
-
title "Testvraag met een datum"
|
282
|
-
end
|
283
|
-
END
|
284
|
-
expect(invalid_keys.valid?).to be_falsey
|
285
|
-
expect(valid_keys.valid?).to be_truthy
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
describe 'subquestion validation' do
|
290
|
-
it 'does not accept subquestions in question of type select' do
|
291
|
-
select_type_without_subquestions = make_definition(<<-END)
|
292
|
-
title "Test"
|
293
|
-
question :v_7, type: :select do
|
294
|
-
title "Vraag met hidden options"
|
295
|
-
option :a1, :value => 1, :description => "Keuze1"
|
296
|
-
option :a2, :value => 2, :description => "Keuze2"
|
297
|
-
end
|
298
|
-
END
|
299
|
-
select_type_with_subquestions = make_definition(<<-END)
|
300
|
-
title "Test"
|
301
|
-
question :v_8, type: :select do
|
302
|
-
title "Vraag met hidden options"
|
303
|
-
option :a3, :value => 1, :description => "Keuze1"
|
304
|
-
option :a4, :value => 2, :description => "Keuze2"
|
305
|
-
option :a5, :value => 7, :description => "Anders, namelijk:"
|
306
|
-
question :v_8a, :type => :radio do
|
307
|
-
option :a7a, :value => 11, :description => "Keuze 3"
|
308
|
-
option :a7b, :value => 12, :description => "Keuze 4"
|
309
|
-
end
|
310
|
-
end
|
311
|
-
END
|
312
|
-
|
313
|
-
expect(select_type_with_subquestions.valid?).to be_falsey
|
314
|
-
expect(select_type_without_subquestions.valid?).to be_truthy
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
describe 'score key validation' do
|
319
|
-
it 'accepts score keys that are the correct length' do
|
320
|
-
valid_definition = make_definition(<<-END)
|
321
|
-
title "Test"
|
322
|
-
score 'ok_key_length', label: 'some_label',
|
323
|
-
schema: [{key: :wait_what_this_key_is_very_long, label: 'Score', export_key: :wat}] do
|
324
|
-
{ wait_what_this_key_is_very_long: 42 }
|
325
|
-
end
|
326
|
-
END
|
327
|
-
expect(valid_definition).to be_valid
|
328
|
-
end
|
329
|
-
|
330
|
-
it 'reject score keys that are too long' do
|
331
|
-
invalid_definition = make_definition(<<-END)
|
332
|
-
title "Test"
|
333
|
-
score 'score_whose_key_is_longer_than_max', label: 'some_label',
|
334
|
-
schema: [{key: :t_score, label: 'Score', export_key: :wat}] do
|
335
|
-
{ t_score: 42 }
|
336
|
-
end
|
337
|
-
END
|
338
|
-
expect(invalid_definition).not_to be_valid
|
339
|
-
end
|
340
|
-
|
341
|
-
it 'reject score key if already defined' do
|
342
|
-
definition = make_definition(<<-END)
|
343
|
-
title "Test"
|
344
|
-
question :v_6, type: :radio, title: 'foo'
|
345
|
-
score 'foo_score', label: 'some_label',
|
346
|
-
schema: [{key: :t_score, label: 'Score', export_key: :wat}] do
|
347
|
-
{ t_score: 42 }
|
348
|
-
end
|
349
|
-
score 'foo_score', label: 'some_label',
|
350
|
-
schema: [{key: :t_score, label: 'Score', export_key: :wat}] do
|
351
|
-
{ t_score: 43 }
|
352
|
-
end
|
353
|
-
END
|
354
|
-
expect(definition).not_to be_valid
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
describe 'score label validation' do
|
359
|
-
it 'accepts the label option' do
|
360
|
-
score_definition = make_definition(<<-END)
|
361
|
-
title "Test"
|
362
|
-
score 'score_key', label: 'score_label',
|
363
|
-
schema: [{key: :value, label: 'Score', export_key: :sc1}] do {value: 42} end
|
364
|
-
END
|
365
|
-
expect(score_definition).to be_valid
|
366
|
-
end
|
367
|
-
|
368
|
-
it 'rejects score definitions without the label option' do
|
369
|
-
score_definition = make_definition(<<-END)
|
370
|
-
title "Test"
|
371
|
-
score 'score_key',
|
372
|
-
schema: [{key: :value, label: 'Score', export_key: :sc1}] do {value: 42} end
|
373
|
-
END
|
374
|
-
expect(score_definition).not_to be_valid
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
describe 'title validations' do
|
379
|
-
context ':title and :context_free_title do not exist' do
|
380
|
-
it 'fails' do
|
381
|
-
definition = make_definition(<<-END)
|
382
|
-
title "Test"
|
383
|
-
question :v_6, type: :radio
|
384
|
-
END
|
385
|
-
expect(definition.valid?).to be false
|
386
|
-
end
|
387
|
-
|
388
|
-
it 'does not fail with :allow_blank_titles option' do
|
389
|
-
definition = make_definition(<<-END)
|
390
|
-
title "Test"
|
391
|
-
question :v_6, type: :radio, allow_blank_titles: true do
|
392
|
-
end
|
393
|
-
END
|
394
|
-
expect(definition.valid?).to be true
|
395
|
-
end
|
396
|
-
|
397
|
-
it 'does not fail on table question' do
|
398
|
-
definition = make_definition(<<-END)
|
399
|
-
title "Test"
|
400
|
-
table columns: 4 do
|
401
|
-
end
|
402
|
-
END
|
403
|
-
expect(definition.valid?).to be true
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
context ':title or :context_free_title exist' do
|
408
|
-
it 'does not fail when :title exists' do
|
409
|
-
definition = make_definition(<<-END)
|
410
|
-
title "Test"
|
411
|
-
question :v_6, type: :radio do
|
412
|
-
title 'foo'
|
413
|
-
end
|
414
|
-
END
|
415
|
-
expect(definition.valid?).to be true
|
416
|
-
end
|
417
|
-
|
418
|
-
it 'does not fail when :context_free_title exists' do
|
419
|
-
definition = make_definition(<<-END)
|
420
|
-
title "Test"
|
421
|
-
question :v_6, type: :radio do
|
422
|
-
context_free_title 'bar'
|
423
|
-
end
|
424
|
-
END
|
425
|
-
expect(definition.valid?).to be true
|
426
|
-
end
|
427
|
-
end
|
428
|
-
|
429
|
-
context 'default question options' do
|
430
|
-
it 'is valid when no title exist and default question options set to true' do
|
431
|
-
definition = make_definition(<<-END)
|
432
|
-
title "Test"
|
433
|
-
default_question_options allow_blank_titles: true
|
434
|
-
question :v_6, type: :radio do
|
435
|
-
context_free_title 'bar'
|
436
|
-
end
|
437
|
-
END
|
438
|
-
expect(definition).to be_valid
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
|
-
context 'subquestions' do
|
443
|
-
it 'acts the same on subquestions' do
|
444
|
-
definition = make_definition(<<-END)
|
445
|
-
title "Test"
|
446
|
-
default_question_options allow_blank_titles: true
|
447
|
-
question :v_22a, :type => :check_box do
|
448
|
-
option :v_22_a01, :description => "Niet genoeg informatie"
|
449
|
-
end
|
450
|
-
END
|
451
|
-
expect(definition).to be_valid
|
452
|
-
end
|
453
|
-
|
454
|
-
it 'acts the same on title_question' do
|
455
|
-
definition = make_definition(<<-END)
|
456
|
-
title "Test"
|
457
|
-
default_question_options allow_blank_titles: true
|
458
|
-
question :v_100a, :type => :radio, :presentation => :horizontal, :required => false do
|
459
|
-
title " 100a."
|
460
|
-
title_question :v_100a_01, :type => :string, :title => ''
|
461
|
-
option :a1, :value => 0, :description => "Optie 1"
|
462
|
-
option :a2, :value => 1, :description => "Optie 2"
|
463
|
-
option :a3, :value => 2, :description => "Optie 3"
|
464
|
-
end
|
465
|
-
END
|
466
|
-
expect(definition).to be_valid
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
context 'spaces before question number' do
|
471
|
-
it 'is valid when title starts with 0 or 1 spaces before question number' do
|
472
|
-
definition = make_definition(<<-END)
|
473
|
-
title "Test"
|
474
|
-
question :v_1, type: :string do
|
475
|
-
title "1\\\\. Title"
|
476
|
-
end
|
477
|
-
END
|
478
|
-
expect(definition).to be_valid
|
479
|
-
end
|
480
|
-
|
481
|
-
it 'is invalid when title starts with more than 1 space before question number' do
|
482
|
-
definition = make_definition(<<-END)
|
483
|
-
title "Test"
|
484
|
-
question :v_1, type: :string do
|
485
|
-
title " 1\\\\. Title"
|
486
|
-
end
|
487
|
-
END
|
488
|
-
expect(definition).to be_invalid
|
489
|
-
end
|
490
|
-
end
|
491
|
-
end
|
492
|
-
|
493
|
-
describe 'subquestions inside a table' do
|
494
|
-
it 'accepts title_questions' do
|
495
|
-
expect(make_definition(<<-END).valid?).to be_truthy
|
496
|
-
title "Test"
|
497
|
-
panel do
|
498
|
-
table do
|
499
|
-
question :v_1, type: :radio do
|
500
|
-
title "Question"
|
501
|
-
title_question :v_2, :type => :string, :title => "Title Question", :depends_on => [:v_1_a1]
|
502
|
-
option :a1, value: 1, description: "Option 1"
|
503
|
-
option :a2, value: 2, description: "Option 2"
|
504
|
-
end
|
505
|
-
end
|
506
|
-
end
|
507
|
-
END
|
508
|
-
end
|
509
|
-
|
510
|
-
it 'does not accept subquestions in questions inside a table' do
|
511
|
-
expect(make_definition(<<-END).valid?).to be_falsey
|
512
|
-
title "Test"
|
513
|
-
panel do
|
514
|
-
table do
|
515
|
-
question :v_1, type: :radio do
|
516
|
-
title "Question"
|
517
|
-
option :a1, value: 1, description: "Option 1"
|
518
|
-
option :a2, value: 2, description: "Option 2" do
|
519
|
-
question :v_2, type: :string, title: 'Subquestion'
|
520
|
-
end
|
521
|
-
end
|
522
|
-
end
|
523
|
-
end
|
524
|
-
END
|
525
|
-
end
|
526
|
-
end
|
527
|
-
|
528
|
-
describe 'flags' do
|
529
|
-
it 'does not accept shows_questions arrays with unknown keys' do
|
530
|
-
expect(make_definition(<<-END).valid?).to be_falsey
|
531
|
-
title "Test"
|
532
|
-
flag key: 'a', description: 'a flag', shows_questions: [:v_22]
|
533
|
-
END
|
534
|
-
end
|
535
|
-
|
536
|
-
it 'does not accept hides_questions arrays with unknown keys' do
|
537
|
-
expect(make_definition(<<-END).valid?).to be_falsey
|
538
|
-
title "Test"
|
539
|
-
flag key: 'a', description: 'a flag', hides_questions: [:v_22]
|
540
|
-
END
|
541
|
-
end
|
542
|
-
|
543
|
-
it 'accepts shows_questions arrays with known keys' do
|
544
|
-
expect(make_definition(<<-END).valid?).to be_truthy
|
545
|
-
title "Test"
|
546
|
-
flag key: 'a', description: 'a flag', shows_questions: [:v_22]
|
547
|
-
question :v_22, type: :string do
|
548
|
-
title 'Question'
|
549
|
-
end
|
550
|
-
END
|
551
|
-
end
|
552
|
-
|
553
|
-
it 'accepts hides_questions arrays with known keys' do
|
554
|
-
expect(make_definition(<<-END).valid?).to be_truthy
|
555
|
-
title "Test"
|
556
|
-
flag key: 'a', description: 'a flag', hides_questions: [:v_22]
|
557
|
-
question :v_22, type: :string do
|
558
|
-
title 'Question'
|
559
|
-
end
|
560
|
-
END
|
561
|
-
end
|
562
|
-
|
563
|
-
it 'accepts depends_on with known flags' do
|
564
|
-
definition = make_definition <<-END
|
565
|
-
title 'Test'
|
566
|
-
flag key: :test, description_true: 'Test flag', description_false: 'Test flag uit'
|
567
|
-
flag key: :test2, description_true: 'Test flag 2', description_false: 'Test flag 2 uit', depends_on: :test_test
|
568
|
-
END
|
569
|
-
definition.valid?
|
570
|
-
expect(definition.errors.full_messages).to be_blank
|
571
|
-
end
|
572
|
-
|
573
|
-
it 'does not accept a flag depending on a non existing flag key' do
|
574
|
-
definition = make_definition <<-END
|
575
|
-
title 'Test'
|
576
|
-
flag key: :test, description_true: 'Test flag', description_false: 'Test flag uit', depends_on: :nonexistent
|
577
|
-
END
|
578
|
-
definition.valid?
|
579
|
-
expect(definition.errors[:sourcecode].first[:message]).to include "Flag test_test depends_on nonexistent flag 'nonexistent'"
|
580
|
-
end
|
581
|
-
end
|
582
|
-
|
583
|
-
describe 'respondent_types' do
|
584
|
-
it 'is optional' do
|
585
|
-
expect(make_definition(<<-END).valid?).to be_truthy
|
586
|
-
title "Test"
|
587
|
-
END
|
588
|
-
end
|
589
|
-
|
590
|
-
it 'accepts valid respondent_types' do
|
591
|
-
expect(make_definition(<<-END).valid?).to be_truthy
|
592
|
-
title "Test"
|
593
|
-
respondent_types :patient, :parent
|
594
|
-
END
|
595
|
-
end
|
596
|
-
|
597
|
-
it 'does not accept invalid respondent_types' do
|
598
|
-
expect(make_definition(<<-END).valid?).to be_falsey
|
599
|
-
title "Test"
|
600
|
-
respondent_types :santa_claus
|
601
|
-
END
|
602
|
-
end
|
603
|
-
end
|
604
|
-
|
605
|
-
describe 'outcome_tables' do
|
606
|
-
it 'checks if outcome tables are valid' do
|
607
|
-
expect(make_definition(<<-END).valid?).to be_truthy
|
608
|
-
title "Test"
|
609
|
-
score(:key, label: 'score', schema: [{key: :value, label: 'Score', export_key: :key}]) do {value: 'oh1'} end
|
610
|
-
score(:key2, label: 'score2', schema: [{key: :value, label: 'Score 2', export_key: :key2}]) do {value: 'oh2'} end
|
611
|
-
|
612
|
-
outcome_table key: :test_outcome_table,
|
613
|
-
score_keys: %i[key key2],
|
614
|
-
subscore_keys: [:value]
|
615
|
-
END
|
616
|
-
end
|
617
|
-
|
618
|
-
it 'fails if there is an error in outcome tables' do
|
619
|
-
definition = make_definition(<<-END)
|
620
|
-
title "Test"
|
621
|
-
score(:key, label: 'score', schema: [{key: :value, label: 'Score', export_key: :key}]) do {value: 'oh1'} end
|
622
|
-
score(:key2, label: 'score2', schema: [{key: :value, label: 'Score 2', export_key: :key2}]) do {value: 'oh2'} end
|
623
|
-
|
624
|
-
outcome_table key: :test_outcome_table,
|
625
|
-
score_keys: %i[key unknown_key_1 unknown_key_2],
|
626
|
-
subscore_keys: [:value]
|
627
|
-
END
|
628
|
-
expect(definition.valid?).to be_falsey
|
629
|
-
expect(definition.errors.full_messages.first).to include('Score keys :unknown_key_1 not found in score schemas')
|
630
|
-
end
|
631
|
-
end
|
632
|
-
describe '#validate_values_unique' do
|
633
|
-
it 'fails on duplicate option values' do
|
634
|
-
definition = make_definition(<<-END)
|
635
|
-
title "Test"
|
636
|
-
question :v_1, type: :scale do
|
637
|
-
title 'Ah'
|
638
|
-
option :a1, value: 0
|
639
|
-
option :a2, value: 0
|
640
|
-
end
|
641
|
-
END
|
642
|
-
expect(definition.valid?).to be false
|
643
|
-
expect(definition.errors.full_messages.first).to \
|
644
|
-
include('v_1:a2: Another option with value 0 is already defined.')
|
645
|
-
end
|
646
|
-
|
647
|
-
it 'does not complain about checkbox questions' do
|
648
|
-
definition = make_definition(<<-END)
|
649
|
-
title "Test"
|
650
|
-
question :v_1, type: :check_box do
|
651
|
-
title "Testvraag met een check_box"
|
652
|
-
option :v_1a1, description: 'some_description'
|
653
|
-
option :v_1a2, description: 'more_description'
|
654
|
-
end
|
655
|
-
END
|
656
|
-
expect(definition.valid?).to be true
|
657
|
-
end
|
658
|
-
|
659
|
-
it 'skips validation if question was passed allow_duplicate_option_values: true' do
|
660
|
-
definition = make_definition(<<-END)
|
661
|
-
title "Test"
|
662
|
-
question :v_1, type: :scale, allow_duplicate_option_values: true do
|
663
|
-
title 'Ah'
|
664
|
-
option :a1, value: 0
|
665
|
-
option :a2, value: 0
|
666
|
-
end
|
667
|
-
END
|
668
|
-
expect(definition.valid?).to be true
|
669
|
-
end
|
670
|
-
|
671
|
-
it 'skips placeholder options' do
|
672
|
-
definition = make_definition(<<-END)
|
673
|
-
title "Test"
|
674
|
-
question :v_1, type: :select do
|
675
|
-
title 'Ah'
|
676
|
-
option :a1, placeholder: true
|
677
|
-
option :a2, placeholder: true
|
678
|
-
end
|
679
|
-
END
|
680
|
-
expect(definition.valid?).to be true
|
681
|
-
end
|
682
|
-
|
683
|
-
it 'skips inner titles' do
|
684
|
-
definition = make_definition(<<-END)
|
685
|
-
title "Test"
|
686
|
-
question :v_1, type: :radio do
|
687
|
-
title "Wat is de hoogst genoten opleiding die u hebt afgerond?"
|
688
|
-
option :a0, value: 0, description: "Geen"
|
689
|
-
inner_title "Basisonderwijs:"
|
690
|
-
option :a1, value: 1, description: "Basisonderwijs"
|
691
|
-
option :a2, value: 2, description: "(SBO) Speciale School voor Basisonderwijs"
|
692
|
-
option :a3, value: 3, description: "(SO) Speciaal Onderwijs"
|
693
|
-
inner_title "Voortgezet onderwijs:"
|
694
|
-
end
|
695
|
-
END
|
696
|
-
expect(definition.valid?).to be true
|
697
|
-
end
|
698
|
-
|
699
|
-
it 'checks if all options have values' do
|
700
|
-
definition = make_definition(<<-END)
|
701
|
-
title "Test"
|
702
|
-
question :v_1, type: :scale do
|
703
|
-
title 'Ah'
|
704
|
-
option :a1
|
705
|
-
end
|
706
|
-
END
|
707
|
-
expect(definition.valid?).to be false
|
708
|
-
expect(definition.errors.full_messages.first).to \
|
709
|
-
include('v_1:a1: Has no option value defined.')
|
710
|
-
end
|
711
|
-
end
|
712
|
-
|
713
|
-
describe '#validate_placeholder_options_nil_values' do
|
714
|
-
it 'validates placeholder options do not have values' do
|
715
|
-
definition = make_definition(<<-END)
|
716
|
-
title "Test"
|
717
|
-
question :v_1, type: :select do
|
718
|
-
title 'Ah'
|
719
|
-
option :a1, placeholder: true, value: 32
|
720
|
-
end
|
721
|
-
END
|
722
|
-
expect(definition.valid?).to be false
|
723
|
-
expect(definition.errors.full_messages.first).to \
|
724
|
-
include('v_1:a1: Placeholder options should not have values defined.')
|
725
|
-
end
|
726
|
-
end
|
727
|
-
|
728
|
-
describe '#validate_markdown' do
|
729
|
-
it 'validates question titles' do
|
730
|
-
definition = make_definition(<<-END)
|
731
|
-
title "Test"
|
732
|
-
question :v_1, type: :string, title: 'a <b> tag'
|
733
|
-
END
|
734
|
-
expect(definition.valid?).to be false
|
735
|
-
expect(definition.errors.full_messages.first).to include('That tag isn\'t allowed here')
|
736
|
-
end
|
737
|
-
|
738
|
-
it 'validates question description' do
|
739
|
-
definition = make_definition(<<-END)
|
740
|
-
title "Test"
|
741
|
-
question :v_1, type: :string, title: 'fine', description: 'a <b> tag'
|
742
|
-
END
|
743
|
-
expect(definition.valid?).to be false
|
744
|
-
expect(definition.errors.full_messages.first).to include('That tag isn\'t allowed here')
|
745
|
-
end
|
746
|
-
|
747
|
-
it 'validates option description' do
|
748
|
-
definition = make_definition(<<-END)
|
749
|
-
title "Test"
|
750
|
-
question :v_1, type: :select, title: 'fine' do
|
751
|
-
option :a1, value: 32, description: 'a <b> tag'
|
752
|
-
end
|
753
|
-
END
|
754
|
-
expect(definition.valid?).to be false
|
755
|
-
expect(definition.errors.full_messages.first).to include('That tag isn\'t allowed here')
|
756
|
-
end
|
757
|
-
end
|
758
|
-
|
759
|
-
describe '#validate_raw_content_items' do
|
760
|
-
it 'validates html fields' do
|
761
|
-
definition = make_definition(<<-END)
|
762
|
-
title "Test"
|
763
|
-
panel do
|
764
|
-
html "A <b> tag"
|
765
|
-
end
|
766
|
-
END
|
767
|
-
expect(definition.valid?).to be false
|
768
|
-
expect(definition.errors.full_messages.first).to include('That tag isn\'t allowed here')
|
769
|
-
end
|
770
|
-
|
771
|
-
it 'allows video elements' do
|
772
|
-
definition = make_definition(<<-END)
|
773
|
-
title "Test"
|
774
|
-
panel do
|
775
|
-
html "A <video></video> tag"
|
776
|
-
end
|
777
|
-
END
|
778
|
-
expect(definition.valid?).to be true
|
779
|
-
end
|
780
|
-
|
781
|
-
it 'validates items with raw_content' do
|
782
|
-
definition = make_definition(<<-END)
|
783
|
-
title "Test"
|
784
|
-
panel do
|
785
|
-
question :v_1, type: :float, title: 'q', raw_content: "<p>a <b> tag</p>"
|
786
|
-
end
|
787
|
-
END
|
788
|
-
expect(definition.valid?).to be false
|
789
|
-
expect(definition.errors.full_messages.first).to include('That tag isn\'t allowed here')
|
790
|
-
end
|
791
|
-
end
|
792
|
-
end
|
793
|
-
end
|