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