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())
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_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')
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'])
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')
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')
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')
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], )
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], )
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')
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")
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)