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