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