Exemplo n.º 1
0
    def post(self):
        errors = dict()
        success = False
        form = SettingsForm(self.request.arguments)
        current_user = self.decoded_username()

        if form.validate():
            try:
                current_password = self.get_argument('current_password')
                new_password = self.get_argument('new_password')
                new_password_confirm = self.get_argument(
                    'new_password_confirm')
                new_email = self.get_argument('new_email')

                # Do the updates in 2 seperate query sessions. The first session updates the
                # email address. If an exception occurs (i.e., duplicate email), we skip the second session,
                # causing nothing to update. If we did both updates in the same session, the password would
                # still update despite the duplicate email problem.
                with Query(self.db) as q:
                    # first, ensure that current_password is correct
                    user = q.query(self.db.account).filter_by(
                        username=current_user).one()
                    h = user.password_hash
                    s = user.password_salt
                    email = user.email_address

                    if authenticate.hash_pw(current_password, s) == h:
                        user.email_address = new_email
                    else:
                        errors['password'] = ["Incorrect password"]

                    email = new_email  #snag it here (if no exception) so we can pass it in in the self.render(...) call

                    # if len is 0, they omitted the new password from the form, so no need to update
                    if len(new_password) > 0 and authenticate.hash_pw(
                            current_password, s) == h:
                        with Query(self.db) as q:
                            user.password_hash, user.password_salt = authenticate.create_password(
                                new_password)

                if len(errors) == 0:
                    success = True

            except IntegrityError as e:
                errors['email'] = [
                    "A user with that email address already exists"
                ]
        else:
            # Invalid forms-- have to re-query the old email address to prepopulate it
            errors = form.errors
            email = self._get_current_user_email()

        return self.render("settings.html",
                           email=email,
                           errors=errors,
                           update_success=success)
Exemplo n.º 2
0
 def test_nested_queries(self):
     with Query(self.db) as outer:
         with Query(self.db) as inner:
             inner.add(
                 Account(username="******",
                         email_address="b",
                         password_hash=b"c",
                         password_salt=b"d"))
         acct = outer.query(Account).one()
         self.assertEqual("a", acct.username)
Exemplo n.º 3
0
    def test_query_working(self):
        with Query(self.db) as q:
            q.add(
                Account(username="******",
                        email_address="b",
                        password_hash=b"c",
                        password_salt=b"d"))

        with Query(self.db) as q:
            acct = q.query(Account).one()
            self.assertEqual("a", acct.username)
Exemplo n.º 4
0
    def test_mismatch_new_passwords(self):
        body = urllib.parse.urlencode({
            "current_password": "******",
            "new_password": "******",
            "new_password_confirm": "orange",
            "new_email": "*****@*****.**"
        })

        with patch('classrank.handlers.BaseHandler.get_current_user'
                   ) as get_current_user:
            get_current_user.return_value = b'"andrew"'
            response = self.fetch("/settings", method="POST", body=body)

            self.assertEqual(response.code, 200)
            self.assertIn(b"Passwords did not match", response.body)

            with Query(self._app.db) as q:
                user = q.query(
                    self._app.db.account).filter_by(username="******").one()
                self.assertEqual(
                    user.password_hash,
                    authenticate.hash_pw("password", user.password_salt))

                # Did not update.. Even though entering new email wasn't erroneous, either ALL
                # updates should go through or NONE. Since new passwords didn't match, NO
                # updates should go through, so don't update email.
                self.assertEqual(user.email_address, "*****@*****.**")
