def get_rating_changes(date=None): """ Call GetRatingChange to get all changes from IARC within 24 hours of the specified date (using today by default), and apply them to the corresponding Webapps. FIXME: Could add support for pagination, but very low priority since we will never ever get anywhere close to 500 rating changes in a single day. """ from mkt.webapps.models import IARCCert start_date = date or datetime.datetime.utcnow() end_date = start_date - datetime.timedelta(days=1) data = _iarc_request('GetRatingChanges', { 'StartDate': start_date.strftime('%Y-%m-%d'), 'EndDate': end_date.strftime('%Y-%m-%d'), 'MaxRows': 500, # Limit. 'StartRowIndex': 0 # Offset. }) for row in data.get('CertList', []): # Find app through Cert ID, ignoring unknown certs. try: cert = IARCCert.objects.get(cert_id=UUID(row['CertID']).get_hex()) except IARCCert.DoesNotExist: continue serializer = IARCV2RatingListSerializer(instance=cert.app, data=row) if serializer.is_valid(): serializer.save() return data
def get_rating_changes(): """ Call GetRatingChange to get all changes from IARC within the last day, and apply them to the corresponding Webapps. FIXME: Could add support for pagination, but very low priority since we will never ever get anywhere close to 500 rating changes in a single day. """ start_date = datetime.datetime.utcnow() end_date = start_date - datetime.timedelta(days=1) url = urljoin(settings.IARC_V2_SERVICE_ENDPOINT, 'GetRatingChanges') data = requests.post(url, json={ 'StartDate': start_date.strftime('%Y-%m-%d'), 'EndDate': end_date.strftime('%Y-%m-%d'), 'MaxRows': 500, # Limit. 'StartRowIndex': 0 # Offset. }).json() for row in data.get('CertList', []): # Find app through Cert ID, ignoring unknown certs. try: cert = IARCCert.objects.get(cert_id=UUID(row['CertID']).get_hex()) except IARCCert.DoesNotExist: continue serializer = IARCV2RatingListSerializer(instance=cert.app, data=row) if serializer.is_valid(): serializer.save() return data
def _search_cert(app, cert_id): """Ask IARC for information about a cert.""" data = _iarc_request('SearchCerts', {'CertID': unicode(UUID(cert_id))}) # We don't care about MatchFound, serializer won't find the right fields # if no match is found. serializer = IARCV2RatingListSerializer(instance=app, data=data) return serializer
def _search_cert(app, cert_id): """Ask IARC for information about a cert.""" url = urljoin(settings.IARC_V2_SERVICE_ENDPOINT, 'SearchCerts') data = requests.post(url, json={'CertID': unicode(UUID(cert_id))}).json() # We don't care about MatchFound, serializer won't find the right fields # if no match is found. serializer = IARCV2RatingListSerializer(instance=app, data=data) return serializer
def test_validate_rating_list_empty(self): data = { 'CertID': 'ae52b2d2-d4f7-4ebb-aade-28aa9795c5db', 'RatingList': [], } serializer = IARCV2RatingListSerializer(mock.Mock(), data) eq_(serializer.is_valid(), False) eq_(serializer.validated_data, None) eq_(serializer.errors, {'RatingList': 'This field is required.'})
def test_validate_no_cert_id(self): data = { 'RatingList': [{ 'RatingAuthorityShortText': 'Generic', 'AgeRatingText': '12+', }] } serializer = IARCV2RatingListSerializer(mock.Mock(), data) eq_(serializer.is_valid(), False) eq_(serializer.validated_data, None) eq_(serializer.errors, {'CertID': 'This field is required.'})
def test_validate_invalid_cert_id(self): data = { 'CertID': 'lol', 'RatingList': [{ 'RatingAuthorityShortText': 'Generic', 'AgeRatingText': '12+', }] } serializer = IARCV2RatingListSerializer(mock.Mock(), data) eq_(serializer.is_valid(), False) eq_(serializer.validated_data, None) eq_(serializer.errors, {'CertID': 'badly formed hexadecimal UUID string'})
def test_validate_with_unknown_body(self): data = { 'CertID': 'ae52b2d2-d4f7-4ebb-aade-28aa9795c5db', 'RatingList': [{ 'RatingAuthorityShortText': 'Blah', 'AgeRatingText': '12+', }] } serializer = IARCV2RatingListSerializer(None, data) # The unknown body should *not* generate an error. eq_(serializer.is_valid(), True) eq_( serializer.validated_data, { 'cert_id': UUID('ae52b2d2-d4f7-4ebb-aade-28aa9795c5db'), 'descriptors': set([]), 'interactives': set([]), 'ratings': {} }) eq_(serializer.errors, {})
def test_validate_multiple_bodies_with_redundant_info(self): data = { 'CertID': 'ae52b2d2-d4f7-4ebb-aade-28aa9795c5db', 'RatingList': [ { 'RatingAuthorityShortText': 'Generic', 'AgeRatingText': '12+', 'DescriptorList': [{ 'DescriptorText': 'PEGI_Violence' }], 'InteractiveElementList': [{ 'InteractiveElementText': 'IE_UsersInteract' }, { 'InteractiveElementText': 'IE_SharesLocation' }, { 'InteractiveElementText': 'IE_DigitalPurchases' }] }, { 'RatingAuthorityShortText': 'PEGI', 'AgeRatingText': '12+', 'DescriptorList': [ { 'DescriptorText': 'PEGI_Violence' }, { 'DescriptorText': 'PEGI_Online' }, ], 'InteractiveElementList': [{ 'InteractiveElementText': 'IE_UsersInteract' }, { 'InteractiveElementText': 'IE_DigitalPurchases' }] }, { 'RatingAuthorityShortText': 'ESRB', 'AgeRatingText': 'Teen', 'DescriptorList': [], 'InteractiveElementList': [] }, ] } expected_data = { 'cert_id': UUID('ae52b2d2-d4f7-4ebb-aade-28aa9795c5db'), 'descriptors': set([ 'has_generic_violence', 'has_pegi_online', 'has_pegi_violence' ]), 'interactives': set([ 'has_shares_location', 'has_digital_purchases', 'has_users_interact' ]), 'ratings': { ratingsbodies.ESRB: ratingsbodies.ESRB_T, ratingsbodies.GENERIC: ratingsbodies.GENERIC_12, ratingsbodies.PEGI: ratingsbodies.PEGI_12, }, } serializer = IARCV2RatingListSerializer(None, data) eq_(serializer.is_valid(), True) eq_(serializer.errors, {}) eq_(serializer.validated_data['cert_id'], expected_data['cert_id']) self.assertSetEqual(serializer.validated_data['descriptors'], expected_data['descriptors']) self.assertSetEqual(serializer.validated_data['interactives'], expected_data['interactives']) eq_(serializer.validated_data['ratings'], expected_data['ratings']) return serializer
def test_validate_no_data(self): data = {} serializer = IARCV2RatingListSerializer(mock.Mock(), data) eq_(serializer.is_valid(), False) eq_(serializer.validated_data, None) eq_(serializer.errors, {'RatingList': 'This field is required.'})
def test_save_with_invalid_data(self, is_valid_mock): is_valid_mock.return_value = False serializer = IARCV2RatingListSerializer(instance=object()) with self.assertRaises(ParseError): serializer.save()
def test_save_with_no_instance(self): serializer = IARCV2RatingListSerializer(data={}) with self.assertRaises(ValueError): serializer.save()