from typing import List from unittest.mock import patch import json from sqlalchemy import and_ from db import db from tests.test_utils import FixtureLoader from models import models, ArtistTeamUser, ArtistTeam, Artist, Project, MediaPlan from tests import BaseTestCase, mock_for_user from tests.label_permissions.fixtures.label_permissions_artist_teams_fixture import fixture user1 = mock_for_user(1, "dev-marketing-user-1@example.com", "sme-dna|5cf0091d6c91d310fe6fcdc6", is_admin=True) user2 = mock_for_user(2, "dev-marketing-user-2@example.com", "sme-dna|5cf0091d6c91d310fe6fcdc7", is_admin=False) user4 = mock_for_user(4, "dev-marketing-user-4@example.com", "sme-dna|5cf0091d6c91d310fe6fcd42", is_admin=False) class TestLabelArtists(BaseTestCase): url = "/labels/{}/permissions/artists/{}/artist-teams" def setUp(self): super().setUp() FixtureLoader(models=models).import_as_sql(fixture) @staticmethod def get_user_projects_for_user_id(users_ids: List[int]): return ( db.session.execute(f""" SELECT project_id FROM user_projects WHERE user_id IN ({",".join(users_ids)}) """).fetchall() ) @staticmethod def __unpack_users_as_query_params(users: List[int]): return "?" + "".join(["userId="+str(user) for user in users]) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1.jwt_decode) def test_create_artist_team_for_user(self): data = { "userId": [2] } response = self.execute_post(self.url.format(1, 'GRAS_10'), headers=self.headers, data=json.dumps(data)) self.assertEqual(204, response.status_code) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1.jwt_decode) def test_delete_artist_team_for_user(self): data = { "userId": [1] } response = self.execute_delete( self.url.format(1, "GRAS_10") + self.__unpack_users_as_query_params(data.get("userId")), headers=self.headers ) self.assertEqual(204, response.status_code) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user2.jwt_decode) def test_not_admin_403(self): data = { "userId": [2] } response = self.execute_post(self.url.format(1, "GRAS_10"), headers=self.headers, data=json.dumps(data)) self.assertEqual(403, response.status_code) response = self.execute_delete( self.url.format(1, "GRAS_10") + self.__unpack_users_as_query_params(data.get("userId")), headers=self.headers ) self.assertEqual(403, response.status_code) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user4.jwt_decode) def test_artist_team_editor_can_add_delete_members(self): data = { "userId": [1] } response = self.execute_post( self.url.format(1, "GRAS_10"), headers=self.headers, data=json.dumps({"userId": [2]}) ) self.assertEqual(204, response.status_code) response = self.execute_delete( self.url.format(1, "GRAS_10") + self.__unpack_users_as_query_params(data.get("userId")), headers=self.headers ) self.assertEqual(204, response.status_code) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1.jwt_decode) def test_artist_exist_not_exist_or_not_from_this_label(self): data = { "userId": [2] } response = self.execute_post(self.url.format(1, "GRAS_42"), headers=self.headers, data=json.dumps(data)) self.assertEqual(422, response.status_code) response = self.execute_delete( self.url.format(1, "GRAS_42") + self.__unpack_users_as_query_params(data.get('userId')), headers=self.headers ) self.assertEqual(422, response.status_code) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1.jwt_decode) def test_add_users_to_artist_team_created_and_projects_claimed(self): user_id = [2, 3] data = { "userId": user_id } artist_id = "GRAS_20" response = self.execute_post(self.url.format(1, artist_id), headers=self.headers, data=json.dumps(data)) self.assertEqual(204, response.status_code) artist_team_users = ( db.session.query(ArtistTeamUser) .select_from(Artist) .join(ArtistTeam, and_(ArtistTeam.artist_id == Artist.id, ArtistTeam.label_id == 1)) .join(ArtistTeamUser, and_( ArtistTeamUser.user_id.in_(user_id), ArtistTeamUser.artist_team_id == ArtistTeam.id )) .filter(Artist.external_id == artist_id) .all() ) self.soft_assert_equal(len(artist_team_users), 2) projects_related_to_artist = ( db.session.query(Project) .filter(Project.id.in_([504, 505, 511])) .all() ) self.soft_assert_equal(len(projects_related_to_artist), 3) self.soft_assert_equal(all([project.is_claimed for project in projects_related_to_artist]), True) self.soft_assert_equal(all([project.end_date for project in projects_related_to_artist]), True) media_plan = ( db.session.query(MediaPlan) .filter(MediaPlan.project_id.in_([504, 505, 511])) .all() ) self.soft_assert_equal(set([mp.project_id for mp in media_plan]), {504, 505, 511}) self.assert_all() @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1.jwt_decode) def test_delete_user_from_artist_remove_artist_team_user_and_team_if_lasat_user(self): data = { "userId": [1] } artist_team_user_before_deletion = ( db.session.query(ArtistTeamUser) .select_from(ArtistTeam) .join(ArtistTeamUser, ArtistTeamUser.artist_team_id == ArtistTeam.id) .filter(ArtistTeamUser.user_id == 1, ArtistTeam.label_id == 1).count() ) response = self.execute_delete( self.url.format(1, "GRAS_10") + self.__unpack_users_as_query_params(data.get("userId")), headers=self.headers ) self.assertEqual(204, response.status_code) artist_team_user_after_deletion = ( db.session.query(ArtistTeamUser) .select_from(ArtistTeam) .join(ArtistTeamUser, ArtistTeamUser.artist_team_id == ArtistTeam.id) .filter(ArtistTeamUser.user_id == 1, ArtistTeam.label_id == 1).count() ) self.assertEqual(artist_team_user_before_deletion - 1, artist_team_user_after_deletion) artist_team_user = ( db.session.query(ArtistTeam) .join(ArtistTeamUser, and_(ArtistTeamUser.artist_team_id == ArtistTeam.id, ArtistTeamUser.user_id == 1)) .filter(ArtistTeam.label_id == 1, ArtistTeam.artist_id == 10) .one_or_none() ) self.assertIsNone(artist_team_user) artist_team = db.session.query(ArtistTeam).filter(ArtistTeam.artist_id == 10, ArtistTeam.label_id == 1).one_or_none() self.assertIsNotNone(artist_team) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1.jwt_decode) def test_delete_user_from_artist_remove_team_if_last_user_removed(self): data = { "userId": [1] } response = self.execute_delete( self.url.format(3, "GRAS_80") + self.__unpack_users_as_query_params(data.get("userId")), headers=self.headers ) self.assertEqual(204, response.status_code) artist_team = db.session.query(ArtistTeam).filter(ArtistTeam.artist_id == 80, ArtistTeam.label_id == 3).one_or_none() self.assertIsNone(artist_team) project_512 = ( db.session.query( Project ) .filter(Project.id == 512) .one() ) self.assertEqual(project_512.is_claimed, False) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1.jwt_decode) def test_add_user_to_primary_locked_artist_team_should_remove_projects_collaborator(self): response = self.execute_get("/projects/513/team", headers=self.headers) self.soft_assert_equal(200, response.status_code) data = response.json self.soft_assert_equal(len(data), 2) user_id = [4] data = { "userId": user_id } artist_id = "GRAS_90" response = self.execute_post(self.url.format(3, artist_id), headers=self.headers, data=json.dumps(data)) self.soft_assert_equal(204, response.status_code) artist_team_users = ( db.session.query(ArtistTeamUser) .select_from(Artist) .join(ArtistTeam, and_(ArtistTeam.artist_id == Artist.id, ArtistTeam.label_id == 3)) .join(ArtistTeamUser, and_( ArtistTeamUser.user_id.in_(user_id), ArtistTeamUser.artist_team_id == ArtistTeam.id )) .filter(Artist.external_id == artist_id) .all() ) self.soft_assert_equal(len(artist_team_users), 1) response = self.execute_get("/projects/513/team", headers=self.headers) self.soft_assert_equal(200, response.status_code) data = response.json self.soft_assert_equal(len(data), 1) self.assert_all()