Esempio n. 1
0
def new_lesson(content):
    """
    create a new lesson and return the lesson id
    """
    unit_id = content['unit']
    unit = get_content_by_id(unit_id)
    if unit is None:
        raise Exception("invalid unit id: that unit does not exist")

    if 'title' not in content:
        content['title'] = ''
    if 'body' not in content:
        content['body'] = ''

    content['private'] = unit.content['private']
    content['teacher'] = unit.content['teacher']
    content['course'] = unit.content['course']

    key = Curriculum(content_type = 'lesson', content = content).put()
    
    # add this lesson to the parent unit's lesson list
    unit.content['lessons'].append(int(key.id()))
    unit.put()

    return int(key.id())
Esempio n. 2
0
def new_unit(content):
    """
    create a new unit entity; return the id of the new unit
    """
    course_id = content["course"]
    course = get_content_by_id(course_id)
    if course is None:
        raise Exception("invalid course id: that course does not exist")

    if "title" not in content:
        content["title"] = ""
    if "body" not in content:
        content["body"] = ""

    content["private"] = course.content["private"]
    content["teacher"] = course.content["teacher"]
    content["course"] = course_id
    content["lessons"] = []
    key = Curriculum(content_type="unit", content=content).put()

    # add this unit to the parent course's unit list
    course.content["units"].append(int(key.id()))
    course.put()

    return int(key.id())
Esempio n. 3
0
    def test_course_unit_lesson_creation_and_query(self):
        """
        create a course, then unit, then lesson and make sure the entity
        relationships are all valid
        """
        course_key = Curriculum(
            content_type='course',
            content={
                'title': 'numero uno'
            },
        ).put()
        unit_key = Curriculum(content_type='unit',
                              content={
                                  'course': int(course_key.id())
                              }).put()
        lesson_key = Curriculum(content_type='lesson',
                                content={
                                    'course': int(course_key.id()),
                                    'unit': int(unit_key.id())
                                }).put()

        lesson = lesson_key.get()
        unit = ndb.Key(Curriculum, lesson.content['unit']).get()
        course = ndb.Key(Curriculum, unit.content['course']).get()
        self.assertIsNotNone(unit)
        self.assertIsNotNone(course)
        self.assertEqual(course.content['title'], 'numero uno')
Esempio n. 4
0
def new_unit(content):
    """
    create a new unit entity; return the id of the new unit
    """
    course_id = content['course']
    course = get_content_by_id(course_id)
    if course is None:
        raise Exception("invalid course id: that course does not exist")

    if 'title' not in content:
        content['title'] = ''
    if 'body' not in content:
        content['body'] = ''

    content['private'] = course.content['private']
    content['teacher'] = course.content['teacher']
    content['course'] = course_id
    content['lessons'] = []
    key = Curriculum(content_type='unit', content=content).put()

    # add this unit to the parent course's unit list
    course.content['units'].append(int(key.id()))
    course.put()

    return int(key.id())
    def test_create_new_course_then_modify_same_course(self):
        """
        create a new course then modify it 
        """
        self.create_google_user(user_id = '123')
        author = self.create_and_return_local_user(googleID = '123')
        data = {
            'title' : 'foo', 
            'body' : 'bar', 
            'content_type' : 'course',
            }
        response = self.testapp.post('/api/curriculum', data)
        self.assertEqual(Curriculum.query().count(), 1)
        response_data = json.loads(response.body)
        course_id = response_data['id']

        # now update the title and send another request
        data['title'] = 'updated foo'
        new_response = self.testapp.post(
            '/api/curriculum/%s' % course_id, 
            data
            )
        new_response_data = json.loads(response.body)
        self.assertNotIn('error', new_response_data)
        self.assertEqual(Curriculum.query().count(), 1)
        db_course = Curriculum.query().get()
        self.assertEqual(db_course.content['title'], 'updated foo')
 def setUp(self):
     self.curr_1 = Curriculum(name="computer_science",
                              country="ireland",
                              ID="n/a",
                              num_of_strands=3,
                              strand_names=[
                                  "core concepts",
                                  "practices and principles",
                                  "applied learning tasks"
                              ],
                              filename_LOs_txt="./fixtures/test_LO_CS.txt")
 def test_new_approval_request(self):
     """
     create a new approval and assert that it shows up in the database
     """
     self.create_new_approval()
     course = Curriculum.query().get()
     self.assertIn(123, course.content['pending_approval'])
