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