Esempio n. 1
0
    def test_valid_map_html_color_name_fragments(self):
        """ Confirm that an otherwise-valid map
            that uses HTML color names in the globals instead of hex values
            will still be accepted
        """

        # Truncated from an assortment of actual failed maps from the logs
        metro_maps = [
            json.dumps({
                "50": {},
                "51": {
                    "190": {
                        "line": "008800",
                        "station": {
                            "name": "Cloverdale",
                            "orientation": "180",
                            "lines": ["reen"]
                        }
                    }
                },
                "global": {
                    "lines": {
                        "002366": {
                            "displayName": "Line 3 Ontario"
                        },
                        "f81894": {
                            "displayName": "Line 7 Jane"
                        },
                        "reen": {
                            "displayName": "Line 2 Bloor-Danforth"
                        },
                        "ellow": {
                            "displayName": "Line 1 Yonge-University"
                        },
                        "urple": {
                            "displayName": "Line 4 Sheppard"
                        },
                        "range": {
                            "displayName": "Line 5 Eglinton"
                        },
                        "rey": {
                            "displayName": "Line 6 Finch West"
                        },
                        "urquoi": {
                            "displayName": "Line 8 Don Mills"
                        }
                    }
                }
            }),
        ]

        for metro_map in metro_maps:
            validate_metro_map(metro_map)
            response = self._post_metromap(metro_map).strip()
            # 73 = 8 character urlhash + comma + 64 char naming token
            self.assertTrue(len(response), 73)
Esempio n. 2
0
 def test_invalid_station_name_too_short(self):
     """ Reject a map with a station name that is too short (no characters)
         Now that we are gracefully renaming any station of zero length, we expect this to no longer raise the assertion
     """
     with self.assertRaisesRegex(
             AssertionError,
             "\[VALIDATIONFAILED\] 12 station name at \(1, 1\) BAD SIZE  is 0: Point at \(2, 2\) has a station whose name is not between 1 and 255 characters long. Please rename it."
     ) as assertion:
         metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "000000", "station": {"name": ""} } } }'
         validate_metro_map(metro_map)
Esempio n. 3
0
    def test_invalid_station_line_not_valid(self):
        """ Reject a map with a station line that is not in the global
            (Graceful failure; does not raise an assertion)
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 17 station_line ffffff NOT IN valid_lines: Station rail line color ffffff is not defined; please create a rail line matching this color or remove it from all stations."
        ) as assertion:
            metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "000000", "station": {"name": "OK", "lines": ["ffffff"]} } } }'
            validate_metro_map(metro_map)
Esempio n. 4
0
    def test_invalid_station_line_not_hex(self):
        """ Reject a map with a station line that is not hex
        """
        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 15 station_line not hex FAILED is_hex\(\): Station Rail line not hex is not a valid color."
        ) as assertion:
            metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "000000", "station": {"name": "OK", "lines": ["not hex"]} } } }'
            validate_metro_map(metro_map)

        self.assertIn("Station Rail line not hex is not a valid color.",
                      self._post_metromap(metro_map))
Esempio n. 5
0
    def test_invalid_map_not_dict(self):
        """ Reject a map that is malformed (not a dictionary)
        """
        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 01 metro_map IS NOT DICT: Bad map object, needs to be an object."
        ) as assertion:
            metro_map = '["mapdata", "needs to be a dict"]'
            validate_metro_map(metro_map)

        self.assertIn("Bad map object, needs to be an object.",
                      self._post_metromap(metro_map))
Esempio n. 6
0
    def test_invalid_map_no_global(self):
        """ Reject a map that has no global key at the root level
        """
        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 02 metro_map DOES NOT HAVE GLOBAL: Bad map object, missing global."
        ) as assertion:
            metro_map = '{"it is a dict": "but has no global"}'
            validate_metro_map(metro_map)

        self.assertIn("Bad map object, missing global.",
                      self._post_metromap(metro_map))
Esempio n. 7
0
    def test_invalid_point_line_not_valid(self):
        """ Reject a map that has a color at a coordinate
                that is not listed in the global
            (Graceful failure; does not raise an assertion)
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 10 ffffff at \(1, 1\) NOT IN valid_lines: Point at \(2, 2\) has a color that is not defined in the rail lines; please create a line matching the color ffffff."
        ) as assertion:
            metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "ffffff"} } }'
            validate_metro_map(metro_map)