Exemplo n.º 5
0
    def test_success(self):
        """Test success condition of rating."""
        self.register()
        self.login()
        body = urllib.parse.urlencode({"course": "CS 4641",
                                       "section": "A",
                                       "semester": "spring",
                                       "year": "2016",
                                       "rating": "5"})
        with patch(get_current_user_func_path) as auth:
            auth.return_value = b'"tester"'
            response = self.fetch("/rate", method="POST", body=body)
            self.assertEqual(self.fetch("/rate").body, response.body)
            with Query(self._app.db) as q:
                rating = q.query(self._app.db.rating).one()
                self.assertEqual(5, rating.rating)

                self.assertEqual("spring", rating.section.semester)
                print("\n\n\n\n\n", type(rating.section.year))
                self.assertEqual(2016, rating.section.year)
                self.assertEqual(1, rating.section.crn)
                self.assertEqual(1, rating.section.course_id)
                self.assertEqual("A", rating.section.name)

                self.assertEqual(1, rating.student.user_id)
Exemplo n.º 6
0
    def get_app(self):
        self.settings = {
            "static_path": path.join(path.dirname(__file__), static_path),
            "template_path": path.join(path.dirname(__file__), template_path),

            "logged_in_pages": {},

            "logged_out_pages": {},
            "cookie_secret": test_cookie_secret,
            "login_url": "/login",
            "grouch_results": "test/empty.json.example"
        }
        cr = ClassRankApp(None, routes, **self.settings)
        with Query(cr.db) as q:
            q.add(cr.db.school(**{"name": "Georgia Institute of Technology",
                                  "abbreviation": "gatech"}))

            q.add(cr.db.course(**{"school_id": 1,
                                  "name": "Machine Learning",
                                  "subject": "CS",
                                  "number": "4641"}))

            q.add(cr.db.section(**{"course_id": 1,
                                   "semester": "spring",
                                   "year": "2016",
                                   "name": "A",
                                   "crn": 1}))
        return cr
Exemplo n.º 7
0
 def test_filter_query(self):
     with self.assertRaises(ValueError):
         cf = CollaborativeFilter(db=self.conn)
     with Query(self.conn) as q:
         q.add(self.conn.rating(student=self.student2, section=self.section3, rating=4))
     cf = CollaborativeFilter(db=self.conn)
     self.assertIsInstance(cf.getData(), type([]))
Exemplo n.º 8
0
 def test_cleanup(self):
     with self.assertRaises(TypeError):
         with Query(self.db) as q:
             with patch.object(q.session, 'rollback',
                               return_value=5) as mock_rollback:
                 raise TypeError
             self.assertEqual(mock_rollback.called, True)
Exemplo n.º 9
0
 def add_filters(self):
     # attrs = set(x for x in dir(self.db.rating) if not x.startswith("_"))
     # attrs -= set(["metadata", "section_id", "student", "section", "student_id"])
     # return {attr: CollaborativeFilter(db=self.db, metric=attr) for attr in attrs}
     with Query(self.db)as q:
         num = max(1, int(q.query(self.db.student).count() / 5))
     return {'rating': CollaborativeFilter(db=self.db, metric='rating', numRecommendations=num)}
Exemplo n.º 10
0
    def _get_current_user_email(self):
        current_user = self.decoded_username()

        with Query(self.db) as q:
            user = q.query(
                self.db.account).filter_by(username=current_user).one()
            return user.email_address
Exemplo n.º 11
0
    def get_app(self):
        self.settings = {
            "logged_in_pages": {},
            "logged_out_pages": {},
            "static_path":
            os.path.join(os.path.dirname(__file__), "../classrank/static"),
            "template_path":
            os.path.join(os.path.dirname(__file__), "../classrank/templates"),
            "cookie_secret":
            test_cookie_secret,
            "login_url":
            "/login",
            "grouch_results":
            "test/empty.json.example"
        }
        cr = ClassRankApp(None, routes, **self.settings)
        with Query(cr.db) as q:
            q.add(
                cr.db.school(**{
                    "name": "Georgia Test University",
                    "abbreviation": "test"
                }))
            phash, psalt = authenticate.create_password("password")
            q.add(
                cr.db.account(username="******",
                              email_address="*****@*****.**",
                              password_hash=phash,
                              password_salt=psalt))

        return cr
