def test_users_with_valid_completed_attempt_counts(self): """ users_with_valid_completed_attempt_counts should return counts of all attempts completed within the time threshold, sorted by highest number of attempts """ task = TaskFactory.create() user1 = UserFactory.create() user2 = UserFactory.create() # Invalid attempt TaskAttemptFactory.create(user=user1, state=TaskAttempt.FINISHED, task=task) # Valid attempts ValidTaskAttemptFactory.create_batch(2, user=user1, state=TaskAttempt.FINISHED, task=task) ValidTaskAttemptFactory.create(user=user2, state=TaskAttempt.FINISHED, task=task) ValidTaskAttemptFactory.create(user=user1, state=TaskAttempt.STARTED, task=task) eq_(user1.taskattempt_set.filter(state=TaskAttempt.STARTED).count(), 1) eq_(user1.taskattempt_set.filter(state=TaskAttempt.FINISHED).count(), 3) eq_(user2.taskattempt_set.filter(state=TaskAttempt.FINISHED).count(), 1) qs = User.users_with_valid_completed_attempt_counts() eq_(len(qs), 2) eq_(qs[0], user1) eq_(qs[0].valid_completed_attempts_count, 2) eq_(qs[1], user2) eq_(qs[1].valid_completed_attempts_count, 1)
def test_save_closes_task_attempts(self): """ When a saved task is unavailable, close any open attempts, and set the attempts to require a notification. """ user1 = UserFactory.create() user2 = UserFactory.create() TaskAttemptFactory.create(user=user1, state=TaskAttempt.STARTED, task=self.task_no_draft) TaskAttemptFactory.create(user=user2, state=TaskAttempt.STARTED, task=self.task_no_draft) eq_( self.task_no_draft.taskattempt_set.filter( state=TaskAttempt.STARTED).count(), 2) self.task_no_draft.is_draft = True self.task_no_draft.save() eq_( TaskAttempt.objects.filter(task=self.task_no_draft, state=TaskAttempt.STARTED).count(), 0) eq_( TaskAttempt.objects.filter(task=self.task_no_draft, state=TaskAttempt.CLOSED, requires_notification=True).count(), 2)
def test_isnt_available_to_user_other_user_non_abandoned_attempt(self): """ If there is a non-abandoned attempt by a different user, the task should not be available. """ user = UserFactory.create() other_user = UserFactory.create() task = TaskFactory.create(repeatable=False) TaskAttemptFactory.create(user=other_user, state=TaskAttempt.STARTED, task=task) eq_(task.is_available_to_user(user), False)
def test_attempt_with_feedback_raises_404(self): """ If the current user has an attempt but feedback has already been provided, return a 404. """ user = UserFactory.create() attempt = TaskAttemptFactory.create(user=user, state=TaskAttempt.FINISHED) FeedbackFactory.create(attempt=attempt) request = Mock(user=UserFactory.create()) with self.assertRaises(Http404): self.view.dispatch(request, pk=attempt.pk)
def test_forbidden_client(self): """ Test user deletion by an authenticated but forbidden client """ forbidden_user = UserFactory.create() forbidden_token = Token.objects.create(user=forbidden_user) self.client.credentials(HTTP_AUTHORIZATION='Token ' + forbidden_token.key) test_user = UserFactory.create() user_uri = self.uri + test_user.email + '/' #Make a DELETE request delete_response = self.client.delete(user_uri) self.assert_response_status(delete_response, status.HTTP_403_FORBIDDEN)
def test_is_available_to_user_no_attempts(self): """ If there are no attempts, the task should be available. """ user = UserFactory.create() eq_(self.task_not_repeatable_no_attempts.is_available_to_user(user), True)
def test_save_processes_keywords_correctly(self): """ Saving the form should update the keywords correctly. - Removed keywords should be removed - New keywords should be added - Remaining keywords should remain """ user = UserFactory.create() task = TaskFactory.create() TaskKeywordFactory.create_batch(3, task=task) form = get_filled_taskform(task, keywords='test3, new_keyword') form.save(user) removed_keyword = TaskKeyword.objects.filter(task=task, name='test1') eq_(len(removed_keyword), 0) added_keyword = TaskKeyword.objects.filter(task=task, name='new_keyword') eq_(len(added_keyword), 1) kept_keyword = TaskKeyword.objects.filter(task=task, name='test3') eq_(len(kept_keyword), 1) # double-check on the keywords_list property eq_(task.keywords_list, 'test3, new_keyword')
def test_success_url_no_profile(self): """ If the user has no profile, return the url to create user profile. """ user = UserFactory.create() self.view.user = user eq_(self.view.success_url, reverse_lazy('users.profile.create'))
def test_close_expired_onetime_attempts(self): """ The close_expired_onetime_attempts routine should close all expired one-time attempts and return the number that were closed. """ user = UserFactory.create() recent_attempt, expired_attempt_1, expired_attempt_2 = TaskAttemptFactory.create_batch( 3, user=user, state=TaskAttempt.STARTED, task=self.task_not_repeatable_no_attempts) recent_attempt.created = aware_datetime(2014, 1, 29) recent_attempt.save() expired_attempt_1.created = aware_datetime(2014, 1, 1) expired_attempt_1.save() expired_attempt_2.created = aware_datetime(2014, 1, 1) expired_attempt_2.save() eq_( self.task_not_repeatable_no_attempts.taskattempt_set.filter( state=TaskAttempt.STARTED).count(), 3) with patch('oneanddone.tasks.models.timezone.now') as now: now.return_value = aware_datetime(2014, 1, 31) eq_(TaskAttempt.close_expired_onetime_attempts(), 2) eq_( TaskAttempt.objects.filter( task=self.task_not_repeatable_no_attempts, state=TaskAttempt.STARTED).count(), 1) eq_( TaskAttempt.objects.filter( task=self.task_not_repeatable_no_attempts, state=TaskAttempt.CLOSED).count(), 2)
def test_not_staff(self): """ If the user is not staff, raise a PermissionDenied exception. """ request = Mock() request.user = UserFactory.create(is_staff=False) self.view.dispatch(request)
def test_close_expired_task_attempts(self): """ The close_expired_task_attempts routine should close all attempts for tasks that are no longer available, set them as requiring notification, and return the number that were closed. """ user1, user2, user3 = UserFactory.create_batch(3) TaskAttemptFactory.create(user=user1, state=TaskAttempt.STARTED, task=self.task_end_jan) TaskAttemptFactory.create(user=user2, state=TaskAttempt.STARTED, task=self.task_end_jan) TaskAttemptFactory.create(user=user3, state=TaskAttempt.STARTED, task=self.task_no_draft) eq_( self.task_end_jan.taskattempt_set.filter( state=TaskAttempt.STARTED).count(), 2) eq_( self.task_no_draft.taskattempt_set.filter( state=TaskAttempt.STARTED).count(), 1) eq_(TaskAttempt.close_expired_task_attempts(), 2) eq_( TaskAttempt.objects.filter(task=self.task_end_jan, state=TaskAttempt.STARTED).count(), 0) eq_( TaskAttempt.objects.filter(task=self.task_end_jan, state=TaskAttempt.CLOSED, requires_notification=True).count(), 2) eq_( TaskAttempt.objects.filter(task=self.task_no_draft, state=TaskAttempt.STARTED).count(), 1)
def test_close_expired_task_attempts(self): """ The close_expired_task_attempts routine should close all attempts for tasks that are no longer available, set them as requiring notification, and return the number that were closed. """ task_no_expire = TaskFactory.create() task = TaskFactory.create(end_date=timezone.now() + timedelta(days=1)) future_date = timezone.now() + timedelta(days=2) user1, user2, user3 = UserFactory.create_batch(3) TaskAttemptFactory.create( user=user1, state=TaskAttempt.STARTED, task=task) TaskAttemptFactory.create( user=user2, state=TaskAttempt.STARTED, task=task) TaskAttemptFactory.create( user=user3, state=TaskAttempt.STARTED, task=task_no_expire) eq_(task.taskattempt_set.filter(state=TaskAttempt.STARTED).count(), 2) eq_(task_no_expire.taskattempt_set.filter(state=TaskAttempt.STARTED).count(), 1) with patch('oneanddone.tasks.models.timezone.now') as now: now.return_value = future_date eq_(TaskAttempt.close_expired_task_attempts(), 2) eq_(TaskAttempt.objects.filter(task=task, state=TaskAttempt.STARTED).count(), 0) eq_(TaskAttempt.objects.filter(task=task, state=TaskAttempt.CLOSED, requires_notification=True).count(), 2) eq_(TaskAttempt.objects.filter(task=task_no_expire, state=TaskAttempt.STARTED).count(), 1)
def test_display_email_without_profile(self): """ The display_email attribute should return 'Email consent denied' if they have no profile. """ user = UserFactory.build(email='*****@*****.**') eq_(user.display_email, 'Email consent denied')
def test_save_processes_keywords_correctly(self): """ Saving the form should update the keywords correctly. - Removed keywords should be removed - New keywords should be added - Remaining keywords should remain """ user = UserFactory.create() task = TaskFactory.create() TaskKeywordFactory.create_batch(3, task=task) data = { 'keywords': 'test3, new_keyword', 'team': task.team.id, } for field in ('name', 'short_description', 'execution_time', 'difficulty', 'repeatable', 'instructions', 'is_draft'): data[field] = getattr(task, field) form = TaskForm(instance=task, data=data) form.save(user) removed_keyword = TaskKeyword.objects.filter(task=task, name='test1') eq_(len(removed_keyword), 0) added_keyword = TaskKeyword.objects.filter(task=task, name='new_keyword') eq_(len(added_keyword), 1) kept_keyword = TaskKeyword.objects.filter(task=task, name='test3') eq_(len(kept_keyword), 1) # double-check on the keywords_list property eq_(task.keywords_list, 'test3, new_keyword')
def test_has_completed_task_false(self): """ has_completed_task should return false if the user has not completed the task. """ user = UserFactory.create() task = TaskFactory.create() ok_(not user.has_completed_task(task))
def test_missing_attempt_raises_404(self): """ If there is no task attempt with the given ID, return a 404. """ request = Mock(user=UserFactory.create()) with self.assertRaises(Http404): self.view.dispatch(request, pk=9999)
def test_close_stale_onetime_attempts(self): """ The close_stale_onetime_attempts routine should close all expired one-time attempts, set them as requiring notification, and return the number that were closed. """ task = TaskFactory.create(repeatable=False) user = UserFactory.create() recent_attempt, expired_attempt_1, expired_attempt_2 = TaskAttemptFactory.create_batch( 3, user=user, state=TaskAttempt.STARTED, task=task) recent_attempt.created = aware_datetime(2014, 1, 29) recent_attempt.save() expired_attempt_1.created = aware_datetime(2014, 1, 1) expired_attempt_1.save() expired_attempt_2.created = aware_datetime(2014, 1, 1) expired_attempt_2.save() eq_(task.taskattempt_set.filter(state=TaskAttempt.STARTED).count(), 3) with patch('oneanddone.tasks.models.timezone.now') as now: now.return_value = aware_datetime(2014, 1, 31) eq_(TaskAttempt.close_stale_onetime_attempts(), 2) eq_( TaskAttempt.objects.filter(task=task, state=TaskAttempt.STARTED).count(), 1) eq_( TaskAttempt.objects.filter(task=task, state=TaskAttempt.CLOSED, requires_notification=True).count(), 2)
def setUp(self): user = UserFactory.create() self.task_not_repeatable_no_attempts = TaskFactory.create( repeatable=False) self.task_not_repeatable_abandoned_attempt = TaskFactory.create( repeatable=False) TaskAttemptFactory.create( user=user, state=TaskAttempt.ABANDONED, task=self.task_not_repeatable_abandoned_attempt) self.task_not_repeatable_started_attempt = TaskFactory.create( repeatable=False) TaskAttemptFactory.create( user=user, state=TaskAttempt.STARTED, task=self.task_not_repeatable_started_attempt) self.task_not_repeatable_finished_attempt = TaskFactory.create( repeatable=False) TaskAttemptFactory.create( user=user, state=TaskAttempt.FINISHED, task=self.task_not_repeatable_finished_attempt) self.task_draft = TaskFactory.create(is_draft=True) self.task_invalid = TaskFactory.create(is_invalid=True) self.task_no_draft = TaskFactory.create(is_draft=False) self.task_start_jan = TaskFactory.create(is_draft=False, start_date=aware_datetime( 2014, 1, 1)) self.task_end_jan = TaskFactory.create(is_draft=False, end_date=aware_datetime( 2014, 1, 1)) self.task_range_jan_feb = TaskFactory.create( is_draft=False, start_date=aware_datetime(2014, 1, 1), end_date=aware_datetime(2014, 2, 1))
def test_get_task_list(self): """ Test GET task list for authenticated user """ header = {'HTTP_AUTHORIZATION': 'Token {}'.format(self.token)} user = UserFactory.create() test_task = self.create_task(user) task_attempt = TaskAttemptFactory.create(user=user, task=test_task) task_data = {"id": test_task.id, "name": test_task.name, "short_description": test_task.short_description, "instructions": test_task.instructions, "prerequisites": test_task.prerequisites, "execution_time": test_task.execution_time, "is_draft": test_task.is_draft, "is_invalid": test_task.is_invalid, "project": test_task.project.name, "team": test_task.team.name, "type": test_task.type.name, "repeatable": test_task.repeatable, "start_date": test_task.start_date, "end_date": test_task.end_date, "difficulty": test_task.difficulty, "why_this_matters": test_task.why_this_matters, "keyword_set": [ {"name": keyword.name} for keyword in test_task.keyword_set.all()], "taskattempt_set": [{"user": user.email, "state": task_attempt.state}], "owner": user.email} response = self.client.get(reverse('api-task'), {}, **header) self.assert_response_status(response, status.HTTP_200_OK) response_data = json.loads(response.content) assert_true(task_data in response_data)
def test_get_task_details(self): """ Test GET details of a task with particular id for authenticated user """ self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) user = UserFactory.create() test_task = self.create_task(user) task_attempt = TaskAttemptFactory.create(user=user, task=test_task) task_uri = self.uri + str(test_task.id) + '/' task_data = {"id": test_task.id, "name": test_task.name, "short_description": test_task.short_description, "instructions": test_task.instructions, "prerequisites": test_task.prerequisites, "execution_time": test_task.execution_time, "is_draft": test_task.is_draft, "is_invalid": test_task.is_invalid, "project": test_task.project.name, "team": test_task.team.name, "type": test_task.type.name, "repeatable": test_task.repeatable, "start_date": test_task.start_date, "end_date": test_task.end_date, "difficulty": test_task.difficulty, "why_this_matters": test_task.why_this_matters, "keyword_set": [{"name": keyword.name} for keyword in test_task.keyword_set.all()], "taskattempt_set": [{"user": user.email, "state": task_attempt.state}], "owner": user.email} response = self.client.get(task_uri) self.assert_response_status(response, status.HTTP_200_OK) response_data = json.loads(response.content) eq_(response_data, task_data)
def test_attempts_finished_count(self): user = UserFactory.create() TaskAttemptFactory.create_batch(4, user=user, state=TaskAttempt.FINISHED) TaskAttemptFactory.create(user=user, state=TaskAttempt.STARTED) eq_(user.attempts_finished_count, 4)
def test_close_stale_onetime_attempts(self): """ The close_stale_onetime_attempts routine should close all expired one-time attempts, set them as requiring notification, and return the number that were closed. """ task = TaskFactory.create(repeatable=False) user = UserFactory.create() recent_attempt, expired_attempt_1, expired_attempt_2 = TaskAttemptFactory.create_batch( 3, user=user, state=TaskAttempt.STARTED, task=task) recent_attempt.created = aware_datetime(2014, 1, 29) recent_attempt.save() expired_attempt_1.created = aware_datetime(2014, 1, 1) expired_attempt_1.save() expired_attempt_2.created = aware_datetime(2014, 1, 1) expired_attempt_2.save() eq_(task.taskattempt_set.filter(state=TaskAttempt.STARTED).count(), 3) with patch('oneanddone.tasks.models.timezone.now') as now: now.return_value = aware_datetime(2014, 1, 31) eq_(TaskAttempt.close_stale_onetime_attempts(), 2) eq_(TaskAttempt.objects.filter(task=task, state=TaskAttempt.STARTED).count(), 1) eq_(TaskAttempt.objects.filter(task=task, state=TaskAttempt.CLOSED, requires_notification=True).count(), 2)
def setUp(self): user = UserFactory.create() self.task_not_repeatable_no_attempts = TaskFactory.create(repeatable=False) self.task_not_repeatable_abandoned_attempt = TaskFactory.create(repeatable=False) TaskAttemptFactory.create( user=user, state=TaskAttempt.ABANDONED, task=self.task_not_repeatable_abandoned_attempt) self.task_not_repeatable_started_attempt = TaskFactory.create(repeatable=False) TaskAttemptFactory.create( user=user, state=TaskAttempt.STARTED, task=self.task_not_repeatable_started_attempt) self.task_not_repeatable_finished_attempt = TaskFactory.create(repeatable=False) TaskAttemptFactory.create( user=user, state=TaskAttempt.FINISHED, task=self.task_not_repeatable_finished_attempt) self.task_draft = TaskFactory.create(is_draft=True) self.task_invalid = TaskFactory.create(is_invalid=True) self.task_no_draft = TaskFactory.create(is_draft=False) self.task_start_jan = TaskFactory.create( is_draft=False, start_date=aware_datetime(2014, 1, 1)) self.task_end_jan = TaskFactory.create(is_draft=False, end_date=aware_datetime(2014, 1, 1)) self.task_range_jan_feb = TaskFactory.create( is_draft=False, start_date=aware_datetime(2014, 1, 1), end_date=aware_datetime(2014, 2, 1))
def test_attempts_in_progress(self): """ attempts_in_progress should return the number of attempts in progress. """ user = UserFactory.create() tasks = TaskAttemptFactory.create_batch(4, user=user, state=TaskAttempt.STARTED) eq_(set(user.attempts_in_progress), set(tasks))
def test_get_task_details(self): """ Test GET details of a task with particular id for authenticated user """ self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) user = UserFactory.create() test_task = self.create_task(user) task_attempt = TaskAttemptFactory.create(user=user, task=test_task) task_uri = self.uri + str(test_task.id) + '/' task_data = { "id": test_task.id, "name": test_task.name, "short_description": test_task.short_description, "instructions": test_task.instructions, "prerequisites": test_task.prerequisites, "execution_time": test_task.execution_time, "is_draft": test_task.is_draft, "is_invalid": test_task.is_invalid, "project": test_task.project.name, "team": test_task.team.name, "type": test_task.type.name, "repeatable": test_task.repeatable, "start_date": test_task.start_date, "end_date": test_task.end_date, "difficulty": test_task.difficulty, "why_this_matters": test_task.why_this_matters, "keyword_set": [{ "name": keyword.name } for keyword in test_task.keyword_set.all()], "taskattempt_set": [{ "user": user.email, "state": task_attempt.state }], "owner": user.email } response = self.client.get(task_uri) self.assert_response_status(response, status.HTTP_200_OK) response_data = json.loads(response.content) eq_(response_data, task_data)
def test_has_completed_task_true(self): """ has_completed_task should return true if the user has completed the task. """ user = UserFactory.create() task = TaskFactory.create() TaskAttemptFactory.create(user=user, task=task, state=TaskAttempt.FINISHED) ok_(user.has_completed_task(task))
def test_has_completed_task_false_task_started(self): """ has_completed_task should return false if the user has just started the task. """ user = UserFactory.create() task = TaskFactory.create() TaskAttemptFactory.create(user=user, task=task, state=TaskAttempt.STARTED) ok_(not user.has_completed_task(task))
def test_dispatch_no_profile(self): """If the user has no profile, dispatch the request normally.""" request = Mock() request.user = UserFactory.create() with patch('oneanddone.users.views.generic.CreateView.dispatch') as dispatch: eq_(self.view.dispatch(request), dispatch.return_value) dispatch.assert_called_with(request)
def test_attempts_finished_count(self): """ attempts_finished_count should return the number of attempts the user has finished. """ user = UserFactory.create() TaskAttemptFactory.create_batch(4, user=user, state=TaskAttempt.FINISHED) TaskAttemptFactory.create(user=user, state=TaskAttempt.STARTED) eq_(user.attempts_finished_count, 4)
def test_is_available_to_user_user_attempt(self): """ If there is an attempt by the current user, the task should be available. """ user = UserFactory.create() task = TaskFactory.create(repeatable=False) TaskAttemptFactory.create(user=user, state=TaskAttempt.STARTED, task=task) eq_(task.is_available_to_user(user), True)
def test_get_user_details(self): """ Test GET details of a user with particular email for authenticated user """ self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) test_user = UserFactory.create() user_uri = self.uri + test_user.email + '/' response = self.client.get(user_uri) self.assert_response_status(response, status.HTTP_200_OK)
def setUp(self): self.client_user = UserFactory.create() # Give all permissions to the client user self.client_user.is_superuser = True self.client_user.save() self.token = Token.objects.create(user=self.client_user) self.uri = '/api/v1/task/'
def test_is_staff(self): """ If the user is staff, call the parent class's dispatch method. """ request = Mock() request.user = UserFactory.create(is_staff=True) eq_(self.view.dispatch(request), 'fakemixin')
def test_dispatch_no_profile(self): """If the user has no profile, dispatch the request normally.""" request = Mock() request.user = UserFactory.create() with patch('oneanddone.users.views.generic.CreateView.dispatch' ) as dispatch: eq_(self.view.dispatch(request), dispatch.return_value) dispatch.assert_called_with(request)
def setUp(self): self.client_user = UserFactory.create() #Add delete user permission for client delete_permission = Permission.objects.get(codename='delete_user') self.client_user.user_permissions.add(delete_permission) self.token = Token.objects.create(user=self.client_user) self.uri = '/api/v1/user/'
def test_not_your_attempt_raises_404(self): """ If the current user doesn't match the user for the requested task attempt, return a 404. """ attempt = TaskAttemptFactory.create() request = Mock(user=UserFactory.create()) with self.assertRaises(Http404): self.view.dispatch(request, pk=attempt.pk)
def test_no_profile(self): """ If the user hasn't created a profile, redirect them to the profile creation view. """ request = Mock() request.user = UserFactory.create() with patch('oneanddone.users.mixins.redirect') as redirect: eq_(self.view.dispatch(request), redirect.return_value) redirect.assert_called_with('users.profile.create')
def test_get_form_kwargs_sets_initial_owner_to_current_user(self): """ The initial owner for the form should be set to the current user. """ user = UserFactory.create() self.view.request = Mock(user=user) self.view.kwargs = {} with patch('oneanddone.tasks.views.generic.CreateView.get_form_kwargs') as get_form_kwargs: get_form_kwargs.return_value = {'initial': {}} kwargs = self.view.get_form_kwargs() eq_(kwargs['initial']['owner'], user)
def test_found_attempt_stores_attempt(self): """ If the current user has a matching attempt, it should be stored in the view. """ user = UserFactory.create() attempt = TaskAttemptFactory.create(user=user, state=TaskAttempt.FINISHED) request = Mock(user=user) self.view.dispatch(request, pk=attempt.pk) eq_(self.view.attempt, attempt)