Esempio n. 8
0
    def test_graceful_failure_map_no_lines(self):
        """ Approve a map that has no rail lines in the global dictionary
            but does have these lines in the map data itself
        """

        metro_map = '{"40":{"54":{"line":"0896d7","station":{"name":"Tunnford","lines":["0896d7"]}},"55":{"line":"0896d7"},"56":{"line":"0896d7"},"57":{"line":"0896d7"},"58":{"line":"0896d7","station":{"name":"Slarnton","lines":["0896d7"]}},"59":{"line":"0896d7"},"60":{"line":"0896d7"},"61":{"line":"0896d7"},"62":{"line":"0896d7"},"63":{"line":"0896d7"},"64":{"line":"0896d7","station":{"name":"Rondington","lines":["0896d7"]}},"65":{"line":"0896d7"},"66":{"line":"0896d7"},"67":{"line":"0896d7"},"68":{"line":"0896d7"},"69":{"line":"0896d7","station":{"name":"Tardston","lines":["0896d7"]}},"70":{"line":"0896d7"},"71":{"line":"0896d7","station":{"name":"Tardston_Woods","lines":["0896d7"]}}},"global":{"lines":{}}}'
        validate_metro_map(metro_map)

        response = self._post_metromap(metro_map)
        urlhash, naming_token = response.split(',')
        self.assertEqual(len(urlhash.strip()), 8)
        self.assertEqual(len(naming_token.strip()), 64)
Esempio n. 9
0
    def test_invalid_global_line_not_hex(self):
        """ Reject a map that has a non-hex color in the global lines
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 05 global_line qwerty FAILED is_hex\(\) qwerty is not a valid color: qwerty is not a valid rail line color."
        ) as assertion:
            metro_map = '{"global": {"lines": {"qwerty": {"displayName": "non-hex rail line"} } } }'
            validate_metro_map(metro_map)

        self.assertIn("qwerty is not a valid rail line color.",
                      self._post_metromap(metro_map))
Esempio n. 10
0
    def test_invalid_map_no_lines(self):
        """ Reject a map that has no rail lines in the global dictionary
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 03 metro_map DOES NOT HAVE LINES: Map does not have any rail lines defined."
        ) as assertion:
            metro_map = '{"global": {"I have global but": "I dont have any lines"} }'
            validate_metro_map(metro_map)

        self.assertIn("Map does not have any rail lines defined.",
                      self._post_metromap(metro_map))
Esempio n. 11
0
    def test_invalid_station_lines_not_list(self):
        """ Reject a map with station lines that are not a list
        """
        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 13 station lines at \(1, 1\) NOT A LIST: Point at \(2, 2\) has its station lines in the incorrect format; must be a list."
        ) as assertion:
            metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "000000", "station": {"name": "OK", "lines": "000000"} } } }'
            validate_metro_map(metro_map)

        self.assertIn(
            "Point at (2, 2) has its station lines in the incorrect format; must be a list.",
            self._post_metromap(metro_map))
Esempio n. 12
0
    def test_invalid_station_line_not_six(self):
        """ Reject a map with a station line that is not a color six characters long
        """
        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 16 station_line beef IS NOT 6 CHARACTERS: Station Rail line color beef needs to be 6 characters long."
        ) as assertion:
            metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "000000", "station": {"name": "OK", "lines": ["beef"]} } } }'
            validate_metro_map(metro_map)

        self.assertIn(
            "Station Rail line color beef needs to be 6 characters long.",
            self._post_metromap(metro_map))
Esempio n. 13
0
    def test_invalid_station_not_dict(self):
        """ Reject a map with a station that is not a dict
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 11 metro_map\[x\]\[y\]\['station'\] at \(1, 1\) IS NOT DICT: Point at \(2, 2\) has a malformed station, must be an object."
        ) as assertion:
            metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "000000", "station": "bad station"} } }'
            validate_metro_map(metro_map)

        self.assertIn(
            "Point at (2, 2) has a malformed station, must be an object.",
            self._post_metromap(metro_map))
Esempio n. 14
0
    def test_invalid_global_line_wrong_size(self):
        """ Reject a map that has a color in the global lines
                that is not exactly six characters
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 06 global_line beef IS NOT 6 CHARACTERS: The color beef must be 6 characters long."
        ) as assertion:
            metro_map = '{"global": {"lines": {"beef": {"problem": "color code not six chars"} } } }'
            validate_metro_map(metro_map)

        self.assertIn("The color beef must be 6 characters long.",
                      self._post_metromap(metro_map))
