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