Skip to content

Commit 17dfda2

Browse files
committed
fetch/fetch_feedback failure tests
1 parent b30b1b1 commit 17dfda2

File tree

2 files changed

+224
-0
lines changed

2 files changed

+224
-0
lines changed

nbgrader/tests/labextension_ui-tests/tests/test_assignment_list.spec.ts

+162
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,54 @@ test('Fetch assignments', async({
309309

310310
});
311311

312+
/*
313+
* Test fetch failure
314+
*/
315+
test('Fetch failure', async({
316+
page,
317+
baseURL,
318+
tmpPath
319+
}) => {
320+
321+
test.skip(is_windows, 'This feature is not implemented for Windows');
322+
323+
if (baseURL === undefined) throw new Error("BaseURL is undefined.");
324+
325+
// create directories and config files, and open assignment_list tab
326+
await create_env(page, tmpPath, exchange_dir, cache_dir, is_windows);
327+
await add_courses(page, baseURL, tmpPath);
328+
await open_assignment_list(page);
329+
330+
// release some assignments
331+
await execute_command("nbgrader generate_assignment 'Problem Set 1' --force");
332+
await execute_command("nbgrader release_assignment 'Problem Set 1' --course 'abc101' --force");
333+
await execute_command("nbgrader generate_assignment 'ps.01' --force");
334+
await execute_command("nbgrader release_assignment 'ps.01' --course 'xyz 200' --force");
335+
336+
// refresh assignment list
337+
await page.locator('#refresh_assignments_list').click();
338+
339+
// select one course
340+
await select_course(page, 'abc101');
341+
342+
// remove write permissions
343+
// check that there is only one released, and try fetch it
344+
// then restore permissions again
345+
await fs.chmod("nbgrader-assignment-list-test", 0o555, err => {});
346+
var rows = await wait_for_list(page, 'released', 1);
347+
await rows.first().locator('.item_status button').click();
348+
await new Promise(resolve => setTimeout(resolve, 1000)); // to make sure permissions are not restored too fast
349+
await fs.chmod("nbgrader-assignment-list-test", 0o755, err => {});
350+
351+
// check that there is still only one released
352+
rows = await wait_for_list(page, 'released', 1);
353+
354+
// Check and close the error message
355+
await wait_for_error_modal(page);
356+
await close_error_modal(page);
357+
358+
});
359+
312360
/*
313361
* Test submit assignment
314362
*/
@@ -711,3 +759,117 @@ test('Missing exchange directory', async({
711759
expect(rows.first().locator('.item_course')).toHaveText("abc101");
712760

713761
});
762+
763+
/*
764+
* Test fetching feedback
765+
*/
766+
test('Fetch feedback', async({
767+
page,
768+
baseURL,
769+
tmpPath
770+
}) => {
771+
772+
test.skip(is_windows, 'This feature is not implemented for Windows');
773+
774+
if (baseURL === undefined) throw new Error("BaseURL is undefined.");
775+
776+
// create directories and config files, and open assignment_list tab
777+
await create_env(page, tmpPath, exchange_dir, cache_dir, is_windows);
778+
await add_courses(page, baseURL, tmpPath);
779+
await open_assignment_list(page);
780+
781+
// release some assignments
782+
await execute_command("nbgrader generate_assignment 'Problem Set 1' --force");
783+
await execute_command("nbgrader release_assignment 'Problem Set 1' --course 'abc101' --force");
784+
await execute_command("nbgrader generate_assignment 'ps.01' --force");
785+
await execute_command("nbgrader release_assignment 'ps.01' --course 'xyz 200' --force");
786+
787+
// refresh assignment list
788+
await page.locator('#refresh_assignments_list').click();
789+
790+
// select one course
791+
await select_course(page, 'xyz 200');
792+
793+
// check that there is only one released, and fetch it
794+
var rows = await wait_for_list(page, 'released', 1);
795+
await rows.first().locator('.item_status button').click();
796+
797+
// check that there is only one fetched and submit
798+
rows = await wait_for_list(page, 'fetched', 1);
799+
await rows.first().locator('.item_status button:text("Submit")').click();
800+
801+
// collect submitted assignment and process it
802+
await execute_command("nbgrader collect 'ps.01' --course 'xyz 200'");
803+
await execute_command("nbgrader autograde 'ps.01' --course 'xyz 200'");
804+
await execute_command("nbgrader generate_feedback 'ps.01' --course 'xyz 200'");
805+
await execute_command("nbgrader release_feedback 'ps.01' --course 'xyz 200'");
806+
807+
// check that there is only one submitted and fetch feedback
808+
rows = await wait_for_list(page, 'submitted', 1);
809+
await rows.first().locator('.item_status button:text("Fetch feedback")').click();
810+
811+
// check that there is only one fetched
812+
rows = await wait_for_list(page, 'submitted', 1);
813+
expect(rows.first().locator('.item_name').first()).toHaveText("ps.01");
814+
expect(rows.first().locator('.item_course').first()).toHaveText("xyz 200");
815+
816+
// check that the directory has been created
817+
const contents = galata.newContentsHelper(baseURL);
818+
expect(contents.directoryExists('ps.01/feedback'));
819+
});
820+
821+
/*
822+
* Test fetch feedback failure
823+
*/
824+
test('Fetch feedback failure', async({
825+
page,
826+
baseURL,
827+
tmpPath
828+
}) => {
829+
830+
test.skip(is_windows, 'This feature is not implemented for Windows');
831+
832+
if (baseURL === undefined) throw new Error("BaseURL is undefined.");
833+
834+
// create directories and config files, and open assignment_list tab
835+
await create_env(page, tmpPath, exchange_dir, cache_dir, is_windows);
836+
await add_courses(page, baseURL, tmpPath);
837+
await open_assignment_list(page);
838+
839+
// release some assignments
840+
await execute_command("nbgrader generate_assignment 'Problem Set 1' --force");
841+
await execute_command("nbgrader release_assignment 'Problem Set 1' --course 'abc101' --force");
842+
await execute_command("nbgrader generate_assignment 'ps.01' --force");
843+
await execute_command("nbgrader release_assignment 'ps.01' --course 'xyz 200' --force");
844+
845+
// refresh assignment list
846+
await page.locator('#refresh_assignments_list').click();
847+
848+
// select one course
849+
await select_course(page, 'xyz 200');
850+
851+
// check that there is only one released, and fetch it
852+
var rows = await wait_for_list(page, 'released', 1);
853+
await rows.first().locator('.item_status button').click();
854+
855+
// check that there is only one fetched and submit
856+
rows = await wait_for_list(page, 'fetched', 1);
857+
await rows.first().locator('.item_status button:text("Submit")').click();
858+
859+
// collect submitted assignment and process it
860+
await execute_command("nbgrader collect 'ps.01' --course 'xyz 200'");
861+
await execute_command("nbgrader autograde 'ps.01' --course 'xyz 200'");
862+
await execute_command("nbgrader generate_feedback 'ps.01' --course 'xyz 200'");
863+
await execute_command("nbgrader release_feedback 'ps.01' --course 'xyz 200'");
864+
865+
// check that there is only one submitted and try fetching feedback
866+
await fs.chmod("nbgrader-assignment-list-test/ps.01", 0o555, err => {console.log(err)});
867+
rows = await wait_for_list(page, 'submitted', 1);
868+
await rows.first().locator('.item_status button:text("Fetch Feedback")').click();
869+
await new Promise(resolve => setTimeout(resolve, 5000)); // to make sure permissions are not restored too fast
870+
await fs.chmod("nbgrader-assignment-list-test/ps.01", 0o755, err => {});
871+
872+
// Check and close the error message
873+
await wait_for_error_modal(page);
874+
await close_error_modal(page);
875+
});

nbgrader/tests/nbextensions/test_assignment_list.py

+62
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,68 @@ def test_validate_failure(browser, port, class_files, tempdir):
468468
_dismiss_modal(browser)
469469

470470

471+
@pytest.mark.nbextensions
472+
@notwindows
473+
def test_fetch_failure(browser, port, class_files, tempdir):
474+
# remove already fetched assignment to try fetching again
475+
shutil.rmtree('ps.01')
476+
_load_assignments_list(browser, port)
477+
_wait_until_loaded(browser)
478+
479+
# choose the course "xyz 200"
480+
_change_course(browser, "xyz 200")
481+
482+
# remove write permissions, click the "fetch" button, and restore permissions
483+
os.chmod(tempdir, 0o555)
484+
rows = _wait_for_list(browser, "released", 1)
485+
rows[0].find_element(By.CSS_SELECTOR, ".item_status button").click()
486+
os.chmod(tempdir, 0o755)
487+
488+
# wait for the modal dialog to appear
489+
_wait_for_modal(browser)
490+
491+
# check that error message is given
492+
modal = browser.find_element(By.ID, "fetch-message")
493+
assert modal.text[:23] == "Assignment not fetched:"
494+
495+
# close the modal dialog
496+
_dismiss_modal(browser)
497+
498+
499+
@pytest.mark.nbextensions
500+
@notwindows
501+
def test_fetch_feedback_failure(browser, port, class_files, tempdir):
502+
_load_assignments_list(browser, port)
503+
_wait_until_loaded(browser)
504+
505+
# generate fetchable feedback
506+
run_nbgrader(["fetch_assignment", "ps.01", "--course", "xyz 200"])
507+
run_nbgrader(["submit", "ps.01", "--course", "xyz 200"])
508+
run_nbgrader(["collect", "ps.01", "--course", "xyz 200"])
509+
run_nbgrader(["autograde", "ps.01", "--course", "xyz 200"])
510+
run_nbgrader(["generate_feedback", "ps.01", "--course", "xyz 200"])
511+
run_nbgrader(["release_feedback", "ps.01", "--course", "xyz 200"])
512+
513+
# choose the course "xyz 200"
514+
_change_course(browser, "xyz 200")
515+
516+
# try fetching feedback without write permissions
517+
os.chmod(os.path.join(tempdir, "ps.01"), 0o555)
518+
rows = _wait_for_list(browser, "submitted", 1)
519+
rows[0].find_element(By.CSS_SELECTOR, ".item_status button").click()
520+
os.chmod(os.path.join(tempdir, "ps.01"), 0o755)
521+
522+
# wait for the modal dialog to appear
523+
_wait_for_modal(browser)
524+
525+
# check that error message is given
526+
modal = browser.find_element(By.ID, "fetchfeedback-message")
527+
assert modal.text[:21] == "Feedback not fetched:"
528+
529+
# close the modal dialog
530+
_dismiss_modal(browser)
531+
532+
471533
@pytest.mark.nbextensions
472534
@notwindows
473535
def test_missing_exchange(exchange, browser, port, class_files, tempdir):

0 commit comments

Comments
 (0)