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