예제 #1
0
def validate(fname):
    """
    Check whether the contents of the specified file is valid iCalendar or vCard data.
    """

    with open(fname) as f:
        data = f.read()

    ParserContext.allRaise()

    if data.find("BEGIN:VCALENDAR") != -1:
        try:
            cal = Calendar.parseText(data)
        except ErrorBase as e:
            print("Failed to parse iCalendar: {}: {}".format(
                e.mReason,
                e.mData,
            ))
            sys.exit(1)
    elif data.find("BEGIN:VCARD") != -1:
        try:
            cal = Card.parseText(data)
        except ErrorBase as e:
            print("Failed to parse vCard: {}: {}".format(
                e.mReason,
                e.mData,
            ))
            sys.exit(1)
    else:
        print("Failed to find valid iCalendar or vCard data")
        sys.exit(1)

    _ignore_fixed, unfixed = cal.validate(doFix=False, doRaise=False)
    if unfixed:
        print("List of problems: {}".format(unfixed, ))
    else:
        print("No problems")

    # Control character check - only HTAB, CR, LF allowed for characters in the range 0x00-0x1F
    s = str(data)
    if len(
            s.translate(
                None,
                "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
            )) != len(s):
        for ctr, i in enumerate(data):
            if i in "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F":
                print("Control character {} at position {}".format(
                    ord(i),
                    ctr,
                ))
예제 #2
0
    def test_basic(self):

        data = (
            (
                "No problems",
                """BEGIN:VCARD
VERSION:3.0
N:Thompson;Default;;;
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace(
                    "\n", "\r\n"
                ),
                set(),
                set(),
            ),
            (
                "No VERSION",
                """BEGIN:VCARD
VERSION:3.0
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace(
                    "\n", "\r\n"
                ),
                set(),
                set(("[VCARD] Missing or too many required property: N",)),
            ),
        )

        for title, item, test_fixed, test_unfixed in data:
            card = Card.parseText(item)
            fixed, unfixed = card.validate(doFix=False)
            self.assertEqual(set(fixed), test_fixed, msg="Failed test: %s" % (title,))
            self.assertEqual(set(unfixed), test_unfixed, msg="Failed test: %s" % (title,))
예제 #3
0
    def test_basic(self):

        data = (
            (
                "No problems",
                """BEGIN:VCARD
VERSION:3.0
N:Thompson;Default;;;
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace("\n", "\r\n"),
                set(),
                set(),
            ),
            (
                "No VERSION",
                """BEGIN:VCARD
VERSION:3.0
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace("\n", "\r\n"),
                set(),
                set(("[VCARD] Missing or too many required property: N", )),
            ),
        )

        for title, item, test_fixed, test_unfixed in data:
            card = Card.parseText(item)
            fixed, unfixed = card.validate(doFix=False)
            self.assertEqual(set(fixed),
                             test_fixed,
                             msg="Failed test: %s" % (title, ))
            self.assertEqual(set(unfixed),
                             test_unfixed,
                             msg="Failed test: %s" % (title, ))
예제 #4
0
    def testABapp(self):

        data = """BEGIN:VCARD
VERSION:3.0
N:Card;Test;;;
FN:Test Card
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:555-1212
TEL;type=HOME:532-1234
PHOTO;BASE64:
  TU0AKgAAMAj////////////////////////////////////////////////////////////+///+
  SW1hZ2VNYWdpY2sgNS4zLjkgMTAvMDEvMDEgUToxNiBodHRwOi8vd3d3LmltYWdlbWFnaWNrLm9y
  ZwA=
CATEGORIES:My Contacts
X-ABUID:5B77BC10-E9DB-48C4-8BE1-BAB5E38E1E43\:ABPerson
UID:128ad7ee-a656-4773-95ce-f07f77e8cc23
REV:2011-03-23T20:20:04Z
END:VCARD
""".replace(
            "\n", "\r\n"
        )

        result = """BEGIN:VCARD
VERSION:3.0
UID:128ad7ee-a656-4773-95ce-f07f77e8cc23
CATEGORIES:My Contacts
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Test Card
N:Card;Test;;;
PHOTO;ENCODING=B:
 TU0AKgAAMAj////////////////////////////////////////////////////////////+
 ///+SW1hZ2VNYWdpY2sgNS4zLjkgMTAvMDEvMDEgUToxNiBodHRwOi8vd3d3LmltYWdlbWFn
 aWNrLm9yZwA=
REV:20110323T202004Z
TEL;type=WORK;type=pref:555-1212
TEL;type=HOME:532-1234
X-ABUID:5B77BC10-E9DB-48C4-8BE1-BAB5E38E1E43\:ABPerson
END:VCARD
""".replace(
            "\n", "\r\n"
        )

        card = Card.parseText(data)
        self.assertEqual(str(card), result)
