mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-10 00:05:27 +00:00
This commit is contained in:
parent
749dd0de14
commit
c8055576ba
@ -79,6 +79,8 @@ class DomodashboardSource(DashboardServiceSource):
|
|||||||
return cls(config, metadata)
|
return cls(config, metadata)
|
||||||
|
|
||||||
def get_dashboards_list(self) -> Optional[List[DomoDashboardDetails]]:
|
def get_dashboards_list(self) -> Optional[List[DomoDashboardDetails]]:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
dashboards = self.client.domo.page_list()
|
dashboards = self.client.domo.page_list()
|
||||||
dashboard_list = []
|
dashboard_list = []
|
||||||
for dashboard in dashboards:
|
for dashboard in dashboards:
|
||||||
@ -104,15 +106,23 @@ class DomodashboardSource(DashboardServiceSource):
|
|||||||
def get_owner_ref(
|
def get_owner_ref(
|
||||||
self, dashboard_details: DomoDashboardDetails
|
self, dashboard_details: DomoDashboardDetails
|
||||||
) -> Optional[EntityReferenceList]:
|
) -> Optional[EntityReferenceList]:
|
||||||
|
try:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
return None
|
||||||
for owner in dashboard_details.owners or []:
|
for owner in dashboard_details.owners or []:
|
||||||
try:
|
try:
|
||||||
owner_details = self.client.domo.users_get(owner.id)
|
owner_details = self.client.domo.users_get(owner.id)
|
||||||
if owner_details.get("email"):
|
if owner_details.get("email"):
|
||||||
return self.metadata.get_reference_by_email(owner_details["email"])
|
return self.metadata.get_reference_by_email(
|
||||||
|
owner_details["email"]
|
||||||
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Error while getting details of user {owner.displayName} - {exc}"
|
f"Error while getting details of user {owner.displayName} - {exc}"
|
||||||
)
|
)
|
||||||
|
except Exception as err:
|
||||||
|
logger.debug(traceback.format_exc())
|
||||||
|
logger.warning(f"Could not fetch owner data due to {err}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def yield_dashboard(
|
def yield_dashboard(
|
||||||
|
@ -922,6 +922,8 @@ class LookerSource(DashboardServiceSource):
|
|||||||
"""
|
"""
|
||||||
Get List of all dashboards
|
Get List of all dashboards
|
||||||
"""
|
"""
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
try:
|
try:
|
||||||
return list(
|
return list(
|
||||||
self.client.all_dashboards(fields=",".join(LIST_DASHBOARD_FIELDS))
|
self.client.all_dashboards(fields=",".join(LIST_DASHBOARD_FIELDS))
|
||||||
@ -963,6 +965,8 @@ class LookerSource(DashboardServiceSource):
|
|||||||
Optional[EntityReference]
|
Optional[EntityReference]
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
return None
|
||||||
if dashboard_details.user_id is not None:
|
if dashboard_details.user_id is not None:
|
||||||
dashboard_owner = self.client.user(dashboard_details.user_id)
|
dashboard_owner = self.client.user(dashboard_details.user_id)
|
||||||
if dashboard_owner.email:
|
if dashboard_owner.email:
|
||||||
|
@ -108,6 +108,8 @@ class MetabaseSource(DashboardServiceSource):
|
|||||||
"""
|
"""
|
||||||
Get List of all dashboards
|
Get List of all dashboards
|
||||||
"""
|
"""
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
self.dashboards_list = self.client.get_dashboards_list(self.collections)
|
self.dashboards_list = self.client.get_dashboards_list(self.collections)
|
||||||
return self.dashboards_list
|
return self.dashboards_list
|
||||||
|
|
||||||
@ -180,6 +182,8 @@ class MetabaseSource(DashboardServiceSource):
|
|||||||
Get dashboard owner from email
|
Get dashboard owner from email
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
return None
|
||||||
if dashboard_details.creator_id:
|
if dashboard_details.creator_id:
|
||||||
owner_details = self.client.get_user_details(
|
owner_details = self.client.get_user_details(
|
||||||
dashboard_details.creator_id
|
dashboard_details.creator_id
|
||||||
|
@ -110,6 +110,8 @@ class RedashSource(DashboardServiceSource):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_dashboards_list(self) -> Optional[List[dict]]:
|
def get_dashboards_list(self) -> Optional[List[dict]]:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
return self.dashboard_list
|
return self.dashboard_list
|
||||||
|
|
||||||
def get_dashboard_name(self, dashboard: dict) -> str:
|
def get_dashboard_name(self, dashboard: dict) -> str:
|
||||||
@ -123,6 +125,8 @@ class RedashSource(DashboardServiceSource):
|
|||||||
Get owner from email
|
Get owner from email
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
return None
|
||||||
if dashboard_details.get("user") and dashboard_details["user"].get("email"):
|
if dashboard_details.get("user") and dashboard_details["user"].get("email"):
|
||||||
return self.metadata.get_reference_by_email(
|
return self.metadata.get_reference_by_email(
|
||||||
dashboard_details["user"].get("email")
|
dashboard_details["user"].get("email")
|
||||||
|
@ -91,6 +91,8 @@ class SigmaSource(DashboardServiceSource):
|
|||||||
"""
|
"""
|
||||||
get list of dashboard
|
get list of dashboard
|
||||||
"""
|
"""
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
return self.client.get_dashboards()
|
return self.client.get_dashboards()
|
||||||
|
|
||||||
def get_dashboard_name(self, dashboard: Workbook) -> Optional[str]:
|
def get_dashboard_name(self, dashboard: Workbook) -> Optional[str]:
|
||||||
@ -367,6 +369,8 @@ class SigmaSource(DashboardServiceSource):
|
|||||||
Get owner from email
|
Get owner from email
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
return None
|
||||||
if dashboard_details.ownerId:
|
if dashboard_details.ownerId:
|
||||||
owner = self.client.get_owner_detail(dashboard_details.ownerId)
|
owner = self.client.get_owner_detail(dashboard_details.ownerId)
|
||||||
return self.metadata.get_reference_by_email(owner.email)
|
return self.metadata.get_reference_by_email(owner.email)
|
||||||
|
@ -77,6 +77,8 @@ class SupersetAPISource(SupersetSourceMixin):
|
|||||||
"""
|
"""
|
||||||
Get List of all dashboards
|
Get List of all dashboards
|
||||||
"""
|
"""
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
current_page = 0
|
current_page = 0
|
||||||
page_size = 25
|
page_size = 25
|
||||||
total_dashboards = self.client.fetch_total_dashboards()
|
total_dashboards = self.client.fetch_total_dashboards()
|
||||||
|
@ -111,6 +111,8 @@ class SupersetDBSource(SupersetSourceMixin):
|
|||||||
"""
|
"""
|
||||||
Get List of all dashboards
|
Get List of all dashboards
|
||||||
"""
|
"""
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
query = (
|
query = (
|
||||||
FETCH_DASHBOARDS
|
FETCH_DASHBOARDS
|
||||||
if self.source_config.includeDraftDashboard
|
if self.source_config.includeDraftDashboard
|
||||||
|
@ -117,6 +117,8 @@ class SupersetSourceMixin(DashboardServiceSource):
|
|||||||
self, dashboard_details: Union[DashboardResult, FetchDashboard]
|
self, dashboard_details: Union[DashboardResult, FetchDashboard]
|
||||||
) -> Optional[EntityReferenceList]:
|
) -> Optional[EntityReferenceList]:
|
||||||
try:
|
try:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
return None
|
||||||
if hasattr(dashboard_details, "owners"):
|
if hasattr(dashboard_details, "owners"):
|
||||||
for owner in dashboard_details.owners or []:
|
for owner in dashboard_details.owners or []:
|
||||||
if owner.email:
|
if owner.email:
|
||||||
|
@ -106,8 +106,15 @@ class TableauClient:
|
|||||||
def site_id(self) -> str:
|
def site_id(self) -> str:
|
||||||
return self.tableau_server.site_id
|
return self.tableau_server.site_id
|
||||||
|
|
||||||
def get_tableau_owner(self, owner_id: str) -> Optional[TableauOwner]:
|
def get_tableau_owner(
|
||||||
|
self, owner_id: str, include_owners: bool = True
|
||||||
|
) -> Optional[TableauOwner]:
|
||||||
|
"""
|
||||||
|
Get tableau owner with optional include_owners flag
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
|
if not include_owners:
|
||||||
|
return None
|
||||||
if owner_id in self.owner_cache:
|
if owner_id in self.owner_cache:
|
||||||
return self.owner_cache[owner_id]
|
return self.owner_cache[owner_id]
|
||||||
owner = self.tableau_server.users.get_by_id(owner_id) if owner_id else None
|
owner = self.tableau_server.users.get_by_id(owner_id) if owner_id else None
|
||||||
@ -122,7 +129,7 @@ class TableauClient:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def get_workbook_charts_and_user_count(
|
def get_workbook_charts_and_user_count(
|
||||||
self, views: List[ViewItem]
|
self, views: List[ViewItem], include_owners: bool = True
|
||||||
) -> Optional[Tuple[Optional[int], Optional[List[TableauChart]]]]:
|
) -> Optional[Tuple[Optional[int], Optional[List[TableauChart]]]]:
|
||||||
"""
|
"""
|
||||||
Fetches workbook charts and dashboard user view count
|
Fetches workbook charts and dashboard user view count
|
||||||
@ -136,7 +143,7 @@ class TableauClient:
|
|||||||
id=str(view.id),
|
id=str(view.id),
|
||||||
name=view.name,
|
name=view.name,
|
||||||
tags=view.tags,
|
tags=view.tags,
|
||||||
owner=self.get_tableau_owner(view.owner_id),
|
owner=self.get_tableau_owner(view.owner_id, include_owners),
|
||||||
contentUrl=view.content_url,
|
contentUrl=view.content_url,
|
||||||
sheetType=view.sheet_type,
|
sheetType=view.sheet_type,
|
||||||
)
|
)
|
||||||
@ -202,7 +209,7 @@ class TableauClient:
|
|||||||
logger.debug(f"Failed to get project parents by id: {str(e)}")
|
logger.debug(f"Failed to get project parents by id: {str(e)}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_workbooks(self) -> Iterable[TableauDashboard]:
|
def get_workbooks(self, include_owners: bool = True) -> Iterable[TableauDashboard]:
|
||||||
"""
|
"""
|
||||||
Fetch all tableau workbooks
|
Fetch all tableau workbooks
|
||||||
"""
|
"""
|
||||||
@ -212,7 +219,7 @@ class TableauClient:
|
|||||||
try:
|
try:
|
||||||
self.tableau_server.workbooks.populate_views(workbook, usage=True)
|
self.tableau_server.workbooks.populate_views(workbook, usage=True)
|
||||||
charts, user_views = self.get_workbook_charts_and_user_count(
|
charts, user_views = self.get_workbook_charts_and_user_count(
|
||||||
workbook.views
|
workbook.views, include_owners
|
||||||
)
|
)
|
||||||
workbook = TableauDashboard(
|
workbook = TableauDashboard(
|
||||||
id=str(workbook.id),
|
id=str(workbook.id),
|
||||||
@ -220,7 +227,7 @@ class TableauClient:
|
|||||||
project=TableauBaseModel(
|
project=TableauBaseModel(
|
||||||
id=str(workbook.project_id), name=workbook.project_name
|
id=str(workbook.project_id), name=workbook.project_name
|
||||||
),
|
),
|
||||||
owner=self.get_tableau_owner(workbook.owner_id),
|
owner=self.get_tableau_owner(workbook.owner_id, include_owners),
|
||||||
description=workbook.description,
|
description=workbook.description,
|
||||||
tags=workbook.tags,
|
tags=workbook.tags,
|
||||||
webpageUrl=workbook.webpage_url,
|
webpageUrl=workbook.webpage_url,
|
||||||
@ -248,9 +255,11 @@ class TableauClient:
|
|||||||
"Please check if the user has permissions to access the Dashboards information"
|
"Please check if the user has permissions to access the Dashboards information"
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_get_workbook_views(self):
|
def test_get_workbook_views(self, include_owners: bool = True):
|
||||||
workbook = self.test_get_workbooks()
|
workbook = self.test_get_workbooks()
|
||||||
charts, _ = self.get_workbook_charts_and_user_count(workbook.views)
|
charts, _ = self.get_workbook_charts_and_user_count(
|
||||||
|
workbook.views, include_owners
|
||||||
|
)
|
||||||
if charts:
|
if charts:
|
||||||
return True
|
return True
|
||||||
raise TableauChartsException(
|
raise TableauChartsException(
|
||||||
@ -258,9 +267,11 @@ class TableauClient:
|
|||||||
"Please check if the user has permissions to access the Charts information"
|
"Please check if the user has permissions to access the Charts information"
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_get_owners(self) -> Optional[List[TableauOwner]]:
|
def test_get_owners(
|
||||||
|
self, include_owners: bool = True
|
||||||
|
) -> Optional[List[TableauOwner]]:
|
||||||
workbook = self.test_get_workbooks()
|
workbook = self.test_get_workbooks()
|
||||||
owners = self.get_tableau_owner(workbook.owner_id)
|
owners = self.get_tableau_owner(workbook.owner_id, include_owners)
|
||||||
if owners is not None:
|
if owners is not None:
|
||||||
return owners
|
return owners
|
||||||
raise TableauOwnersNotFound(
|
raise TableauOwnersNotFound(
|
||||||
|
@ -132,7 +132,11 @@ class TableauSource(DashboardServiceSource):
|
|||||||
return cls(config, metadata)
|
return cls(config, metadata)
|
||||||
|
|
||||||
def get_dashboards_list(self) -> Iterable[TableauDashboard]:
|
def get_dashboards_list(self) -> Iterable[TableauDashboard]:
|
||||||
yield from self.client.get_workbooks()
|
if not self.source_config.includeOwners:
|
||||||
|
logger.debug("Skipping owner information as includeOwners is False")
|
||||||
|
yield from self.client.get_workbooks(
|
||||||
|
include_owners=self.source_config.includeOwners
|
||||||
|
)
|
||||||
|
|
||||||
def get_dashboard_name(self, dashboard: TableauDashboard) -> str:
|
def get_dashboard_name(self, dashboard: TableauDashboard) -> str:
|
||||||
return dashboard.name
|
return dashboard.name
|
||||||
@ -151,6 +155,8 @@ class TableauSource(DashboardServiceSource):
|
|||||||
Get dashboard owner from email
|
Get dashboard owner from email
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
if not self.source_config.includeOwners:
|
||||||
|
return None
|
||||||
if dashboard_details.owner and dashboard_details.owner.email:
|
if dashboard_details.owner and dashboard_details.owner.email:
|
||||||
return self.metadata.get_reference_by_email(
|
return self.metadata.get_reference_by_email(
|
||||||
dashboard_details.owner.email
|
dashboard_details.owner.email
|
||||||
|
@ -44,6 +44,7 @@ from metadata.generated.schema.type.basic import FullyQualifiedEntityName
|
|||||||
from metadata.generated.schema.type.entityLineage import EntitiesEdge, LineageDetails
|
from metadata.generated.schema.type.entityLineage import EntitiesEdge, LineageDetails
|
||||||
from metadata.generated.schema.type.entityLineage import Source as LineageSource
|
from metadata.generated.schema.type.entityLineage import Source as LineageSource
|
||||||
from metadata.generated.schema.type.entityReference import EntityReference
|
from metadata.generated.schema.type.entityReference import EntityReference
|
||||||
|
from metadata.generated.schema.type.entityReferenceList import EntityReferenceList
|
||||||
from metadata.generated.schema.type.usageDetails import UsageDetails, UsageStats
|
from metadata.generated.schema.type.usageDetails import UsageDetails, UsageStats
|
||||||
from metadata.generated.schema.type.usageRequest import UsageRequest
|
from metadata.generated.schema.type.usageRequest import UsageRequest
|
||||||
from metadata.ingestion.api.steps import InvalidSourceException
|
from metadata.ingestion.api.steps import InvalidSourceException
|
||||||
@ -68,6 +69,7 @@ MOCK_LOOKER_CONFIG = {
|
|||||||
"sourceConfig": {
|
"sourceConfig": {
|
||||||
"config": {
|
"config": {
|
||||||
"type": "DashboardMetadata",
|
"type": "DashboardMetadata",
|
||||||
|
"includeOwners": True,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -594,3 +596,88 @@ class LookerUnitTest(TestCase):
|
|||||||
|
|
||||||
self.assertEqual(self.looker._parsed_views, EXPECTED_PARSED_VIEWS)
|
self.assertEqual(self.looker._parsed_views, EXPECTED_PARSED_VIEWS)
|
||||||
self.assertEqual(self.looker._unparsed_views, {})
|
self.assertEqual(self.looker._unparsed_views, {})
|
||||||
|
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.looker.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Mock a user with email
|
||||||
|
mock_user = User(email="test@example.com")
|
||||||
|
|
||||||
|
# Mock the client.user method to return our mock user
|
||||||
|
with patch.object(self.looker.client, "user", return_value=mock_user):
|
||||||
|
# Mock the metadata.get_reference_by_email method
|
||||||
|
with patch.object(
|
||||||
|
self.looker.metadata, "get_reference_by_email"
|
||||||
|
) as mock_get_ref:
|
||||||
|
mock_get_ref.return_value = EntityReferenceList(
|
||||||
|
root=[
|
||||||
|
EntityReference(id=uuid.uuid4(), name="Test User", type="user")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test get_owner_ref with includeOwners = True
|
||||||
|
result = self.looker.get_owner_ref(MOCK_LOOKER_DASHBOARD)
|
||||||
|
|
||||||
|
# Should return owner reference
|
||||||
|
self.assertIsNotNone(result)
|
||||||
|
self.assertEqual(len(result.root), 1)
|
||||||
|
self.assertEqual(result.root[0].name, "Test User")
|
||||||
|
|
||||||
|
# Should have called get_reference_by_email
|
||||||
|
mock_get_ref.assert_called_once_with("test@example.com")
|
||||||
|
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.looker.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test get_owner_ref with includeOwners = False
|
||||||
|
result = self.looker.get_owner_ref(MOCK_LOOKER_DASHBOARD)
|
||||||
|
|
||||||
|
# Should return None when includeOwners is False
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_include_owners_flag_with_no_user_id(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True but dashboard has no user_id, returns None
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.looker.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Create a dashboard with no user_id
|
||||||
|
dashboard_no_user = LookerDashboard(
|
||||||
|
id="no_user_dashboard",
|
||||||
|
title="No User Dashboard",
|
||||||
|
dashboard_elements=[],
|
||||||
|
description="Dashboard without user",
|
||||||
|
user_id=None, # No user_id
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test get_owner_ref with no user_id
|
||||||
|
result = self.looker.get_owner_ref(dashboard_no_user)
|
||||||
|
|
||||||
|
# Should return None when there's no user_id
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_include_owners_flag_with_exception(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True but an exception occurs, it's handled gracefully
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.looker.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Mock the client.user method to raise an exception
|
||||||
|
with patch.object(
|
||||||
|
self.looker.client, "user", side_effect=Exception("API Error")
|
||||||
|
):
|
||||||
|
# Test get_owner_ref with exception
|
||||||
|
result = self.looker.get_owner_ref(MOCK_LOOKER_DASHBOARD)
|
||||||
|
|
||||||
|
# Should return None when exception occurs
|
||||||
|
self.assertIsNone(result)
|
||||||
|
@ -103,7 +103,11 @@ mock_config = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sourceConfig": {
|
"sourceConfig": {
|
||||||
"config": {"dashboardFilterPattern": {}, "chartFilterPattern": {}}
|
"config": {
|
||||||
|
"dashboardFilterPattern": {},
|
||||||
|
"chartFilterPattern": {},
|
||||||
|
"includeOwners": True,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sink": {"type": "metadata-rest", "config": {}},
|
"sink": {"type": "metadata-rest", "config": {}},
|
||||||
@ -320,6 +324,47 @@ class MetabaseUnitTest(TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(list(result), [])
|
self.assertEqual(list(result), [])
|
||||||
|
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.metabase.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test that owner information is processed when includeOwners is True
|
||||||
|
self.assertTrue(self.metabase.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.metabase.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test that owner information is not processed when includeOwners is False
|
||||||
|
self.assertFalse(self.metabase.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_in_config(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag is properly set in the configuration
|
||||||
|
"""
|
||||||
|
# Check that the mock configuration includes the includeOwners flag
|
||||||
|
config = mock_config["source"]["sourceConfig"]["config"]
|
||||||
|
self.assertIn("includeOwners", config)
|
||||||
|
self.assertTrue(config["includeOwners"])
|
||||||
|
|
||||||
|
def test_include_owners_flag_affects_owner_processing(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag affects how owner information is processed
|
||||||
|
"""
|
||||||
|
# Test with includeOwners = True
|
||||||
|
self.metabase.source_config.includeOwners = True
|
||||||
|
self.assertTrue(self.metabase.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with includeOwners = False
|
||||||
|
self.metabase.source_config.includeOwners = False
|
||||||
|
self.assertFalse(self.metabase.source_config.includeOwners)
|
||||||
|
|
||||||
def test_dataset_query_string_parsing(self):
|
def test_dataset_query_string_parsing(self):
|
||||||
"""
|
"""
|
||||||
Test that dataset_query field can handle both string and dict inputs
|
Test that dataset_query field can handle both string and dict inputs
|
||||||
|
@ -42,7 +42,9 @@ mock_micro_config = {
|
|||||||
"password": "password",
|
"password": "password",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sourceConfig": {"config": {"type": "DashboardMetadata"}},
|
"sourceConfig": {
|
||||||
|
"config": {"type": "DashboardMetadata", "includeOwners": True}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"sink": {"type": "metadata-rest", "config": {}},
|
"sink": {"type": "metadata-rest", "config": {}},
|
||||||
"workflowConfig": {
|
"workflowConfig": {
|
||||||
@ -125,3 +127,57 @@ class MicroStrategyUnitTest(TestCase):
|
|||||||
self.microstrategy.client.get_dashboards_list = lambda *_: MOCK_DASHBORD_LIST
|
self.microstrategy.client.get_dashboards_list = lambda *_: MOCK_DASHBORD_LIST
|
||||||
fetched_dashboards_list = self.microstrategy.get_dashboards_list()
|
fetched_dashboards_list = self.microstrategy.get_dashboards_list()
|
||||||
self.assertEqual(list(fetched_dashboards_list), MOCK_DASHBORD_LIST)
|
self.assertEqual(list(fetched_dashboards_list), MOCK_DASHBORD_LIST)
|
||||||
|
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.microstrategy.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test that owner information is processed when includeOwners is True
|
||||||
|
self.assertTrue(self.microstrategy.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.microstrategy.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test that owner information is not processed when includeOwners is False
|
||||||
|
self.assertFalse(self.microstrategy.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_in_config(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag is properly set in the configuration
|
||||||
|
"""
|
||||||
|
# Check that the mock configuration includes the includeOwners flag
|
||||||
|
config = mock_micro_config["source"]["sourceConfig"]["config"]
|
||||||
|
self.assertIn("includeOwners", config)
|
||||||
|
self.assertTrue(config["includeOwners"])
|
||||||
|
|
||||||
|
def test_include_owners_flag_affects_owner_processing(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag affects how owner information is processed
|
||||||
|
"""
|
||||||
|
# Test with includeOwners = True
|
||||||
|
self.microstrategy.source_config.includeOwners = True
|
||||||
|
self.assertTrue(self.microstrategy.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with includeOwners = False
|
||||||
|
self.microstrategy.source_config.includeOwners = False
|
||||||
|
self.assertFalse(self.microstrategy.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_with_owner_data(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner data from dashboard is accessible
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.microstrategy.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test that we can access owner information from the mock dashboard
|
||||||
|
dashboard = MOCK_DASHBORD_LIST[0]
|
||||||
|
self.assertIsNotNone(dashboard.owner)
|
||||||
|
self.assertEqual(dashboard.owner.name, "Administrator")
|
||||||
|
self.assertEqual(dashboard.owner.id, "54F3D26011D2896560009A8E67019608")
|
||||||
|
@ -423,3 +423,139 @@ class PowerBIUnitTest(TestCase):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
assert lineage_request[0].right is not None
|
assert lineage_request[0].right is not None
|
||||||
|
|
||||||
|
@pytest.mark.order(6)
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.powerbi.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test that owner information is processed when includeOwners is True
|
||||||
|
self.assertTrue(self.powerbi.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with a dashboard that has owners
|
||||||
|
dashboard_with_owners = PowerBIDashboard.model_validate(
|
||||||
|
MOCK_DASHBOARD_WITH_OWNERS
|
||||||
|
)
|
||||||
|
|
||||||
|
# Mock the metadata.get_reference_by_email method to return different users for different emails
|
||||||
|
with patch.object(
|
||||||
|
self.powerbi.metadata, "get_reference_by_email"
|
||||||
|
) as mock_get_ref:
|
||||||
|
|
||||||
|
def mock_get_ref_by_email(email):
|
||||||
|
if email == "john.doe@example.com":
|
||||||
|
return EntityReferenceList(
|
||||||
|
root=[
|
||||||
|
EntityReference(
|
||||||
|
id=uuid.uuid4(), name="John Doe", type="user"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
elif email == "jane.smith@example.com":
|
||||||
|
return EntityReferenceList(
|
||||||
|
root=[
|
||||||
|
EntityReference(
|
||||||
|
id=uuid.uuid4(), name="Jane Smith", type="user"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return EntityReferenceList(root=[])
|
||||||
|
|
||||||
|
mock_get_ref.side_effect = mock_get_ref_by_email
|
||||||
|
|
||||||
|
# Test get_owner_ref with includeOwners = True
|
||||||
|
result = self.powerbi.get_owner_ref(dashboard_with_owners)
|
||||||
|
|
||||||
|
# Should return owner reference when includeOwners is True
|
||||||
|
self.assertIsNotNone(result)
|
||||||
|
self.assertEqual(len(result.root), 2)
|
||||||
|
# Check that both owners are present
|
||||||
|
owner_names = [owner.name for owner in result.root]
|
||||||
|
self.assertIn("John Doe", owner_names)
|
||||||
|
self.assertIn("Jane Smith", owner_names)
|
||||||
|
|
||||||
|
@pytest.mark.order(7)
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.powerbi.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test that owner information is not processed when includeOwners is False
|
||||||
|
self.assertFalse(self.powerbi.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with a dashboard that has owners
|
||||||
|
dashboard_with_owners = PowerBIDashboard.model_validate(
|
||||||
|
MOCK_DASHBOARD_WITH_OWNERS
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test get_owner_ref with includeOwners = False
|
||||||
|
result = self.powerbi.get_owner_ref(dashboard_with_owners)
|
||||||
|
|
||||||
|
# Should return None when includeOwners is False
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
@pytest.mark.order(8)
|
||||||
|
def test_include_owners_flag_in_config(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag is properly set in the configuration
|
||||||
|
"""
|
||||||
|
# Check that the mock configuration includes the includeOwners flag
|
||||||
|
config = mock_config["source"]["sourceConfig"]["config"]
|
||||||
|
self.assertIn("includeOwners", config)
|
||||||
|
self.assertTrue(config["includeOwners"])
|
||||||
|
|
||||||
|
@pytest.mark.order(9)
|
||||||
|
def test_include_owners_flag_with_no_owners(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True but dashboard has no owners, returns None
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.powerbi.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Create a dashboard with no owners
|
||||||
|
dashboard_no_owners = PowerBIDashboard.model_validate(
|
||||||
|
{
|
||||||
|
"id": "dashboard_no_owners",
|
||||||
|
"displayName": "Test Dashboard No Owners",
|
||||||
|
"webUrl": "https://test.com",
|
||||||
|
"embedUrl": "https://test.com/embed",
|
||||||
|
"tiles": [],
|
||||||
|
"users": [], # No users/owners
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test get_owner_ref with no owners
|
||||||
|
result = self.powerbi.get_owner_ref(dashboard_no_owners)
|
||||||
|
|
||||||
|
# Should return None when there are no owners
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
@pytest.mark.order(10)
|
||||||
|
def test_include_owners_flag_with_exception(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True but an exception occurs, it's handled gracefully
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.powerbi.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test with a dashboard that has owners
|
||||||
|
dashboard_with_owners = PowerBIDashboard.model_validate(
|
||||||
|
MOCK_DASHBOARD_WITH_OWNERS
|
||||||
|
)
|
||||||
|
|
||||||
|
# Mock the metadata.get_reference_by_email method to raise an exception
|
||||||
|
with patch.object(
|
||||||
|
self.powerbi.metadata,
|
||||||
|
"get_reference_by_email",
|
||||||
|
side_effect=Exception("API Error"),
|
||||||
|
):
|
||||||
|
# Test get_owner_ref with exception
|
||||||
|
result = self.powerbi.get_owner_ref(dashboard_with_owners)
|
||||||
|
|
||||||
|
# Should return None when exception occurs
|
||||||
|
self.assertIsNone(result)
|
||||||
|
@ -61,6 +61,7 @@ mock_qlikcloud_config = {
|
|||||||
"sourceConfig": {
|
"sourceConfig": {
|
||||||
"config": {
|
"config": {
|
||||||
"includeDraftDashboard": False,
|
"includeDraftDashboard": False,
|
||||||
|
"includeOwners": True,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -73,6 +73,7 @@ mock_qliksense_config = {
|
|||||||
"dashboardFilterPattern": {},
|
"dashboardFilterPattern": {},
|
||||||
"chartFilterPattern": {},
|
"chartFilterPattern": {},
|
||||||
"includeDraftDashboard": False,
|
"includeDraftDashboard": False,
|
||||||
|
"includeOwners": True,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -225,3 +226,48 @@ class QlikSenseUnitTest(TestCase):
|
|||||||
if self.qliksense.filter_draft_dashboard(dashboard):
|
if self.qliksense.filter_draft_dashboard(dashboard):
|
||||||
draft_dashboards_count += 1
|
draft_dashboards_count += 1
|
||||||
assert draft_dashboards_count == DRAFT_DASHBOARDS_IN_MOCK_DASHBOARDS
|
assert draft_dashboards_count == DRAFT_DASHBOARDS_IN_MOCK_DASHBOARDS
|
||||||
|
|
||||||
|
@pytest.mark.order(5)
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.qliksense.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test that owner information is processed when includeOwners is True
|
||||||
|
self.assertTrue(self.qliksense.source_config.includeOwners)
|
||||||
|
|
||||||
|
@pytest.mark.order(6)
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.qliksense.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test that owner information is not processed when includeOwners is False
|
||||||
|
self.assertFalse(self.qliksense.source_config.includeOwners)
|
||||||
|
|
||||||
|
@pytest.mark.order(7)
|
||||||
|
def test_include_owners_flag_in_config(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag is properly set in the configuration
|
||||||
|
"""
|
||||||
|
# Check that the mock configuration includes the includeOwners flag
|
||||||
|
config = mock_qliksense_config["source"]["sourceConfig"]["config"]
|
||||||
|
self.assertIn("includeOwners", config)
|
||||||
|
self.assertTrue(config["includeOwners"])
|
||||||
|
|
||||||
|
@pytest.mark.order(8)
|
||||||
|
def test_include_owners_flag_affects_owner_processing(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag affects how owner information is processed
|
||||||
|
"""
|
||||||
|
# Test with includeOwners = True
|
||||||
|
self.qliksense.source_config.includeOwners = True
|
||||||
|
self.assertTrue(self.qliksense.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with includeOwners = False
|
||||||
|
self.qliksense.source_config.includeOwners = False
|
||||||
|
self.assertFalse(self.qliksense.source_config.includeOwners)
|
||||||
|
@ -78,7 +78,11 @@ mock_quicksight_config = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sourceConfig": {
|
"sourceConfig": {
|
||||||
"config": {"dashboardFilterPattern": {}, "chartFilterPattern": {}}
|
"config": {
|
||||||
|
"dashboardFilterPattern": {},
|
||||||
|
"chartFilterPattern": {},
|
||||||
|
"includeOwners": True,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sink": {"type": "metadata-rest", "config": {}},
|
"sink": {"type": "metadata-rest", "config": {}},
|
||||||
@ -200,3 +204,48 @@ class QuickSightUnitTest(TestCase):
|
|||||||
chart_list.append(result)
|
chart_list.append(result)
|
||||||
for _, (expected, original) in enumerate(zip(EXPECTED_DASHBOARDS, chart_list)):
|
for _, (expected, original) in enumerate(zip(EXPECTED_DASHBOARDS, chart_list)):
|
||||||
self.assertEqual(expected, original)
|
self.assertEqual(expected, original)
|
||||||
|
|
||||||
|
@pytest.mark.order(4)
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.quicksight.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test that owner information is processed when includeOwners is True
|
||||||
|
self.assertTrue(self.quicksight.source_config.includeOwners)
|
||||||
|
|
||||||
|
@pytest.mark.order(5)
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.quicksight.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test that owner information is not processed when includeOwners is False
|
||||||
|
self.assertFalse(self.quicksight.source_config.includeOwners)
|
||||||
|
|
||||||
|
@pytest.mark.order(6)
|
||||||
|
def test_include_owners_flag_in_config(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag is properly set in the configuration
|
||||||
|
"""
|
||||||
|
# Check that the mock configuration includes the includeOwners flag
|
||||||
|
config = mock_quicksight_config["source"]["sourceConfig"]["config"]
|
||||||
|
self.assertIn("includeOwners", config)
|
||||||
|
self.assertTrue(config["includeOwners"])
|
||||||
|
|
||||||
|
@pytest.mark.order(7)
|
||||||
|
def test_include_owners_flag_affects_owner_processing(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag affects how owner information is processed
|
||||||
|
"""
|
||||||
|
# Test with includeOwners = True
|
||||||
|
self.quicksight.source_config.includeOwners = True
|
||||||
|
self.assertTrue(self.quicksight.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with includeOwners = False
|
||||||
|
self.quicksight.source_config.includeOwners = False
|
||||||
|
self.assertFalse(self.quicksight.source_config.includeOwners)
|
||||||
|
@ -92,7 +92,11 @@ mock_config = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sourceConfig": {
|
"sourceConfig": {
|
||||||
"config": {"dashboardFilterPattern": {}, "chartFilterPattern": {}}
|
"config": {
|
||||||
|
"dashboardFilterPattern": {},
|
||||||
|
"chartFilterPattern": {},
|
||||||
|
"includeOwners": True,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sink": {"type": "metadata-rest", "config": {}},
|
"sink": {"type": "metadata-rest", "config": {}},
|
||||||
@ -227,3 +231,44 @@ class SigmaUnitTest(TestCase):
|
|||||||
|
|
||||||
for expected, original in zip(EXPECTED_CHARTS, chart_list):
|
for expected, original in zip(EXPECTED_CHARTS, chart_list):
|
||||||
self.assertEqual(expected, original)
|
self.assertEqual(expected, original)
|
||||||
|
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.sigma.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Test that owner information is processed when includeOwners is True
|
||||||
|
self.assertTrue(self.sigma.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.sigma.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test that owner information is not processed when includeOwners is False
|
||||||
|
self.assertFalse(self.sigma.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_in_config(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag is properly set in the configuration
|
||||||
|
"""
|
||||||
|
# Check that the mock configuration includes the includeOwners flag
|
||||||
|
config = mock_config["source"]["sourceConfig"]["config"]
|
||||||
|
self.assertIn("includeOwners", config)
|
||||||
|
self.assertTrue(config["includeOwners"])
|
||||||
|
|
||||||
|
def test_include_owners_flag_affects_owner_processing(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag affects how owner information is processed
|
||||||
|
"""
|
||||||
|
# Test with includeOwners = True
|
||||||
|
self.sigma.source_config.includeOwners = True
|
||||||
|
self.assertTrue(self.sigma.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with includeOwners = False
|
||||||
|
self.sigma.source_config.includeOwners = False
|
||||||
|
self.assertFalse(self.sigma.source_config.includeOwners)
|
||||||
|
@ -21,6 +21,7 @@ from metadata.generated.schema.metadataIngestion.workflow import (
|
|||||||
)
|
)
|
||||||
from metadata.generated.schema.type.basic import FullyQualifiedEntityName
|
from metadata.generated.schema.type.basic import FullyQualifiedEntityName
|
||||||
from metadata.generated.schema.type.entityReference import EntityReference
|
from metadata.generated.schema.type.entityReference import EntityReference
|
||||||
|
from metadata.generated.schema.type.entityReferenceList import EntityReferenceList
|
||||||
from metadata.generated.schema.type.filterPattern import FilterPattern
|
from metadata.generated.schema.type.filterPattern import FilterPattern
|
||||||
from metadata.generated.schema.type.usageDetails import UsageDetails, UsageStats
|
from metadata.generated.schema.type.usageDetails import UsageDetails, UsageStats
|
||||||
from metadata.generated.schema.type.usageRequest import UsageRequest
|
from metadata.generated.schema.type.usageRequest import UsageRequest
|
||||||
@ -59,7 +60,11 @@ mock_tableau_config = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sourceConfig": {
|
"sourceConfig": {
|
||||||
"config": {"dashboardFilterPattern": {}, "chartFilterPattern": {}}
|
"config": {
|
||||||
|
"dashboardFilterPattern": {},
|
||||||
|
"chartFilterPattern": {},
|
||||||
|
"includeOwners": True,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sink": {"type": "metadata-rest", "config": {}},
|
"sink": {"type": "metadata-rest", "config": {}},
|
||||||
@ -772,3 +777,61 @@ class TableauUnitTest(TestCase):
|
|||||||
|
|
||||||
# Verify that the method didn't throw any exceptions
|
# Verify that the method didn't throw any exceptions
|
||||||
# The test passes if we reach this point without exceptions
|
# The test passes if we reach this point without exceptions
|
||||||
|
|
||||||
|
def test_include_owners_flag_enabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is True, owner information is processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = True
|
||||||
|
self.tableau.source_config.includeOwners = True
|
||||||
|
|
||||||
|
# Create a mock dashboard with owner information
|
||||||
|
mock_dashboard_with_owner = MOCK_DASHBOARD
|
||||||
|
|
||||||
|
# Mock the metadata.get_reference_by_email method
|
||||||
|
with patch.object(
|
||||||
|
self.tableau.metadata, "get_reference_by_email"
|
||||||
|
) as mock_get_ref:
|
||||||
|
mock_get_ref.return_value = EntityReferenceList(
|
||||||
|
root=[
|
||||||
|
EntityReference(
|
||||||
|
id=uuid.uuid4(), name="Dashboard Owner", type="user"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test that owner information is included when includeOwners is True
|
||||||
|
# This would typically be tested in the yield_dashboard method
|
||||||
|
# For now, we'll test the configuration is properly set
|
||||||
|
self.assertTrue(self.tableau.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_disabled(self):
|
||||||
|
"""
|
||||||
|
Test that when includeOwners is False, owner information is not processed
|
||||||
|
"""
|
||||||
|
# Mock the source config to have includeOwners = False
|
||||||
|
self.tableau.source_config.includeOwners = False
|
||||||
|
|
||||||
|
# Test that owner information is not processed when includeOwners is False
|
||||||
|
self.assertFalse(self.tableau.source_config.includeOwners)
|
||||||
|
|
||||||
|
def test_include_owners_flag_in_config(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag is properly set in the configuration
|
||||||
|
"""
|
||||||
|
# Check that the mock configuration includes the includeOwners flag
|
||||||
|
config = mock_tableau_config["source"]["sourceConfig"]["config"]
|
||||||
|
self.assertIn("includeOwners", config)
|
||||||
|
self.assertTrue(config["includeOwners"])
|
||||||
|
|
||||||
|
def test_include_owners_flag_affects_owner_processing(self):
|
||||||
|
"""
|
||||||
|
Test that the includeOwners flag affects how owner information is processed
|
||||||
|
"""
|
||||||
|
# Test with includeOwners = True
|
||||||
|
self.tableau.source_config.includeOwners = True
|
||||||
|
self.assertTrue(self.tableau.source_config.includeOwners)
|
||||||
|
|
||||||
|
# Test with includeOwners = False
|
||||||
|
self.tableau.source_config.includeOwners = False
|
||||||
|
self.assertFalse(self.tableau.source_config.includeOwners)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user