def test_load_class(self, request, database_backend, class_data):
        """Class loaded has same data as that saved in db, with class/student ids."""
        test_database = request.getfixturevalue(database_backend)
        preexisting_class = request.getfixturevalue(class_data)
        # Create test NewClass object, mocking avatar_files.
        preexisting_class = NewClass.from_dict(preexisting_class.json_dict())
        for student in preexisting_class:
            if student.avatar_id:
                Path(preexisting_class.temp_avatars_dir,
                     student.avatar_id).write_text(student.avatar_id)
        # Create class in db:
        test_database.create_class(preexisting_class)

        # Find class id, load class to verify:
        classes = test_database.get_classes()
        test_full_class_id = classes[
            0].id  # As the only class will be first item.

        # Loaded class will have ids:
        test_loaded_class_with_student_ids = Class.from_dict(
            preexisting_class.json_dict())
        if isinstance(test_database, JSONDatabase):
            for student in test_loaded_class_with_student_ids.students:
                student.id = student.name
        if not isinstance(test_database, JSONDatabase):
            # This should be accurate for most sql databases.
            for test_id, student in enumerate(
                    test_loaded_class_with_student_ids.students, start=1):
                student.id = test_id

        assert test_database.load_class(test_full_class_id).json_dict(
        ) == test_loaded_class_with_student_ids.json_dict()
Beispiel #2
0
class TestAssembleChartData:
    @pytest.mark.parametrize('class_from_create_class',
                             [Class.from_dict(test_full_class_data_set['json_dict_rep']),  # Pass in test_class
                              NewClass.from_dict(test_full_class_data_set['json_dict_rep'])  # NewClass obj
                              ])
    def test_assemble_chart_data(self, monkeypatch, class_from_create_class):
        test_chart_name = 'my_chart'
        test_chart_filename = test_chart_name
        mock_score_avatar_dict = {'scores': 'list of avatars'}
        mock_chart_params = {'some': 'chart_params'}

        def mocked_take_score_data(class_obj):
            assert class_obj is class_from_create_class
            return mock_score_avatar_dict

        def mocked_take_chart_name():
            return test_chart_name

        def mocked_clean_for_filename(chart_name):
            assert chart_name == test_chart_name
            return test_chart_name

        def mocked_set_chart_params():
            return mock_chart_params

        monkeypatch.setattr(create_chart, 'take_score_data', mocked_take_score_data)
        monkeypatch.setattr(create_chart, 'take_chart_name', mocked_take_chart_name)
        monkeypatch.setattr(create_chart, 'clean_for_filename', mocked_clean_for_filename)
        monkeypatch.setattr(create_chart, 'set_chart_params', mocked_set_chart_params)

        assert assemble_chart_data(class_from_create_class) == (
            test_chart_name, test_chart_filename, mock_score_avatar_dict, mock_chart_params)
    def test_create_class(self, request, empty_sqlite_database, class_data):
        test_database = empty_sqlite_database
        test_class_data = request.getfixturevalue(class_data)
        # Create test NewClass object, mocking avatar_files.
        test_class = NewClass.from_dict(test_class_data.json_dict())
        for student in test_class:
            if student.avatar_id:
                Path(test_class.temp_avatars_dir,
                     student.avatar_id).write_text(student.avatar_id)

        # no students or class in empty db:
        assert not test_database._connection().cursor().execute(
            """SELECT * FROM class""").fetchall()
        assert not test_database._connection().cursor().execute(
            """SELECT * FROM student""").fetchall()

        # Create class in db:
        assert test_database.create_class(test_class) is None

        # Find class id, load class to verify:
        classes = test_database.get_classes()
        test_class_id = classes[0].id

        # Class will have ids:
        test_loaded_class_with_student_ids = Class.from_dict(
            test_class.json_dict()).json_dict()
        for test_id, student in enumerate(
                test_loaded_class_with_student_ids['students'], start=1):
            student['id'] = test_id

        assert test_database.load_class(  # NB Returned object will be Class, not NewClass:
            test_class_id).json_dict() == test_loaded_class_with_student_ids
