1use std::sync::Arc;
2
3use crate::domain::models_requests::{self, JwtKey};
4use crate::programs::seed::seed_helpers::{
5 create_best_exercise, create_best_peer_review, create_page, example_exercise_flexible,
6 paragraph, quizzes_exercise, submit_and_grade,
7};
8use anyhow::Result;
9use chrono::{TimeZone, Utc};
10
11use headless_lms_models::{
12 PKeyPolicy, certificate_configuration_to_requirements, certificate_configurations, chapters,
13 chapters::NewChapter,
14 course_instance_enrollments,
15 course_instance_enrollments::NewCourseInstanceEnrollment,
16 course_instances::{self, NewCourseInstance},
17 course_modules::{self, NewCourseModule},
18 courses::NewCourse,
19 feedback,
20 feedback::{FeedbackBlock, NewFeedback},
21 file_uploads, glossary, library,
22 library::content_management::CreateNewCourseFixedIds,
23 page_history::HistoryChangeReason,
24 pages::CmsPageUpdate,
25 pages::{self, NewCoursePage},
26 peer_or_self_review_configs::PeerReviewProcessingStrategy::{
27 AutomaticallyGradeByAverage, AutomaticallyGradeOrManualReviewByAverage,
28 ManualReviewEverything,
29 },
30 proposed_block_edits::NewProposedBlockEdit,
31 proposed_page_edits,
32 proposed_page_edits::NewProposedPageEdits,
33 url_redirections,
34};
35use headless_lms_models::{certificate_configurations::DatabaseCertificateConfiguration, roles};
36use headless_lms_models::{
37 pages::PageUpdateArgs,
38 roles::{RoleDomain, UserRole},
39};
40use headless_lms_utils::{attributes, document_schema_processor::GutenbergBlock};
41
42use sqlx::{Pool, Postgres};
43use tracing::info;
44use uuid::Uuid;
45
46use super::{
47 seed_helpers::{CommonExerciseData, get_seed_spec_fetcher, heading},
48 seed_users::SeedUsersResult,
49};
50
51#[derive(Clone)]
52pub struct CommonCourseData {
53 pub db_pool: Pool<Postgres>,
54 pub organization_id: Uuid,
55 pub teacher_user_id: Uuid,
56 pub student_user_id: Uuid,
57 pub langs_user_id: Uuid,
58 pub example_normal_user_ids: Arc<Vec<Uuid>>,
59 pub jwt_key: Arc<JwtKey>,
60 pub base_url: String,
61}
62
63pub async fn seed_sample_course(
64 course_id: Uuid,
65 course_name: &str,
66 course_slug: &str,
67 common_course_data: CommonCourseData,
68 can_add_chatbot: bool,
69 seed_users_result: SeedUsersResult,
70) -> Result<Uuid> {
71 let CommonCourseData {
72 db_pool,
73 organization_id: org,
74 teacher_user_id,
75 student_user_id: student,
76 langs_user_id,
77 example_normal_user_ids: users,
78 jwt_key: _jwt_key,
79 base_url: _base_url,
80 } = common_course_data;
81 let spec_fetcher = get_seed_spec_fetcher();
82 info!("inserting sample course {}", course_name);
83 info!("inserting sample course {}", course_name);
84 let mut conn = db_pool.acquire().await?;
85 let new_course = NewCourse {
86 name: course_name.to_string(),
87 organization_id: org,
88 slug: course_slug.to_string(),
89 language_code: "en-US".to_string(),
90 teacher_in_charge_name: "admin".to_string(),
91 teacher_in_charge_email: "admin@example.com".to_string(),
92 description: "Sample course.".to_string(),
93 is_draft: false,
94 is_test_mode: false,
95 is_unlisted: false,
96 copy_user_permissions: false,
97 is_joinable_by_code_only: false,
98 join_code: None,
99 ask_marketing_consent: false,
100 flagged_answers_threshold: Some(3),
101 can_add_chatbot,
102 };
103 let (course, _front_page, default_instance, default_module) =
104 library::content_management::create_new_course(
105 &mut conn,
106 PKeyPolicy::Fixed(CreateNewCourseFixedIds {
107 course_id,
108 default_course_instance_id: Uuid::new_v5(
109 &course_id,
110 b"7344f1c8-b7ce-4c7d-ade2-5f39997bd454",
111 ),
112 }),
113 new_course,
114 teacher_user_id,
115 &spec_fetcher,
116 models_requests::fetch_service_info,
117 )
118 .await?;
119 course_modules::update_enable_registering_completion_to_uh_open_university(
120 &mut conn,
121 default_module.id,
122 true,
123 )
124 .await?;
125 course_instances::insert(
126 &mut conn,
127 PKeyPolicy::Fixed(Uuid::new_v5(
128 &course_id,
129 b"67f077b4-0562-47ae-a2b9-db2f08f168a9",
130 )),
131 NewCourseInstance {
132 course_id: course.id,
133 name: Some("Non-default instance"),
134 description: Some("This is a non-default instance"),
135 support_email: Some("contact@example.com"),
136 teacher_in_charge_name: "admin",
137 teacher_in_charge_email: "admin@example.com",
138 opening_time: None,
139 closing_time: None,
140 },
141 )
142 .await?;
143
144 let new_chapter = NewChapter {
147 chapter_number: 1,
148 course_id: course.id,
149 front_page_id: None,
150 name: "The Basics".to_string(),
151 color: None,
152 opens_at: None,
153 deadline: Some(Utc.with_ymd_and_hms(2225, 1, 1, 23, 59, 59).unwrap()),
154 course_module_id: Some(default_module.id),
155 };
156 let (chapter_1, _front_page_1) = library::content_management::create_new_chapter(
157 &mut conn,
158 PKeyPolicy::Fixed((
159 Uuid::new_v5(&course_id, b"bfc557e1-0f8e-4f10-8e21-d7d8ffe50a3a"),
160 Uuid::new_v5(&course_id, b"b1e392db-482a-494e-9cbb-c87bbc70e340"),
161 )),
162 &new_chapter,
163 teacher_user_id,
164 &spec_fetcher,
165 models_requests::fetch_service_info,
166 )
167 .await?;
168 chapters::set_opens_at(&mut conn, chapter_1.id, Utc::now()).await?;
169 let new_chapter = NewChapter {
170 chapter_number: 2,
171 course_id: course.id,
172 front_page_id: None,
173 name: "The intermediaries".to_string(),
174 color: None,
175 opens_at: None,
176 deadline: None,
177 course_module_id: Some(default_module.id),
178 };
179 let (chapter_2, _front_page_2) = library::content_management::create_new_chapter(
180 &mut conn,
181 PKeyPolicy::Fixed((
182 Uuid::new_v5(&course_id, b"8d699f05-4318-47f7-b020-b2084128f746"),
183 Uuid::new_v5(&course_id, b"9734cb59-4c3c-467d-91e8-f4281baccfe5"),
184 )),
185 &new_chapter,
186 teacher_user_id,
187 &spec_fetcher,
188 models_requests::fetch_service_info,
189 )
190 .await?;
191 chapters::set_opens_at(
192 &mut conn,
193 chapter_2.id,
194 Utc::now() + chrono::Duration::minutes(10),
195 )
196 .await?;
197 let new_chapter = NewChapter {
198 chapter_number: 3,
199 course_id: course.id,
200 front_page_id: None,
201 name: "Advanced studies".to_string(),
202 color: None,
203 opens_at: None,
204 deadline: None,
205 course_module_id: Some(default_module.id),
206 };
207 let (chapter_3, _front_page_3) = library::content_management::create_new_chapter(
208 &mut conn,
209 PKeyPolicy::Fixed((
210 Uuid::new_v5(&course_id, b"791eada6-5299-41e9-b39c-da4f3c564814"),
211 Uuid::new_v5(&course_id, b"22cb6a59-9d9d-4a0b-945b-11a6f2f8d6ef"),
212 )),
213 &new_chapter,
214 teacher_user_id,
215 &spec_fetcher,
216 models_requests::fetch_service_info,
217 )
218 .await?;
219 chapters::set_opens_at(
220 &mut conn,
221 chapter_3.id,
222 Utc::now() + chrono::Duration::minutes(20),
223 )
224 .await?;
225 let new_chapter = NewChapter {
226 chapter_number: 4,
227 course_id: course.id,
228 front_page_id: None,
229 name: "Forbidden magicks".to_string(),
230 color: None,
231 opens_at: None,
232 deadline: None,
233 course_module_id: Some(default_module.id),
234 };
235 let (chapter_4, _front_page_4) = library::content_management::create_new_chapter(
236 &mut conn,
237 PKeyPolicy::Fixed((
238 Uuid::new_v5(&course_id, b"07f8ceea-d41e-4dcb-9e4b-f600d3894e7f"),
239 Uuid::new_v5(&course_id, b"cd7a35b7-8f16-4e86-bef2-b730943ec15b"),
240 )),
241 &new_chapter,
242 teacher_user_id,
243 &spec_fetcher,
244 models_requests::fetch_service_info,
245 )
246 .await?;
247 chapters::set_opens_at(
248 &mut conn,
249 chapter_4.id,
250 Utc::now() + (chrono::Duration::days(365) * 100),
251 )
252 .await?;
253
254 tracing::info!("inserting modules");
255 let second_module = course_modules::insert(
256 &mut conn,
257 PKeyPolicy::Generate,
258 &NewCourseModule::new(course.id, Some("Another module".to_string()), 1)
259 .set_ects_credits(Some(5.0)),
260 )
261 .await?;
262 let new_chapter = NewChapter {
263 chapter_number: 5,
264 course_id: course.id,
265 front_page_id: None,
266 name: "Another chapter".to_string(),
267 color: None,
268 opens_at: None,
269 deadline: None,
270 course_module_id: Some(second_module.id),
271 };
272 let (_m1_chapter_1, _m1c1_front_page) = library::content_management::create_new_chapter(
273 &mut conn,
274 PKeyPolicy::Fixed((
275 Uuid::new_v5(&course_id, b"c9003113-b69b-4ee7-8b13-e16397f1a3ea"),
276 Uuid::new_v5(&course_id, b"f95aa0bc-93d0-4d83-acde-64682f5e8f66"),
277 )),
278 &new_chapter,
279 teacher_user_id,
280 &spec_fetcher,
281 models_requests::fetch_service_info,
282 )
283 .await?;
284 let new_chapter = NewChapter {
285 chapter_number: 6,
286 course_id: course.id,
287 front_page_id: None,
288 name: "Another another chapter".to_string(),
289 color: None,
290 opens_at: None,
291 deadline: None,
292 course_module_id: Some(second_module.id),
293 };
294 let (_m1_chapter_2, _m1c2_front_page) = library::content_management::create_new_chapter(
295 &mut conn,
296 PKeyPolicy::Fixed((
297 Uuid::new_v5(&course_id, b"4989533a-7888-424c-963c-d8007d820fca"),
298 Uuid::new_v5(&course_id, b"e68b9d5b-fa2e-4a94-a1da-5d69f29dcb63"),
299 )),
300 &new_chapter,
301 teacher_user_id,
302 &spec_fetcher,
303 models_requests::fetch_service_info,
304 )
305 .await?;
306 let module = course_modules::insert(
307 &mut conn,
308 PKeyPolicy::Generate,
309 &NewCourseModule::new(course.id, Some("Bonus module".to_string()), 2)
310 .set_enable_registering_completion_to_uh_open_university(true),
311 )
312 .await?;
313 let new_chapter = NewChapter {
314 chapter_number: 7,
315 course_id: course.id,
316 front_page_id: None,
317 name: "Bonus chapter".to_string(),
318 color: None,
319 opens_at: None,
320 deadline: None,
321 course_module_id: Some(module.id),
322 };
323 let (_m2_chapter_1, _m2c1_front_page) = library::content_management::create_new_chapter(
324 &mut conn,
325 PKeyPolicy::Fixed((
326 Uuid::new_v5(&course_id, b"26b52b2f-8b02-4be8-b341-6e956ff3ca86"),
327 Uuid::new_v5(&course_id, b"0512fb7c-cb3f-4111-b663-e2fa7714939f"),
328 )),
329 &new_chapter,
330 teacher_user_id,
331 &spec_fetcher,
332 models_requests::fetch_service_info,
333 )
334 .await?;
335 let new_chapter = NewChapter {
336 chapter_number: 8,
337 course_id: course.id,
338 front_page_id: None,
339 name: "Another bonus chapter".to_string(),
340 color: None,
341 opens_at: None,
342 deadline: None,
343 course_module_id: Some(module.id),
344 };
345 let (_m2_chapter_2, _m2c2_front_page) = library::content_management::create_new_chapter(
346 &mut conn,
347 PKeyPolicy::Fixed((
348 Uuid::new_v5(&course_id, b"4e48b13a-9740-4d4f-9f60-8176649901b9"),
349 Uuid::new_v5(&course_id, b"bc6569fe-52d2-4590-aa3a-8ae80e961db8"),
350 )),
351 &new_chapter,
352 teacher_user_id,
353 &spec_fetcher,
354 models_requests::fetch_service_info,
355 )
356 .await?;
357
358 let welcome_page = NewCoursePage::new(
359 course.id,
360 1,
361 "/welcome",
362 "Welcome to Introduction to Everything",
363 );
364 let (_page, _) = pages::insert_course_page(&mut conn, &welcome_page, teacher_user_id).await?;
365 let hidden_page = welcome_page
366 .followed_by("/hidden", "Hidden Page")
367 .set_hidden(true)
368 .set_content(vec![GutenbergBlock::paragraph(
369 "You found the secret of the project 331!",
370 )]);
371 let (_page, _) = pages::insert_course_page(&mut conn, &hidden_page, teacher_user_id).await?;
372
373 info!("sample exercises");
374 let block_id_1 = Uuid::new_v5(&course_id, b"af3b467a-f5db-42ad-9b21-f42ca316b3c6");
375 let block_id_2 = Uuid::new_v5(&course_id, b"465f1f95-22a1-43e1-b4a3-7d18e525dc12");
376 let block_id_3 = Uuid::new_v5(&course_id, b"46aad5a8-71bd-49cd-8d86-3368ee8bb7ac");
377 let block_id_4 = Uuid::new_v5(&course_id, b"09b327a8-8e65-437e-9678-554fc4d98dd4");
378 let block_id_5 = Uuid::new_v5(&course_id, b"834648cc-72d9-42d1-bed7-cc6a2e186ae6");
379 let block_id_6 = Uuid::new_v5(&course_id, b"223a4718-5287-49ff-853e-a67f4612c629");
380 let exercise_1_id = Uuid::new_v5(&course_id, b"cfb950a7-db4e-49e4-8ec4-d7a32b691b08");
381 let exercise_1_slide_1_id = Uuid::new_v5(&course_id, b"182c4128-c4e4-40c9-bc5a-1265bfd3654c");
382 let exercise_1_slide_1_task_1_id =
383 Uuid::new_v5(&course_id, b"f73dab3b-3549-422d-8377-ece1972e5576");
384 let exercise_1_slide_1_task_1_spec_1_id =
385 Uuid::new_v5(&course_id, b"5f6b7850-5034-4cef-9dcf-e3fd4831067f");
386 let exercise_1_slide_1_task_1_spec_2_id =
387 Uuid::new_v5(&course_id, b"c713bbfc-86bf-4877-bd39-53afaf4444b5");
388 let exercise_1_slide_1_task_1_spec_3_id =
389 Uuid::new_v5(&course_id, b"4027d508-4fad-422e-bb7f-15c613a02cc6");
390
391 let (exercise_block_1, exercise_1, slide_1, task_1) = create_best_exercise(
392 block_id_3,
393 exercise_1_slide_1_task_1_spec_1_id,
394 exercise_1_slide_1_task_1_spec_2_id,
395 exercise_1_slide_1_task_1_spec_3_id,
396 Some("Best exercise".to_string()),
397 CommonExerciseData {
398 exercise_id: exercise_1_id,
399 exercise_slide_id: exercise_1_slide_1_id,
400 exercise_task_id: exercise_1_slide_1_task_1_id,
401 block_id: block_id_2,
402 },
403 );
404 let page_c1_1 = create_page(
405 &mut conn,
406 course.id,
407 teacher_user_id,
408 Some(chapter_1.id),
409 CmsPageUpdate {
410 url_path: "/chapter-1/page-1".to_string(),
411 title: "Page One".to_string(),
412 chapter_id: Some(chapter_1.id),
413 exercises: vec![exercise_1],
414 exercise_slides: vec![slide_1],
415 exercise_tasks: vec![task_1],
416 content: serde_json::json!([
417 paragraph("Everything is a big topic.", block_id_1),
418 exercise_block_1,
419 paragraph("So big, that we need many paragraphs.", block_id_4),
420 paragraph("Like this.", block_id_5),
421 paragraph(&"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. ".repeat(4), block_id_6),
422 ]),
423 },
424
425 )
426 .await?;
427
428 let exercise_2_id = Uuid::new_v5(&course_id, b"36e7f0c2-e663-4382-a503-081866cfe7d0");
429 let exercise_2_slide_1_id = Uuid::new_v5(&course_id, b"0d85864d-a20d-4d65-9ace-9b4d377f38e8");
430 let exercise_2_slide_1_task_1_id =
431 Uuid::new_v5(&course_id, b"e7fca192-2161-4ab8-8533-8c41dbaa2d69");
432 let exercise_2_slide_1_task_1_spec_1_id =
433 Uuid::new_v5(&course_id, b"5898293f-2d41-43b1-9e44-92d487196ade");
434 let exercise_2_slide_1_task_1_spec_2_id =
435 Uuid::new_v5(&course_id, b"93d27d79-f9a1-44ab-839f-484accc67e32");
436 let exercise_2_slide_1_task_1_spec_3_id =
437 Uuid::new_v5(&course_id, b"81ec2df2-a5fd-4d7d-b85f-0c304e8d2030");
438 let exercise_3_id = Uuid::new_v5(&course_id, b"64d273eb-628f-4d43-a11a-e69ebe244942");
439 let exercise_3_slide_1_id = Uuid::new_v5(&course_id, b"5441c7c0-60f1-4058-8223-7090c9cac7cb");
440 let exercise_3_slide_1_task_1_id =
441 Uuid::new_v5(&course_id, b"114caac5-006a-4afb-9806-785154263c11");
442 let exercise_3_slide_1_task_1_spec_1_id =
443 Uuid::new_v5(&course_id, b"28ea3062-bd6a-45f5-9844-03174e00a0a8");
444 let exercise_3_slide_1_task_1_spec_2_id =
445 Uuid::new_v5(&course_id, b"1982f566-2d6a-485d-acb0-65d8b8864c7e");
446 let exercise_3_slide_1_task_1_spec_3_id =
447 Uuid::new_v5(&course_id, b"01ec5329-2cf6-4d0f-92b2-d388360fb402");
448 let exercise_4_id = Uuid::new_v5(&course_id, b"029688ec-c7be-4cb3-8928-85cfd6551083");
449 let exercise_4_slide_1_id = Uuid::new_v5(&course_id, b"ab8a314b-ac03-497b-8ade-3d8512ed00c9");
450 let exercise_4_slide_1_task_1_id =
451 Uuid::new_v5(&course_id, b"382fffce-f177-47d0-a5c0-cc8906d34c49");
452 let exercise_4_slide_1_task_1_spec_1_id =
453 Uuid::new_v5(&course_id, b"4bae54a3-d67c-428b-8996-290f70ae08fa");
454 let exercise_4_slide_1_task_1_spec_2_id =
455 Uuid::new_v5(&course_id, b"c3f257c0-bdc2-4d81-99ff-a71c76fe670a");
456 let exercise_4_slide_1_task_1_spec_3_id =
457 Uuid::new_v5(&course_id, b"fca5a8ba-50e0-4375-8d4b-9d02762d908c");
458 let (exercise_block_2, exercise_2, slide_2, task_2) = create_best_exercise(
459 Uuid::new_v5(&course_id, b"c0986981-c8ae-4c0b-b558-1163a16760ec"),
460 exercise_2_slide_1_task_1_spec_1_id,
461 exercise_2_slide_1_task_1_spec_2_id,
462 exercise_2_slide_1_task_1_spec_3_id,
463 Some("Best exercise".to_string()),
464 CommonExerciseData {
465 exercise_id: exercise_2_id,
466 exercise_slide_id: exercise_2_slide_1_id,
467 exercise_task_id: exercise_2_slide_1_task_1_id,
468 block_id: Uuid::new_v5(&course_id, b"2dbb4649-bcac-47ab-a817-ca17dcd70378"),
469 },
470 );
471 let (exercise_block_3, exercise_3, slide_3, task_3) = create_best_exercise(
472 Uuid::new_v5(&course_id, b"c0986981-c8ae-4c0b-b558-1163a16760ec"),
473 exercise_3_slide_1_task_1_spec_1_id,
474 exercise_3_slide_1_task_1_spec_2_id,
475 exercise_3_slide_1_task_1_spec_3_id,
476 Some("Best exercise".to_string()),
477 CommonExerciseData {
478 exercise_id: exercise_3_id,
479 exercise_slide_id: exercise_3_slide_1_id,
480 exercise_task_id: exercise_3_slide_1_task_1_id,
481 block_id: Uuid::new_v5(&course_id, b"fb26489d-ca49-4f76-a1c2-f759ed3146c0"),
482 },
483 );
484 let (exercise_block_4, exercise_4, slide_4, task_4_1) = create_best_exercise(
485 Uuid::new_v5(&course_id, b"389e80bd-5f91-40c7-94ff-7dda1eeb96fb"),
486 exercise_4_slide_1_task_1_spec_1_id,
487 exercise_4_slide_1_task_1_spec_2_id,
488 exercise_4_slide_1_task_1_spec_3_id,
489 Some("Best exercise".to_string()),
490 CommonExerciseData {
491 exercise_id: exercise_4_id,
492 exercise_slide_id: exercise_4_slide_1_id,
493 exercise_task_id: exercise_4_slide_1_task_1_id,
494 block_id: Uuid::new_v5(&course_id, b"334593ad-8ba5-4589-b1f7-b159e754bdc5"),
495 },
496 );
497
498 let page2_id = create_page(
499 &mut conn,
500 course.id,
501 teacher_user_id,
502 Some(chapter_1.id),
503 CmsPageUpdate {
504 url_path: "/chapter-1/page-2".to_string(),
505 title: "Page 2".to_string(),
506 chapter_id: Some(chapter_1.id),
507 exercises: vec![exercise_2, exercise_3, exercise_4],
508 exercise_slides: vec![slide_2, slide_3, slide_4],
509 exercise_tasks: vec![task_2, task_3, task_4_1],
510 content: serde_json::json!([
511 paragraph(
512 "First chapters second page.",
513 Uuid::new_v5(&course_id, b"9faf5a2d-f60d-4a70-af3d-0e7e3d6fe273"),
514 ),
515 exercise_block_2,
516 exercise_block_3,
517 exercise_block_4,
518 ]),
519 },
520 )
521 .await?;
522
523 url_redirections::upsert(
524 &mut conn,
525 PKeyPolicy::Generate,
526 page2_id,
527 "/old-url",
528 course.id,
529 )
530 .await?;
531
532 let (
533 quizzes_exercise_block_1,
534 quizzes_exercise_1,
535 quizzes_exercise_slide_1,
536 quizzes_exercise_task_1,
537 ) = quizzes_exercise(
538 "Best quizzes exercise".to_string(),
539 Uuid::new_v5(&course_id, b"f6f63ff0-c119-4141-922b-bc04cbfa0a31"),
540 true,
541 serde_json::json!({
542 "id": "a2704a2b-fe3d-4945-a007-5593e4b81195",
543 "body": "very hard",
544 "open": "2021-12-17T07:15:33.479Z",
545 "part": 0,
546 "items": [{
547 "id": "c449acf6-094e-494e-aef4-f5dfa51729ae",
548 "body": "",
549 "type": "essay",
550 "multi": false,
551 "multipleChoiceMultipleOptionsGradingPolicy": "default",
552 "order": 0,
553 "title": "write an essay",
554 "quizId": "a2704a2b-fe3d-4945-a007-5593e4b81195",
555 "options": [],
556 "maxValue": null,
557 "maxWords": 500,
558 "minValue": null,
559 "minWords": 10,
560 "createdAt": "2021-12-17T07:16:23.202Z",
561 "direction": "row",
562 "updatedAt": "2021-12-17T07:16:23.202Z",
563 "formatRegex": null,
564 "validityRegex": null,
565 "failureMessage": null,
566 "successMessage": null,
567 "allAnswersCorrect": false,
568 "sharedOptionFeedbackMessage": null,
569 "usesSharedOptionFeedbackMessage": false
570 }],
571 "title": "Pretty good exercise",
572 "tries": 1,
573 "points": 2,
574 "section": 0,
575 "courseId": "1dbd4a71-5f4c-49c9-b8a0-2e65fb8c4e0c",
576 "deadline": "3125-12-17T07:15:33.479Z",
577 "createdAt": "2021-12-17T07:15:33.479Z",
578 "updatedAt": "2021-12-17T07:15:33.479Z",
579 "autoReject": false,
580 "autoConfirm": true,
581 "triesLimited": true,
582 "submitMessage": "This is an extra submit message from the teacher.",
583 "excludedFromScore": true,
584 "grantPointsPolicy": "grant_whenever_possible",
585 "awardPointsEvenIfWrong": false}),
586 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
587 CommonExerciseData {
588 exercise_id: Uuid::new_v5(&course_id, b"a6ee42d0-2200-43b7-9981-620753a9b5c0"),
589 exercise_slide_id: Uuid::new_v5(&course_id, b"8d01d9b3-87d1-4e24-bee2-2726d3853ec6"),
590 exercise_task_id: Uuid::new_v5(&course_id, b"00dd984d-8651-404e-80b8-30fae9cf32ed"),
591 block_id: Uuid::new_v5(&course_id, b"a66c2552-8123-4287-bd8b-b49a29204870"),
592 },
593 );
594
595 let (
596 quizzes_exercise_block_2,
597 quizzes_exercise_2,
598 quizzes_exercise_slide_2,
599 quizzes_exercise_task_2,
600 ) = quizzes_exercise(
601 "Best quizzes exercise".to_string(),
602 Uuid::new_v5(&course_id, b"1057f91c-9dac-4364-9d6a-fa416abc540b"),
603 false,
604 serde_json::json!({
605 "id": "1e2bb795-1736-4b37-ae44-b16ca59b4e4f",
606 "body": "very hard",
607 "open": "2021-12-17T07:15:33.479Z",
608 "part": 0,
609 "items": [{
610 "id": "d81a81f2-5e44-48c5-ab6d-f724af8a23f2",
611 "body": "",
612 "type": "open",
613 "multi": false,
614 "multipleChoiceMultipleOptionsGradingPolicy": "default",
615 "order": 0,
616 "title": "When you started studying at the uni? Give the date in yyyy-mm-dd format.",
617 "quizId": "690c69e2-9275-4cfa-aba4-63ac917e59f6",
618 "options": [],
619 "maxValue": null,
620 "maxWords": null,
621 "minValue": null,
622 "minWords": null,
623 "createdAt": "2021-12-17T07:16:23.202Z",
624 "direction": "row",
625 "updatedAt": "2021-12-17T07:16:23.202Z",
626 "formatRegex": null,
627 "validityRegex": r"^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$".to_string(),
628 "failureMessage": "Oh no! Your answer is not in yyyy-mm-dd format :(".to_string(),
629 "successMessage": "Gongrats! your answer is in yyyy-mm-dd format!".to_string(),
630 "allAnswersCorrect": false,
631 "sharedOptionFeedbackMessage": null,
632 "usesSharedOptionFeedbackMessage": false
633 }],
634 "title": "Pretty good exercise",
635 "tries": 1,
636 "points": 2,
637 "section": 0,
638 "courseId": "39c7879a-e61f-474a-8f18-7fc476ccc3a0",
639 "deadline": "2021-12-17T07:15:33.479Z",
640 "createdAt": "2021-12-17T07:15:33.479Z",
641 "updatedAt": "2021-12-17T07:15:33.479Z",
642 "autoReject": false,
643 "autoConfirm": true,
644 "randomizeOptions": false,
645 "triesLimited": true,
646 "submitMessage": "This is an extra submit message from the teacher.",
647 "excludedFromScore": true,
648 "grantPointsPolicy": "grant_whenever_possible",
649 "awardPointsEvenIfWrong": false}),
650 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
651 CommonExerciseData {
652 exercise_id: Uuid::new_v5(&course_id, b"949b548f-a87f-4dc6-aafc-9f1e1abe34a7"),
653 exercise_slide_id: Uuid::new_v5(&course_id, b"39c36d3f-017e-4c36-a97e-908e25b3678b"),
654 exercise_task_id: Uuid::new_v5(&course_id, b"8ae8971c-95dd-4d8c-b38f-152ad89c6b20"),
655 block_id: Uuid::new_v5(&course_id, b"d05b1d9b-f270-4e5e-baeb-a904ea29dc90"),
656 },
657 );
658
659 let (
660 quizzes_exercise_block_3,
661 quizzes_exercise_3,
662 quizzes_exercise_slide_3,
663 quizzes_exercise_task_3,
664 ) = quizzes_exercise(
665 "Best quizzes exercise".to_string(),
666 Uuid::new_v5(&course_id, b"8845b17e-2320-4384-97f8-24e42457cb5e"),
667 false,
668 serde_json::json!({
669 "id": "f1f0520e-3037-409c-b52d-163ad0bc5c59",
670 "body": "very hard",
671 "open": "2021-12-17T07:15:33.479Z",
672 "part": 0,
673 "items": [{
674 "id": "f8cff916-da28-40ab-9e8b-f523e661ddb6",
675 "body": "",
676 "type": "multiple-choice-dropdown",
677 "multi": false,
678 "multipleChoiceMultipleOptionsGradingPolicy": "default",
679 "order": 0,
680 "title": "Choose the right answer from given options.",
681 "quizId": "f1f0520e-3037-409c-b52d-163ad0bc5c59",
682 "options": [{
683 "id": "86a2d838-04aa-4b1c-8115-2c15ed19e7b3",
684 "body": null,
685 "order": 1,
686 "title": "The right answer",
687 "quizItemId": "f8cff916-da28-40ab-9e8b-f523e661ddb6",
688 "correct":true,
689 "messageAfterSubmissionWhenSelected": "You chose wisely...",
690 "additionalCorrectnessExplanationOnModelSolution": null,
691 },
692 {
693 "id": "fef8cd36-04ab-48f2-861c-51769ccad52f",
694 "body": null,
695 "order": 2,
696 "title": "The Wright answer",
697 "quizItemId": "f8cff916-da28-40ab-9e8b-f523e661ddb6",
698 "correct":false,
699 "messageAfterSubmissionWhenSelected": "You chose poorly...",
700 "additionalCorrectnessExplanationOnModelSolution": null,
701 }],
702 "maxValue": null,
703 "maxWords": null,
704 "minValue": null,
705 "minWords": null,
706 "createdAt": "2021-12-17T07:16:23.202Z",
707 "direction": "row",
708 "updatedAt": "2021-12-17T07:16:23.202Z",
709 "formatRegex": null,
710 "validityRegex": null,
711 "messageAfterSubmissionWhenSelected": null,
712 "additionalCorrectnessExplanationOnModelSolution": null,
713 "allAnswersCorrect": false,
714 "sharedOptionFeedbackMessage": null,
715 "usesSharedOptionFeedbackMessage": false
716 }],
717 "title": "Pretty good exercise",
718 "tries": 1,
719 "points": 2,
720 "section": 0,
721 "courseId": "39c7879a-e61f-474a-8f18-7fc476ccc3a0",
722 "deadline": "2021-12-17T07:15:33.479Z",
723 "createdAt": "2021-12-17T07:15:33.479Z",
724 "updatedAt": "2021-12-17T07:15:33.479Z",
725 "autoReject": false,
726 "autoConfirm": true,
727 "randomizeOptions": false,
728 "triesLimited": true,
729 "submitMessage": "This is an extra submit message from the teacher.",
730 "excludedFromScore": true,
731 "grantPointsPolicy": "grant_whenever_possible",
732 "awardPointsEvenIfWrong": false}),
733 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
734 CommonExerciseData {
735 exercise_id: Uuid::new_v5(&course_id, b"9bcf634d-584c-4fef-892c-3c0e97dab1d5"),
736 exercise_slide_id: Uuid::new_v5(&course_id, b"984457f6-bc9b-4604-b54c-80fb4adfab76"),
737 exercise_task_id: Uuid::new_v5(&course_id, b"e4230b3a-1db8-49c4-9554-1f96f7f3d015"),
738 block_id: Uuid::new_v5(&course_id, b"52939561-af36-4ab6-bffa-be97e94d3314"),
739 },
740 );
741
742 let (
743 quizzes_exercise_block_4,
744 quizzes_exercise_4,
745 quizzes_exercise_slide_4,
746 quizzes_exercise_task_4,
747 ) = quizzes_exercise(
748 "Best quizzes exercise".to_string(),
749 Uuid::new_v5(&course_id, b"7ca39a36-2dcd-4521-bbf6-bfc5849874e3"),
750 false,
751 serde_json::json!({
752 "version": "2",
753 "title": "",
754 "body": "very hard",
755 "awardPointsEvenIfWrong": false,
756 "grantPointsPolicy": "grant_whenever_possible",
757 "quizItemDisplayDirection": "vertical",
758 "submitMessage": "This is an extra submit message from the teacher.",
759 "items": [
760 {
761 "type": "choose-n",
762 "id": "663c52bd-f649-4ba2-9c39-2387c386cbf1",
763 "failureMessage": "",
764 "options": [
765 {
766 "order": 1,
767 "additionalCorrectnessExplanationOnModelSolution": "",
768 "body": "",
769 "correct": true,
770 "id": "9339c966-cc48-4a6c-9512-b38c82240dd0",
771 "messageAfterSubmissionWhenSelected": "Java is a programming language",
772 "title": "Java"
773 },
774 {
775 "order": 2,
776 "additionalCorrectnessExplanationOnModelSolution": "",
777 "body": "",
778 "correct": true,
779 "id": "2e6de165-ea76-4f03-a216-2f15179c9e6e",
780 "messageAfterSubmissionWhenSelected": "Erlang is a programming language",
781 "title": "Erlang"
782 },
783 {
784 "order": 3,
785 "additionalCorrectnessExplanationOnModelSolution": "",
786 "body": "",
787 "correct": false,
788 "id": "2d452914-8cf7-426c-b130-51d556a33566",
789 "messageAfterSubmissionWhenSelected": "Jupiter is not a programming language",
790 "title": "Jupiter"
791 },
792 {
793 "order": 4,
794 "additionalCorrectnessExplanationOnModelSolution": "",
795 "body": "",
796 "correct": true,
797 "id": "d503894c-3eaf-4ebe-a7d5-95f04b641479",
798 "messageAfterSubmissionWhenSelected": "Rust is a programming language",
799 "title": "Rust"
800 },
801 {
802 "order": 5,
803 "additionalCorrectnessExplanationOnModelSolution": "",
804 "body": "",
805 "correct": false,
806 "id": "a5a6cef2-df55-4926-9ecc-95da3e049ea7",
807 "messageAfterSubmissionWhenSelected": "AC is not a programming language",
808 "title": "AC"
809 }
810 ],
811 "order": 0,
812 "successMessage": "",
813 "title": "Pick all the programming languages from below",
814 "body": "",
815 "n": 2
816 }
817 ]
818 }),
819 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
820 CommonExerciseData {
821 exercise_id: Uuid::new_v5(&course_id, b"854a4e05-6575-4d27-8feb-6ee01f662d8a"),
822 exercise_slide_id: Uuid::new_v5(&course_id, b"6a8e65be-f5cd-4c87-b4f9-9522cb37bbcb"),
823 exercise_task_id: Uuid::new_v5(&course_id, b"b5e1e7e87-0678-4296-acf7-a8ac926ff94b"),
824 block_id: Uuid::new_v5(&course_id, b"50e26d7f-f11f-4a8a-990d-fb17c3371d1d"),
825 },
826 );
827
828 let (
829 quizzes_exercise_block_5,
830 quizzes_exercise_5,
831 quizzes_exercise_slide_5,
832 quizzes_exercise_task_5,
833 ) = quizzes_exercise(
834 "Best quizzes exercise".to_string(),
835 Uuid::new_v5(&course.id, b"b2f7d8d5-f3c0-4cac-8eb7-89a7b88c2236"),
836 false,
837 serde_json::json!({
838 "autoConfirm": true,
839 "randomizeOptions": false,
840 "autoReject": false,
841 "awardPointsEvenIfWrong": false,
842 "body": "",
843 "courseId": "29b09b7e-337f-4074-b14b-6109427a52f6",
844 "createdAt": "2022-05-04T09:03:06.271Z",
845 "deadline": "2022-05-04T09:03:06.271Z",
846 "excludedFromScore": true,
847 "grantPointsPolicy": "grant_whenever_possible",
848 "id": "72c3bb44-1695-4ea0-af3e-f2280c726551",
849 "items": [
850 {
851 "allAnswersCorrect": false,
852 "body": "",
853 "createdAt": "2022-05-04T09:03:09.167Z",
854 "direction": "column",
855 "failureMessage": null,
856 "formatRegex": null,
857 "id": "105270c8-e94a-40ec-a159-8fe38f116bb4",
858 "maxValue": null,
859 "maxWords": null,
860 "minValue": null,
861 "minWords": null,
862 "multi": false,
863 "optionCells": null,
864 "options": [],
865 "order": 0,
866 "quizId": "72c3bb44-1695-4ea0-af3e-f2280c726551",
867 "sharedOptionFeedbackMessage": null,
868 "successMessage": null,
869 "timelineItems": [
870 {
871 "correctEventId": "59e30264-fb11-4e44-a91e-1c5cf80fd977",
872 "correctEventName": "Finland joins the European Union",
873 "id": "c40fc487-9cb9-4007-80d3-8ffd7a8dc799",
874 "year": "1995"
875 },
876 {
877 "correctEventId": "0ee17a8e-6d51-4620-b355-90815462543f",
878 "correctEventName": "Finland switches their currency to Euro",
879 "id": "d63fd98e-b73c-47cf-a634-9046249c78e4",
880 "year": "2002"
881 },
882 {
883 "correctEventId": "0a59d2d3-6cf6-4b91-b1bd-873eefde78ac",
884 "correctEventName": "Finland joins the Economic and Monetary Union of the European Union",
885 "id": "50d7641c-382e-4805-95d8-e873c462bc48",
886 "year": "1998"
887 }
888 ],
889 "title": "",
890 "type": "timeline",
891 "updatedAt": "2022-05-04T09:03:09.167Z",
892 "usesSharedOptionFeedbackMessage": false,
893 "validityRegex": null
894 }
895 ],
896 "open": "2022-05-04T09:03:06.271Z",
897 "part": 0,
898 "points": 0,
899 "section": 0,
900 "submitMessage": "This is an extra submit message from the teacher.",
901 "title": "",
902 "tries": 1,
903 "triesLimited": true,
904 "updatedAt": "2022-05-04T09:03:06.271Z"
905 }),
906 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
907 CommonExerciseData {
908 exercise_id: Uuid::new_v5(&course.id, b"981623c8-baa3-4d14-bb8a-963e167da9ca"),
909 exercise_slide_id: Uuid::new_v5(&course.id, b"b1a6d7e4-00b2-43fb-bf39-863f4ef49d09"),
910 exercise_task_id: Uuid::new_v5(&course.id, b"1a2f2c9f-9552-440e-8dd3-1e3703bd0fab"),
911 block_id: Uuid::new_v5(&course.id, b"6b568812-f752-4d9f-a60a-48257822d21e"),
912 },
913 );
914
915 let (
916 quizzes_exercise_block_6,
917 quizzes_exercise_6,
918 quizzes_exercise_slide_6,
919 quizzes_exercise_task_6,
920 ) = quizzes_exercise(
921 "Multiple choice with feedback".to_string(),
922 Uuid::new_v5(&course.id, b"664ea614-4af4-4ad0-9855-eae1881568e6"),
923 false,
924 serde_json::from_str(include_str!(
925 "../../assets/quizzes-multiple-choice-feedback.json"
926 ))?,
927 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
928 CommonExerciseData {
929 exercise_id: Uuid::new_v5(&course.id, b"f7fa3a08-e287-44de-aea8-32133af89d31"),
930 exercise_slide_id: Uuid::new_v5(&course.id, b"31820133-579a-4d9f-8b0c-2120f76d1390"),
931 exercise_task_id: Uuid::new_v5(&course.id, b"55f929c7-30ab-441d-a0ad-6cd115857b3b"),
932 block_id: Uuid::new_v5(&course.id, b"d7a91d07-9bd9-449c-9862-fbacb0b402b0"),
933 },
934 );
935
936 let (
937 quizzes_exercise_block_7,
938 quizzes_exercise_7,
939 quizzes_exercise_slide_7,
940 quizzes_exercise_task_7,
941 ) = quizzes_exercise(
942 "Scale".to_string(),
943 Uuid::new_v5(&course.id, b"05fa1188-4653-4904-bf1c-a93363225841"),
944 false,
945 serde_json::from_str(include_str!("../../assets/scale.json"))?,
946 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
947 CommonExerciseData {
948 exercise_id: Uuid::new_v5(&course.id, b"212132eb-b108-4027-b312-2275cf0b7473"),
949 exercise_slide_id: Uuid::new_v5(&course.id, b"6172a36a-b65d-463c-81d0-7f7fce07615c"),
950 exercise_task_id: Uuid::new_v5(&course.id, b"0dcfc4ca-c2f7-40b0-8654-14c6893a1fd9"),
951 block_id: Uuid::new_v5(&course.id, b"b64d7bd2-a216-494e-a23c-7a975fb1a415"),
952 },
953 );
954
955 let (
956 quizzes_exercise_block_8,
957 quizzes_exercise_8,
958 quizzes_exercise_slide_8,
959 quizzes_exercise_task_8,
960 ) = quizzes_exercise(
961 "Vector exercise".to_string(),
962 Uuid::new_v5(&course.id, b"0c271345-6934-4489-8164-2cc4dc8974bb"),
963 false,
964 serde_json::from_str(include_str!("../../assets/vector-exercise.json"))?,
965 None,
966 CommonExerciseData {
967 exercise_id: Uuid::new_v5(&course.id, b"80373dc3-ceba-45b4-a114-161d60228c0c"),
968 exercise_slide_id: Uuid::new_v5(&course.id, b"08f0da90-9080-4cdd-adc7-66173cd5b833"),
969 exercise_task_id: Uuid::new_v5(&course.id, b"ea24c875-1a3c-403e-8272-b1249a475c89"),
970 block_id: Uuid::new_v5(&course.id, b"38ed716f-5d4f-4ddd-9f5a-700ef124b934"),
971 },
972 );
973
974 let page_3 = create_page(
975 &mut conn,
976 course.id,
977 teacher_user_id,
978 Some(chapter_1.id),
979 CmsPageUpdate {
980 url_path: "/chapter-1/page-3".to_string(),
981 title: "Page 3".to_string(),
982 chapter_id: Some(chapter_1.id),
983 exercises: vec![quizzes_exercise_1],
984 exercise_slides: vec![quizzes_exercise_slide_1],
985 exercise_tasks: vec![quizzes_exercise_task_1],
986 content: serde_json::json!([
987 paragraph(
988 "First chapters essay page.",
989 Uuid::new_v5(&course_id, b"6e4ab83a-2ae8-4bd2-a6ea-0e0d1eeabe23")
990 ),
991 quizzes_exercise_block_1,
992 ]),
993 },
994 )
995 .await?;
996
997 create_page(
998 &mut conn,
999 course.id,
1000 teacher_user_id,
1001 Some(chapter_1.id),
1002 CmsPageUpdate {
1003 url_path: "/chapter-1/page-4".to_string(),
1004 title: "Page 4".to_string(),
1005 chapter_id: Some(chapter_1.id),
1006 exercises: vec![quizzes_exercise_2],
1007 exercise_slides: vec![quizzes_exercise_slide_2],
1008 exercise_tasks: vec![quizzes_exercise_task_2],
1009 content: serde_json::json!([
1010 paragraph(
1011 "First chapters open page.",
1012 Uuid::new_v5(&course_id, b"771b9c61-dbc9-4266-a980-dadc853455c9")
1013 ),
1014 quizzes_exercise_block_2
1015 ]),
1016 },
1017 )
1018 .await?;
1019
1020 create_page(
1021 &mut conn,
1022 course.id,
1023 teacher_user_id,
1024 Some(chapter_1.id),
1025 CmsPageUpdate {
1026 url_path: "/chapter-1/page-5".to_string(),
1027 title: "Page 5".to_string(),
1028 chapter_id: Some(chapter_1.id),
1029 exercises: vec![quizzes_exercise_3],
1030 exercise_slides: vec![quizzes_exercise_slide_3],
1031 exercise_tasks: vec![quizzes_exercise_task_3],
1032 content: serde_json::json!([
1033 paragraph(
1034 "First chapters multiple-choice-dropdown page",
1035 Uuid::new_v5(&course_id, b"7af470e7-cc4f-411e-ad5d-c137e353f7c3")
1036 ),
1037 quizzes_exercise_block_3
1038 ]),
1039 },
1040 )
1041 .await?;
1042
1043 create_page(
1044 &mut conn,
1045 course.id,
1046 teacher_user_id,
1047 Some(chapter_1.id),
1048 CmsPageUpdate {
1049 url_path: "/chapter-1/page-6".to_string(),
1050 title: "Page 6".to_string(),
1051 chapter_id: Some(chapter_1.id),
1052 exercises: vec![quizzes_exercise_4],
1053 exercise_slides: vec![quizzes_exercise_slide_4],
1054 exercise_tasks: vec![quizzes_exercise_task_4],
1055 content: serde_json::json!([
1056 paragraph(
1057 "First chapters multiple-choice clickable page.",
1058 Uuid::new_v5(&course_id, b"6b7775c3-b46e-41e5-a730-0a2c2f0ba148")
1059 ),
1060 quizzes_exercise_block_4
1061 ]),
1062 },
1063 )
1064 .await?;
1065
1066 create_page(
1067 &mut conn,
1068 course.id,
1069 teacher_user_id,
1070 Some(chapter_1.id),
1071 CmsPageUpdate {
1072 url_path: "/chapter-1/the-timeline".to_string(),
1073 title: "The timeline".to_string(),
1074 chapter_id: Some(chapter_2.id),
1075 exercises: vec![quizzes_exercise_5],
1076 exercise_slides: vec![quizzes_exercise_slide_5],
1077 exercise_tasks: vec![quizzes_exercise_task_5],
1078 content: serde_json::json!([
1079 paragraph(
1080 "Best page",
1081 Uuid::new_v5(&course.id, b"891de1ca-f3a9-506f-a268-3477ea4fdd27")
1082 ),
1083 quizzes_exercise_block_5,
1084 ]),
1085 },
1086 )
1087 .await?;
1088
1089 create_page(
1090 &mut conn,
1091 course.id,
1092 teacher_user_id,
1093 Some(chapter_1.id),
1094 CmsPageUpdate {
1095 url_path: "/chapter-1/scale".to_string(),
1096 title: "scale".to_string(),
1097 chapter_id: Some(chapter_1.id),
1098 exercises: vec![quizzes_exercise_7],
1099 exercise_slides: vec![quizzes_exercise_slide_7],
1100 exercise_tasks: vec![quizzes_exercise_task_7],
1101 content: serde_json::json!([
1102 paragraph(
1103 "The page for the scale execise.",
1104 Uuid::new_v5(&course_id, b"53f68082-c417-4d38-99ad-40b6a30b2da4")
1105 ),
1106 quizzes_exercise_block_7
1107 ]),
1108 },
1109 )
1110 .await?;
1111
1112 create_page(
1113 &mut conn,
1114 course.id,
1115 teacher_user_id,
1116 Some(chapter_1.id),
1117 CmsPageUpdate {
1118 url_path: "/chapter-1/the-multiple-choice-with-feedback".to_string(),
1119 title: "Multiple choice with feedback".to_string(),
1120 chapter_id: Some(chapter_1.id),
1121 exercises: vec![quizzes_exercise_6],
1122 exercise_slides: vec![quizzes_exercise_slide_6],
1123 exercise_tasks: vec![quizzes_exercise_task_6],
1124 content: serde_json::json!([
1125 paragraph(
1126 "Something about rust and feedback.",
1127 Uuid::new_v5(&course_id, b"cbb87878-5af1-4c01-b343-97bf668b8034")
1128 ),
1129 quizzes_exercise_block_6
1130 ]),
1131 },
1132 )
1133 .await?;
1134
1135 create_page(
1136 &mut conn,
1137 course.id,
1138 teacher_user_id,
1139 Some(chapter_1.id),
1140 CmsPageUpdate {
1141 url_path: "/chapter-1/vector".to_string(),
1142 title: "Vector".to_string(),
1143 chapter_id: Some(chapter_1.id),
1144 exercises: vec![quizzes_exercise_8],
1145 exercise_slides: vec![quizzes_exercise_slide_8],
1146 exercise_tasks: vec![quizzes_exercise_task_8],
1147 content: serde_json::json!([
1148 paragraph(
1149 "This page has a vector exercise composed of three close-ended questions.",
1150 Uuid::new_v5(&course_id, b"53f68082-c417-4d38-99ad-40b6a30b2da4")
1151 ),
1152 quizzes_exercise_block_8
1153 ]),
1154 },
1155 )
1156 .await?;
1157
1158 let multi_exercise_1_id = Uuid::new_v5(&course_id, b"3abe8579-73f1-4cdf-aba0-3e123fcedaea");
1159 let multi_exercise_1_slide_1_id =
1160 Uuid::new_v5(&course_id, b"efc7663c-b0fd-4e21-893a-7b7891191e07");
1161 let multi_exercise_1_slide_1_task_1_id =
1162 Uuid::new_v5(&course_id, b"b8833157-aa58-4472-a09b-98406a82ef42");
1163 let multi_exercise_1_slide_1_task_2_id =
1164 Uuid::new_v5(&course_id, b"36921424-0a65-4de8-8f92-3be96d695463");
1165 let multi_exercise_1_slide_1_task_3_id =
1166 Uuid::new_v5(&course_id, b"4c4bc8e5-7108-4f0d-a3d9-54383aa57269");
1167 let (multi_exercise_block_1, multi_exercise_1, multi_exercise_1_slides, multi_exercise_1_tasks) =
1168 example_exercise_flexible(
1169 multi_exercise_1_id,
1170 "Multiple task exercise".to_string(),
1171 vec![(
1172 multi_exercise_1_slide_1_id,
1173 vec![
1174 (
1175 multi_exercise_1_slide_1_task_1_id,
1176 "example-exercise".to_string(),
1177 serde_json::json!([paragraph(
1178 "First question.",
1179 Uuid::new_v5(&course_id, b"e972a22b-67ae-4971-b437-70effd5614d4")
1180 )]),
1181 serde_json::json!([
1182 {
1183 "name": "Correct",
1184 "correct": true,
1185 "id": Uuid::new_v5(&course_id, b"0a046287-6b49-405d-ad9e-12f6dc5f9b1d"),
1186 },
1187 {
1188 "name": "Incorrect",
1189 "correct": false,
1190 "id": Uuid::new_v5(&course_id, b"c202540e-9a3f-4ff4-9703-b9921e9eee8e"),
1191 },
1192 ]),
1193 ),
1194 (
1195 multi_exercise_1_slide_1_task_2_id,
1196 "example-exercise".to_string(),
1197 serde_json::json!([paragraph(
1198 "Second question.",
1199 Uuid::new_v5(&course_id, b"e4895ced-757c-401a-8836-b734b75dff54")
1200 )]),
1201 serde_json::json!([
1202 {
1203 "name": "Correct",
1204 "correct": true,
1205 "id": Uuid::new_v5(&course_id, b"e0c2efa8-ac15-4a3c-94bb-7d5e72e57671"),
1206 },
1207 {
1208 "name": "Incorrect",
1209 "correct": false,
1210 "id": Uuid::new_v5(&course_id, b"db5cf7d4-b5bb-43f7-931e-e329cc2e95b1"),
1211 },
1212 ]),
1213 ),
1214 (
1215 multi_exercise_1_slide_1_task_3_id,
1216 "example-exercise".to_string(),
1217 serde_json::json!([paragraph(
1218 "Third question.",
1219 Uuid::new_v5(&course_id, b"13b75f4e-b02d-41fa-b5bc-79adf22d9aef")
1220 )]),
1221 serde_json::json!([
1222 {
1223 "name": "Correct",
1224 "correct": true,
1225 "id": Uuid::new_v5(&course_id, b"856defd2-08dd-4632-aaef-ec71cdfd3bca"),
1226 },
1227 {
1228 "name": "Incorrect",
1229 "correct": false,
1230 "id": Uuid::new_v5(&course_id, b"95ffff70-7dbe-4e39-9480-2a3514e9ea1d"),
1231 },
1232 ]),
1233 ),
1234 ],
1235 )],
1236 Uuid::new_v5(&course_id, b"9e70076a-9137-4d65-989c-0c0951027c53"),
1237 );
1238 create_page(
1239 &mut conn,
1240 course.id,
1241 teacher_user_id,
1242 Some(chapter_1.id),
1243 CmsPageUpdate {
1244 url_path: "/chapter-1/complicated-exercise".to_string(),
1245 title: "Complicated exercise page".to_string(),
1246 chapter_id: Some(chapter_1.id),
1247 exercises: vec![multi_exercise_1],
1248 exercise_slides: multi_exercise_1_slides,
1249 exercise_tasks: multi_exercise_1_tasks,
1250 content: serde_json::json!([
1251 paragraph(
1252 "This page has a complicated exercise.",
1253 Uuid::new_v5(&course_id, b"86f1b595-ec82-43a6-954f-c1f8de3d53ac")
1254 ),
1255 multi_exercise_block_1
1256 ]),
1257 },
1258 )
1259 .await?;
1260
1261 let exercise_5_id = Uuid::new_v5(&course_id, b"8bb4faf4-9a34-4df7-a166-89ade530d0f6");
1262 let exercise_5_slide_1_id = Uuid::new_v5(&course_id, b"b99d1041-7835-491e-a1c8-b47eee8e7ab4");
1263 let exercise_5_slide_1_task_1_id =
1264 Uuid::new_v5(&course_id, b"a6508b8a-f58e-43ac-9f02-785575e716f5");
1265 let exercise_5_slide_1_task_1_spec_1_id =
1266 Uuid::new_v5(&course_id, b"fe464d17-2365-4e65-8b33-e0ebb5a67836");
1267 let exercise_5_slide_1_task_1_spec_2_id =
1268 Uuid::new_v5(&course_id, b"6633ffc7-c76e-4049-840e-90eefa6b49e8");
1269 let exercise_5_slide_1_task_1_spec_3_id =
1270 Uuid::new_v5(&course_id, b"d77fb97d-322c-4c5f-a405-8978a8cfb0a9");
1271 let (exercise_block_5, exercise_5, exercise_slide_5, exercise_task_5) = create_best_exercise(
1272 Uuid::new_v5(&course_id, b"fe464d17-2365-4e65-8b33-e0ebb5a67836"),
1273 exercise_5_slide_1_task_1_spec_1_id,
1274 exercise_5_slide_1_task_1_spec_2_id,
1275 exercise_5_slide_1_task_1_spec_3_id,
1276 Some("Best exercise".to_string()),
1277 CommonExerciseData {
1278 exercise_id: exercise_5_id,
1279 exercise_slide_id: exercise_5_slide_1_id,
1280 exercise_task_id: exercise_5_slide_1_task_1_id,
1281 block_id: Uuid::new_v5(&course_id, b"e869c471-b1b7-42a0-af05-dffd1d86a7bb"),
1282 },
1283 );
1284 create_page(
1285 &mut conn,
1286 course.id,
1287 teacher_user_id,
1288 Some(chapter_2.id),
1289 CmsPageUpdate {
1290 url_path: "/chapter-2/intro".to_string(),
1291 title: "In the second chapter...".to_string(),
1292 chapter_id: Some(chapter_2.id),
1293 exercises: vec![exercise_5],
1294 exercise_slides: vec![exercise_slide_5],
1295 exercise_tasks: vec![exercise_task_5],
1296 content: serde_json::json!([exercise_block_5]),
1297 },
1298 )
1299 .await?;
1300
1301 let multi_exercise_2_id = Uuid::new_v5(&course_id, b"057def52-6895-4374-a7f5-1849d136f1f4");
1302 let multi_exercise_2_slide_1_id =
1303 Uuid::new_v5(&course_id, b"fa02d232-8e33-4e20-9c20-d3b03fa89eb5");
1304 let multi_exercise_2_slide_1_task_1_id =
1305 Uuid::new_v5(&course_id, b"6c72f989-4d7e-4b22-b63c-3c51c631abcb");
1306 let multi_exercise_2_slide_1_task_2_id =
1307 Uuid::new_v5(&course_id, b"9445e8a3-6a86-4492-96b8-971f7b7acedd");
1308 let multi_exercise_2_slide_1_task_3_id =
1309 Uuid::new_v5(&course_id, b"8fbdbc4d-0c62-4b70-bb31-4c5fbb4ea6dd");
1310 let (multi_exercise_block_2, multi_exercise_2, multi_exercise_2_slides, multi_exercise_2_tasks) =
1311 example_exercise_flexible(
1312 multi_exercise_2_id,
1313 "Multiple task quizzes exercise".to_string(),
1314 vec![(
1315 multi_exercise_2_slide_1_id,
1316 vec![
1317 (
1318 multi_exercise_2_slide_1_task_1_id,
1319 "quizzes".to_string(),
1320 serde_json::json!([paragraph(
1321 "First question.",
1322 Uuid::new_v5(&course_id, b"c8414adc-4e99-4d93-b926-e257517ff934")
1323 )]),
1324 serde_json::json!({
1325 "id": "e8a81dad-d616-44ab-bd6e-ec5430b454be",
1326 "body": "very hard",
1327 "open": "2021-12-17T07:15:33.479Z",
1328 "part": 0,
1329 "items": [{
1330 "id": "ba2b179a-fab7-4eb7-896f-ef841eeda8e5",
1331 "body": null,
1332 "type": "multiple-choice",
1333 "multi": false,
1334 "multipleChoiceMultipleOptionsGradingPolicy": "default",
1335 "order": 0,
1336 "title": "Select all correct answers from below",
1337 "quizId": "e8a81dad-d616-44ab-bd6e-ec5430b454be",
1338 "options": [
1339 {
1340 "id": "bb172040-753d-40ef-bded-a487b668905a",
1341 "body": "Correct",
1342 "order": 1,
1343 "title": null,
1344 "quizItemId": "ba2b179a-fab7-4eb7-896f-ef841eeda8e5",
1345 "correct":true,
1346 "messageAfterSubmissionWhenSelected": "This is correct option",
1347 "additionalCorrectnessExplanationOnModelSolution": null
1348 },
1349 {
1350 "id": "a1534c77-3379-4462-b67c-f55a17aa6499",
1351 "body": "Correct",
1352 "order": 2,
1353 "title": null,
1354 "quizItemId": "ba2b179a-fab7-4eb7-896f-ef841eeda8e5",
1355 "correct":true,
1356 "messageAfterSubmissionWhenSelected": "This is correct option",
1357 "additionalCorrectnessExplanationOnModelSolution": null,
1358 },
1359 {
1360 "id": "828328e6-5491-4ccb-b6f7-1df0796db44e",
1361 "body": "Incorrect",
1362 "order": 3,
1363 "title": null,
1364 "quizItemId": "ba2b179a-fab7-4eb7-896f-ef841eeda8e5",
1365 "correct":false,
1366 "messageAfterSubmissionWhenSelected": "This is incorrect option",
1367 "additionalCorrectnessExplanationOnModelSolution": null
1368 },
1369 ],
1370 "allAnswersCorrect": false,
1371 "sharedOptionFeedbackMessage": null,
1372 "usesSharedOptionFeedbackMessage": false
1373 }],
1374 "title": "Pretty good exercise",
1375 "tries": 1,
1376 "points": 2,
1377 "section": 0,
1378 "courseId": "39c7879a-e61f-474a-8f18-7fc476ccc3a0",
1379 "deadline": "2021-12-17T07:15:33.479Z",
1380 "createdAt": "2021-12-17T07:15:33.479Z",
1381 "updatedAt": "2021-12-17T07:15:33.479Z",
1382 "autoReject": false,
1383 "autoConfirm": true,
1384 "randomizeOptions": false,
1385 "triesLimited": true,
1386 "submitMessage": "This is an extra submit message from the teacher.",
1387 "excludedFromScore": true,
1388 "grantPointsPolicy": "grant_whenever_possible",
1389 "awardPointsEvenIfWrong": false}),
1390 ),
1391 (
1392 multi_exercise_2_slide_1_task_2_id,
1393 "quizzes".to_string(),
1394 serde_json::json!([paragraph(
1395 "Second question.",
1396 Uuid::new_v5(&course_id, b"fcdeb228-a36e-499b-9cf0-dfb264a2cf34")
1397 )]),
1398 serde_json::json!({
1399 "id": "67fc1eea-541c-4247-a852-090c71d7a9d1",
1400 "body": "very hard",
1401 "open": "2021-12-17T07:15:33.479Z",
1402 "part": 0,
1403 "items": [{
1404 "id": "7640b8db-eee0-4685-b031-dde26f183c9c",
1405 "body": null,
1406 "type": "multiple-choice",
1407 "multi": false,
1408 "multipleChoiceMultipleOptionsGradingPolicy": "default",
1409 "order": 0,
1410 "title": "Select all correct answers from below",
1411 "quizId": "67fc1eea-541c-4247-a852-090c71d7a9d1",
1412 "options": [
1413 {
1414 "id": "446034b8-e049-4973-a634-5561da4b6d8e",
1415 "body": "Correct",
1416 "order": 1,
1417 "title": null,
1418 "quizItemId": "7640b8db-eee0-4685-b031-dde26f183c9c",
1419 "correct":true,
1420 "messageAfterSubmissionWhenSelected": "This is correct option",
1421 "additionalCorrectnessExplanationOnModelSolution": null
1422 },
1423 {
1424 "id": "a4a0c48a-b171-4855-b738-b248f1e50561",
1425 "body": "Incorrect",
1426 "order": 2,
1427 "title": null,
1428 "quizItemId": "7640b8db-eee0-4685-b031-dde26f183c9c",
1429 "correct":false,
1430 "messageAfterSubmissionWhenSelected": "This is incorrect option",
1431 "additionalCorrectnessExplanationOnModelSolution": null,
1432 },
1433 {
1434 "id": "f65330da-de15-47f3-9a4d-9f47eb6a5f5a",
1435 "body": "Correct",
1436 "order": 3,
1437 "title": null,
1438 "quizItemId": "7640b8db-eee0-4685-b031-dde26f183c9c",
1439 "correct":true,
1440 "messageAfterSubmissionWhenSelected": "This is correct option",
1441 "additionalCorrectnessExplanationOnModelSolution": null
1442 },
1443 ],
1444 "allAnswersCorrect": false,
1445 "sharedOptionFeedbackMessage": null,
1446 "usesSharedOptionFeedbackMessage": false
1447 }],
1448 "title": "Pretty good exercise",
1449 "tries": 1,
1450 "points": 2,
1451 "section": 0,
1452 "courseId": "39c7879a-e61f-474a-8f18-7fc476ccc3a0",
1453 "deadline": "2021-12-17T07:15:33.479Z",
1454 "createdAt": "2021-12-17T07:15:33.479Z",
1455 "updatedAt": "2021-12-17T07:15:33.479Z",
1456 "autoReject": false,
1457 "autoConfirm": true,
1458 "randomizeOptions": false,
1459 "triesLimited": true,
1460 "submitMessage": "This is an extra submit message from the teacher.",
1461 "excludedFromScore": true,
1462 "grantPointsPolicy": "grant_whenever_possible",
1463 "awardPointsEvenIfWrong": false}),
1464 ),
1465 (
1466 multi_exercise_2_slide_1_task_3_id,
1467 "quizzes".to_string(),
1468 serde_json::json!([paragraph(
1469 "Third question.",
1470 Uuid::new_v5(&course_id, b"13b75f4e-b02d-41fa-b5bc-79adf22d9aef")
1471 )]),
1472 serde_json::json!({
1473 "id": "3f332295-b409-4fa8-a690-e5afd4e06b7a",
1474 "body": "very hard",
1475 "open": "2021-12-17T07:15:33.479Z",
1476 "part": 0,
1477 "items": [{
1478 "id": "a72b53f5-97c4-4385-899b-560d06592aec",
1479 "body": null,
1480 "type": "multiple-choice",
1481 "multi": false,
1482 "multipleChoiceMultipleOptionsGradingPolicy": "default",
1483 "order": 0,
1484 "title": "Pick all the correct answers from below",
1485 "quizId": "3f332295-b409-4fa8-a690-e5afd4e06b7a",
1486 "options": [
1487 {
1488 "id": "d606fec9-6854-4b40-9b37-e1f53f4d4a0f",
1489 "body": "Incorrect",
1490 "order": 1,
1491 "title": null,
1492 "quizItemId": "a72b53f5-97c4-4385-899b-560d06592aec",
1493 "correct":false,
1494 "messageAfterSubmissionWhenSelected": "This is incorrect option",
1495 "additionalCorrectnessExplanationOnModelSolution": null
1496 },
1497 {
1498 "id": "9c69312d-c1e1-48bd-b920-309b39d2a7db",
1499 "body": "Correct",
1500 "order": 2,
1501 "title": null,
1502 "quizItemId": "a72b53f5-97c4-4385-899b-560d06592aec",
1503 "correct":true,
1504 "messageAfterSubmissionWhenSelected": "This is correct option",
1505 "additionalCorrectnessExplanationOnModelSolution": null,
1506 },
1507 {
1508 "id": "fef8854d-fee0-40ad-ab81-f4ed66daadeb",
1509 "body": "Correct",
1510 "order": 3,
1511 "title": null,
1512 "quizItemId": "a72b53f5-97c4-4385-899b-560d06592aec",
1513 "correct":true,
1514 "messageAfterSubmissionWhenSelected": "This is correct option",
1515 "additionalCorrectnessExplanationOnModelSolution": null
1516 },
1517 ],
1518 "allAnswersCorrect": false,
1519 "sharedOptionFeedbackMessage": null,
1520 "usesSharedOptionFeedbackMessage": false
1521 }],
1522 "title": "Pretty good exercise",
1523 "tries": 1,
1524 "points": 2,
1525 "section": 0,
1526 "courseId": "39c7879a-e61f-474a-8f18-7fc476ccc3a0",
1527 "deadline": "2021-12-17T07:15:33.479Z",
1528 "createdAt": "2021-12-17T07:15:33.479Z",
1529 "updatedAt": "2021-12-17T07:15:33.479Z",
1530 "autoReject": false,
1531 "autoConfirm": true,
1532 "randomizeOptions": false,
1533 "triesLimited": true,
1534 "submitMessage": "This is an extra submit message from the teacher.",
1535 "excludedFromScore": true,
1536 "grantPointsPolicy": "grant_whenever_possible",
1537 "awardPointsEvenIfWrong": false}),
1538 ),
1539 ],
1540 )],
1541 Uuid::new_v5(&course_id, b"9e70076a-9137-4d65-989c-0c0951027c53"),
1542 );
1543
1544 create_page(
1545 &mut conn,
1546 course.id,
1547 teacher_user_id,
1548 Some(chapter_1.id),
1549 CmsPageUpdate {
1550 url_path: "/chapter-1/complicated-quizzes-exercise".to_string(),
1551 title: "Complicated quizzes exercise page".to_string(),
1552 chapter_id: Some(chapter_1.id),
1553 exercises: vec![multi_exercise_2],
1554 exercise_slides: multi_exercise_2_slides,
1555 exercise_tasks: multi_exercise_2_tasks,
1556 content: serde_json::json!([
1557 paragraph(
1558 "This page has a complicated quizzes exercise.",
1559 Uuid::new_v5(&course_id, b"ea0eaf34-3c92-4007-aae4-9abff7ad1e4c")
1560 ),
1561 multi_exercise_block_2
1562 ]),
1563 },
1564 )
1565 .await?;
1566
1567 create_page(
1568 &mut conn,
1569 course.id,
1570 teacher_user_id,
1571 Some(chapter_1.id),
1572 CmsPageUpdate {
1573 url_path: "/chapter-1/the-authors".to_string(),
1574 title: "The Author Block".to_string(),
1575 chapter_id: Some(chapter_1.id),
1576 exercises: vec![],
1577 exercise_slides: vec![],
1578 exercise_tasks: vec![],
1579 content: serde_json::json!([GutenbergBlock {
1580 name: "moocfi/author".to_string(),
1581 is_valid: true,
1582 client_id: Uuid::parse_str("eb27eddd-6fc7-46f8-b7aa-968b16f86f1f").unwrap(),
1583 attributes: attributes! {},
1584 inner_blocks: vec![GutenbergBlock {
1585 name: "moocfi/author-inner-block".to_string(),
1586 is_valid: true,
1587 client_id: Uuid::parse_str("b5565362-e8e3-4837-9546-014dc98af686").unwrap(),
1588 attributes: attributes! {},
1589 inner_blocks: vec![GutenbergBlock {
1590 name: "core/columns".to_string(),
1591 is_valid: true,
1592 client_id: Uuid::parse_str("d8df9ead-9be3-4d25-96ec-c6e591db261b").unwrap(),
1593 attributes: attributes! { "isStackedOnMobile": true },
1594 inner_blocks: vec![GutenbergBlock {
1595 name: "core/column".to_string(),
1596 is_valid: true,
1597 client_id: Uuid::parse_str("6435c2f7-ccc0-4cec-9c38-19bd688b057c").unwrap(),
1598 attributes: attributes! {},
1599 inner_blocks: vec![GutenbergBlock {
1600 name: "core/image".to_string(),
1601 is_valid: true,
1602 client_id: Uuid::parse_str("f700cf35-0c8e-4905-88ed-475ad60bdf82").unwrap(),
1603 attributes: attributes! {
1604 "alt": "Add alt",
1605 "anchor": "author-photo",
1606 "blurDataUrl": "",
1607 "href": "http://project-331.local/api/v0/files/uploads/jpgs/lilo-and-stitch.jpg",
1608 "linkDestination": "media",
1609 "sizeSlug": "full",
1610 "url": "http://project-331.local/api/v0/files/uploads/jpgs/lilo-and-stitch.jpg",
1611 },
1612 inner_blocks: vec![],
1613 }],
1614 },
1615 GutenbergBlock {
1616 name: "core/column".to_string(),
1617 is_valid: true,
1618 client_id: Uuid::parse_str("fe8b2efc-e5da-407e-9293-f156847cc571").unwrap(),
1619 attributes: attributes! {},
1620 inner_blocks: vec![GutenbergBlock {
1621 name: "core/paragraph".to_string(),
1622 is_valid: true,
1623 client_id: Uuid::parse_str("6d0e2979-9a57-492a-af6f-9f62381f1ede").unwrap(),
1624 attributes: attributes! {
1625 "align": "left",
1626 "content": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur",
1627 "dropCap": false,
1628 "placeholder": "Insert author's bio text..."
1629 },
1630 inner_blocks: vec![],
1631 }],
1632 },
1633 ],
1634
1635 },
1636 ],
1637 }]
1638 }])
1639 },
1640
1641 )
1642 .await?;
1643
1644 create_page(
1645 &mut conn,
1646 course.id,
1647 teacher_user_id,
1648 None,
1649 CmsPageUpdate {
1650 url_path: "/glossary".to_string(),
1651 title: "Glossary".to_string(),
1652 chapter_id: None,
1653 exercises: vec![],
1654 exercise_slides: vec![],
1655 exercise_tasks: vec![],
1656 content: serde_json::json!([GutenbergBlock {
1657 name: "moocfi/glossary".to_string(),
1658 is_valid: true,
1659 client_id: Uuid::parse_str("3a388f47-4aa7-409f-af14-a0290b916225").unwrap(),
1660 attributes: attributes! {},
1661 inner_blocks: vec![]
1662 }]),
1663 },
1664 )
1665 .await?;
1666
1667 info!("sample enrollments, user exercise states, submissions, grades");
1669 for user_id in users.iter().copied() {
1670 course_instance_enrollments::insert_enrollment_and_set_as_current(
1671 &mut conn,
1672 NewCourseInstanceEnrollment {
1673 course_id,
1674 course_instance_id: default_instance.id,
1675 user_id,
1676 },
1677 )
1678 .await?;
1679
1680 submit_and_grade(
1681 &mut conn,
1682 b"8c447aeb-1791-4236-8471-204d8bc27507",
1683 exercise_1_id,
1684 exercise_1_slide_1_id,
1685 course.id,
1686 exercise_1_slide_1_task_1_id,
1687 user_id,
1688 default_instance.id,
1689 exercise_1_slide_1_task_1_spec_1_id.to_string(),
1690 100.0,
1691 )
1692 .await?;
1693 submit_and_grade(
1695 &mut conn,
1696 b"a719fe25-5721-412d-adea-4696ccb3d883",
1697 exercise_1_id,
1698 exercise_1_slide_1_id,
1699 course.id,
1700 exercise_1_slide_1_task_1_id,
1701 user_id,
1702 default_instance.id,
1703 exercise_1_slide_1_task_1_spec_2_id.to_string(),
1704 1.0,
1705 )
1706 .await?;
1707 submit_and_grade(
1708 &mut conn,
1709 b"bbc16d4b-1f91-4bd0-a47f-047665a32196",
1710 exercise_1_id,
1711 exercise_1_slide_1_id,
1712 course.id,
1713 exercise_1_slide_1_task_1_id,
1714 user_id,
1715 default_instance.id,
1716 exercise_1_slide_1_task_1_spec_3_id.to_string(),
1717 0.0,
1718 )
1719 .await?;
1720 submit_and_grade(
1721 &mut conn,
1722 b"c60bf5e5-9b67-4f62-9df7-16d268c1b5f5",
1723 exercise_1_id,
1724 exercise_1_slide_1_id,
1725 course.id,
1726 exercise_1_slide_1_task_1_id,
1727 user_id,
1728 default_instance.id,
1729 exercise_1_slide_1_task_1_spec_1_id.to_string(),
1730 60.0,
1731 )
1732 .await?;
1733 submit_and_grade(
1734 &mut conn,
1735 b"e0ec1386-72aa-4eed-8b91-72bba420c23b",
1736 exercise_2_id,
1737 exercise_2_slide_1_id,
1738 course.id,
1739 exercise_2_slide_1_task_1_id,
1740 user_id,
1741 default_instance.id,
1742 exercise_2_slide_1_task_1_spec_1_id.to_string(),
1743 70.0,
1744 )
1745 .await?;
1746 submit_and_grade(
1747 &mut conn,
1748 b"02c9e1ad-6e4c-4473-a3e9-dbfab018a055",
1749 exercise_5_id,
1750 exercise_5_slide_1_id,
1751 course.id,
1752 exercise_5_slide_1_task_1_id,
1753 user_id,
1754 default_instance.id,
1755 exercise_5_slide_1_task_1_spec_1_id.to_string(),
1756 80.0,
1757 )
1758 .await?;
1759 submit_and_grade(
1760 &mut conn,
1761 b"75df4600-d337-4083-99d1-e8e3b6bf6192",
1762 exercise_1_id,
1763 exercise_1_slide_1_id,
1764 course.id,
1765 exercise_1_slide_1_task_1_id,
1766 user_id,
1767 default_instance.id,
1768 exercise_1_slide_1_task_1_spec_1_id.to_string(),
1769 90.0,
1770 )
1771 .await?;
1772 }
1773 course_instance_enrollments::insert_enrollment_and_set_as_current(
1774 &mut conn,
1775 NewCourseInstanceEnrollment {
1776 course_id,
1777 course_instance_id: default_instance.id,
1778 user_id: langs_user_id,
1779 },
1780 )
1781 .await?;
1782
1783 info!("sample feedback");
1785 let new_feedback = NewFeedback {
1786 feedback_given: "this part was unclear to me".to_string(),
1787 selected_text: Some("blanditiis".to_string()),
1788 related_blocks: vec![FeedbackBlock {
1789 id: block_id_4,
1790 text: Some(
1791 "blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas"
1792 .to_string(),
1793 ),
1794 order_number: Some(0),
1795 }],
1796 page_id: page_3,
1797 };
1798 let feedback = feedback::insert(
1799 &mut conn,
1800 PKeyPolicy::Generate,
1801 Some(student),
1802 course.id,
1803 new_feedback,
1804 )
1805 .await?;
1806 feedback::mark_as_read(&mut conn, feedback, true).await?;
1807 let new_feedback = NewFeedback {
1808 feedback_given: "I dont think we need these paragraphs".to_string(),
1809 selected_text: Some("verything".to_string()),
1810 related_blocks: vec![
1811 FeedbackBlock {
1812 id: block_id_1,
1813 text: Some("verything is a big topic.".to_string()),
1814 order_number: Some(0),
1815 },
1816 FeedbackBlock {
1817 id: block_id_4,
1818 text: Some("So big, that we need many paragraphs.".to_string()),
1819 order_number: Some(1),
1820 },
1821 FeedbackBlock {
1822 id: block_id_5,
1823 text: Some("Like th".to_string()),
1824 order_number: Some(2),
1825 },
1826 ],
1827 page_id: page_3,
1828 };
1829 feedback::insert(
1830 &mut conn,
1831 PKeyPolicy::Generate,
1832 Some(student),
1833 course.id,
1834 new_feedback,
1835 )
1836 .await?;
1837 feedback::insert(
1838 &mut conn,
1839 PKeyPolicy::Generate,
1840 None,
1841 course.id,
1842 NewFeedback {
1843 feedback_given: "Anonymous feedback".to_string(),
1844 selected_text: None,
1845 related_blocks: vec![FeedbackBlock {
1846 id: block_id_1,
1847 text: None,
1848 order_number: Some(0),
1849 }],
1850 page_id: page_3,
1851 },
1852 )
1853 .await?;
1854 feedback::insert(
1855 &mut conn,
1856 PKeyPolicy::Generate,
1857 None,
1858 course.id,
1859 NewFeedback {
1860 feedback_given: "Anonymous unrelated feedback".to_string(),
1861 selected_text: None,
1862 related_blocks: vec![],
1863 page_id: page_3,
1864 },
1865 )
1866 .await?;
1867
1868 info!("sample edit proposals");
1870 let edits = NewProposedPageEdits {
1871 page_id: page_c1_1,
1872 block_edits: vec![NewProposedBlockEdit {
1873 block_id: block_id_4,
1874 block_attribute: "content".to_string(),
1875 original_text: "So bg, that we need many paragraphs.".to_string(),
1876 changed_text: "So bg, that we need many, many paragraphs.".to_string(),
1877 }],
1878 };
1879 proposed_page_edits::insert(
1880 &mut conn,
1881 PKeyPolicy::Generate,
1882 course.id,
1883 Some(student),
1884 &edits,
1885 )
1886 .await?;
1887 let edits = NewProposedPageEdits {
1888 page_id: page_c1_1,
1889 block_edits: vec![
1890 NewProposedBlockEdit {
1891 block_id: block_id_1,
1892 block_attribute: "content".to_string(),
1893 original_text: "Everything is a big topic.".to_string(),
1894 changed_text: "Everything is a very big topic.".to_string(),
1895 },
1896 NewProposedBlockEdit {
1897 block_id: block_id_5,
1898 block_attribute: "content".to_string(),
1899 original_text: "Like this.".to_string(),
1900 changed_text: "Like this!".to_string(),
1901 },
1902 ],
1903 };
1904 proposed_page_edits::insert(
1905 &mut conn,
1906 PKeyPolicy::Generate,
1907 course.id,
1908 Some(student),
1909 &edits,
1910 )
1911 .await?;
1912
1913 glossary::insert(&mut conn, "CS", "Computer science. Computer science is an essential part of being successful in your life. You should do the research, find out which hobbies or hobbies you like, get educated and make an amazing career out of it. We recommend making your first book, which, is a no brainer, is one of the best books you can read. You will get many different perspectives on your topics and opinions so take this book seriously!", course.id).await?;
1915 glossary::insert(&mut conn, "HDD", "Hard disk drive. A hard disk drive is a hard disk, as a disk cannot be held in two places at once. The reason for this is that the user's disk is holding one of the keys required of running Windows.", course.id).await?;
1916 glossary::insert(&mut conn, "SSD", "Solid-state drive. A solid-state drive is a hard drive that's a few gigabytes in size, but a solid-state drive is one where data loads are big enough and fast enough that you can comfortably write to it over long distances. This is what drives do. You need to remember that a good solid-state drive has a lot of data: it stores files on disks and has a few data centers. A good solid-state drive makes for a nice little library: its metadata includes information about everything it stores, including any data it can access, but does not store anything that does not exist outside of those files. It also stores large amounts of data from one location, which can cause problems since the data might be different in different places, or in different ways, than what you would expect to see when driving big data applications. The drives that make up a solid-state drive are called drives that use a variety of storage technologies. These drive technology technologies are called \"super drives,\" and they store some of that data in a solid-state drive. Super drives are designed to be fast but very big: they aren't built to store everything, but to store many kinds of data: including data about the data they contain, and more, like the data they are supposed to hold in them. The super drives that make up a solid-state drive can have capacities of up to 50,000 hard disks. These can be used to store files if", course.id).await?;
1917 glossary::insert(&mut conn, "KB", "Keyboard.", course.id).await?;
1918
1919 let background_svg_path = "svgs/certificate-background.svg".to_string();
1923 let background_svg_file_upload_id = file_uploads::insert(
1924 &mut conn,
1925 &format!("background-{}.svg", module.id),
1926 &background_svg_path,
1927 "image/svg+xml",
1928 None,
1929 )
1930 .await?;
1931 let configuration = DatabaseCertificateConfiguration {
1932 id: Uuid::new_v5(&course_id, b"886d3e22-5007-4371-94d7-e0ad93a2391c"),
1933 certificate_owner_name_y_pos: None,
1934 certificate_owner_name_x_pos: None,
1935 certificate_owner_name_font_size: None,
1936 certificate_owner_name_text_color: None,
1937 certificate_owner_name_text_anchor: None,
1938 certificate_validate_url_y_pos: None,
1939 certificate_validate_url_x_pos: None,
1940 certificate_validate_url_font_size: None,
1941 certificate_validate_url_text_color: None,
1942 certificate_validate_url_text_anchor: None,
1943 certificate_date_y_pos: None,
1944 certificate_date_x_pos: None,
1945 certificate_date_font_size: None,
1946 certificate_date_text_color: None,
1947 certificate_date_text_anchor: None,
1948 certificate_locale: None,
1949 paper_size: None,
1950 background_svg_path,
1951 background_svg_file_upload_id,
1952 overlay_svg_path: None,
1953 overlay_svg_file_upload_id: None,
1954 render_certificate_grade: false,
1955 certificate_grade_y_pos: None,
1956 certificate_grade_x_pos: None,
1957 certificate_grade_font_size: None,
1958 certificate_grade_text_color: None,
1959 certificate_grade_text_anchor: None,
1960 };
1961 let database_configuration =
1962 certificate_configurations::insert(&mut conn, &configuration).await?;
1963 certificate_configuration_to_requirements::insert(
1964 &mut conn,
1965 database_configuration.id,
1966 Some(default_module.id),
1967 Some(default_instance.id),
1968 )
1969 .await?;
1970
1971 roles::insert(
1973 &mut conn,
1974 seed_users_result.teacher_user_id,
1975 UserRole::Teacher,
1976 RoleDomain::Course(course.id),
1977 )
1978 .await?;
1979
1980 Ok(course.id)
1981}
1982
1983pub async fn create_glossary_course(
1984 course_id: Uuid,
1985 common_course_data: CommonCourseData,
1986) -> Result<Uuid> {
1987 let CommonCourseData {
1988 db_pool,
1989 organization_id: org_id,
1990 teacher_user_id,
1991 student_user_id: _,
1992 langs_user_id: _,
1993 example_normal_user_ids: _,
1994 jwt_key: _jwt_key,
1995 base_url: _base_url,
1996 } = common_course_data;
1997 let mut conn = db_pool.acquire().await?;
1998
1999 let new_course = NewCourse {
2001 name: "Glossary Tooltip".to_string(),
2002 organization_id: org_id,
2003 slug: "glossary-tooltip".to_string(),
2004 language_code: "en-US".to_string(),
2005 teacher_in_charge_name: "admin".to_string(),
2006 teacher_in_charge_email: "admin@example.com".to_string(),
2007 description: "Sample course.".to_string(),
2008 is_draft: false,
2009 is_test_mode: false,
2010 is_unlisted: false,
2011 copy_user_permissions: false,
2012 is_joinable_by_code_only: false,
2013 join_code: None,
2014 ask_marketing_consent: false,
2015 flagged_answers_threshold: Some(3),
2016 can_add_chatbot: false,
2017 };
2018
2019 let (course, _front_page, _default_instance, default_module) =
2020 library::content_management::create_new_course(
2021 &mut conn,
2022 PKeyPolicy::Fixed(CreateNewCourseFixedIds {
2023 course_id,
2024 default_course_instance_id: Uuid::new_v5(
2025 &course_id,
2026 b"7344f1c8-b7ce-4c7d-ade2-5f39997bd454",
2027 ),
2028 }),
2029 new_course,
2030 teacher_user_id,
2031 get_seed_spec_fetcher(),
2032 models_requests::fetch_service_info,
2033 )
2034 .await?;
2035
2036 course_instances::insert(
2038 &mut conn,
2039 PKeyPolicy::Fixed(Uuid::new_v5(
2040 &course_id,
2041 b"67f077b4-0562-47ae-a2b9-db2f08f168a9",
2042 )),
2043 NewCourseInstance {
2044 course_id: course.id,
2045 name: Some("Non-default instance"),
2046 description: Some("This is a non-default instance"),
2047 support_email: Some("contact@example.com"),
2048 teacher_in_charge_name: "admin",
2049 teacher_in_charge_email: "admin@example.com",
2050 opening_time: None,
2051 closing_time: None,
2052 },
2053 )
2054 .await?;
2055
2056 let new_chapter = NewChapter {
2058 chapter_number: 1,
2059 course_id: course.id,
2060 front_page_id: None,
2061 name: "Glossary".to_string(),
2062 color: None,
2063 opens_at: None,
2064 deadline: Some(Utc.with_ymd_and_hms(2225, 1, 1, 23, 59, 59).unwrap()),
2065 course_module_id: Some(default_module.id),
2066 };
2067 let (chapter, _front_page) = library::content_management::create_new_chapter(
2068 &mut conn,
2069 PKeyPolicy::Fixed((
2070 Uuid::new_v5(&course_id, b"3d1d7303-b654-428a-8b46-1dbfe908d38a"),
2071 Uuid::new_v5(&course_id, b"97568e97-0d6c-4702-9534-77d6e2784c8a"),
2072 )),
2073 &new_chapter,
2074 teacher_user_id,
2075 get_seed_spec_fetcher(),
2076 models_requests::fetch_service_info,
2077 )
2078 .await?;
2079 chapters::set_opens_at(&mut conn, chapter.id, Utc::now()).await?;
2080
2081 create_page(
2083 &mut conn,
2084 course.id,
2085 teacher_user_id,
2086 Some(chapter.id),
2087 CmsPageUpdate {
2088 url_path: "/tooltip".to_string(),
2089 title: "Tooltip".to_string(),
2090 chapter_id: Some(chapter.id),
2091 exercises: vec![],
2092 exercise_slides: vec![],
2093 exercise_tasks: vec![],
2094 content: serde_json::json!([paragraph(
2095 "Use the KB to write sentences for your CS-courses.",
2096 Uuid::new_v5(&course.id, b"6903cf16-4f79-4985-a354-4257be1193a2")
2097 ),]),
2098 },
2099 )
2100 .await?;
2101
2102 glossary::insert(&mut conn, "CS", "Computer science. Computer science is an essential part of being successful in your life. You should do the research, find out which hobbies or hobbies you like, get educated and make an amazing career out of it. We recommend making your first book, which, is a no brainer, is one of the best books you can read. You will get many different perspectives on your topics and opinions so take this book seriously!", course.id).await?;
2104 glossary::insert(&mut conn, "HDD", "Hard disk drive. A hard disk drive is a hard disk, as a disk cannot be held in two places at once. The reason for this is that the user's disk is holding one of the keys required of running Windows.", course.id).await?;
2105 glossary::insert(&mut conn, "SSD", "Solid-state drive. A solid-state drive is a hard drive that's a few gigabytes in size, but a solid-state drive is one where data loads are big enough and fast enough that you can comfortably write to it over long distances. This is what drives do. You need to remember that a good solid-state drive has a lot of data: it stores files on disks and has a few data centers. A good solid-state drive makes for a nice little library: its metadata includes information about everything it stores, including any data it can access, but does not store anything that does not exist outside of those files. It also stores large amounts of data from one location, which can cause problems since the data might be different in different places, or in different ways, than what you would expect to see when driving big data applications. The drives that make up a solid-state drive are called drives that use a variety of storage technologies. These drive technology technologies are called \"super drives,\" and they store some of that data in a solid-state drive. Super drives are designed to be fast but very big: they aren't built to store everything, but to store many kinds of data: including data about the data they contain, and more, like the data they are supposed to hold in them. The super drives that make up a solid-state drive can have capacities of up to 50,000 hard disks. These can be used to store files if", course.id).await?;
2106 glossary::insert(&mut conn, "KB", "Keyboard.", course.id).await?;
2107
2108 Ok(course.id)
2109}
2110
2111pub async fn seed_cs_course_material(
2112 db_pool: &Pool<Postgres>,
2113 org: Uuid,
2114 teacher_user_id: Uuid,
2115 langs_user_id: Uuid,
2116 _base_url: String,
2117) -> Result<Uuid> {
2118 let mut conn = db_pool.acquire().await?;
2119 let spec_fetcher = get_seed_spec_fetcher();
2120 let new_course = NewCourse {
2122 name: "Introduction to Course Material".to_string(),
2123 organization_id: org,
2124 slug: "introduction-to-course-material".to_string(),
2125 language_code: "en-US".to_string(),
2126 teacher_in_charge_name: "admin".to_string(),
2127 teacher_in_charge_email: "admin@example.com".to_string(),
2128 description: "The definitive introduction to course material.".to_string(),
2129 is_draft: false,
2130 is_test_mode: false,
2131 is_unlisted: false,
2132 copy_user_permissions: false,
2133 is_joinable_by_code_only: false,
2134 join_code: None,
2135 ask_marketing_consent: false,
2136 flagged_answers_threshold: Some(3),
2137 can_add_chatbot: false,
2138 };
2139 let (course, front_page, default_instance, default_module) =
2140 library::content_management::create_new_course(
2141 &mut conn,
2142 PKeyPolicy::Fixed(CreateNewCourseFixedIds {
2143 course_id: Uuid::parse_str("d6b52ddc-6c34-4a59-9a59-7e8594441007")?,
2144 default_course_instance_id: Uuid::parse_str(
2145 "8e6c35cd-43f2-4982-943b-11e3ffb1b2f8",
2146 )?,
2147 }),
2148 new_course,
2149 teacher_user_id,
2150 &spec_fetcher,
2151 models_requests::fetch_service_info,
2152 )
2153 .await?;
2154
2155 let (
2157 quizzes_exercise_block_5,
2158 quizzes_exercise_5,
2159 quizzes_exercise_slide_5,
2160 quizzes_exercise_task_5,
2161 ) = quizzes_exercise(
2162 "Best quizzes exercise".to_string(),
2163 Uuid::new_v5(&course.id, b"58e71279-81e1-4679-83e6-8f5f23ec055a"),
2164 false,
2165 serde_json::json!({
2166 "id": "3a1b3e10-2dd5-4cb9-9460-4c08f19e16d3",
2167 "body": "very hard",
2168 "part": 3,
2169 "items": [{
2170 "id": "7b0049ea-de8b-4eef-a4a9-164e0e874ecc",
2171 "body": "",
2172 "type": "multiple-choice",
2173 "direction": "row",
2174 "multi": false,
2175 "multipleChoiceMultipleOptionsGradingPolicy": "default",
2176 "order": 0,
2177 "title": "Choose the first answer",
2178 "quizId": "3a1b3e10-2dd5-4cb9-9460-4c08f19e16d3",
2179 "options": [{
2180 "id": "d5124283-4e84-4b4f-84c0-a91961b0ef21",
2181 "body": "This is first option",
2182 "order": 1,
2183 "title": null,
2184 "quizItemId": "7b0049ea-de8b-4eef-a4a9-164e0e874ecc",
2185 "correct":true,
2186 "messageAfterSubmissionWhenSelected": "Correct! This is indeed the first answer",
2187 "additionalCorrectnessExplanationOnModelSolution": null,
2188 },{
2189 "id": "846c09e2-653a-4471-81ae-25726486b003",
2190 "body": "This is second option",
2191 "order": 1,
2192 "title": null,
2193 "quizItemId": "7b0049ea-de8b-4eef-a4a9-164e0e874ecc",
2194 "correct":false,
2195 "messageAfterSubmissionWhenSelected": "Incorrect. This is not the first answer",
2196 "additionalCorrectnessExplanationOnModelSolution": null,
2197 },{
2198 "id": "8107ae39-96aa-4f54-aa78-1a33362a19c1",
2199 "body": "This is third option",
2200 "order": 1,
2201 "title": null,
2202 "quizItemId": "7b0049ea-de8b-4eef-a4a9-164e0e874ecc",
2203 "correct":false,
2204 "messageAfterSubmissionWhenSelected": "Incorrect. This is not the first answer",
2205 "additionalCorrectnessExplanationOnModelSolution": null,
2206 },],
2207 "allAnswersCorrect": false,
2208 "sharedOptionFeedbackMessage": null,
2209 "usesSharedOptionFeedbackMessage": false
2210 }],
2211 "title": "Very good exercise",
2212 "tries": 1,
2213 "points": 3,
2214 "section": 0,
2215 "courseId": "d6b52ddc-6c34-4a59-9a59-7e8594441007",
2216 "deadline": "2021-12-17T07:15:33.479Z",
2217 "createdAt": "2021-12-17T07:15:33.479Z",
2218 "updatedAt": "2021-12-17T07:15:33.479Z",
2219 "autoReject": false,
2220 "autoConfirm": true,
2221 "randomizeOptions": false,
2222 "triesLimited": true,
2223 "submitMessage": "This is an extra submit message from the teacher.",
2224 "excludedFromScore": true,
2225 "grantPointsPolicy": "grant_whenever_possible",
2226 "awardPointsEvenIfWrong": false}),
2227 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
2228 CommonExerciseData {
2229 exercise_id: Uuid::new_v5(&course.id, b"cd3aa815-620e-43b3-b291-0fb10beca030"),
2230 exercise_slide_id: Uuid::new_v5(&course.id, b"0b1bbfb0-df56-4e40-92f1-df0a33f1fc70"),
2231 exercise_task_id: Uuid::new_v5(&course.id, b"7f011d0e-1cbf-4870-bacf-1873cf360c15"),
2232 block_id: Uuid::new_v5(&course.id, b"b9446b94-0edf-465c-9a9a-57708b7ef180"),
2233 },
2234 );
2235
2236 let (
2237 quizzes_exercise_block_6,
2238 quizzes_exercise_6,
2239 quizzes_exercise_slide_6,
2240 quizzes_exercise_task_6,
2241 ) = quizzes_exercise(
2242 "Best quizzes exercise".to_string(),
2243 Uuid::new_v5(&course.id, b"085b60ec-aa9d-11ec-b500-7b1e176646f8"),
2244 false,
2245 serde_json::from_str(include_str!(
2246 "../../assets/quizzes-multiple-choice-additional-feedback.json"
2247 ))?,
2248 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
2249 CommonExerciseData {
2250 exercise_id: Uuid::new_v5(&course.id, b"925d4a89-0f25-4e8e-bc11-350393d8d894"),
2251 exercise_slide_id: Uuid::new_v5(&course.id, b"ff92ca4a-aa9c-11ec-ac56-475e57747ad3"),
2252 exercise_task_id: Uuid::new_v5(&course.id, b"9037cb17-3841-4a79-8f50-bbe595a4f785"),
2253 block_id: Uuid::new_v5(&course.id, b"d6d80ae0-97a1-4db1-8a3b-2bdde3cfbe9a"),
2254 },
2255 );
2256
2257 let (
2258 quizzes_exercise_block_7,
2259 quizzes_exercise_7,
2260 quizzes_exercise_slide_7,
2261 quizzes_exercise_task_7,
2262 ) = quizzes_exercise(
2263 "Best quizzes exercise".to_string(),
2264 Uuid::new_v5(&course.id, b"6365746e-aa9d-11ec-8718-0b5628cbe29f"),
2265 false,
2266 serde_json::json!({
2267 "id": "33cd47ea-aa9d-11ec-897c-5b22513d61ee",
2268 "body": "very hard",
2269 "part": 5,
2270 "items": [{
2271 "id": "395888c8-aa9d-11ec-bb81-cb3a3f2609e4",
2272 "body": "",
2273 "type": "multiple-choice",
2274 "direction": "column",
2275 "multi": false,
2276 "multipleChoiceMultipleOptionsGradingPolicy": "default",
2277 "order": 0,
2278 "title": "Choose the first answer",
2279 "quizId": "33cd47ea-aa9d-11ec-897c-5b22513d61ee",
2280 "options": [{
2281 "id": "490543d8-aa9d-11ec-a20f-07269e5c09df",
2282 "body": "This is first option",
2283 "order": 1,
2284 "title": null,
2285 "quizItemId": "395888c8-aa9d-11ec-bb81-cb3a3f2609e4",
2286 "correct":true,
2287 "messageAfterSubmissionWhenSelected": "Correct! This is indeed the first answer",
2288 "additionalCorrectnessExplanationOnModelSolution": null,
2289 },{
2290 "id": "45e77450-aa9d-11ec-abea-6b824f5ae1f6",
2291 "body": "This is second option",
2292 "order": 1,
2293 "title": null,
2294 "quizItemId": "395888c8-aa9d-11ec-bb81-cb3a3f2609e4",
2295 "correct":false,
2296 "messageAfterSubmissionWhenSelected": "Incorrect. This is not the first answer",
2297 "additionalCorrectnessExplanationOnModelSolution": null,
2298 },{
2299 "id": "43428140-aa9d-11ec-a6b3-83ec8e2dfb88",
2300 "body": "This is third option",
2301 "order": 1,
2302 "title": null,
2303 "quizItemId": "395888c8-aa9d-11ec-bb81-cb3a3f2609e4",
2304 "correct":false,
2305 "messageAfterSubmissionWhenSelected": "Incorrect. This is not the first answer",
2306 "additionalCorrectnessExplanationOnModelSolution": null,
2307 },],
2308 "allAnswersCorrect": false,
2309 "sharedOptionFeedbackMessage": null,
2310 "usesSharedOptionFeedbackMessage": false
2311 }],
2312 "title": "Very good exercise",
2313 "tries": 1,
2314 "points": 3,
2315 "section": 0,
2316 "courseId": "d6b52ddc-6c34-4a59-9a59-7e8594441007",
2317 "deadline": "2021-12-17T07:15:33.479Z",
2318 "createdAt": "2021-12-17T07:15:33.479Z",
2319 "updatedAt": "2021-12-17T07:15:33.479Z",
2320 "autoReject": false,
2321 "autoConfirm": true,
2322 "randomizeOptions": false,
2323 "triesLimited": true,
2324 "submitMessage": "This is an extra submit message from the teacher.",
2325 "excludedFromScore": true,
2326 "grantPointsPolicy": "grant_whenever_possible",
2327 "awardPointsEvenIfWrong": false}),
2328 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
2329 CommonExerciseData {
2330 exercise_id: Uuid::new_v5(&course.id, b"57905c8a-aa9d-11ec-92d4-47ab996cb70c"),
2331 exercise_slide_id: Uuid::new_v5(&course.id, b"5b058552-aa9d-11ec-bc36-57e1c5f8407a"),
2332 exercise_task_id: Uuid::new_v5(&course.id, b"5d953894-aa9d-11ec-97e7-2ff4d73f69f1"),
2333 block_id: Uuid::new_v5(&course.id, b"604dae7c-aa9d-11ec-8df1-575042832340"),
2334 },
2335 );
2336
2337 let (
2338 quizzes_exercise_block_8,
2339 quizzes_exercise_8,
2340 quizzes_exercise_slide_8,
2341 quizzes_exercise_task_8,
2342 ) = quizzes_exercise(
2343 "Best quizzes exercise".to_string(),
2344 Uuid::new_v5(&course.id, b"01b69776-3e82-4694-98a9-5ce53f2a4ab5"),
2345 false,
2346 serde_json::json!({
2347 "id": "9a186f2b-7616-472e-b839-62ab0f2f0a6c",
2348 "body": "very hard",
2349 "part": 6,
2350 "items": [{
2351 "id": "871c3640-aa9d-11ec-8103-633d645899a3",
2352 "body": "",
2353 "type": "multiple-choice",
2354 "direction": "column",
2355 "multi": false,
2356 "multipleChoiceMultipleOptionsGradingPolicy": "default",
2357 "order": 0,
2358 "title": "Choose the first answer",
2359 "quizId": "9a186f2b-7616-472e-b839-62ab0f2f0a6c",
2360 "options": [{
2361 "id": "4435ed30-c1da-46a0-80b8-c5b9ee923dd4",
2362 "body": "This is first option",
2363 "order": 1,
2364 "title": null,
2365 "quizItemId": "871c3640-aa9d-11ec-8103-633d645899a3",
2366 "correct":true,
2367 "messageAfterSubmissionWhenSelected": "Correct! This is indeed the first answer",
2368 "additionalCorrectnessExplanationOnModelSolution": null,
2369 },{
2370 "id": "1d5de4d0-8499-4ac1-b44c-21c1562639cb",
2371 "body": "This is second option",
2372 "order": 1,
2373 "title": null,
2374 "quizItemId": "871c3640-aa9d-11ec-8103-633d645899a3",
2375 "correct":false,
2376 "messageAfterSubmissionWhenSelected": "Incorrect. This is not the first answer",
2377 "additionalCorrectnessExplanationOnModelSolution": null,
2378 },{
2379 "id": "93fe358e-aa9d-11ec-9aa1-f3d18a09d58c",
2380 "body": "This is third option",
2381 "order": 1,
2382 "title": null,
2383 "quizItemId": "871c3640-aa9d-11ec-8103-633d645899a3",
2384 "correct":false,
2385 "messageAfterSubmissionWhenSelected": "Incorrect. This is not the first answer",
2386 "additionalCorrectnessExplanationOnModelSolution": null,
2387 },],
2388 "allAnswersCorrect": false,
2389 "sharedOptionFeedbackMessage": null,
2390 "usesSharedOptionFeedbackMessage": false
2391 }],
2392 "title": "Very good exercise",
2393 "tries": 1,
2394 "points": 3,
2395 "section": 0,
2396 "courseId": "d6b52ddc-6c34-4a59-9a59-7e8594441007",
2397 "deadline": "2021-12-17T07:15:33.479Z",
2398 "createdAt": "2021-12-17T07:15:33.479Z",
2399 "updatedAt": "2021-12-17T07:15:33.479Z",
2400 "autoReject": false,
2401 "autoConfirm": true,
2402 "randomizeOptions": false,
2403 "triesLimited": true,
2404 "submitMessage": "This is an extra submit message from the teacher.",
2405 "excludedFromScore": true,
2406 "grantPointsPolicy": "grant_whenever_possible",
2407 "awardPointsEvenIfWrong": false}),
2408 Some(Utc.with_ymd_and_hms(2125, 1, 1, 23, 59, 59).unwrap()),
2409 CommonExerciseData {
2410 exercise_id: Uuid::new_v5(&course.id, b"c1a4831c-cc78-4f42-be18-2a35a7f3b506"),
2411 exercise_slide_id: Uuid::new_v5(&course.id, b"75045b18-aa9d-11ec-b3d1-6f64c2d6d46d"),
2412 exercise_task_id: Uuid::new_v5(&course.id, b"712fd37c-e3d7-4569-8a64-371d7dda9c19"),
2413 block_id: Uuid::new_v5(&course.id, b"6799021d-ff0c-4e4d-b5db-c2c19fba7fb9"),
2414 },
2415 );
2416
2417 pages::update_page(
2418 &mut conn,
2419 PageUpdateArgs {
2420 page_id: front_page.id,
2421 author: teacher_user_id,
2422 cms_page_update: CmsPageUpdate {
2423 title: "Introduction to Course Material".to_string(),
2424 url_path: "/".to_string(),
2425 chapter_id: None,
2426 content: serde_json::to_value(&[
2427 GutenbergBlock::landing_page_hero_section("Welcome to Introduction to Course Material", "In this course you'll learn the basics of UI/UX design. At the end of course you should be able to create your own design system.")
2428 .with_id(Uuid::parse_str("6ad81525-0010-451f-85e5-4832e3e364a8")?),
2429 GutenbergBlock::course_objective_section()
2430 .with_id(Uuid::parse_str("2eec7ad7-a95f-406f-acfe-f3a332b86e26")?),
2431 GutenbergBlock::empty_block_from_name("moocfi/course-chapter-grid".to_string())
2432 .with_id(Uuid::parse_str("bb51d61b-fd19-44a0-8417-7ffc6058b247")?),
2433 GutenbergBlock::empty_block_from_name("moocfi/course-progress".to_string())
2434 .with_id(Uuid::parse_str("1d7c28ca-86ab-4318-8b10-3e5b7cd6e465")?),
2435 ])
2436 .unwrap(),
2437 exercises: vec![],
2438 exercise_slides: vec![],
2439 exercise_tasks: vec![],
2440 },
2441 retain_ids: true,
2442 history_change_reason: HistoryChangeReason::PageSaved,
2443 is_exam_page: false
2444 },
2445 &spec_fetcher,
2446 models_requests::fetch_service_info,
2447 )
2448 .await?;
2449 let (_page, _history) = pages::insert_course_page(
2452 &mut conn,
2453 &NewCoursePage::new(course.id, 1, "/faq", "FAQ"),
2454 teacher_user_id,
2455 )
2456 .await?;
2457
2458 let new_chapter = NewChapter {
2460 chapter_number: 1,
2461 course_id: course.id,
2462 front_page_id: None,
2463 name: "User Interface".to_string(),
2464 color: None,
2465 opens_at: None,
2466 deadline: None,
2467 course_module_id: Some(default_module.id),
2468 };
2469 let (chapter_1, front_page_ch_1) = library::content_management::create_new_chapter(
2470 &mut conn,
2471 PKeyPolicy::Fixed((
2472 Uuid::new_v5(&course.id, b"77e95910-2289-452f-a1dd-8b8bf4a829a0"),
2473 Uuid::new_v5(&course.id, b"91b6887f-8bc0-4df6-89a4-5687890bc955"),
2474 )),
2475 &new_chapter,
2476 teacher_user_id,
2477 &spec_fetcher,
2478 models_requests::fetch_service_info,
2479 )
2480 .await?;
2481 chapters::set_opens_at(&mut conn, chapter_1.id, Utc::now()).await?;
2482
2483 pages::update_page(
2484 &mut conn,
2485 PageUpdateArgs {
2486 page_id: front_page_ch_1.id,
2487 author: teacher_user_id,
2488 cms_page_update: CmsPageUpdate {
2489 title: "User Interface".to_string(),
2490 url_path: "/chapter-1".to_string(),
2491 chapter_id: Some(chapter_1.id),
2492 content: serde_json::to_value(&[
2493 GutenbergBlock::hero_section("User Interface", "In the industrial design field of human–computer interaction, a user interface is the space where interactions between humans and machines occur.")
2494 .with_id(Uuid::parse_str("848ac898-81c0-4ebc-881f-6f84e9eaf472")?),
2495 GutenbergBlock::empty_block_from_name("moocfi/pages-in-chapter".to_string())
2496 .with_id(Uuid::parse_str("c8b36f58-5366-4d6b-b4ec-9fc0bd65950e")?),
2497 GutenbergBlock::empty_block_from_name("moocfi/exercises-in-chapter".to_string())
2498 .with_id(Uuid::parse_str("457431b0-55db-46ac-90ae-03965f48b27e")?),
2499 ])
2500 .unwrap(),
2501 exercises: vec![],
2502 exercise_slides: vec![],
2503 exercise_tasks: vec![],
2504 },
2505 retain_ids: true,
2506 history_change_reason: HistoryChangeReason::PageSaved,
2507 is_exam_page: false
2508 },
2509 &spec_fetcher,
2510 models_requests::fetch_service_info,
2511 )
2512 .await?;
2513
2514 let design_content = CmsPageUpdate {
2516 url_path: "/chapter-1/design".to_string(),
2517 title: "Design".to_string(),
2518 chapter_id: Some(chapter_1.id),
2519 exercises: vec![],
2520 exercise_slides: vec![],
2521 exercise_tasks: vec![],
2522 content: serde_json::json!([
2523 GutenbergBlock::hero_section("Design", "A design is a plan or specification for the construction of an object or system or for the implementation of an activity or process, or the result of that plan or specification in the form of a prototype, product or process.")
2524 .with_id(Uuid::parse_str("98729704-9dd8-4309-aa08-402f9b2a6071")?),
2525 heading("First heading", Uuid::parse_str("731aa55f-238b-42f4-8c40-c093dd95ee7f")?, 2),
2526 GutenbergBlock::block_with_name_and_attributes(
2527 "core/paragraph",
2528 attributes!{
2529 "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum felis nisi, vitae commodo mi venenatis in. Mauris hendrerit lacinia augue ut hendrerit. Vestibulum non tellus mattis, convallis magna vel, semper mauris. Maecenas porta, arcu eget porttitor sagittis, nulla magna auctor dolor, sed tempus sem lacus eu tortor. Ut id diam quam. Etiam quis sagittis justo. Quisque sagittis dolor vitae felis facilisis, ut suscipit ipsum malesuada. Nulla tempor ultricies erat ut venenatis. Ut pulvinar lectus non mollis efficitur.",
2530 "dropCap": false
2531 },
2532 )
2533 .with_id(Uuid::parse_str("9ebddb78-23f6-4440-8d8f-5e4b33abb16f")?),
2534 heading("Second heading", Uuid::parse_str("a70aac40-acda-48e3-8f53-b64370be4585")?, 3),
2535 GutenbergBlock::block_with_name_and_attributes(
2536 "core/paragraph",
2537 attributes!{
2538 "content": "Sed quis fermentum mi. Integer commodo turpis a fermentum tristique. Integer convallis, nunc sed scelerisque varius, mi tellus molestie metus, eu ultrices justo tellus non arcu. Cras euismod, lectus eu scelerisque mattis, odio ex ornare ipsum, a dapibus nulla leo maximus orci. Etiam laoreet venenatis lorem, vitae iaculis mauris. Nullam lobortis, tortor eget ullamcorper lobortis, tellus odio tincidunt dolor, vitae gravida nibh turpis ac sem. Integer non sodales eros.",
2539 "dropCap": false
2540 },
2541 )
2542 .with_id(Uuid::parse_str("029ae4b5-08b0-49f7-8baf-d916b5f879a2")?),
2543 GutenbergBlock::block_with_name_and_attributes(
2544 "core/paragraph",
2545 attributes!{
2546 "content": "Vestibulum a scelerisque ante. Fusce interdum eros elit, posuere mattis sapien tristique id. Integer commodo mi orci, sit amet tempor libero vulputate in. Ut id gravida quam. Proin massa dolor, posuere nec metus eu, dignissim viverra nulla. Vestibulum quis neque bibendum, hendrerit diam et, fermentum diam. Sed risus nibh, suscipit in neque nec, bibendum interdum nibh. Aliquam ut enim a mi ultricies finibus. Nam tristique felis ac risus interdum molestie. Nulla venenatis, augue sed porttitor ultrices, lacus ante sollicitudin dui, vel vehicula ex enim ac mi.",
2547 "dropCap": false
2548 },
2549 )
2550 .with_id(Uuid::parse_str("3693e92b-9cf0-485a-b026-2851de58e9cf")?),
2551 heading("Third heading", Uuid::parse_str("4d16bfea-4fa9-4355-bbd4-4c61e33d3d7c")?, 2),
2552 GutenbergBlock::block_with_name_and_attributes(
2553 "core/paragraph",
2554 attributes!{
2555 "content": "Sed quis fermentum mi. Integer commodo turpis a fermentum tristique. Integer convallis, nunc sed scelerisque varius, mi tellus molestie metus, eu ultrices justo tellus non arcu. Cras euismod, lectus eu scelerisque mattis, odio ex ornare ipsum, a dapibus nulla leo maximus orci. Etiam laoreet venenatis lorem, vitae iaculis mauris. Nullam lobortis, tortor eget ullamcorper lobortis, tellus odio tincidunt dolor, vitae gravida nibh turpis ac sem. Integer non sodales eros.",
2556 "dropCap": false
2557 },
2558 )
2559 .with_id(Uuid::parse_str("4ef39962-634d-488c-be82-f44e5db19421")?),
2560 GutenbergBlock::block_with_name_and_attributes(
2561 "core/paragraph",
2562 attributes!{
2563 "content": "Vestibulum a scelerisque ante. Fusce interdum eros elit, posuere mattis sapien tristique id. Integer commodo mi orci, sit amet tempor libero vulputate in. Ut id gravida quam. Proin massa dolor, posuere nec metus eu, dignissim viverra nulla. Vestibulum quis neque bibendum, hendrerit diam et, fermentum diam. Sed risus nibh, suscipit in neque nec, bibendum interdum nibh. Aliquam ut enim a mi ultricies finibus. Nam tristique felis ac risus interdum molestie. Nulla venenatis, augue sed porttitor ultrices, lacus ante sollicitudin dui, vel vehicula ex enim ac mi.",
2564 "dropCap": false
2565 },
2566 )
2567 .with_id(Uuid::parse_str("0d47c02a-194e-42a4-927e-fb29a4fda39c")?),
2568 ]),
2569 };
2570 create_page(
2571 &mut conn,
2572 course.id,
2573 teacher_user_id,
2574 Some(chapter_1.id),
2575 design_content,
2576 )
2577 .await?;
2578
2579 let content_b = CmsPageUpdate {
2581 chapter_id: Some(chapter_1.id),
2582 url_path: "/chapter-1/human-machine-interface".to_string(),
2583 title: "Human-machine interface".to_string(),
2584 exercises: vec![],
2585 exercise_slides: vec![],
2586 exercise_tasks: vec![],
2587 content: serde_json::json!([
2588 GutenbergBlock::hero_section("Human-machine interface", "In the industrial design field of human–computer interaction, a user interface is the space where interactions between humans and machines occur.")
2589 .with_id(Uuid::parse_str("ae22ae64-c0e5-42e1-895a-4a49411a72e8")?),
2590 GutenbergBlock::block_with_name_and_attributes(
2591 "core/paragraph",
2592 attributes!{
2593 "content": "Sed venenatis, magna in ornare suscipit, orci ipsum consequat nulla, ut pulvinar libero metus et metus. Maecenas nec bibendum est. Donec quis ante elit. Nam in eros vitae urna aliquet vestibulum. Donec posuere laoreet facilisis. Aliquam auctor a tellus a tempus. Sed molestie leo eget commodo pellentesque. Curabitur lacinia odio nisl, eu sodales nunc placerat sit amet. Vivamus venenatis, risus vitae lobortis eleifend, odio nisi faucibus tortor, sed aliquet leo arcu et tellus. Donec ultrices consectetur nunc, non rhoncus sapien malesuada et. Nulla tempus ipsum vitae justo scelerisque, sed pretium neque fermentum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur accumsan et ex pellentesque dignissim. Integer viverra libero quis tortor dignissim elementum.",
2594 "dropCap": false
2595 },
2596 )
2597 .with_id(Uuid::parse_str("b05a62ad-e5f7-432c-8c88-2976d971e7e1")?),
2598 GutenbergBlock::block_with_name_and_attributes(
2599 "core/paragraph",
2600 attributes!{
2601 "content": "Sed quis fermentum mi. Integer commodo turpis a fermentum tristique. Integer convallis, nunc sed scelerisque varius, mi tellus molestie metus, eu ultrices banana justo tellus non arcu. Cras euismod, cat lectus eu scelerisque mattis, odio ex ornare ipsum, a dapibus nulla leo maximus orci. Etiam laoreet venenatis lorem, vitae iaculis mauris. Nullam lobortis, tortor eget ullamcorper lobortis, tellus odio tincidunt dolor, vitae gravida nibh turpis ac sem. Integer non sodales eros.",
2602 "dropCap": false
2603 },
2604 )
2605 .with_id(Uuid::parse_str("db20e302-d4e2-4f56-a0b9-e48a4fbd5fa8")?),
2606 GutenbergBlock::block_with_name_and_attributes(
2607 "core/paragraph",
2608 attributes!{
2609 "content": "Vestibulum a scelerisque ante. Fusce interdum eros elit, posuere mattis sapien tristique id. Integer commodo mi orci, sit amet tempor libero vulputate in. Ut id gravida quam. Proin massa dolor, posuere nec metus eu, dignissim viverra nulla. Vestibulum quis neque bibendum, hendrerit diam et, fermentum diam. Sed risus nibh, suscipit in neque nec, bibendum interdum nibh. Aliquam ut enim a mi ultricies finibus. Nam tristique felis ac risus interdum molestie. Nulla venenatis, augue sed porttitor ultrices, lacus ante sollicitudin dui, vel vehicula ex enim ac mi.",
2610 "dropCap": false
2611 },
2612 )
2613 .with_id(Uuid::parse_str("c96f56d5-ea35-4aae-918a-72a36847a49c")?),
2614 ]),
2615 };
2616 create_page(
2617 &mut conn,
2618 course.id,
2619 teacher_user_id,
2620 Some(chapter_1.id),
2621 content_b,
2622 )
2623 .await?;
2624
2625 let new_chapter_2 = NewChapter {
2627 chapter_number: 2,
2628 course_id: course.id,
2629 front_page_id: None,
2630 name: "User Experience".to_string(),
2631 color: None,
2632 opens_at: None,
2633 deadline: None,
2634 course_module_id: Some(default_module.id),
2635 };
2636 let (chapter_2, front_page_ch_2) = library::content_management::create_new_chapter(
2637 &mut conn,
2638 PKeyPolicy::Fixed((
2639 Uuid::new_v5(&course.id, b"5adff726-8910-4163-9fdb-e2f0f45c04d7"),
2640 Uuid::new_v5(&course.id, b"4d916791-5a09-4e3c-8201-c46509e0b2c7"),
2641 )),
2642 &new_chapter_2,
2643 teacher_user_id,
2644 &spec_fetcher,
2645 models_requests::fetch_service_info,
2646 )
2647 .await?;
2648 chapters::set_opens_at(&mut conn, chapter_2.id, Utc::now()).await?;
2649
2650 pages::update_page(
2651 &mut conn,
2652 PageUpdateArgs {
2653 page_id: front_page_ch_2.id,
2654 author: teacher_user_id,
2655 cms_page_update: CmsPageUpdate {
2656 url_path: "/chapter-2".to_string(),
2657 title: "User Experience".to_string(),
2658 chapter_id: Some(chapter_2.id),
2659 content: serde_json::to_value(&[
2660 GutenbergBlock::hero_section("User Experience", "The user experience is how a user interacts with and experiences a product, system or service. It includes a person's perceptions of utility, ease of use, and efficiency.")
2661 .with_id(Uuid::parse_str("c5c623f9-c7ca-4f8e-b04b-e91cecef217a")?),
2662 GutenbergBlock::empty_block_from_name("moocfi/pages-in-chapter".to_string())
2663 .with_id(Uuid::parse_str("37bbc4e9-2e96-45ea-a6f8-bbc7dc7f6be3")?),
2664 GutenbergBlock::empty_block_from_name("moocfi/exercises-in-chapter".to_string())
2665 .with_id(Uuid::parse_str("1bf7e311-75e8-48ec-bd55-e8f1185d76d0")?),
2666 ])
2667 .unwrap(),
2668 exercises: vec![],
2669 exercise_slides: vec![],
2670 exercise_tasks: vec![],
2671 },
2672 retain_ids: true,
2673 history_change_reason: HistoryChangeReason::PageSaved,
2674 is_exam_page: false
2675 },
2676 &spec_fetcher,
2677 models_requests::fetch_service_info,
2678 )
2679 .await?;
2680 let page_content = CmsPageUpdate {
2682 chapter_id: Some(chapter_2.id),
2683 content: serde_json::json!([
2684 GutenbergBlock::hero_section("User research", "User research focuses on understanding user behaviors, needs, and motivations through observation techniques, task analysis, and other feedback methodologies.")
2685 .with_id(Uuid::parse_str("a43f5460-b588-44ac-84a3-5fdcabd5d3f7")?),
2686 GutenbergBlock::block_with_name_and_attributes(
2687 "core/paragraph",
2688 attributes!{
2689 "content": "Sed venenatis, magna in ornare suscipit, orci ipsum consequat nulla, ut pulvinar libero metus et metus. Maecenas nec bibendum est. Donec quis ante elit. Nam in eros vitae urna aliquet vestibulum. Donec posuere laoreet facilisis. Aliquam auctor a tellus a tempus. Sed molestie leo eget commodo pellentesque. Curabitur lacinia odio nisl, eu sodales nunc placerat sit amet. Vivamus venenatis, risus vitae lobortis eleifend, odio nisi faucibus tortor, sed aliquet leo arcu et tellus. Donec ultrices consectetur nunc, non rhoncus sapien malesuada et. Nulla tempus ipsum vitae justo scelerisque, sed pretium neque fermentum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur accumsan et ex pellentesque dignissim. Integer viverra libero quis tortor dignissim elementum.",
2690 "dropCap": false
2691 },
2692 )
2693 .with_id(Uuid::parse_str("816310e3-bbd7-44ae-87cb-3f40633a4b08")?),
2694 GutenbergBlock::block_with_name_and_attributes(
2695 "core/paragraph",
2696 attributes!{
2697 "content": "Sed quis fermentum mi. Integer commodo turpis a fermentum tristique. Integer convallis, nunc sed scelerisque varius, mi tellus molestie metus, eu ultrices justo tellus non arcu. Cras euismod, lectus eu scelerisque mattis, odio ex ornare ipsum, a dapibus nulla leo maximus orci. Etiam laoreet venenatis lorem, vitae iaculis mauris. Nullam lobortis, tortor eget ullamcorper lobortis, tellus odio tincidunt dolor, vitae gravida nibh turpis ac sem. Integer non sodales eros.",
2698 "dropCap": false
2699 },
2700 )
2701 .with_id(Uuid::parse_str("37aa6421-768e-49b9-b447-5f457e5192bc")?),
2702 GutenbergBlock::block_with_name_and_attributes(
2703 "core/paragraph",
2704 attributes!{
2705 "content": "Vestibulum a scelerisque ante. Fusce interdum eros elit, posuere mattis sapien tristique id. Integer commodo mi orci, sit amet tempor libero vulputate in. Ut id gravida quam. Proin massa dolor, posuere nec metus eu, dignissim viverra nulla. Vestibulum quis neque bibendum, hendrerit diam et, fermentum diam. Sed risus nibh, suscipit in neque nec, bibendum interdum nibh. Aliquam ut banana cat enim a mi ultricies finibus. Nam tristique felis ac risus interdum molestie. Nulla venenatis, augue sed porttitor ultrices, lacus ante sollicitudin dui, vel vehicula ex enim ac mi.",
2706 "dropCap": false
2707 },
2708 )
2709 .with_id(Uuid::parse_str("cf11a0fb-f56e-4e0d-bc12-51d920dbc278")?),
2710 ]),
2711 exercises: vec![],
2712 exercise_slides: vec![],
2713 exercise_tasks: vec![],
2714 url_path: "/chapter-2/user-research".to_string(),
2715 title: "User research".to_string(),
2716 };
2717 create_page(
2718 &mut conn,
2719 course.id,
2720 teacher_user_id,
2721 Some(chapter_2.id),
2722 page_content,
2723 )
2724 .await?;
2725
2726 let page_content = include_str!("../../assets/example-page.json");
2727 let parse_page_content = serde_json::from_str(page_content)?;
2728 create_page(
2729 &mut conn,
2730 course.id,
2731 teacher_user_id,
2732 Some(chapter_2.id),
2733 CmsPageUpdate {
2734 content: parse_page_content,
2735 exercises: vec![],
2736 exercise_slides: vec![],
2737 exercise_tasks: vec![],
2738 url_path: "/chapter-2/content-rendering".to_string(),
2739 title: "Content rendering".to_string(),
2740 chapter_id: Some(chapter_2.id),
2741 },
2742 )
2743 .await?;
2744
2745 create_page(
2748 &mut conn,
2749 course.id,
2750 teacher_user_id,
2751 Some(chapter_2.id),
2752 CmsPageUpdate {
2753 url_path: "/chapter-2/page-3".to_string(),
2754 title: "Page 3".to_string(),
2755 chapter_id: Some(chapter_2.id),
2756 exercises: vec![quizzes_exercise_5],
2757 exercise_slides: vec![quizzes_exercise_slide_5],
2758 exercise_tasks: vec![quizzes_exercise_task_5],
2759 content: serde_json::json!([
2760 paragraph(
2761 "Second chapters third page",
2762 Uuid::new_v5(&course.id, b"4ebd0208-8328-5d69-8c44-ec50939c0967")
2763 ),
2764 quizzes_exercise_block_5,
2765 ]),
2766 },
2767 )
2768 .await?;
2769
2770 create_page(
2771 &mut conn,
2772 course.id,
2773 teacher_user_id,
2774 Some(chapter_2.id),
2775 CmsPageUpdate {
2776 url_path: "/chapter-2/page-4".to_string(),
2777 title: "Page 4".to_string(),
2778 chapter_id: Some(chapter_2.id),
2779 exercises: vec![quizzes_exercise_6],
2780 exercise_slides: vec![quizzes_exercise_slide_6],
2781 exercise_tasks: vec![quizzes_exercise_task_6],
2782 content: serde_json::json!([
2783 paragraph(
2784 "Second chapters fourth page",
2785 Uuid::new_v5(&course.id, b"4841cabb-77a0-53cf-b539-39fbd060e73b")
2786 ),
2787 quizzes_exercise_block_6,
2788 ]),
2789 },
2790 )
2791 .await?;
2792
2793 create_page(
2794 &mut conn,
2795 course.id,
2796 teacher_user_id,
2797 Some(chapter_2.id),
2798 CmsPageUpdate {
2799 url_path: "/chapter-2/page-5".to_string(),
2800 title: "Page 5".to_string(),
2801 chapter_id: Some(chapter_2.id),
2802 exercises: vec![quizzes_exercise_7],
2803 exercise_slides: vec![quizzes_exercise_slide_7],
2804 exercise_tasks: vec![quizzes_exercise_task_7],
2805
2806 content: serde_json::json!([
2807 paragraph(
2808 "Second chapters fifth page",
2809 Uuid::new_v5(&course.id, b"9a614406-e1b4-5920-8e0d-54d1a3ead5f3")
2810 ),
2811 quizzes_exercise_block_7,
2812 ]),
2813 },
2814 )
2815 .await?;
2816
2817 create_page(
2818 &mut conn,
2819 course.id,
2820 teacher_user_id,
2821 Some(chapter_2.id),
2822 CmsPageUpdate {
2823 url_path: "/chapter-2/page-6".to_string(),
2824 title: "Page 6".to_string(),
2825 chapter_id: Some(chapter_2.id),
2826 exercises: vec![quizzes_exercise_8],
2827 exercise_slides: vec![quizzes_exercise_slide_8],
2828 exercise_tasks: vec![quizzes_exercise_task_8],
2829 content: serde_json::json!([
2830 paragraph(
2831 "Second chapters sixth page",
2832 Uuid::new_v5(&course.id, b"891de1ca-f3a9-506f-a268-3477ea4fdd27")
2833 ),
2834 quizzes_exercise_block_8,
2835 ]),
2836 },
2837 )
2838 .await?;
2839
2840 course_instance_enrollments::insert_enrollment_and_set_as_current(
2842 &mut conn,
2843 NewCourseInstanceEnrollment {
2844 course_id: course.id,
2845 course_instance_id: default_instance.id,
2846 user_id: langs_user_id,
2847 },
2848 )
2849 .await?;
2850
2851 Ok(course.id)
2852}
2853
2854pub async fn seed_peer_review_course_without_submissions(
2855 course_id: Uuid,
2856 course_name: &str,
2857 course_slug: &str,
2858 common_course_data: CommonCourseData,
2859) -> Result<Uuid> {
2860 let CommonCourseData {
2861 db_pool,
2862 organization_id: org,
2863 teacher_user_id,
2864 student_user_id: _,
2865 langs_user_id: _,
2866 example_normal_user_ids: _,
2867 jwt_key: _jwt_key,
2868 base_url: _base_url,
2869 } = common_course_data;
2870 let spec_fetcher = get_seed_spec_fetcher();
2871 info!("inserting sample course {}", course_name);
2872 let mut conn = db_pool.acquire().await?;
2873 let new_course = NewCourse {
2874 name: course_name.to_string(),
2875 organization_id: org,
2876 slug: course_slug.to_string(),
2877 language_code: "en-US".to_string(),
2878 teacher_in_charge_name: "admin".to_string(),
2879 teacher_in_charge_email: "admin@example.com".to_string(),
2880 description: "Sample course.".to_string(),
2881 is_draft: false,
2882 is_test_mode: false,
2883 is_unlisted: false,
2884 copy_user_permissions: false,
2885 is_joinable_by_code_only: false,
2886 join_code: None,
2887 ask_marketing_consent: false,
2888 flagged_answers_threshold: Some(3),
2889 can_add_chatbot: false,
2890 };
2891
2892 let (course, _front_page, _, default_module) = library::content_management::create_new_course(
2893 &mut conn,
2894 PKeyPolicy::Fixed(CreateNewCourseFixedIds {
2895 course_id,
2896 default_course_instance_id: Uuid::new_v5(
2897 &course_id,
2898 b"7344f1c8-b7ce-4c7d-ade2-5f39997bd454",
2899 ),
2900 }),
2901 new_course,
2902 teacher_user_id,
2903 &spec_fetcher,
2904 models_requests::fetch_service_info,
2905 )
2906 .await?;
2907
2908 course_instances::insert(
2909 &mut conn,
2910 PKeyPolicy::Fixed(Uuid::new_v5(
2911 &course_id,
2912 b"67f077b4-0562-47ae-a2b9-db2f08f168a9",
2913 )),
2914 NewCourseInstance {
2915 course_id: course.id,
2916 name: Some("Non-default instance"),
2917 description: Some("This is a non-default instance"),
2918 support_email: Some("contact@example.com"),
2919 teacher_in_charge_name: "admin",
2920 teacher_in_charge_email: "admin@example.com",
2921 opening_time: None,
2922 closing_time: None,
2923 },
2924 )
2925 .await?;
2926
2927 let new_chapter = NewChapter {
2930 chapter_number: 1,
2931 course_id: course.id,
2932 front_page_id: None,
2933 name: "The Basics".to_string(),
2934 color: None,
2935 opens_at: None,
2936 deadline: Some(Utc.with_ymd_and_hms(2225, 1, 1, 23, 59, 59).unwrap()),
2937
2938 course_module_id: Some(default_module.id),
2939 };
2940
2941 let (chapter_1, _front_page_1) = library::content_management::create_new_chapter(
2942 &mut conn,
2943 PKeyPolicy::Fixed((
2944 Uuid::new_v5(&course_id, b"bfc557e1-0f8e-4f10-8e21-d7d8ffe50a3a"),
2945 Uuid::new_v5(&course_id, b"b1e392db-482a-494e-9cbb-c87bbc70e340"),
2946 )),
2947 &new_chapter,
2948 teacher_user_id,
2949 &spec_fetcher,
2950 models_requests::fetch_service_info,
2951 )
2952 .await?;
2953
2954 chapters::set_opens_at(&mut conn, chapter_1.id, Utc::now()).await?;
2955
2956 let welcome_page = NewCoursePage::new(
2957 course.id,
2958 1,
2959 "/welcome",
2960 "Welcome to Introduction to peer reviews",
2961 );
2962 let (_page, _) = pages::insert_course_page(&mut conn, &welcome_page, teacher_user_id).await?;
2963 let hidden_page = welcome_page
2964 .followed_by("/hidden", "Hidden Page")
2965 .set_hidden(true)
2966 .set_content(vec![GutenbergBlock::paragraph(
2967 "You found the secret of the project 331!",
2968 )]);
2969 let (_page, _) = pages::insert_course_page(&mut conn, &hidden_page, teacher_user_id).await?;
2970
2971 info!("sample exercises");
2972 let block_id_1 = Uuid::new_v5(&course_id, b"4ef933d8-170f-4437-a5af-bc7690cfac5a");
2973 let block_id_2 = Uuid::new_v5(&course_id, b"35510467-9a7b-46de-9878-d9d34a1821a4");
2974 let exercise_1_id = Uuid::new_v5(&course_id, b"bae98f14-9ffd-4647-8f28-fe4a5967d6e9");
2975 let exercise_1_slide_1_id = Uuid::new_v5(&course_id, b"6d3feb9c-fc95-4908-803f-1b0d0e3f2c18");
2976 let exercise_1_slide_1_task_1_id =
2977 Uuid::new_v5(&course_id, b"47517fe6-d5e2-4b8f-8d94-541a4d849aed");
2978 let exercise_1_slide_1_task_1_spec_1_id =
2979 Uuid::new_v5(&course_id, b"847a2144-e55b-4c2f-a6a7-98bbe7927d10");
2980 let exercise_1_slide_1_task_1_spec_2_id =
2981 Uuid::new_v5(&course_id, b"979a00a7-2e8a-4294-9e46-3367c372864f");
2982 let exercise_1_slide_1_task_1_spec_3_id =
2983 Uuid::new_v5(&course_id, b"b354830c-38c7-4b83-8370-0e7222272c56");
2984
2985 let (exercise_block_1, exercise_1, slide_1, task_1) = create_best_exercise(
2986 block_id_2,
2987 exercise_1_slide_1_task_1_spec_1_id,
2988 exercise_1_slide_1_task_1_spec_2_id,
2989 exercise_1_slide_1_task_1_spec_3_id,
2990 Some("ManualReviewEverything".to_string()),
2991 CommonExerciseData {
2992 exercise_id: exercise_1_id,
2993 exercise_slide_id: exercise_1_slide_1_id,
2994 exercise_task_id: exercise_1_slide_1_task_1_id,
2995 block_id: block_id_1,
2996 },
2997 );
2998
2999 create_page(
3000 &mut conn,
3001 course.id,
3002 teacher_user_id,
3003 Some(chapter_1.id),
3004 CmsPageUpdate {
3005 url_path: "/chapter-1/page-1".to_string(),
3006 title: "Page One".to_string(),
3007 chapter_id: Some(chapter_1.id),
3008 exercises: vec![exercise_1],
3009 exercise_slides: vec![slide_1],
3010 exercise_tasks: vec![task_1],
3011 content: serde_json::json!([exercise_block_1,]),
3012 },
3013 )
3014 .await?;
3015
3016 create_best_peer_review(
3017 &mut conn,
3018 course_id,
3019 exercise_1_id,
3020 ManualReviewEverything,
3021 3.0,
3022 true,
3023 2,
3024 1,
3025 )
3026 .await?;
3027
3028 let block_id_3 = Uuid::new_v5(&course_id, b"4b57812a-6509-4783-a746-3e382adf5060");
3029 let block_id_4 = Uuid::new_v5(&course_id, b"d315f5bb-306f-478b-846c-ca5f1407f2db");
3030 let exercise_2_id = Uuid::new_v5(&course_id, b"39f23830-d2eb-4232-b6f7-78822f0e0fbd");
3031 let exercise_2_slide_1_id = Uuid::new_v5(&course_id, b"cbbbee55-511b-45be-9d95-1fa9273497ee");
3032 let exercise_2_slide_1_task_1_id =
3033 Uuid::new_v5(&course_id, b"a2ae64bd-9518-4c2b-88c1-49ba103f14ff");
3034 let exercise_2_slide_1_task_1_spec_1_id =
3035 Uuid::new_v5(&course_id, b"f1cd2f78-a489-4cae-a656-86aa574faf19");
3036 let exercise_2_slide_1_task_1_spec_2_id =
3037 Uuid::new_v5(&course_id, b"5435b9ae-d811-43b6-b208-23f64267eef1");
3038 let exercise_2_slide_1_task_1_spec_3_id =
3039 Uuid::new_v5(&course_id, b"9f6e4ad4-b9f5-40cf-b071-642da7058fec");
3040
3041 let (exercise_block_2, exercise_2, slide_1, task_1) = create_best_exercise(
3042 block_id_4,
3043 exercise_2_slide_1_task_1_spec_1_id,
3044 exercise_2_slide_1_task_1_spec_2_id,
3045 exercise_2_slide_1_task_1_spec_3_id,
3046 Some("AutomaticallyGradeOrManualReviewByAverage".to_string()),
3047 CommonExerciseData {
3048 exercise_id: exercise_2_id,
3049 exercise_slide_id: exercise_2_slide_1_id,
3050 exercise_task_id: exercise_2_slide_1_task_1_id,
3051 block_id: block_id_3,
3052 },
3053 );
3054
3055 create_page(
3056 &mut conn,
3057 course.id,
3058 teacher_user_id,
3059 Some(chapter_1.id),
3060 CmsPageUpdate {
3061 url_path: "/chapter-1/page-2".to_string(),
3062 title: "Page Two".to_string(),
3063 chapter_id: Some(chapter_1.id),
3064 exercises: vec![exercise_2],
3065 exercise_slides: vec![slide_1],
3066 exercise_tasks: vec![task_1],
3067 content: serde_json::json!([exercise_block_2]),
3068 },
3069 )
3070 .await?;
3071
3072 create_best_peer_review(
3073 &mut conn,
3074 course_id,
3075 exercise_2_id,
3076 AutomaticallyGradeOrManualReviewByAverage,
3077 3.0,
3078 true,
3079 2,
3080 1,
3081 )
3082 .await?;
3083
3084 let block_id_5 = Uuid::new_v5(&course_id, b"591b1612-36c8-4f02-841b-d5f95be9b410");
3085 let block_id_6 = Uuid::new_v5(&course_id, b"2adbaaef-6213-4b83-ba8f-827e5a4f084f");
3086 let exercise_3_id = Uuid::new_v5(&course_id, b"3b4e964b-8992-4595-92ad-bdb1721e9352");
3087 let exercise_3_slide_1_id = Uuid::new_v5(&course_id, b"d0596f5c-885b-483e-9f59-271b289e4220");
3088 let exercise_3_slide_1_task_1_id =
3089 Uuid::new_v5(&course_id, b"170a97c9-2e75-4817-af17-5e45bd362260");
3090 let exercise_3_slide_1_task_1_spec_1_id =
3091 Uuid::new_v5(&course_id, b"b74450cf-e8a5-4689-b2a4-7a0ed491dcbc");
3092 let exercise_3_slide_1_task_1_spec_2_id =
3093 Uuid::new_v5(&course_id, b"f27a8e35-2d72-406d-9c99-fd8b7c1991a3");
3094 let exercise_3_slide_1_task_1_spec_3_id =
3095 Uuid::new_v5(&course_id, b"31443721-fc55-4ea6-9b2a-2da8a6a991df");
3096
3097 let (exercise_block_3, exercise_3, slide_1, task_1) = create_best_exercise(
3098 block_id_6,
3099 exercise_3_slide_1_task_1_spec_1_id,
3100 exercise_3_slide_1_task_1_spec_2_id,
3101 exercise_3_slide_1_task_1_spec_3_id,
3102 Some("AutomaticallyGradeByAverage".to_string()),
3103 CommonExerciseData {
3104 exercise_id: exercise_3_id,
3105 exercise_slide_id: exercise_3_slide_1_id,
3106 exercise_task_id: exercise_3_slide_1_task_1_id,
3107 block_id: block_id_5,
3108 },
3109 );
3110
3111 create_page(
3112 &mut conn,
3113 course.id,
3114 teacher_user_id,
3115 Some(chapter_1.id),
3116 CmsPageUpdate {
3117 url_path: "/chapter-1/page-3".to_string(),
3118 title: "Page Three".to_string(),
3119 chapter_id: Some(chapter_1.id),
3120 exercises: vec![exercise_3],
3121 exercise_slides: vec![slide_1],
3122 exercise_tasks: vec![task_1],
3123 content: serde_json::json!([exercise_block_3,]),
3124 },
3125 )
3126 .await?;
3127
3128 create_best_peer_review(
3129 &mut conn,
3130 course_id,
3131 exercise_3_id,
3132 AutomaticallyGradeByAverage,
3133 3.0,
3134 true,
3135 2,
3136 1,
3137 )
3138 .await?;
3139
3140 let block_id_7 = Uuid::new_v5(&course_id, b"80e97fbc-ebc1-46f3-a19c-04cdb9f3d349");
3141 let block_id_8 = Uuid::new_v5(&course_id, b"db818c1f-0667-4050-9289-7224a8ca3c5c");
3142 let exercise_4_id = Uuid::new_v5(&course_id, b"65cde761-6ccd-4804-8343-c85b1d3d6fc4");
3143 let exercise_4_slide_1_id = Uuid::new_v5(&course_id, b"b37771bc-37d0-4cae-b06d-c35256f289a5");
3144 let exercise_4_slide_1_task_1_id =
3145 Uuid::new_v5(&course_id, b"0ecaff02-d8cf-44c3-be8c-ea2449c02d0f");
3146 let exercise_4_slide_1_task_1_spec_1_id =
3147 Uuid::new_v5(&course_id, b"caaf7ec5-fd2b-4e07-b185-58b8070b059e");
3148 let exercise_4_slide_1_task_1_spec_2_id =
3149 Uuid::new_v5(&course_id, b"f92ba66c-fe8a-4711-b25a-73a13c451543");
3150 let exercise_4_slide_1_task_1_spec_3_id =
3151 Uuid::new_v5(&course_id, b"c17f23ca-7daa-40dd-b390-1ac8531dd17d");
3152
3153 let (exercise_block_1, exercise_1, slide_1, task_1) = create_best_exercise(
3154 block_id_8,
3155 exercise_4_slide_1_task_1_spec_1_id,
3156 exercise_4_slide_1_task_1_spec_2_id,
3157 exercise_4_slide_1_task_1_spec_3_id,
3158 Some("ManualReviewEverything2".to_string()),
3159 CommonExerciseData {
3160 exercise_id: exercise_4_id,
3161 exercise_slide_id: exercise_4_slide_1_id,
3162 exercise_task_id: exercise_4_slide_1_task_1_id,
3163 block_id: block_id_7,
3164 },
3165 );
3166
3167 create_page(
3168 &mut conn,
3169 course.id,
3170 teacher_user_id,
3171 Some(chapter_1.id),
3172 CmsPageUpdate {
3173 url_path: "/chapter-1/page-4".to_string(),
3174 title: "Page Four".to_string(),
3175 chapter_id: Some(chapter_1.id),
3176 exercises: vec![exercise_1],
3177 exercise_slides: vec![slide_1],
3178 exercise_tasks: vec![task_1],
3179 content: serde_json::json!([exercise_block_1,]),
3180 },
3181 )
3182 .await?;
3183
3184 create_best_peer_review(
3185 &mut conn,
3186 course_id,
3187 exercise_4_id,
3188 ManualReviewEverything,
3189 3.0,
3190 true,
3191 2,
3192 1,
3193 )
3194 .await?;
3195
3196 let block_id_9 = Uuid::new_v5(&course_id, b"54349cc8-dbba-4223-b5e0-71fafdfe8fd3");
3197 let block_id_10 = Uuid::new_v5(&course_id, b"ee05ad17-07dc-4c3b-be63-67bd2a4ac46a");
3198 let exercise_5_id = Uuid::new_v5(&course_id, b"31717e20-8fe5-451c-a7d3-bca09d0ea14f");
3199 let exercise_5_slide_1_id = Uuid::new_v5(&course_id, b"9bd990d1-3cd6-4e23-b372-8860ebd8bac5");
3200 let exercise_5_slide_1_task_1_id =
3201 Uuid::new_v5(&course_id, b"fe5da9f8-aaae-4b05-9cf9-29f3cde55bd7");
3202 let exercise_5_slide_1_task_1_spec_1_id =
3203 Uuid::new_v5(&course_id, b"5efb1377-70af-455f-ad78-cddd0bd6cbb1");
3204 let exercise_5_slide_1_task_1_spec_2_id =
3205 Uuid::new_v5(&course_id, b"f92ba66c-fe8a-4711-b25a-73a13c451543");
3206 let exercise_5_slide_1_task_1_spec_3_id =
3207 Uuid::new_v5(&course_id, b"75bbc9f6-84f2-4182-80d1-07bd7c435d6c");
3208
3209 let (exercise_block_1, exercise_1, slide_1, task_1) = create_best_exercise(
3210 block_id_10,
3211 exercise_5_slide_1_task_1_spec_1_id,
3212 exercise_5_slide_1_task_1_spec_2_id,
3213 exercise_5_slide_1_task_1_spec_3_id,
3214 Some("Can give extra reviews".to_string()),
3215 CommonExerciseData {
3216 exercise_id: exercise_5_id,
3217 exercise_slide_id: exercise_5_slide_1_id,
3218 exercise_task_id: exercise_5_slide_1_task_1_id,
3219 block_id: block_id_9,
3220 },
3221 );
3222
3223 create_page(
3224 &mut conn,
3225 course.id,
3226 teacher_user_id,
3227 Some(chapter_1.id),
3228 CmsPageUpdate {
3229 url_path: "/chapter-1/can-give-extra-reviews".to_string(),
3230 title: "Can give extra peer reviews".to_string(),
3231 chapter_id: Some(chapter_1.id),
3232 exercises: vec![exercise_1],
3233 exercise_slides: vec![slide_1],
3234 exercise_tasks: vec![task_1],
3235 content: serde_json::json!([exercise_block_1,]),
3236 },
3237 )
3238 .await?;
3239
3240 create_best_peer_review(
3241 &mut conn,
3242 course_id,
3243 exercise_5_id,
3244 AutomaticallyGradeByAverage,
3245 3.0,
3246 true,
3247 3,
3248 2,
3249 )
3250 .await?;
3251
3252 Ok(course.id)
3253}