"""Access and data visibility tests.""" import pytest from owsrequest.constants import headers as owsrequest_headers from analytics import config from tests.integration.request import request_get_cache class BaseAccessControls: """Base class for access and data visibility tests.""" @staticmethod def product_response(label, product_id): """Return /product/{productId} response.""" return request_get_cache( config.PRODUCT_URL.replace("", product_id), headers=label["headers"], ).json() @staticmethod def product_response_code(label, product_id): """Return /product/{productId} response.""" return request_get_cache( config.PRODUCT_URL.replace("", product_id), headers=label["headers"], ).status_code @staticmethod def product_metadata_response(label, product_id): """Return /product/{productId}/metadata response.""" # this product metadata owned by regular_label_1 contains ISRCs which # are present on other product(s) of regular_label_2 return request_get_cache( config.PRODUCT_METADATA_URL.replace("", product_id), headers=label["headers"], ).json() @staticmethod def product_metadata_response_code(label, product_id): """Return /product/{productId}/metadata response.""" # this product metadata owned by regular_label_1 contains ISRCs which # are present on other product(s) of regular_label_2 return request_get_cache( config.PRODUCT_METADATA_URL.replace("", product_id), headers=label["headers"], ).status_code @staticmethod def top_sound_recordings_response(label): """Return /top-sound-recordings response.""" return request_get_cache( config.TOP_SOUND_RECORDINGS_URL, headers=label["headers"] ).json() @staticmethod def top_countries_videos_response(label, video_id): """Return /videos/{video_id}/top-countries response.""" return request_get_cache( config.TOP_COUNTRIES_VIDEOS_URL.replace("", video_id) + "?start_date=2019-12-01&end_date=2019-12-28", headers=label["headers"], ).json() @staticmethod def sound_recording_metadata_response(label, isrc): """Return /sound-recording/{isrc}/metadata response (for top s-r).""" return request_get_cache( config.SOUND_RECORDING_METADATA_URL.replace("", isrc), headers=label["headers"], ).json() @staticmethod def sound_recording_metadata_response_code(label, isrc): """Return /sound-recording/{isrc}/metadata response (for top s-r).""" return request_get_cache( config.SOUND_RECORDING_METADATA_URL.replace("", isrc), headers=label["headers"], ).status_code @staticmethod def check_isrc_on_product(isrc, product_response): """Check if /product/{productId} returns correct tracklist.""" tracks_on_product = list( filter(lambda track: track["isrc"] == isrc, product_response["tracks"]) ) assert len(tracks_on_product) > 0 @staticmethod def check_sound_recording_on_product(sound_recording, product): """Check if /product/{productId} returns correct tracklist.""" tracks_on_product = list( filter( lambda track: track["track_name"] == sound_recording["name"], product["tracks"], ) ) assert len(tracks_on_product) > 0 @pytest.mark.skip(reason="Skipping due to external failures") class TestAccessRegularLabels(BaseAccessControls): """Test data access and data visibility for a regular label.""" regular_label_1 = { "labelid": "19510", "headers": { owsrequest_headers.GRASS_ACCOUNT_ID: "19510", owsrequest_headers.GRASS_ACCOUNT_TYPE: "vendor", owsrequest_headers.ORCHARD_USER_ID: "alw:95202", }, } @pytest.fixture def owned_isrc(self): """Return an isrc that regular_label_1 owns.""" return "US3Z40407399" @pytest.fixture def not_owned_isrc(self): """Return an isrc that regular_label_1 doesn't own.""" return "GBUM71105426" @pytest.fixture def owned_product_id(self): """Return a product id that regular_label_1 owns.""" return "2857032" @pytest.fixture def not_owned_product_id(self): """Return a product id that regular_label_1 doesn't own.""" return "320039" def test_top_countries_videos(self): """Check if /videos/{video_id}/top-countries is accessible.""" video_id = "xA0DBcsfjTE" top_countries_response = self.top_countries_videos_response( self.regular_label_1, video_id ) assert len(top_countries_response["top_countries_videos"]) > 0 def test_sound_recording_metadata(self, owned_isrc): """Check if /sound-recording/{isrc}/metadata is accessible.""" sound_recording_metadata_response = self.sound_recording_metadata_response( self.regular_label_1, owned_isrc ) assert sound_recording_metadata_response["isrc"] == owned_isrc def test_product_endpoint(self, owned_isrc, owned_product_id): """Check if /product/{productId} returns correct tracklist.""" product_response = self.product_response(self.regular_label_1, owned_product_id) self.check_isrc_on_product(owned_isrc, product_response) def test_product_metadata(self, owned_isrc, owned_product_id): """Check if /product/{productId}/metadata returns correct tracklist.""" sound_recording_metadata = self.sound_recording_metadata_response( self.regular_label_1, owned_isrc ) product_metadata = self.product_metadata_response( self.regular_label_1, owned_product_id ) self.check_sound_recording_on_product( sound_recording_metadata, product_metadata ) def test_product_endpoint_for_not_owned_product(self, not_owned_product_id): """Test if product/{productId} returns 200 for not owned product with empty data response.""" product_response_code = self.product_response_code( self.regular_label_1, not_owned_product_id ) assert product_response_code == 200 def test_product_metadata_endpoint_for_not_owned_product( self, not_owned_product_id ): """Test product/{productId}/metadata returns 404.""" product_metadata_response_code = self.product_metadata_response_code( self.regular_label_1, not_owned_product_id ) assert product_metadata_response_code == 404 def test_sound_recording_metadata_endpoint_for_not_owned_sound_recoding( self, not_owned_isrc ): """Test /sound-recording/{isrc}/metadata returns 404.""" response_code = self.sound_recording_metadata_response_code( self.regular_label_1, not_owned_isrc ) assert response_code == 404 @pytest.mark.skip(reason="Skipping due to external failures") class TestAccessD3andSubaccounts(BaseAccessControls): """Test data visibility of products for D3 label and its subaccounts. One D3 own two subaccounts, each sub has a product, there is an ISRC that appears on both products. """ d3_label = { "labelid": "21989", "headers": { owsrequest_headers.GRASS_ACCOUNT_ID: "21989", owsrequest_headers.GRASS_ACCOUNT_TYPE: "vendor", owsrequest_headers.ORCHARD_USER_ID: "alw:38259", }, } subaccount_label_1 = { "labelid": "21989", "subaccountid": "11777", "headers": { owsrequest_headers.GRASS_ACCOUNT_ID: "11777", owsrequest_headers.GRASS_ACCOUNT_TYPE: "subaccount", owsrequest_headers.ORCHARD_USER_ID: "alw:55776", }, } owned_isrc = "QMYLU1500005" not_owned_isrc = "ATN261983908" owned_product_id = "1868966" not_owned_product_id = "2595212" def test_sound_recording_metadata(self): """Check if /sound-recording/{isrc}/metadata is accessible.""" sound_recording_metadata_response = self.sound_recording_metadata_response( self.subaccount_label_1, self.owned_isrc ) assert sound_recording_metadata_response["isrc"] == self.owned_isrc @pytest.mark.skip(reason="Skipping due to external failures") def test_d3_can_access_subaccount_sound_recording_metadata(self): """Check if /sound-recording/{isrc}/metadata is accessible.""" sound_recording_metadata_response = self.sound_recording_metadata_response( self.d3_label, self.owned_isrc ) assert sound_recording_metadata_response["isrc"] == self.owned_isrc def test_product_endpoint(self): """Check if /product/{productId} returns correct tracklist.""" product_response = self.product_response( self.subaccount_label_1, self.owned_product_id ) self.check_isrc_on_product(self.owned_isrc, product_response) @pytest.mark.skip(reason="Skipping due to external failures") def test_d3_can_access_subaccount_product_endpoint(self): """Check if /product/{productId} returns correct tracklist.""" product_response = self.product_response(self.d3_label, self.owned_product_id) self.check_isrc_on_product(self.owned_isrc, product_response) def test_product_metadata(self): """Check if /product/{productId}/metadata returns correct tracklist.""" sound_recording_metadata = self.sound_recording_metadata_response( self.subaccount_label_1, self.owned_isrc ) product_metadata = self.product_metadata_response( self.subaccount_label_1, self.owned_product_id ) self.check_sound_recording_on_product( sound_recording_metadata, product_metadata ) @pytest.mark.skip(reason="Skipping due to external failures") def test_d3_can_access_subaccount_product_metadata(self): """Check if /product/{productId}/metadata returns correct tracklist.""" sound_recording_metadata = self.sound_recording_metadata_response( self.d3_label, self.owned_isrc ) product_metadata = self.product_metadata_response( self.d3_label, self.owned_product_id ) self.check_sound_recording_on_product( sound_recording_metadata, product_metadata ) def test_product_endpoint_for_not_owned_product(self): """Test /product/{productId} returns 200 for not owned product with empty data response.""" product_response_code = self.product_response_code( self.subaccount_label_1, self.not_owned_product_id ) assert product_response_code == 200 def test_product_metadata_endpoint_for_not_owned_product(self): """Test /product/{productId}/metadata returns 404-not owned product.""" product_metadata_response_code = self.product_metadata_response_code( self.subaccount_label_1, self.not_owned_product_id ) assert product_metadata_response_code == 404 def test_sound_recording_metadata_endpoint_for_not_owned_sound_recoding(self): """Test /sound-recording/{isrc}/metadata returns 404-not owned s-r.""" response_code = self.sound_recording_metadata_response_code( self.subaccount_label_1, self.not_owned_isrc ) assert response_code == 404 @pytest.mark.skip(reason="This is too brittle for now due to QA neo4j issues") class TestAccessArtists(BaseAccessControls): """Test data access and data visibility for regular labels. There are two labels (not D3, not subaccounts) that have the same ISRC on different Foducts. """ artist_profile_1 = { "labelid": None, "headers": { owsrequest_headers.ORCHARD_PROFILE_ID: "1346777", owsrequest_headers.ORCHARD_PROFILE_TYPE: "ArtistProfile", }, } artist_profile_2 = { "labelid": None, "headers": { owsrequest_headers.ORCHARD_PROFILE_ID: "12134", owsrequest_headers.ORCHARD_PROFILE_TYPE: "ArtistProfile", }, } @pytest.fixture def owned_isrc(self): """Return an isrc this labels owns.""" top_sound_recordings = self.top_sound_recordings_response(self.artist_profile_1) return top_sound_recordings["items"][0]["isrc"] @pytest.fixture def not_owned_isrc(self): """Return an isrc this labels owns.""" return "QM4TX2030965" @pytest.fixture def owned_product_id(self, owned_isrc): """Return a product id this label owns.""" sound_recording_metadata_response = self.sound_recording_metadata_response( self.artist_profile_1, owned_isrc ) return sound_recording_metadata_response["products"][0]["product_id"] @pytest.fixture def not_owned_product_id(self, not_owned_isrc): """Return a product id this label owns.""" sound_recording_metadata_response = self.sound_recording_metadata_response( self.artist_profile_2, not_owned_isrc ) return sound_recording_metadata_response["products"][0]["product_id"] def test_sound_recording_metadata(self, owned_isrc): """Check if /sound-recording/{isrc}/metadata is accessible.""" sound_recording_metadata_response = self.sound_recording_metadata_response( self.artist_profile_1, owned_isrc ) assert sound_recording_metadata_response["isrc"] == owned_isrc def test_sound_recording_metadata_endpoint_for_not_owned_sound_recoding( self, not_owned_isrc ): """Check if /sound-recording/{isrc}/metadata returns 404.""" response_code = self.sound_recording_metadata_response_code( self.artist_profile_1, not_owned_isrc ) assert response_code == 404 @pytest.mark.skip(reason="https://theorchard.atlassian.net/browse/IN-10922") class TestAccessInsights(BaseAccessControls): """Test data access and data visibility for Insights Profiles. Testing employee, D3, vendor & subaccount profiles. N.B. THIS D3 DOES NOT OWN THIS SUBACCOUNT. """ # Profile has access to all Orchard labels employee_profile = { "headers": { owsrequest_headers.ORCHARD_PROFILE_ID: "1040", owsrequest_headers.ORCHARD_PROFILE_TYPE: "InsightsProfile", } } # Profile has access to Thirty Tigers d3_profile = { "headers": { owsrequest_headers.ORCHARD_PROFILE_ID: "26517", owsrequest_headers.ORCHARD_PROFILE_TYPE: "InsightsProfile", } } # Profile has access to Frenchkiss Records vendor_profile = { "headers": { owsrequest_headers.ORCHARD_PROFILE_ID: "26426", owsrequest_headers.ORCHARD_PROFILE_TYPE: "InsightsProfile", } } # Profile has access to City of Dreams LLC subaccount_profile = { "headers": { owsrequest_headers.ORCHARD_PROFILE_ID: "6617", owsrequest_headers.ORCHARD_PROFILE_TYPE: "InsightsProfile", } } d3_owned_isrc = "QZ84K1700002" d3_owned_product_id = "2047561" vendor_owned_isrc = "GBUM71105426" vendor_owned_product_id = "320039" subaccount_owned_isrc = "TCADD1729833" subaccount_owned_product_id = "2615324" @pytest.mark.parametrize( ("insights_profile, profile_owned_isrc"), [ (d3_profile, d3_owned_isrc), (vendor_profile, vendor_owned_isrc), (subaccount_profile, subaccount_owned_isrc), (employee_profile, d3_owned_isrc), (employee_profile, vendor_owned_isrc), (employee_profile, subaccount_owned_isrc), ], ) def test_profile_has_sound_recording_metadata_for_profile_owned_isrc( self, insights_profile, profile_owned_isrc ): """Check if /sound-recording/{isrc}/metadata is accessible.""" response = self.sound_recording_metadata_response( insights_profile, profile_owned_isrc ) assert response["isrc"] == profile_owned_isrc @pytest.mark.parametrize( ("isrc_not_owned_by_subaccount"), [d3_owned_isrc, vendor_owned_isrc] ) def test_subaccount_profile_does_not_see_sr_metadata_for_not_owned_isrcs( self, isrc_not_owned_by_subaccount ): """Check if /sound-recording/{isrc}/metadata returns 404.""" response_code = self.sound_recording_metadata_response_code( self.subaccount_profile, isrc_not_owned_by_subaccount ) assert response_code == 404 @pytest.mark.parametrize( ("isrc_not_owned_by_vendor"), [d3_owned_isrc, subaccount_owned_isrc] ) def test_vendor_profile_does_not_see_sr_metadata_for_not_owned_isrcs( self, isrc_not_owned_by_vendor ): """Check if /sound-recording/{isrc}/metadata returns 404.""" response_code = self.sound_recording_metadata_response_code( self.vendor_profile, isrc_not_owned_by_vendor ) assert response_code == 404 @pytest.mark.parametrize( ("isrc_not_owned_by_d3"), [vendor_owned_isrc, subaccount_owned_isrc] ) def test_d3_profile_does_not_see_sr_metadata_for_not_owned_isrcs( self, isrc_not_owned_by_d3 ): """Check if /sound-recording/{isrc}/metadata returns 404.""" response_code = self.sound_recording_metadata_response_code( self.d3_profile, isrc_not_owned_by_d3 ) assert response_code == 404 @pytest.mark.parametrize( ("insights_profile, profile_owned_product_id"), [ (d3_profile, d3_owned_product_id), (vendor_profile, vendor_owned_product_id), (subaccount_profile, subaccount_owned_product_id), (employee_profile, d3_owned_product_id), (employee_profile, vendor_owned_product_id), (employee_profile, subaccount_owned_product_id), ], ) def test_profile_has_product_metadata_for_owned_product_id( self, insights_profile, profile_owned_product_id ): """Check if /product/{productId}/metadata is accessible.""" response = self.product_metadata_response( insights_profile, profile_owned_product_id ) assert response["product_id"] == profile_owned_product_id @pytest.mark.parametrize( ("product_id_not_owned_by_subaccount"), [d3_owned_product_id, vendor_owned_product_id], ) def test_subaccount_does_not_see_p_metadata_for_not_owned_product_ids( self, product_id_not_owned_by_subaccount ): """Check if /product/{productId}/metadata returns 404.""" response_code = self.product_metadata_response_code( self.subaccount_profile, product_id_not_owned_by_subaccount ) assert response_code == 404 @pytest.mark.parametrize( ("product_id_not_owned_by_vendor"), [d3_owned_product_id, subaccount_owned_product_id], ) def test_vendor_does_not_see_p_metadata_for_not_owned_product_ids( self, product_id_not_owned_by_vendor ): """Check if /product/{productId}/metadata returns 404.""" response_code = self.product_metadata_response_code( self.vendor_profile, product_id_not_owned_by_vendor ) assert response_code == 404 @pytest.mark.parametrize( ("product_id_not_owned_by_d3"), [vendor_owned_product_id, subaccount_owned_product_id], ) def test_d3_does_not_see_p_metadata_for_not_owned_product_ids( self, product_id_not_owned_by_d3 ): """Check if /product/{productId}/metadata returns 404.""" response_code = self.product_metadata_response_code( self.d3_profile, product_id_not_owned_by_d3 ) assert response_code == 404