import pytest from starlette.testclient import TestClient from campaigns.connectors.facebook.base import FacebookClient from campaigns.connectors.facebook.constants import TARGETING_LOCATION_TYPES from campaigns.connectors.facebook.models import TargetingGeolocation, TargetingInterest from campaigns.meta import constants from campaigns.meta.dtos import FacebookConnection, FacebookUser, InstagramAccount from campaigns.meta.enums import FacebookConnectionStatus from campaigns.meta.handlers import ( ConnectFacebookUserHandler, DisconnectFacebookUserHandler, GetFacebookConnectionStatusHandler, GetFacebookUserPageForLabelHandler, GetFacebookUserPagesForLabelHandler, GetFacebookUserPagesHandler, GetInstagramAccountForFacebookPageHandler, ) from campaigns.meta.models import FacebookPage, FacebookPageLabel from tests.unit.faker import FakerTyped from tests.unit.types import BuildModel, MockDependency pytestmark = pytest.mark.usefixtures("mock_auth") def test_get_facebook_connection_status( test_client: TestClient, build_model: BuildModel, mock_dependency: MockDependency ) -> None: user = build_model(FacebookUser) handler_mock = mock_dependency(GetFacebookConnectionStatusHandler) handler_mock.handle.return_value = FacebookConnection( user=user, status=FacebookConnectionStatus.CONNECTED, ) response = test_client.get("/facebook/connection") assert response.status_code == 200 assert response.json() == { "user": { "name": user.name, "picture": user.picture, "grantedScopes": user.granted_scopes, }, "status": "CONNECTED", "scopes": constants.REQUEST_SCOPES, "requiredScopes": constants.REQUIRED_SCOPES, } def test_connect_facebook_user( test_client: TestClient, build_model: BuildModel, fake: FakerTyped, mock_dependency: MockDependency, ) -> None: user_id = fake.uuid4_string() access_token = fake.pystr() user = build_model(FacebookUser) handler_mock = mock_dependency(ConnectFacebookUserHandler) handler_mock.handle.return_value = FacebookConnection( user=user, status=FacebookConnectionStatus.CONNECTED, ) response = test_client.post( "/facebook/connection", json={ "userId": user_id, "accessToken": access_token, }, ) assert response.status_code == 200 assert response.json() == { "user": { "name": user.name, "picture": user.picture, "grantedScopes": user.granted_scopes, }, "status": "CONNECTED", "scopes": constants.REQUEST_SCOPES, "requiredScopes": constants.REQUIRED_SCOPES, } def test_disconnect_facebook_user( test_client: TestClient, mock_dependency: MockDependency ) -> None: handler_mock = mock_dependency(DisconnectFacebookUserHandler) handler_mock.handle.return_value = FacebookConnection.not_connected() response = test_client.delete("/facebook/connection") assert response.status_code == 200 assert response.json() == { "user": None, "status": "NOT_CONNECTED", "scopes": constants.REQUEST_SCOPES, "requiredScopes": constants.REQUIRED_SCOPES, } def test_get_facebook_user_pages( test_client: TestClient, build_model: BuildModel, mock_dependency: MockDependency, ) -> None: page = build_model(FacebookPage, is_manageable=True, is_value=True) handler_mock = mock_dependency(GetFacebookUserPagesHandler) handler_mock.handle.return_value = [page] response = test_client.get("/facebook/connection/pages") assert response.status_code == 200 assert response.json() == [ { "id": page.id, "externalId": page.external_id, "name": page.name, "isManageable": page.is_manageable, "isValid": page.is_valid, "pictureUrl": page.picture_url, } ] def test_get_facebook_user_pages_for_label( test_client: TestClient, build_model: BuildModel, mock_dependency: MockDependency ) -> None: vendor_id = 100 subaccount_id = 1000 page = build_model(FacebookPage) handler_mock = mock_dependency(GetFacebookUserPagesForLabelHandler) handler_mock.handle.return_value = [page] response = test_client.get( "/facebook/pages", params={ "vendorId": vendor_id, "subaccountId": subaccount_id, }, ) assert response.status_code == 200 assert response.json() == [ { "id": page.id, "externalId": page.external_id, "name": page.name, "isManageable": page.is_manageable, "isValid": page.is_valid, "pictureUrl": page.picture_url, } ] def test_get_facebook_user_page_for_label( test_client: TestClient, build_model: BuildModel, mock_dependency: MockDependency ) -> None: vendor_id = 100 subaccount_id = 1000 page = build_model(FacebookPage) handler_mock = mock_dependency(GetFacebookUserPageForLabelHandler) handler_mock.handle.return_value = page response = test_client.get( f"/facebook/pages/{page.id}", params={ "vendorId": vendor_id, "subaccountId": subaccount_id, }, ) assert response.status_code == 200 assert response.json() == { "id": page.id, "externalId": page.external_id, "name": page.name, "isManageable": page.is_manageable, "isValid": page.is_valid, "pictureUrl": page.picture_url, } def test_get_instagram_account_for_facebook_page( test_client: TestClient, fake: FakerTyped, build_model: BuildModel, mock_dependency: MockDependency, ) -> None: page_label = build_model(FacebookPageLabel) page = page_label.page instagram_account = InstagramAccount( id=fake.uuid4_string(), name=fake.name(), username=fake.user_name(), profile_picture_url=fake.image_url(), ) handler_mock = mock_dependency(GetInstagramAccountForFacebookPageHandler) handler_mock.handle.return_value = instagram_account response = test_client.get( f"/facebook/pages/{page.id}/instagram/account", params={ "vendorId": page_label.vendor_id, "subaccountId": page_label.subaccount_id, }, ) assert response.status_code == 200 assert response.json() == { "instagramAccount": { "id": instagram_account.id, "name": instagram_account.name, "username": instagram_account.username, "profilePictureUrl": instagram_account.profile_picture_url, } } def test_get_instagram_account_for_facebook_page_none( test_client: TestClient, fake: FakerTyped, build_model: BuildModel, mock_dependency: MockDependency, ) -> None: page_label = build_model(FacebookPageLabel) page = page_label.page handler_mock = mock_dependency(GetInstagramAccountForFacebookPageHandler) handler_mock.handle.return_value = None response = test_client.get( f"/facebook/pages/{page.id}/instagram/account", params={ "vendorId": page_label.vendor_id, "subaccountId": page_label.subaccount_id, }, ) assert response.status_code == 200 assert response.json() == {"instagramAccount": None} def test_get_facebook_geolocations( test_client: TestClient, fake: FakerTyped, mock_dependency: MockDependency ) -> None: geolocation = TargetingGeolocation( key=fake.pystr(), name=fake.pystr(), type=fake.choice(TARGETING_LOCATION_TYPES), country_code=fake.country_code(), country_name=fake.country(), region=fake.region(), ) facebook_client_mock = mock_dependency(FacebookClient) facebook_client_mock.get_targeting_geolocations.return_value = [geolocation] response = test_client.get("/facebook/geolocations", params={"search": "aaa"}) assert response.status_code == 200 assert response.json() == [ { "key": geolocation.key, "name": geolocation.name, "type": geolocation.type, "countryCode": geolocation.country_code, "countryName": geolocation.country_name, "region": geolocation.region, } ] def test_get_facebook_interests( test_client: TestClient, fake: FakerTyped, mock_dependency: MockDependency ) -> None: interest = TargetingInterest( id=fake.pystr(), name=fake.pystr(), path=[fake.pystr(), fake.pystr(), fake.pystr()], ) facebook_client_mock = mock_dependency(FacebookClient) facebook_client_mock.get_targeting_interests.return_value = [interest] response = test_client.get("/facebook/interests", params={"search": "aaa"}) assert response.status_code == 200 assert response.json() == [ { "id": interest.id, "name": interest.name, "path": interest.path, "disambiguationCategory": interest.disambiguation_category, "topic": interest.topic, } ]