Skip to content

Commit e35b044

Browse files
authored
Merge pull request #196 from rage/fallback-dl-template-if-exam
Fallback to download exercise template, if exercise submissions hidden
2 parents 75752ca + 95b5a45 commit e35b044

File tree

5 files changed

+122
-20
lines changed

5 files changed

+122
-20
lines changed

bindings/tmc-langs-node/jest/mock_server.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,35 @@ app.get("/api/v8/core/exercises/details", (_req, res) => {
1010
course_name: "some course",
1111
exercise_name: "on disk exercise with update and submission",
1212
checksum: "new checksum",
13+
hide_submission_results: false,
1314
},
1415
{
1516
id: 2,
1617
course_name: "some course",
1718
exercise_name: "on disk exercise without update",
1819
checksum: "new checksum",
20+
hide_submission_results: false,
1921
},
2022
{
2123
id: 3,
2224
course_name: "another course",
2325
exercise_name: "not on disk exercise with submission",
2426
checksum: "new checksum",
27+
hide_submission_results: false,
2528
},
2629
{
2730
id: 4,
2831
course_name: "another course",
2932
exercise_name: "not on disk exercise without submission",
3033
checksum: "new checksum",
34+
hide_submission_results: false,
35+
},
36+
{
37+
id: 5,
38+
course_name: "another course",
39+
exercise_name: "not on disk exercise with submission exercise hide submission result",
40+
checksum: "new checksum",
41+
hide_submission_results: true,
3142
},
3243
],
3344
});

tmc-client/src/response.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ pub struct ExercisesDetails {
270270
pub course_name: String,
271271
pub exercise_name: String,
272272
pub checksum: String,
273+
pub hide_submission_results: bool,
273274
}
274275

275276
/// get /api/v8/courses/{course_id}/submissions

tmc-client/src/tmc_client/api_v8.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2372,7 +2372,8 @@ mod test {
23722372
"id": 1,
23732373
"course_name": "course",
23742374
"exercise_name": "exercise",
2375-
"checksum": "f25e139769b2688e213938456959eeaf"
2375+
"checksum": "f25e139769b2688e213938456959eeaf",
2376+
"hide_submission_results": false
23762377
}
23772378
]
23782379
}

tmc-langs/src/lib.rs

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -282,25 +282,27 @@ pub fn download_or_update_course_exercises(
282282
.into_iter()
283283
.max_by_key(|s| s.created_at)
284284
{
285-
// previous submission found
286-
to_be_downloaded.push(DownloadTarget {
287-
target: ExerciseDownload {
288-
id: exercise_detail.id,
289-
course_slug: exercise_detail.course_name,
290-
exercise_slug: exercise_detail.exercise_name,
291-
path: target,
292-
},
293-
checksum: exercise_detail.checksum,
294-
kind: DownloadTargetKind::Submission {
295-
submission_id: latest_submission.id,
296-
},
297-
});
298-
continue;
285+
// previous submission found, check if exercise submission results hidden (part of exam)
286+
if !exercise_detail.hide_submission_results {
287+
to_be_downloaded.push(DownloadTarget {
288+
target: ExerciseDownload {
289+
id: exercise_detail.id,
290+
course_slug: exercise_detail.course_name,
291+
exercise_slug: exercise_detail.exercise_name,
292+
path: target,
293+
},
294+
checksum: exercise_detail.checksum,
295+
kind: DownloadTargetKind::Submission {
296+
submission_id: latest_submission.id,
297+
},
298+
});
299+
continue;
300+
}
299301
}
300302
}
301303
}
302304

