Пример #1
0
 def setUp(self):
     faculty_test_data.Command().handle()
     self.p = Person.objects.get(userid='ggbaker')
     self.u = Unit.objects.get(id=1)
     self.date = datetime.date(2014, 1, 1)
     self.e = CareerEvent(person=self.p,
                          unit=self.u,
                          event_type="APPOINT",
                          start_date=self.date)
     self.e.get_handler().save(self.p)
Пример #2
0
class CareerEventTest(TestCase):
    def setUp(self):
        faculty_test_data.Command().handle()
        self.p = Person.objects.get(userid='ggbaker')
        self.u = Unit.objects.get(id=1)
        self.date = datetime.date(2014, 1, 1)
        self.e = CareerEvent(person=self.p,
                             unit=self.u,
                             event_type="APPOINT",
                             start_date=self.date)
        self.e.get_handler().save(self.p)

    def test_get_effective_date(self):
        events = CareerEvent.objects.effective_date(self.date)
        for e in events:
            assert e.start_date <= self.date
            assert e.end_date == None or e.end_date >= self.date

    def test_get_effective_semester(self):
        semester = Semester.objects.get(name='1141')
        events = CareerEvent.objects.effective_semester(semester)
        start, end = semester.start_end_dates(semester)
        for e in events:
            assert e.start_date >= start
            assert e.end_date == None or (e.end_date <= end
                                          and e.end_date >= start)

    def test_flag_logic(self):
        """
        Check the event.flags setting logic: flags set only if there's a real effect.
        """
        e = CareerEvent(person=self.p,
                        unit=self.u,
                        event_type="FELLOW",
                        start_date=self.date)
        e.config = {'add_salary': 0, 'add_pay': 0, 'teaching_credit': 0}
        h = e.get_handler()
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 5
        h.save(self.p)
        self.assertTrue(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 0
        e.config['teaching_credit'] = 1
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertTrue(e.flags.affects_teaching)
Пример #3
0
 def run(self):
     sems = Semester.objects.filter(name__gte='1001', name__lte=Semester.next_starting().name)
     u = Unit.objects.get(label='ENSC')
     courses = CourseOffering.objects.prefetch_related('meeting_time').filter(semester__in=sems, owner=u,
                                                                              graded=True).exclude(
         flags=CourseOffering.flags.combined).exclude(subject='DDP').order_by('semester', 'subject', 'number')
     course_history = Table()
     course_history.append_column('Semester')
     course_history.append_column('Course')
     course_history.append_column('Instructor')
     course_history.append_column('Enrolment')
     course_history.append_column('Campus')
     course_history.append_column('Joint With')
     course_history.append_column('Lecture Times')
     course_history.append_column('Instructor(s) Rank(s)')
     for course in courses:
         semester = course.semester.label()
         label = course.name()
         instr = course.instructors_printing_str()
         enrl = '%i/%i' % (course.enrl_tot, course.enrl_cap)
         if course.campus in CAMPUSES_SHORT:
             campus = CAMPUSES_SHORT[course.campus]
         else:
             campus = 'Unknown'
         if course.config.get('joint_with'):
             joint = str(', '.join(course.config.get('joint_with')))
         else:
             joint = ''
         meeting_times = ''
         mt = [t for t in course.meeting_time.all() if t.meeting_type == 'LEC']
         if mt:
             meeting_times = ', '.join(str("%s %s-%s" % (WEEKDAYS[t.weekday], t.start_time, t.end_time)) for t in mt)
         ranks = "; ".join(CareerEvent.ranks_as_of_semester(p.id, course.semester) for p in course.instructors())
         course_history.append_row([semester, label, instr, enrl, campus, joint, meeting_times, ranks])
     self.artifacts.append(course_history)
Пример #4
0
 def setUp(self):
     faculty_test_data.Command().handle()
     self.p = Person.objects.get(userid='ggbaker')
     self.u = Unit.objects.get(id=1)
     self.date = datetime.date(2014, 1, 1)
     self.e = CareerEvent(person=self.p, unit=self.u, event_type="APPOINT", start_date=self.date)
     self.e.get_handler().save(self.p)
Пример #5
0
    def test_event_types(self):
        """
        Basic tests of each event handler
        """
        fac_member = Person.objects.get(userid='ggbaker')
        fac_role = Role.objects.filter(person=fac_member)[0]
        editor = Person.objects.get(userid='dixon')
        units = Unit.objects.all()
        start_date = datetime.date(2014, 1, 1)

        for Handler in HANDLERS:
            # Make sure all required abstract methods at least overrided
            # XXX: should output the missing method on fail
            try:
                # If a handler is missing any required methods (like teaching, salary, etc),
                # then instantiation will raise an Exception. This means that there is no need
                # to explicitly check if a handler with a flag has overriden a specific base
                # mixin method.
                handler = Handler(
                    CareerEvent(person=fac_member,
                                unit=fac_role.unit,
                                start_date=start_date))
                handler.set_handler_specific_data()

                if 'affects_salary' in Handler.FLAGS:
                    self.assertTrue(issubclass(Handler, SalaryCareerEvent))
                    self.assertIsInstance(handler, SalaryCareerEvent)
                    self.assertIsInstance(handler.salary_adjust_annually(),
                                          SalaryAdjust)
                else:
                    self.assertFalse(handler.event.flags.affects_salary)

                if 'affects_teaching' in Handler.FLAGS:
                    self.assertTrue(issubclass(Handler, TeachingCareerEvent))
                    self.assertIsInstance(handler, TeachingCareerEvent)
                    self.assertIsInstance(
                        handler.teaching_adjust_per_semester(), TeachingAdjust)
                else:
                    self.assertFalse(handler.event.flags.affects_teaching)

                # test form creation
                Handler.get_entry_form(editor=editor, units=units)

                # display methods that each handler must implement
                shortsummary = handler.short_summary()
                self.assertIsInstance(shortsummary, basestring)
                self.assertNotIn(
                    '%s',
                    shortsummary)  # find these cases that shouldn't exist
                html = handler.to_html()
                self.assertIsInstance(
                    html, (safestring.SafeString, safestring.SafeText,
                           safestring.SafeUnicode))

            except:
                print "failure with Handler==%s" % (Handler)
                raise
Пример #6
0
class CareerEventTest(TestCase):
    def setUp(self):
        faculty_test_data.Command().handle()
        self.p = Person.objects.get(userid='ggbaker')
        self.u = Unit.objects.get(id=1)
        self.date = datetime.date(2014, 1, 1)
        self.e = CareerEvent(person=self.p, unit=self.u, event_type="APPOINT", start_date=self.date)
        self.e.get_handler().save(self.p)

    def test_get_effective_date(self):
        events = CareerEvent.objects.effective_date(self.date)
        for e in events:
            assert e.start_date <= self.date
            assert e.end_date == None or e.end_date >= self.date
            
    def test_get_effective_semester(self):
        semester = Semester.objects.get(name='1141')
        events = CareerEvent.objects.effective_semester(semester)
        start, end = semester.start_end_dates(semester)
        for e in events:
            assert e.start_date >= start
            assert e.end_date == None or (e.end_date <= end and e.end_date >= start)

    def test_flag_logic(self):
        """
        Check the event.flags setting logic: flags set only if there's a real effect.
        """
        e = CareerEvent(person=self.p, unit=self.u, event_type="FELLOW", start_date=self.date)
        e.config = {'add_salary': 0, 'add_pay': 0, 'teaching_credit': 0}
        h = e.get_handler()
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 5
        h.save(self.p)
        self.assertTrue(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 0
        e.config['teaching_credit'] = 1
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertTrue(e.flags.affects_teaching)
Пример #7
0
 def create_for(cls, person, form=None):
     """
     Given a person, create a new instance of the handler for them.
     """
     from faculty.models import CareerEvent
     event = CareerEvent(person=person, event_type=cls.EVENT_TYPE)
     ret = cls(event)
     if form:
         ret.load(form)
     return ret
Пример #8
0
def event_get_or_create(**kwargs):
    """
    CareerEvent.objects.get_or_create, but doesn't save and returns a Handler
    """
    try:
        e = CareerEvent.objects.get(**kwargs)
    except CareerEvent.DoesNotExist:
        e = CareerEvent(**kwargs)

    h = EVENT_TYPES[e.event_type](event=e)
    return e, h
Пример #9
0
    def test_is_exclusive_close_previous(self):
        self.Handler.IS_EXCLUSIVE = True
        handler1 = self.Handler(CareerEvent(person=self.person,
                                            unit=self.unit))
        handler1.event.title = 'hello world'
        handler1.event.start_date = date.today()
        handler1.save(self.person)

        handler2 = self.Handler(CareerEvent(person=self.person,
                                            unit=self.unit))
        handler2.event.title = 'Foobar'
        handler2.event.start_date = date.today() + timedelta(days=1)
        handler2.save(self.person)

        # XXX: handler1's event won't be automatically refreshed after we've 'closed' it
        #      so we must grab a fresh copy to verify.
        handler1_modified_event = CareerEvent.objects.get(id=handler1.event.id)

        self.assertEqual(
            handler1_modified_event.end_date,
            handler2.event.start_date - datetime.timedelta(days=1))
Пример #10
0
 def run(self):
     sems = Semester.objects.filter(name__gte='1001',
                                    name__lte=Semester.next_starting().name)
     u = Unit.objects.filter(label__in=['CMPT', 'ENSC', 'MSE'])
     courses = CourseOffering.objects.prefetch_related(
         'meeting_time').filter(
             semester__in=sems, owner__in=u, graded=True).exclude(
                 flags=CourseOffering.flags.combined).exclude(
                     subject='DDP').exclude(component='CAN').order_by(
                         'semester', 'subject', 'number')
     course_history = Table()
     course_history.append_column('Semester')
     course_history.append_column('Course')
     course_history.append_column('Units')
     course_history.append_column('Instructor')
     course_history.append_column('Enrolment')
     course_history.append_column('Campus')
     course_history.append_column('Joint With')
     course_history.append_column('Lecture Times')
     course_history.append_column('Instructor(s) Rank(s)')
     for course in courses:
         semester = course.semester.label()
         label = course.name()
         units = course.units
         instr = course.instructors_printing_str()
         enrl = '%i/%i' % (course.enrl_tot, course.enrl_cap)
         if course.campus in CAMPUSES_SHORT:
             campus = CAMPUSES_SHORT[course.campus]
         else:
             campus = 'Unknown'
         if course.config.get('joint_with'):
             joint = str(', '.join(course.config.get('joint_with')))
         else:
             joint = ''
         meeting_times = ''
         mt = [
             t for t in course.meeting_time.all() if t.meeting_type == 'LEC'
         ]
         if mt:
             meeting_times = ', '.join(
                 str("%s %s-%s" %
                     (WEEKDAYS[t.weekday], t.start_time, t.end_time))
                 for t in mt)
         ranks = "; ".join(
             CareerEvent.ranks_as_of_semester(p.id, course.semester)
             for p in course.instructors())
         course_history.append_row([
             semester, label, units, instr, enrl, campus, joint,
             meeting_times, ranks
         ])
     self.artifacts.append(course_history)
Пример #11
0
    def test_is_instant(self):
        handler = self.HandlerInstant(
            CareerEvent(person=self.person, unit=self.unit))

        # Ensure the 'end_date' field is successfully removed
        form = handler.get_entry_form(self.person, [])
        self.assertNotIn('end_date', form.fields)

        # 'end_date' should be None before saving
        handler.event.start_date = date.today()
        self.assertIsNone(handler.event.end_date)

        # 'start_date' should be equal to 'end_date' after saving
        handler.save(self.person)
        self.assertEqual(handler.event.start_date, handler.event.end_date)
 def run(self):
     sems = Semester.objects.filter(name__gte='1094', name__lte=Semester.current().offset(2).name)
     u = Unit.objects.filter(label__in=['CMPT', 'MSE', 'ENSC'])
     courses = CourseOffering.objects.prefetch_related('meeting_time').filter(semester__in=sems, owner__in=u,
                                                                              graded=True).exclude(
         flags=CourseOffering.flags.combined).exclude(subject='DDP').order_by('semester', 'subject', 'number')
     courses = list(courses)
     courses.sort(key=lambda x: (x.instructors_printing_str(), x.semester))
     course_history = Table()
     course_history.append_column('Instructor')
     course_history.append_column('Instructor(s) Rank(s)')
     course_history.append_column('School')
     course_history.append_column('Grad Students')
     course_history.append_column('Semester')
     course_history.append_column('Course')
     course_history.append_column('Enrolment')
     course_history.append_column('Campus')
     course_history.append_column('Joint With')
     course_history.append_column('Lecture Times')
     course_history.append_column('Credits')
     for course in courses:
         semester = course.semester.label()
         label = course.name()
         instr = course.instructors_printing_str()
         enrl = '%i/%i' % (course.enrl_tot, course.enrl_cap)
         unit = course.owner
         credits = course.units
         if course.campus in CAMPUSES_SHORT:
             campus = CAMPUSES_SHORT[course.campus]
         else:
             campus = 'Unknown'
         if course.config.get('joint_with'):
             joint = str(', '.join(course.config.get('joint_with')))
         else:
             joint = ''
         meeting_times = ''
         mt = [t for t in course.meeting_time.all() if t.meeting_type == 'LEC']
         if mt:
             meeting_times = ', '.join(str("%s %s-%s" % (WEEKDAYS[t.weekday], t.start_time, t.end_time)) for t in mt)
         grads = "; ".join(str(Supervisor.objects.filter(supervisor__userid=p.userid, supervisor_type='SEN', removed=False).count()) for p in course.instructors())
         ranks = "; ".join(CareerEvent.ranks_as_of_semester(p.id, course.semester) for p in course.instructors())
         course_history.append_row([instr, ranks, unit, grads, semester, label, enrl, campus, joint, meeting_times, credits])
     self.artifacts.append(course_history)
Пример #13
0
    def test_management_permissions(self):
        """
        Check that permission methods are returning as expected
        """
        fac_member = Person.objects.get(userid='ggbaker')
        dept_admin = Person.objects.get(userid='dixon')
        dean_admin = Person.objects.get(userid='dzhao')

        fac_role = Role.objects.filter(person=fac_member)[0]
        handler = SalaryModificationEventHandler(
            CareerEvent(person=fac_member, unit=fac_role.unit))

        # tests below assume these permission settings for this event type
        self.assertEqual(handler.VIEWABLE_BY, 'MEMB')
        self.assertEqual(handler.EDITABLE_BY, 'DEPT')
        self.assertEqual(handler.APPROVAL_BY, 'FAC')

        self.assertFalse(handler.can_edit(fac_member))
        self.assertTrue(handler.can_edit(dept_admin))
        self.assertTrue(handler.can_edit(dean_admin))

        self.assertFalse(handler.can_approve(fac_member))
        self.assertFalse(handler.can_approve(dept_admin))
        self.assertTrue(handler.can_approve(dean_admin))
Пример #14
0
    def test_flag_logic(self):
        """
        Check the event.flags setting logic: flags set only if there's a real effect.
        """
        e = CareerEvent(person=self.p,
                        unit=self.u,
                        event_type="FELLOW",
                        start_date=self.date)
        e.config = {'add_salary': 0, 'add_pay': 0, 'teaching_credit': 0}
        h = e.get_handler()
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 5
        h.save(self.p)
        self.assertTrue(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 0
        e.config['teaching_credit'] = 1
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertTrue(e.flags.affects_teaching)
Пример #15
0
    def test_flag_logic(self):
        """
        Check the event.flags setting logic: flags set only if there's a real effect.
        """
        e = CareerEvent(person=self.p, unit=self.u, event_type="FELLOW", start_date=self.date)
        e.config = {'add_salary': 0, 'add_pay': 0, 'teaching_credit': 0}
        h = e.get_handler()
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 5
        h.save(self.p)
        self.assertTrue(e.flags.affects_salary)
        self.assertFalse(e.flags.affects_teaching)

        e.config['add_salary'] = 0
        e.config['teaching_credit'] = 1
        h.save(self.p)
        self.assertFalse(e.flags.affects_salary)
        self.assertTrue(e.flags.affects_teaching)
    def run(self):
        sems = Semester.objects.filter(name__gte='1101',
                                       name__lte=Semester.current().name)
        u = Unit.objects.filter(label__in=['CMPT', 'MSE', 'ENSC'])
        courses = CourseOffering.objects.prefetch_related(
            'meeting_time').filter(
                semester__in=sems, owner__in=u, graded=True).exclude(
                    flags=CourseOffering.flags.combined).exclude(
                        subject='DDP').order_by('semester', 'subject',
                                                'number')

        instructors = Member.objects.filter(role='INST', added_reason='AUTO', offering__in=courses) \
            .exclude(offering__component='CAN') \
            .order_by('person__last_name', 'person__first_name', 'offering__semester__name')

        course_history = Table()
        course_history.append_column('Instructor')
        course_history.append_column('First Teaching Semester (>=1101)')
        course_history.append_column('Last Teaching Semester')
        course_history.append_column('Current Rank')
        course_history.append_column('School')
        course_history.append_column('Teaching Credits')
        course_history.append_column('Mean Headcount')
        course_history.append_column('Crs per Year')
        course_history.append_column('Unique Crs')
        course_history.append_column('Crs Levels')

        for i, memberships in itertools.groupby(instructors,
                                                key=lambda i: i.person):
            memberships = [m for m in memberships if m.teaching_credit() > 0]
            if i is None or not memberships:
                continue

            instr = i.sortname()
            first_semester = memberships[0].offering.semester
            last_semester = memberships[-1].offering.semester
            rank = CareerEvent.current_ranks(i.id)
            roles = Role.objects.filter(person=i,
                                        role='FAC').select_related('unit')
            unit = ', '.join(r.unit.label for r in roles)

            if rank == 'unknown':
                rank = 'non-faculty'
            if unit == '':
                unit = ', '.join(set(m.offering.subject for m in memberships))

            offerings = [m.offering for m in memberships]
            num_offerings = float(sum(m.teaching_credit()
                                      for m in memberships))
            headcount = sum(o.enrl_tot for o in offerings)
            duration = last_semester - first_semester + 1
            levels = sorted(list(set(str(o.number)[0] for o in offerings)))
            unique = len(set(o.course_id for o in offerings))

            course_history.append_row([
                instr, first_semester.name, last_semester.name, rank, unit,
                round(num_offerings, 2),
                round(headcount / num_offerings, 1),
                round(num_offerings / duration * 3, 1), unique,
                ','.join(levels)
            ])

        self.artifacts.append(course_history)