blob: 5e4d23ab6fb57bcca9f4f60fa3b2b320623c984d [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from unittest.mock import MagicMock
import pytest
from pytest_mock import MockerFixture
from superset.commands.database.create import CreateDatabaseCommand
from superset.exceptions import OAuth2RedirectError
from superset.extensions import security_manager
@pytest.fixture
def database_with_catalog(mocker: MockerFixture) -> MagicMock:
"""
Mock a database with catalogs and schemas.
"""
mocker.patch("superset.commands.database.create.TestConnectionDatabaseCommand")
database = mocker.MagicMock()
database.database_name = "test_database"
database.db_engine_spec.__name__ = "test_engine"
database.db_engine_spec.supports_catalog = True
database.get_all_catalog_names.return_value = ["catalog1", "catalog2"]
database.get_all_schema_names.side_effect = [
{"schema1", "schema2"},
{"schema3", "schema4"},
]
DatabaseDAO = mocker.patch("superset.commands.database.create.DatabaseDAO") # noqa: N806
DatabaseDAO.create.return_value = database
return database
@pytest.fixture
def database_without_catalog(mocker: MockerFixture) -> MagicMock:
"""
Mock a database without catalogs.
"""
mocker.patch("superset.commands.database.create.TestConnectionDatabaseCommand")
database = mocker.MagicMock()
database.database_name = "test_database"
database.db_engine_spec.__name__ = "test_engine"
database.db_engine_spec.supports_catalog = False
database.get_all_schema_names.return_value = ["schema1", "schema2"]
DatabaseDAO = mocker.patch("superset.commands.database.create.DatabaseDAO") # noqa: N806
DatabaseDAO.create.return_value = database
return database
def test_create_permissions_with_catalog(
mocker: MockerFixture,
database_with_catalog: MockerFixture,
) -> None:
"""
Test that permissions are created when a database with a catalog is created.
"""
add_permission_view_menu = mocker.patch.object(
security_manager,
"add_permission_view_menu",
)
CreateDatabaseCommand(
{
"database_name": "test_database",
"sqlalchemy_uri": "sqlite://",
}
).run()
add_permission_view_menu.assert_has_calls(
[
mocker.call("catalog_access", "[test_database].[catalog1]"),
mocker.call("catalog_access", "[test_database].[catalog2]"),
mocker.call("schema_access", "[test_database].[catalog1].[schema1]"),
mocker.call("schema_access", "[test_database].[catalog1].[schema2]"),
mocker.call("schema_access", "[test_database].[catalog2].[schema3]"),
mocker.call("schema_access", "[test_database].[catalog2].[schema4]"),
],
any_order=True,
)
def test_create_permissions_without_catalog(
mocker: MockerFixture,
database_without_catalog: MockerFixture,
) -> None:
"""
Test that permissions are created when a database without a catalog is created.
"""
add_permission_view_menu = mocker.patch.object(
security_manager,
"add_permission_view_menu",
)
CreateDatabaseCommand(
{
"database_name": "test_database",
"sqlalchemy_uri": "sqlite://",
}
).run()
add_permission_view_menu.assert_has_calls(
[
mocker.call("schema_access", "[test_database].[schema1]"),
mocker.call("schema_access", "[test_database].[schema2]"),
],
any_order=True,
)
def test_create_with_oauth2(
mocker: MockerFixture,
database_without_catalog: MockerFixture,
) -> None:
"""
Test that the database can be created even if OAuth2 is needed to connect.
"""
TestConnectionDatabaseCommand = mocker.patch( # noqa: N806
"superset.commands.database.create.TestConnectionDatabaseCommand"
)
TestConnectionDatabaseCommand().run.side_effect = OAuth2RedirectError(
"url",
"tab_id",
"redirect_uri",
)
add_permission_view_menu = mocker.patch.object(
security_manager,
"add_permission_view_menu",
)
CreateDatabaseCommand(
{
"database_name": "test_database",
"sqlalchemy_uri": "sqlite://",
}
).run()
add_permission_view_menu.assert_not_called()