@pie-element/image-cloze-association 10.1.2-next.2 → 10.1.2

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.
Files changed (130) hide show
  1. package/CHANGELOG.json +437 -0
  2. package/CHANGELOG.md +1997 -0
  3. package/LICENSE.md +5 -0
  4. package/README.md +1 -0
  5. package/configure/CHANGELOG.json +197 -0
  6. package/configure/CHANGELOG.md +1600 -0
  7. package/configure/lib/defaults.js +86 -0
  8. package/configure/lib/defaults.js.map +1 -0
  9. package/configure/lib/index.js +99 -0
  10. package/configure/lib/index.js.map +1 -0
  11. package/configure/lib/root.js +135 -0
  12. package/configure/lib/root.js.map +1 -0
  13. package/configure/package.json +23 -0
  14. package/configure/src/__tests__/index.test.js +155 -0
  15. package/configure/src/defaults.js +59 -0
  16. package/configure/src/index.js +114 -0
  17. package/configure/src/root.jsx +116 -0
  18. package/controller/CHANGELOG.json +137 -0
  19. package/controller/CHANGELOG.md +1149 -0
  20. package/controller/lib/defaults.js +14 -0
  21. package/controller/lib/defaults.js.map +1 -0
  22. package/controller/lib/index.js +304 -0
  23. package/controller/lib/index.js.map +1 -0
  24. package/controller/lib/utils.js +70 -0
  25. package/controller/lib/utils.js.map +1 -0
  26. package/controller/package.json +19 -0
  27. package/controller/src/__tests__/index.test.js +711 -0
  28. package/controller/src/defaults.js +7 -0
  29. package/controller/src/index.js +322 -0
  30. package/controller/src/utils.js +72 -0
  31. package/docs/config-schema.json +1382 -0
  32. package/docs/config-schema.json.md +1021 -0
  33. package/docs/demo/config.js +8 -0
  34. package/docs/demo/generate.js +74 -0
  35. package/docs/demo/index.html +1 -0
  36. package/docs/demo/session.js +16 -0
  37. package/docs/pie-schema.json +1085 -0
  38. package/docs/pie-schema.json.md +810 -0
  39. package/lib/constants.js +12 -0
  40. package/lib/constants.js.map +1 -0
  41. package/lib/evaluation-icon.js +60 -0
  42. package/lib/evaluation-icon.js.map +1 -0
  43. package/lib/image-container.js +94 -0
  44. package/lib/image-container.js.map +1 -0
  45. package/lib/image-drop-target.js +130 -0
  46. package/lib/image-drop-target.js.map +1 -0
  47. package/lib/index.js +220 -0
  48. package/lib/index.js.map +1 -0
  49. package/lib/interactive-section.js +104 -0
  50. package/lib/interactive-section.js.map +1 -0
  51. package/lib/possible-response.js +161 -0
  52. package/lib/possible-response.js.map +1 -0
  53. package/lib/possible-responses.js +58 -0
  54. package/lib/possible-responses.js.map +1 -0
  55. package/lib/root.js +491 -0
  56. package/lib/root.js.map +1 -0
  57. package/lib/static-html-span.js +35 -0
  58. package/lib/static-html-span.js.map +1 -0
  59. package/lib/utils-correctness.js +89 -0
  60. package/lib/utils-correctness.js.map +1 -0
  61. package/package.json +21 -86
  62. package/src/__tests__/index.test.js +174 -0
  63. package/src/__tests__/root.test.jsx +99 -0
  64. package/src/__tests__/utils.test.js +207 -0
  65. package/src/constants.js +5 -0
  66. package/src/evaluation-icon.jsx +54 -0
  67. package/src/image-container.jsx +90 -0
  68. package/src/image-drop-target.jsx +140 -0
  69. package/src/index.js +245 -0
  70. package/src/interactive-section.jsx +94 -0
  71. package/src/possible-response.jsx +152 -0
  72. package/src/possible-responses.jsx +52 -0
  73. package/src/root.jsx +490 -0
  74. package/src/static-html-span.jsx +30 -0
  75. package/src/utils-correctness.js +95 -0
  76. package/configure.js +0 -2
  77. package/controller.js +0 -1
  78. package/dist/author/defaults.d.ts +0 -88
  79. package/dist/author/defaults.js +0 -58
  80. package/dist/author/index.d.ts +0 -34
  81. package/dist/author/index.js +0 -71
  82. package/dist/author/root.d.ts +0 -14
  83. package/dist/author/root.js +0 -80
  84. package/dist/browser/Check-DL1c-mLM.js +0 -10708
  85. package/dist/browser/Check-DL1c-mLM.js.map +0 -1
  86. package/dist/browser/author/index.js +0 -38597
  87. package/dist/browser/author/index.js.map +0 -1
  88. package/dist/browser/controller/index.js +0 -171
  89. package/dist/browser/controller/index.js.map +0 -1
  90. package/dist/browser/delivery/index.js +0 -2699
  91. package/dist/browser/delivery/index.js.map +0 -1
  92. package/dist/browser/dist-BphSS14E.js +0 -346
  93. package/dist/browser/dist-BphSS14E.js.map +0 -1
  94. package/dist/browser/humps-CZ4RCLab.js +0 -67
  95. package/dist/browser/humps-CZ4RCLab.js.map +0 -1
  96. package/dist/browser/image-cloze-association.css +0 -2
  97. package/dist/controller/defaults.d.ts +0 -16
  98. package/dist/controller/defaults.js +0 -10
  99. package/dist/controller/index.d.ts +0 -23
  100. package/dist/controller/index.js +0 -122
  101. package/dist/controller/utils.d.ts +0 -14
  102. package/dist/controller/utils.js +0 -36
  103. package/dist/delivery/constants.d.ts +0 -14
  104. package/dist/delivery/evaluation-icon.d.ts +0 -28
  105. package/dist/delivery/evaluation-icon.js +0 -38
  106. package/dist/delivery/image-container.d.ts +0 -13
  107. package/dist/delivery/image-container.js +0 -61
  108. package/dist/delivery/image-drop-target.d.ts +0 -45
  109. package/dist/delivery/image-drop-target.js +0 -90
  110. package/dist/delivery/index.d.ts +0 -20
  111. package/dist/delivery/index.js +0 -110
  112. package/dist/delivery/interactive-section.d.ts +0 -15
  113. package/dist/delivery/interactive-section.js +0 -72
  114. package/dist/delivery/possible-response.d.ts +0 -34
  115. package/dist/delivery/possible-response.js +0 -100
  116. package/dist/delivery/possible-responses.d.ts +0 -31
  117. package/dist/delivery/possible-responses.js +0 -41
  118. package/dist/delivery/root.d.ts +0 -21
  119. package/dist/delivery/root.js +0 -278
  120. package/dist/delivery/static-html-span.d.ts +0 -14
  121. package/dist/delivery/static-html-span.js +0 -22
  122. package/dist/delivery/utils-correctness.d.ts +0 -10
  123. package/dist/delivery/utils-correctness.js +0 -43
  124. package/dist/index.d.ts +0 -1
  125. package/dist/index.iife.d.ts +0 -8
  126. package/dist/index.iife.js +0 -152
  127. package/dist/index.js +0 -2
  128. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +0 -16
  129. package/dist/runtime-support.d.ts +0 -12
  130. package/dist/runtime-support.js +0 -12
