def test_scheduled_json_report_action(self): """Create a scheduled send report action and execute it.""" token = 'false token' settings.EXECUTE_ACTION_JSON_TRANSFER = False OnTaskSharedState.json_outbox = [] user = get_user_model().objects.get(email='*****@*****.**') # User must exist self.assertIsNotNone(user, 'User [email protected] not found') action = models.Action.objects.get(name='send json report') now = datetime.now(pytz.timezone(settings.TIME_ZONE)) scheduled_item = models.ScheduledOperation( user=user, operation_type=models.Log.ACTION_RUN_JSON_REPORT, name='JSON Report scheduled action', workflow=action.workflow, action=action, execute=now + timedelta(minutes=2), status=models.scheduler.STATUS_PENDING, payload={'token': token}) scheduled_item.save() # Execute the scheduler tasks.execute_scheduled_operation(scheduled_item.id) json_outbox = OnTaskSharedState.json_outbox scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_DONE assert len(json_outbox) == 1 assert all(token in item['auth'] for item in json_outbox)
def test_scheduled_email_report(self): """Create a scheduled send report action and execute it.""" user = get_user_model().objects.get(email='*****@*****.**') # User must exist self.assertIsNotNone(user, 'User [email protected] not found') action = models.Action.objects.get(name='send list') now = datetime.now(pytz.timezone(settings.TIME_ZONE)) scheduled_item = models.ScheduledOperation( user=user, operation_type=models.Log.ACTION_RUN_EMAIL_REPORT, name='send list scheduled action', workflow=action.workflow, action=action, execute=now + self.tdelta, status=models.scheduler.STATUS_PENDING, payload={ 'email_to': '*****@*****.**', 'subject': 'Action subject', 'cc_email': '', 'bcc_email': '' }) scheduled_item.save() # Execute the scheduler tasks.execute_scheduled_operation(scheduled_item.id) scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_DONE assert len(mail.outbox) == 1 assert ('*****@*****.**' in mail.outbox[0].body) assert ('*****@*****.**' in mail.outbox[0].body)
def test_scheduled_json_action(self): """Create a scheduled send list action and execute it.""" token = 'fake token' OnTaskSharedState.json_outbox = [] settings.EXECUTE_ACTION_JSON_TRANSFER = False user = get_user_model().objects.get(email='*****@*****.**') # User must exist self.assertIsNotNone(user, 'User [email protected] not found') action = models.Action.objects.get(name='send json') now = datetime.now(pytz.timezone(settings.TIME_ZONE)) scheduled_item = models.ScheduledOperation( user=user, operation_type=models.Log.ACTION_RUN_PERSONALIZED_JSON, name='JSON scheduled action', workflow=action.workflow, action=action, execute=now + self.tdelta, status=models.scheduler.STATUS_PENDING, payload={ 'item_column': action.workflow.columns.get(name='email').id, 'token': token }) scheduled_item.save() # Execute the scheduler tasks.execute_scheduled_operation(scheduled_item.id) scheduled_item.refresh_from_db() json_outbox = OnTaskSharedState.json_outbox assert scheduled_item.status == models.scheduler.STATUS_DONE assert len(json_outbox) == 3 assert all(item['target'] == action.target_url for item in json_outbox) assert all(token in item['auth'] for item in json_outbox)
def test_scheduled_email_action(self): """Create a scheduled send email action and execute it.""" user = get_user_model().objects.get(email='*****@*****.**') # User must exist self.assertIsNotNone(user, 'User [email protected] not found') action = models.Action.objects.get(name='send email') now = datetime.now(pytz.timezone(settings.TIME_ZONE)) scheduled_item = models.ScheduledOperation( user=user, operation_type=models.Log.ACTION_RUN_PERSONALIZED_EMAIL, name='send email action', workflow=action.workflow, action=action, execute=now + self.tdelta, status=models.scheduler.STATUS_PENDING, payload={ 'item_column': action.workflow.columns.get(name='email').id, 'subject': 'Email subject', 'cc_email': '', 'bcc_email': '', 'send_confirmation': False, 'track_read': False }) scheduled_item.save() # Execute the scheduler tasks.execute_scheduled_operation(scheduled_item.id) scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_DONE assert len(mail.outbox) == 2 assert 'Hi Student Two' in mail.outbox[0].body assert 'Hi Student Three' in mail.outbox[1].body
def test_scheduled_incremental_email(self): """Test an incremental scheduled action.""" # Modify the data table so that initially all records have registered # equal to alse workflow = models.Workflow.objects.all().first() with connection.cursor() as cursor: query = sql.SQL('UPDATE {0} SET {1} = false').format( sql.Identifier(workflow.get_data_frame_table_name()), sql.Identifier('registered')) cursor.execute(query) user = get_user_model().objects.get(email='*****@*****.**') # User must exist self.assertIsNotNone(user, 'User [email protected] not found') action = models.Action.objects.get(name='send email incrementally') now = datetime.now(pytz.timezone(settings.TIME_ZONE)) scheduled_item = models.ScheduledOperation( user=user, operation_type=models.Log.ACTION_RUN_PERSONALIZED_EMAIL, name='send email action incrementally', workflow=action.workflow, action=action, execute=now, frequency='* * * * *', execute_until=now + timedelta(hours=1), status=models.scheduler.STATUS_PENDING, payload={ 'item_column': action.workflow.columns.get(name='email').id, 'exclude_values': [], 'subject': 'Email subject', 'cc_email': '', 'bcc_email': '', 'send_confirmation': False, 'track_read': False }) scheduled_item.save() # Execute the scheduler for the first time tasks.execute_scheduled_operation(scheduled_item.id) # Event still pending, with no values in exclude values scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_PENDING assert scheduled_item.payload.get('exclude_values', []) == [] # Modify one of the values in the matrix with connection.cursor() as cursor: query = sql.SQL( 'UPDATE {0} SET {1} = true WHERE {2} = {3}').format( sql.Identifier(workflow.get_data_frame_table_name()), sql.Identifier('registered'), sql.Identifier('email'), sql.Placeholder()) cursor.execute(query, ['*****@*****.**']) # Execute the scheduler for the first time tasks.execute_scheduled_operation(scheduled_item.id) # Event still pending, with one values in exclude values scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_PENDING assert scheduled_item.payload['exclude_values'] == [ '*****@*****.**' ] # Modify one of the values in the matrix with connection.cursor() as cursor: query = sql.SQL( 'UPDATE {0} SET {1} = true WHERE {2} = {3}').format( sql.Identifier(workflow.get_data_frame_table_name()), sql.Identifier('registered'), sql.Identifier('email'), sql.Placeholder()) cursor.execute(query, ['*****@*****.**']) # Execute the scheduler for the first time tasks.execute_scheduled_operation(scheduled_item.id) # Event still pending, with two values in exclude values scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_PENDING assert scheduled_item.payload['exclude_values'] == [ '*****@*****.**', '*****@*****.**' ] # Modify one of the values in the matrix with connection.cursor() as cursor: query = sql.SQL( 'UPDATE {0} SET {1} = true WHERE {2} = {3}').format( sql.Identifier(workflow.get_data_frame_table_name()), sql.Identifier('registered'), sql.Identifier('email'), sql.Placeholder()) cursor.execute(query, ['*****@*****.**']) # Execute the scheduler for the first time tasks.execute_scheduled_operation(scheduled_item.id) # Event still pending, with three values in exclude values scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_PENDING assert scheduled_item.payload['exclude_values'] == [ '*****@*****.**', '*****@*****.**', '*****@*****.**' ] # Execute the scheduler for the first time tasks.execute_scheduled_operation(scheduled_item.id) # Event still pending, with no values in exclude values scheduled_item.refresh_from_db() assert scheduled_item.status == models.scheduler.STATUS_PENDING assert scheduled_item.payload['exclude_values'] == [ '*****@*****.**', '*****@*****.**', '*****@*****.**' ]
def test_sql_update_create(self): """Create a new SQL Scheduled operation.""" initial_df = self.workflow.data_frame() # Create the new table in the DB for the scheduled operation with connection.connection.cursor() as cursor: # Add the extra table to the database for the merge for query, fields in SQL_QUERIES: cursor.execute(query, fields) # Save some current variables for future checks current_ops = models.ScheduledOperation.objects.count() current_tasks = PeriodicTask.objects.count() current_nrows = self.workflow.nrows current_columns = self.workflow.ncols # Index page should be ok resp = self.get_response('scheduler:index') self.assertTrue(status.is_success(resp.status_code)) # GET the page to select the SQL connection resp = self.get_response('scheduler:select_sql') self.assertTrue(status.is_success(resp.status_code)) for sql_conn in models.SQLConnection.objects.all(): self.assertTrue(sql_conn.name in str(resp.content)) # Get the connection pointing to localhost sql_conn = models.SQLConnection.objects.get(name='remote server 2') # Modify connection to point to the test DB sql_conn.db_name = settings.DATABASE_URL['NAME'] sql_conn.save() # GET the form to create the scheduled SQL operation resp = self.get_response('scheduler:sqlupload', {'pk': str(sql_conn.id)}) self.assertTrue(status.is_success(resp.status_code)) # POST incorrect form without a dst key resp = self.get_response('scheduler:sqlupload', {'pk': str(sql_conn.id)}, method='POST', req_params={ 'name': 'schedule sql upload', 'execute': '05/31/2999 14:35', 'src_key': 'email', 'how_merge': 'outer', 'db_password': '******' }) self.assertTrue(status.is_success(resp.status_code)) self.assertIn('operation requires the names', str(resp.content)) # POST incorrect form without a src key resp = self.get_response('scheduler:sqlupload', {'pk': str(sql_conn.id)}, method='POST', req_params={ 'name': 'schedule sql upload', 'execute': '05/31/2999 14:35', 'dst_key': 'email', 'how_merge': 'outer', 'db_password': '******' }) self.assertTrue(status.is_success(resp.status_code)) self.assertIn('operation requires the names', str(resp.content)) # POST incorrect form without a non-existent dst_key resp = self.get_response('scheduler:sqlupload', {'pk': str(sql_conn.id)}, method='POST', req_params={ 'name': 'schedule sql upload', 'execute': '05/31/2999 14:35', 'dst_key': 'INCORRECT NAME', 'src_key': 'email', 'how_merge': 'outer', 'db_password': '******' }) self.assertTrue(status.is_success(resp.status_code)) self.assertIn('is not a key column', str(resp.content)) # POST incorrect form without an incorrect dst_key resp = self.get_response('scheduler:sqlupload', {'pk': str(sql_conn.id)}, method='POST', req_params={ 'name': 'schedule sql upload', 'execute': '05/31/2999 14:35', 'dst_key': 'Gender', 'src_key': 'email', 'how_merge': 'outer', 'db_password': '******' }) self.assertTrue(status.is_success(resp.status_code)) self.assertIn('is not a key column', str(resp.content)) # POST incorrect form without a merge method resp = self.get_response('scheduler:sqlupload', {'pk': str(sql_conn.id)}, method='POST', req_params={ 'name': 'schedule sql upload', 'execute': '05/31/2999 14:35', 'dst_key': 'Gender', 'src_key': 'email', 'db_password': '******' }) self.assertTrue(status.is_success(resp.status_code)) self.assertIn('requires a merge method', str(resp.content)) # POST the correct form to create the SQL operation resp = self.get_response('scheduler:sqlupload', {'pk': str(sql_conn.id)}, method='POST', req_params={ 'name': 'schedule sql upload', 'execute': '05/31/2999 14:35', 'dst_key': 'email', 'src_key': 'email', 'how_merge': 'outer', 'db_password': '******' }) self.assertTrue(status.is_success(resp.status_code)) self.assertEqual(current_ops + 1, models.ScheduledOperation.objects.count()) # Execute the operation s_item = self.workflow.scheduled_operations.get( name='schedule sql upload') tasks.execute_scheduled_operation(s_item.id) # Verify the result of the operation s_item.refresh_from_db() self.workflow.refresh_from_db() # Identical number of tasks pending than at the start self.assertEqual(current_tasks + 1, PeriodicTask.objects.count()) # Operation must have status equal to DONE self.assertEqual(s_item.status, models.scheduler.STATUS_DONE) # Operation execution time must be reflected in the log field self.assertIsNotNone(s_item.last_executed_log) # Number of rows and columns in workflow has changed self.assertEqual(self.workflow.nrows, current_nrows + 3) self.assertEqual(self.workflow.ncols, current_columns + 1) # New column with the right name and type new_column = self.workflow.columns.filter(name='NEW COLUMN').first() self.assertIsNotNone(new_column) self.assertEqual(new_column.data_type, 'double') result_df = self.workflow.data_frame() # New rows with the right email email_values = list(result_df['email']) self.assertIn('*****@*****.**', email_values) self.assertIn('*****@*****.**', email_values) self.assertIn('*****@*****.**', email_values) # Columns with the right value old_hecs_count = initial_df['Enrolment Type'].loc[ initial_df['Enrolment Type'] == 'Local'].count() new_hecs_count = result_df['Enrolment Type'].loc[ result_df['Enrolment Type'] == 'Local'].count() self.assertEqual(old_hecs_count + 6, new_hecs_count) self.assertEqual(result_df['NEW COLUMN'].count(), 6)