Beispiel #4
0
class TestNewChart:
    @pytest.mark.parametrize('user_wants_to_save', [True, False], ids=['User saving.', 'User not saving.'])
    @pytest.mark.parametrize('class_from_create_class',
                             [None,  # Test Full class fixture
                              Class.from_dict(test_full_class_data_set['json_dict_rep']),  # Pass in test_class
                              NewClass.from_dict(test_full_class_data_set['json_dict_rep'])  # NewClass obj
                              ])
    def test_new_chart(self, monkeypatch, empty_generic_database,
                       class_from_create_class, test_full_class,
                       user_wants_to_save):
        # Test class either passed, or instantiated if None is passed.
        test_class = class_from_create_class or test_full_class

        test_chart_name = 'test_chart_name'
        test_chart_default_filename = 'test_chart_default_filename'
        test_chart_params = {'test_chart_params': 'some chart params'}
        test_score_avatar_dict = {'test_student_scores': 'test student avatars'}

        test_chart_data_dict = {'class_id': test_class.id,
                                'class_name': test_class.name,
                                'chart_name': test_chart_name,
                                'chart_default_filename': test_chart_default_filename,
                                'chart_params': test_chart_params,
                                'score-students_dict': test_score_avatar_dict,
                                }

        test_chart_image_location = 'some image location'

        def mocked_select_classlist():
            if class_from_create_class:
                raise ValueError('select_classlist should not be called if a class is passed.')
            return test_full_class.name

        def mocked_get_classes():
            if class_from_create_class:
                raise ValueError('Function should not be called if class is passed.')
            return test_class.name

        def mocked_load_class(class_name):
            if class_from_create_class:
                raise ValueError('Function should not be called if class is passed.')
            return test_class

        def mocked_assemble_chart_data(class_obj):
            return (test_chart_name,
                    test_chart_default_filename,
                    test_score_avatar_dict,
                    test_chart_params)

        def mocked_create_chart(chart_data_dict):
            assert chart_data_dict == test_chart_data_dict

        def mocked_generate_chart_image(chart_data_dict):
            assert chart_data_dict == test_chart_data_dict
            return test_chart_image_location

        def mocked_show_image(chart_image_location):
            assert chart_image_location == test_chart_image_location
            return user_wants_to_save

        user_save_chart_image_mock = {'called': False}

        def mocked_user_save_chart_image(chart_data_dict, chart_image_location):
            assert chart_data_dict == test_chart_data_dict
            assert chart_image_location == test_chart_image_location
            user_save_chart_image_mock['called'] = True
            if not user_wants_to_save:
                raise ValueError('Should not be called if user did not want to save.')

        test_database = empty_generic_database
        test_database.load_class = mocked_load_class
        test_database.get_classes = mocked_get_classes
        test_database.create_chart = mocked_create_chart

        monkeypatch.setattr(definitions, 'DATABASE', test_database)
        monkeypatch.setattr(create_chart, 'select_classlist', mocked_select_classlist)
        monkeypatch.setattr(create_chart, 'assemble_chart_data', mocked_assemble_chart_data)
        monkeypatch.setattr(create_chart, 'generate_chart_image', mocked_generate_chart_image)
        monkeypatch.setattr(create_chart, 'show_image', mocked_show_image)
        monkeypatch.setattr(create_chart, 'user_save_chart_image', mocked_user_save_chart_image)

        assert new_chart(class_from_create_class) is None

        assert user_save_chart_image_mock['called'] is user_wants_to_save
    def test_save_chart_image(self, request, database_backend, test_full_class,
                              tmpdir):
        """
        Verify API works.

        NB No db verification in API test, as API for verifying does not exist.
        TODO: Verify db saved chart contents when load/edit features added.
        """
        test_database = request.getfixturevalue(database_backend)

        test_existing_class = NewClass.from_dict(test_full_class.json_dict())
        for student in test_existing_class:
            if student.avatar_id:
                Path(test_existing_class.temp_avatars_dir,
                     student.avatar_id).write_text(student.avatar_id)
        # Create class in db:
        test_database.create_class(test_existing_class)

        # Find class id to load:
        classes = test_database.get_classes()
        test_class_id = classes[0].id

        # test_class = Class.from_dict(test_full_class_data_set['json_dict_rep'])
        test_class = test_database.load_class(test_class_id)

        test_data_dict = {
            'class_id': test_class_id,
            'class_name': "test_class_name",
            'chart_name': "test_chart_name",
            'chart_default_filename': "test_chart_default_filename",
            'chart_params': {
                "some": "chart",
                "default": "params"
            },
            'score-students_dict': {
                0: [test_class.students[0]],  # Cali
                1: [
                    test_class.students[1],  # Monty
                    test_class.students[7]
                ],  # Regina
                3: [
                    test_class.students[2],  # Abby
                    test_class.students[9]
                ],  # Alex
                # No score, not returned: None: [test_class.students[3],  # Zach
                #                                test_class.students[11]],  # Edgar
                50: [test_class.students[4]],  # Janell
                99: [test_class.students[5]],  # Matthew
                100: [test_class.students[6]],  # Olivia
                2: [test_class.students[8]],  # Ashley
                4: [test_class.students[10]],  # Melissa
                6: [test_class.students[12]],  # Danielle
                7: [test_class.students[13]],  # Kayla
                8: [test_class.students[14]],  # Jaleigh
            },
        }
        # Create chart in db:
        test_database.create_chart(test_data_dict)

        mock_plt = plt.figure(figsize=(19.20, 10.80))

        test_image = io.BytesIO()
        # Images must both be saved as '.png' for comparison.
        test_image_path = Path(tmpdir, 'test image.png')
        mock_plt.savefig(test_image_path, format='png', dpi=300)
        test_image.seek(0)  # Return pointer to start of binary stream.

        save_chart_path = test_database.save_chart_image(
            test_data_dict, mock_plt)
        # Return pointer:
        test_image.seek(0)  # Return pointer to start of binary stream.
        # Path exists ad image at path is expected data:
        assert save_chart_path.exists()

        compare_images(save_chart_path, test_image_path, 0.0001)
