def test_multiple_versions(self): """Meta section spells out significant versions.""" feature = self.create(Feature, slug='feature') browser = self.create(Browser, slug='browser', name={'en': 'Browser'}) version1 = self.create( Version, browser=browser, status='current', version='1.0') version2 = self.create( Version, browser=browser, status='current', version='2.0') version3 = self.create( Version, browser=browser, status='current', version='3.0') support1 = self.create( Support, version=version1, feature=feature, support='no') # No change in support self.create( Support, version=version2, feature=feature, support='no') support3 = self.create( Support, version=version3, feature=feature, support='yes') self.changeset.closed = True self.changeset.save() url = self.api_reverse('viewfeatures-detail', pk=feature.pk) serializer = ViewFeatureSerializer(context=self.make_context(url)) representation = serializer.to_representation(feature) compat_table = representation['_view_extra']['meta']['compat_table'] expected_supports = { str(feature.pk): { str(browser.pk): [str(support1.pk), str(support3.pk)], } } self.assertEqual(compat_table['supports'], expected_supports)
def test_large_feature_tree(self): feature = self.setup_feature_tree() url = self.api_reverse('viewfeatures-detail', pk=feature.pk) context = self.make_context(url, include_child_pages=True) serializer = ViewFeatureSerializer(context=context) representation = serializer.to_representation(feature) next_page = url + '?child_pages=1&page=2' expected_pagination = { 'linked.features': { 'previous': None, 'next': self.baseUrl + next_page, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertDataEqual(expected_pagination, actual_pagination) context2 = self.make_context(next_page, include_child_pages=True) serializer2 = ViewFeatureSerializer(context=context2) representation = serializer2.to_representation(feature) expected_pagination = { 'linked.features': { 'previous': self.baseUrl + url + '?child_pages=1&page=1', 'next': None, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertEqual(expected_pagination, actual_pagination)
def assertUpdateFailed(self, data, expected_errors): feature = Feature.objects.get(id=self.feature.id) # Clear prop caches serializer = ViewFeatureSerializer(feature, data=data, context=self.context, partial=True) self.assertFalse(serializer.is_valid()) self.assertEqual(serializer.errors, expected_errors)
def assertUpdateSuccess(self, data): feature = Feature.objects.get(id=self.feature.id) # Clear prop caches serializer = ViewFeatureSerializer(feature, data=data, context=self.context, partial=True) self.assertTrue(serializer.is_valid()) return serializer.save()
def test_canonical_removed(self): """zxx (non-linguistic, canonical) does not appear in languages.""" resources = self.setup_minimal() feature = resources['feature'] del self.changeset self.create( Feature, parent=feature, slug='child', name='{"zxx": "canonical"}') self.changeset.closed = True self.changeset.save() feature = Feature.objects.get(pk=feature.pk) url = self.api_reverse('viewfeatures-detail', pk=feature.pk) serializer = ViewFeatureSerializer(context=self.make_context(url)) representation = serializer.to_representation(feature) compat_table = representation['_view_extra']['meta']['compat_table'] self.assertEqual(compat_table['languages'], ['en'])
def test_just_right_feature_tree(self): feature = self.setup_feature_tree() self.assertEqual(feature.descendant_count, 3) url = self.api_reverse('viewfeatures-detail', pk=feature.pk) context = self.make_context(url, include_child_pages=True) serializer = ViewFeatureSerializer(context=context) representation = serializer.to_representation(feature) expected_pagination = { 'linked.features': { 'previous': None, 'next': None, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertDataEqual(expected_pagination, actual_pagination)
def test_canonical_removed(self): """zxx (non-linguistic, canonical) does not appear in languages.""" resources = self.setup_minimal() feature = resources['feature'] del self.changeset self.create(Feature, parent=feature, slug='child', name='{"zxx": "canonical"}') self.changeset.closed = True self.changeset.save() feature = Feature.objects.get(pk=feature.pk) url = self.api_reverse('viewfeatures-detail', pk=feature.pk) serializer = ViewFeatureSerializer(context=self.make_context(url)) representation = serializer.to_representation(feature) compat_table = representation['_view_extra']['meta']['compat_table'] self.assertEqual(compat_table['languages'], ['en'])
def test_multiple_versions(self): """Meta section spells out significant versions.""" feature = self.create(Feature, slug='feature') browser = self.create(Browser, slug='browser', name={'en': 'Browser'}) version1 = self.create(Version, browser=browser, status='current', version='1.0') version2 = self.create(Version, browser=browser, status='current', version='2.0') version3 = self.create(Version, browser=browser, status='current', version='3.0') support1 = self.create(Support, version=version1, feature=feature, support='no') # No change in support self.create(Support, version=version2, feature=feature, support='no') support3 = self.create(Support, version=version3, feature=feature, support='yes') self.changeset.closed = True self.changeset.save() url = self.api_reverse('viewfeatures-detail', pk=feature.pk) serializer = ViewFeatureSerializer(context=self.make_context(url)) representation = serializer.to_representation(feature) compat_table = representation['_view_extra']['meta']['compat_table'] expected_supports = { str(feature.pk): { str(browser.pk): [str(support1.pk), str(support3.pk)], } } self.assertEqual(compat_table['supports'], expected_supports)
def test_large_feature_tree_cached_feature(self): feature = self.setup_feature_tree() cached_qs = CachedQueryset( Cache(), Feature.objects.all(), primary_keys=[feature.pk]) cached_feature = cached_qs.get(pk=feature.pk) self.assertEqual(cached_feature.pk, feature.id) self.assertEqual(cached_feature.descendant_count, 3) self.assertEqual(cached_feature.descendant_pks, []) # Too big to cache url = self.api_reverse('viewfeatures-detail', pk=cached_feature.pk) context = self.make_context(url, include_child_pages=True) serializer = ViewFeatureSerializer(context=context) representation = serializer.to_representation(cached_feature) next_page = url + '?child_pages=1&page=2' expected_pagination = { 'linked.features': { 'previous': None, 'next': self.baseUrl + next_page, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertDataEqual(expected_pagination, actual_pagination) context2 = self.make_context(next_page, include_child_pages=True) serializer2 = ViewFeatureSerializer(context=context2) representation = serializer2.to_representation(feature) expected_pagination = { 'linked.features': { 'previous': self.baseUrl + url + '?child_pages=1&page=1', 'next': None, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertEqual(expected_pagination, actual_pagination)
def test_large_feature_tree_cached_feature(self): feature = self.setup_feature_tree() cached_qs = CachedQueryset(Cache(), Feature.objects.all(), primary_keys=[feature.pk]) cached_feature = cached_qs.get(pk=feature.pk) self.assertEqual(cached_feature.pk, feature.id) self.assertEqual(cached_feature.descendant_count, 3) self.assertEqual(cached_feature.descendant_pks, []) # Too big to cache url = self.api_reverse('viewfeatures-detail', pk=cached_feature.pk) context = self.make_context(url, include_child_pages=True) serializer = ViewFeatureSerializer(context=context) representation = serializer.to_representation(cached_feature) next_page = url + '?child_pages=1&page=2' expected_pagination = { 'linked.features': { 'previous': None, 'next': self.baseUrl + next_page, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertDataEqual(expected_pagination, actual_pagination) context2 = self.make_context(next_page, include_child_pages=True) serializer2 = ViewFeatureSerializer(context=context2) representation = serializer2.to_representation(feature) expected_pagination = { 'linked.features': { 'previous': self.baseUrl + url + '?child_pages=1&page=1', 'next': None, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertEqual(expected_pagination, actual_pagination)
def test_minimal(self): """Get a minimal but complete viewfeature.""" resources = self.setup_minimal() browser = resources['browser'] feature = resources['feature'] reference = resources['reference'] section = resources['section'] support = resources['support'] maturity = resources['maturity'] version = resources['version'] specification = resources['specification'] url = self.api_reverse('viewfeatures-detail', pk=feature.pk) serializer = ViewFeatureSerializer(context=self.make_context(url)) representation = serializer.to_representation(feature) expected_representation = { 'id': feature.id, 'mdn_uri': None, 'slug': 'feature', 'experimental': False, 'standardized': True, 'stable': True, 'obsolete': False, 'name': None, 'references': [reference.pk], 'supports': [support.pk], 'parent': None, 'children': [], 'history_current': self.history_pk(feature), 'history': self.history_pks(feature), '_view_extra': { 'browsers': [{ 'id': browser.pk, 'slug': 'chrome_desktop', 'name': {'en': 'Browser'}, 'note': None, 'history_current': self.history_pk(browser), 'history': self.history_pks(browser), }], 'features': [], 'maturities': [{ 'id': maturity.id, 'slug': 'maturity', 'name': {'en': 'Maturity'}, 'history_current': self.history_pk(maturity), 'history': self.history_pks(maturity), }], 'references': [{ 'id': reference.id, 'note': None, 'feature': feature.id, 'section': section.id, 'history_current': self.history_pk(reference), 'history': self.history_pks(reference), }], 'sections': [{ 'id': section.id, 'number': None, 'name': None, 'subpath': None, 'specification': specification.id, 'history_current': self.history_pk(section), 'history': self.history_pks(section), }], 'specifications': [{ 'id': specification.id, 'slug': 'spec', 'mdn_key': None, 'name': {'en': 'Specification'}, 'uri': None, 'maturity': maturity.id, 'history_current': self.history_pk(specification), 'history': self.history_pks(specification), }], 'supports': [{ 'id': support.id, 'support': 'yes', 'prefix': None, 'prefix_mandatory': False, 'alternate_name': None, 'alternate_mandatory': False, 'requires_config': None, 'default_config': None, 'protected': False, 'note': None, 'version': version.id, 'feature': feature.id, 'history_current': self.history_pk(support), 'history': self.history_pks(support), }], 'versions': [{ 'id': version.id, 'version': None, 'release_day': None, 'retirement_day': None, 'status': 'current', 'release_notes_uri': None, 'note': None, 'order': 0, 'browser': browser.id, 'history_current': self.history_pk(version), 'history': self.history_pks(version), }], 'meta': { 'compat_table': { 'tabs': [ { 'name': {'en': 'Desktop Browsers'}, 'browsers': [str(browser.pk)] }, ], 'supports': { str(feature.pk): { str(browser.pk): [str(support.pk)], } }, 'child_pages': False, 'pagination': { 'linked.features': { 'previous': None, 'next': None, 'count': 0, }, }, 'languages': ['en'], 'notes': {}, } } } } self.assertDataEqual(representation, expected_representation)
def assertUpdateFailed(self, data, expected_errors): feature = Feature.objects.get(id=self.feature.id) # Clear prop caches serializer = ViewFeatureSerializer( feature, data=data, context=self.context, partial=True) self.assertFalse(serializer.is_valid()) self.assertEqual(serializer.errors, expected_errors)
def assertUpdateSuccess(self, data): feature = Feature.objects.get(id=self.feature.id) # Clear prop caches serializer = ViewFeatureSerializer( feature, data=data, context=self.context, partial=True) self.assertTrue(serializer.is_valid()) return serializer.save()
def test_important_versions(self): feature = self.create(Feature, slug='feature') browser = self.create(Browser, slug='browser') v1 = self.create(Version, browser=browser, version='1') support = { 'support': 'yes', 'prefix': '--pre', 'prefix_mandatory': True, 'alternate_name': 'future', 'alternate_mandatory': True, 'requires_config': 'feature=Yes', 'default_config': 'feature=No', 'protected': False, 'note': {'en': 'note'}, } s1 = self.create(Support, version=v1, feature=feature, **support) v2 = self.create(Version, browser=browser, version='2') support['prefix_mandatory'] = False s2 = self.create(Support, version=v2, feature=feature, **support) v3 = self.create(Version, browser=browser, version='3') support['prefix'] = '' s3 = self.create(Support, version=v3, feature=feature, **support) v4 = self.create(Version, browser=browser, version='4') support['alternate_mandatory'] = False s4 = self.create(Support, version=v4, feature=feature, **support) v5 = self.create(Version, browser=browser, version='5') support['alternate_name'] = '' s5 = self.create(Support, version=v5, feature=feature, **support) # BORING VERSION v51 = self.create(Version, browser=browser, version='5.1') self.create(Support, version=v51, feature=feature, **support) v6 = self.create(Version, browser=browser, version='6') support['default_config'] = 'feature=Yes' s6 = self.create(Support, version=v6, feature=feature, **support) v7 = self.create(Version, browser=browser, version='7') support['protected'] = True s7 = self.create(Support, version=v7, feature=feature, **support) v8 = self.create(Version, browser=browser, version='8') support['note']['es'] = 'el note' s8 = self.create(Support, version=v8, feature=feature, **support) v9 = self.create(Version, browser=browser, version='9') support['note'] = None s9 = self.create(Support, version=v9, feature=feature, **support) url = self.api_reverse('viewfeatures-detail', pk=feature.pk) context = self.make_context(url) serializer = ViewFeatureSerializer(context=context) representation = serializer.to_representation(feature) expected_supports = { str(feature.pk): { str(browser.pk): [ str(s1.pk), str(s2.pk), str(s3.pk), str(s4.pk), str(s5.pk), str(s6.pk), str(s7.pk), str(s8.pk), str(s9.pk) ]}} compat_table = representation['_view_extra']['meta']['compat_table'] actual_supports = compat_table['supports'] self.assertDataEqual(expected_supports, actual_supports)
def test_minimal(self): """Get a minimal but complete viewfeature.""" resources = self.setup_minimal() browser = resources['browser'] feature = resources['feature'] reference = resources['reference'] section = resources['section'] support = resources['support'] maturity = resources['maturity'] version = resources['version'] specification = resources['specification'] url = self.api_reverse('viewfeatures-detail', pk=feature.pk) serializer = ViewFeatureSerializer(context=self.make_context(url)) representation = serializer.to_representation(feature) expected_representation = { 'id': feature.id, 'mdn_uri': None, 'slug': 'feature', 'experimental': False, 'standardized': True, 'stable': True, 'obsolete': False, 'name': None, 'references': [reference.pk], 'supports': [support.pk], 'parent': None, 'children': [], 'history_current': self.history_pk(feature), 'history': self.history_pks(feature), '_view_extra': { 'browsers': [{ 'id': browser.pk, 'slug': 'chrome_desktop', 'name': { 'en': 'Browser' }, 'note': None, 'history_current': self.history_pk(browser), 'history': self.history_pks(browser), }], 'features': [], 'maturities': [{ 'id': maturity.id, 'slug': 'maturity', 'name': { 'en': 'Maturity' }, 'history_current': self.history_pk(maturity), 'history': self.history_pks(maturity), }], 'references': [{ 'id': reference.id, 'note': None, 'feature': feature.id, 'section': section.id, 'history_current': self.history_pk(reference), 'history': self.history_pks(reference), }], 'sections': [{ 'id': section.id, 'number': None, 'name': None, 'subpath': None, 'specification': specification.id, 'history_current': self.history_pk(section), 'history': self.history_pks(section), }], 'specifications': [{ 'id': specification.id, 'slug': 'spec', 'mdn_key': None, 'name': { 'en': 'Specification' }, 'uri': None, 'maturity': maturity.id, 'history_current': self.history_pk(specification), 'history': self.history_pks(specification), }], 'supports': [{ 'id': support.id, 'support': 'yes', 'prefix': None, 'prefix_mandatory': False, 'alternate_name': None, 'alternate_mandatory': False, 'requires_config': None, 'default_config': None, 'protected': False, 'note': None, 'version': version.id, 'feature': feature.id, 'history_current': self.history_pk(support), 'history': self.history_pks(support), }], 'versions': [{ 'id': version.id, 'version': None, 'release_day': None, 'retirement_day': None, 'status': 'current', 'release_notes_uri': None, 'note': None, 'order': 0, 'browser': browser.id, 'history_current': self.history_pk(version), 'history': self.history_pks(version), }], 'meta': { 'compat_table': { 'tabs': [ { 'name': { 'en': 'Desktop Browsers' }, 'browsers': [str(browser.pk)] }, ], 'supports': { str(feature.pk): { str(browser.pk): [str(support.pk)], } }, 'child_pages': False, 'pagination': { 'linked.features': { 'previous': None, 'next': None, 'count': 0, }, }, 'languages': ['en'], 'notes': {}, } } } } self.assertDataEqual(representation, expected_representation)
def test_important_versions(self): feature = self.create(Feature, slug='feature') browser = self.create(Browser, slug='browser') v1 = self.create(Version, browser=browser, version='1') support = { 'support': 'yes', 'prefix': '--pre', 'prefix_mandatory': True, 'alternate_name': 'future', 'alternate_mandatory': True, 'requires_config': 'feature=Yes', 'default_config': 'feature=No', 'protected': False, 'note': { 'en': 'note' }, } s1 = self.create(Support, version=v1, feature=feature, **support) v2 = self.create(Version, browser=browser, version='2') support['prefix_mandatory'] = False s2 = self.create(Support, version=v2, feature=feature, **support) v3 = self.create(Version, browser=browser, version='3') support['prefix'] = '' s3 = self.create(Support, version=v3, feature=feature, **support) v4 = self.create(Version, browser=browser, version='4') support['alternate_mandatory'] = False s4 = self.create(Support, version=v4, feature=feature, **support) v5 = self.create(Version, browser=browser, version='5') support['alternate_name'] = '' s5 = self.create(Support, version=v5, feature=feature, **support) # BORING VERSION v51 = self.create(Version, browser=browser, version='5.1') self.create(Support, version=v51, feature=feature, **support) v6 = self.create(Version, browser=browser, version='6') support['default_config'] = 'feature=Yes' s6 = self.create(Support, version=v6, feature=feature, **support) v7 = self.create(Version, browser=browser, version='7') support['protected'] = True s7 = self.create(Support, version=v7, feature=feature, **support) v8 = self.create(Version, browser=browser, version='8') support['note']['es'] = 'el note' s8 = self.create(Support, version=v8, feature=feature, **support) v9 = self.create(Version, browser=browser, version='9') support['note'] = None s9 = self.create(Support, version=v9, feature=feature, **support) url = self.api_reverse('viewfeatures-detail', pk=feature.pk) context = self.make_context(url) serializer = ViewFeatureSerializer(context=context) representation = serializer.to_representation(feature) expected_supports = { str(feature.pk): { str(browser.pk): [ str(s1.pk), str(s2.pk), str(s3.pk), str(s4.pk), str(s5.pk), str(s6.pk), str(s7.pk), str(s8.pk), str(s9.pk) ] } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_supports = compat_table['supports'] self.assertDataEqual(expected_supports, actual_supports)