303-
// not skipped, either not on disk or no previous submissions, downloading template
305+
// not skipped, either not on disk or no previous submissions or submission result hidden, downloading template
304306
to_be_downloaded.push(DownloadTarget {
305307
target: ExerciseDownload {
306308
id: exercise_detail.id,
@@ -1052,12 +1054,14 @@ mod test {
10521054
course_name: "some course".to_string(),
10531055
exercise_name: "some exercise".to_string(),
10541056
checksum: "new checksum".to_string(),
1057+
hide_submission_results: false,
10551058
},
10561059
ExercisesDetails {
10571060
id: 2,
10581061
course_name: "some course".to_string(),
10591062
exercise_name: "another exercise".to_string(),
10601063
checksum: "old checksum".to_string(),
1064+
hide_submission_results: false,
10611065
},
10621066
];
10631067
let mut response = HashMap::new();
@@ -1157,24 +1161,37 @@ checksum = 'new checksum'
11571161
checksum: "new checksum".to_string(),
11581162
course_name: "some course".to_string(),
11591163
exercise_name: "on disk exercise with update and submission".to_string(),
1164+
hide_submission_results: false,
11601165
},
11611166
ExercisesDetails {
11621167
id: 2,
11631168
checksum: "new checksum".to_string(),
11641169
course_name: "some course".to_string(),
11651170
exercise_name: "on disk exercise without update".to_string(),
1171+
hide_submission_results: false,
11661172
},
11671173
ExercisesDetails {
11681174
id: 3,
11691175
checksum: "new checksum".to_string(),
11701176
course_name: "another course".to_string(),
11711177
exercise_name: "not on disk exercise with submission".to_string(),
1178+
hide_submission_results: false,
11721179
},
11731180
ExercisesDetails {
11741181
id: 4,
11751182
checksum: "new checksum".to_string(),
11761183
course_name: "another course".to_string(),
11771184
exercise_name: "not on disk exercise without submission".to_string(),
1185+
hide_submission_results: false,
1186+
},
1187+
ExercisesDetails {
1188+
id: 5,
1189+
checksum: "new checksum".to_string(),
1190+
course_name: "another course".to_string(),
1191+
exercise_name:
1192+
"not on disk exercise with submission exercise hide submission result"
1193+
.to_string(),
1194+
hide_submission_results: true,
11781195
},
11791196
],
11801197
);
@@ -1252,6 +1269,16 @@ checksum = 'new checksum'
12521269
.with_body(serde_json::to_string(&[0; 0]).unwrap())
12531270
.create();
12541271

1272+
let _m = mockito::mock(
1273+
"GET",
1274+
mockito::Matcher::AllOf(vec![
1275+
mockito::Matcher::Regex("exercises/5".to_string()),
1276+
mockito::Matcher::Regex("submissions".to_string()),
1277+
]),
1278+
)
1279+
.with_body(serde_json::to_string(&sub_body).unwrap())
1280+
.create();
1281+
12551282
let mut template_zw = zip::ZipWriter::new(std::io::Cursor::new(vec![]));
12561283
template_zw
12571284
.start_file("src/student_file.py", zip::write::FileOptions::default())
@@ -1310,6 +1337,15 @@ checksum = 'new checksum'
13101337
)
13111338
.with_body(&template_z)
13121339
.create();
1340+
let _m = mockito::mock(
1341+
"GET",
1342+
mockito::Matcher::AllOf(vec![
1343+
mockito::Matcher::Regex("exercises/5".to_string()),
1344+
mockito::Matcher::Regex("download".to_string()),
1345+
]),
1346+
)
1347+
.with_body(&template_z)
1348+
.create();
13131349

13141350
let mut sub_zw = zip::ZipWriter::new(std::io::Cursor::new(vec![]));
13151351
sub_zw
@@ -1354,13 +1390,14 @@ checksum = 'new checksum'
13541390
other => panic!("{:?}", other),
13551391
};
13561392

1357-
assert_eq!(downloaded.len(), 3);
1393+
assert_eq!(downloaded.len(), 4);
13581394
assert_eq!(skipped.len(), 1);
13591395

13601396
let e1 = downloaded.iter().find(|e| e.id == 1).unwrap();
13611397
let _e2 = skipped.iter().find(|e| e.id == 2).unwrap();
13621398
let e3 = downloaded.iter().find(|e| e.id == 3).unwrap();
13631399
let e4 = downloaded.iter().find(|e| e.id == 4).unwrap();
1400+
let e5 = downloaded.iter().find(|e| e.id == 5).unwrap();
13641401

13651402
// did not download submission even though it was available because it was on disk
13661403
let f = file_util::read_file_to_string(e1.path.join("src/student_file.py")).unwrap();
@@ -1383,9 +1420,16 @@ checksum = 'new checksum'
13831420
// did not download submission because one was not available
13841421
let f = file_util::read_file_to_string(e4.path.join("src/student_file.py")).unwrap();
13851422
assert_eq!(f, "template");
1386-
assert!(e1.path.join("src/template_only_student_file.py").exists());
1423+
assert!(e4.path.join("src/template_only_student_file.py").exists());
13871424
let f = file_util::read_file_to_string(e4.path.join("test/exercise_file.py")).unwrap();
13881425
assert_eq!(f, "template");
1426+
1427+
// did not download submission because exercise hides submission results, for example exam exercise
1428+
let f = file_util::read_file_to_string(e5.path.join("src/student_file.py")).unwrap();
1429+
assert_eq!(f, "template");
1430+
assert!(e5.path.join("src/template_only_student_file.py").exists());
1431+
let f = file_util::read_file_to_string(e5.path.join("test/exercise_file.py")).unwrap();
1432+
assert_eq!(f, "template");
13891433
}
13901434

