Skip to main content

headless_lms_server/programs/seed/seed_courses/
mod.rs

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