Exemplo n.º 12
0
    def post(self):
        """Method that processes information placed into the rate form.

        Results are validated through the 'RateForm' object. If they are
        validated, check the database to see if the given course and section
        exist. If so, put it in. Else, fail.

        :returns: redirect to '/rate' regardless of success or failure
        """
        form = RateForm(self.request.arguments)

        if form.validate():
            try:
                # store argument data
                subject, number = self.get_argument('course').split(" ")
                section = self.get_argument('section')
                semester = self.get_argument('semester')
                rating = self.get_argument('rating')
                year = self.get_argument('year')
                cur_user = self.__decoded_username()

                print(subject, number, section, semester, rating, year,
                      cur_user)

                with Query(self.db) as q:
                    # get queries for all concerned tables
                    course_q = q.query(Course)
                    section_q = q.query(Section)
                    account_q = q.query(Account)

                    # get needed course, section, and account info from db
                    # calling 'one()' verifies that one match exists
                    course = course_q.filter_by(subject=subject,
                                                number=number).one()

                    section = section_q.filter_by(course_id=course.uid,
                                                  name=section,
                                                  semester=semester,
                                                  year=year).one()

                    account = account_q.filter_by(username=cur_user).one()

                    # generate rating object/row
                    rating = self.db.rating(student_id=account.student.uid,
                                            section_id=section.uid,
                                            rating=rating,
                                            section=section,
                                            student=account.student)
                    # add rating to db
                    q.add(rating)

                    return self.render("rate.html", error=False)
            except Exception as e:
                print(e)
                return self.render("rate.html", error=True)
        else:
            return self.render("rate.html", error=True)
Exemplo n.º 13
0
 def test_register_post_success(self):
     body = urllib.parse.urlencode({
         "email": "*****@*****.**",
         "school": "test",
         "username": "******",
         "password": "******",
         "password_confirm": "password"
     })
     response = self.fetch("/register", method="POST", body=body)
     self.assertEqual(self.fetch("/login").body, response.body)
     with Query(self._app.db) as q:
         user = q.query(self._app.db.account).one()
         self.assertEqual("*****@*****.**", user.email_address)
Exemplo n.º 14
0
 def get(self):
     course = self.request.arguments['query'][0] or ""
     s, n = course.decode('utf-8').partition(" ")[::2]
     with Query(self.db) as q:
         courses = q.query(self.db.course.subject,
                           self.db.course.number).filter(
                               self.db.course.number.like(n + "%"),
                               self.db.course.subject.like(s + "%")).all()
     return self.write({
         "suggestions":
         sorted([course[0] + " " + course[1] for course in courses]),
         "query":
         course.decode('utf-8')
     })
Exemplo n.º 15
0
 def test_fail_section_name_not_found(self):
     """Test failure if rating a non-existent section (name not found)."""
     self.register()
     self.login()
     body = urllib.parse.urlencode({"course": "CS 4641",
                                    "section": "XXX",
                                    "semester": "spring",
                                    "year": "2016",
                                    "rating": "5"})
     with patch(get_current_user_func_path) as auth:
         auth.return_value = b'"tester"'
         response = self.fetch("/rate", method="POST", body=body)
         self.assertIn(b"There was an error adding your rating.", response.body)
         with Query(self._app.db) as q:
             rating = q.query(self._app.db.rating).all()
         self.assertEqual(len(rating), 0)
Exemplo n.º 16
0
 def get_app(self):
     self.settings = {
         "static_path": os.path.join(os.path.dirname(__file__), "../classrank/static"),
         "template_path": os.path.join(os.path.dirname(__file__),
                                       "../classrank/templates"),
         "logged_in_pages": {},
         "logged_out_pages": {},
         "cookie_secret": test_cookie_secret,
         "login_url": "/login",
         "grouch_results": "test/empty.json.example"
     }
     cr = ClassRankApp(os.environ.get("CONNECTION", "sqlite://"), routes, **self.settings)
     with Query(cr.db) as q:
         q.add(cr.db.school(**{"name":"Georgia Test University", "abbreviation": "test"}))
         q.add(cr.db.course(**{"school_id": 1, "name": "CS-4641", "description": "Machine learning", "number": "4641", "subject": "CS"}))
     return cr