@@ -0,0 +1,711 @@
1
+ import { model, outcome, getPartialScore, isResponseCorrect, createCorrectResponseSession } from '../index';
2
+
3
+ jest.mock('../utils', () => ({
4
+ ...jest.requireActual('../utils.js'),
5
+ isResponseCorrect: jest.fn().mockReturnValue(false),
6
+ }));
7
+
8
+ const rhomb = 'rhomb';
9
+ const hexagon = 'hexagon';
10
+ const square = 'square';
11
+ const trapeze = 'trapeze';
12
+
13
+ const responseContainer1 = {
14
+ x: 0,
15
+ y: 0,
16
+ height: '0%',
17
+ width: '0%',
18
+ };
19
+ const responseContainer2 = {
20
+ x: 1,
21
+ y: 1,
22
+ height: '1%',
23
+ width: '1%',
24
+ };
25
+
26
+ describe('controller', () => {
27
+ let result, question, session, env;
28
+
29
+ beforeEach(() => {
30
+ question = {
31
+ prompt: 'prompt',
32
+ image: {
33
+ src: '',
34
+ width: 0,
35
+ scale: false,
36
+ height: 0,
37
+ },
38
+ validation: {
39
+ valid_response: {
40
+ score: 1,
41
+ value: [
42
+ {
43
+ images: [rhomb, square],
44
+ },
45
+ {
46
+ images: [rhomb, square, trapeze],
47
+ },
48
+ ],
49
+ },
50
+ },
51
+ possible_responses: [rhomb, hexagon, square, trapeze],
52
+ response_containers: [responseContainer1, responseContainer2],
53
+ duplicate_responses: true,
54
+ max_response_per_zone: 5,
55
+ partialScoring: false,
56
+ shuffle: true
57
+ };
58
+ });
59
+
60
+ describe('outcome partialScoring test', () => {
61
+ const assertOutcome = (message, extra, sessionValue, env, expected) => {
62
+ it(message, async () => {
63
+ const result = await outcome({ ...question, ...extra }, sessionValue, env);
64
+
65
+ expect(result).toEqual(expect.objectContaining(expected));
66
+ });
67
+ };
68
+
69
+ assertOutcome(
70
+ 'element.partialScoring = true',
71
+ { partialScoring: true },
72
+ {
73
+ answers: [
74
+ { value: rhomb, containerIndex: 0 },
75
+ { value: square, containerIndex: 0 },
76
+ { value: rhomb, containerIndex: 1 },
77
+ { value: square, containerIndex: 1 },
78
+ { value: trapeze, containerIndex: 0 },
79
+ ],
80
+ },
81
+ { mode: 'evaluate' },
82
+ { score: 0.2 },
83
+ );
84
+
85
+ assertOutcome(
86
+ 'element.partialScoring = false',
87
+ { partialScoring: false },
88
+ {
89
+ answers: [
90
+ { value: rhomb, containerIndex: 0 },
91
+ { value: square, containerIndex: 0 },
92
+ { value: rhomb, containerIndex: 1 },
93
+ { value: square, containerIndex: 1 },
94
+ { value: trapeze, containerIndex: 0 },
95
+ ],
96
+ },
97
+ { mode: 'evaluate' },
98
+ { score: 0 },
99
+ );
100
+
101
+ assertOutcome(
102
+ 'element.partialScoring = false, env.partialScoring = true',
103
+ { partialScoring: false },
104
+ {
105
+ answers: [
106
+ { value: rhomb, containerIndex: 0 },
107
+ { value: square, containerIndex: 0 },
108
+ { value: rhomb, containerIndex: 1 },
109
+ { value: square, containerIndex: 1 },
110
+ { value: trapeze, containerIndex: 0 },
111
+ ],
112
+ },
113
+ { mode: 'evaluate', partialScoring: true },
114
+ { score: 0 },
115
+ );
116
+
117
+ assertOutcome(
118
+ 'element.partialScoring = true, env.partialScoring = false',
119
+ { partialScoring: true },
120
+ {
121
+ answers: [
122
+ { value: rhomb, containerIndex: 0 },
123
+ { value: square, containerIndex: 0 },
124
+ { value: rhomb, containerIndex: 1 },
125
+ { value: square, containerIndex: 1 },
126
+ { value: trapeze, containerIndex: 0 },
127
+ ],
128
+ },
129
+ { mode: 'evaluate', partialScoring: false },
130
+ { score: 0 },
131
+ );
132
+ });
133
+
134
+ describe('outcome', () => {
135
+ const returnOutcome = (session) => {
136
+ it(`returns score of 0 and empty: true if session is ${JSON.stringify(session)}`, async () => {
137
+ const result = await outcome(question, session);
138
+ expect(result).toEqual({ score: 0, empty: true, traceLog: ['Student did not place any images into placement containers. Score is 0.'] });
139
+ });
140
+ };
141
+
142
+ returnOutcome(undefined);
143
+ returnOutcome(null);
144
+ returnOutcome({});
145
+
146
+ it('returns score of 0', async () => {
147
+ const result = await outcome(question, {
148
+ answers: [{ value: rhomb, containerIndex: 0 }],
149
+ });
150
+ expect(result.score).toEqual(0);
151
+ });
152
+
153
+ it('returns score of 1', async () => {
154
+ const result = await outcome(question, {
155
+ answers: [
156
+ { value: rhomb, containerIndex: 0 },
157
+ { value: square, containerIndex: 0 },
158
+ { value: rhomb, containerIndex: 1 },
159
+ { value: square, containerIndex: 1 },
160
+ { value: trapeze, containerIndex: 1 },
161
+ ],
162
+ });
163
+ expect(result.score).toEqual(1);
164
+ });
165
+
166
+ it('returns correct score for valid response with empty response containers and partialScoring: false', async () => {
167
+ const result = await outcome({
168
+ ...question,
169
+ validation: {
170
+ valid_response: {
171
+ score: 1,
172
+ value: [
173
+ {
174
+ images: [rhomb, square],
175
+ },
176
+ {
177
+ images: [],
178
+ },
179
+ ],
180
+ },
181
+ }
182
+ }, {
183
+ answers: [
184
+ { value: rhomb, containerIndex: 0 },
185
+ { value: square, containerIndex: 0 },
186
+ ],
187
+ });
188
+
189
+ expect(result.score).toEqual(1);
190
+ });
191
+
192
+ it('returns correct score for valid response with empty response containers and partialScoring: true', async () => {
193
+ const result = await outcome({
194
+ ...question,
195
+ partialScoring: true,
196
+ validation: {
197
+ valid_response: {
198
+ score: 1,
199
+ value: [
200
+ {
201
+ images: [rhomb, square],
202
+ },
203
+ {
204
+ images: [],
205
+ },
206
+ ],
207
+ },
208
+ }
209
+ }, {
210
+ answers: [
211
+ { value: rhomb, containerIndex: 0 },
212
+ ],
213
+ });
214
+
215
+ expect(result.score).toEqual(0.5);
216
+ });
217
+
218
+ it('returns correct score for valid response with empty response containers, incorrect answers and partialScoring: true', async () => {
219
+ const result = await outcome({
220
+ ...question,
221
+ partialScoring: true,
222
+ validation: {
223
+ valid_response: {
224
+ score: 1,
225
+ value: [
226
+ {
227
+ images: [rhomb],
228
+ },
229
+ {
230
+ images: [],
231
+ },
232
+ {
233
+ images: [rhomb],
234
+ },
235
+ {
236
+ images: [],
237
+ },
238
+ ],
239
+ },
240
+ }
241
+ }, {
242
+ answers: [
243
+ { value: rhomb, containerIndex: 0 },
244
+ { value: rhomb, containerIndex: 1 },
245
+ { value: rhomb, containerIndex: 2 },
246
+ { value: rhomb, containerIndex: 3 },
247
+ ],
248
+ });
249
+
250
+ expect(result.score).toEqual(0);
251
+ });
252
+
253
+ describe('returns score 0 for wrong validation format', () => {
254
+ it('returns 0 for old value format', async () => {
255
+ const result = await outcome(
256
+ {
257
+ ...question,
258
+ validation: {
259
+ valid_response: {
260
+ score: 1,
261
+ value: [
262
+ [rhomb, square],
263
+ [trapeze, hexagon],
264
+ ],
265
+ },
266
+ },
267
+ },
268
+ {
269
+ answers: [
270
+ { value: rhomb, containerIndex: 0 },
271
+ { value: square, containerIndex: 0 },
272
+ { value: trapeze, containerIndex: 1 },
273
+ { value: hexagon, containerIndex: 1 },
274
+ ],
275
+ },
276
+ );
277
+ expect(result.score).toEqual(0);
278
+ });
279
+
280
+ it('returns 0 for when images is null ', async () => {
281
+ const result = await outcome(
282
+ {
283
+ ...question,
284
+ validation: {
285
+ valid_response: {
286
+ score: 1,
287
+ value: [{ images: null }],
288
+ },
289
+ },
290
+ },
291
+ {
292
+ answers: [
293
+ { value: rhomb, containerIndex: 0 },
294
+ { value: hexagon, containerIndex: 1 },
295
+ ],
296
+ },
297
+ );
298
+ expect(result.score).toEqual(0);
299
+ });
300
+
301
+ it('returns 0 for when value is [{}]', async () => {
302
+ const result = await outcome(
303
+ {
304
+ ...question,
305
+ validation: {
306
+ valid_response: {
307
+ score: 1,
308
+ value: [{}],
309
+ },
310
+ },
311
+ },
312
+ {
313
+ answers: [
314
+ { value: rhomb, containerIndex: 0 },
315
+ { value: hexagon, containerIndex: 1 },
316
+ ],
317
+ },
318
+ );
319
+ expect(result.score).toEqual(0);
320
+ });
321
+ });
322
+
323
+ describe('alternate correct answers', () => {
324
+ describe('handles one option', () => {
325
+ it('returns score of 1', async () => {
326
+ const result = await outcome(
327
+ {
328
+ ...question,
329
+ validation: {
330
+ ...question.validation,
331
+ alt_responses: [
332
+ {
333
+ score: 1,
334
+ value: [{ images: [rhomb] }, { images: [square] }, { images: [trapeze] }, { images: [hexagon] }],
335
+ },
336
+ ],
337
+ },
338
+ },
339
+ {
340
+ answers: [
341
+ { value: rhomb, containerIndex: 0 },
342
+ { value: square, containerIndex: 1 },
343
+ { value: trapeze, containerIndex: 2 },
344
+ { value: hexagon, containerIndex: 3 },
345
+ ],
346
+ },
347
+ );
348
+ expect(result.score).toEqual(1);
349
+ });
350
+
351
+ it('returns score of 0', async () => {
352
+ const result = await outcome(
353
+ {
354
+ ...question,
355
+ validation: {
356
+ ...question.validation,
357
+ alt_responses: [
358
+ {
359
+ score: 1,
360
+ value: [{ images: [rhomb] }, { images: [square] }, { images: [trapeze] }, { images: [hexagon] }],
361
+ },
362
+ ],
363
+ },
364
+ },
365
+ {
366
+ answers: [
367
+ { value: rhomb, containerIndex: 3 },
368
+ { value: square, containerIndex: 1 },
369
+ { value: trapeze, containerIndex: 2 },
370
+ { value: hexagon, containerIndex: 0 },
371
+ ],
372
+ },
373
+ );
374
+ expect(result.score).toEqual(0);
375
+ });
376
+ });
377
+
378
+ describe('handles multiple options', () => {
379
+ it('returns score of 1', async () => {
380
+ const result = await outcome(
381
+ {
382
+ ...question,
383
+ validation: {
384
+ ...question.validation,
385
+ alt_responses: [
386
+ {
387
+ score: 1,
388
+ value: [{ images: [square] }, { images: [rhomb] }, { images: [trapeze] }, { images: [hexagon] }],
389
+ },
390
+ {
391
+ score: 1,
392
+ value: [{ images: [rhomb] }, { images: [square] }, { images: [trapeze] }, { images: [hexagon] }],
393
+ },
394
+ ],
395
+ },
396
+ },
397
+ {
398
+ answers: [
399
+ { value: rhomb, containerIndex: 0 },
400
+ { value: square, containerIndex: 1 },
401
+ { value: trapeze, containerIndex: 2 },
402
+ { value: hexagon, containerIndex: 3 },
403
+ ],
404
+ },
405
+ );
406
+ expect(result.score).toEqual(1);
407
+ });
408
+
409
+ it('returns score of 0', async () => {
410
+ const result = await outcome(
411
+ {
412
+ ...question,
413
+ validation: {
414
+ ...question.validation,
415
+ alt_responses: [
416
+ {
417
+ score: 1,
418
+ value: [{ images: [square] }, { images: [rhomb] }, { images: [trapeze] }, { images: [hexagon] }],
419
+ },
420
+ {
421
+ score: 1,
422
+ value: [{ images: [rhomb] }, { images: [square] }, { images: [trapeze] }, { images: [hexagon] }],
423
+ },
424
+ ],
425
+ },
426
+ },
427
+ {
428
+ answers: [
429
+ { value: rhomb, containerIndex: 3 },
430
+ { value: square, containerIndex: 1 },
431
+ { value: trapeze, containerIndex: 2 },
432
+ { value: hexagon, containerIndex: 0 },
433
+ ],
434
+ },
435
+ );
436
+ expect(result.score).toEqual(0);
437
+ });
438
+ });
439
+ });
440
+ });
441
+
442
+ describe('model', () => {
443
+ describe('mode: gather', () => {
444
+ beforeEach(async () => {
445
+ session = {};
446
+ env = { mode: 'gather' };
447
+ result = await model(question, session, env);
448
+ });
449
+
450
+ it('returns disabled', () => {
451
+ expect(result.disabled).toEqual(false);
452
+ });
453
+
454
+ it('returns mode', () => {
455
+ expect(result.mode).toEqual('gather');
456
+ });
457
+
458
+ it('returns prompt', () => {
459
+ expect(result.prompt).toEqual('prompt');
460
+ });
461
+
462
+ it('returns image', () => {
463
+ expect(result.image).toEqual({
464
+ src: '',
465
+ width: 0,
466
+ scale: false,
467
+ height: 0,
468
+ });
469
+ });
470
+
471
+ it('returns validation', () => {
472
+ expect(result.validation).toBeUndefined();
473
+ });
474
+
475
+ it('returns responseContainers', () => {
476
+ expect(result.responseContainers).toEqual([responseContainer1, responseContainer2]);
477
+ });
478
+
479
+ it('returns duplicateResponses', () => {
480
+ expect(result.duplicateResponses).toEqual(true);
481
+ });
482
+
483
+ it('returns maxResponsePerZone', () => {
484
+ expect(result.maxResponsePerZone).toEqual(5);
485
+ });
486
+
487
+ it('does not return responseCorrect', () => {
488
+ expect(result.responseCorrect).toBe(undefined);
489
+ });
490
+
491
+ it('returns possibleResponses in shuffled order', () => {
492
+ expect(result.possibleResponses).toEqual(expect.arrayContaining(question.possible_responses));
493
+ });
494
+ });
495
+
496
+ describe('mode: view', () => {
497
+ beforeEach(async () => {
498
+ session = {};
499
+ env = { mode: 'view' };
500
+ result = await model(question, session, env);
501
+ });
502
+
503
+ it('returns disabled', () => {
504
+ expect(result.disabled).toEqual(true);
505
+ });
506
+ });
507
+
508
+ describe('mode: evaluate', () => {
509
+ beforeEach(async () => {
510
+ session = { answers: [] };
511
+ env = { mode: 'evaluate' };
512
+ result = await model(question, session, env);
513
+ return result;
514
+ });
515
+
516
+ it('returns validation', () => {
517
+ expect(result.validation).toEqual({
518
+ validResponse: {
519
+ score: 1,
520
+ value: [{ images: [rhomb, square] }, { images: [rhomb, square, trapeze] }],
521
+ },
522
+ });
523
+ });
524
+
525
+ it('returns is response correct', () => {
526
+ expect(result.responseCorrect).toEqual(false);
527
+ });
528
+
529
+ const returnModel = (sess) => {
530
+ it(`returns responseCorrect: false if session is ${JSON.stringify(sess)}`, async () => {
531
+ const result = await model(question, sess, (env = { mode: 'evaluate' }));
532
+ expect(result).toEqual(
533
+ expect.objectContaining({
534
+ responseCorrect: false,
535
+ }),
536
+ );
537
+ });
538
+ };
539
+
540
+ returnModel(undefined);
541
+ returnModel(null);
542
+ returnModel({});
543
+ });
544
+ });
545
+
546
+ describe('validation property behavior across modes', () => {
547
+ it('does not include validation in gather mode', async () => {
548
+ const result = await model(question, {}, { mode: 'gather' });
549
+
550
+ expect(result.validation).toBeUndefined();
551
+ });
552
+
553
+ it('does not include validation in view mode', async () => {
554
+ const result = await model(question, {}, { mode: 'view' });
555
+
556
+ expect(result.validation).toBeUndefined();
557
+ });
558
+
559
+ it('includes validation in evaluate mode and when instructor is in view mode', async () => {
560
+ const evalResult = await model(question, {}, { mode: 'evaluate' });
561
+ const viewResult = await model(question, {}, { mode: 'view', role: 'instructor' });
562
+
563
+ expect(evalResult.validation).toBeDefined();
564
+ expect(viewResult.validation).toBeUndefined();
565
+ });
566
+
567
+ it('ensures validation is explicitly undefined when not in evaluate or instructor view mode', async () => {
568
+ const gatherResult = await model(question, {}, { mode: 'gather' });
569
+ const studentViewResult = await model(question, {}, { mode: 'view', role: 'student' });
570
+
571
+ expect(gatherResult.validation).toBeUndefined();
572
+ expect(studentViewResult.validation).toBeUndefined();
573
+ });
574
+ });
575
+
576
+ describe('getPartialScore', () => {
577
+ const returnPartialScore = (sess) => {
578
+ it(`returns score of 0 if session is ${JSON.stringify(sess)}`, () => {
579
+ const result = getPartialScore(question, sess);
580
+ expect(result).toEqual(0);
581
+ });
582
+ };
583
+
584
+ returnPartialScore(undefined);
585
+ returnPartialScore(null);
586
+ returnPartialScore({});
587
+ });
588
+
589
+ describe('isResponseCorrect', () => {
590
+ const returnIsResponseCorrect = (sess) => {
591
+ it(`returns score of 0 if session is ${JSON.stringify(sess)}`, () => {
592
+ const result = isResponseCorrect([], sess);
593
+ expect(result).toEqual(false);
594
+ });
595
+ };
596
+
597
+ returnIsResponseCorrect(undefined);
598
+ returnIsResponseCorrect(null);
599
+ returnIsResponseCorrect({});
600
+ });
601
+ });
602
+
603
+ describe('createCorrectResponseSession', () => {
604
+ const question = {
605
+ prompt: 'This is the question prompt',
606
+ image: {
607
+ src: 'https://app.fluence.net/ia/image/6412223997a34018b15f8512bee6c04c',
608
+ width: 465,
609
+ scale: false,
610
+ height: 313,
611
+ },
612
+ response_containers: [
613
+ {
614
+ pointer: undefined,
615
+ wordwrap: true,
616
+ x: 64.3,
617
+ width: '35.70%',
618
+ y: 1.6,
619
+ height: '23.64%',
620
+ aria_label: '',
621
+ },
622
+ {
623
+ pointer: 'undefined',
624
+ wordwrap: true,
625
+ x: 64.09,
626
+ width: '35.92%',
627
+ y: 39.62,
628
+ height: '23.32%',
629
+ aria_label: '',
630
+ },
631
+ ],
632
+ possible_responses: [
633
+ '<img alt="" src="https://app.fluence.net/ia/image/9e5ed1d6762c4dac87b080e190af113d"/>',
634
+ '<img alt="" src="https://app.fluence.net/ia/image/729ca157d04c440ab7ae1c2abfb9c057"/>',
635
+ ],
636
+ validation: {
637
+ scoring_type: 'exactMatch',
638
+ valid_response: {
639
+ score: 1,
640
+ value: [
641
+ {
642
+ images: ['<img alt="" src="https://app.fluence.net/ia/image/729ca157d04c440ab7ae1c2abfb9c057"/>'],
643
+ },
644
+ {
645
+ images: ['<img alt="" src="https://app.fluence.net/ia/image/9e5ed1d6762c4dac87b080e190af113d"/>'],
646
+ },
647
+ ],
648
+ },
649
+ },
650
+ };
651
+
652
+ it('returns correct response if role is instructor and mode is gather', async () => {
653
+ const sess = await createCorrectResponseSession(question, {
654
+ mode: 'gather',
655
+ role: 'instructor',
656
+ });
657
+
658
+ expect(sess).toEqual({
659
+ answers: [
660
+ {
661
+ value: '<img alt="" src="https://app.fluence.net/ia/image/729ca157d04c440ab7ae1c2abfb9c057"/>',
662
+ containerIndex: 0,
663
+ },
664
+ {
665
+ value: '<img alt="" src="https://app.fluence.net/ia/image/9e5ed1d6762c4dac87b080e190af113d"/>',
666
+ containerIndex: 1,
667
+ },
668
+ ],
669
+ id: '1',
670
+ });
671
+ });
672
+
673
+ it('returns correct response if role is instructor and mode is view', async () => {
674
+ const sess = await createCorrectResponseSession(question, {
675
+ mode: 'view',
676
+ role: 'instructor',
677
+ });
678
+
679
+ expect(sess).toEqual({
680
+ answers: [
681
+ {
682
+ value: '<img alt="" src="https://app.fluence.net/ia/image/729ca157d04c440ab7ae1c2abfb9c057"/>',
683
+ containerIndex: 0,
684
+ },
685
+ {
686
+ value: '<img alt="" src="https://app.fluence.net/ia/image/9e5ed1d6762c4dac87b080e190af113d"/>',
687
+ containerIndex: 1,
688
+ },
689
+ ],
690
+ id: '1',
691
+ });
692
+ });
693
+
694
+ it('returns null if mode is evaluate', async () => {
695
+ const noResult = await createCorrectResponseSession(question, {
696
+ mode: 'evaluate',
697
+ role: 'instructor',
698
+ });
699
+
700
+ expect(noResult).toBeNull();
701
+ });
702
+
703
+ it('returns null if role is student', async () => {
704
+ const noResult = await createCorrectResponseSession(question, {
705
+ mode: 'gather',
706
+ role: 'student',
707
+ });
708
+
709
+ expect(noResult).toBeNull();
710
+ });
711
+ });
@@ -0,0 +1,7 @@
1
+ export default {
2
+ rationale: '',
3
+ rationaleEnabled: true,
4
+ studentInstructionsEnabled: true,
5
+ teacherInstructions: '',
6
+ teacherInstructionsEnabled: true,
7
+ };