"""Unit tests for check_dynamo_status.""" from datetime import datetime import pytest import snowflake_views.tasks as tasks from tests.tasks import conftest @pytest.fixture def mock_get_item_from_dynamo(mock_dynamo_table): """Mock get item from Dynamo.""" return mock_dynamo_table.return_value.get_item @pytest.fixture def check_dynamo_status( mock_sf_executor_context_validator, mock_load_view_from_config, mock_ingestion_status_table, mock_activity, mock_aws_region): """Check Dynamo status.""" mock_sf_executor_context_validator.format_identifiers.side_effect = [ (conftest.STATE_SQL, None)] tasks.check_dynamo_status(mock_activity, conftest.VIEW_NAME) def test_dynamo_resource_is_invoked(mock_boto3_resource, check_dynamo_status): """Test Dynamo resource is invoked.""" mock_boto3_resource.assert_called_with( 'dynamodb', region_name=conftest.AWS_REGION) def test_dynamo_table_is_invoked(mock_dynamo_table, check_dynamo_status): """Test Dynamo table is invoked.""" mock_dynamo_table.assert_called_with(conftest.INGESTION_STATUS_TABLE) def test_dynamo_table_is_queried( mock_get_item_from_dynamo, check_dynamo_status): """Test Dynamo is queried.""" mock_get_item_from_dynamo.assert_called_with( Key={'view_name': conftest.VIEW_NAME}, ProjectionExpression='last_processed_timestamp') class TestWhenNoStatus(object): """Tests when no status is set.""" status = {} response = { 'rebuild_view': True, 'current_last_processed_timestamp': '2018-01-01 00:00:00:000000'} @pytest.fixture def mock_dynamo_status(self, mock_get_item_from_dynamo): """Mock DynamoDB status.""" mock_get_item_from_dynamo.return_value = self.status @pytest.fixture def mock_source_last_updated(self, mock_sf_executor_context): """Mock source last updated.""" mock_sf_executor_context.fetchone.return_value = datetime( 2018, 1, 1), @pytest.fixture def check_dynamo_status( self, mock_activity, mock_load_view_from_config, mock_ingestion_status_table, mock_dynamo_status, mock_sf_executor_class, mock_config_sf_params, mock_sf_executor_context_validator, mock_source_last_updated): """Check Dynamo status.""" mock_sf_executor_context_validator.format_identifiers.side_effect = [ (conftest.STATE_SQL, None)] return tasks.check_dynamo_status(mock_activity, conftest.VIEW_NAME) def test_returns_rebuild_view_true(self, check_dynamo_status): """Test returns rebuild view true.""" assert check_dynamo_status == self.response class TestWhenViewUpToDate(object): """Tests when view is up-to-date.""" status = { 'Item': {'last_processed_timestamp': '2018-01-01 00:00:00:000000'}} response = {'rebuild_view': False} @pytest.fixture def mock_dynamo_status(self, mock_get_item_from_dynamo): """Mock DynamoDB status.""" mock_get_item_from_dynamo.return_value = self.status @pytest.fixture def mock_source_last_updated(self, mock_sf_executor_context): """Mock source last updated.""" mock_sf_executor_context.fetchone.return_value = datetime( 2018, 1, 1), @pytest.fixture(autouse=True) def check_dynamo_status( self, mock_activity, mock_load_view_from_config, mock_ingestion_status_table, mock_aws_region, mock_dynamo_status, mock_sf_executor_class, mock_config_sf_params, mock_sf_executor_context_validator, mock_source_last_updated): """Check Dynamo status.""" mock_sf_executor_context_validator.format_identifiers.side_effect = [ (conftest.STATE_SQL, None)] return tasks.check_dynamo_status(mock_activity, conftest.VIEW_NAME) def test_params_are_passed_to_sf_executor( self, mock_sf_executor_class, mock_sf_config): """Test params are passed to SF executor.""" mock_sf_executor_class.assert_called_with(mock_sf_config) def test_state_sql_is_executed(self, mock_sf_executor_context): """Test state SQL is executed.""" mock_sf_executor_context.fetchone.assert_any_call(conftest.STATE_SQL) def test_identifiers_for_state_sql_are_validated( self, mock_sf_executor_context_validator, mock_sf_config): """Test identifiers for state SQL are validated.""" mock_sf_executor_context_validator.format_identifiers.assert_any_call( conftest.STATE_SQL, mock_sf_config) def test_returns_rebuild_view_false(self, check_dynamo_status): """Test returns rebuild view false.""" assert check_dynamo_status == self.response class TestWhenViewBehind(object): """Tests when view is behind.""" status = { 'Item': {'last_processed_timestamp': '2018-01-01 00:00:00:000000'}} response = { 'rebuild_view': True, 'current_last_processed_timestamp': '2018-01-02 00:00:00:000000'} @pytest.fixture def mock_dynamo_status(self, mock_get_item_from_dynamo): """Mock DynamoDB status.""" mock_get_item_from_dynamo.return_value = self.status @pytest.fixture def mock_source_last_updated(self, mock_sf_executor_context): """Mock source last updated.""" mock_sf_executor_context.fetchone.return_value = datetime( 2018, 1, 2), @pytest.fixture def check_dynamo_status( self, mock_activity, mock_load_view_from_config, mock_ingestion_status_table, mock_aws_region, mock_dynamo_status, mock_sf_executor_class, mock_config_sf_params, mock_sf_executor_context_validator, mock_source_last_updated): """Check Dynamo status.""" mock_sf_executor_context_validator.format_identifiers.side_effect = [ (conftest.STATE_SQL, None)] return tasks.check_dynamo_status(mock_activity, conftest.VIEW_NAME) def test_returns_rebuild_view_true(self, check_dynamo_status): """Test returns rebuild view true.""" assert check_dynamo_status == self.response