Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #144 from cvan/master

some new properties for webapp manifest validator
  • Loading branch information...
commit c06efcbf57f83f4fa4a2c0b738352e64be2867c9 2 parents 3b39d36 + fbaabde
@mattbasta authored
Showing with 289 additions and 4 deletions.
  1. +211 −1 tests/test_webapp.py
  2. +78 −3 validator/webapp.py
View
212 tests/test_webapp.py
@@ -73,7 +73,16 @@ def _get_json():
}
}
},
- "default_locale": "en"
+ "default_locale": "en",
+ "screen_size": {
+ "min_width": "600",
+ "min_height": "300"
+ },
+ "required_features": [
+ "touch", "geolocation", "webgl"
+ ],
+ "orientation": "landscape",
+ "fullscreen": "true"
})
@@ -349,3 +358,204 @@ def test_webapp_bad_dev_url():
_detect(err, data)
assert err.failed()
+
+def test_webapp_screen_size_missing():
+ """Test that the 'screen_size' property can be absent."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ del data["screen_size"]
+ _detect(err, data)
+ assert not err.failed()
+
+
+def test_webapp_screen_size_is_dict():
+ """Test that the 'screen_size' property must be a dict."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["screen_size"] = "foo"
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_screen_size_contains_pair():
+ """Test that 'screen_size' must contain at least one key/value pair."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["screen_size"] = {}
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_bad_screen_size_key():
+ """Test that the 'screen_size' keys are correct."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["screen_size"]["max_width"] = "500"
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_bad_screen_size_value():
+ """Test that the 'screen_size' keys are correct."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["screen_size"]["min_width"] = "500px"
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_required_features_missing():
+ """Test that the 'required_features' property can be absent."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ del data["screen_size"]
+ _detect(err, data)
+ assert not err.failed()
+
+
+def test_webapp_required_features_is_list():
+ """Test that the 'required_features' property must be a list."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["required_features"] = "fart"
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_required_features_missing():
+ """Test that 'required_features' can be absent."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ del data["required_features"]
+ _detect(err, data)
+ assert not err.failed()
+
+
+def test_webapp_required_features_empty():
+ """Test that 'required_features' can be an empty list."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["required_features"] = []
+ _detect(err, data)
+ assert not err.failed()
+
+
+def test_webapp_orientation_missing():
+ """Test that the 'orientation' property can be absent."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ del data["orientation"]
+ _detect(err, data)
+ assert not err.failed()
+
+
+def test_webapp_orientation_is_string():
+ """Test that the 'orientation' property must be a string."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["orientation"] = {}
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_orientation_cannot_be_empty():
+ """Test that 'orientation' cannot be an empty string."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["orientation"] = ""
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_orientation_valid_value():
+ """Test that 'orientation' must have a valid value."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ for key in validator.webapp.ORIENTATION_KEYS:
+ data["orientation"] = key
+ _detect(err, data)
+ assert not err.failed(), "'orientation' sadly failed for %r" % key
+
+
+def test_webapp_orientation_bad_value():
+ """Test that 'orientation' cannot have an invalid value."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["orientation"] = "fart"
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_orientation_empty_value():
+ """Test that 'orientation' cannot have an empty value."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["orientation"] = ""
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_fullscreen_missing():
+ """Test that the 'fullscreen' property can be absent."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ del data["fullscreen"]
+ _detect(err, data)
+ assert not err.failed()
+
+
+def test_webapp_fullscreen_is_string():
+ """Test that the 'fullscreen' property must be a string."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["fullscreen"] = {}
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_fullscreen_cannot_be_empty():
+ """Test that 'fullscreen' cannot be an empty string."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["fullscreen"] = ""
+ _detect(err, data)
+ assert err.failed()
+
+
+def test_webapp_fullscreen_valid_value():
+ """Test that 'fullscreen' must have a valid value."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ for key in ("true", "false"):
+ data["fullscreen"] = key
+ _detect(err, data)
+ assert not err.failed(), "'orientation' sadly failed for %r" % key
+
+
+def test_webapp_fullscreen_bad_value():
+ """Test that 'fullscreen' cannot have an invalid value."""
+
+ err = ErrorBundle(listed=False)
+ data = _get_json()
+ data["fullscreen"] = "fart"
+ _detect(err, data)
+ assert err.failed()
View
81 validator/webapp.py
@@ -12,10 +12,15 @@
# TODO: `widget` is deprecated but we should eventually make it invalid.
VALID_KEYS = set(["name", "description", "launch_path", "icons", "developer",
"locales", "default_locale", "installs_allowed_from",
- "version", "widget", "services", "experimental"])
+ "version", "widget", "services", "experimental",
+ "screen_size", "required_features", "orientation",
+ "fullscreen"])
INVALID_LOCALE_KEYS = set(["locales", "default_locale",
"installs_allowed_from", ])
DEVELOPER_KEYS = set(["name", "url", ])
+SCREEN_SIZE_KEYS = set(["min_width", "min_height"])
+ORIENTATION_KEYS = set(["portrait", "landscape", "portrait-secondary",
+ "landscape-secondary"])
def _test_url(url, can_be_asterisk=False):
@@ -138,7 +143,7 @@ def test_webapp(err, webapp, current_valid_keys, required=True):
elif key == "icons":
if not isinstance(webapp[key], dict):
err.error(
- err_id=("webapp", "detect", "icons_not_list"),
+ err_id=("webapp", "detect", "icons_not_dict"),
error="'icons' property not an object.",
description="The 'icons' property is not an object, "
"though it should be.")
@@ -148,7 +153,7 @@ def test_webapp(err, webapp, current_valid_keys, required=True):
if not size.isdigit():
err.error(
err_id=("webapp", "detect", "size_not_num"),
- error="Icon size not number.",
+ error="Icon size is not a number.",
description=["Icon sizes (keys) must be natural "
"numbers.",
"Invalid size: %s" % size])
@@ -226,3 +231,73 @@ def test_webapp(err, webapp, current_valid_keys, required=True):
warning="'developer' property is deprecated.",
description=["The 'developer' property is deprecated and is "
"no longer supported."])
+ elif key == "screen_size":
+ if not isinstance(webapp[key], dict):
+ err.error(
+ err_id=("webapp", "detect", "screen_size_dict"),
+ error="'screen_size' property is not an object.",
+ description="The 'screen_size' property must be an "
+ "object.")
+ continue
+
+ keys = set(webapp[key].keys())
+ extra_keys = keys - SCREEN_SIZE_KEYS
+ if extra_keys:
+ err.warning(
+ err_id=("webapp", "detect", "extra_screen_size"),
+ warning="Extra keys in 'screen_size'.",
+ description=["The 'screen_size' key contains extra keys "
+ "that could not be identified.",
+ "Extra keys: %s" % ", ".join(extra_keys)])
+
+ for field, size in webapp[key].iteritems():
+ if not size.isdigit():
+ err.error(
+ err_id=("webapp", "detect", "screen_size_not_num"),
+ error="Screen size %r is not a number." % field,
+ description=["Icon sizes (keys) must be natural "
+ "numbers.",
+ "Invalid size: %s" % size])
+
+ if not any([s in keys for s in SCREEN_SIZE_KEYS]) and required:
+ err.error(
+ err_id=("webapp", "detect", "absent_screen_size"),
+ error="Missing 'min_width' or 'min_height' in "
+ "'screen_size'.",
+ description=["The 'screen_size' key must contain at least "
+ "one value: 'min_width' or 'min_height'"])
+ elif key == "required_features":
+ if not isinstance(webapp[key], list):
+ err.error(
+ err_id=("webapp", "detect", "required_features_list"),
+ error="'required_features' property is not a list.",
+ description="The values of 'required_features' must be "
+ "an array of values.")
+ continue
+ elif key == "orientation":
+ if not isinstance(webapp[key], basestring):
+ err.error(
+ err_id=("webapp", "detect", "orientation_string"),
+ error="'orientation' property is not a string.",
+ description="The value of 'orientation' must be a string.")
+ continue
+ if webapp[key] not in ORIENTATION_KEYS and required:
+ err.error(
+ err_id=("webapp", "detect", "extra_orientation"),
+ error="Invalid value for 'orientation'.",
+ description=["The value for the 'orientation' key "
+ "contains incorrect values. ",
+ "Acceptable values: %s" %
+ ", ".join(ORIENTATION_KEYS)])
+ elif key == "fullscreen":
+ if not isinstance(webapp[key], basestring):
+ err.error(
+ err_id=("webapp", "detect", "fullscreen_string"),
+ error="'fullscreen' property is not a list.",
+ description="The value of 'fullscreen' must be a string.")
+ continue
+ if webapp[key] not in ("true", "false"):
+ err.error(
+ err_id=("webapp", "detect", "fullscreen_boolean"),
+ error="'fullscreen' property is not a boolean.",
+ description="The value of 'fullscreen' must be a boolean.")
Please sign in to comment.
Something went wrong with that request. Please try again.