Esempio n. 15
0
    def test_invalid_point_line_not_hex(self):
        """ Reject a map that has a non-hex color at a coordinate.
            Coordinates are displayed to the end user 1-indexed.
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 08 nonhex at \(1, 1\) FAILED is_hex\(\): Point at \(2, 2\) is not a valid color: nonhex."
        ) as assertion:
            metro_map = '{"global": { "lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "nonhex"} } }'
            validate_metro_map(metro_map)

        self.assertIn("Point at (2, 2) is not a valid color  nonhex.",
                      self._post_metromap(metro_map))
Esempio n. 16
0
    def test_invalid_map_lines_not_dict(self):
        """ Reject a map that has the global dictionary at the root
            but the lines does not contain a dictionary
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 04 metro_map LINES IS NOT DICT: Map lines must be stored as an object."
        ) as assertion:
            metro_map = '{"global": {"lines": ["this should be a dict, not a list"]} }'
            validate_metro_map(metro_map)

        self.assertIn("Map lines must be stored as an object.",
                      self._post_metromap(metro_map))
Esempio n. 17
0
    def test_invalid_global_line_display_too_short(self):
        """ Reject a map that has a color in the global lines
                whose display name is zero characters long
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 07 displayName BAD SIZE: Rail line names must be between 1 and 255 characters long \(spaces are okay\)."
        ):
            metro_map = '{"global" : {"lines": {"000000": {"displayName": ""} } } }'
            validate_metro_map(metro_map)

        self.assertIn(
            "Rail line names must be between 1 and 255 characters long (spaces are okay).",
            self._post_metromap(metro_map))
Esempio n. 18
0
    def test_invalid_station_name_too_long(self):
        """ Reject a map with a station name that is too long (> 255 characters)
        """
        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 12 station name at \(1, 1\) BAD SIZE a{256} is 256: Point at \(2, 2\) has a station whose name is not between 1 and 255 characters long. Please rename it."
        ) as assertion:
            station_name_too_long = "a" * 256
            metro_map = '{{"global": {{"lines": {{"000000": {{"displayName": "Black Line"}} }} }}, "1": {{"1": {{"line": "000000", "station": {{"name": "{0}"}} }} }} }}'.format(
                station_name_too_long)
            validate_metro_map(metro_map)

        self.assertIn(
            "Point at (2, 2) has a station whose name is not between 1 and 255 characters long. Please rename it.",
            self._post_metromap(metro_map))
Esempio n. 19
0
    def test_invalid_point_line_not_six(self):
        """ Reject a map that has a color at a coordinate
                that is not six characters long.
        """

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 09 beef at \(1, 1\) IS NOT 6 CHARACTERS: Point at \(2, 2\) has a color that needs to be 6 characters long: beef"
        ) as assertion:
            metro_map = '{"global": {"lines": {"000000": {"displayName": "Black Line"} } }, "1": {"1": {"line": "beef"} } }'
            validate_metro_map(metro_map)

        self.assertIn(
            "Point at (2, 2) has a color that needs to be 6 characters long  beef",
            self._post_metromap(metro_map))
Esempio n. 20
0
    def test_global_line_display_removes_backslash_special_chars(self):
        """ Confirm that saving a rail line that somehow had a tab, backspace, or newline in its name will replace that with a space
        """

        metro_map = '{"global": {"lines": {"000000": {"displayName": "Tab\\t\\b\\nCentral"} } } }'
        metro_map = validate_metro_map(metro_map)
        self.assertNotIn('\\t', metro_map)
        self.assertNotIn('\\b', metro_map)
        self.assertNotIn('\\n', metro_map)
        self.assertEqual('Tab   Central',
                         metro_map["global"]["lines"]["000000"]["displayName"])
Esempio n. 21
0
    def test_invalid_toomanylines(self):
        """ Reject a map that has too many lines (Validation #04B: <= 100 lines)
        """

        too_many_lines = {}
        for line in range(101):
            too_many_lines.update(**{str(line): {"displayName": line}})
        self.assertEqual(len(too_many_lines), 101)

        with self.assertRaisesRegex(
                AssertionError,
                "\[VALIDATIONFAILED\] 04B metro_map HAS TOO MANY LINES: Map has too many lines \(limit is 100\); remove unused lines."
        ) as assertion:
            metro_map = '{{"global": {{"lines": {0} }} }}'.format(
                too_many_lines)
            metro_map = metro_map.replace("'", '"')
            validate_metro_map(metro_map)

        self.assertIn(
            "Map has too many lines (limit is 100); remove unused lines.",
            self._post_metromap(metro_map))
Esempio n. 22
0
    def test_validator(self):
        """ Ensure that all maps already saved will pass the validation
              as written in validate_metro_map()
            That way, I'll know any changes to validate_metro_map() have
              at least been tested on a large number of real, existing maps.
        """

        saved_maps = SavedMap.objects.all()
        for saved_map in saved_maps:
            # Ensure that the maps already saved will not be malformed by the validation
            saved_map_data = dict(
                json.loads(
                    str(
                        json.loads(
                            json.dumps(
                                saved_map.mapdata.replace(" u'", "'").replace(
                                    "{u'", "{'").replace(
                                        "[u'", "['").replace("'", '"').replace(
                                            "\\",
                                            "").strip('"').strip("'"))))))

            try:
                validated_map = validate_metro_map(
                    str(
                        json.loads(
                            json.dumps(
                                saved_map.mapdata.replace(" u'", "'").replace(
                                    "{u'", "{'").replace("[u'", "['").replace(
                                        "'", '"').replace(
                                            "\\", "").strip('"').strip("'")))))
            except AssertionError:
                print("Failed validate_metro_map for map #{0}".format(
                    saved_map.id))
                raise

            if saved_map_data != validated_map:
                # Characters like & get converted to &amp; as part of the validation process,
                #   so some maps will not be exactly equal off the bat.

                validated_map = dict(
                    json.loads(
                        json.dumps(validated_map).replace("&amp;", '&')))

                self.assertEqual(
                    saved_map_data, validated_map,
                    "saved_map.mapdata != validated version for ID: {0}:\n\n{1}\n\n{2}"
                    .format(saved_map.id, saved_map_data, validated_map))
Esempio n. 23
0
    def test_valid_map_station_lines(self):
        """ Confirm that I'm safe to remove the
            "Rail Lines this Station serves" feature
            without causing any maps to fail validation.

            Valid maps include:
            No ["station"]["lines"] at all
            ["station"]["lines"] is an empty list
            ["station"]["lines"] is a list of hex values I don't have in the globals
        """

        metro_map = json.dumps({
            "8": {
                "8": {
                    "line": "bd1038",
                    "station": {
                        "name": "Nice Station"
                    }
                }
            },
            "global": {
                "lines": {
                    "0896d7": {
                        "displayName": "Blue Line"
                    },
                    "df8600": {
                        "displayName": "Orange Line"
                    },
                    "000000": {
                        "displayName": "Logo"
                    },
                    "00b251": {
                        "displayName": "Green Line"
                    },
                    "662c90": {
                        "displayName": "Purple Line"
                    },
                    "a2a2a2": {
                        "displayName": "Silver Line"
                    },
                    "f0ce15": {
                        "displayName": "Yellow Line"
                    },
                    "bd1038": {
                        "displayName": "Red Line"
                    },
                    "79bde9": {
                        "displayName": "Rivers"
                    },
                    "cfe4a7": {
                        "displayName": "Parks"
                    }
                }
            }
        })
        validate_metro_map(metro_map)
        response = self._post_metromap(metro_map).strip()
        # 73 = 8 character urlhash + comma + 64 char naming token
        self.assertTrue(len(response), 73)

        metro_map = json.dumps({
            "8": {
                "8": {
                    "line": "bd1038",
                    "station": {
                        "name": "Nice Station",
                        "lines": []
                    }
                }
            },
            "global": {
                "lines": {
                    "0896d7": {
                        "displayName": "Blue Line"
                    },
                    "df8600": {
                        "displayName": "Orange Line"
                    },
                    "000000": {
                        "displayName": "Logo"
                    },
                    "00b251": {
                        "displayName": "Green Line"
                    },
                    "662c90": {
                        "displayName": "Purple Line"
                    },
                    "a2a2a2": {
                        "displayName": "Silver Line"
                    },
                    "f0ce15": {
                        "displayName": "Yellow Line"
                    },
                    "bd1038": {
                        "displayName": "Red Line"
                    },
                    "79bde9": {
                        "displayName": "Rivers"
                    },
                    "cfe4a7": {
                        "displayName": "Parks"
                    }
                }
            }
        })
        validate_metro_map(metro_map)
        response = self._post_metromap(metro_map).strip()
        self.assertTrue(len(response), 73)

        metro_map = json.dumps({
            "8": {
                "8": {
                    "line": "bd1038",
                    "station": {
                        "name": "Nice Station",
                        "lines": ['123456', '678909']
                    }
                }
            },
            "global": {
                "lines": {
                    "0896d7": {
                        "displayName": "Blue Line"
                    },
                    "df8600": {
                        "displayName": "Orange Line"
                    },
                    "000000": {
                        "displayName": "Logo"
                    },
                    "00b251": {
                        "displayName": "Green Line"
                    },
                    "662c90": {
                        "displayName": "Purple Line"
                    },
                    "a2a2a2": {
                        "displayName": "Silver Line"
                    },
                    "f0ce15": {
                        "displayName": "Yellow Line"
                    },
                    "bd1038": {
                        "displayName": "Red Line"
                    },
                    "79bde9": {
                        "displayName": "Rivers"
                    },
                    "cfe4a7": {
                        "displayName": "Parks"
                    }
                }
            }
        })
        validate_metro_map(metro_map)
        response = self._post_metromap(metro_map).strip()
        self.assertTrue(len(response), 73)