headless_lms_server/programs/seed/
seed_courses.rs

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