001: /**********************************************************************************
002: *
003: * $Id: GradeManagerTest.java 22226 2007-03-06 17:42:53Z ray@media.berkeley.edu $
004: *
005: ***********************************************************************************
006: *
007: * Copyright (c) 2005 The Regents of the University of California, The MIT Corporation
008: *
009: * Licensed under the Educational Community License, Version 1.0 (the "License");
010: * you may not use this file except in compliance with the License.
011: * You may obtain a copy of the License at
012: *
013: * http://www.opensource.org/licenses/ecl1.php
014: *
015: * Unless required by applicable law or agreed to in writing, software
016: * distributed under the License is distributed on an "AS IS" BASIS,
017: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018: * See the License for the specific language governing permissions and
019: * limitations under the License.
020: *
021: **********************************************************************************/package org.sakaiproject.tool.gradebook.test;
022:
023: import java.util.ArrayList;
024: import java.util.Arrays;
025: import java.util.Date;
026: import java.util.HashMap;
027: import java.util.HashSet;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Map;
031: import java.util.Set;
032:
033: import junit.framework.Assert;
034:
035: import org.sakaiproject.tool.gradebook.Assignment;
036: import org.sakaiproject.tool.gradebook.AssignmentGradeRecord;
037: import org.sakaiproject.tool.gradebook.CourseGrade;
038: import org.sakaiproject.tool.gradebook.CourseGradeRecord;
039: import org.sakaiproject.tool.gradebook.GradeMapping;
040: import org.sakaiproject.tool.gradebook.Gradebook;
041: import org.sakaiproject.tool.gradebook.GradingEvents;
042:
043: /**
044: * Tests the grade manager.
045: *
046: */
047: public class GradeManagerTest extends GradebookTestBase {
048: protected Gradebook gradebook;
049:
050: protected void onSetUpInTransaction() throws Exception {
051: super .onSetUpInTransaction();
052:
053: String gradebookName = this .getClass().getName();
054: gradebookFrameworkService.addGradebook(gradebookName,
055: gradebookName);
056:
057: // Set up a holder for enrollments, teaching assignments, and sections.
058: integrationSupport.createCourse(gradebookName, gradebookName,
059: false, false, false);
060:
061: // Grab the gradebook for use in the tests
062: gradebook = gradebookManager.getGradebook(gradebookName);
063: }
064:
065: public void testGradeManager() throws Exception {
066: List studentUidsList = Arrays.asList(new String[] {
067: "testStudentUserUid1", "testStudentUserUid2",
068: "testStudentUserUid3", });
069: addUsersEnrollments(gradebook, studentUidsList);
070:
071: gradebookManager.createAssignment(gradebook.getId(),
072: "Assignment #1", new Double(20), new Date(),
073: Boolean.FALSE, Boolean.FALSE);
074: Assignment persistentAssignment = (Assignment) gradebookManager
075: .getAssignmentsWithStats(gradebook.getId(),
076: Assignment.DEFAULT_SORT, true).get(0);
077:
078: Map studentAssignmentScoreMap = new HashMap();
079: studentAssignmentScoreMap.put(studentUidsList.get(0),
080: new Double(18));
081: studentAssignmentScoreMap.put(studentUidsList.get(1),
082: new Double(19));
083: studentAssignmentScoreMap.put(studentUidsList.get(2),
084: new Double(20));
085: Map gradeRecordMap = new HashMap();
086: gradeRecordMap.put(studentUidsList.get(0),
087: new AssignmentGradeRecord(persistentAssignment,
088: (String) studentUidsList.get(0),
089: (Double) studentAssignmentScoreMap
090: .get(studentUidsList.get(0))));
091: gradeRecordMap.put(studentUidsList.get(1),
092: new AssignmentGradeRecord(persistentAssignment,
093: (String) studentUidsList.get(1),
094: (Double) studentAssignmentScoreMap
095: .get(studentUidsList.get(1))));
096: gradeRecordMap.put(studentUidsList.get(2),
097: new AssignmentGradeRecord(persistentAssignment,
098: (String) studentUidsList.get(2),
099: (Double) studentAssignmentScoreMap
100: .get(studentUidsList.get(2))));
101:
102: gradebookManager.updateAssignmentGradeRecords(
103: persistentAssignment, gradeRecordMap.values());
104:
105: // Fetch the grade records
106: List records = gradebookManager.getAssignmentGradeRecords(
107: persistentAssignment, studentUidsList);
108:
109: // Ensure that each of the students in the map have a grade record, and
110: // that their grade is correct
111: Set students = new HashSet(studentUidsList);
112: for (Iterator iter = records.iterator(); iter.hasNext();) {
113: AssignmentGradeRecord agr = (AssignmentGradeRecord) iter
114: .next();
115: double tmpScore = ((AssignmentGradeRecord) gradeRecordMap
116: .get(agr.getStudentId())).getPointsEarned()
117: .doubleValue();
118: double persistentScore = agr.getPointsEarned()
119: .doubleValue();
120: Assert.assertTrue(tmpScore == persistentScore);
121: }
122:
123: // Add overrides to the course grades
124: CourseGrade courseGrade = gradebookManager
125: .getCourseGrade(gradebook.getId());
126: records = gradebookManager.getPointsEarnedCourseGradeRecords(
127: courseGrade, students);
128:
129: gradeRecordMap = new HashMap();
130: for (Iterator iter = records.iterator(); iter.hasNext();) {
131: CourseGradeRecord record = (CourseGradeRecord) iter.next();
132: if (record.getStudentId().equals(studentUidsList.get(0))) {
133: record.setEnteredGrade("C-");
134: } else if (record.getStudentId().equals(
135: studentUidsList.get(1))) {
136: record.setEnteredGrade("D+");
137: } else if (record.getStudentId().equals(
138: studentUidsList.get(2))) {
139: record.setEnteredGrade("F");
140: }
141: gradeRecordMap.put(record.getStudentId(), record);
142: }
143:
144: gradebookManager.updateCourseGradeRecords(courseGrade,
145: gradeRecordMap.values());
146:
147: GradeMapping gradeMapping = gradebook.getSelectedGradeMapping();
148:
149: // Ensure that the sort grades have been updated to reflect the overridden grades
150: List courseGradeRecords = gradebookManager
151: .getPointsEarnedCourseGradeRecords(courseGrade,
152: studentUidsList);
153: for (Iterator iter = courseGradeRecords.iterator(); iter
154: .hasNext();) {
155: CourseGradeRecord cgr = (CourseGradeRecord) iter.next();
156: Double sortGrade = cgr.getGradeAsPercentage();
157: String studentId = cgr.getStudentId();
158: String tmpGrade = ((CourseGradeRecord) gradeRecordMap
159: .get(studentId)).getEnteredGrade();
160: if (logger.isDebugEnabled())
161: logger.debug("sortGrade=" + sortGrade
162: + ", gradeMapping=" + gradeMapping
163: + ", tmpGrade=" + tmpGrade);
164:
165: Assert.assertTrue(sortGrade.equals(gradeMapping
166: .getValue(tmpGrade)));
167: Assert.assertTrue(gradeMapping.getGrade(
168: cgr.getGradeAsPercentage()).equals(tmpGrade));
169: }
170:
171: // Remove the overrides
172: gradeRecordMap = new HashMap();
173: for (Iterator iter = records.iterator(); iter.hasNext();) {
174: CourseGradeRecord record = (CourseGradeRecord) iter.next();
175: record.setEnteredGrade(null);
176: gradeRecordMap.put(record.getStudentId(), record);
177: }
178:
179: gradebookManager.updateCourseGradeRecords(courseGrade,
180: gradeRecordMap.values());
181:
182: // Ensure that the sort grades have been updated
183: courseGradeRecords = gradebookManager
184: .getPointsEarnedCourseGradeRecords(courseGrade,
185: studentUidsList);
186: double totalPoints = gradebookManager.getTotalPoints(gradebook
187: .getId());
188:
189: for (Iterator iter = courseGradeRecords.iterator(); iter
190: .hasNext();) {
191: CourseGradeRecord cgr = (CourseGradeRecord) iter.next();
192: double percent = ((Double) studentAssignmentScoreMap
193: .get(cgr.getStudentId())).doubleValue()
194: / totalPoints * 100.0;
195: Double sortGrade = cgr.getGradeAsPercentage();
196: Assert.assertTrue(sortGrade.doubleValue() - percent < .001);
197: }
198: }
199:
200: public void testNewExcessiveScores() throws Exception {
201: List studentUidsList = Arrays.asList(new String[] {
202: "normalStudent", "goodStudent", "excessiveStudent", });
203: addUsersEnrollments(gradebook, studentUidsList);
204:
205: gradebookManager.createAssignment(gradebook.getId(),
206: "Excessive Test", new Double(10), new Date(),
207: Boolean.FALSE, Boolean.FALSE);
208: Assignment asn = (Assignment) gradebookManager
209: .getAssignmentsWithStats(gradebook.getId(),
210: Assignment.DEFAULT_SORT, true).get(0);
211:
212: // Create a grade record set
213: List gradeRecords = new ArrayList();
214: gradeRecords.add(new AssignmentGradeRecord(asn,
215: "normalStudent", new Double(9)));
216: gradeRecords.add(new AssignmentGradeRecord(asn, "goodStudent",
217: new Double(10)));
218: gradeRecords.add(new AssignmentGradeRecord(asn,
219: "excessiveStudent", new Double(11)));
220:
221: Set excessives = gradebookManager.updateAssignmentGradeRecords(
222: asn, gradeRecords);
223: Assert.assertTrue(excessives.size() == 1);
224: Assert.assertTrue(excessives.contains("excessiveStudent"));
225: }
226:
227: public void testAssignmentScoresEntered() throws Exception {
228: Set students = new HashSet();
229: students.add("entered1");
230:
231: Long asgId = gradebookManager.createAssignment(gradebook
232: .getId(), "Scores Entered Test", new Double(10),
233: new Date(), Boolean.FALSE, Boolean.FALSE);
234: Assignment asn = (Assignment) gradebookManager
235: .getAssignmentsWithStats(gradebook.getId(),
236: Assignment.DEFAULT_SORT, true).get(0);
237:
238: Assert.assertTrue(!gradebookManager
239: .isEnteredAssignmentScores(asgId));
240:
241: List gradeRecords = new ArrayList();
242: gradeRecords.add(new AssignmentGradeRecord(asn, "entered1",
243: new Double(9)));
244:
245: gradebookManager
246: .updateAssignmentGradeRecords(asn, gradeRecords);
247: Assert.assertTrue(gradebookManager
248: .isEnteredAssignmentScores(asgId));
249:
250: List persistentGradeRecords = gradebookManager
251: .getAssignmentGradeRecords(asn, students);
252:
253: gradeRecords = new ArrayList();
254: AssignmentGradeRecord gradeRecord = (AssignmentGradeRecord) persistentGradeRecords
255: .get(0);
256: gradeRecord.setPointsEarned(null);
257: gradeRecords.add(gradeRecord);
258:
259: gradebookManager
260: .updateAssignmentGradeRecords(asn, gradeRecords);
261: Assert.assertTrue(!gradebookManager
262: .isEnteredAssignmentScores(asgId));
263: }
264:
265: public void testGradeEvents() throws Exception {
266: String studentId = "student1";
267: List studentUidsList = Arrays
268: .asList(new String[] { studentId, });
269: gradebookManager.createAssignment(gradebook.getId(),
270: "GradingEvent Test", new Double(10), new Date(),
271: Boolean.FALSE, Boolean.FALSE);
272: Assignment assignment = (Assignment) gradebookManager
273: .getAssignments(gradebook.getId()).get(0);
274:
275: // Create a map of studentUserUids to grades
276: List gradeRecords = new ArrayList();
277: gradeRecords.add(new AssignmentGradeRecord(assignment,
278: studentId, new Double(9)));
279:
280: // Save the grades
281: gradebookManager.updateAssignmentGradeRecords(assignment,
282: gradeRecords);
283:
284: // Update the grades (make sure we grab them from the db, first)
285: Set students = new HashSet();
286: students.add(studentId);
287: List persistentGradeRecords = gradebookManager
288: .getAssignmentGradeRecords(assignment, students);
289:
290: gradeRecords = new ArrayList();
291: AssignmentGradeRecord gradeRecord = (AssignmentGradeRecord) persistentGradeRecords
292: .get(0);
293: gradeRecord.setPointsEarned(new Double(10));
294: gradeRecords.add(gradeRecord);
295:
296: gradebookManager.updateAssignmentGradeRecords(assignment,
297: gradeRecords);
298:
299: // Ensure that there are two grading events for this student
300: GradingEvents events = gradebookManager.getGradingEvents(
301: assignment, studentUidsList);
302: Assert.assertEquals(events.getEvents(studentId).size(), 2);
303: }
304:
305: public void testDroppedStudents() throws Exception {
306: Gradebook gradebook = gradebookManager.getGradebook(this
307: .getClass().getName());
308: Long asgId = gradebookManager.createAssignment(gradebook
309: .getId(), "Dropped Students Test", new Double(10),
310: new Date(), Boolean.FALSE, Boolean.FALSE);
311: Assignment asn = gradebookManager.getAssignment(asgId);
312:
313: // We need to operate on whatever grade records already exist in the db
314: List studentUidsList = Arrays.asList(new String[] {
315: "realStudent1", "realStudent2", });
316: addUsersEnrollments(gradebook, studentUidsList);
317:
318: // Create a grade record set
319: List gradeRecords = new ArrayList();
320: gradeRecords.add(new AssignmentGradeRecord(asn, "realStudent1",
321: new Double(10)));
322: gradeRecords.add(new AssignmentGradeRecord(asn, "realStudent2",
323: new Double(10)));
324: gradeRecords.add(new AssignmentGradeRecord(asn,
325: "droppedStudent", new Double(1)));
326:
327: gradebookManager
328: .updateAssignmentGradeRecords(asn, gradeRecords);
329:
330: asn = gradebookManager.getAssignmentWithStats(asgId);
331:
332: // Make sure the dropped student wasn't included in the average.
333: Assert.assertTrue(asn.getMean().doubleValue() == 100.0);
334:
335: // Now add the dropped student.
336: studentUidsList = Arrays
337: .asList(new String[] { "droppedStudent", });
338: addUsersEnrollments(gradebook, studentUidsList);
339:
340: asn = gradebookManager.getAssignmentWithStats(asgId);
341: Assert.assertTrue(asn.getMean().doubleValue() < 100.0);
342:
343: // Make sure that dropped students can't prevent changing final grade types.
344: CourseGrade courseGrade = getCourseGradeWithStats(gradebook
345: .getId());
346: gradeRecords = new ArrayList();
347: CourseGradeRecord courseGradeRecord = new CourseGradeRecord(
348: courseGrade, "noSuchStudent");
349: courseGradeRecord.setEnteredGrade("C-");
350: gradeRecords.add(courseGradeRecord);
351: gradebookManager.updateCourseGradeRecords(courseGrade,
352: gradeRecords);
353: Assert.assertFalse(gradebookManager
354: .isExplicitlyEnteredCourseGradeRecords(gradebook
355: .getId()));
356: }
357:
358: public void testNotCountedAssignments() throws Exception {
359: List studentUidsList = Arrays
360: .asList(new String[] { "testStudentUserUid1", });
361: addUsersEnrollments(gradebook, studentUidsList);
362:
363: Long id1 = gradebookManager.createAssignment(gradebook.getId(),
364: "asn1", new Double(10), null, Boolean.FALSE,
365: Boolean.TRUE);
366: Long id2 = gradebookManager.createAssignment(gradebook.getId(),
367: "asn2", new Double(20), new Date(10), Boolean.FALSE,
368: Boolean.TRUE);
369:
370: Assignment asn1 = gradebookManager.getAssignmentWithStats(id1);
371: Assignment asn2 = gradebookManager.getAssignmentWithStats(id2);
372:
373: // Add some scores to the assignments.
374: List gradeRecords = new ArrayList();
375: gradeRecords.add(new AssignmentGradeRecord(asn1,
376: (String) studentUidsList.get(0), new Double(8)));
377: gradebookManager.updateAssignmentGradeRecords(asn1,
378: gradeRecords);
379: gradeRecords = new ArrayList();
380: gradeRecords.add(new AssignmentGradeRecord(asn2,
381: (String) studentUidsList.get(0), new Double(18)));
382: gradebookManager.updateAssignmentGradeRecords(asn2,
383: gradeRecords);
384:
385: // Make sure that the Course Grade total points includes both.
386: CourseGrade courseGrade = getCourseGradeWithStats(gradebook
387: .getId());
388: List courseGradeRecords = gradebookManager
389: .getPointsEarnedCourseGradeRecords(courseGrade,
390: studentUidsList);
391: CourseGradeRecord cgr = (CourseGradeRecord) courseGradeRecords
392: .get(0);
393: Assert.assertTrue(cgr.getPointsEarned().doubleValue() == 26.0);
394:
395: // Don't count one assignment.
396: asn2.setNotCounted(true);
397: gradebookManager.updateAssignment(asn2);
398:
399: // Get what the student will see.
400: CourseGradeRecord scgr = gradebookManager
401: .getStudentCourseGradeRecord(gradebook,
402: (String) studentUidsList.get(0));
403:
404: // Make sure it's not counted.
405: courseGrade = getCourseGradeWithStats(gradebook.getId());
406: courseGradeRecords = gradebookManager
407: .getPointsEarnedCourseGradeRecords(courseGrade,
408: studentUidsList);
409: cgr = (CourseGradeRecord) courseGradeRecords.get(0);
410: Assert.assertTrue(cgr.getPointsEarned().doubleValue() == 8.0);
411:
412: // Make sure there's no disconnect between what the instructor
413: // will see and what the student will see.
414: Assert.assertTrue(cgr.getNonNullAutoCalculatedGrade().equals(
415: scgr.getGradeAsPercentage()));
416:
417: // Test what is now (unfortunately) a different code path.
418: List persistentGradeRecords = gradebookManager
419: .getAssignmentGradeRecords(asn1, studentUidsList);
420: AssignmentGradeRecord gradeRecord = (AssignmentGradeRecord) persistentGradeRecords
421: .get(0);
422: gradeRecord.setPointsEarned(new Double(7));
423: gradeRecords = new ArrayList();
424: gradeRecords.add(gradeRecord);
425: gradebookManager.updateAssignmentGradeRecords(asn1,
426: gradeRecords);
427: courseGradeRecords = gradebookManager
428: .getPointsEarnedCourseGradeRecords(courseGrade,
429: studentUidsList);
430: cgr = (CourseGradeRecord) courseGradeRecords.get(0);
431: Assert.assertTrue(cgr.getPointsEarned().doubleValue() == 7.0);
432: }
433:
434: /**
435: * This tests an edge case responsible for an earlier bug: If an unscored assignment
436: * changes whether it's counted towards the course grade, all course grades need
437: * to be recalculated because the total points possible have changed.
438: */
439: public void testNotCountedUnscoredAssignments() throws Exception {
440: List studentUidsList = Arrays
441: .asList(new String[] { "testStudentUserUid1", });
442: addUsersEnrollments(gradebook, studentUidsList);
443:
444: Long id1 = gradebookManager.createAssignment(gradebook.getId(),
445: "asn1", new Double(10), null, Boolean.FALSE,
446: Boolean.FALSE);
447: Long id2 = gradebookManager.createAssignment(gradebook.getId(),
448: "asn2", new Double(20), new Date(10), Boolean.FALSE,
449: Boolean.FALSE);
450:
451: Assignment asn1 = gradebookManager.getAssignmentWithStats(id1);
452: Assignment asn2 = gradebookManager.getAssignmentWithStats(id2);
453:
454: // Only score the first assignment.
455: List gradeRecords = new ArrayList();
456: gradeRecords.add(new AssignmentGradeRecord(asn1,
457: (String) studentUidsList.get(0), new Double(8)));
458: gradebookManager.updateAssignmentGradeRecords(asn1,
459: gradeRecords);
460:
461: // Don't count the unscored assignment.
462: asn2.setNotCounted(true);
463: gradebookManager.updateAssignment(asn2);
464:
465: // Get what the student will see.
466: CourseGradeRecord scgr = gradebookManager
467: .getStudentCourseGradeRecord(gradebook,
468: (String) studentUidsList.get(0));
469:
470: // Make sure it's not counted.
471: CourseGrade courseGrade = getCourseGradeWithStats(gradebook
472: .getId());
473: List courseGradeRecords = gradebookManager
474: .getPointsEarnedCourseGradeRecords(courseGrade,
475: studentUidsList);
476: CourseGradeRecord cgr = (CourseGradeRecord) courseGradeRecords
477: .get(0);
478: Assert.assertTrue(cgr.getPointsEarned().doubleValue() == 8.0);
479:
480: // Make sure there's no disconnect between what the instructor
481: // will see and what the student will see.
482: Assert.assertTrue(cgr.getNonNullAutoCalculatedGrade().equals(
483: scgr.getGradeAsPercentage()));
484: }
485:
486: }
|