Esempio n. 8
0
 def test_new_approval_request(self):
     """
     create a new approval and assert that it shows up in the database
     """
     self.create_new_approval()
     course = Curriculum.query().get()
     self.assertIn(123, course.content['pending_approval'])
Esempio n. 9
0
    def test_simple_creation_of_new_curriculum_model(self):
        """
        test a simple put() of a new curriculum model 
        """

        new_content = Curriculum()
        new_content.populate(content_type='course',
                             content={
                                 'title': 'foo course',
                                 'owner': 123,
                                 'units': None
                             })
        key = new_content.put()

        fetched_content = ndb.Key(Curriculum, key.id()).get()
        self.assertEqual(fetched_content.content['title'], 'foo course')
Esempio n. 10
0
    def test_course_unit_lesson_creation_and_query(self):
        """
        create a course, then unit, then lesson and make sure the entity
        relationships are all valid
        """
        course_key = Curriculum(
            content_type = 'course',
            content={'title':'numero uno'},
            ).put()
        unit_key = Curriculum(
            content_type = 'unit', 
            content={'course':int(course_key.id())}
            ).put()
        lesson_key = Curriculum(
            content_type = 'lesson',
            content={'course':int(course_key.id()), 'unit':int(unit_key.id())}
            ).put()

        lesson = lesson_key.get()
        unit = ndb.Key(Curriculum, lesson.content['unit']).get()
        course = ndb.Key(Curriculum, unit.content['course']).get()
        self.assertIsNotNone(unit)
        self.assertIsNotNone(course)
        self.assertEqual(course.content['title'], 'numero uno')

        
Esempio n. 11
0
    def test_simple_creation_of_new_curriculum_model(self):
        """
        test a simple put() of a new curriculum model 
        """

        new_content = Curriculum()
        new_content.populate(
            content_type = 'course',
            content = {
                'title' : 'foo course',
                'owner' : 123,
                'units' : None
                }
            )
        key = new_content.put()

        fetched_content = ndb.Key(Curriculum, key.id()).get()
        self.assertEqual(fetched_content.content['title'], 'foo course')
Esempio n. 12
0
 def test_get_approved_users(self):
     """
     create a course, add a few approval requests, 
     and assert that they are retrieved correctly
     """
     self.create_several_approvals_for_course(1)
     course = Curriculum.query().get()
     self.assertEqual(
         course.content['pending_approval'],
         [1, 2, 3, 4, 5],
     )
Esempio n. 13
0
 def test_get_approved_users(self):
     """
     create a course, add a few approval requests, 
     and assert that they are retrieved correctly
     """
     self.create_several_approvals_for_course(1)
     course = Curriculum.query().get()
     self.assertEqual(
         course.content['pending_approval'], 
         [1,2,3,4,5],
         )