13911435
#[test]

tmc-server-mock/src/lib.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ checksum = '{checksum}'
3636
id = {}
3737
checksum = '{checksum}'
3838
39+
[exercises."{}"]
40+
id = {}
41+
checksum = '{checksum}'
42+
3943
[exercises."{}"]
4044
id = {}
4145
checksum = '{checksum}'
@@ -49,6 +53,8 @@ checksum = '{checksum}'
4953
EXERCISE_IDS[2],
5054
EXERCISE_NAMES[3],
5155
EXERCISE_IDS[3],
56+
EXERCISE_NAMES[4],
57+
EXERCISE_IDS[4],
5258
checksum = EXERCISE_CHECKSUM,
5359
)
5460
}
@@ -60,12 +66,13 @@ pub const ORGANIZATION_NAME: &str = "mock-organization";
6066
pub const ORGANIZATION_SLUG: &str = "morg";
6167
pub const COURSE_ID: u32 = 1;
6268
pub const COURSE_NAME: &str = "mock-course";
63-
pub const EXERCISE_IDS: [u32; 4] = [1, 2, 3, 4];
64-
pub const EXERCISE_NAMES: [&str; 4] = [
69+
pub const EXERCISE_IDS: [u32; 5] = [1, 2, 3, 4, 5];
70+
pub const EXERCISE_NAMES: [&str; 5] = [
6571
"mock-exercise-1",
6672
"mock-exercise-2",
6773
"mock-exercise-3",
6874
"mock-exercise-4",
75+
"mock-exercise-5",
6976
];
7077
pub const EXERCISE_CHECKSUM: &str = "new checksum";
7178
pub const SUBMISSION_ID: u32 = 1;
@@ -608,6 +615,33 @@ pub mod core {
608615
"latest_submission_id": SUBMISSION_ID,
609616
"solution_zip_url": "http://localhost"
610617
},
618+
{
619+
"id": EXERCISE_IDS[4],
620+
"name": EXERCISE_NAMES[4],
621+
"locked": false,
622+
"deadline_description": "2016-02-29 23:59:00 +0200",
623+
"deadline": "2016-02-29T23:59:00.000+02:00",
624+
"checksum": "new checksum",
625+
"return_url": "https://tmc.mooc.fi/api/v8/core/exercises/1337/submissions",
626+
"zip_url": "https://tmc.mooc.fi/api/v8/core/exercises/4272/download",
627+
"returnable": true,
628+
"requires_review": false,
629+
"attempted": false,
630+
"completed": false,
631+
"reviewed": false,
632+
"all_review_points_given": true,
633+
"memory_limit": 1024,
634+
"runtime_params": [
635+
"-Xss64M"
636+
],
637+
"valgrind_strategy": "fail",
638+
"code_review_requests_enabled": false,
639+
"run_tests_locally_action_enabled": true,
640+
"exercise_submissions_url": "https://localhost",
641+
"latest_submission_url": "https://localhost",
642+
"latest_submission_id": SUBMISSION_ID,
643+
"solution_zip_url": "http://localhost"
644+
},
611645
]
612646
}})
613647
}
@@ -669,24 +703,35 @@ pub mod core {
669703
"course_name": COURSE_NAME,
670704
"exercise_name": EXERCISE_NAMES[0],
671705
"checksum": EXERCISE_CHECKSUM,
706+
"hide_submission_results": false,
672707
},
673708
{
674709
"id": EXERCISE_IDS[1],
675710
"course_name": COURSE_NAME,
676711
"exercise_name": EXERCISE_NAMES[1],
677712
"checksum": EXERCISE_CHECKSUM,
713+
"hide_submission_results": false,
678714
},
679715
{
680716
"id": EXERCISE_IDS[2],
681717
"course_name": COURSE_NAME,
682718
"exercise_name": EXERCISE_NAMES[2],
683719
"checksum": EXERCISE_CHECKSUM,
720+
"hide_submission_results": false,
684721
},
685722
{
686723
"id": EXERCISE_IDS[3],
687724
"course_name": COURSE_NAME,
688725
"exercise_name": EXERCISE_NAMES[3],
689726
"checksum": EXERCISE_CHECKSUM,
727+
"hide_submission_results": false,
728+
},
729+
{
730+
"id": EXERCISE_IDS[4],
731+
"course_name": COURSE_NAME,
732+
"exercise_name": EXERCISE_NAMES[4],
733+
"checksum": EXERCISE_CHECKSUM,
734+
"hide_submission_results": true,
690735
},
691736
]
692737
})

0 commit comments

Comments
 (0)