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