Beispiel #6
0
class TestMoveAvatarsToClassData:
    @pytest.mark.parametrize(
        'test_new_class, expected_moved_avatars',
        [
            (NewClass('test empty class'), []),  # No students
            # All students have avatar_id
            (NewClass.from_dict({
                'name':
                'test_class',
                'students': [
                    {
                        'name': 'Cali',
                        'avatar_id': 'Cali_avatar.png'
                    },
                    {
                        'name': 'Zach',
                        'avatar_id': 'Zach_avatar.png'
                    },
                    {
                        'name': 'Ashley',
                        'avatar_id': 'Ashley_avatar.png'
                    },
                    {
                        'name': 'Danielle',
                        'avatar_id': 'Danielle_avatar.png'
                    },
                ]
            }), [
                'Cali_avatar.png',
                'Zach_avatar.png',
                'Ashley_avatar.png',
                'Danielle_avatar.png',
            ]),
            # Some students have avatar_id
            (NewClass.from_dict(test_full_class_data_set['json_dict_rep']), [
                'Cali_avatar.png',
                'Zach_avatar.png',
                'Ashley_avatar.png',
                'Danielle_avatar.png',
            ]),
            # No students have avatar_id
            (NewClass.from_dict({
                'name':
                'test_class',
                'students': [
                    {
                        'name': 'Cali'
                    },
                    {
                        'name': 'Zach'
                    },
                    {
                        'name': 'Ashley'
                    },
                    {
                        'name': 'Danielle'
                    },
                ]
            }), []),
        ])
    def test_move_avatars_to_class_data(self, empty_json_database,
                                        test_new_class,
                                        expected_moved_avatars):
        """Avatar files copied from original locations to class data."""
        test_json_database = empty_json_database
        moved_avatars = []

        def mock_move_avatar_to_class_data(test_class: NewClass,
                                           avatar_filename: str):
            assert test_class is test_new_class
            moved_avatars.append(avatar_filename)

        empty_json_database._move_avatar_to_class_data = mock_move_avatar_to_class_data

        assert test_json_database._move_avatars_to_class_data(
            test_new_class) is None
        assert moved_avatars == expected_moved_avatars
