Skip to content

Commit

Permalink
Add more tests for instructor permissions to fetch ddahs (#599)
Browse files Browse the repository at this point in the history
More tests for fetching DDAHs for instructor. Related to issue #597
  • Loading branch information
alex-kozin authored Jun 20, 2021
1 parent a64715b commit 0cffc80
Show file tree
Hide file tree
Showing 3 changed files with 336 additions and 88 deletions.
5 changes: 3 additions & 2 deletions frontend/src/tests/ddah-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ export function ddahTests(api) {
it("get all ddahs associated with a session", async () => {
let resp = await apiGET(`/admin/sessions/${session.id}/ddahs`);
expect(resp).toHaveStatus("success");
// Originally only one ddah is seeded
expect(resp.payload.length).toEqual(1);
// Originally two ddahs are seeded and
// another one is added in this test suite
expect(resp.payload.length).toEqual(3);
expect(resp.payload).toContainObject(ddah);
});

Expand Down
292 changes: 206 additions & 86 deletions frontend/src/tests/instructor-permission-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,55 +46,6 @@ export function instructorsPermissionTests(api) {
expect(respSwitchBackUser).toHaveStatus("success");
}

/**
* Updates a position to include instructor with `instructorId` and
* creates a DDAH for one of the assignments realted to that
* instructor.
*
* @param instructorId: int - the unique Id of an instructor
*
* @returns {Promise<Ddah>}
*/
async function createDdahWithFixedDuties(instructorId) {
// We first need to update position to include our instructor
const existingPosition = databaseSeeder.seededData.positions[0];
const positionWithInstructor = {
...existingPosition,
instructor_ids: [...existingPosition.instructor_ids, instructorId],
};
let resp = await apiPOST(`/admin/positions`, positionWithInstructor);
expect(resp).toHaveStatus("success");

// We then proceed to create a DDAH for that position
resp = await apiGET(`/instructor/sessions/${session.id}/assignments`);
expect(resp).toHaveStatus("success");
expect(resp.payload.length).toBeGreaterThan(0);
const newDdah = {
assignment_id: resp.payload[0].id,
duties: [
{
order: 2,
hours: 25,
description: "marking:Marking the midterm",
},
{
order: 1,
hours: 4,
description: "training:Initial training",
},
{
order: 3,
hours: 40,
description: "contact:Running tutorials",
},
],
};

resp = await apiPOST(`/admin/ddahs`, newDdah);
expect(resp).toHaveStatus("success");
return resp.payload;
}

beforeAll(async () => {
await databaseSeeder.seed(api);
await databaseSeeder.seedForInstructors(api);
Expand All @@ -116,7 +67,7 @@ export function instructorsPermissionTests(api) {
existingContractTemplateId = resp.payload[0].id;

const instructorOnlyUserData = {
utorid: "instructor_only_test_user_utorid",
...databaseSeeder.seededData.instructors[3],
roles: ["instructor"],
};

Expand Down Expand Up @@ -524,43 +475,212 @@ export function instructorsPermissionTests(api) {
await restoreDefaultUser();
});

it("fetch Ddahs", async () => {
// If a user is not in Instructors table, it is not considered an instructor
// for the purpose of fetching DDAHs - so we create one
const newInstructor = {
first_name: "Jane",
last_name: "Smith",
email: "[email protected]",
utorid: instructorUser.utorid,
};
let resp = await apiPOST(`/admin/instructors`, newInstructor);
expect(resp).toHaveStatus("success");
describe("Ddah permissions", () => {
let position = databaseSeeder.seededData.positions[3];
let assignment;
let assignmentInstructorCantAccess;

beforeAll(async () => {
await restoreDefaultUser();

// Create another assignment (with no DDAH)
// for position associated with our instructor
const newAssignment = {
applicant_id: databaseSeeder.seededData.applicant.id,
position_id: position.id,
start_date: "2019-09-02T00:00:00.000Z",
end_date: "2019-12-31T00:00:00.000Z",
};
let resp = await apiPOST("/admin/assignments", newAssignment);
expect(resp).toHaveStatus("success");
expect(resp.payload).toBeDefined();
assignment = resp.payload;

// Create another assignment (with no DDAH)
// for position associated with other instructor
const otherPosition = databaseSeeder.seededData.positions[4];
const otherAssignment = {
note: "",
applicant_id: databaseSeeder.seededData.applicant.id,
position_id: otherPosition.id,
start_date: "2019-09-02T00:00:00.000Z",
end_date: "2019-12-31T00:00:00.000Z",
};
resp = await apiPOST("/admin/assignments", otherAssignment);
expect(resp).toHaveStatus("success");
assignmentInstructorCantAccess = resp.payload;
});

// Get newly created instructor and create a DDAH for them
resp = await apiGET(`/admin/instructors`);
expect(resp).toHaveStatus("success");
const instructorId = resp.payload.find(
(instructor) => instructor.utorid === instructorUser.utorid
)?.id;
expect(instructorId).toBeDefined();
const newDDAH = await createDdahWithFixedDuties(instructorId);
beforeEach(async () => {
await switchToInstructorOnlyUser();
});

// Test the DDAH is fetched properly
await switchToInstructorOnlyUser();
resp = await apiGET(`/instructor/sessions/${session.id}/ddahs`);
expect(resp).toHaveStatus("success");
expect(resp.payload).toHaveLength(1);
expect(resp.payload[0]).toStrictEqual(newDDAH);
});
it("fetch Ddahs associated with self only", async () => {
// Our instructor should only be able to fetch ddahs associated with them
const resp = await apiGET(
`/instructor/sessions/${session.id}/ddahs`
);
expect(resp).toHaveStatus("success");

// Only one DDAH is intially seeded for this instructor
expect(resp.payload).toHaveLength(1);

// We get duties returned sorted in ascending order, so
// we need to sort the seeded ones before comparing
const sortedSeededDuties = databaseSeeder.seededData.ddahs[0].duties.sort(
(first, second) => first.order - second.order
);
const firstDdah = resp.payload[0];
expect(firstDdah.duties).toEqual(sortedSeededDuties);
});

it("create a Ddah for an assignment associated with self", async () => {
const ddahToCreate = {
// This assignment has no DDAH initially
assignment_id: assignment.id,
duties: [
{
order: 1,
hours: 20,
description: "other:Facilitating workshops",
},
{
order: 2,
hours: 50,
description: "other:Lecture support",
},
],
};
let resp = await apiPOST(`/instructor/ddahs`, ddahToCreate);
expect(resp).toHaveStatus("success");
expect(resp.payload).toEqual(expect.objectContaining(ddahToCreate));

// Test we can fetch both DDAHs now: the seeded one and the newly created one
resp = await apiGET(`/instructor/sessions/${session.id}/ddahs`);
expect(resp).toHaveStatus("success");
expect(resp.payload).toHaveLength(2);
});

it.todo("fetch Ddahs a position associated with self");
it.todo("fetch Ddahs an assignment associated with self");
it.todo("cannot fetch Ddahs for assignment not associated with self");
it.todo("create a Ddah for an assignment associated with self");
it.todo("update a Ddah for an assignment associated with self");
it.todo(
"cannot set approved_date/accepted_date/revised_date/emailed_ate/signature for a Ddah associated with self"
);
it.todo("cannot create a Ddah for an assignment not associated with self");
it.todo("cannot update a Ddah for an assignment not associated with self");
it("update a Ddah for an assignment associated with self", async () => {
// Fetch the first assignment associated with our instructor
let resp = await apiGET(
`/instructor/sessions/${session.id}/assignments`
);
expect(resp).toHaveStatus("success");
const assignment_id = resp.payload[0].id;

// Update the DDAH and check it was updated correctly
const updatedDdah = {
assignment_id,
duties: [
{
order: 1,
hours: 20,
description: "marking:Test Marking",
},
{
order: 2,
hours: 50,
description: "other:Additional duties",
},
],
};
resp = await apiPOST(`/instructor/ddahs`, updatedDdah);
expect(resp).toHaveStatus("success");
expect(resp.payload).toEqual(expect.objectContaining(updatedDdah));
});

// This test indeed fails and allows to set these fields, check Issue #608
it.skip("cannot set approved_date/accepted_date/revised_date/emailed_date/signature for a Ddah associated with self", async () => {
// Fetch the DDAH related to instructor's assignment
let resp = await apiGET(`/instructor/sessions/${session.id}/ddahs`);
expect(resp).toHaveStatus("success");
const originalDdah = resp.payload.find(
(ddah) => ddah.assignment_id === assignment.id
);

// Update the DDAH and check it was updated correctly
const ddahWithRestrictedFields = {
assignment_id: assignment.id,
duties: [
{
order: 1,
hours: 40,
description: "marking:Test Marking",
},
{
order: 2,
hours: 30,
description: "other:Additional duties",
},
],
approved_date: new Date().toISOString(),
accepted_date: "2020-09-02T00:00:00.000Z",
revised_date: "2020-09-01T00:00:00.000Z",
emailed_date: "2020-08-28T00:00:00.000Z",
signature: "Harry Potter",
};
resp = await apiPOST(`/instructor/ddahs`, ddahWithRestrictedFields);
expect(resp).toHaveStatus("success");
expect(resp.payload).toEqual(expect.objectContaining(originalDdah));

resp = await apiGET(`/instructor/sessions/${session.id}/ddahs`);
// still a success, but does not change the underlying data
expect(resp).toHaveStatus("success");
const newDdah = resp.payload.find(
(ddah) => ddah.assignment_id === assignment.id
);
expect(newDdah).toEqual(expect.objectContaining(originalDdah));
});

it("cannot create a Ddah for an assignment not associated with self", async () => {
const ddahToCreate = {
// This assignment has no DDAH initially
assignment_id: assignmentInstructorCantAccess.id,
duties: [
{
order: 1,
hours: 20,
description: "other:Facilitating workshops",
},
],
};
let resp = await apiPOST(`/instructor/ddahs`, ddahToCreate);
expect(resp).toHaveStatus("error");
});

it("cannot update a Ddah for an assignment not associated with self", async () => {
// First we add the DDAH to the assignment
// associated with another instructor
await restoreDefaultUser();
const ddahToCreate = {
assignment_id: assignmentInstructorCantAccess.id,
duties: [
{
order: 1,
hours: 30,
description: "contact:Practice",
},
],
};
let resp = await apiPOST(`/admin/ddahs`, ddahToCreate);
expect(resp).toHaveStatus("success");

// Then we try to update the existing DDAH with our instructor
await switchToInstructorOnlyUser();
const ddahToUpdate = {
// This assignment has a DDAH initially
assignment_id: assignmentInstructorCantAccess.id,
duties: [
{
order: 1,
hours: 20,
description: "other:Facilitating workshops",
},
],
};
resp = await apiPOST(`/instructor/ddahs`, ddahToUpdate);
expect(resp).toHaveStatus("error");
});
});
}
Loading

0 comments on commit 0cffc80

Please sign in to comment.