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