def setUp(self): super(BasePeerReviewStageTest, self).setUp() self.project_api_mock.get_workgroups_to_review = mock.Mock( return_value=OTHER_GROUPS.values()) self.project_api_mock.get_workgroup_reviewers = mock.Mock( return_value=[{ "id": user.id } for user in KNOWN_USERS.values()])
def setUp(self): super(TestOtherGroupSubmissionLinks, self).setUp() self.project_api_mock.get_workgroups_to_review = mock.Mock( return_value=OTHER_GROUPS.values()) self.project_api_mock.get_workgroup_reviewers = mock.Mock( return_value=[{ "id": user.id } for user in KNOWN_USERS.values()])
def setUp(self): super(TestOtherGroupSubmissionLinks, self).setUp() self.project_api_mock.get_workgroups_to_review = mock.Mock(return_value=OTHER_GROUPS.values()) self.project_api_mock.get_workgroup_reviewers = mock.Mock(return_value=[ {"id": user.id} for user in KNOWN_USERS.values() ])
def setUp(self): super(BasePeerReviewStageTest, self).setUp() self.project_api_mock.get_workgroups_to_review = mock.Mock(return_value=OTHER_GROUPS.values()) self.project_api_mock.get_workgroup_reviewers = mock.Mock(return_value=[ {"id": user.id} for user in KNOWN_USERS.values() ])
class TestBaseGroupActivityStage(BaseStageTest): """ Tests for Base Stage Class """ block_to_test = DummyStageBlock def setUp(self): super(TestBaseGroupActivityStage, self).setUp() self.render_template_patch = self.make_patch(self.block, 'render_template') # invalid name in order to match camlCase naming of assertSomething methods def assertDictionaryEqual(self, actual, expected, strict=False): # pylint: disable=invalid-name """ Less strict assert for dictionary equality - checks that `actual` contains all the keys from expected, and values match. If `strict` is true, also checks that no other keys are present in the `actual` (roughly equal to plain assertEqual) :param dict[Any, Any] actual: actual result :param dict[Any, ANy] expected: expected result :param bool strict: Strict comparison: If set to False allows `actual` to contain keys not found in `expected`. If True - requires that no other keys are present in `actual` - roughly equivalent to plain assertEqual """ for key, value in expected.iteritems(): self.assertIn(key, actual) self.assertEqual(actual[key], value) if strict: self.assertEqual(actual.keys(), expected.keys()) @ddt.data( ([WORKGROUP], KNOWN_USERS.values(), StageState.COMPLETED, make_stats(1.0, 0, 0)), ([WORKGROUP], KNOWN_USERS.values(), StageState.INCOMPLETE, make_stats(0.3, 0.4, 0.3)), (OTHER_GROUPS, KNOWN_USERS.values(), StageState.INCOMPLETE, make_stats(0.3, 0.4, 0.3)), (OTHER_GROUPS, KNOWN_USERS.values(), StageState.NOT_STARTED, make_stats(0.0, 0.0, 1.0)), ) @ddt.unpack def test_dashboard_view(self, workgroups, target_students, state, stats): render_template_response = u'render_template_response' is_ta_graded = False patched_stats = self.make_patch(self.block, 'get_dashboard_stage_state') patched_stats.return_value = (state, stats) type(self.activity_mock).is_ta_graded = mock.PropertyMock( return_value=is_ta_graded) self.render_template_patch.return_value = render_template_response context = make_context(workgroups, target_students, []) expected_human_stats = get_human_stats(stats[StageState.COMPLETED], stats[StageState.INCOMPLETE], stats[StageState.NOT_STARTED]) expected_context = { 'stage': self.block, 'stats': expected_human_stats, 'stage_state': state, 'ta_graded': is_ta_graded } with mock.patch('group_project_v2.stage.base.Fragment.add_content' ) as patched_add_content: self.block.dashboard_view(context) patched_add_content.assert_called_once_with( render_template_response) # single call - roughly equivalent to assert_called_once_with(...) self.assertEqual(len(self.render_template_patch.call_args_list), 1) args, kwargs = self.render_template_patch.call_args_list[0] self.assertEqual(kwargs, {}) self.assertEqual(len(args), 2) self.assertEqual(args[0], 'dashboard_view') self.assertDictionaryEqual(args[1], expected_context) @ddt.data( # not filtered - pass all students ([WORKGROUP], KNOWN_USERS.values(), [], KNOWN_USERS.values()), # single filter hit - pass all except that student ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.USER1_ID], [KNOWN_USERS[TEST_USERS.USER2_ID], KNOWN_USERS[TEST_USERS.USER3_ID]]), # multiple filter hits - pass all except that students ([WORKGROUP], KNOWN_USERS.values(), [ TEST_USERS.USER1_ID, TEST_USERS.USER3_ID ], [KNOWN_USERS[TEST_USERS.USER2_ID]]), # filter "miss" - pass all ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.UNKNOWN_USER ], KNOWN_USERS.values()), # filter hit and miss - pass all expcept hit ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.USER2_ID, TEST_USERS.UNKNOWN_USER], [KNOWN_USERS[TEST_USERS.USER1_ID], KNOWN_USERS[TEST_USERS.USER3_ID]]), # filtered all - pass no students ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.USER1_ID, TEST_USERS.USER2_ID, TEST_USERS.USER3_ID], []), ) @ddt.unpack def test_dashboard_view_filters_students(self, workgroups, target_students, filtered_students, expected_students): patched_stats = self.make_patch(self.block, 'get_dashboard_stage_state') patched_stats.return_value = (StageState.COMPLETED, make_stats(1.0, 0.0, 0.0)) context = make_context(workgroups, target_students, filtered_students) with mock.patch('group_project_v2.stage.base.Fragment.add_content'): self.block.dashboard_view(context) patched_stats.assert_called_once_with(workgroups, expected_students) def test_get_external_group_status(self): self.assertEqual(self.block.get_external_group_status('irrelevant'), StageState.NOT_AVAILABLE) def test_get_external_status_label(self): self.assertEqual(self.block.get_external_status_label('irrelevant'), self.block.DEFAULT_EXTERNAL_STATUS_LABEL)
class TestBaseGroupActivityStage(BaseStageTest): """ Tests for Base Stage Class """ block_to_test = DummyStageBlock def setUp(self): super(TestBaseGroupActivityStage, self).setUp() self.render_template_patch = self.make_patch(self.block, 'render_template') def test_stage_is_not_graded(self): self.assertFalse(self.block.is_graded_stage) def test_stage_is_not_shown_on_detail_dashboard(self): self.assertFalse(self.block.shown_on_detail_view) # invalid name in order to match camlCase naming of assertSomething methods def assertDictionaryEqual(self, actual, expected, strict=False): # pylint: disable=invalid-name """ Less strict assert for dictionary equality - checks that `actual` contains all the keys from expected, and values match. If `strict` is true, also checks that no other keys are present in the `actual` (roughly equal to plain assertEqual) :param dict[Any, Any] actual: actual result :param dict[Any, ANy] expected: expected result :param bool strict: Strict comparison: If set to False allows `actual` to contain keys not found in `expected`. If True - requires that no other keys are present in `actual` - roughly equivalent to plain assertEqual """ for key, value in expected.iteritems(): self.assertIn(key, actual) self.assertEqual(actual[key], value) if strict: self.assertEqual(actual.keys(), expected.keys()) @ddt.data( ([WORKGROUP], KNOWN_USERS.values(), StageState.COMPLETED, make_stats(1.0, 0, 0)), ([WORKGROUP], KNOWN_USERS.values(), StageState.INCOMPLETE, make_stats(0.3, 0.4, 0.3)), (OTHER_GROUPS, KNOWN_USERS.values(), StageState.INCOMPLETE, make_stats(0.3, 0.4, 0.3)), (OTHER_GROUPS, KNOWN_USERS.values(), StageState.NOT_STARTED, make_stats(0.0, 0.0, 1.0)), ) @ddt.unpack def test_dashboard_view(self, workgroups, target_students, state, stats): render_template_response = u'render_template_response' is_ta_graded = False patched_stats = self.make_patch(self.block, 'get_dashboard_stage_state') patched_stats.return_value = (state, stats) type(self.activity_mock).is_ta_graded = mock.PropertyMock( return_value=is_ta_graded) self.render_template_patch.return_value = render_template_response context = make_context(workgroups, target_students, []) expected_human_stats = BaseGroupActivityStage.make_human_stats(stats) expected_context = { 'stage': self.block, 'stats': expected_human_stats, 'stage_state': state, 'ta_graded': is_ta_graded } with mock.patch('group_project_v2.stage.base.Fragment.add_content' ) as patched_add_content: self.block.dashboard_view(context) patched_add_content.assert_called_once_with( render_template_response) # single call - roughly equivalent to assert_called_once_with(...) self.assertEqual(len(self.render_template_patch.call_args_list), 1) args, kwargs = self.render_template_patch.call_args_list[0] self.assertEqual(kwargs, {}) self.assertEqual(len(args), 2) self.assertEqual(args[0], 'dashboard_view') self.assertDictionaryEqual(args[1], expected_context) @ddt.data((make_stats(0.4, 0.3, 0.4), (40, 30, 40)), (make_stats(0.1, 0.1, 0.8), (80, 10, 10)), (make_stats(None, None, None), (None, None, None))) @ddt.unpack def test_make_human_stats(self, stats, human_stats_data): stats_order = (StageState.NOT_STARTED, StageState.INCOMPLETE, StageState.COMPLETED) actual_human_stats = BaseGroupActivityStage.make_human_stats(stats) expected_human_stats = OrderedDict([ (StageState.get_human_name(stats_order[idx]), human_stats_data[idx]) for idx in range(3) ]) self.assertEqual(actual_human_stats.keys(), expected_human_stats.keys()) for idx, human_stat in enumerate(expected_human_stats.items()): stat_name, stat_value = human_stat actual_stat_value = actual_human_stats[stat_name] self.assertAlmostEqual(stat_value, actual_stat_value) @ddt.data( # not filtered - pass all students ([WORKGROUP], KNOWN_USERS.values(), [], KNOWN_USERS.values()), # single filter hit - pass all except that student ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.USER1_ID], [KNOWN_USERS[TEST_USERS.USER2_ID], KNOWN_USERS[TEST_USERS.USER3_ID]]), # multiple filter hits - pass all except that students ([WORKGROUP], KNOWN_USERS.values(), [ TEST_USERS.USER1_ID, TEST_USERS.USER3_ID ], [KNOWN_USERS[TEST_USERS.USER2_ID]]), # filter "miss" - pass all ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.UNKNOWN_USER ], KNOWN_USERS.values()), # filter hit and miss - pass all expcept hit ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.USER2_ID, TEST_USERS.UNKNOWN_USER], [KNOWN_USERS[TEST_USERS.USER1_ID], KNOWN_USERS[TEST_USERS.USER3_ID]]), # filtered all - pass no students ([WORKGROUP], KNOWN_USERS.values(), [TEST_USERS.USER1_ID, TEST_USERS.USER2_ID, TEST_USERS.USER3_ID], []), ) @ddt.unpack def test_dashboard_view_filters_students(self, workgroups, target_students, filtered_students, expected_students): patched_stats = self.make_patch(self.block, 'get_dashboard_stage_state') patched_stats.return_value = (StageState.COMPLETED, make_stats(1.0, 0.0, 0.0)) context = make_context(workgroups, target_students, filtered_students) with mock.patch('group_project_v2.stage.base.Fragment.add_content'): self.block.dashboard_view(context) patched_stats.assert_called_once_with(workgroups, expected_students) @ddt.data( ([1], [1], [], make_stats(1, 0, 0), True), (range(10), range(3), range(3, 6), make_stats(.3, .3, .4), True), ([], [], [], make_stats(None, None, None), False), ) @ddt.unpack def test_get_stage_stats(self, all_user_ids, completed_user_ids, partial_user_ids, expected_stats, completions_called): all_users = [ make_reduced_user_details(id=user_id) for user_id in all_user_ids ] completed_user_ids = set(completed_user_ids) partial_user_ids = set(partial_user_ids) patched_completions = self.make_patch(self.block, 'get_users_completion') self.block.display_name = "dummy block" patched_completions.return_value = (completed_user_ids, partial_user_ids) target_workgroups = tuple() stats = self.block.get_stage_stats(target_workgroups, all_users) if completions_called: patched_completions.assert_called_once_with( target_workgroups, all_users) else: self.assertFalse(patched_completions.called) self.assertEqual(len(expected_stats), len(stats)) for stat, value in stats.items(): self.assertAlmostEqual(value, expected_stats[stat]) def test_get_external_group_status(self): self.assertEqual(self.block.get_external_group_status('irrelevant'), StageState.NOT_AVAILABLE) def test_get_external_status_label(self): self.assertEqual(self.block.get_external_status_label('irrelevant'), self.block.DEFAULT_EXTERNAL_STATUS_LABEL)