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