Exemplo n.º 17
0
def add_to_database(grouch_output, db):
    """
    Add courses from Grouch's output to a db.

    Keyword arguments:
    grouch_output -- the output of Grouch (the scraped info)
    db -- the db to add to
    """

    print("Beginning Grouch parse ({}).".format(datetime.datetime.now()))
    all_courses = parse(grouch_output)
    print("Ending Grouch parse ({}).".format(datetime.datetime.now()))

    if len(all_courses) != 0:
        print("Beginning database add ({}).".format(datetime.datetime.now()))
        with Query(db) as q:

            school_dict = {"name": "Georgia Institute of Technology",
                           "abbreviation": "gatech"}

            if not _school_in_database(school_dict, db, q):
                q.add(db.school(**school_dict))

            school_id = q.query(db.school).filter_by(**school_dict).one().uid

            for course, sections in all_courses:
                course_dict = {"school_id": school_id,
                               "name": course['name'],
                               "description": course['fullname'],
                               "number": course['number'],
                               "subject": course['school']}

                if not _course_in_database(course_dict, db, q):
                    q.add(db.course(**course_dict))

                course_id = q.query(db.course).filter_by(**course_dict).one().uid

                for section in sections:
                    section_dict = {"course_id": course_id,
                                    "semester": course['semester'],
                                    "year": course['year'],
                                    "name": section['section_id'],
                                    "crn": section['crn']}

                    q.add(db.section(**section_dict))

    print("Ending database add ({}).".format(datetime.datetime.now()))
Exemplo n.º 18
0
 def get(self):
     page_data = {"error": False, "data":{}}
     user = self.decoded_username()
     data = dict()
     try:
         filters = self.add_filters()
         with Query(self.db) as q:
             student = q.query(self.db.account).filter_by(username=user).one().student
             courses = set(c[0] for c in q.query(self.db.course.name).all()) - set([c.name for c in student.courses])
             student_id = student.uid
         ratings = filters['rating'].getRecommendation({student_id: courses})[student_id]
         page_data['data']['rating'] = sorted([(k, v) for k, v in ratings.items()], key=lambda x: x[1] or 0)[::-1]
         self.render('suggestion.html', **page_data)
     except Exception as e:
         print(e)
         page_data['error'] = True
         self.render("suggestion.html", **page_data)
Exemplo n.º 19
0
    def create_example_user(self):
        """
        Add's a user to the database and creates corresponding login headers

        :return: the HTTP headers corresponding to the user's data
        """
        body = urllib.parse.urlencode({
            "email": "*****@*****.**",
            "password": "******"
        })
        user = self._app.db.account(username="******",
                                    email_address="*****@*****.**",
                                    password_hash=b"secret",
                                    password_salt=b"salt")

        with Query(self._app.db) as db:
            db.add(user)

        return body
Exemplo n.º 20
0
    def post(self):
        errors = dict()
        form = LoginForm(self.request.arguments)
        if form.validate():
            try:
                with Query(self.db) as q:
                    user = q.query(self.db.account).filter_by(
                        email_address=self.get_argument('email')).one()
                    h = user.pw_hash
                    s = user.pw_salt

                    if authenticate.hash_pw(self.get_argument('password'), s) == h:
                        self.authorize(user.username)
                        return self.redirect('/dashboard')
                    else:
                        errors['password'] = ["Incorrect password"]
            except NoResultFound:
                errors['email'] = ["No user exists with that email address"]
        else:
            errors = form.errors
        return self.render("login.html", errors=errors)
