def test_greater_less_than(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats?pattern=Tabby&age__gt=2') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert response.json['data'][0]['name'] == 'Ada' response = json_call(test_client.get, '/cats?pattern=Tabby&age__gte=2') assert response.status_code == 200 assert response.json['count'] == 2 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 2 response = json_call(test_client.get, '/cats?pattern=Tabby&age__lte=2') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert response.json['data'][0]['name'] == 'Leo' response = json_call(test_client.get, '/cats?age__lt=3') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert response.json['data'][0]['name'] == 'Leo'
def test_update_workflow_instance(app, instances): test_client = app.test_client() csrf_token = login(test_client) response = json_call(test_client.get, '/v1/workflow-instances/1') assert response.status_code == 200 workflow_instance = response.json workflow_instance['priority'] = 'high' previous_updated_at = response.json['updated_at'] response = json_call(test_client.put, '/v1/workflow-instances/1', workflow_instance, headers={'X-CSRF': csrf_token}) assert response.status_code == 200 assert dict_contains( response.json, { 'id': 1, 'workflow_name': 'workflow1', 'status': 'running', 'run_at': iso_regex, 'unique': None, 'params': None, 'priority': 'high', 'started_at': iso_regex, 'scheduled': True, 'ended_at': None, 'created_at': iso_regex, 'updated_at': iso_regex }) assert response.json['updated_at'] > previous_updated_at
def test_authorization(app): test_client = app.test_client() login(test_client, email='*****@*****.**', password='******') ## normal role response = json_call(test_client.post, '/cats', { 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby', 'age': 7 }, headers={'X-Requested-With': 'requests'}) assert response.status_code == 403 login(test_client, email='*****@*****.**', password='******') ## admin role response = json_call(test_client.post, '/cats', { 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby', 'age': 7 }, headers={'X-Requested-With': 'requests'}) assert response.status_code == 201
def test_pagination(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats?$page_size=1') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 1 assert response.json['total_pages'] == 3 assert len(response.json['data']) == 1 assert dict_contains( response.json['data'][0], { 'id': 1, 'name': 'Ada', 'age': 5, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) response = json_call(test_client.get, '/cats?$page=2&$page_size=1') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 2 assert response.json['total_pages'] == 3 assert len(response.json['data']) == 1 assert dict_contains( response.json['data'][0], { 'id': 2, 'name': 'Leo', 'age': 2, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) response = json_call(test_client.get, '/cats?$page=3&$page_size=1') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 3 assert response.json['total_pages'] == 3 assert len(response.json['data']) == 1 assert dict_contains( response.json['data'][0], { 'id': 3, 'name': 'Wilhelmina', 'age': 4, 'pattern': 'Calico', 'updated_at': iso_regex, 'created_at': iso_regex })
def test_delete_task_instance(app, instances): test_client = app.test_client() csrf_token = login(test_client) response = json_call(test_client.get, '/v1/task-instances/1') assert response.status_code == 200 response = json_call(test_client.delete, '/v1/task-instances/1', headers={'X-CSRF': csrf_token}) assert response.status_code == 204 response = json_call(test_client.get, '/v1/task-instances/1') assert response.status_code == 404
def test_create_workflow_instance(app, instances): test_client = app.test_client() csrf_token = login(test_client) workflow_instance = { 'workflow_name': 'workflow2', 'unique': 'user-32324-payment-973794' } response = json_call(test_client.post, '/v1/workflow-instances', workflow_instance, headers={'X-CSRF': csrf_token}) assert response.status_code == 201 assert dict_contains( response.json, { 'id': 2, 'workflow_name': 'workflow2', 'status': 'queued', 'run_at': iso_regex, 'unique': 'user-32324-payment-973794', 'params': None, 'priority': 'normal', 'started_at': None, 'scheduled': False, 'ended_at': None, 'created_at': iso_regex, 'updated_at': iso_regex })
def test_get_task_instance(app, instances): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/v1/task-instances/1') assert response.status_code == 200 assert dict_contains( response.json, { 'id': 1, 'task_name': 'task1', 'workflow_instance_id': 1, 'status': 'success', 'run_at': iso_regex, 'unique': None, 'params': {}, 'priority': 'normal', 'started_at': iso_regex, 'scheduled': True, 'ended_at': iso_regex, 'attempts': 1, 'max_attempts': 1, 'timeout': 300, 'retry_delay': 300, 'push': False, 'push_state': None, 'worker_id': None, 'locked_at': None, 'created_at': iso_regex, 'updated_at': iso_regex })
def test_get_recurring_latest(app, instances, dbsession): test_client = app.test_client() login(test_client) workflow_instance = WorkflowInstance(workflow_name='workflow1', scheduled=True, run_at=datetime(2017, 6, 4, 6), started_at=datetime(2017, 6, 4, 6), status='running', priority='normal') dbsession.add(workflow_instance) dbsession.commit() response = json_call(test_client.get, '/v1/workflow-instances/recurring-latest') assert response.status_code == 200 assert dict_contains( response.json[0], { 'id': 2, 'workflow_name': 'workflow1', 'status': 'running', 'run_at': '2017-06-04T06:00:00+00:00', 'unique': None, 'params': None, 'priority': 'normal', 'started_at': '2017-06-04T06:00:00+00:00', 'scheduled': True, 'ended_at': None, 'created_at': iso_regex, 'updated_at': iso_regex })
def test_filter_by_pattern(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats?pattern=Tabby') assert response.status_code == 200 assert response.json['count'] == 2 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 2 assert dict_contains( response.json['data'][0], { 'id': 1, 'name': 'Ada', 'age': 5, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) assert dict_contains( response.json['data'][1], { 'id': 2, 'name': 'Leo', 'age': 2, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex })
def test_list_workflow_instances(app, instances): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/v1/workflow-instances') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert dict_contains( response.json['data'][0], { 'id': 1, 'workflow_name': 'workflow1', 'status': 'running', 'run_at': '2017-06-03T06:00:00+00:00', 'unique': None, 'params': None, 'priority': 'normal', 'started_at': '2017-06-03T06:00:00+00:00', 'scheduled': True, 'ended_at': None, 'created_at': iso_regex, 'updated_at': iso_regex })
def test_equality(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats?pattern=Tabby') assert response.status_code == 200 assert response.json['count'] == 2 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 2 response = json_call(test_client.get, '/cats?pattern__ne=Tabby') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert response.json['data'][0]['name'] == 'Wilhelmina'
def test_retrieve(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats/2') assert response.status_code == 200 assert dict_contains( response.json, { 'id': 2, 'name': 'Leo', 'age': 2, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) response = json_call(test_client.get, '/cats/1234') assert response.status_code == 404
def test_in_operator(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats?name__in=Ada&name__in=Leo') assert response.status_code == 200 assert response.json['count'] == 2 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 2 response = json_call(test_client.get, '/cats?name__notin=Ada&name__notin=Leo') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert response.json['data'][0]['name'] == 'Wilhelmina'
def test_is_operator(app): test_client = app.test_client() login(test_client) ## setup response = json_call(test_client.post, '/cats', { 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby' }, headers={'X-Requested-With': 'requests'}) assert response.status_code == 201 response = json_call(test_client.get, '/users/1') assert response.status_code == 200 user = response.json user['active'] = False response = json_call(test_client.put, '/users/1', user, headers={'X-Requested-With': 'requests'}) assert response.status_code == 200 ## is null response = json_call(test_client.get, '/cats?age__is=null') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert response.json['data'][0]['name'] == 'Dr. Kitty McMoewMoew' ## isnot null response = json_call(test_client.get, '/cats?age__isnot=null') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 3 ## is true response = json_call(test_client.get, '/users?active__is=true') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 3 ## is false response = json_call(test_client.get, '/users?active__is=false') assert response.status_code == 200 assert response.json['count'] == 1 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 1 assert response.json['data'][0]['email'] == '*****@*****.**'
def test_update_task_instance(app, instances): test_client = app.test_client() csrf_token = login(test_client) response = json_call(test_client.get, '/v1/task-instances/1') assert response.status_code == 200 task_instance = response.json task_instance['worker_id'] = 'foo' previous_updated_at = task_instance['updated_at'] response = json_call(test_client.put, '/v1/task-instances/1', task_instance, headers={'X-CSRF': csrf_token}) assert response.status_code == 200 assert dict_contains( response.json, { 'id': 1, 'task_name': 'task1', 'workflow_instance_id': 1, 'status': 'success', 'run_at': iso_regex, 'unique': None, 'params': {}, 'priority': 'normal', 'started_at': iso_regex, 'scheduled': True, 'ended_at': iso_regex, 'attempts': 1, 'max_attempts': 1, 'timeout': 300, 'retry_delay': 300, 'push': False, 'push_state': None, 'worker_id': 'foo', 'locked_at': None, 'created_at': iso_regex, 'updated_at': iso_regex }) assert response.json['updated_at'] > previous_updated_at
def test_update(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats/2') assert response.status_code == 200 assert dict_contains( response.json, { 'id': 2, 'name': 'Leo', 'age': 2, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) cat = response.json cat['age'] = 3 previous_updated_at = cat['updated_at'] response = json_call(test_client.put, '/cats/2', cat, headers={'X-Requested-With': 'requests'}) assert response.status_code == 200 assert dict_contains( response.json, { 'id': 2, 'name': 'Leo', 'age': 3, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) assert response.json['updated_at'] > previous_updated_at response = json_call(test_client.put, '/cats/1234', {}, headers={'X-Requested-With': 'requests'}) assert response.status_code == 404
def test_login_fail(app): test_client = app.test_client() response = json_call(test_client.post, '/session', email='*****@*****.**', password='******') assert response.status_code == 401 response = json_call(test_client.post, '/session', email='*****@*****.**', password='******') assert response.status_code == 401 with app.app_context(): log_entry = db.session.query(app.auth.auth_log_entry_model).first() assert log_entry.type == 'failed_login_attempt' assert log_entry.email == '*****@*****.**' assert log_entry.user_id == None assert log_entry.ip == '127.0.0.1' assert isinstance(log_entry.timestamp, datetime) assert log_entry.user_agent == 'werkzeug/0.14.1'
def test_delete_workflow_instance(app, instances): test_client = app.test_client() csrf_token = login(test_client) response = json_call(test_client.get, '/v1/workflow-instances/1') assert response.status_code == 200 response = json_call(test_client.get, '/v1/task-instances?workflow_instance_id=1') assert response.status_code == 200 assert response.json['count'] == 4 response = json_call(test_client.delete, '/v1/workflow-instances/1', headers={'X-CSRF': csrf_token}) assert response.status_code == 204 response = json_call(test_client.get, '/v1/workflow-instances/1') assert response.status_code == 404 response = json_call(test_client.get, '/v1/task-instances?workflow_instance_id=1') assert response.status_code == 200 assert response.json['count'] == 0
def test_delete(app): test_client = app.test_client() login(test_client) response = test_client.delete('/cats/2', headers={'X-Requested-With': 'requests'}) assert response.status_code == 204 response = test_client.get('/cats/2') assert response.status_code == 404 response = json_call(test_client.delete, '/cats/1234', {}, headers={'X-Requested-With': 'requests'}) assert response.status_code == 404
def test_field_selection(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/cats?$fields=name,pattern') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 3 assert response.json['data'][0] == {'name': 'Ada', 'pattern': 'Tabby'} assert response.json['data'][1] == {'name': 'Leo', 'pattern': 'Tabby'} assert response.json['data'][2] == { 'name': 'Wilhelmina', 'pattern': 'Calico' }
def test_get_workflow(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/v1/workflows/workflow1') assert response.status_code == 200 assert dict_contains( response.json, { 'name': 'workflow1', 'active': True, 'title': None, 'description': None, 'schedule': '0 6 * * *', 'start_date': None, 'end_date': None, 'concurrency': 1, 'sla': None, 'default_priority': 'normal' })
def test_ip_login_attempts(app): auth_log_entry_model = app.auth.auth_log_entry_model with app.app_context(): for i in range(0, 100): db.session.add( auth_log_entry_model(type='failed_login_attempt', email='*****@*****.**', ip='127.0.0.1', timestamp=datetime.utcnow(), user_agent='Curl or something')) db.session.commit() test_client = app.test_client() response = json_call(test_client.post, '/session', email='*****@*****.**', password='******') assert response.status_code == 401 assert response.json['errors'][0] == 'Too Many Login Attempts'
def test_max_sessions(app): token_model = app.auth.token_model with app.app_context(): for i in range(0, 10): db.session.add( token_model(type='session', user_id=1, expires_at=datetime.utcnow() + timedelta(hours=12), ip='127.0.0.1', user_agent='Curl or something')) db.session.commit() test_client = app.test_client() response = json_call(test_client.post, '/session', email='*****@*****.**', password='******') assert response.status_code == 401 assert response.json['errors'][ 0] == 'Maximum number of user sessions reached.'
def test_create(app): test_client = app.test_client() login(test_client) response = json_call(test_client.post, '/cats', { 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby', 'age': 7 }, headers={'X-Requested-With': 'requests'}) assert response.status_code == 201 assert dict_contains( response.json, { 'id': 4, 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby', 'age': 7, 'updated_at': iso_regex, 'created_at': iso_regex })
def test_create_task_instance(app, instances): test_client = app.test_client() csrf_token = login(test_client) task_instance = { 'task_name': 'task1', 'unique': 'user-32324-payment-973794' } response = json_call(test_client.post, '/v1/task-instances', task_instance, headers={'X-CSRF': csrf_token}) assert response.status_code == 201 assert dict_contains( response.json, { 'id': 5, 'task_name': 'task1', 'workflow_instance_id': None, 'status': 'queued', 'run_at': iso_regex, 'unique': 'user-32324-payment-973794', 'params': {}, 'priority': 'normal', 'started_at': None, 'scheduled': False, 'ended_at': None, 'attempts': 0, 'max_attempts': 1, 'timeout': 300, 'retry_delay': 300, 'push': False, 'push_state': None, 'worker_id': None, 'locked_at': None, 'created_at': iso_regex, 'updated_at': iso_regex })
def test_list_workflows(app): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/v1/workflows') assert response.status_code == 200 assert response.json['count'] == 2 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 2 assert dict_contains( response.json['data'][0], { 'name': 'workflow1', 'active': True, 'title': None, 'description': None, 'schedule': '0 6 * * *', 'start_date': None, 'end_date': None, 'concurrency': 1, 'sla': None, 'default_priority': 'normal' }) assert dict_contains( response.json['data'][1], { 'name': 'workflow2', 'active': True, 'title': None, 'description': None, 'schedule': None, 'start_date': None, 'end_date': None, 'concurrency': 1, 'sla': None, 'default_priority': 'normal' })
def test_login(app): test_client = app.test_client() response = json_call(test_client.post, '/session', email='*****@*****.**', password='******') assert response.status_code == 201 assert 'Set-Cookie' in response.headers cookie_regex = r'session=[^;]+;\sExpires=[A-Za-z]{3},\s[0-9]{2}\s[A-Za-z]{3}\s[0-9]{4}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\sGMT;\sHttpOnly' matches = re.match(cookie_regex, response.headers['Set-Cookie']) assert matches != None with app.app_context(): log_entry = db.session.query(app.auth.auth_log_entry_model).first() assert log_entry.type == 'login' assert log_entry.email == '*****@*****.**' assert log_entry.user_id == 1 assert log_entry.ip == '127.0.0.1' assert isinstance(log_entry.timestamp, datetime) assert log_entry.user_agent == 'werkzeug/0.14.1'
def test_order_by_pattern(app): test_client = app.test_client() login(test_client) ## asc response = json_call(test_client.get, '/cats?$order_by=pattern') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 3 assert dict_contains( response.json['data'][0], { 'id': 3, 'name': 'Wilhelmina', 'age': 4, 'pattern': 'Calico', 'updated_at': iso_regex, 'created_at': iso_regex }) assert dict_contains( response.json['data'][1], { 'id': 1, 'name': 'Ada', 'age': 5, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) assert dict_contains( response.json['data'][2], { 'id': 2, 'name': 'Leo', 'age': 2, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) ## desc response = json_call(test_client.get, '/cats?$order_by=-pattern') assert response.status_code == 200 assert response.json['count'] == 3 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 3 assert dict_contains( response.json['data'][0], { 'id': 1, 'name': 'Ada', 'age': 5, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) assert dict_contains( response.json['data'][1], { 'id': 2, 'name': 'Leo', 'age': 2, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) assert dict_contains( response.json['data'][2], { 'id': 3, 'name': 'Wilhelmina', 'age': 4, 'pattern': 'Calico', 'updated_at': iso_regex, 'created_at': iso_regex })
def test_csrf(app): test_client = app.test_client() login(test_client) ## POST response = json_call(test_client.post, '/cats', { 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby', 'age': 7 }) assert response.status_code == 401 response = json_call(test_client.post, '/cats', { 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby', 'age': 7 }, headers={'x-requested-with': 'requests'}) assert response.status_code == 201 assert dict_contains( response.json, { 'id': 4, 'name': 'Dr. Kitty McMoewMoew', 'pattern': 'Tabby', 'age': 7, 'updated_at': iso_regex, 'created_at': iso_regex }) ## PUT response = json_call(test_client.get, '/cats/2') assert response.status_code == 200 cat = response.json cat['age'] = 3 response = json_call(test_client.put, '/cats/2', cat) assert response.status_code == 401 response = json_call(test_client.put, '/cats/2', cat, headers={'X-Requested-With': 'requests'}) assert response.status_code == 200 assert dict_contains( response.json, { 'id': 2, 'name': 'Leo', 'age': 3, 'pattern': 'Tabby', 'updated_at': iso_regex, 'created_at': iso_regex }) ## DELETE response = test_client.delete('/cats/2') assert response.status_code == 401 response = test_client.delete('/cats/2', headers={'X-Requested-With': 'requests'}) assert response.status_code == 204 response = test_client.get('/cats/2') assert response.status_code == 404
def test_list_task_instances(app, instances): test_client = app.test_client() login(test_client) response = json_call(test_client.get, '/v1/task-instances') assert response.status_code == 200 assert response.json['count'] == 4 assert response.json['page'] == 1 assert response.json['total_pages'] == 1 assert len(response.json['data']) == 4 assert dict_contains( response.json['data'][0], { 'id': 1, 'task_name': 'task1', 'workflow_instance_id': 1, 'status': 'success', 'run_at': iso_regex, 'unique': None, 'params': {}, 'priority': 'normal', 'started_at': iso_regex, 'scheduled': True, 'ended_at': iso_regex, 'attempts': 1, 'max_attempts': 1, 'timeout': 300, 'retry_delay': 300, 'push': False, 'push_state': None, 'worker_id': None, 'locked_at': None, 'created_at': iso_regex, 'updated_at': iso_regex }) assert dict_contains( response.json['data'][1], { 'id': 2, 'task_name': 'task2', 'workflow_instance_id': 1, 'status': 'success', 'run_at': iso_regex, 'unique': None, 'params': {}, 'priority': 'normal', 'started_at': iso_regex, 'scheduled': True, 'ended_at': iso_regex, 'attempts': 1, 'max_attempts': 1, 'timeout': 300, 'retry_delay': 300, 'push': False, 'push_state': None, 'worker_id': None, 'locked_at': None, 'created_at': iso_regex, 'updated_at': iso_regex }) assert dict_contains( response.json['data'][2], { 'id': 3, 'task_name': 'task3', 'workflow_instance_id': 1, 'status': 'success', 'run_at': iso_regex, 'unique': None, 'params': {}, 'priority': 'normal', 'started_at': iso_regex, 'scheduled': True, 'ended_at': iso_regex, 'attempts': 1, 'max_attempts': 1, 'timeout': 300, 'retry_delay': 300, 'push': False, 'push_state': None, 'worker_id': None, 'locked_at': None, 'created_at': iso_regex, 'updated_at': iso_regex }) assert dict_contains( response.json['data'][3], { 'id': 4, 'task_name': 'task4', 'workflow_instance_id': 1, 'status': 'running', 'run_at': iso_regex, 'unique': None, 'params': {}, 'priority': 'normal', 'started_at': iso_regex, 'scheduled': True, 'ended_at': None, 'attempts': 1, 'max_attempts': 1, 'timeout': 300, 'retry_delay': 300, 'push': False, 'push_state': None, 'worker_id': None, 'locked_at': None, 'created_at': iso_regex, 'updated_at': iso_regex })