from unittest import mock import pytest from audience_common.auth.account import Account from campaigns.auth.dtos import User, UserId from campaigns.config import settings from campaigns.connectors.facebook import models as fb_models from campaigns.meta.exceptions import FacebookPageDoesNotExist, FacebookPageInvalidToken from campaigns.meta.models import FacebookPage, FacebookPageLabel from campaigns.meta.services import FacebookPageService from tests.unit.faker import FakerTyped from tests.unit.types import CreateModel async def test_get_user_valid_page_for_label_not_exist( facebook_page_service: FacebookPageService, fake: FakerTyped, user: User ) -> None: page_id = fake.uuid4_string() account = Account(vendor_id=fake.integer(), subaccount_id=0) with pytest.raises(FacebookPageDoesNotExist): await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page_id, account=account, ) async def test_get_user_valid_page_for_label_owned_by_identity( facebook_page_service: FacebookPageService, create_model: CreateModel, user: User ) -> None: page_label = await create_model( FacebookPageLabel, page__association__orchard_identity_id=user.id.identity_id, ) page = page_label.page result = await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page.id, account=page_label.account, ) assert result.id == page.id async def test_get_user_valid_page_for_label_owned_has_direct_access_to_vendor( facebook_page_service: FacebookPageService, facebook_client_mock: mock.MagicMock, create_model: CreateModel, user_id: UserId, ) -> None: page_label = await create_model(FacebookPageLabel, page__is_valid=True) page = page_label.page account_access = mock.MagicMock() account_access.has_direct_access_to_vendor.return_value = True user = User(id=user_id, account_access=account_access) facebook_client_mock.debug_tokens.return_value = { page.token: fb_models.DebugToken(is_valid=True, scopes=[]) } result = await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page.id, account=page_label.account, ) assert result.id == page.id assert result.is_valid is True async def test_get_user_valid_page_for_label_owned_has_direct_access_to_subaccount( facebook_page_service: FacebookPageService, create_model: CreateModel, user_id: UserId, ) -> None: page_label = await create_model(FacebookPageLabel, page__is_valid=True) page = page_label.page account_access = mock.MagicMock() account_access.has_direct_access_to_vendor.return_value = False account_access.has_direct_access_to_subaccount.return_value = True user = User(id=user_id, account_access=account_access) result = await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page.id, account=page_label.account, ) assert result.id == page.id async def test_get_user_valid_page_for_label_owned_no_account_access( facebook_page_service: FacebookPageService, create_model: CreateModel, user_id: UserId, ) -> None: page_label = await create_model(FacebookPageLabel) page = page_label.page account_access = mock.MagicMock() account_access.has_access_to_vendor.return_value = False account_access.has_access_to_subaccount.return_value = False user = User(id=user_id, account_access=account_access) with pytest.raises(FacebookPageDoesNotExist): await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page.id, account=page_label.account, ) async def test_get_user_valid_page_for_label_has_direct_access_to_vendor_not_found( facebook_page_service: FacebookPageService, create_model: CreateModel, fake: FakerTyped, user_id: UserId, ) -> None: page_label = await create_model(FacebookPageLabel) account_access = mock.MagicMock() account_access.has_direct_access_to_vendor.return_value = True user = User(id=user_id, account_access=account_access) with pytest.raises(FacebookPageDoesNotExist): await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page_label.page_id, account=Account(vendor_id=fake.integer(), subaccount_id=0), ) async def test_get_user_valid_page_for_label_has_direct_access_to_subaccount_not_found( facebook_page_service: FacebookPageService, create_model: CreateModel, user_id: UserId, ) -> None: page_label = await create_model(FacebookPageLabel) page = page_label.page account_access = mock.MagicMock() account_access.has_access_to_vendor.return_value = False account_access.has_access_to_subaccount.return_value = True user = User(id=user_id, account_access=account_access) with pytest.raises(FacebookPageDoesNotExist): await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page.id, account=Account( vendor_id=page_label.vendor_id, subaccount_id=0, ), ) async def test_get_user_valid_page_for_label_invalid_token( facebook_page_service: FacebookPageService, facebook_client_mock: mock.MagicMock, create_model: CreateModel, fake: FakerTyped, user_id: UserId, ) -> None: page_label = await create_model(FacebookPageLabel, page__is_valid=False) page = page_label.page account_access = mock.MagicMock() account_access.has_direct_access_to_vendor.return_value = True user = User(id=user_id, account_access=account_access) facebook_client_mock.debug_tokens.return_value = { page.token: fb_models.DebugToken(is_valid=False, scopes=[]) } with pytest.raises(FacebookPageInvalidToken): await facebook_page_service.get_user_valid_page_for_account( user=user, page_id=page.id, account=page_label.account, ) async def test_save_page_picture( facebook_page_service: FacebookPageService, s3_client_mock: mock.MagicMock, create_model: CreateModel, fake: FakerTyped, ) -> None: page = await create_model(FacebookPage, picture_bucket=None, picture_key=None) picture_content = fake.bytes() result = await facebook_page_service.save_page_picture( page, content=picture_content ) s3_client_mock.put_object.assert_called_once_with( bucket=settings.assets_bucket_name, key=f"{page.UPLOAD_FOLDER}/{page.id}/picture.png", content=picture_content, content_type="image/png", ) assert result assert result.id == page.id assert result.picture_bucket == settings.assets_bucket_name assert result.picture_key == f"{page.UPLOAD_FOLDER}/{page.id}/picture.png"