Skip to main content

headless_lms_server/programs/seed/seed_courses/
mod.rs

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    // Seeded courses are completed in seconds by system tests, which would flag every seeded user
151    // and break the suite, so disable cheater detection. Callers that need detection on (e.g. the
152    // dedicated suspected-cheaters course) re-enable it after seeding.
153    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    // chapters and pages
180
181    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    // enrollments, user exercise states, submissions, grades
1735    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        // Pre-acknowledge the AI-usage notice for seeded enrollments so the dialog does not
1748        // block already-enrolled users (e.g. in system tests).
1749        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        // this submission is for the same exercise, but no points are removed due to the update strategy
1767        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    // feedback
1870    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    // edit proposals
1955    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    // acronyms
2000    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    // create_best_peer_review(&mut conn, course.id, Some(exercise_1_id)).await?;
2005
2006    // certificate configuration
2007    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    // Add roles
2057    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    // Create new course
2079    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    // Exercises
2116    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    // FAQ, we should add card/accordion block to visualize here.
2410
2411    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    // Chapter-1
2419    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    // /chapter-1/design
2475    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    // /chapter-1/human-machine-interface
2541    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    // Chapter-2
2588    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    // /chapter-2/user-research
2643    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    // Multiple choice
2778
2779    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    // enrollments
2877    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    // chapters and pages
2968
2969    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}