Exemplo n.º 21
0
 def queryDB(self):
     with Query(self.db) as query:
         for student in query.query(self.db.student).filter(
                 self.db.school.abbreviation == self.school).all():
             results = query.query(self.db.rating, self.db.section).filter(self.db.rating.student_id == student.uid).\
                 filter(self.db.rating.section_id==self.db.section.uid).all() #a tuple of lists
             #results = list(zip(*results)) #a list of tuples
             instance = {}
             for result in results:
                 courseName = query.query(self.db.course).filter(
                     self.db.course.uid == result[1].course_id).first()
                 courseName = courseName.name
                 rating = result[0].__getattribute__(self.metric)
                 #if self.metric == "rating":
                 #    rating = result[0][0].rating
                 #elif self.metric == "grade":
                 #    rating = result[0][0].grade
                 #elif self.metric == "workload":
                 #    rating = result[0][0].workload
                 #elif self.metric == "difficulty":
                 #    rating = result[0][0].difficulty
                 instance[courseName] = rating
             self.dataDict[student.uid] = instance
Exemplo n.º 22
0
 def post(self):
     errors = dict()
     form = RegistrationForm(self.request.arguments)
     if form.validate():
         h, s = authenticate.create_password(self.get_argument('password'))
         user = self.db.account(username=self.get_argument('username'),
                                email_address=self.get_argument('email'),
                                password_hash=h, password_salt=s)
         try:
             with Query(self.db) as q:
                 q.add(user)
                 q.add(self.db.student(account=user, school=q.query(self.db.school).
                                       filter_by(abbreviation=self.get_argument('school')).one()))
         except IntegrityError:
             errors['username'] = ["A user with that username or email address already exists, or invalid school"]
         except Exception as e:
             raise
         else:
             #on success
             return self.redirect('/login')
     else:
         errors = form.errors
     return self.render('register.html', errors=errors)
Exemplo n.º 23
0
    def test_update_email_only(self):
        body = urllib.parse.urlencode({
            "current_password": "******",
            "new_password": "",
            "new_password_confirm": "",
            "new_email": "*****@*****.**"
        })

        with patch('classrank.handlers.BaseHandler.get_current_user'
                   ) as get_current_user:
            get_current_user.return_value = b'"andrew"'
            response = self.fetch("/settings", method="POST", body=body)

            self.assertEqual(response.code, 200)
            self.assertIn(b"Your information has been updated", response.body)

            with Query(self._app.db) as q:
                user = q.query(
                    self._app.db.account).filter_by(username="******").one()
                self.assertEqual(
                    user.password_hash,
                    authenticate.hash_pw("password", user.password_salt))
                self.assertEqual(user.email_address, "*****@*****.**")
Exemplo n.º 24
0
 def setUp(self):
     self.conn = Database(engine=os.environ.get("CONNECTION", "sqlite:///:memory:"))
     school = self.conn.school(name="Georgia Tech", abbreviation="gatech")
     course = self.conn.course(school=school, name="Intro Java", number="1331", subject="CS")
     course2 = self.conn.course(school=school, name="Stuff", number="1332", subject="CS")
     section1 = self.conn.section(course=course, semester="fall", year=2016, name="A1")
     section2 = self.conn.section(course=course, semester="fall", year=2016, name="A2")
     self.section3 = self.conn.section(course=course2, semester="spring",year=2015, name="A")
     account = self.conn.account(username="******", email_address="*****@*****.**", password_hash=b"t", password_salt=b"t")
     student = self.conn.student(account=account, school=school)
     account2 = self.conn.account(username="******", email_address="*****@*****.**", password_hash=b"t", password_salt=b"t")
     self.student2 = self.conn.student(account=account2, school=school)
     with Query(self.conn) as q:
         q.add(school)
         q.add(course)
         q.add(section1)
         q.add(section2)
         q.add(course2)
         q.add(self.section3)
         q.add(account)
         q.add(student)
         q.add(self.student2)
         q.add(self.conn.rating(student=student, section=section1, rating=5))
         q.add(self.conn.rating(student=self.student2, section=section2, rating=3))
