def test_install_new_agent_new_user_existing_strand_user(self, slack_oauth_response_and_user_in_strand, client, slack_client_class, strand_api_client, db_session, mocker, baseline_thread_count): """ GIVEN: new agent, new user, existing strand user OUTPUT: new Agent, new User, new Installation, new StrandTeam, new StrandUser - StrandTeam relationship """ # `slack_oauth_response_and_user_in_strand` sets up state with an existing strand user target_url = url_for(endpoint=self.target_endpoint) f = slack_oauth_response_and_user_in_strand # faked data payload = {'code': f.code} mocker.spy(slack_client_class, 'api_call') mocker.spy(strand_api_client, 'mutate') client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die(baseline_count=baseline_thread_count), 'Extra threads timed out' assert_values_in_call_args_list( params_to_expecteds=[ {'method': 'oauth.access', 'code': f.code}, # Call Slack OAuth {'method': 'chat.postMessage'}, # DM user with welcome message ], call_args_list=slack_client_class.api_call.call_args_list ) assert 'createTeam' in strand_api_client.mutate.call_args_list[0][1]['operation_definition'] assert 'addMembersToTeam' in strand_api_client.mutate.call_args_list[1][1]['operation_definition'] assert len(strand_api_client.mutate.call_args_list) == 2 assert db_session.query(Agent).filter(Agent.slack_team_id == f.slack_oauth_access_response.team_id).one() assert db_session.query(User).filter(User.agent_slack_team_id == f.slack_oauth_access_response.team_id).one() assert db_session.query(Installation).filter( Installation.installer_agent_slack_team_id == f.slack_oauth_access_response.team_id).one()
def test_remove_application(self, installed_agent: Agent, slack_event_request_factory, slack_client_class, baseline_thread_count, client, mocker, db_session): """Remove the agent when receiving a slack event regarding application removal""" assert 1 == db_session.query(Agent).filter_by( slack_team_id=installed_agent.slack_team_id).count() target_url = url_for(endpoint=self.target_endpoint) fake_slack_event_request = slack_event_request_factory( type='event_callback', challenge=None, team_id=installed_agent.slack_team_id, event=SlackEventFactory.create(type='app_uninstalled')) payload = json.loads(fake_slack_event_request.to_json()) mocker.spy(slack_client_class, 'api_call') response = client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die( baseline_count=baseline_thread_count), 'Extra threads timed out' assert HTTPStatus.OK == response.status_code assert 0 == db_session.query(Agent).filter_by( slack_team_id=installed_agent.slack_team_id).count()
def test_install_just_existing_agent_new_user(self, slack_oauth_response_and_agent_in_db, client, slack_client_class, strand_api_client, db_session, mocker, baseline_thread_count): """ GIVEN: existing agent, new user, existing strand team, new bot OUTPUT: new User, new Installation, new StrandUser, updated bot """ # `slack_oauth_access_and_agent_in_db` sets up state with one existing installation target_url = url_for(endpoint=self.target_endpoint) f = slack_oauth_response_and_agent_in_db # faked data payload = {'code': f.code} mocker.spy(slack_client_class, 'api_call') mocker.spy(strand_api_client, 'mutate') current_bot_access_token = db_session.query(Bot).one().access_token client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die(baseline_count=baseline_thread_count), 'Extra threads timed out' assert_values_in_call_args_list( params_to_expecteds=[ {'method': 'oauth.access', 'code': f.code}, # Call Slack OAuth {'method': 'chat.postMessage'}, # DM user with welcome message ], call_args_list=slack_client_class.api_call.call_args_list ) assert 'createUserWithTeams' in strand_api_client.mutate.call_args_list[0][1]['operation_definition'] assert len(strand_api_client.mutate.call_args_list) == 1 assert db_session.query(Agent).filter(Agent.slack_team_id == f.slack_oauth_access_response.team_id).one() assert len( db_session.query(User).filter(User.agent_slack_team_id == f.slack_oauth_access_response.team_id).all()) == 2 assert len(db_session.query(Installation).filter( Installation.installer_agent_slack_team_id == f.slack_oauth_access_response.team_id).all()) == 2 print(current_bot_access_token) assert current_bot_access_token != db_session.query(Bot).one().access_token, 'Bot token should be updated'
def test_send_metadata_dialog(self, installed_user: User, slack_client_class, slack_interactive_component_request_factory, baseline_thread_count, client, mocker): """Send the dialog to the user when s/he clicks the button to prompt it""" target_url = url_for(endpoint=self.target_endpoint) fake_strand_id = str(PrimitiveFaker('ean8')) fake_slack_interactive_component_request = slack_interactive_component_request_factory( team=SlackTeamFactory.create(id=installed_user.agent_slack_team_id), user=SlackUserFactory.create(id=installed_user.slack_user_id), actions=[SlackActionFactory.create( name=EditMetadataButton(value=fake_strand_id).name, type='dialog_submission', value=fake_strand_id )] ) fake_trigger_id = fake_slack_interactive_component_request.trigger_id payload = json.loads(fake_slack_interactive_component_request.to_json()) mocker.spy(slack_client_class, 'api_call') response = client.post(path=target_url, headers=self.default_headers, data=urlencode({'payload': json.dumps(payload)})) assert wait_for_extra_threads_to_die(baseline_count=baseline_thread_count), 'Extra threads timed out' assert 200 <= response.status_code <= 300 assert slack_client_class.api_call.call_args[1]['method'] == 'dialog.open' assert slack_client_class.api_call.call_args[1]['trigger_id'] == fake_trigger_id
def test_help_dm_new_user(self, installed_agent: Agent, slack_client_class, slack_event_request_factory, baseline_thread_count, client, mocker, dm_message_text): """All users who do not have the app installed should receive a help to install DM response to any message""" target_url = url_for(endpoint=self.target_endpoint) fake_slack_event_request = slack_event_request_factory( type='event_callback', challenge=None, team_id=installed_agent.slack_team_id, event=SlackEventFactory.create(user=str(PrimitiveFaker('bban')), text=dm_message_text, channel='D12345678', type='message')) payload = json.loads(fake_slack_event_request.to_json()) mocker.spy(slack_client_class, 'api_call') response = client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die( baseline_count=baseline_thread_count), 'Extra threads timed out' assert HTTPStatus.OK == response.status_code assert slack_client_class.api_call.call_args[1][ 'method'] == 'chat.postEphemeral' assert 'installing the app' in slack_client_class.api_call.call_args[ 1]['text']
def test_nonhelp_dm_installed_user(self, installed_user: User, slack_client_class, slack_event_request_factory, baseline_thread_count, client, mocker): """Ensure we don't send a help message in 'non-help' DMs""" target_url = url_for(endpoint=self.target_endpoint) fake_slack_event_request = slack_event_request_factory( type='event_callback', challenge=None, team_id=installed_user.agent_slack_team_id, event=SlackEventFactory.create(user=installed_user.slack_user_id, text='this is not a help dm', channel='D12345678', type='message')) payload = json.loads(fake_slack_event_request.to_json()) mocker.spy(slack_client_class, 'api_call') response = client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die( baseline_count=baseline_thread_count), 'Extra threads timed out' assert HTTPStatus.OK == response.status_code assert_values_in_call_args_list( params_to_expecteds=[ { 'method': 'chat.postEphemeral' }, # Ensure help message was not sent ], call_args_list=slack_client_class.api_call.call_args_list, expect_succeed=False)
def test_help_dm_installed_user(self, installed_user: User, slack_client_class, slack_event_request_factory, baseline_thread_count, client, mocker): """Ensure we send a help message to users who have the app installed when they DM 'help'""" target_url = url_for(endpoint=self.target_endpoint) fake_slack_event_request = slack_event_request_factory( type='event_callback', challenge=None, team_id=installed_user.agent_slack_team_id, event=SlackEventFactory.create(user=installed_user.slack_user_id, text='HELP', channel='D12345678', type='message')) payload = json.loads(fake_slack_event_request.to_json()) mocker.spy(slack_client_class, 'api_call') response = client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die( baseline_count=baseline_thread_count), 'Extra threads timed out' assert HTTPStatus.OK == response.status_code assert slack_client_class.api_call.call_args[1][ 'method'] == 'chat.postEphemeral' assert 'installing the app' not in slack_client_class.api_call.call_args[ 1]['text']
def test_remove_bots_and_installations(self, installed_agent: Agent, slack_event_request_factory, slack_client_class, baseline_thread_count, client, mocker, db_session): """Remove the bot and installer when receiving a slack event regarding tokens revoked""" assert 1 == db_session.query(Bot).filter_by( agent_slack_team_id=installed_agent.slack_team_id).count() assert 1 == db_session.query(Installation).filter_by( installer_agent_slack_team_id=installed_agent.slack_team_id).count( ) assert 1 == db_session.query(Agent).filter_by( slack_team_id=installed_agent.slack_team_id).count() target_url = url_for(endpoint=self.target_endpoint) oauth_token = installed_agent.users[0].installation[0].access_token bot_token = installed_agent.bot.access_token fake_slack_event_request = slack_event_request_factory( type='event_callback', challenge=None, team_id=installed_agent.slack_team_id, event=SlackEventFactory.create( type='tokens_revoked', tokens=SlackTokensFactory.create(oauth=[oauth_token], bot=[bot_token]), ), ) payload = json.loads(fake_slack_event_request.to_json()) mocker.spy(slack_client_class, 'api_call') response = client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die( baseline_count=baseline_thread_count), 'Extra threads timed out' assert HTTPStatus.OK == response.status_code assert 0 == db_session.query(Bot).filter_by( agent_slack_team_id=installed_agent.slack_team_id).count() assert 0 == db_session.query(Installation).filter_by( installer_agent_slack_team_id=installed_agent.slack_team_id).count( ) assert 1 == db_session.query(Agent).filter_by( slack_team_id=installed_agent.slack_team_id).count()
def test_save_installed_user(self, installed_user: User, slack_client_class, strand_api_client, slack_event_request_factory, baseline_thread_count, client, mocker): """Forward the pasted message to Strand API, and send the user an ephemeral message to invoke metadata edit""" target_url = url_for(endpoint=self.target_endpoint) fake_slack_event_request = slack_event_request_factory( type='event_callback', challenge=None, team_id=installed_user.agent_slack_team_id, event=SlackEventFactory.create( user=installed_user.slack_user_id, text='this is some stuff i want saved', channel='D12345678', type='message')) payload = json.loads(fake_slack_event_request.to_json()) mocker.spy(slack_client_class, 'api_call') mocker.spy(strand_api_client, 'mutate') response = client.post(path=target_url, headers=self.default_headers, data=json.dumps(payload)) assert wait_for_extra_threads_to_die( baseline_count=baseline_thread_count), 'Extra threads timed out' assert HTTPStatus.OK == response.status_code assert 'createStrand' in strand_api_client.mutate.call_args[1][ 'operation_definition'] assert str( installed_user.strand_user_id ) in strand_api_client.mutate.call_args[1]['operation_definition'] assert str( installed_user.agent.strand_team_id ) in strand_api_client.mutate.call_args[1]['operation_definition'] assert slack_client_class.api_call.call_args[1][ 'method'] == 'chat.postMessage'
def test_receive_metadata_dialog(self, installed_user: User, slack_client_class, strand_api_client, slack_interactive_component_request_factory, baseline_thread_count, client, mocker): """Receieve the metadata dialog from user when s/he submits, send info to Strand API, and post ephemeral""" target_url = url_for(endpoint=self.target_endpoint) fake_strand_id = str(PrimitiveFaker('ean8')) fake_slack_interactive_component_request = slack_interactive_component_request_factory( type='dialog_submission', callback_id=EditMetadataDialog(strand_id=fake_strand_id).callback_id, team=SlackTeamFactory.create(id=installed_user.agent_slack_team_id), user=SlackUserFactory.create(id=installed_user.slack_user_id), ) payload = json.loads(fake_slack_interactive_component_request.to_json()) mocker.spy(slack_client_class, 'api_call') mocker.spy(strand_api_client, 'mutate') response = client.post(path=target_url, headers=self.default_headers, data=urlencode({'payload': json.dumps(payload)})) assert wait_for_extra_threads_to_die(baseline_count=baseline_thread_count), 'Extra threads timed out' assert 200 <= response.status_code <= 300 assert slack_client_class.api_call.call_args[1]['method'] == 'chat.postEphemeral' assert 'updateStrand' in strand_api_client.mutate.call_args[1]['operation_definition'] assert fake_strand_id in strand_api_client.mutate.call_args[1]['operation_definition']