def test_05_app_stats_index(self): '''Test PRIVACY project stats privacy is respected''' # As Anonymou user admin, user, owner = UserFactory.create_batch(3) task = TaskFactory.create(n_answers=3) TaskRunFactory.create_batch(3, task=task) url = '/project/%s/stats' % task.project.short_name update_stats(task.project.id) res = self.app.get(url, follow_redirects=True) dom = BeautifulSoup(res.data) err_msg = 'Project Stats page should not be shown to anonymous users' assert dom.find(id='enforce_privacy') is not None, res.data # As Authenticated user but NOT ADMIN res = self.app.get(url + '?api_key=%s' % user.api_key, follow_redirects=True) dom = BeautifulSoup(res.data) err_msg = 'Project Stats page should not be shown to authenticated users' assert dom.find(id='enforce_privacy') is not None, err_msg self.signout # As Authenticated user but ADMIN res = self.app.get(url + '?api_key=%s' % admin.api_key, follow_redirects=True) dom = BeautifulSoup(res.data) err_msg = 'Project Stats page should be shown to admin users' assert dom.find(id='enforce_privacy') is None, err_msg self.signout()
def test_user_progress_anonymous(self): """Test API userprogress as anonymous works""" user = UserFactory.create() app = AppFactory.create(owner=user) tasks = TaskFactory.create_batch(2, app=app) for task in tasks: taskruns = TaskRunFactory.create_batch(2, task=task, user=user) taskruns = db.session.query(TaskRun)\ .filter(TaskRun.app_id == app.id)\ .filter(TaskRun.user_id == user.id)\ .all() res = self.app.get('/api/app/1/userprogress', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "The reported number of done tasks is wrong" assert len(taskruns) == data['done'], data # Add a new TaskRun and check again taskrun = TaskRunFactory.create(task=tasks[0], info={'answer': u'hello'}) res = self.app.get('/api/app/1/userprogress', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "Number of done tasks is wrong: %s" % len(taskruns) assert len(taskruns) + 1 == data['done'], error_msg
def create_result(self, n_answers=1, filter_by=False): task = TaskFactory.create(n_answers=n_answers) TaskRunFactory.create(task=task) if filter_by: return self.result_repo.filter_by(project_id=1) else: return self.result_repo.get_by(project_id=1)
def test_get_users_page_only_returns_users_with_contributions(self): users = UserFactory.create_batch(2) TaskRunFactory.create(user=users[0]) users_with_contrib = cached_users.get_users_page(1) assert len(users_with_contrib) == 1, users_with_contrib
def test_create_result_event(self, mock_create_result): """Test create_result is called.""" from pybossa.core import db task = TaskFactory.create(n_answers=1) TaskRunFactory.create(task=task) conn = db.engine.connect() result_id = create_result(conn, task.project_id, task.id) result = result_repo.filter_by(project_id=task.project_id, task_id=task.id, last_version=True)[0] assert mock_create_result.called err_msg = "The result should ID should be the same" assert result_id == result.id, err_msg task.n_answers = 2 task_repo.update(task) TaskRunFactory.create(task=task) result_id = create_result(conn, task.project_id, task.id) assert mock_create_result.called result = result_repo.filter_by(project_id=task.project_id, task_id=task.id, last_version=True) assert len(result) == 1, len(result) result = result[0] err_msg = "The result should ID should be the same" assert result_id == result.id, err_msg
def test_query_taskrun(self): """Test API query for taskrun with params works""" app = AppFactory.create() TaskRunFactory.create_batch(10, app=app) # Test for real field res = self.app.get("/api/taskrun?app_id=1") data = json.loads(res.data) # Should return one result assert len(data) == 10, data # Correct result assert data[0]['app_id'] == 1, data # Valid field but wrong value res = self.app.get("/api/taskrun?app_id=99999999") data = json.loads(res.data) assert len(data) == 0, data # Multiple fields res = self.app.get('/api/taskrun?app_id=1&task_id=1') data = json.loads(res.data) # One result assert len(data) == 1, data # Correct result assert data[0]['app_id'] == 1, data assert data[0]['task_id'] == 1, data # Limits res = self.app.get("/api/taskrun?app_id=1&limit=5") data = json.loads(res.data) for item in data: assert item['app_id'] == 1, item assert len(data) == 5, data
def test_n_total_task_runs_site_returns_total_number_of_answers(self): AnonymousTaskRunFactory.create() TaskRunFactory.create() task_runs = stats.n_task_runs_site() assert task_runs == 2, task_runs
def test_trigger_webhook_without_url(self): """Test WEBHOOK is triggered without url.""" project = ProjectFactory.create() task = TaskFactory.create(project=project, n_answers=1) TaskRunFactory.create(project=project, task=task) assert queue.enqueue.called is False, queue.enqueue.called queue.reset_mock()
def test_no_more_tasks_limit(self): """Test that a users gets always tasks with limit""" owner = UserFactory.create() project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=owner, short_name='egil', name='egil', description='egil') project_id = project.id all_tasks = TaskFactory.create_batch(20, project=project, n_answers=10) for t in all_tasks[0:10]: TaskRunFactory.create_batch(10, task=t, project=project) tasks = db.session.query(Task).filter_by(project_id=project.id, state='ongoing').all() assert tasks[0].n_answers == 10 url = 'api/project/%s/newtask?limit=2&orderby=id' % project_id res = self.app.get(url) data = json.loads(res.data) err_msg = "User should get a task" i = 0 for t in data: print t['id'] assert 'project_id' in t.keys(), err_msg assert t['project_id'] == project_id, err_msg assert t['id'] == all_tasks[i].id, (err_msg, t, all_tasks[i].id) assert t['state'] == 'completed', err_msg i += 1
def test_stats_dates_completed_tasks(self): """Test STATS stats_dates with tasks completed tasks""" today = unicode(datetime.date.today()) TaskRunFactory.create(task=self.project.tasks[1]) dates, dates_anon, dates_auth = stats.stats_dates(self.project.id) assert dates[today] == 1, dates assert dates_anon[today] == 4, dates_anon[today] assert dates_auth[today] == 5, dates_auth[today]
def test_get_task_run_by_returns_none_if_no_task_run(self): """Test get_task_run_by returns None if no taskrun matches the query""" TaskRunFactory.create(info='info') taskrun = self.task_repo.get_task_run_by(info='other info') assert taskrun is None, taskrun
def test_count_task_runs_with_no_matches(self): """Test count_task_runs_with returns 0 if no taskruns match the query""" TaskRunFactory.create(info='info') count = self.task_repo.count_task_runs_with(info='other info') assert count == 0, count
def test_authenticated_user_create_repeated_taskrun(self): """Test authenticated user cannot create two taskruns for the same task""" task = TaskFactory.create() taskrun1 = TaskRunFactory.create(task=task) taskrun2 = TaskRunFactory.build(task=task, user=taskrun1.user) assert self.mock_authenticated.id == taskrun1.user.id assert_raises(Forbidden, ensure_authorized_to, 'create', taskrun2)
def test_anon_week(self): """Test JOB leaderboard returns anon active week runs.""" users = UserFactory.create_batch(20) for user in users: TaskRunFactory.create(user=user) leaderboard() top_users = get_leaderboard() assert len(top_users) == 20, len(top_users)
def test_get_top5_projects_24_hours_returns_required_fields(self): fields = ('id', 'name', 'short_name', 'info', 'n_answers') TaskRunFactory.create() top5 = stats.get_top5_projects_24_hours() for field in fields: assert field in top5[0].keys()
def test_warm_project(self): """Test JOB warm_project works.""" project = ProjectFactory.create() task = TaskFactory.create(n_answers=1) for i in range(0,30): TaskRunFactory.create(project=project, task=task) res = warm_cache() assert res, res
def test_send_email(self, mock): """Test JOB send email works.""" user = UserFactory.create(pro=False) pr = ProjectFactory(owner=user, featured=True) task = TaskFactory.create(project=pr) TaskRunFactory.create(project=pr, task=task) send_weekly_stats_project(pr.id) assert mock.called
def test_send_email_not_subscribed(self, mock): """Test JOB send email not subscribed works.""" user = UserFactory.create(pro=False, subscribed=False) pr = ProjectFactory(owner=user, featured=True) task = TaskFactory.create(project=pr) TaskRunFactory.create(project=pr, task=task) res = send_weekly_stats_project(pr.id) assert res == "Owner does not want updates by email", res
def test_last_activity_returns_date_of_latest_contribution(self): project = ProjectFactory.create() first_task_run = TaskRunFactory.create(project=project) last_task_run = TaskRunFactory.create(project=project) activity = cached_projects.last_activity(project.id) assert activity == last_task_run.finish_time, last_task_run
def test_get_query_with_api_key_context(self): """ Test API GET query with an API-KEY requesting only APIKEY results.""" users = UserFactory.create_batch(4) project_oc = ProjectFactory.create(owner=users[0], info={'total': 150}) projects = ProjectFactory.create_batch(3, owner=users[1]) task_oc = TaskFactory.create(project=project_oc, info={'url': 'my url'}) taskrun_oc = TaskRunFactory.create(task=task_oc, user=users[0], info={'answer': 'annakarenina'}) for p in projects: print p.owner_id task_tmp = TaskFactory.create(project=p) TaskRunFactory.create(task=task_tmp) # For project owner with associated data for endpoint in self.endpoints: url = '/api/' + endpoint + '?api_key=' + users[0].api_key res = self.app.get(url) data = json.loads(res.data) if endpoint == 'project': assert len(data) == 1, data project = data[0] assert project['owner_id'] == users[0].id, project['owner_id'] assert project['info']['total'] == 150, data assert res.mimetype == 'application/json', res if endpoint == 'task': assert len(data) == 1, data task = data[0] assert task['project_id'] == project_oc.id, task assert task['info']['url'] == 'my url', data assert res.mimetype == 'application/json', res if endpoint == 'taskrun': assert len(data) == 1, data taskrun = data[0] assert taskrun['project_id'] == project_oc.id, taskrun assert taskrun['info']['answer'] == 'annakarenina', data assert res.mimetype == 'application/json', res # For authenticated with non-associated data for endpoint in self.endpoints: url = '/api/' + endpoint + '?api_key=' + users[3].api_key res = self.app.get(url) data = json.loads(res.data) if endpoint == 'project': assert len(data) == 0, data assert res.mimetype == 'application/json', res if endpoint == 'task': assert len(data) == 0, data assert res.mimetype == 'application/json', res if endpoint == 'taskrun': assert len(data) == 0, data assert res.mimetype == 'application/json', res
def test_authenticated_user_create_repeated_taskrun(self): """Test authenticated user cannot create a taskrun for a task to which he has previously posted a taskrun""" task = TaskFactory.create() taskrun1 = TaskRunFactory.create(task=task) taskrun2 = TaskRunFactory.build(task=task, user=taskrun1.user) assert self.mock_authenticated.id == taskrun1.user.id assert_raises(Forbidden, ensure_authorized_to, 'create', taskrun2)
def test_get_users_page_supports_pagination(self): users = UserFactory.create_batch(3) for user in users: TaskRunFactory.create(user=user) paginated_users = cached_users.get_users_page(page=2, per_page=1) assert len(paginated_users) == 1, paginated_users assert paginated_users[0]['id'] == users[1].id
def test_stats_users(self): """Test CACHE PROJECT STATS user stats works.""" pr = ProjectFactory.create() TaskRunFactory.create(project=pr) AnonymousTaskRunFactory.create(project=pr) users, anon_users, auth_users = stats_users(pr.id) assert len(users) == 2, len(users) assert len(anon_users) == 1, len(anon_users) assert len(auth_users) == 1, len(auth_users)
def test_limits_query(self): """Test API GET limits works""" owner = UserFactory.create() projects = ProjectFactory.create_batch(30, owner=owner) for project in projects: task = TaskFactory.create(project=project) TaskRunFactory.create(task=task) res = self.app.get('/api/project') data = json.loads(res.data) assert len(data) == 20, len(data) res = self.app.get('/api/project?limit=10') data = json.loads(res.data) assert len(data) == 10, len(data) # DEPRECATED res = self.app.get('/api/project?limit=10&offset=10') data = json.loads(res.data) assert len(data) == 10, len(data) assert data[0].get('name') == projects[10].name, data[0] # Keyset pagination url = '/api/project?limit=10&last_id=%s' % projects[9].id res = self.app.get(url) data = json.loads(res.data) assert len(data) == 10, len(data) assert data[0].get('name') == projects[10].name, data[0] res = self.app.get('/api/task') data = json.loads(res.data) assert len(data) == 20, len(data) res = self.app.get('/api/taskrun') data = json.loads(res.data) assert len(data) == 20, len(data) UserFactory.create_batch(30) res = self.app.get('/api/user') data = json.loads(res.data) assert len(data) == 20, len(data) res = self.app.get('/api/user?limit=10') data = json.loads(res.data) assert len(data) == 10, len(data) # DEPRECATED res = self.app.get('/api/user?limit=10&offset=10') data = json.loads(res.data) assert len(data) == 10, len(data) assert data[0].get('name') == 'user11', data res = self.app.get('/api/user?limit=10&last_id=10') data = json.loads(res.data) assert len(data) == 10, len(data) assert data[0].get('name') == 'user11', data
def test_get_inactive_users_jobs_with_users(self): """Test JOB get with users returns empty list.""" TaskRunFactory.create() jobs_generator = get_inactive_users_jobs() jobs = [] for job in jobs_generator: jobs.append(job) msg = "There should not be any job." assert len(jobs) == 0, msg
def test_trigger_webhook_with_url_not_completed_task(self): """Test WEBHOOK is not triggered for uncompleted tasks.""" import random project = ProjectFactory.create() task = TaskFactory.create(project=project) for i in range(1, random.randrange(2, 5)): TaskRunFactory.create(project=project, task=task) assert queue.enqueue.called is False, queue.enqueue.called assert task.state != 'completed' queue.reset_mock()
def test_count_task_runs_with_one_condition(self): """Test count_task_runs_with returns the number of taskruns that meet the filtering condition""" TaskRunFactory.create_batch(3, info='info') should_be_missing = TaskRunFactory.create(info='other info') count = self.task_repo.count_task_runs_with(info='info') assert count == 3, count
def test_count_task_runs_with_multiple_conditions(self): """Test count_task_runs_with supports multiple-condition queries""" TaskRunFactory.create(info='info', user_ip='8.8.8.8') taskrun = TaskRunFactory.create(info='info', user_ip='1.1.1.1') count = self.task_repo.count_task_runs_with(info='info', user_ip='1.1.1.1') assert count == 1, count
def test_notify_blog_users_featured_project(self, mock): """Test Notify Blog users with featured project works.""" user = UserFactory.create(subscribed=False) project = ProjectFactory.create(featured=True) TaskRunFactory.create(project=project) TaskRunFactory.create(project=project, user=user) blog = BlogpostFactory.create(project=project) res = notify_blog_users(blog.id, blog.project.id) msg = "1 users notified by email" assert res == msg, res
def test_filter_task_runs_by_no_matches(self): """Test filter_task_runs_by returns an empty list if no taskruns match the query""" TaskRunFactory.create(info='info') retrieved_taskruns = self.task_repo.filter_task_runs_by(info='other') assert isinstance(retrieved_taskruns, list) assert len(retrieved_taskruns) == 0, retrieved_taskruns
def test_get_notify_with_users(self): """Test JOB get with users returns empty list.""" user = UserFactory.create() tr = TaskRunFactory.create(user=user) jobs_generator = get_notify_inactive_accounts() jobs = [] for job in jobs_generator: jobs.append(job) msg = "There should not be any job." assert len(jobs) == 0, msg
def test_stats_hours(self): """Test CACHE PROJECT STATS hours works.""" pr = ProjectFactory.create() task = TaskFactory.create(n_answers=1) today = datetime.now(pytz.utc) TaskFactory.create() TaskRunFactory.create(project=pr, task=task) AnonymousTaskRunFactory.create(project=pr) hours, hours_anon, hours_auth, max_hours, \ max_hours_anon, max_hours_auth = stats_hours(pr.id) assert len(hours) == 24, len(hours) assert hours[today.strftime('%H')] == 2, hours[today.strftime('%H')] assert hours_anon[today.strftime('%H')] == 1, hours_anon[ today.strftime('%H')] assert hours_auth[today.strftime('%H')] == 1, hours_auth[ today.strftime('%H')] assert max_hours == 2 assert max_hours_anon == 1 assert max_hours_auth == 1
def test_update_taskrun(self): """Test update persists the changes made to TaskRun instances""" taskrun = TaskRunFactory.create(info='info') taskrun.info = 'updated info!' self.task_repo.update(taskrun) updated_taskrun = self.task_repo.get_task_run(taskrun.id) assert updated_taskrun.info == 'updated info!', updated_taskrun
def test_delete_task_deletes_dependent_taskruns(self): """Test delete removes the dependent TaskRun instances""" task = TaskFactory.create() taskrun = TaskRunFactory.create(task=task) self.task_repo.delete(task) deleted = self.task_repo.get_task_run(taskrun.id) assert deleted is None, deleted
def test_stats_hours_with_period(self): """Test CACHE PROJECT STATS hours with period works.""" pr = ProjectFactory.create() today = datetime.now(pytz.utc) d = date.today() - timedelta(days=6) task = TaskFactory.create(n_answers=1, created=d) TaskRunFactory.create(project=pr, task=task, created=d, finish_time=d) d = date.today() - timedelta(days=16) AnonymousTaskRunFactory.create(project=pr, created=d, finish_time=d) hours, hours_anon, hours_auth, max_hours, \ max_hours_anon, max_hours_auth = stats_hours(pr.id) assert len(hours) == 24, len(hours) # We use 00 as the timedelta sets the hour to 00 assert hours['00'] == 1, hours[today.strftime('%H')] assert hours_anon['00'] == 0, hours_anon[today.strftime('%H')] assert hours_auth['00'] == 1, hours_auth[today.strftime('%H')] assert max_hours == 1 assert max_hours_anon is None assert max_hours_auth == 1
def test_authenticated_user_create_first_taskrun(self): """Test authenticated user can create a taskrun for a given task if he hasn't already done it""" task = TaskFactory.create() taskrun = TaskRunFactory.build(task_id=task.id, project_id=task.project_id, user_id=self.mock_authenticated.id) assert self.mock_authenticated.id == taskrun.user_id, taskrun assert_not_raises(Exception, ensure_authorized_to, 'create', taskrun)
def test_user_progress_authenticated_user(self): """Test API userprogress as an authenticated user works""" user = UserFactory.create() project = ProjectFactory.create(owner=user) tasks = TaskFactory.create_batch(2, project=project) taskruns = [] for task in tasks: taskruns.extend(TaskRunFactory.create_batch(2, task=task, user=user)) url = '/api/project/1/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg url = '/api/project/%s/userprogress?api_key=%s' % (project.short_name, user.api_key) res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg url = '/api/project/5000/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) assert res.status_code == 404, res.status_code url = '/api/project/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) assert res.status_code == 404, res.status_code error_msg = "The reported number of done tasks is wrong" assert len(taskruns) == data['done'], error_msg # Add a new TaskRun and check again taskrun = TaskRunFactory.create(task=tasks[0], info={'answer': u'hello'}, user=user) url = '/api/project/1/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "Number of done tasks is wrong: %s" % len(taskruns) assert len(taskruns) + 1 == data['done'], error_msg
def test_filter_task_runs_by_multiple_conditions_fulltext(self): """Test filter_task_runs_by supports multiple-condition fulltext queries""" text = 'you agent something word' data = {'foo': 'bar', 'bar': text} TaskRunFactory.create(info=data, user_ip='8.8.8.8') taskrun = TaskRunFactory.create(info=data, user_ip='1.1.1.1') info = 'foo::bar|bar::agent' retrieved_taskruns = self.task_repo.filter_task_runs_by( info=info, user_ip='1.1.1.1', fulltextsearch='1') assert len(retrieved_taskruns) == 1, retrieved_taskruns assert taskrun in retrieved_taskruns[0], retrieved_taskruns retrieved_taskruns = self.task_repo.filter_task_runs_by( info=info, user_ip='1.1.1.1') assert len(retrieved_taskruns) == 0, retrieved_taskruns
def test_update_tasks_redundancy_updates_state_when_decrementing(self): """Test update_tasks_redundancy changes 'ongoing' tasks to 'completed' if n_answers is decremented enough""" project = ProjectFactory.create() tasks = TaskFactory.create_batch(2, project=project, n_answers=2) TaskRunFactory.create_batch(2, task=tasks[0]) TaskRunFactory.create(task=tasks[1]) tasks[0].state = 'completed' self.task_repo.update(tasks[0]) assert tasks[0].state == 'completed', tasks[0].state assert tasks[1].state == 'ongoing', tasks[1].state self.task_repo.update_tasks_redundancy(project, 1) tasks = self.task_repo.filter_tasks_by(project_id=project.id) for task in tasks: assert task.state == 'completed', task.state
def test_delete_all_deletes_dependent(self): """Test delete_all deletes dependent taskruns too""" task = TaskFactory.create() taskrun = TaskRunFactory.create(task=task) self.task_repo.delete_all([task]) deleted = self.task_repo.get_task_run(taskrun.id) assert deleted is None, deleted
def test_delete_task_cascade(self): """Test API delete task deletes associated taskruns""" task = TaskFactory.create() task_runs = TaskRunFactory.create_batch(3, task=task) url = '/api/task/%s?api_key=%s' % (task.id, task.project.owner.api_key) res = self.app.delete(url) assert_equal(res.status, '204 NO CONTENT', res.data) task_runs = task_repo.filter_task_runs_by(task_id=task.id) assert len(task_runs) == 0, "There should not be any task run for task"
def test_anonymous_user_read(self): """Test anonymous user can read any taskrun""" anonymous_taskrun = AnonymousTaskRunFactory.create() user_taskrun = TaskRunFactory.create() assert_not_raises(Exception, getattr(require, 'taskrun').read, anonymous_taskrun) assert_not_raises(Exception, getattr(require, 'taskrun').read, user_taskrun)
def test_save_saves_taskruns(self): """Test save persists TaskRun instances""" taskrun = TaskRunFactory.build() assert self.task_repo.get_task_run(taskrun.id) is None self.task_repo.save(taskrun) assert self.task_repo.get_task_run( taskrun.id) == taskrun, "TaskRun not saved"
def test_authenticated_user_create_first_taskrun(self): """Test authenticated user can create a taskrun for a given task if he hasn't already done it""" with self.flask_app.test_request_context('/'): taskrun = TaskRunFactory.build() assert self.mock_authenticated.id == taskrun.user.id assert_not_raises(Exception, getattr(require, 'taskrun').create, taskrun)
def test_public_projects_contributed_contributions_cached(self): """Test CACHE USERS public cached projects_contributed returns a list of projects that has contributed to""" user = UserFactory.create() project_contributed = ProjectFactory.create() task = TaskFactory.create(project=project_contributed) TaskRunFactory.create(task=task, user=user) another_project = ProjectFactory.create() projects_contributed = cached_users.public_projects_contributed_cached(user.id) assert len(projects_contributed) == 1 assert projects_contributed[0]['short_name'] == project_contributed.short_name, projects_contributed # check privacy err_msg = 'private information is in public record' assert 'secret_key' not in projects_contributed[0], err_msg assert 'onesignal' not in projects_contributed[0]['info'] assert 'passwd_hash' not in projects_contributed[0]['info']
def test_n_available_tasks_some_task_answered_by_another_user(self): """Test n_available_tasks returns 1 for a user if another user has submitted taskruns for the task but he hasn't""" project = ProjectFactory.create() task = TaskFactory.create(project=project) user = UserFactory.create() taskrun = TaskRunFactory.create(task=task) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert n_available_tasks == 1, n_available_tasks
def test_get_leaderboard_includes_specific_user_even_is_not_in_top(self): leader = UserFactory.create() second = UserFactory.create() third = UserFactory.create() project = ProjectFactory.create() tasks = TaskFactory.create_batch(3, project=project) i = 3 for user in [leader, second, third]: TaskRunFactory.create_batch(i, user=user, task=tasks[i - 1]) i -= 1 user_out_of_top = UserFactory.create() update_leaderboard() leaderboard = cached_users.get_leaderboard(3, user_id=user_out_of_top.id) assert len(leaderboard) is 4, len(leaderboard) assert leaderboard[-1]['name'] == user_out_of_top.name
def test_delete_jobs(self): """Test JOB returns jobs to delete inactive accounts.""" # create root user UserFactory.create() projectOwner = UserFactory.create(admin=False) ProjectFactory.create(owner=projectOwner) today = datetime.datetime.today() old_date = today + relativedelta(months=-1) date_str = old_date.strftime('%Y-%m-%dT%H:%M:%S.%f') # substract six months and take care of leap years one_year = today + relativedelta(months=-6, leapdays=1) one_year_str = one_year.strftime('%Y-%m-%dT%H:%M:%S.%f') user = UserFactory.create() user_recent = UserFactory.create() # 1 month old contribution tr = TaskRunFactory.create(finish_time=date_str) # 1 year old contribution tr_year = TaskRunFactory.create(finish_time=one_year_str) # 1 year old contribution for a project owner tr_year_project = TaskRunFactory.create(finish_time=one_year_str, user=projectOwner) # User with a contribution from a long time ago tr2 = TaskRunFactory.create(finish_time="2010-08-08T18:23:45.714110", user=user) # User with a recent contribution tr3 = TaskRunFactory.create(user=user) user = user_repo.get(tr.user_id) jobs_generator = get_delete_inactive_accounts() jobs = [] for job in jobs_generator: jobs.append(job) msg = "There should be one job." assert len(jobs) == 1, (msg, len(jobs)) emails = [tr_year.user.id] for job in jobs: err_msg = "Delete user is not the same" assert job['args'][0] == tr_year.user.id, err_msg job = jobs[0] args = job['args'][0] assert job['queue'] == 'bimonthly', job['queue']
def test_authenticated_user_create_repeated_taskrun(self): """Test authenticated user cannot create a taskrun for a task to which he has previously posted a taskrun""" with self.flask_app.test_request_context('/'): task = TaskFactory.create() taskrun1 = TaskRunFactory.create(task=task) taskrun2 = TaskRunFactory.build(task=task, user=taskrun1.user) assert self.mock_authenticated.id == taskrun1.user.id assert_raises(Forbidden, getattr(require, 'taskrun').create, taskrun2) # But the user can still create taskruns for different tasks task2 = TaskFactory.create(app=task.app) taskrun3 = TaskRunFactory.build(task=task2, user=taskrun1.user) assert self.mock_authenticated.id == taskrun3.user.id assert_not_raises(Exception, getattr(require, 'taskrun').create, taskrun3)
def test_get_top5_users_24_hours_returns_best_5_users_only(self): users = UserFactory.create_batch(4) restricted = UserFactory.create(restrict=True) users.append(restricted) i = 5 for user in users: TaskRunFactory.create_batch(i, user=user) i -= 1 worst_user = UserFactory.create() top5 = stats.get_top5_users_24_hours() top5_ids = [top['id'] for top in top5] assert len(top5) == 4, len(top5) assert worst_user.id not in top5_ids for i in range(len(top5)): assert users[i].id == top5_ids[i] assert users[i].restrict is False assert users[i].id != restricted.id
def test_taskrun_delete(self): """Test TaskRun API delete works""" admin = UserFactory.create() owner = UserFactory.create() non_owner = UserFactory.create() project = ProjectFactory.create(owner=owner) task = TaskFactory.create(project=project) anonymous_taskrun = AnonymousTaskRunFactory.create( task=task, info='my task result') user_taskrun = TaskRunFactory.create(task=task, user=owner, info='my task result') ## anonymous res = self.app.delete('/api/taskrun/%s' % user_taskrun.id) error_msg = 'Anonymous should not be allowed to delete' assert_equal(res.status, '401 UNAUTHORIZED', error_msg) ### real user but not allowed to delete anonymous TaskRuns url = '/api/taskrun/%s?api_key=%s' % (anonymous_taskrun.id, owner.api_key) res = self.app.delete(url) error_msg = 'Authenticated user should not be allowed ' \ 'to delete anonymous TaskRuns' assert_equal(res.status, '403 FORBIDDEN', error_msg) ### real user but not allowed as not owner! url = '/api/taskrun/%s?api_key=%s' % (user_taskrun.id, non_owner.api_key) res = self.app.delete(url) error_msg = 'Should not be able to delete TaskRuns of others' assert_equal(res.status, '403 FORBIDDEN', error_msg) #### real user # DELETE with not allowed args url = '/api/taskrun/%s?api_key=%s' % (user_taskrun.id, owner.api_key) res = self.app.delete(url + "&foo=bar") err = json.loads(res.data) assert res.status_code == 415, err assert err['status'] == 'failed', err assert err['target'] == 'taskrun', err assert err['action'] == 'DELETE', err assert err['exception_cls'] == 'AttributeError', err # Owner with valid args can delete res = self.app.delete(url) assert_equal(res.status, '204 NO CONTENT', res.data) ### root url = '/api/taskrun/%s?api_key=%s' % (anonymous_taskrun.id, admin.api_key) res = self.app.delete(url) error_msg = 'Admin should be able to delete TaskRuns of others' assert_equal(res.status, '204 NO CONTENT', error_msg)
def test_it_deletes_project_taskruns_before_publishing( self, mock_task_repo, mock_result_repo, mock_webhook_repo): project = project_repo.get(self.project_id) task = TaskFactory.create(project=project, n_answers=1) TaskRunFactory.create(task=task) result = result_repo.get_by(project_id=task.project_id) assert not result, "There should not be a result" resp = self.app.post('/project/%s/publish' % project.short_name, follow_redirects=True, data={'force_reset': 'on'}) taskruns = task_repo.filter_task_runs_by(project_id=project.id) repo_call = mock_task_repo.delete_taskruns_from_project.call_args_list[ 0][0][0] assert repo_call.id == project.id, repo_call mock_webhook_repo.assert_called_with(project) mock_result_repo.assert_called_with(project) assert 'Project published' in resp.data, resp.data
def test_get_task_run_by_info_json(self): """Test get_task_run_by with JSON returns a taskrun with the specified attribute""" data = {'foo': 'bar'} taskrun = TaskRunFactory.create(info=data) info = 'foo::bar' retrieved_taskrun = self.task_repo.get_task_run_by(info=info) assert taskrun == retrieved_taskrun, retrieved_taskrun
def test_get_dataframe_with_dict(self): """Test the task run dataframe with a dict as the info.""" info = {'foo': 'bar'} n_task_runs = 2 task = TaskFactory() taskruns = TaskRunFactory.create_batch(n_task_runs, task=task, info=info) df = self.base_analyst.get_task_run_df(task, taskruns) assert_equal(df['foo'].tolist(), [info['foo']] * n_task_runs) assert_equal(df['info'].tolist(), [info] * n_task_runs)
def test_authenticated_user_create_taskrun_non_allow_anonymous_contrib( self): """Test authenticated user can create a taskrun for a project that does not allow for anonymous contributors""" project = AppFactory.create(allow_anonymous_contributors=False) task = TaskFactory.create(app=project) taskrun = TaskRunFactory.build(task_id=task.id) assert_not_raises(Exception, getattr(require, 'taskrun').create, taskrun)
def test_authenticated_user_create_first_taskrun(self): """Test authenticated user can create a taskrun for a given task if he hasn't already done it""" task = TaskFactory.create() taskrun = TaskRunFactory.build(task_id=task.id, user_id=self.mock_authenticated.id) assert self.mock_authenticated.id == taskrun.user_id, taskrun assert_not_raises(Exception, getattr(require, 'taskrun').create, taskrun)
def test_n_available_tasks_some_tasks_answered_by_authenticated_user(self): """Test n_available_tasks returns 1 for authenticated user if he has submitted taskruns for one of the tasks but there is still another task""" project = ProjectFactory.create() answered_task = TaskFactory.create(project=project) available_task = TaskFactory.create(project=project) user = UserFactory.create() taskrun = TaskRunFactory.create(task=answered_task, user=user) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert n_available_tasks == 1, n_available_tasks
def test_trigger_webhook_with_url(self): """Test WEBHOOK is triggered with url.""" url = 'http://server.com' owner = UserFactory.create(pro=True) project = ProjectFactory.create(webhook=url, owner=owner) task = TaskFactory.create(project=project, n_answers=1) TaskRunFactory.create(project=project, task=task) result = result_repo.get_by(project_id=project.id, task_id=task.id) payload = dict( event='task_completed', project_short_name=project.short_name, project_id=project.id, task_id=task.id, result_id=result.id, fired_at=datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")) assert queue.enqueue.called assert queue.called_with(webhook, url, payload) u = '/project/%s/webhook?api_key=%s&all=1' % (project.short_name, project.owner.api_key) res = self.app.get(u) assert queue.enqueue.called assert queue.called_with(webhook, url, payload, True) wh = WebhookFactory(response_status_code=500, project_id=project.id, payload=payload, response="500") u = '/project/%s/webhook?api_key=%s&failed=1' % (project.short_name, project.owner.api_key) res = self.app.get(u) assert queue.enqueue.called assert queue.called_with(webhook, url, payload, True) u = '/project/%s/webhook/%s?api_key=%s&failed=1' % ( wh.id, project.short_name, project.owner.api_key) res = self.app.post(u) assert queue.enqueue.called assert queue.called_with(webhook, url, payload, True) queue.reset_mock()
def test_charts(self): """Test project chart""" return #to fix date_old = (datetime.datetime.utcnow() - datetime.timedelta(30*36)).isoformat() date_4_mo = (datetime.datetime.utcnow() - datetime.timedelta(120)).isoformat() date_3_mo = (datetime.datetime.utcnow() - datetime.timedelta(90)).isoformat() date_2_mo = (datetime.datetime.utcnow() - datetime.timedelta(60)).isoformat() date_1_mo = (datetime.datetime.utcnow() - datetime.timedelta(30)).isoformat() expected_tasks = 6 expected_categories = 2 expected_projects = 4 expected_taskruns = 5 CategoryFactory.create(created=date_1_mo) CategoryFactory.create(created=date_2_mo) CategoryFactory.create(created=date_3_mo) ProjectFactory.create(created=date_1_mo) ProjectFactory.create(created=date_2_mo) ProjectFactory.create(created=date_3_mo) ProjectFactory.create(created=date_4_mo) ProjectFactory.create(created=date_old) TaskFactory.create(created=date_1_mo) TaskFactory.create(created=date_2_mo) TaskFactory.create(created=date_3_mo) TaskRunFactory.create(created=date_1_mo) TaskRunFactory.create(created=date_2_mo) TaskRunFactory.create(created=date_3_mo) TaskRunFactory.create(created=date_4_mo) TaskRunFactory.create(created=date_old) projects = stats.project_chart() assert projects['series'][0][24] == expected_projects, "{} projects created in last 24 months".format(expected_projects) categories = stats.category_chart() assert categories['series'][0][24] == expected_categories, "{} categories created in last 24 months".format(expected_categories) tasks = stats.task_chart() assert tasks['series'][0][24] == expected_tasks, "{} tasks created in last 24 months".format(expected_tasks) taskruns = stats.submission_chart() assert taskruns['series'][0][24] == expected_taskruns, "{} taskruns created in last 24 months".format(expected_taskruns)
def create_result(self, n_results=1, n_answers=1, owner=None, filter_by=False): if owner: owner = owner else: admin, owner, user = UserFactory.create_batch(3) project = ProjectFactory.create(owner=owner) tasks = [] for i in range(n_results): tasks.append( TaskFactory.create(n_answers=n_answers, project=project)) for i in range(n_answers): for task in tasks: TaskRunFactory.create(task=task, project=project) if filter_by: return result_repo.filter_by(project_id=1) else: return result_repo.get_by(project_id=1)