headless_lms_server/programs/seed/seed_courses/
mod.rs

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