Esempio n. 14
0
def new_course(content):
    """
    create a new course entity; return the id of the new course

    content should conform to:
    content = {
        'teacher' : (str or int, Required),
        'title' : (string),
        'body' : (string),
        'private' : (boolean),
    }
    """
    teacher_id = content['teacher']
    teacher = get_user(teacher_id)
    if teacher is None:
        raise Exception("invalid user id: that user does not exist")

    if 'title' not in content:
        content['title'] = ''
    if 'body' not in content:
        content['body'] = ''
    
    if 'private' not in content or content['private'] != True:
        content['private'] = False
        
    content['approved_students'] = []
    content['pending_approval'] = []
    content['units'] = []
    content['listed'] = False
    key = Curriculum(content_type = 'course', content = content).put()

    if teacher.courses:
        teacher.courses.append(int(key.id()))
    else:
        teacher.courses = [int(key.id())]
    teacher.put()

    return int(key.id())
    def test_get_public_course(self):
        """
        test api response for a request of a publically available course
        at /api/curriculum{{courseID}}

        we'll first create a bunch of course material, then we'll determine 
        the id of the first user and their first course that was generated
        """
        self.create_sample_course_framework(1, 1, 1)
        user_id = User.query().get().key.id()
        course_id = Curriculum.query(
            Curriculum.content_type == 'course').get().key.id()
        response = self.testapp.get('/api/curriculum/%s' % course_id)
        self.assertEqual(response.status_int, 200)

        self.assertEqual(response.content_type, 'application/json')
        data = json.loads(response.body)
        self.assertNotIn('error', data)
        self.assertEqual(data['id'], course_id)
        self.assertEqual(data['content']['title'], 'Foo Course 0')
        self.assertEqual(data['content_type'], 'course')
    def test_get_public_course(self):
        """
        test api response for a request of a publically available course
        at /api/curriculum{{courseID}}

        we'll first create a bunch of course material, then we'll determine 
        the id of the first user and their first course that was generated
        """
        self.create_sample_course_framework(1,1,1)
        user_id = User.query().get().key.id()
        course_id = Curriculum.query(
            Curriculum.content_type == 'course'
            ).get().key.id()
        response = self.testapp.get('/api/curriculum/%s' % course_id)
        self.assertEqual(response.status_int, 200)

        self.assertEqual(response.content_type, 'application/json')
        data = json.loads(response.body)
        self.assertNotIn('error', data)
        self.assertEqual(data['id'], course_id)
        self.assertEqual(data['content']['title'], 'Foo Course 0')
        self.assertEqual(data['content_type'], 'course')
Esempio n. 17
0
from models.curriculum import (
        Curriculum,
        LO_list_to_dict,
        dict_to_LO_list,
        dump_LO_dict
        )

""" Scripts which builds a curriculum for the user from an input
learning outcome .txt file and dumps it to a pickle file.
A human-readable version is dumped to a json file, as a dictionary """

# Instantiates a curriculum object
curr = Curriculum()
# User inputs name of the curriculum e.g. 'computer_science'
curr.user_input_name()
# User inputs name of the .txt file containing the learning outcomes
curr.user_input_filename_LOs()
# Sets the number of learning outcome strands from blank lines in file
curr.set_num_strands_from_file()
# Checks with user whether number of strands is correct
curr.user_check_num_strands()
# User inputs names of the strands
curr.user_input_strand_names()
# Loads the LOs into the curriculum, as a list of lists of LearningOutcome objects
curr.load_LOs_from_file(curr.filename_LOs_txt)
# Writes a pickle object representation of the curriculum to file
curr.dump_curriculum(f"{curr.name}.curriculum.pickle")
# Converts the LO lists to dictionary form
LO_dict = LO_list_to_dict(curr.LOs, curr.strand_names)
dump_LO_dict(LO_dict, f"{curr.name}.LO_dict.json")
Esempio n. 18
0
    def get(self, migration_type=None):
        current_user = users.get_current_user()
        if current_user.email() != '*****@*****.**':
            abort(403)
        else:
            if migration_type == 'clear_content':
                ndb.delete_multi(Curriculum.query().fetch(keys_only=True))

            elif migration_type == 'clear_teacher_courses':
                teachers = User.query()
                for teacher in teachers:
                    logging.info('clearing courses for %s' % teacher.key.id())
                    teacher.courses = []
                    teacher.put()
                    logging.info('Completed clearing courses for %s' % teacher.key.id())

            elif migration_type == 'course':
                courses = Content.query(Content.contentType == 'course')
                for course in courses:
                    if course.listed != 'done_migrating3':
                        try:
                            logging.info("Begin course migration for %s" % course.key.id())
                            app_user = course.key.parent().get()
                            teacher = get_user_by_google_id(app_user.googleID)
                            course_data = {
                                'teacher' : teacher.key.id(),
                                'title' : course.title,
                                'body' : course.body
                            }
                            new_course_id = new_course(course_data)
                            logging.info("Saved data for Curriculum ID: %s" % new_course_id)
                            units = Content.query(Content.contentType == 'unit', ancestor=course.key)
                            for unit in units:
                                logging.info("Begin unit migration for %s" % unit.key.id())
                                unit_data = {
                                    'teacher' : teacher.key.id(),
                                    'course' : new_course_id,
                                    'title' : unit.title,
                                    'body' : unit.body
                                }
                                new_unit_id = new_unit(unit_data)
                                logging.info("Saved data for Unit ID: %s" % new_unit_id)

                                lessons = Content.query(Content.contentType == 'lesson', ancestor=unit.key)
                                for lesson in lessons:
                                    logging.info("Begin lesson migration for %s" % lesson.key.id())
                                    lesson_data = {
                                        'teacher' : teacher.key.id(),
                                        'course' : new_course_id,
                                        'unit' : new_unit_id,
                                        'title' : lesson.title,
                                        'body' : lesson.body
                                    }
                                    lesson_id = new_lesson(lesson_data)
                                    logging.info("Saved data for Lesson ID: %s" % lesson_id)

                            course.listed = 'done_migrating3'
                            course.put()
                            logging.info("Finished course migration for %s" % course.key.id())
                        except Exception as e:
                            logging.info("Error migrating course %s" % course.key.id())
                            logging.info(str(e))


            return render_template(
                'migrate.html',
                status_msg = 'migration complete'
                )
