def setUp(self): '''Performed before every test''' super(TestExploreMethods, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name=self.FACILITY) self.facility.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user1.set_password(self.PASSWORD) self.user1.save() #add one exercise self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.latest_activity_timestamp = self.TIMESTAMP self.original_exerciselog.completion_timestamp = self.TIMESTAMP self.original_exerciselog.save() #create a request factory for later instantiation of request self.factory = RequestFactory()
class ZoneDeletionTestCase(OrganizationManagementTestCase): def setUp(self): super(ZoneDeletionTestCase, self).setUp() self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() def test_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().accept() self.browser_wait_for_no_element(".zone-delete-link") time.sleep(1) self.browser_check_django_message(message_type="success", contains="successfully deleted") with self.assertRaises(NoSuchElementException): self.assertEqual(self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link no longer exists.") def test_cancel_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().dismiss() self.assertNotEqual(self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link still exists.") self.browser_check_django_message(num_messages=0) def test_issue_697_part1(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_zone_from_org_admin()
def setUp(self): super(TestExerciseLogs, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username="******", facility=self.facility) self.user.set_password("dumber") self.user.save() # create an initial ExerciseLog instance so we have something to collide with later self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.save(update_userlog=False) # get a new reference to the existing ExerciseLog exerciselog = ExerciseLog.objects.get(id=self.original_exerciselog.id) # make sure the ExerciseLog was saved as intended self.assertEqual(exerciselog.points, self.ORIGINAL_POINTS, "The ExerciseLog's points have already changed.") self.assertEqual(exerciselog.attempts, self.ORIGINAL_ATTEMPTS, "The ExerciseLog's attempts have already changed.")
def setUp(self): super(TestVideoLogs, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username="******", facility=self.facility) self.user.set_password("dumber") self.user.save() # create an initial VideoLog instance so we have something to collide with later self.original_videolog = VideoLog(video_id=self.VIDEO_ID, youtube_id=self.YOUTUBE_ID, user=self.user) self.original_videolog.points = self.ORIGINAL_POINTS self.original_videolog.total_seconds_watched = self.ORIGINAL_SECONDS_WATCHED self.original_videolog.save(update_userlog=False) # get a new reference to the existing VideoLog videolog = VideoLog.objects.get(id=self.original_videolog.id) # make sure the VideoLog was created correctly self.assertEqual(videolog.points, self.ORIGINAL_POINTS, "The VideoLog's points have already changed.") self.assertEqual( videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED, "The VideoLog's total seconds watched have already changed.")
class TestSaveContentLog(KALiteTestCase): CONTENT_ID = "712f11" POINTS = 3 COMPLETION_COUNTER = 1 CONTENT_SOURCE = "" CONTENT_KIND = "Document" USERNAME = "******" PASSWORD = "******" def setUp(self): super(TestSaveContentLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Default Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial ContentLog instance so we have something to update later self.contentlog = ContentLog(content_id=self.CONTENT_ID, user=self.user) self.contentlog.points = self.POINTS self.contentlog.content_kind = self.CONTENT_KIND self.contentlog.content_source = self.CONTENT_SOURCE self.contentlog.save() def test_timestamp(self): new_start_timestamp = ContentLog.objects.get(user=self.user) new_start_timestamp.save() # Make sure that the start_timestamp will not change when we update, # only progress_timestamp will update. self.assertEqual(new_start_timestamp.start_timestamp, self.contentlog.start_timestamp) self.assertTrue(new_start_timestamp.progress_timestamp > self.contentlog.progress_timestamp)
def test_records_created_before_reg_still_sync(self): with self.get_distributed_server() as d: # Create a facility on central server, in correct zone facility_central = Facility(name="Central Facility", zone_fallback=self.zone) facility_central.save() # Create a facility on distributed server facility_distributed_id = d.addmodel(FACILITY_MODEL, name='Distributed Facility') self.register(d) sync_results = d.sync() self.assertEqual(sync_results["downloaded"], 2, "Wrong number of records downloaded" ) # =2 because DeviceZone is redownloaded self.assertEqual(sync_results["uploaded"], 1, "Wrong number of records uploaded") self.assertEqual( Facility.objects.filter(id=facility_distributed_id).count(), 1, "Distributed server facility not found centrally.") results = d.runcode( "from kalite.facility.models import Facility; count = Facility.objects.filter(id='%s').count()" % facility_central.id) self.assertEqual( results["count"], 1, "Central server facility not found on distributed.")
class CentralFacilityUserFormTestCase(OrganizationManagementTestCase): def setUp(self): super(CentralFacilityUserFormTestCase, self).setUp() self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() self.facility = Facility(name=self.FACILITY_NAME, zone_fallback=self.zone) self.facility.save() self.user.facility = self.facility self.user.save() def test_add_student(self): self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browse_to( '%s?facility=%s' % (self.reverse('add_facility_student'), self.facility.id)) self.browser.find_element_by_id('id_username').send_keys('s') self.browser.find_element_by_id('id_password_first').send_keys( 'password') self.browser.find_element_by_id('id_password_recheck').send_keys( 'password') self.browser.find_elements_by_class_name('submit')[0].click() self.browser_check_django_message(message_type="success", contains="successfully created")
class TestSaveContentLog(KALiteTestCase): CONTENT_ID = "712f11" POINTS = 3 COMPLETION_COUNTER = 1 CONTENT_SOURCE = "" CONTENT_KIND = "Document" USERNAME = "******" PASSWORD = "******" def setUp(self): super(TestSaveContentLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Default Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial ContentLog instance so we have something to update later self.contentlog = ContentLog(content_id=self.CONTENT_ID, user=self.user) self.contentlog.points = self.POINTS self.contentlog.content_kind = (self.CONTENT_KIND,) self.contentlog.content_source = self.CONTENT_SOURCE self.contentlog.save() def test_timestamp(self): new_start_timestamp = ContentLog.objects.get(user=self.user) new_start_timestamp.save() # Make sure that the start_timestamp will not change when we update, # only progress_timestamp will update. self.assertEqual(new_start_timestamp.start_timestamp, self.contentlog.start_timestamp) self.assertTrue(new_start_timestamp.progress_timestamp > self.contentlog.progress_timestamp)
def test_syncing_of_remotely_created_model_modified_locally(self): with self.get_distributed_server() as d: # Create a facility on central server facility_central = Facility(name="Central Facility", zone_fallback=self.zone) facility_central.save() self.register(d) sync_results = d.sync() d.modifymodel(FACILITY_MODEL, facility_central.id, name="Central Facility - Mod") sync_results = d.sync() self.assertEqual(sync_results["uploaded"], 1, "Wrong number of records uploaded") self.assertEqual( Facility.objects.get(id=facility_central.id).name, "Central Facility - Mod", "Updated Facility name not synced back to central server")
def setUp(self): '''Performed before every test''' super(TestHelperMethods, self).setUp() # user + facility self.facility = Facility(name=self.FACILITY) self.facility.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user1.set_password(self.PASSWORD) self.user1.save() # insert some exercise activity self.original_exerciselog1 = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog1.points = self.ORIGINAL_POINTS self.original_exerciselog1.attempts = self.ORIGINAL_POINTS self.original_exerciselog1.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog1.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog1.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog1.struggling = False self.original_exerciselog1.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user=self.user1) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.struggling = False self.original_exerciselog2.save()
class ZoneDeletionTestCase(OrganizationManagementTestCase): def setUp(self): super(ZoneDeletionTestCase, self).setUp() self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() def test_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().accept() self.browser_wait_for_no_element(".zone-delete-link") self.browser_check_django_message(message_type="success", contains="successfully deleted") with self.assertRaises(NoSuchElementException): self.assertEqual( self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link is gone.") def test_cancel_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().dismiss() self.assertNotEqual( self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link still exists.") self.browser_check_django_message(num_messages=0) def test_cannot_delete_full_zone(self): # Save zone info, but without adding self.devicezone = DeviceZone(device=Device.get_own_device(), zone=self.zone) self.devicezone.save() # Check on the org management page self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) with self.assertRaises(NoSuchElementException): self.assertEqual( self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link is gone.") # Follow the link, and confirm on the zone management page. zone_url = self.browser.find_element_by_css_selector( ".zone-manage-link").get_attribute("href") self.browse_to(zone_url) self.assertEqual(self.browser.current_url, zone_url, "Expect link to go to zone management page") with self.assertRaises(NoSuchElementException): self.assertEqual( self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link is gone.") def test_issue_697_part1(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_zone_from_org_admin()
def __init__(self, *args, **kwargs): # It's not good to override __init__ for classes that inherit from TestCase # Since we're hackily inheriting here, we have to hackily invoke __init__ # Perhaps better would be to decouple this class from the testing framework # by ditching the various mixins (they invoke TestCase methods) and just calling # selenium methods directly, as the mixins are a thin wrapper for that. # -- M.C. Gallaspy, 1/21/2015 KALiteBrowserTestCase.__init__(self, "_fake_test") self.verbosity = kwargs['verbosity'] # make sure output path exists and is empty if kwargs['output_dir']: self.output_path = os.path.join( os.path.realpath(os.getcwd()), kwargs['output_dir'] ) else: self.output_path = settings.SCREENSHOTS_OUTPUT_PATH ensure_dir(self.output_path) # make sure directory is empty from screenshot files png_path = os.path.join(self.output_path, "*%s" % settings.SCREENSHOTS_EXTENSION) pngs = glob.glob(png_path) if pngs and not kwargs['no_del']: self.logwarn("==> Deleting existing screenshots: %s ..." % png_path) for filename in pngs: os.remove(filename) # setup database to use and auto-create admin user self.loginfo("==> Setting-up database ...") self.admin_user = reset_sqlite_database(self.admin_username, self.admin_email, self.default_password, verbosity=self.verbosity) self.admin_pass = self.default_password if not self.admin_user: raise Exception("==> Did not successfully setup database!") Facility.initialize_default_facility("Facility Dos") # Default facility required to avoid pernicious facility selection page facility = self.facility = Facility.objects.get(name="Facility Dos") self.create_student(username=self.student_username, password=self.default_password, facility=facility) self.create_teacher(username=self.coach_username, password=self.default_password, facility=facility) self.persistent_browser = True self.max_wait_time = kwargs.get('max_wait_time', 30) self.setUpClass() self.loginfo("==> Setting-up browser ...") super(Screenshot, self).setUp() # Selenium won't scroll to an element, so we have to make the window size is large enough so that everything is visible self.browser.set_window_size(1024, 768) # self.browser.implicitly_wait(3) # After initializing the server (with setUp) and a browser, set the language self.set_session_language(kwargs['language']) self.loginfo("==> Browser %s successfully setup with live_server_url %s." % (self.browser.name, self.live_server_url,)) self.loginfo("==> Saving screenshots to %s ..." % (settings.SCREENSHOTS_OUTPUT_PATH,))
def setUp(self): '''Performed before every test''' super(TestNextMethods, self).setUp() self.EXERCISE_ID = self.content_exercises[0].id self.EXERCISE_ID2 = self.content_exercises[1].id self.EXERCISE_ID_STRUGGLE = self.content_exercises[2].id # create a facility and user that can be referred to in models across tests self.facility = Facility(name=self.FACILITY) self.facility.save() self.facilitygroup = FacilityGroup(name=self.GROUP, description="", facility=self.facility) self.facilitygroup.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility, group=self.facilitygroup) self.user1.set_password(self.PASSWORD) self.user1.save() self.user2 = FacilityUser(username=self.USERNAME2, facility=self.facility, group=self.facilitygroup) self.user2.set_password(self.PASSWORD) self.user2.save() #user 1 - now add some mock data into exercise log self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog.save() #user 2 self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID, user = self.user2, struggling=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user = self.user2, struggling=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.save() self.original_exerciselog3 = ExerciseLog(exercise_id=self.EXERCISE_ID_STRUGGLE, user = self.user2, struggling=True) self.original_exerciselog3.points = self.ORIGINAL_POINTS self.original_exerciselog3.attempts = self.ORIGINAL_POINTS #intentionally made larger to trigger struggling self.original_exerciselog3.streak_progress = 0 self.original_exerciselog3.attempts = 100 self.original_exerciselog3.latest_activity_timestamp = self.TIMESTAMP_STRUGGLE self.original_exerciselog3.completion_timestamp = self.TIMESTAMP_STRUGGLE self.original_exerciselog3.save()
class OrganizationDeletionTestCase(OrganizationManagementTestCase): def test_delete_org(self): """Delete an empty org""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.assertNotEqual( self.browser.find_element_by_css_selector(".icon-pencil"), None, "Make sure 'edit' icon appears.") self.assertNotEqual( self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon appears.") self.browser.find_element_by_css_selector(".icon-trash").click() self.browser.switch_to_alert().accept() self.browser_wait_for_no_element(".icon-trash") self.browser_check_django_message(message_type="success", contains="successfully deleted") with self.assertRaises(NoSuchElementException): self.assertEqual( self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon is gone.") def test_cancel_delete_org(self): """Click to delete an empty org, then choose CANCEL""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.assertNotEqual( self.browser.find_element_by_css_selector(".icon-pencil"), None, "Make sure 'edit' icon appears.") self.assertNotEqual( self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon appears.") self.browser.find_element_by_css_selector(".icon-trash").click() self.browser.switch_to_alert().dismiss() self.assertNotEqual( self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon appears.") self.browser_check_django_message(num_messages=0) def test_cannot_delete_full_org(self): """Confirm no option to delete an org with data""" # Save zone info, but without adding self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.assertNotEqual( self.browser.find_element_by_css_selector(".icon-pencil"), None, "Make sure 'edit' icon appears.") with self.assertRaises(NoSuchElementException): self.assertEqual( self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon does not appear.") def test_issue_697_part2(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_org()
def __init__(self, *args, **kwargs): # It's not good to override __init__ for classes that inherit from TestCase # Since we're hackily inheriting here, we have to hackily invoke __init__ # Perhaps better would be to decouple this class from the testing framework # by ditching the various mixins (they invoke TestCase methods) and just calling # selenium methods directly, as the mixins are a thin wrapper for that. # -- M.C. Gallaspy, 1/21/2015 KALiteBrowserTestCase.__init__(self, "_fake_test") self.verbosity = kwargs['verbosity'] # make sure output path exists and is empty if kwargs['output_dir']: self.output_path = os.path.join( os.path.realpath(os.path.join(settings.PROJECT_PATH, '..')), kwargs['output_dir']) else: self.output_path = settings.SCREENSHOTS_OUTPUT_PATH ensure_dir(self.output_path) # make sure directory is empty from screenshot files png_path = os.path.join(self.output_path, "*%s" % settings.SCREENSHOTS_EXTENSION) pngs = glob.glob(png_path) if pngs and not kwargs['no_del']: self.logwarn("==> Deleting existing screenshots: %s ..." % png_path) for filename in pngs: os.remove(filename) # setup database to use and auto-create admin user self.loginfo("==> Setting-up database ...") self.admin_user = reset_sqlite_database(self.admin_username, self.admin_email, self.default_password, verbosity=self.verbosity) self.admin_pass = self.default_password if not self.admin_user: raise Exception("==> Did not successfully setup database!") Facility.initialize_default_facility("Facility Dos") # Default facility required to avoid pernicious facility selection page facility = self.facility = Facility.objects.get(name="Facility Dos") self.create_student(username=self.student_username, password=self.default_password, facility=facility) self.create_teacher(username=self.coach_username, password=self.default_password, facility=facility) self.persistent_browser = True self.max_wait_time = kwargs.get('max_wait_time', 30) self.setUpClass() self.loginfo("==> Setting-up browser ...") super(Screenshot, self).setUp() # Selenium won't scroll to an element, so we have to make the window size is large enough so that everything is visible self.browser.set_window_size(1024, 768) # self.browser.implicitly_wait(3) # After initializing the server (with setUp) and a browser, set the language self.set_session_language(kwargs['language']) self.loginfo("==> Browser %s successfully setup with live_server_url %s." % (self.browser.name, self.live_server_url,)) self.loginfo("==> Saving screenshots to %s ..." % (settings.SCREENSHOTS_OUTPUT_PATH,))
def test_fetch_model(self): MODEL_NAME = "kalite.facility.models.Facility" facility_name = "kir1" # Create a Facility object first that will be fetched. facility = Facility(name=facility_name) facility.save() (out, err, rc) = call_command_with_output("readmodel", MODEL_NAME, id=facility.id) data_map = json.loads(out) self.assertEquals(data_map["name"], facility_name)
def setUp(self): """Performed before every test""" # a brand new user self.facility = Facility(name=self.FACILITY) self.facility.save() self.user_with_no_activity = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user_with_no_activity.set_password(self.PASSWORD) self.user_with_no_activity.save() # a user with valid exercises self.user_with_activity = FacilityUser(username=self.USERNAME2, facility=self.facility) self.user_with_activity.set_password(self.PASSWORD) self.user_with_activity.save() # a user with invalid exercises self.user_with_old_activity = FacilityUser(username=self.USERNAME3, facility=self.facility) self.user_with_old_activity.set_password(self.PASSWORD) self.user_with_old_activity.save() # add some exercises for second user (both incomplete) self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user_with_activity, complete=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user=self.user_with_activity, complete=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.save() self.original_exerciselog3 = ExerciseLog( exercise_id=self.INVALID_EXERCISE_ID, user=self.user_with_old_activity, complete=False) self.original_exerciselog3.points = self.ORIGINAL_POINTS self.original_exerciselog3.attempts = self.ORIGINAL_POINTS self.original_exerciselog3.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog3.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog3.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog3.save()
def setUp(self): super(CentralFacilityUserFormTestCase, self).setUp() self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() self.facility = Facility(name=self.FACILITY_NAME, zone_fallback=self.zone) self.facility.save() self.user.facility = self.facility self.user.save()
def test_fetch_model(self): MODEL_NAME = 'kalite.facility.models.Facility' facility_name = 'kir1' # Create a Facility object first that will be fetched. facility = Facility(name=facility_name) facility.save() (out, err, rc) = call_command_with_output('readmodel', MODEL_NAME, id=facility.id) data_map = json.loads(out) self.assertEquals(data_map['name'], facility_name)
class TestExploreMethods(KALiteTestCase): ORIGINAL_POINTS = 37 ORIGINAL_ATTEMPTS = 3 ORIGINAL_STREAK_PROGRESS = 20 NEW_POINTS_LARGER = 22 NEW_ATTEMPTS = 5 NEW_STREAK_PROGRESS_LARGER = 10 NEW_POINTS_SMALLER = 0 NEW_STREAK_PROGRESS_SMALLER = 0 EXERCISE_ID = "number_line" USERNAME1 = "test_user_explore_1" PASSWORD = "******" FACILITY = "Test Facility Explore" TIMESTAMP = datetime.datetime(2014, 11, 17, 20, 51, 2, 342662) def setUp(self): '''Performed before every test''' # create a facility and user that can be referred to in models across tests self.facility = Facility(name=self.FACILITY) self.facility.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user1.set_password(self.PASSWORD) self.user1.save() #add one exercise self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.latest_activity_timestamp = self.TIMESTAMP self.original_exerciselog.completion_timestamp = self.TIMESTAMP self.original_exerciselog.save() #create a request factory for later instantiation of request self.factory = RequestFactory() def test_explore_overall(self): '''get_explore_recommendations()''' #create a request object and set the language attribute request = self.factory.get('/content_recommender?explore=true') request.language = settings.LANGUAGE_CODE actual = get_explore_recommendations(self.user1, request) self.assertEqual(actual[0].get("interest_topic").get("id"), "arithmetic")
def setUp(self): super(TestSaveVideoLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial VideoLog instance so we have something to update later self.original_videolog = VideoLog(video_id=self.VIDEO_ID, youtube_id=self.YOUTUBE_ID, user=self.user) self.original_videolog.points = self.ORIGINAL_POINTS self.original_videolog.total_seconds_watched = self.ORIGINAL_SECONDS_WATCHED self.original_videolog.save()
def test_unicode_string(self): # Dependencies dev = Device.get_own_device() self.assertNotIn(unicode(dev), "Bad Unicode data", "Device: Bad conversion to unicode.") fac = Facility(name=self.korean_string) fac.save() self.assertNotIn(unicode(fac), "Bad Unicode data", "Facility: Bad conversion to unicode.") fg = FacilityGroup(facility=fac, name=self.korean_string) fg.save() self.assertNotIn(unicode(fg), "Bad Unicode data", "FacilityGroup: Bad conversion to unicode.") user = FacilityUser( facility=fac, group=fg, first_name=self.korean_string, last_name=self.korean_string, username=self.korean_string, notes=self.korean_string, ) user.set_password(self.korean_string * settings.PASSWORD_CONSTRAINTS["min_length"]) user.save() self.assertNotIn(unicode(user), "Bad Unicode data", "FacilityUser: Bad conversion to unicode.") known_classes = [ExerciseLog, UserLog, UserLogSummary, VideoLog] # elog = ExerciseLog(user=user, exercise_id=self.korean_string) self.assertNotIn(unicode(elog), "Bad Unicode data", "ExerciseLog: Bad conversion to unicode (before saving).") elog.save() self.assertNotIn(unicode(elog), "Bad Unicode data", "ExerciseLog: Bad conversion to unicode (after saving).") vlog = VideoLog(user=user, video_id=self.korean_string, youtube_id=self.korean_string) self.assertNotIn(unicode(vlog), "Bad Unicode data", "VideoLog: Bad conversion to unicode (before saving).") vlog.save() self.assertNotIn(unicode(vlog), "Bad Unicode data", "VideoLog: Bad conversion to unicode (after saving).") ulog = UserLog(user=user) self.assertNotIn(unicode(ulog), "Bad Unicode data", "UserLog: Bad conversion to unicode.") ulogsum = UserLogSummary( user=user, device=dev, activity_type=1, start_datetime=datetime.now(), end_datetime=datetime.now(), ) self.assertNotIn(unicode(ulogsum), "Bad Unicode data", "UserLogSummary: Bad conversion to unicode.")
class ZoneDeletionTestCase(OrganizationManagementTestCase): def setUp(self): super(ZoneDeletionTestCase, self).setUp() self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() def test_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().accept() self.browser_wait_for_no_element(".zone-delete-link") self.browser_check_django_message(message_type="success", contains="successfully deleted") with self.assertRaises(NoSuchElementException): self.assertEqual(self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link is gone.") def test_cancel_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().dismiss() self.assertNotEqual(self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link still exists.") self.browser_check_django_message(num_messages=0) def test_cannot_delete_full_zone(self): # Save zone info, but without adding self.devicezone = DeviceZone(device=Device.get_own_device(), zone=self.zone) self.devicezone.save() # Check on the org management page self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) with self.assertRaises(NoSuchElementException): self.assertEqual(self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link is gone.") # Follow the link, and confirm on the zone management page. zone_url = self.browser.find_element_by_css_selector(".zone-manage-link").get_attribute("href") self.browse_to(zone_url) self.assertEqual(self.browser.current_url, zone_url, "Expect link to go to zone management page") with self.assertRaises(NoSuchElementException): self.assertEqual(self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link is gone.") def test_issue_697_part1(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_zone_from_org_admin()
def setUp(self): super(TestSaveContentLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Default Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial ContentLog instance so we have something to update later self.contentlog = ContentLog(content_id=self.CONTENT_ID, user=self.user) self.contentlog.points = self.POINTS self.contentlog.content_kind = self.CONTENT_KIND self.contentlog.content_source = self.CONTENT_SOURCE self.contentlog.save()
def setUp(self): super(TestSaveExerciseLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial ExerciseLog instance so we have something to update later self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.save()
def generate_fake_facilities(names=("Wilson Elementary", )): """Add the given fake facilities""" facilities = [] for name in names: found_facilities = Facility.objects.filter(name=name) if found_facilities: facility = found_facilities[0] logging.info("Retrieved facility '%s'" % name) else: facility = Facility(name=name) facility.save() logging.info("Created facility '%s'" % name) facilities.append(facility) return facilities
def generate_fake_facilities(names=("Wilson Elementary",)): """Add the given fake facilities""" facilities = [] for name in names: found_facilities = Facility.objects.filter(name=name) if found_facilities: facility = found_facilities[0] logging.info("Retrieved facility '%s'" % name) else: facility = Facility(name=name) facility.save() logging.info("Created facility '%s'" % name) facilities.append(facility) return facilities
class OrganizationDeletionTestCase(OrganizationManagementTestCase): def test_delete_org(self): """Delete an empty org""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.assertNotEqual(self.browser.find_element_by_css_selector(".icon-pencil"), None, "Make sure 'edit' icon appears.") self.assertNotEqual(self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon appears.") self.browser.find_element_by_css_selector(".icon-trash").click() self.browser.switch_to_alert().accept() self.browser_wait_for_no_element(".icon-trash") self.browser_check_django_message(message_type="success", contains="successfully deleted") with self.assertRaises(NoSuchElementException): self.assertEqual(self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon is gone.") def test_cancel_delete_org(self): """Click to delete an empty org, then choose CANCEL""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.assertNotEqual(self.browser.find_element_by_css_selector(".icon-pencil"), None, "Make sure 'edit' icon appears.") self.assertNotEqual(self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon appears.") self.browser.find_element_by_css_selector(".icon-trash").click() self.browser.switch_to_alert().dismiss() self.assertNotEqual(self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon appears.") self.browser_check_django_message(num_messages=0) def test_cannot_delete_full_org(self): """Confirm no option to delete an org with data""" # Save zone info, but without adding self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.assertNotEqual(self.browser.find_element_by_css_selector(".icon-pencil"), None, "Make sure 'edit' icon appears.") with self.assertRaises(NoSuchElementException): self.assertEqual(self.browser.find_element_by_css_selector(".icon-trash"), None, "Make sure 'delete' icon does not appear.") def test_issue_697_part2(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_org()
class CentralFacilityUserFormTestCase(OrganizationManagementTestCase): def setUp(self): super(CentralFacilityUserFormTestCase, self).setUp() self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() self.facility = Facility(name=self.FACILITY_NAME, zone_fallback=self.zone) self.facility.save() self.user.facility = self.facility self.user.save() def test_add_student(self): self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browse_to('%s?facility=%s' % (self.reverse('add_facility_student'), self.facility.id)) self.browser.find_element_by_id('id_username').send_keys('s') self.browser.find_element_by_id('id_password_first').send_keys('password') self.browser.find_element_by_id('id_password_recheck').send_keys('password') self.browser.find_elements_by_class_name('submit')[0].click() self.browser_check_django_message(message_type="success", contains="successfully created")
def test_syncing_of_remotely_created_model_modified_locally(self): with self.get_distributed_server() as d: # Create a facility on central server facility_central = Facility(name="Central Facility", zone_fallback=self.zone) facility_central.save() self.register(d) sync_results = d.sync() d.modifymodel(FACILITY_MODEL, facility_central.id, name="Central Facility - Mod") sync_results = d.sync() self.assertEqual(sync_results["uploaded"], 1, "Wrong number of records uploaded") self.assertEqual(Facility.objects.get(id=facility_central.id).name, "Central Facility - Mod", "Updated Facility name not synced back to central server")
def test_records_created_before_reg_still_sync(self): with self.get_distributed_server() as d: # Create a facility on central server, in correct zone facility_central = Facility(name="Central Facility", zone_fallback=self.zone) facility_central.save() # Create a facility on distributed server facility_distributed_id = d.addmodel(FACILITY_MODEL, name='Distributed Facility') self.register(d) sync_results = d.sync() self.assertEqual(sync_results["downloaded"], 2, "Wrong number of records downloaded") # =2 because DeviceZone is redownloaded self.assertEqual(sync_results["uploaded"], 1, "Wrong number of records uploaded") self.assertEqual(Facility.objects.filter(id=facility_distributed_id).count(), 1, "Distributed server facility not found centrally.") results = d.runcode("from kalite.facility.models import Facility; count = Facility.objects.filter(id='%s').count()" % facility_central.id) self.assertEqual(results["count"], 1, "Central server facility not found on distributed.")
def setUp(self): super(TestSaveContentLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Default Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial ContentLog instance so we have something to update later self.contentlog = ContentLog(content_id=self.CONTENT_ID, user=self.user) self.contentlog.points = self.POINTS self.contentlog.content_kind = (self.CONTENT_KIND,) self.contentlog.content_source = self.CONTENT_SOURCE self.contentlog.save()
class ZoneDeletionTestCase(OrganizationManagementTestCase): def setUp(self): super(ZoneDeletionTestCase, self).setUp() self.zone = Zone(name=self.ZONE_NAME) self.zone.save() self.org.add_zone(self.zone) self.org.save() def test_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().accept() self.browser_wait_for_no_element(".zone-delete-link") time.sleep(1) self.browser_check_django_message(message_type="success", contains="successfully deleted") with self.assertRaises(NoSuchElementException): self.assertEqual( self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link no longer exists.") def test_cancel_delete_zone_from_org_admin(self): """Delete a zone from the org_management page""" self.browser_login_user(self.USER_EMAIL, self.USER_PASSWORD) self.browser.find_element_by_css_selector(".zone-delete-link").click() self.browser.switch_to_alert().dismiss() self.assertNotEqual( self.browser.find_element_by_css_selector(".zone-delete-link"), None, "Make sure 'delete' link still exists.") self.browser_check_django_message(num_messages=0) def test_issue_697_part1(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_zone_from_org_admin()
def setUp(self): """Performed before every test""" # a brand new user self.facility = Facility(name=self.FACILITY) self.facility.save() self.user_with_no_activity = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user_with_no_activity.set_password(self.PASSWORD) self.user_with_no_activity.save() # a user with valid exercises self.user_with_activity = FacilityUser(username=self.USERNAME2, facility=self.facility) self.user_with_activity.set_password(self.PASSWORD) self.user_with_activity.save() # a user with invalid exercises self.user_with_old_activity = FacilityUser(username=self.USERNAME3, facility=self.facility) self.user_with_old_activity.set_password(self.PASSWORD) self.user_with_old_activity.save() # add some exercises for second user (both incomplete) self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user_with_activity, complete=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user=self.user_with_activity, complete=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.save() self.original_exerciselog3 = ExerciseLog(exercise_id=self.INVALID_EXERCISE_ID, user=self.user_with_old_activity, complete=False) self.original_exerciselog3.points = self.ORIGINAL_POINTS self.original_exerciselog3.attempts = self.ORIGINAL_POINTS self.original_exerciselog3.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog3.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog3.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog3.save()
def setUp(self): super(TestVideoLogs, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username="******", facility=self.facility) self.user.set_password("dumber") self.user.save() # create an initial VideoLog instance so we have something to collide with later self.original_videolog = VideoLog(video_id=self.VIDEO_ID, youtube_id=self.YOUTUBE_ID, user=self.user) self.original_videolog.points = self.ORIGINAL_POINTS self.original_videolog.total_seconds_watched = self.ORIGINAL_SECONDS_WATCHED self.original_videolog.save() # get a new reference to the existing VideoLog videolog = VideoLog.objects.get(id=self.original_videolog.id) # make sure the VideoLog was created correctly self.assertEqual(videolog.points, self.ORIGINAL_POINTS, "The VideoLog's points have already changed.") self.assertEqual(videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED, "The VideoLog's total seconds watched have already changed.")
def setUp(self): '''Performed before every test''' # create a facility and user that can be referred to in models across tests self.facility = Facility(name=self.FACILITY) self.facility.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user1.set_password(self.PASSWORD) self.user1.save() #add one exercise self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.latest_activity_timestamp = self.TIMESTAMP self.original_exerciselog.completion_timestamp = self.TIMESTAMP self.original_exerciselog.save() #create a request factory for later instantiation of request self.factory = RequestFactory()
def setUp(self): super(TestExerciseLogs, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username="******", facility=self.facility) self.user.set_password("dumber") self.user.save() # create an initial ExerciseLog instance so we have something to collide with later self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.save() # get a new reference to the existing ExerciseLog exerciselog = ExerciseLog.objects.get(id=self.original_exerciselog.id) # make sure the ExerciseLog was saved as intended self.assertEqual(exerciselog.points, self.ORIGINAL_POINTS, "The ExerciseLog's points have already changed.") self.assertEqual(exerciselog.attempts, self.ORIGINAL_ATTEMPTS, "The ExerciseLog's attempts have already changed.")
class TestSaveExerciseLog(KALiteTestCase): ORIGINAL_POINTS = 37 ORIGINAL_ATTEMPTS = 3 ORIGINAL_STREAK_PROGRESS = 20 NEW_POINTS_LARGER = 22 NEW_ATTEMPTS = 5 NEW_STREAK_PROGRESS_LARGER = 10 NEW_POINTS_SMALLER = 0 NEW_STREAK_PROGRESS_SMALLER = 0 EXERCISE_ID = "number_line" EXERCISE_ID2 = "radius_diameter_and_circumference" USERNAME = "******" PASSWORD = "******" def setUp(self): super(TestSaveExerciseLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial ExerciseLog instance so we have something to update later self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.save() def test_new_exerciselog(self): # make sure the target exercise log does not already exist exerciselogs = ExerciseLog.objects.filter(exercise_id=self.EXERCISE_ID2, user__username=self.USERNAME) self.assertEqual(exerciselogs.count(), 0, "The target exercise log to be newly created already exists") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new exercise log result = c.save_exercise_log( exercise_id=self.EXERCISE_ID2, streak_progress=self.NEW_STREAK_PROGRESS_LARGER, points=self.NEW_POINTS_LARGER, correct=True, attempts=self.NEW_ATTEMPTS, user=self.USERNAME, ) self.assertEqual(result.status_code, 201, "An error (%d) was thrown while saving the exercise log." % result.status_code) # get a reference to the newly created ExerciseLog exerciselog = ExerciseLog.objects.get(exercise_id=self.EXERCISE_ID2, user__username=self.USERNAME) # make sure the ExerciseLog was properly created self.assertEqual(exerciselog.points, self.NEW_POINTS_LARGER, "The ExerciseLog's points were not saved correctly.") self.assertEqual(exerciselog.streak_progress, self.NEW_STREAK_PROGRESS_LARGER, "The ExerciseLog's streak progress was not saved correctly.") self.assertEqual(exerciselog.attempts, self.NEW_ATTEMPTS, "The ExerciseLog did not have the correct number of attempts (%d)." % self.NEW_ATTEMPTS) def test_update_exerciselog(self): # get a new reference to the existing ExerciseLog exerciselog = ExerciseLog.objects.get(id=self.original_exerciselog.id) # make sure the ExerciseLog hasn't already been changed self.assertEqual(exerciselog.points, self.ORIGINAL_POINTS, "The ExerciseLog's points have already changed.") self.assertEqual(exerciselog.streak_progress, self.ORIGINAL_STREAK_PROGRESS, "The ExerciseLog's streak progress already changed.") self.assertEqual(exerciselog.attempts, self.ORIGINAL_ATTEMPTS, "The ExerciseLog's attempts have already changed.") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new record onto the exercise log, with a correct answer (increasing the points and streak) result = c.save_exercise_log( exercise_id=self.EXERCISE_ID, streak_progress=self.NEW_STREAK_PROGRESS_LARGER, points=self.NEW_POINTS_LARGER, attempts=self.NEW_ATTEMPTS, user=self.USERNAME, ) self.assertEqual(result.status_code, 201, "An error (%d) was thrown while saving the exercise log." % result.status_code) # get a reference to the updated ExerciseLog exerciselog = ExerciseLog.objects.get(exercise_id=self.EXERCISE_ID, user__username=self.USERNAME) # make sure the ExerciseLog was properly updated self.assertEqual(exerciselog.points, self.NEW_POINTS_LARGER, "The ExerciseLog's points were not updated correctly.") self.assertEqual(exerciselog.streak_progress, self.NEW_STREAK_PROGRESS_LARGER, "The ExerciseLog's streak progress was not updated correctly.") self.assertEqual(exerciselog.attempts, self.NEW_ATTEMPTS, "The ExerciseLog did not have the correct number of attempts (%d)." % self.NEW_ATTEMPTS) # save a new record onto the exercise log, with an incorrect answer (decreasing the points and streak) result = c.save_exercise_log( exercise_id=self.EXERCISE_ID, streak_progress=self.NEW_STREAK_PROGRESS_SMALLER, points=self.NEW_POINTS_SMALLER, attempts=self.NEW_ATTEMPTS + 1, user=self.USERNAME, ) self.assertEqual(result.status_code, 201, "An error (%d) was thrown while saving the exercise log." % result.status_code) # get a reference to the updated ExerciseLog exerciselog = ExerciseLog.objects.get(exercise_id=self.EXERCISE_ID, user__username=self.USERNAME) # make sure the ExerciseLog was properly updated self.assertEqual(exerciselog.points, self.NEW_POINTS_SMALLER, "The ExerciseLog's points were not saved correctly.") self.assertEqual(exerciselog.streak_progress, self.NEW_STREAK_PROGRESS_SMALLER, "The ExerciseLog's streak progress was not saved correctly.") self.assertEqual(exerciselog.attempts, self.NEW_ATTEMPTS + 1, "The ExerciseLog did not have the correct number of attempts.")
def handle(self, *args, **options): if not options["interactive"]: options["hostname"] = options["hostname"] or get_host_name() # blank allows ansible scripts to dump errors cleanly. print(" ") print(" _ __ ___ _ _ _ ") print(" | | / / / _ \ | | (_) | ") print(" | |/ / / /_\ \ | | _| |_ ___ ") print(" | \ | _ | | | | | __/ _ \ ") print(" | |\ \| | | | | |___| | || __/ ") print(" \_| \_/\_| |_/ \_____/_|\__\___| ") print(" ") print("https://learningequality.org/ka-lite/") print(" ") print(" version %s" % VERSION) print(" ") if sys.version_info < (2, 7): raise CommandError("Support for Python version 2.6 and below had been discontinued, please upgrade.") elif sys.version_info >= (2, 8): raise CommandError( "Your Python version is: %d.%d.%d -- which is not supported. Please use the Python 2.7 series or wait for Learning Equality to release Kolibri.\n" % sys.version_info[:3]) elif sys.version_info < (2, 7, 6): logging.warning( "It's recommended that you install Python version 2.7.6. Your version is: %d.%d.%d\n" % sys.version_info[:3]) if options["interactive"]: print( "--------------------------------------------------------------------------------") print( "This script will configure the database and prepare it for use.") print( "--------------------------------------------------------------------------------") raw_input("Press [enter] to continue...") # Tried not to be os-specific, but ... hey. :-/ # benjaoming: This doesn't work, why is 502 hard coded!? Root is normally # '0' And let's not care about stuff like this, people can be free to # run this as root if they want :) if not is_windows() and hasattr(os, "getuid") and os.getuid() == 502: print( "-------------------------------------------------------------------") print("WARNING: You are installing KA-Lite as root user!") print( "\tInstalling as root may cause some permission problems while running") print("\tas a normal user in the future.") print( "-------------------------------------------------------------------") if options["interactive"]: if not raw_input_yn("Do you wish to continue and install it as root?"): raise CommandError("Aborting script.\n") git_migrate_path = options["git_migrate_path"] if git_migrate_path: call_command("gitmigrate", path=git_migrate_path, interactive=options["interactive"]) database_kind = settings.DATABASES["default"]["ENGINE"] if "sqlite" in database_kind: database_file = settings.DATABASES["default"]["NAME"] else: database_file = None database_exists = database_file and os.path.isfile(database_file) # An empty file is created automatically even when the database dosn't # exist. But if it's empty, it's safe to overwrite. database_exists = database_exists and os.path.getsize(database_file) > 0 install_clean = not database_exists if database_file: if not database_exists: install_clean = True else: # We found an existing database file. By default, # we will upgrade it; users really need to work hard # to delete the file (but it's possible, which is nice). print( "-------------------------------------------------------------------") print("WARNING: Database file already exists!") print( "-------------------------------------------------------------------") if not options["interactive"] \ or raw_input_yn("Keep database file and upgrade to KA Lite version %s? " % VERSION) \ or not raw_input_yn("Remove database file '%s' now? " % database_file) \ or not raw_input_yn("WARNING: all data will be lost! Are you sure? "): install_clean = False print("Upgrading database to KA Lite version %s" % VERSION) else: install_clean = True print("OK. We will run a clean install; ") # After all, don't delete--just move. print( "the database file will be moved to a deletable location.") if not install_clean and not database_file: # Make sure that, for non-sqlite installs, the database exists. raise Exception( "For databases not using SQLite, you must set up your database before running setup.") # Do all input at once, at the beginning if install_clean and options["interactive"]: if not options["username"] or not options["password"]: print( "Please choose a username and password for the admin account on this device.") print( "\tYou must remember this login information, as you will need") print( "\tto enter it to administer this installation of KA Lite.") (username, password) = get_username_password( options["username"], options["password"]) email = options["email"] (hostname, description) = get_hostname_and_description( options["hostname"], options["description"]) else: username = options["username"] = ( options["username"] or getattr(settings, "INSTALL_ADMIN_USERNAME", None) or get_clean_default_username() ) password = options["password"] or getattr(settings, "INSTALL_ADMIN_PASSWORD", None) email = options["email"] # default is non-empty hostname = options["hostname"] description = options["description"] if username and not validate_username(username): raise CommandError( "Username must contain only letters, digits, and underscores, and start with a letter.\n") ######################## # Now do stuff ######################## # Clean *pyc files if we are in a git repo if settings.IS_SOURCE: clean_pyc(settings.SOURCE_DIR) else: # Because we install dependencies as data_files, we run into problems, # namely that the pyc files are left dangling. distributed_packages = [ os.path.join(kalite.ROOT_DATA_PATH, 'dist-packages'), os.path.join(kalite.ROOT_DATA_PATH, 'python-packages'), ] # Try locating django for dir_to_clean in distributed_packages: clean_pyc(dir_to_clean) # Move database file (if exists) if install_clean and database_file and os.path.exists(database_file): if not settings.DB_TEMPLATE_DEFAULT or database_file != settings.DB_TEMPLATE_DEFAULT: # This is an overwrite install; destroy the old db dest_file = tempfile.mkstemp()[1] print( "(Re)moving database file to temp location, starting clean install. Recovery location: %s" % dest_file) shutil.move(database_file, dest_file) if settings.DB_TEMPLATE_DEFAULT and not database_exists and os.path.exists(settings.DB_TEMPLATE_DEFAULT): print("Copying database file from {0} to {1}".format(settings.DB_TEMPLATE_DEFAULT, settings.DEFAULT_DATABASE_PATH)) shutil.copy(settings.DB_TEMPLATE_DEFAULT, settings.DEFAULT_DATABASE_PATH) else: print("Baking a fresh database from scratch or upgrading existing database.") call_command("syncdb", interactive=False, verbosity=options.get("verbosity")) call_command("migrate", merge=True, verbosity=options.get("verbosity")) Settings.set("database_version", VERSION) # Copy all content item db templates if os.path.exists(settings.DB_CONTENT_ITEM_TEMPLATE_DIR): for file_name in os.listdir(settings.DB_CONTENT_ITEM_TEMPLATE_DIR): if file_name.endswith("sqlite"): template_path = os.path.join(settings.DB_CONTENT_ITEM_TEMPLATE_DIR, file_name) dest_database = os.path.join(settings.DEFAULT_DATABASE_DIR, file_name) if install_clean or not os.path.exists(dest_database): print("Copying {} to {}".format(template_path, dest_database)) shutil.copy(template_path, dest_database) else: print("Skipping {}".format(template_path)) # download the english content pack # This can take a long time and lead to Travis stalling. None of this # is required for tests, and does not apply to the central server. if options.get("no-assessment-items", False): logging.warning("Skipping content pack downloading and configuration.") else: # Outdated location of assessment items - move assessment items from their # old location (CONTENT_ROOT/khan where they were mixed with other content # items) # TODO(benjaoming) for 0.15, remove the "move assessment items" # mechanism writable_assessment_items = os.access(KHAN_ASSESSMENT_ITEM_ROOT, os.W_OK) # Remove old assessment items if os.path.exists(OLD_ASSESSMENT_ITEMS_LOCATION) and os.access(OLD_ASSESSMENT_ITEMS_LOCATION, os.W_OK): logging.info("Deleting old assessment items") shutil.rmtree(OLD_ASSESSMENT_ITEMS_LOCATION) if options['force-assessment-item-dl']: # user wants to force a new download; do it if we can, else error if writable_assessment_items: call_command("retrievecontentpack", "download", "en") else: raise RuntimeError("Got force-assessment-item-dl but directory not writable") elif english_content_pack_and_assessment_resources_are_current(): logging.warning("English content pack is already up-to-date; skipping download and configuration.") elif not writable_assessment_items: # skip if we're not going to be able to unpack it anyway logging.warning("Assessment item directory not writable; skipping content pack download.") elif settings.RUNNING_IN_TRAVIS: # skip if we're running on Travis logging.warning("Running in Travis; skipping content pack download.") elif not options['interactive']: # skip if we're not running in interactive mode (and it wasn't forced) logging.warning("Not running in interactive mode; skipping content pack download.") else: # if we get this far, then we need to ask the user whether/how they want to get the content pack print( "\nIn order to access many of the available exercises, you need to load a content pack for the latest version.") print( "If you have an Internet connection, you can download the needed package. Warning: this may take a long time!") print( "If you have already downloaded the content pack, you can specify the location of the file in the next step.") print("Otherwise, we will download it from {url}.".format(url=CONTENTPACK_URL)) if raw_input_yn("Do you wish to download and install the content pack now?"): ass_item_filename = CONTENTPACK_URL retrieval_method = "download" elif raw_input_yn("Do you have a local copy of the content pack already downloaded that you want to install?"): ass_item_filename = get_assessment_items_filename() retrieval_method = "local" else: ass_item_filename = None retrieval_method = "local" if not ass_item_filename: logging.warning( "No content pack given. You will need to download and install it later.") else: call_command("retrievecontentpack", retrieval_method, "en", ass_item_filename, foreground=True) # Individually generate any prerequisite models/state that is missing if not Settings.get("private_key"): call_command("generatekeys", verbosity=options.get("verbosity")) if not Device.objects.count(): call_command( "initdevice", hostname, description, verbosity=options.get("verbosity")) if not Facility.objects.count(): Facility.initialize_default_facility() # Create the admin user # blank password (non-interactive) means don't create a superuser if password: admin = get_object_or_None(User, username=username) if not admin: call_command("createsuperuser", username=username, email=email, interactive=False, verbosity=options.get("verbosity")) admin = User.objects.get(username=username) admin.set_password(password) admin.save() # Now deploy the static files logging.info("Copying static media...") ensure_dir(settings.STATIC_ROOT) # The following file ignores have to be preserved from a # collectstatic(clear=True), due to being bundled with content packs, # and we thus have now way of getting them back. collectstatic_ignores = [ "*.vtt", "*.srt", # subtitle files come with language packs -- don't delete "*/perseus/ke/exercises/*", # exercises come with language packs, and we have no way to replicate ] call_command("collectstatic", interactive=False, verbosity=0, ignore_patterns=collectstatic_ignores, clear=True) call_command("collectstatic_js_reverse", interactive=False) # This is not possible in a distributed env if not settings.CENTRAL_SERVER: kalite_executable = 'kalite' if not spawn.find_executable('kalite'): if os.name == 'posix': start_script_path = os.path.realpath( os.path.join(settings.PROJECT_PATH, "..", "bin", kalite_executable)) else: start_script_path = os.path.realpath( os.path.join(settings.PROJECT_PATH, "..", "bin", "windows", "kalite.bat")) else: start_script_path = kalite_executable # Run annotate_content_items, on the distributed server. print("Annotating availability of all content, checking for content in this directory: (%s)" % settings.CONTENT_ROOT) try: call_command("annotate_content_items") except OperationalError: pass # done; notify the user. print("\nCONGRATULATIONS! You've finished setting up the KA Lite server software.") print("You can now start KA Lite with the following command:\n\n\t%s start\n\n" % start_script_path) if options['interactive']: if raw_input_yn("Do you wish to start the server now?"): print("Running {0} start".format(start_script_path)) p = subprocess.Popen([start_script_path, "start"], env=os.environ) p.wait()
class TestSaveVideoLog(KALiteTestCase): ORIGINAL_POINTS = 84 ORIGINAL_SECONDS_WATCHED = 32 NEW_POINTS = 32 NEW_SECONDS_WATCHED = 15 YOUTUBE_ID = "aNqG4ChKShI" VIDEO_ID = "dummy" YOUTUBE_ID2 = "b22tMEc6Kko" VIDEO_ID2 = "dummy2" USERNAME = "******" PASSWORD = "******" def setUp(self): super(TestSaveVideoLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial VideoLog instance so we have something to update later self.original_videolog = VideoLog(video_id=self.VIDEO_ID, youtube_id=self.YOUTUBE_ID, user=self.user) self.original_videolog.points = self.ORIGINAL_POINTS self.original_videolog.total_seconds_watched = self.ORIGINAL_SECONDS_WATCHED self.original_videolog.save() def test_new_videolog(self): # make sure the target video log does not already exist videologs = VideoLog.objects.filter(video_id=self.VIDEO_ID2, user__username=self.USERNAME) self.assertEqual(videologs.count(), 0, "The target video log to be newly created already exists") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new video log result = c.save_video_log( video_id=self.VIDEO_ID2, youtube_id=self.YOUTUBE_ID2, total_seconds_watched=self.ORIGINAL_SECONDS_WATCHED, points=self.NEW_POINTS, user=self.USERNAME, ) self.assertEqual(result.status_code, 201, "An error (%d) was thrown while saving the video log." % result.status_code) # get a reference to the newly created VideoLog videolog = VideoLog.objects.get(video_id=self.VIDEO_ID2, user__username=self.USERNAME) # make sure the VideoLog was properly created self.assertEqual(videolog.points, self.NEW_POINTS, "The VideoLog's points were not saved correctly.") self.assertEqual(videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED, "The VideoLog's seconds watched was not saved correctly.") def test_update_videolog(self): # get a new reference to the existing VideoLog videolog = VideoLog.objects.get(id=self.original_videolog.id) # make sure the VideoLog hasn't already been changed self.assertEqual(videolog.points, self.ORIGINAL_POINTS, "The VideoLog's points have already changed.") self.assertEqual(videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED, "The VideoLog's seconds watched already changed.") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new record onto the video log, with a correct answer (increasing the points and streak) result = c.save_video_log( video_id=self.VIDEO_ID, youtube_id=self.YOUTUBE_ID, total_seconds_watched=self.ORIGINAL_SECONDS_WATCHED + self.NEW_SECONDS_WATCHED, points=self.ORIGINAL_POINTS + self.NEW_POINTS, user=self.USERNAME, ) self.assertEqual(result.status_code, 201, "An error (%d) was thrown while saving the video log." % result.status_code) # get a reference to the updated VideoLog videolog = VideoLog.objects.get(video_id=self.VIDEO_ID, user__username=self.USERNAME) # make sure the VideoLog was properly updated self.assertEqual(videolog.points, self.ORIGINAL_POINTS + self.NEW_POINTS, "The VideoLog's points were not updated correctly.") self.assertEqual(videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED + self.NEW_SECONDS_WATCHED, "The VideoLog's seconds watched was not updated correctly.")
class TestNextMethods(KALiteTestCase): ORIGINAL_POINTS = 37 ORIGINAL_ATTEMPTS = 0 ORIGINAL_STREAK_PROGRESS = 20 NEW_POINTS_LARGER = 22 NEW_ATTEMPTS = 5 NEW_STREAK_PROGRESS_LARGER = 10 NEW_POINTS_SMALLER = 0 NEW_STREAK_PROGRESS_SMALLER = 0 EXERCISE_ID = "number_line" EXERCISE_ID2 = "radius_diameter_and_circumference" EXERCISE_ID_STRUGGLE = "counting-out-1-20-objects" USERNAME1 = "test_user_next1" USERNAME2 = "test_user_next2" PASSWORD = "******" FACILITY = "Test Facility Next Steps" TIMESTAMP_LATER = datetime.datetime(2014, 11, 17, 20, 51, 2, 342662) TIMESTAMP_EARLY = datetime.datetime(2014, 10, 8, 15, 59, 59, 370290) TIMESTAMP_STRUGGLE = datetime.datetime(2014, 9, 17, 17, 43, 36, 405260) GROUP = 'Test Group Next Steps' def setUp(self): '''Performed before every test''' # create a facility and user that can be referred to in models across tests self.facility = Facility(name=self.FACILITY) self.facility.save() self.facilitygroup = FacilityGroup(name=self.GROUP, description="", facility=self.facility) self.facilitygroup.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility, group=self.facilitygroup) self.user1.set_password(self.PASSWORD) self.user1.save() self.user2 = FacilityUser(username=self.USERNAME2, facility=self.facility, group=self.facilitygroup) self.user2.set_password(self.PASSWORD) self.user2.save() #user 1 - now add some mock data into exercise log self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog.save() #user 2 self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user2, struggling=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user=self.user2, struggling=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.save() self.original_exerciselog3 = ExerciseLog( exercise_id=self.EXERCISE_ID_STRUGGLE, user=self.user2, struggling=True) self.original_exerciselog3.points = self.ORIGINAL_POINTS self.original_exerciselog3.attempts = self.ORIGINAL_POINTS #intentionally made larger to trigger struggling self.original_exerciselog3.streak_progress = 0 self.original_exerciselog3.attempts = 100 self.original_exerciselog3.latest_activity_timestamp = self.TIMESTAMP_STRUGGLE self.original_exerciselog3.completion_timestamp = self.TIMESTAMP_STRUGGLE self.original_exerciselog3.save() #set all other exercise's struggling param to false def test_group_recommendations(self): '''get_group_recommendations()''' user = FacilityUser.objects.filter(username=self.USERNAME1)[0] expected = ["radius_diameter_and_circumference"] actual = get_group_recommendations(user) self.assertEqual(expected, actual, "Group recommendations incorrect.") def test_struggling(self): '''get_struggling_exercises()''' expected = [unicode(self.EXERCISE_ID_STRUGGLE, 'utf-8')] actual = get_struggling_exercises( FacilityUser.objects.filter( username=self.USERNAME2).order_by('-id')[0]) self.assertSequenceEqual(expected, actual, "Struggling return incorrect.") def test_exercise_prereqs(self): '''get_exercise_prereqs()''' ex_id = 'equivalent_fractions' expected = ['visualizing-equivalent-fractions'] actual = get_exercise_prereqs([ex_id]) self.assertEqual(expected, actual, "Exercise Prereqs incorrect.")
def test_issue_697_part2(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_org()
def handle(self, *args, **options): if not options["interactive"]: options["hostname"] = options["hostname"] or get_host_name() # blank allows ansible scripts to dump errors cleanly. print(" ") print(" _ __ ___ _ _ _ ") print(" | | / / / _ \ | | (_) | ") print(" | |/ / / /_\ \ | | _| |_ ___ ") print(" | \ | _ | | | | | __/ _ \ ") print(" | |\ \| | | | | |___| | || __/ ") print(" \_| \_/\_| |_/ \_____/_|\__\___| ") print(" ") print("https://learningequality.org/ka-lite/") print(" ") print(" version %s" % VERSION) print(" ") if sys.version_info < (2, 7): raise CommandError( "Support for Python version 2.6 and below had been discontinued, please upgrade." ) elif sys.version_info >= (2, 8): raise CommandError( "Your Python version is: %d.%d.%d -- which is not supported. Please use the Python 2.7 series or wait for Learning Equality to release Kolibri.\n" % sys.version_info[:3]) elif sys.version_info < (2, 7, 6): logging.warning( "It's recommended that you install Python version 2.7.6. Your version is: %d.%d.%d\n" % sys.version_info[:3]) if options["interactive"]: print( "--------------------------------------------------------------------------------" ) print( "This script will configure the database and prepare it for use." ) print( "--------------------------------------------------------------------------------" ) raw_input("Press [enter] to continue...") # Assuming uid '0' is always root if not is_windows() and hasattr(os, "getuid") and os.getuid() == 0: print( "-------------------------------------------------------------------" ) print("WARNING: You are installing KA-Lite as root user!") print( "\tInstalling as root may cause some permission problems while running" ) print("\tas a normal user in the future.") print( "-------------------------------------------------------------------" ) if options["interactive"]: if not raw_input_yn( "Do you wish to continue and install it as root?"): raise CommandError("Aborting script.\n") database_kind = settings.DATABASES["default"]["ENGINE"] if "sqlite" in database_kind: database_file = settings.DATABASES["default"]["NAME"] else: database_file = None database_exists = database_file and os.path.isfile(database_file) # An empty file is created automatically even when the database dosn't # exist. But if it's empty, it's safe to overwrite. database_exists = database_exists and os.path.getsize( database_file) > 0 install_clean = not database_exists if database_file: if not database_exists: install_clean = True else: # We found an existing database file. By default, # we will upgrade it; users really need to work hard # to delete the file (but it's possible, which is nice). print( "-------------------------------------------------------------------" ) print("WARNING: Database file already exists!") print( "-------------------------------------------------------------------" ) if not options["interactive"] \ or raw_input_yn("Keep database file and upgrade to KA Lite version %s? " % VERSION) \ or not raw_input_yn("Remove database file '%s' now? " % database_file) \ or not raw_input_yn("WARNING: all data will be lost! Are you sure? "): install_clean = False print("Upgrading database to KA Lite version %s" % VERSION) else: install_clean = True print("OK. We will run a clean install; ") # After all, don't delete--just move. print( "the database file will be moved to a deletable location." ) if not install_clean and not database_file: # Make sure that, for non-sqlite installs, the database exists. raise Exception( "For databases not using SQLite, you must set up your database before running setup." ) # Do all input at once, at the beginning if install_clean and options["interactive"]: if not options["username"] or not options["password"]: print( "Please choose a username and password for the admin account on this device." ) print( "\tYou must remember this login information, as you will need" ) print( "\tto enter it to administer this installation of KA Lite." ) (username, password) = get_username_password(options["username"], options["password"]) email = options["email"] (hostname, description) = get_hostname_and_description( options["hostname"], options["description"]) else: username = options["username"] = (options["username"] or getattr( settings, "INSTALL_ADMIN_USERNAME", None) or get_clean_default_username()) password = options["password"] or getattr( settings, "INSTALL_ADMIN_PASSWORD", None) email = options["email"] # default is non-empty hostname = options["hostname"] description = options["description"] if username and not validate_username(username): raise CommandError( "Username must contain only letters, digits, and underscores, and start with a letter.\n" ) ######################## # Now do stuff ######################## # Move database file (if exists) if install_clean and database_file and os.path.exists(database_file): if not settings.DB_TEMPLATE_DEFAULT or database_file != settings.DB_TEMPLATE_DEFAULT: # This is an overwrite install; destroy the old db dest_file = tempfile.mkstemp()[1] print( "(Re)moving database file to temp location, starting clean install. Recovery location: %s" % dest_file) shutil.move(database_file, dest_file) if settings.DB_TEMPLATE_DEFAULT and not database_exists and os.path.exists( settings.DB_TEMPLATE_DEFAULT): print("Copying database file from {0} to {1}".format( settings.DB_TEMPLATE_DEFAULT, settings.DEFAULT_DATABASE_PATH)) shutil.copy(settings.DB_TEMPLATE_DEFAULT, settings.DEFAULT_DATABASE_PATH) else: print( "Baking a fresh database from scratch or upgrading existing database." ) call_command("syncdb", interactive=False, verbosity=options.get("verbosity")) call_command("migrate", merge=True, verbosity=options.get("verbosity")) Settings.set("database_version", VERSION) # Copy all content item db templates reset_content_db(force=install_clean) # download the english content pack # This can take a long time and lead to Travis stalling. None of this # is required for tests, and does not apply to the central server. if options.get("no-assessment-items", False): logging.warning( "Skipping content pack downloading and configuration.") else: # user wants to force a new download; do it if we can, else error if options['force-assessment-item-dl']: call_command("retrievecontentpack", "download", "en") else: detect_content_packs(options) # Individually generate any prerequisite models/state that is missing if not Settings.get("private_key"): call_command("generatekeys", verbosity=options.get("verbosity")) if not Device.objects.count(): call_command("initdevice", hostname, description, verbosity=options.get("verbosity")) if not Facility.objects.count(): Facility.initialize_default_facility() # Create the admin user # blank password (non-interactive) means don't create a superuser if password: admin = get_object_or_None(User, username=username) if not admin: call_command("createsuperuser", username=username, email=email, interactive=False, verbosity=options.get("verbosity")) admin = User.objects.get(username=username) admin.set_password(password) admin.save() # Now deploy the static files logging.info("Copying static media...") ensure_dir(settings.STATIC_ROOT) call_command("collectstatic", interactive=False, verbosity=0, clear=True) call_command("collectstatic_js_reverse", interactive=False) # This is not possible in a distributed env if not settings.CENTRAL_SERVER: kalite_executable = 'kalite' if not spawn.find_executable('kalite'): if os.name == 'posix': start_script_path = os.path.realpath( os.path.join(settings.PROJECT_PATH, "..", "bin", kalite_executable)) else: start_script_path = os.path.realpath( os.path.join(settings.PROJECT_PATH, "..", "bin", "windows", "kalite.bat")) else: start_script_path = kalite_executable # Run annotate_content_items, on the distributed server. print( "Annotating availability of all content, checking for content in this directory: (%s)" % settings.CONTENT_ROOT) try: call_command("annotate_content_items") except OperationalError: pass # done; notify the user. print( "\nCONGRATULATIONS! You've finished setting up the KA Lite server software." ) print( "You can now start KA Lite with the following command:\n\n\t%s start\n\n" % start_script_path) if options['interactive']: if raw_input_yn("Do you wish to start the server now?"): print("Running {0} start".format(start_script_path)) p = subprocess.Popen([start_script_path, "start"], env=os.environ) p.wait()
def test_issue_697_part1(self): self.facility = Facility(name=self.FACILITY_NAME) self.facility.save() self.test_delete_zone_from_org_admin()
class TestSaveExerciseLog(KALiteTestCase): ORIGINAL_POINTS = 37 ORIGINAL_ATTEMPTS = 3 ORIGINAL_STREAK_PROGRESS = 20 NEW_POINTS_LARGER = 22 NEW_ATTEMPTS = 5 NEW_STREAK_PROGRESS_LARGER = 10 NEW_POINTS_SMALLER = 0 NEW_STREAK_PROGRESS_SMALLER = 0 EXERCISE_ID = "number_line" EXERCISE_ID2 = "radius_diameter_and_circumference" USERNAME = "******" PASSWORD = "******" def setUp(self): super(TestSaveExerciseLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial ExerciseLog instance so we have something to update later self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.save() def test_new_exerciselog(self): # make sure the target exercise log does not already exist exerciselogs = ExerciseLog.objects.filter( exercise_id=self.EXERCISE_ID2, user__username=self.USERNAME) self.assertEqual( exerciselogs.count(), 0, "The target exercise log to be newly created already exists") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new exercise log result = c.save_exercise_log( exercise_id=self.EXERCISE_ID2, streak_progress=self.NEW_STREAK_PROGRESS_LARGER, points=self.NEW_POINTS_LARGER, correct=True, attempts=self.NEW_ATTEMPTS, user=self.USERNAME, ) self.assertEqual( result.status_code, 201, "An error (%d) was thrown while saving the exercise log." % result.status_code) # get a reference to the newly created ExerciseLog exerciselog = ExerciseLog.objects.get(exercise_id=self.EXERCISE_ID2, user__username=self.USERNAME) # make sure the ExerciseLog was properly created self.assertEqual(exerciselog.points, self.NEW_POINTS_LARGER, "The ExerciseLog's points were not saved correctly.") self.assertEqual( exerciselog.streak_progress, self.NEW_STREAK_PROGRESS_LARGER, "The ExerciseLog's streak progress was not saved correctly.") self.assertEqual( exerciselog.attempts, self.NEW_ATTEMPTS, "The ExerciseLog did not have the correct number of attempts (%d)." % self.NEW_ATTEMPTS) def test_update_exerciselog(self): # get a new reference to the existing ExerciseLog exerciselog = ExerciseLog.objects.get(id=self.original_exerciselog.id) # make sure the ExerciseLog hasn't already been changed self.assertEqual(exerciselog.points, self.ORIGINAL_POINTS, "The ExerciseLog's points have already changed.") self.assertEqual(exerciselog.streak_progress, self.ORIGINAL_STREAK_PROGRESS, "The ExerciseLog's streak progress already changed.") self.assertEqual(exerciselog.attempts, self.ORIGINAL_ATTEMPTS, "The ExerciseLog's attempts have already changed.") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new record onto the exercise log, with a correct answer (increasing the points and streak) result = c.save_exercise_log( exercise_id=self.EXERCISE_ID, streak_progress=self.NEW_STREAK_PROGRESS_LARGER, points=self.NEW_POINTS_LARGER, attempts=self.NEW_ATTEMPTS, user=self.USERNAME, ) self.assertEqual( result.status_code, 201, "An error (%d) was thrown while saving the exercise log." % result.status_code) # get a reference to the updated ExerciseLog exerciselog = ExerciseLog.objects.get(exercise_id=self.EXERCISE_ID, user__username=self.USERNAME) # make sure the ExerciseLog was properly updated self.assertEqual( exerciselog.points, self.NEW_POINTS_LARGER, "The ExerciseLog's points were not updated correctly.") self.assertEqual( exerciselog.streak_progress, self.NEW_STREAK_PROGRESS_LARGER, "The ExerciseLog's streak progress was not updated correctly.") self.assertEqual( exerciselog.attempts, self.NEW_ATTEMPTS, "The ExerciseLog did not have the correct number of attempts (%d)." % self.NEW_ATTEMPTS) # save a new record onto the exercise log, with an incorrect answer (decreasing the points and streak) result = c.save_exercise_log( exercise_id=self.EXERCISE_ID, streak_progress=self.NEW_STREAK_PROGRESS_SMALLER, points=self.NEW_POINTS_SMALLER, attempts=self.NEW_ATTEMPTS + 1, user=self.USERNAME, ) self.assertEqual( result.status_code, 201, "An error (%d) was thrown while saving the exercise log." % result.status_code) # get a reference to the updated ExerciseLog exerciselog = ExerciseLog.objects.get(exercise_id=self.EXERCISE_ID, user__username=self.USERNAME) # make sure the ExerciseLog was properly updated self.assertEqual(exerciselog.points, self.NEW_POINTS_SMALLER, "The ExerciseLog's points were not saved correctly.") self.assertEqual( exerciselog.streak_progress, self.NEW_STREAK_PROGRESS_SMALLER, "The ExerciseLog's streak progress was not saved correctly.") self.assertEqual( exerciselog.attempts, self.NEW_ATTEMPTS + 1, "The ExerciseLog did not have the correct number of attempts.")
class TestSaveVideoLog(KALiteTestCase): ORIGINAL_POINTS = 84 ORIGINAL_SECONDS_WATCHED = 32 NEW_POINTS = 32 NEW_SECONDS_WATCHED = 15 YOUTUBE_ID = "aNqG4ChKShI" VIDEO_ID = i18n.get_video_id(YOUTUBE_ID) or "dummy" YOUTUBE_ID2 = "b22tMEc6Kko" VIDEO_ID2 = i18n.get_video_id(YOUTUBE_ID2) or "dummy2" USERNAME = "******" PASSWORD = "******" def setUp(self): super(TestSaveVideoLog, self).setUp() # create a facility and user that can be referred to in models across tests self.facility = Facility(name="Test Facility") self.facility.save() self.user = FacilityUser(username=self.USERNAME, facility=self.facility) self.user.set_password(self.PASSWORD) self.user.save() # create an initial VideoLog instance so we have something to update later self.original_videolog = VideoLog(video_id=self.VIDEO_ID, youtube_id=self.YOUTUBE_ID, user=self.user) self.original_videolog.points = self.ORIGINAL_POINTS self.original_videolog.total_seconds_watched = self.ORIGINAL_SECONDS_WATCHED self.original_videolog.save() def test_new_videolog(self): # make sure the target video log does not already exist videologs = VideoLog.objects.filter(video_id=self.VIDEO_ID2, user__username=self.USERNAME) self.assertEqual( videologs.count(), 0, "The target video log to be newly created already exists") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new video log result = c.save_video_log( video_id=self.VIDEO_ID2, youtube_id=self.YOUTUBE_ID2, total_seconds_watched=self.ORIGINAL_SECONDS_WATCHED, points=self.NEW_POINTS, user=self.USERNAME, ) self.assertEqual( result.status_code, 201, "An error (%d) was thrown while saving the video log." % result.status_code) # get a reference to the newly created VideoLog videolog = VideoLog.objects.get(video_id=self.VIDEO_ID2, user__username=self.USERNAME) # make sure the VideoLog was properly created self.assertEqual(videolog.points, self.NEW_POINTS, "The VideoLog's points were not saved correctly.") self.assertEqual( videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED, "The VideoLog's seconds watched was not saved correctly.") def test_update_videolog(self): # get a new reference to the existing VideoLog videolog = VideoLog.objects.get(id=self.original_videolog.id) # make sure the VideoLog hasn't already been changed self.assertEqual(videolog.points, self.ORIGINAL_POINTS, "The VideoLog's points have already changed.") self.assertEqual(videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED, "The VideoLog's seconds watched already changed.") c = KALiteClient() # login success = c.login(username=self.USERNAME, password=self.PASSWORD, facility=self.facility.id) self.assertTrue(success, "Was not able to login as the test user") # save a new record onto the video log, with a correct answer (increasing the points and streak) result = c.save_video_log( video_id=self.VIDEO_ID, youtube_id=self.YOUTUBE_ID, total_seconds_watched=self.ORIGINAL_SECONDS_WATCHED + self.NEW_SECONDS_WATCHED, points=self.ORIGINAL_POINTS + self.NEW_POINTS, user=self.USERNAME, ) self.assertEqual( result.status_code, 201, "An error (%d) was thrown while saving the video log." % result.status_code) # get a reference to the updated VideoLog videolog = VideoLog.objects.get(video_id=self.VIDEO_ID, user__username=self.USERNAME) # make sure the VideoLog was properly updated self.assertEqual(videolog.points, self.ORIGINAL_POINTS + self.NEW_POINTS, "The VideoLog's points were not updated correctly.") self.assertEqual( videolog.total_seconds_watched, self.ORIGINAL_SECONDS_WATCHED + self.NEW_SECONDS_WATCHED, "The VideoLog's seconds watched was not updated correctly.")
class TestHelperMethods(KALiteTestCase): ORIGINAL_POINTS = 37 ORIGINAL_ATTEMPTS = 3 ORIGINAL_STREAK_PROGRESS = 20 NEW_POINTS_LARGER = 22 NEW_ATTEMPTS = 5 NEW_STREAK_PROGRESS_LARGER = 10 NEW_POINTS_SMALLER = 0 NEW_STREAK_PROGRESS_SMALLER = 0 EXERCISE_ID = "number_line" EXERCISE_ID2 = "radius_diameter_and_circumference" USERNAME1 = "test_user_helper1" PASSWORD = "******" FACILITY = "Test Facility Next Steps" TIMESTAMP_LATER = datetime.datetime(2014, 11, 17, 20, 51, 2, 342662) TIMESTAMP_EARLY = datetime.datetime(2014, 10, 8, 15, 59, 59, 370290) def setUp(self): '''Performed before every test''' super(TestHelperMethods, self).setUp() # user + facility self.facility = Facility(name=self.FACILITY) self.facility.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user1.set_password(self.PASSWORD) self.user1.save() # insert some exercise activity self.original_exerciselog1 = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog1.points = self.ORIGINAL_POINTS self.original_exerciselog1.attempts = self.ORIGINAL_POINTS self.original_exerciselog1.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog1.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog1.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog1.struggling = False self.original_exerciselog1.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user=self.user1) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.struggling = False self.original_exerciselog2.save() def tearDown(self): '''Performed after each test''' super(TestHelperMethods, self).tearDown() self.user_with_activity = None self.user_with_no_activity = None @unittest.skipIf( settings.RUNNING_IN_CI, "benjaoming: Disabling for now, cannot reproduce failures locally, " "but it fails consistently on Circle." ) def test_exercises_from_topics(self): '''get_exercises_from_topics()''' expected = [e.id for e in self.content_exercises[0:4]] actual = get_exercises_from_topics([self.content_subsubtopics[0].id]) actual = map(lambda s: str(s), actual) expected = set(expected) actual = set(sorted(actual)) self.assertEqual(expected, actual) def test_most_recent_exercises(self): '''get_most_recent_exercises()''' first = "radius_diameter_and_circumference" second = "number_line" expected = [unicode(first, 'utf-8'), unicode(second, 'utf-8')] actual = get_most_recent_exercises(self.user1) self.assertSequenceEqual(expected, actual)
def handle(self, *args, **options): if not options["interactive"]: options["hostname"] = options["hostname"] or get_host_name() # blank allows ansible scripts to dump errors cleanly. logger.info( " \n" " _ __ ___ _ _ _ \n" " | | / / / _ \ | | (_) | \n" " | |/ / / /_\ \ | | _| |_ ___ \n" " | \ | _ | | | | | __/ _ \ \n" " | |\ \| | | | | |___| | || __/ \n" " \_| \_/\_| |_/ \_____/_|\__\___| \n" " \n" "https://learningequality.org/ka-lite/\n" " \n" " version {version:s}\n" " ".format( version=VERSION ) ) if sys.version_info < (2, 7): raise CommandError( "Support for Python version 2.6 and below had been discontinued, please upgrade.") elif sys.version_info >= (2, 8): raise CommandError( "Your Python version is: %d.%d.%d -- which is not supported. Please use the Python 2.7 series or wait for Learning Equality to release Kolibri.\n" % sys.version_info[:3]) elif sys.version_info < (2, 7, 6): logger.warning( "It's recommended that you install Python version 2.7.6. Your version is: %d.%d.%d\n" % sys.version_info[:3]) if options["interactive"]: logger.info( "--------------------------------------------------------------------------------\n" "This script will configure the database and prepare it for use.\n" "--------------------------------------------------------------------------------\n" ) raw_input("Press [enter] to continue...") # Assuming uid '0' is always root if not is_windows() and hasattr(os, "getuid") and os.getuid() == 0: logger.info( "-------------------------------------------------------------------\n" "WARNING: You are installing KA-Lite as root user!\n" " Installing as root may cause some permission problems while running\n" " as a normal user in the future.\n" "-------------------------------------------------------------------\n" ) if options["interactive"]: if not raw_input_yn("Do you wish to continue and install it as root?"): raise CommandError("Aborting script.\n") database_kind = settings.DATABASES["default"]["ENGINE"] if "sqlite" in database_kind: database_file = settings.DATABASES["default"]["NAME"] else: database_file = None database_exists = database_file and os.path.isfile(database_file) # An empty file is created automatically even when the database dosn't # exist. But if it's empty, it's safe to overwrite. database_exists = database_exists and os.path.getsize( database_file) > 0 install_clean = not database_exists if database_file: if not database_exists: install_clean = True else: # We found an existing database file. By default, # we will upgrade it; users really need to work hard # to delete the file (but it's possible, which is nice). logger.info( "-------------------------------------------------------------------\n" "WARNING: Database file already exists!\n" "-------------------------------------------------------------------" ) if not options["interactive"] \ or raw_input_yn("Keep database file and upgrade to KA Lite version %s? " % VERSION) \ or not raw_input_yn("Remove database file '%s' now? " % database_file) \ or not raw_input_yn("WARNING: all data will be lost! Are you sure? "): install_clean = False logger.info("Upgrading database to KA Lite version %s" % VERSION) else: install_clean = True logger.info("OK. We will run a clean install; ") # After all, don't delete--just move. logger.info( "the database file will be moved to a deletable " "location." ) if not install_clean and not database_file: # Make sure that, for non-sqlite installs, the database exists. raise Exception( "For databases not using SQLite, you must set up your database before running setup.") # Do all input at once, at the beginning if install_clean and options["interactive"]: if not options["username"] or not options["password"]: logger.info( "Please choose a username and password for the admin account on this device.\n" " You must remember this login information, as you will need\n" " to enter it to administer this installation of KA Lite." ) (username, password) = get_username_password( options["username"], options["password"]) email = options["email"] (hostname, description) = get_hostname_and_description( options["hostname"], options["description"]) else: username = options["username"] = ( options["username"] or getattr(settings, "INSTALL_ADMIN_USERNAME", None) or get_clean_default_username() ) password = options["password"] or getattr( settings, "INSTALL_ADMIN_PASSWORD", None) email = options["email"] # default is non-empty hostname = options["hostname"] description = options["description"] if username and not validate_username(username): raise CommandError( "Username must contain only letters, digits, and underscores, and start with a letter.\n") ######################## # Now do stuff ######################## # Move database file (if exists) if install_clean and database_file and os.path.exists(database_file): if not settings.DB_TEMPLATE_DEFAULT or database_file != settings.DB_TEMPLATE_DEFAULT: # This is an overwrite install; destroy the old db dest_file = tempfile.mkstemp()[1] logger.info( "(Re)moving database file to temp location, starting " "clean install. Recovery location: {recovery:s}".format( recovery=dest_file ) ) shutil.move(database_file, dest_file) if settings.DB_TEMPLATE_DEFAULT and not database_exists and os.path.exists(settings.DB_TEMPLATE_DEFAULT): logger.info( "Copying database file from {0} to {1}".format( settings.DB_TEMPLATE_DEFAULT, settings.DEFAULT_DATABASE_PATH ) ) shutil.copy( settings.DB_TEMPLATE_DEFAULT, settings.DEFAULT_DATABASE_PATH) else: logger.info( "Baking a fresh database from scratch or upgrading existing " "database." ) call_command( "syncdb", interactive=False, verbosity=options.get("verbosity")) call_command( "migrate", merge=True, verbosity=options.get("verbosity")) Settings.set("database_version", VERSION) # Copy all content item db templates reset_content_db(force=install_clean) # download the english content pack # This can take a long time and lead to Travis stalling. None of this # is required for tests, and does not apply to the central server. if options.get("no-assessment-items", False): logger.warning( "Skipping content pack downloading and configuration.") else: # user wants to force a new download; do it if we can, else error if options['force-assessment-item-dl']: call_command("retrievecontentpack", "download", "en") else: detect_content_packs(options) # Individually generate any prerequisite models/state that is missing if not Settings.get("private_key"): call_command("generatekeys", verbosity=options.get("verbosity")) if not Device.objects.count(): call_command( "initdevice", hostname, description, verbosity=options.get("verbosity")) if not Facility.objects.count(): Facility.initialize_default_facility() # Create the admin user # blank password (non-interactive) means don't create a superuser if password: admin = get_object_or_None(User, username=username) if not admin: call_command("createsuperuser", username=username, email=email, interactive=False, verbosity=options.get("verbosity")) admin = User.objects.get(username=username) admin.set_password(password) admin.save() # Now deploy the static files logger.info("Copying static media...") ensure_dir(settings.STATIC_ROOT) call_command("collectstatic", interactive=False, verbosity=0, clear=True) call_command("collectstatic_js_reverse", interactive=False) # This is not possible in a distributed env if not settings.CENTRAL_SERVER: kalite_executable = 'kalite' if spawn.find_executable(kalite_executable): start_script_path = kalite_executable else: start_script_path = None # Run annotate_content_items, on the distributed server. logger.info( "Annotating availability of all content, checking for content " "in this directory: {content_root:s}".format( content_root=settings.CONTENT_ROOT ) ) try: call_command("annotate_content_items") except OperationalError: pass # done; notify the user. logger.info( "\nCONGRATULATIONS! You've finished setting up the KA Lite " "server software." ) logger.info( "You can now start KA Lite with the following command:" "\n\n" " {kalite_cmd} start" "\n\n".format( kalite_cmd=start_script_path ) ) if options['interactive'] and start_script_path: if raw_input_yn("Do you wish to start the server now?"): logger.info("Running {0} start".format(start_script_path)) p = subprocess.Popen( [start_script_path, "start"], env=os.environ) p.wait()
class TestResumeMethods(KALiteTestCase): ORIGINAL_POINTS = 37 ORIGINAL_ATTEMPTS = 3 ORIGINAL_STREAK_PROGRESS = 20 NEW_POINTS_LARGER = 22 NEW_ATTEMPTS = 5 NEW_STREAK_PROGRESS_LARGER = 10 NEW_POINTS_SMALLER = 0 NEW_STREAK_PROGRESS_SMALLER = 0 EXERCISE_ID = "number_line" EXERCISE_ID2 = "radius_diameter_and_circumference" INVALID_EXERCISE_ID = "s_diameter_and_circumference" USERNAME1 = "test_user_resume1" USERNAME2 = "test_user_resume2" USERNAME3 = "test_user_resume3" PASSWORD = "******" FACILITY = "Test Facility Resume" TIMESTAMP_LATER = datetime.datetime(2014, 11, 17, 20, 51, 2, 342662) TIMESTAMP_EARLY = datetime.datetime(2014, 10, 8, 15, 59, 59, 370290) def setUp(self): """Performed before every test""" # a brand new user self.facility = Facility(name=self.FACILITY) self.facility.save() self.user_with_no_activity = FacilityUser(username=self.USERNAME1, facility=self.facility) self.user_with_no_activity.set_password(self.PASSWORD) self.user_with_no_activity.save() # a user with valid exercises self.user_with_activity = FacilityUser(username=self.USERNAME2, facility=self.facility) self.user_with_activity.set_password(self.PASSWORD) self.user_with_activity.save() # a user with invalid exercises self.user_with_old_activity = FacilityUser(username=self.USERNAME3, facility=self.facility) self.user_with_old_activity.set_password(self.PASSWORD) self.user_with_old_activity.save() # add some exercises for second user (both incomplete) self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user_with_activity, complete=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user=self.user_with_activity, complete=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_POINTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.save() self.original_exerciselog3 = ExerciseLog( exercise_id=self.INVALID_EXERCISE_ID, user=self.user_with_old_activity, complete=False) self.original_exerciselog3.points = self.ORIGINAL_POINTS self.original_exerciselog3.attempts = self.ORIGINAL_POINTS self.original_exerciselog3.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog3.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog3.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog3.save() def test_get_most_recent_incomplete_item(self): '''get_most_recent_incomplete_item()''' # test user with activity first expected = { "id": unicode(self.EXERCISE_ID2, 'utf-8'), "timestamp": self.TIMESTAMP_LATER, "kind": "Exercise" } actual = get_most_recent_incomplete_item(self.user_with_activity) self.assertEqual(expected, actual) # new user just created (no activity logged) self.assertIsNone( get_most_recent_incomplete_item(user=self.user_with_no_activity)) def test_get_empty_list_invalid_resume(self): # Used to mock a request object that is only queried for its 'lang' property. class MicroMock(object): def __init__(self, **kwargs): self.__dict__.update(kwargs) # test user with invalid activity actual = get_resume_recommendations(self.user_with_old_activity, MicroMock(language="en")) # ensure that no recommendations are returned self.assertEqual(len(actual), 0)
def handle(self, *args, **options): if not options["interactive"]: options["username"] = options["username"] or getattr(settings, "INSTALL_ADMIN_USERNAME", None) or get_clean_default_username() options["hostname"] = options["hostname"] or get_host_name() sys.stdout.write(" \n") # blank allows ansible scripts to dump errors cleanly. sys.stdout.write(" _ __ ___ _ _ _ \n") sys.stdout.write(" | | / / / _ \ | | (_) | \n") sys.stdout.write(" | |/ / / /_\ \ | | _| |_ ___ \n") sys.stdout.write(" | \ | _ | | | | | __/ _ \ \n") sys.stdout.write(" | |\ \| | | | | |___| | || __/ \n") sys.stdout.write(" \_| \_/\_| |_/ \_____/_|\__\___| \n") sys.stdout.write(" \n") sys.stdout.write("http://kalite.learningequality.org\n") sys.stdout.write(" \n") sys.stdout.write(" version %s\n" % VERSION) sys.stdout.write(" \n") if sys.version_info >= (2,8) or sys.version_info < (2,6): raise CommandError("You must have Python version 2.6.x or 2.7.x installed. Your version is: %s\n" % sys.version_info) if options["interactive"]: sys.stdout.write("--------------------------------------------------------------------------------\n") sys.stdout.write("\n") sys.stdout.write("This script will configure the database and prepare it for use.\n") sys.stdout.write("\n") sys.stdout.write("--------------------------------------------------------------------------------\n") sys.stdout.write("\n") raw_input("Press [enter] to continue...") sys.stdout.write("\n") # Tried not to be os-specific, but ... hey. :-/ if not is_windows() and hasattr(os, "getuid") and os.getuid() == 502: sys.stdout.write("-------------------------------------------------------------------\n") sys.stdout.write("WARNING: You are installing KA-Lite as root user!\n") sys.stdout.write("\tInstalling as root may cause some permission problems while running\n") sys.stdout.write("\tas a normal user in the future.\n") sys.stdout.write("-------------------------------------------------------------------\n") if options["interactive"]: if not raw_input_yn("Do you wish to continue and install it as root?"): raise CommandError("Aborting script.\n") sys.stdout.write("\n") # Check to see if the current user is the owner of the install directory if not os.access(BASE_DIR, os.W_OK): raise CommandError("You do not have permission to write to this directory!") install_clean = not kalite.is_installed() database_kind = settings.DATABASES["default"]["ENGINE"] database_file = ("sqlite" in database_kind and settings.DATABASES["default"]["NAME"]) or None if database_file and os.path.exists(database_file): # We found an existing database file. By default, # we will upgrade it; users really need to work hard # to delete the file (but it's possible, which is nice). sys.stdout.write("-------------------------------------------------------------------\n") sys.stdout.write("WARNING: Database file already exists! \n") sys.stdout.write("-------------------------------------------------------------------\n") if not options["interactive"] \ or raw_input_yn("Keep database file and upgrade to KA Lite version %s? " % VERSION) \ or not raw_input_yn("Remove database file '%s' now? " % database_file) \ or not raw_input_yn("WARNING: all data will be lost! Are you sure? "): install_clean = False sys.stdout.write("Upgrading database to KA Lite version %s\n" % VERSION) else: install_clean = True sys.stdout.write("OK. We will run a clean install; \n") sys.stdout.write("the database file will be moved to a deletable location.\n") # After all, don't delete--just move. if not install_clean and not database_file and not kalite.is_installed(): # Make sure that, for non-sqlite installs, the database exists. raise Exception("For databases not using SQLIte, you must set up your database before running setup.") # Do all input at once, at the beginning if install_clean and options["interactive"]: if not options["username"] or not options["password"]: sys.stdout.write("\n") sys.stdout.write("Please choose a username and password for the admin account on this device.\n") sys.stdout.write("\tYou must remember this login information, as you will need\n") sys.stdout.write("\tto enter it to administer this installation of KA Lite.\n") sys.stdout.write("\n") (username, password) = get_username_password(options["username"], options["password"]) email = options["email"] (hostname, description) = get_hostname_and_description(options["hostname"], options["description"]) else: username = options["username"] or getattr(settings, "INSTALL_ADMIN_USERNAME", None) password = options["password"] or getattr(settings, "INSTALL_ADMIN_PASSWORD", None) email = options["email"] # default is non-empty hostname = options["hostname"] description = options["description"] if username and not validate_username(username): raise CommandError("Username must contain only letters, digits, and underscores, and start with a letter.\n") ######################## # Now do stuff ######################## # Move database file (if exists) if install_clean and database_file and os.path.exists(database_file): # This is an overwrite install; destroy the old db dest_file = tempfile.mkstemp()[1] sys.stdout.write("(Re)moving database file to temp location, starting clean install. Recovery location: %s\n" % dest_file) shutil.move(database_file, dest_file) # Should clean_pyc for (clean) reinstall purposes call_command("clean_pyc", interactive=False, verbosity=options.get("verbosity"), path=os.path.join(settings.PROJECT_PATH, "..")) # Migrate the database call_command("syncdb", interactive=False, verbosity=options.get("verbosity")) call_command("migrate", merge=True, verbosity=options.get("verbosity")) # Install data if install_clean: # Create device, load on any zone data call_command("generatekeys", verbosity=options.get("verbosity")) call_command("initdevice", hostname, description, verbosity=options.get("verbosity")) Facility.initialize_default_facility() #else: # Device exists; load data if required. # # Hackish, as this duplicates code from initdevice. # #if os.path.exists(InitCommand.data_json_file): # # This is a pathway to install zone-based data on a software upgrade. # sys.stdout.write("Loading zone data from '%s'\n" % InitCommand.data_json_file) # load_data_for_offline_install(in_file=InitCommand.data_json_file) # confirm_or_generate_zone() # Create the admin user if password: # blank password (non-interactive) means don't create a superuser admin = get_object_or_None(User, username=username) if not admin: call_command("createsuperuser", username=username, email=email, interactive=False, verbosity=options.get("verbosity")) admin = User.objects.get(username=username) admin.set_password(password) admin.save() # Now deploy the static files call_command("collectstatic", interactive=False) if not settings.CENTRAL_SERVER: # Move scripts for script_name in ["start", "stop", "run_command"]: script_file = script_name + system_script_extension() dest_dir = os.path.join(settings.PROJECT_PATH, "..") src_dir = os.path.join(dest_dir, "scripts") shutil.copyfile(os.path.join(src_dir, script_file), os.path.join(dest_dir, script_file)) shutil.copystat(os.path.join(src_dir, script_file), os.path.join(dest_dir, script_file)) start_script_path = os.path.realpath(os.path.join(settings.PROJECT_PATH, "..", "start%s" % system_script_extension())) # Run videoscan, on the distributed server. sys.stdout.write("Scanning for video files in the content directory (%s)\n" % settings.CONTENT_ROOT) call_command("videoscan") # done; notify the user. sys.stdout.write("\n") if install_clean: sys.stdout.write("CONGRATULATIONS! You've finished setting up the KA Lite server software.\n") sys.stdout.write("\tPlease run '%s' to start the server,\n" % start_script_path) sys.stdout.write("\tthen load one of the following addresses in your browser to complete the configuration:\n") for ip in get_ip_addresses(): sys.stdout.write("\t\thttp://%s:%d/\n" % (ip, settings.USER_FACING_PORT())) else: sys.stdout.write("CONGRATULATIONS! You've finished updating the KA Lite server software.\n") sys.stdout.write("\tPlease run '%s' to start the server.\n" % start_script_path) sys.stdout.write("\n")
class TestNextMethods(KALiteTestCase): ORIGINAL_POINTS = 37 ORIGINAL_ATTEMPTS = 0 ORIGINAL_STREAK_PROGRESS = 20 NEW_POINTS_LARGER = 22 NEW_ATTEMPTS = 5 NEW_STREAK_PROGRESS_LARGER = 10 NEW_POINTS_SMALLER = 0 NEW_STREAK_PROGRESS_SMALLER = 0 EXERCISE_ID = "number_line" EXERCISE_ID2 = "radius_diameter_and_circumference" EXERCISE_ID_STRUGGLE = "counting-out-1-20-objects" USERNAME1 = "test_user_next1" USERNAME2 = "test_user_next2" PASSWORD = "******" FACILITY = "Test Facility Next Steps" TIMESTAMP_LATER = datetime.datetime(2014, 11, 17, 20, 51, 2, 342662) TIMESTAMP_EARLY = datetime.datetime(2014, 10, 8, 15, 59, 59, 370290) TIMESTAMP_STRUGGLE = datetime.datetime(2014, 9, 17, 17, 43, 36, 405260) GROUP = 'Test Group Next Steps' def setUp(self): '''Performed before every test''' # create a facility and user that can be referred to in models across tests self.facility = Facility(name=self.FACILITY) self.facility.save() self.facilitygroup = FacilityGroup(name=self.GROUP, description="", facility=self.facility) self.facilitygroup.save() self.user1 = FacilityUser(username=self.USERNAME1, facility=self.facility, group=self.facilitygroup) self.user1.set_password(self.PASSWORD) self.user1.save() self.user2 = FacilityUser(username=self.USERNAME2, facility=self.facility, group=self.facilitygroup) self.user2.set_password(self.PASSWORD) self.user2.save() #user 1 - now add some mock data into exercise log self.original_exerciselog = ExerciseLog(exercise_id=self.EXERCISE_ID, user=self.user1) self.original_exerciselog.points = self.ORIGINAL_POINTS self.original_exerciselog.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog.save() #user 2 self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID, user = self.user2, struggling=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_EARLY self.original_exerciselog2.save() self.original_exerciselog2 = ExerciseLog(exercise_id=self.EXERCISE_ID2, user = self.user2, struggling=False) self.original_exerciselog2.points = self.ORIGINAL_POINTS self.original_exerciselog2.attempts = self.ORIGINAL_ATTEMPTS self.original_exerciselog2.streak_progress = self.ORIGINAL_STREAK_PROGRESS self.original_exerciselog2.latest_activity_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.completion_timestamp = self.TIMESTAMP_LATER self.original_exerciselog2.save() self.original_exerciselog3 = ExerciseLog(exercise_id=self.EXERCISE_ID_STRUGGLE, user = self.user2, struggling=True) self.original_exerciselog3.points = self.ORIGINAL_POINTS self.original_exerciselog3.attempts = self.ORIGINAL_POINTS #intentionally made larger to trigger struggling self.original_exerciselog3.streak_progress = 0 self.original_exerciselog3.attempts = 100 self.original_exerciselog3.latest_activity_timestamp = self.TIMESTAMP_STRUGGLE self.original_exerciselog3.completion_timestamp = self.TIMESTAMP_STRUGGLE self.original_exerciselog3.save() #set all other exercise's struggling param to false def test_group_recommendations(self): '''get_group_recommendations()''' user = FacilityUser.objects.filter(username=self.USERNAME1)[0] expected = ["radius_diameter_and_circumference"] actual = get_group_recommendations(user) self.assertEqual(expected, actual, "Group recommendations incorrect.") def test_struggling(self): '''get_struggling_exercises()''' expected = [unicode(self.EXERCISE_ID_STRUGGLE, 'utf-8')] actual = get_struggling_exercises(FacilityUser .objects .filter(username=self.USERNAME2) .order_by('-id')[0]) self.assertSequenceEqual(expected, actual, "Struggling return incorrect.") def test_exercise_prereqs(self): '''get_exercise_prereqs()''' ex_id = 'equivalent_fractions' expected = ['visualizing-equivalent-fractions'] actual = get_exercise_prereqs([ex_id]) self.assertEqual(expected, actual, "Exercise Prereqs incorrect.")