Exemplo n.º 25
0
 def test_query_throws(self):
     with self.assertRaises(IntegrityError):
         with Query(self.db) as q:
             q.add(Account())
Exemplo n.º 26
0
if __name__ == "__main__":
    parser = parser()
    args = parser.parse_args()
    settings = {
        "static_path": os.path.join(os.path.dirname(__file__), "classrank/static"),
        "template_path": os.path.join(os.path.dirname(__file__), "classrank/templates")
    }

    try:
        with open(args.settings) as f:
            settings.update(json.loads(f.read()))
    except FileNotFoundError:
        # no additional settings file so we ignore
        pass

    settings['debug'] == args.debug
    db_config = settings['db_config']
    del settings['db_config']
    cr = ClassRankApp(args.connection, routes, **settings)
    try:
        with Query(cr.db) as q:
            for table in db_config:
                for item in db_config[table]:
                    q.add(cr.db.__getattribute__(table)(**item))
    except IntegrityError as e:
        print(e)


    cr.listen(args.port)
    tornado.ioloop.IOLoop.current().start()
Exemplo n.º 27
0
def create_example_database(app):
    with Query(app.db) as q:
        # first a school
        s = app.db.school(**{
            "name": "Georgia Test University",
            "abbreviation": "test"
        })
        q.add(s)

    usernames = [
        "A", "B", "Casey", "D", "E", "Fortnow", "G", "H", "I", "Josh", "K",
        "L", "Mitchell", "N", "Omojokun", "P", "Q", "R", "S", "T"
    ]

    courses = [
        "CS 1301", "CS 1331", "CS 1332", "CS 2110", "CS 4641", "MATH 1552",
        "MATH 3406", "ENGL 1101", "ENGL 1102"
    ]

    students = []
    teachers = []
    classes = []
    sections = []
    with Query(app.db) as q:  # now create some accounts and the users
        for username in usernames:
            a = app.db.account(username=username,
                               email_address=username + "@gmail.com",
                               password_hash=b'hash',
                               password_salt=b'salt')
            q.add(a)
            if len(username) > 1:
                f = app.db.faculty(account=a, school=s)
                teachers.append(f)
                q.add(f)

            if username not in {"Fortnow", "Omojokun"}:
                p = app.db.student(account=a, school=s)
                students.append(p)
                q.add(p)
        print(len(students))

        for course in courses:
            subj, _, num = course.partition(" ")
            cs = app.db.course(name=course, subject=subj, number=num, school=s)
            q.add(cs)
            classes.append(cs)

            if cs.subject == "CS":
                for i in range(classes.index(cs) + 1):
                    char = string.ascii_uppercase[i]
                    sec = app.db.section(course=cs,
                                         professor=teachers[i],
                                         name=char,
                                         semester="Spring",
                                         year=2016)
                    sections.append(sec)
                    q.add(sec)

            elif cs.subject == "MATH":
                sec = app.db.section(course=cs,
                                     professor=teachers[4],
                                     name="A",
                                     semester="Spring",
                                     year=2016)
                sections.append(sec)
                q.add(sec)
            else:
                sec = app.db.section(course=cs,
                                     name="A",
                                     semester="Spring",
                                     year=2016)
                sections.append(sec)
                q.add(sec)
                sec = app.db.section(course=cs,
                                     name="B",
                                     semester="Spring",
                                     year=2016)
                sections.append(sec)
                q.add(sec)

            for sec in cs.sections:
                q.add(app.db.rating(section=sec, student=students[0],
                                    rating=1))  # rates all courses one

            for i in range(1, 6):
                if cs.sections:
                    q.add(
                        app.db.rating(section=cs.sections[0],
                                      student=students[i],
                                      rating=i))  # each rates section 0 as n

            if cs.subject == "CS":
                if len(cs.sections) > 1:
                    q.add(
                        app.db.rating(section=cs.sections[1],
                                      student=students[7],
                                      rating=3))

            if cs.subject == "ENGL":
                if cs.number == "1101":
                    q.add(
                        app.db.rating(section=cs.sections[0],
                                      student=students[8],
                                      rating=1))
                    q.add(
                        app.db.rating(section=cs.sections[0],
                                      student=students[10],
                                      rating=5))
                else:
                    q.add(
                        app.db.rating(section=cs.sections[1],
                                      student=students[9],
                                      rating=5))
                    q.add(
                        app.db.rating(section=cs.sections[0],
                                      student=students[11],
                                      rating=1))

            if cs.subject == "CS" and cs.number == "1301":
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[11],
                                  rating=1))
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[12],
                                  rating=3))
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[13],
                                  rating=5))

            if cs.subject == "CS" and cs.number == "1331":
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[11],
                                  rating=1))
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[12],
                                  rating=3))
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[13],
                                  rating=5))

            if cs.subject == "CS" and cs.number == "1332":
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[11],
                                  rating=1))
                q.add(
                    app.db.rating(section=cs.sections[0],
                                  student=students[12],
                                  rating=3))