class TestCurriculum(unittest.TestCase):
    def setUp(self):
        self.curr_1 = Curriculum(name="computer_science",
                                 country="ireland",
                                 ID="n/a",
                                 num_of_strands=3,
                                 strand_names=[
                                     "core concepts",
                                     "practices and principles",
                                     "applied learning tasks"
                                 ],
                                 filename_LOs_txt="./fixtures/test_LO_CS.txt")

    def tearDown(self):
        pass

    def test_init(self):
        self.assertEqual(self.curr_1.name, "COMPUTER_SCIENCE")
        self.assertEqual(self.curr_1.country, "Ireland")
        self.assertEqual(self.curr_1.ID, "n/a")
        self.assertEqual(self.curr_1.num_of_strands, 3)
        self.assertEqual(self.curr_1.strand_names[0], "CORE CONCEPTS")

    def test_set_num_of_strands(self):
        self.assertRaises(TypeError, self.curr_1.set_num_of_strands, 2.5)
        self.assertRaises(TypeError, self.curr_1.set_num_of_strands, "igs")

    def test_set_num_strands_from_file(self):
        self.curr_1.set_num_of_strands(0)
        self.curr_1.set_num_strands_from_file(self.curr_1.filename_LOs_txt)
        self.assertEqual(self.curr_1.num_of_strands, 3)

    def test_add_strand_name(self):
        self.curr_1.add_strand_name("dummy")
        self.assertEqual(len(self.curr_1.strand_names), 4)
        self.assertEqual(self.curr_1.add_strand_name("dummy"), False)
        self.assertEqual(len(self.curr_1.strand_names), 4)

    def test_add_strand_names(self):
        self.curr_1.add_strand_names(["dummy", "dummy_2"])
        self.assertEqual(len(self.curr_1.strand_names), 5)
        self.curr_1.add_strand_names(["dummy", "dummy_2"])
        self.assertEqual(len(self.curr_1.strand_names), 5)

    def test_load_LOs_from_file(self):
        self.curr_1.load_LOs_from_file(self.curr_1.filename_LOs_txt)
        self.assertEqual([len(self.curr_1.LOs[i]) for i in range(3)],
                         [23, 22, 14])
        self.assertEqual(
            self.curr_1.LOs[1][-1].text,
            "students can explain the different stages in software testing")
        self.assertEqual(
            self.curr_1.LOs[2][-2].text,
            "students can develop a program that utilises digital and analogue inputs"
        )

    def test_list_to_dict_conversion(self):
        """ This simulataneously tests LO_list_to_dict and dict_to_LO_list (inverse functions) """
        self.curr_1.load_LOs_from_file(self.curr_1.filename_LOs_txt)
        LO_dict = LO_list_to_dict(self.curr_1.LOs, self.curr_1.strand_names)
        LO_list = dict_to_LO_list(LO_dict)
        LO_dict_2 = LO_list_to_dict(LO_list, self.curr_1.strand_names)
        self.assertEqual(LO_dict, LO_dict_2)

    def test_getitem(self):
        self.curr_1.load_LOs_from_file(self.curr_1.filename_LOs_txt)
        dict_1, i = {}, 0
        for strand in self.curr_1.LOs:
            for LO in strand:
                dict_1[i] = LO.text
                i += 1
        dict_2 = {i: LO.text for i, LO in enumerate(self.curr_1)}
        self.assertEqual(dict_1, dict_2)