예제 #5
0
    def testABapp(self):

        data = """BEGIN:VCARD
VERSION:3.0
N:Card;Test;;;
FN:Test Card
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:555-1212
TEL;type=HOME:532-1234
PHOTO;BASE64:
  TU0AKgAAMAj////////////////////////////////////////////////////////////+///+
  SW1hZ2VNYWdpY2sgNS4zLjkgMTAvMDEvMDEgUToxNiBodHRwOi8vd3d3LmltYWdlbWFnaWNrLm9y
  ZwA=
CATEGORIES:My Contacts
X-ABUID:5B77BC10-E9DB-48C4-8BE1-BAB5E38E1E43\:ABPerson
UID:128ad7ee-a656-4773-95ce-f07f77e8cc23
REV:2011-03-23T20:20:04Z
END:VCARD
""".replace("\n", "\r\n")

        result = """BEGIN:VCARD
VERSION:3.0
UID:128ad7ee-a656-4773-95ce-f07f77e8cc23
CATEGORIES:My Contacts
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Test Card
N:Card;Test;;;
PHOTO;ENCODING=B:
 TU0AKgAAMAj////////////////////////////////////////////////////////////+
 ///+SW1hZ2VNYWdpY2sgNS4zLjkgMTAvMDEvMDEgUToxNiBodHRwOi8vd3d3LmltYWdlbWFn
 aWNrLm9yZwA=
REV:20110323T202004Z
TEL;type=WORK;type=pref:555-1212
TEL;type=HOME:532-1234
X-ABUID:5B77BC10-E9DB-48C4-8BE1-BAB5E38E1E43\:ABPerson
END:VCARD
""".replace("\n", "\r\n")

        card = Card.parseText(data)
        self.assertEqual(str(card), result)
예제 #6
0
    def testParseBlank(self):

        data = (
            """
BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace(
                "\n", "\r\n"
            ),
            """

BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace(
                "\n", "\r\n"
            ),
            """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD


""".replace(
                "\n", "\r\n"
            ),
            """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]

FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace(
                "\n", "\r\n"
            ),
            """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]


FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace(
                "\n", "\r\n"
            ),
        )

        save = ParserContext.BLANK_LINES_IN_DATA
        for item in data:
            ParserContext.BLANK_LINES_IN_DATA = ParserContext.PARSER_RAISE
            self.assertRaises(InvalidData, Card.parseText, item)

            ParserContext.BLANK_LINES_IN_DATA = ParserContext.PARSER_IGNORE
            lines = item.split("\r\n")
            result = "\r\n".join([line for line in lines if line]) + "\r\n"
            self.assertEqual(str(Card.parseText(item)), result)

        ParserContext.BLANK_LINES_IN_DATA = save
예제 #7
0
    """

    with open(fname) as f:
        data = f.read()

    ParserContext.allRaise()

    if data.find("BEGIN:VCALENDAR") != -1:
        try:
            cal = Calendar.parseText(data)
        except ErrorBase, e:
            print "Failed to parse iCalendar: %r" % (e, )
            sys.exit(1)
    elif data.find("BEGIN:VCARD") != -1:
        try:
            cal = Card.parseText(data)
        except ErrorBase, e:
            print "Failed to parse vCard: %r" % (e, )
            sys.exit(1)
    else:
        print "Failed to find valid iCalendar or vCard data"
        sys.exit(1)

    _ignore_fixed, unfixed = cal.validate(doFix=False, doRaise=False)
    if unfixed:
        print "List of problems: %s" % (unfixed, )
    else:
        print "No problems"

    # Control character check - only HTAB, CR, LF allowed for characters in the range 0x00-0x1F
    s = str(data)
    def verify(self, manager, uri, response, respdata, args): #@UnusedVariable
        # Get arguments
        files = args.get("filepath", [])
        carddata = args.get("data", [])
        filters = args.get("filter", [])

        # Always remove these
        filters.append("PRODID")
        filters.append("REV")

        # status code must be 200, 201, 207
        if response.status not in (200, 201, 207):
            return False, "        HTTP Status Code Wrong: %d" % (response.status,)

        # look for response data
        if not respdata:
            return False, "        No response body"

        # look for one file
        if len(files) != 1 and len(carddata) != 1:
            return False, "        No file to compare response to"

        # read in all data from specified file or use provided data
        if len(files):
            fd = open(files[0], "r")
            try:
                try:
                    data = fd.read()
                finally:
                    fd.close()
            except:
                data = None
        else:
            data = carddata[0] if len(carddata) else None

        if data is None:
            return False, "        Could not read data file"

        data = manager.server_info.subs(data)

        def removePropertiesParameters(component):

            allProps = []
            for properties in component.getProperties().itervalues():
                allProps.extend(properties)
            for property in allProps:
                for filter in filters:
                    if ":" in filter:
                        propname, parameter = filter.split(":")
                        if property.getName() == propname:
                            if property.hasParameter(parameter):
                                property.removeParameters(parameter)
                    else:
                        if property.getName() == filter:
                            component.removeProperty(property)

        try:
            resp_adbk = Card.parseText(respdata)
            removePropertiesParameters(resp_adbk)
            respdata = resp_adbk.getText()

            data_adbk = Card.parseText(data)
            removePropertiesParameters(data_adbk)
            data = data_adbk.getText()

            result = respdata == data

            if result:
                return True, ""
            else:
                error_diff = "\n".join([line for line in unified_diff(data.split("\n"), respdata.split("\n"))])
                return False, "        Response data does not exactly match file data%s" % (error_diff,)
        except Exception, e:
            return False, "        Response data is not address data: %s" % (e,)
예제 #9
0
    def test_mode_raise(self):

        data = (
            (
                "OK",
                """BEGIN:VCARD
