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