Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
    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.")
Ejemplo n.º 4
0
    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)
Ejemplo n.º 6
0
    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.")
Ejemplo n.º 7
0
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")
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
    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")
Ejemplo n.º 10
0
    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()
Ejemplo n.º 11
0
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()
Ejemplo n.º 12
0
    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,))
Ejemplo n.º 13
0
	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()
Ejemplo n.º 14
0
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()
Ejemplo n.º 15
0
    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,))
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
    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()
Ejemplo n.º 18
0
 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()
Ejemplo n.º 19
0
    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)
Ejemplo n.º 20
0
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")
Ejemplo n.º 21
0
    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()
Ejemplo n.º 22
0
    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.")
Ejemplo n.º 23
0
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()
Ejemplo n.º 24
0
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(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()
Ejemplo n.º 26
0
    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()
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
 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()
Ejemplo n.º 30
0
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()
Ejemplo n.º 31
0
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")
Ejemplo n.º 32
0
    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")
Ejemplo n.º 33
0
    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.")
Ejemplo n.º 34
0
    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()
Ejemplo n.º 35
0
    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()
Ejemplo n.º 36
0
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()
Ejemplo n.º 37
0
    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()
Ejemplo n.º 38
0
    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()
Ejemplo n.º 39
0
    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.")
Ejemplo n.º 40
0
    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() 
Ejemplo n.º 41
0
    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.")
Ejemplo n.º 42
0
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.")
Ejemplo n.º 43
0
    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()
Ejemplo n.º 44
0
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.")
Ejemplo n.º 45
0
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.")
Ejemplo n.º 46
0
 def test_issue_697_part2(self):
     self.facility = Facility(name=self.FACILITY_NAME)
     self.facility.save()
     self.test_delete_org()
Ejemplo n.º 47
0
 def test_issue_697_part2(self):
     self.facility = Facility(name=self.FACILITY_NAME)
     self.facility.save()
     self.test_delete_org()
Ejemplo n.º 48
0
    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()
Ejemplo n.º 49
0
 def test_issue_697_part1(self):
     self.facility = Facility(name=self.FACILITY_NAME)
     self.facility.save()
     self.test_delete_zone_from_org_admin()
Ejemplo n.º 50
0
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.")
Ejemplo n.º 51
0
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.")
Ejemplo n.º 52
0
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)
Ejemplo n.º 53
0
 def test_issue_697_part1(self):
     self.facility = Facility(name=self.FACILITY_NAME)
     self.facility.save()
     self.test_delete_zone_from_org_admin()
Ejemplo n.º 54
0
    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()
Ejemplo n.º 55
0
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)
Ejemplo n.º 56
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")
Ejemplo n.º 57
0
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.")