VERSION:3.0
N:Thompson;Default;;;
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace(
                    "\n", "\r\n"
                ),
                """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace(
                    "\n", "\r\n"
                ),
                set(),
                set(),
                False,
            ),
            (
                "Unfixable only",
                """BEGIN:VCARD
VERSION:3.0
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace(
                    "\n", "\r\n"
                ),
                """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace(
                    "\n", "\r\n"
                ),
                set(),
                set(("[VCARD] Missing or too many required property: N",)),
                True,
            ),
        )

        for title, test_old, test_new, test_fixed, test_unfixed, test_raises in data:
            card = Card.parseText(test_old)
            if test_raises:
                self.assertRaises(ValidationError, card.validate, doFix=False, doRaise=True)
            else:
                try:
                    fixed, unfixed = card.validate(doFix=False, doRaise=False)
                except:
                    self.fail(msg="Failed test: %s" % (title,))
                self.assertEqual(str(card), test_new, msg="Failed test: %s" % (title,))
                self.assertEqual(set(fixed), test_fixed, msg="Failed test: %s" % (title,))
                self.assertEqual(set(unfixed), test_unfixed, msg="Failed test: %s" % (title,))
예제 #10
0
    def testParseBlank(self):

        data = (
            """
BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace("\n", "\r\n"),
            """

BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace("\n", "\r\n"),
            """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD


""".replace("\n", "\r\n"),
            """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]

FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace("\n", "\r\n"),
            """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]


FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace("\n", "\r\n"),
        )

        save = ParserContext.BLANK_LINES_IN_DATA
        for item in data:
            ParserContext.BLANK_LINES_IN_DATA = ParserContext.PARSER_RAISE
            self.assertRaises(InvalidData, Card.parseText, item)

            ParserContext.BLANK_LINES_IN_DATA = ParserContext.PARSER_IGNORE
            lines = item.split("\r\n")
            result = "\r\n".join([line for line in lines if line]) + "\r\n"
            self.assertEqual(str(Card.parseText(item)), result)

        ParserContext.BLANK_LINES_IN_DATA = save
예제 #11
0
    """

    with open(fname) as f:
        data = f.read()

    ParserContext.allRaise()

    if data.find("BEGIN:VCALENDAR") != -1:
        try:
            cal = Calendar.parseText(data)
        except ErrorBase, e:
            print "Failed to parse iCalendar: %r" % (e,)
            sys.exit(1)
    elif data.find("BEGIN:VCARD") != -1:
        try:
            cal = Card.parseText(data)
        except ErrorBase, e:
            print "Failed to parse vCard: %r" % (e,)
            sys.exit(1)
    else:
        print "Failed to find valid iCalendar or vCard data"
        sys.exit(1)

    _ignore_fixed, unfixed = cal.validate(doFix=False, doRaise=False)
    if unfixed:
        print "List of problems: %s" % (unfixed,)
    else:
        print "No problems"

    # Control character check - only HTAB, CR, LF allowed for characters in the range 0x00-0x1F
    s = str(data)
예제 #12
0
    def test_mode_raise(self):

        data = (
            (
                "OK",
                """BEGIN:VCARD
VERSION:3.0
N:Thompson;Default;;;
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace("\n", "\r\n"),
                """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
N:Thompson;Default;;;
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace("\n", "\r\n"),
                set(),
                set(),
                False,
            ),
            (
                "Unfixable only",
                """BEGIN:VCARD
VERSION:3.0
FN:Default Thompson
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
item1.X-ABADR:us
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
END:VCARD
""".replace("\n", "\r\n"),
                """BEGIN:VCARD
VERSION:3.0
UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson
item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;U
 SA
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
FN:Default Thompson
TEL;type=WORK;type=pref:1-555-555-5555
TEL;type=CELL:1-444-444-4444
item1.X-ABADR:us
END:VCARD
""".replace("\n", "\r\n"),
                set(),
                set(("[VCARD] Missing or too many required property: N", )),
                True,
            ),
        )

        for title, test_old, test_new, test_fixed, test_unfixed, test_raises in data:
            card = Card.parseText(test_old)
            if test_raises:
                self.assertRaises(ValidationError,
                                  card.validate,
                                  doFix=False,
                                  doRaise=True)
            else:
                try:
                    fixed, unfixed = card.validate(doFix=False, doRaise=False)
                except:
                    self.fail(msg="Failed test: %s" % (title, ))
                self.assertEqual(str(card),
                                 test_new,
                                 msg="Failed test: %s" % (title, ))
                self.assertEqual(set(fixed),
                                 test_fixed,
                                 msg="Failed test: %s" % (title, ))
                self.assertEqual(set(unfixed),
                                 test_unfixed,
                                 msg="Failed test: %s" % (title, ))