Exemplo n.º 28
0
 def test_db_example(self):
     with Query(self._app.db) as q:
         q.session.delete(q.query(self._app.db.school).one())
     create_example_database(self._app)
Exemplo n.º 29
0
    def test_fail_invalid_formdata_rating(self):
        """Tests for all types of invalid rating formdata coming in.
        These should be detected by the RateForm validator. The invalid types
        are:
            01. rating too high (> 5),
            02. rating too low  (< 1),
            03. rating not extant,
            04. name too short (< 5),
            05. name too long  (> 30),
            06. name not extant,
            07. section name too short / not extant,
            08. section name too long (> 4),
            09. year too high (> current year)
            10. year too low  (< 1970)

        In each case, we want to go back to a blank 'rate' page. Finally, we
        then wish to assert that nothing was added to the database from these
        attempts.
        """
        self.register()
        self.login()
        rate_body = self.fetch("/rate").body

        cur_year = datetime.datetime.now().year

        invalid_forms = [
            {"name": "CS-4641", "section": "A",
                "semester": "spring", "rating": "6", "year": "2016"},

            {"name": "CS-4641", "section": "A",
             "semester": "spring", "rating": "0", "year": "2016"},

            {"name": "CS-4641", "section": "A",
             "semester": "spring", "rating": "", "year": "2016"},

            {"name": "C", "section": "A",
             "semester": "spring", "rating": "3", "year": "2016"},

            {"name": "CS-0123456789abcdefghijklmnopqr", "section": "A",
             "semester": "spring ", "rating": "3", "year": "2016"},

            {"name": "", "section": "A",
             "semester": "spring", "rating": "3", "year": "2016"},

            {"name": "CS-4641", "section": "",
             "semester": "spring", "rating": "3", "year": "2016"},

            {"name": "CS-4641", "section": "A 123456789",
             "semester": "spring", "rating": "3", "year": "2016"},

            {"name": "CS-4641", "section": "A",
             "semester": "spring", "rating": "3", "year": str(cur_year + 1)},

            {"name": "CS-4641", "section": "A",
             "semester": "spring", "rating": "3", "year": "1969"}
        ]
        with patch(get_current_user_func_path) as auth:
            auth.return_value = b'"tester"'
            # iterate over all forms, returning to register page each time
            for form in invalid_forms:
                response = self.post_form(form)
                self.assertIn(b"There was an error adding your rating.", response.body)

        # assert that nothing was added to database from all attempts
        with Query(self._app.db) as q:
            rating = q.query(self._app.db.rating).all()
            self.assertEqual(0, len(rating))