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