Beispiel #7
0
    def test_generate_avatar_coords_backends(self, request, monkeypatch,
                                             database_backend):
        test_database = request.getfixturevalue(database_backend)
        test_database.default_avatar_path = 'mocked_default_avatar_path'

        test_existing_class = NewClass.from_dict(
            test_full_class_data_set['json_dict_rep'])
        for student in test_existing_class:
            if student.avatar_id:
                Path(test_existing_class.temp_avatars_dir,
                     student.avatar_id).write_text(student.avatar_id)
        # Create class in db:
        test_database.create_class(test_existing_class)

        # Find class id to load:
        classes = test_database.get_classes()
        test_class_id = classes[0].id

        # test_class = Class.from_dict(test_full_class_data_set['json_dict_rep'])
        test_class = test_database.load_class(test_class_id)

        monkeypatch.setattr(process_chart_data.definitions, 'DATABASE',
                            test_database)

        # student_score_entry_sequence = [0, 1, 3, None, 50, 99, 100, 1, 2, 3, 4, None, 6, 7, 8]
        test_student_scores_dict = {
            0: [test_class.students[0]],  # Cali
            1: [
                test_class.students[1],  # Monty
                test_class.students[7]
            ],  # Regina
            3: [
                test_class.students[2],  # Abby
                test_class.students[9]
            ],  # Alex
            # No score, not returned: None: [test_class.students[3],  # Zach
            #                                test_class.students[11]],  # Edgar
            50: [test_class.students[4]],  # Janell
            99: [test_class.students[5]],  # Matthew
            100: [test_class.students[6]],  # Olivia
            2: [test_class.students[8]],  # Ashley
            4: [test_class.students[10]],  # Melissa
            6: [test_class.students[12]],  # Danielle
            7: [test_class.students[13]],  # Kayla
            8: [test_class.students[14]],  # Jaleigh
        }

        # Vary calls for actual avatars based on backend.
        test_generate_avatar_coords_result = {
            **{
                'mocked_default_avatar_path': [(0.0, 15), (0.0, 25), (0.0, 45),
                                               (0.0, 55), (0.0, 65), (10.0, 15),
                                               (10.0, 25), (50.0, 5), (100.0, 5),
                                               (100.0, 15)],
            },
            **({
                test_database.get_avatar_path_class_filename(
                    test_class.id, test_class.students[8].avatar_id): [(0.0, 35)],  # Ashley
                test_database.get_avatar_path_class_filename(
                    test_class.id, test_class.students[0].avatar_id): [(0.0, 5)],  # Cali
                test_database.get_avatar_path_class_filename(
                    test_class.id, test_class.students[12].avatar_id): [(10.0, 5)],  # Danielle
            } if isinstance(test_database, JSONDatabase) else {
                   test_database.get_avatar_path(test_class.students[8].avatar_id): [(0.0, 35)],  # Ashley
                   test_database.get_avatar_path(test_class.students[0].avatar_id): [(0.0, 5)],  # Cali
                   test_database.get_avatar_path(test_class.students[12].avatar_id): [(10.0, 5)],  # Danielle
               }),
        }

        assert generate_avatar_coords(
            test_student_scores_dict,
            test_class.id) == test_generate_avatar_coords_result
    def test_save_chart_image(self, empty_sqlite_database, test_full_class):
        test_database = empty_sqlite_database

        test_existing_class = NewClass.from_dict(test_full_class.json_dict())
        for student in test_existing_class:
            if student.avatar_id:
                Path(test_existing_class.temp_avatars_dir,
                     student.avatar_id).write_text(student.avatar_id)
        # Create class in db:
        test_database.create_class(test_existing_class)

        # Find class id to load:
        classes = test_database.get_classes()
        test_class_id = classes[0].id

        # test_class = Class.from_dict(test_full_class_data_set['json_dict_rep'])
        test_class = test_database.load_class(test_class_id)

        test_data_dict = {
            'class_id': test_class_id,
            'class_name': "test_class_name",
            'chart_name': "test_chart_name",
            'chart_default_filename': "test_chart_default_filename",
            'chart_params': {
                "some": "chart",
                "default": "params"
            },
            'score-students_dict': {
                0: [test_class.students[0]],  # Cali
                1: [
                    test_class.students[1],  # Monty
                    test_class.students[7]
                ],  # Regina
                3: [
                    test_class.students[2],  # Abby
                    test_class.students[9]
                ],  # Alex
                # No score, not returned: None: [test_class.students[3],  # Zach
                #                                test_class.students[11]],  # Edgar
                50: [test_class.students[4]],  # Janell
                99: [test_class.students[5]],  # Matthew
                100: [test_class.students[6]],  # Olivia
                2: [test_class.students[8]],  # Ashley
                4: [test_class.students[10]],  # Melissa
                6: [test_class.students[12]],  # Danielle
                7: [test_class.students[13]],  # Kayla
                8: [test_class.students[14]],  # Jaleigh
            },
        }
        # Create chart in db:
        test_database.create_chart(test_data_dict)

        mock_plt = plt.figure(figsize=(19.20, 10.80))

        test_image = io.BytesIO()
        mock_plt.savefig(test_image, format='png', dpi=300)
        test_image.seek(0)  # Return pointer to start of binary stream.

        save_chart_path = test_database.save_chart_image(
            test_data_dict, mock_plt)
        # Return pointer:
        test_image.seek(0)  # Return pointer to start of binary stream.
        # Path exists ad image at path is expected data:
        assert save_chart_path.exists()
        assert save_chart_path.read_bytes() == test_image.read1(
        )  # size arg can be omitted on 3.7+