diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index a945b589..a4c6bf00 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -3,6 +3,7 @@ # metadata.py - part of the FDroid server tools # Copyright (C) 2013, Ciaran Gultnieks, ciaran@ciarang.com # Copyright (C) 2013-2014 Daniel Martí +# Copyright (C) 2017-2018 Michael Pöhn # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -1078,11 +1079,16 @@ def parse_yaml_metadata(mf, app): if field not in yaml_app_fields: warn_or_exception(_('Unrecognised app field: {fieldname}') .format(fieldname=field)) - if 'Builds' not in yamldata.keys(): + if not yamldata.get('Builds', None): warn_or_exception(_('Missing app field: {fieldname}') .format(fieldname='Builds')) - for build in yamldata['Builds']: + for build in yamldata.get('Builds', []): + # put all build flag keywords into a set to avoid + # excessive looping action + build_flag_set = set() for build_flag in build.keys(): + build_flag_set.add(build_flag) + for build_flag in build_flag_set: if build_flag not in build_flags: warn_or_exception(_('Unrecognised build flag: {build_flag}') .format(build_flag=build_flag)) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 247f6a89..c2cf871a 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -2,6 +2,7 @@ # http://www.drdobbs.com/testing/unit-testing-with-python/240165163 +import io import glob import inspect import logging @@ -13,6 +14,8 @@ import sys import unittest import yaml import tempfile +import textwrap +from unittest import mock localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -22,6 +25,7 @@ if localmodule not in sys.path: import fdroidserver.common import fdroidserver.metadata +from fdroidserver.exception import MetaDataException class MetadataTest(unittest.TestCase): @@ -139,6 +143,26 @@ class MetadataTest(unittest.TestCase): allappids.append(appid) self.assertEqual(randomlist, allappids) + def test_parse_yaml_metadata_unknown_app_field(self): + mf = io.StringIO(textwrap.dedent("""\ + AutoName: F-Droid + RepoType: git + Builds: [] + bad: value""")) + with mock.patch('fdroidserver.metadata.warnings_action', 'error'): + with self.assertRaises(MetaDataException): + fdroidserver.metadata.parse_yaml_metadata(mf, {}) + + def test_parse_yaml_metadata_unknown_build_flag(self): + mf = io.StringIO(textwrap.dedent("""\ + AutoName: F-Droid + RepoType: git + Builds: + - bad: value""")) + with mock.patch('fdroidserver.metadata.warnings_action', 'error'): + with self.assertRaises(MetaDataException): + fdroidserver.metadata.parse_yaml_metadata(mf, {}) + if __name__ == "__main__": parser = optparse.OptionParser()