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