# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from parameterized import parameterized
import unittest
import xml.dom.minidom
import actions_model
PRETTY_XML = """
<actions>
<action name="Action1">
<owner>[email protected]</owner>
<description>Description1</description>
</action>
<action name="Action2" not_user_triggered="true">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<description>Description2</description>
</action>
<action name="Action3">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<owner>[email protected]</owner>
<description>Description3</description>
</action>
<action-suffix separator="." ordering="suffix">
<suffix name="AppMenu" label="Users opened a new incognito tab by app menu"/>
<suffix name="LongTapMenu"
label="Users opened a new incognito tab by long tap menu"/>
</action-suffix>
<action-suffix separator="." ordering="suffix">
<suffix name="LongTapMenu" label="Users closed a tab by long tap menu"/>
<affected-action name="AnAction"/>
<affected-action name="MobileMenuCloseTab"/>
</action-suffix>
</actions>
""".strip()
XML_WITH_WRONG_INDENT = """
<actions>
<action name="Action1">
<owner>[email protected]</owner>
<description>Description1</description>
</action>
<action name="Action2" not_user_triggered="true">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<description>Description2</description>
</action>
<action name="Action3">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<owner>[email protected]</owner>
<description>Description3</description>
</action>
<action-suffix separator="." ordering="suffix">
<suffix name="AppMenu" label="Users opened a new incognito tab by app menu"/>
<suffix name="LongTapMenu"
label="Users opened a new incognito tab by long tap menu"/>
</action-suffix>
<action-suffix separator="." ordering="suffix">
<suffix name="LongTapMenu" label="Users closed a tab by long tap menu"/>
<affected-action name="AnAction"/>
<affected-action name="MobileMenuCloseTab"/>
</action-suffix>
</actions>
""".strip()
XML_WITH_WRONG_SINGLELINE = """
<actions>
<action name="Action1">
<owner>
[email protected]
</owner>
<description>Description1</description>
</action>
<action name="Action2" not_user_triggered="true">
<obsolete>
Obsolete text
</obsolete>
<owner>[email protected]</owner>
<description>Description2</description>
</action>
<action name="Action3">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<owner>[email protected]</owner>
<description>
Description3
</description>
</action>
<action-suffix separator="." ordering="suffix">
<suffix name="AppMenu" label="Users opened a new incognito tab by app menu"/>
<suffix name="LongTapMenu"
label="Users opened a new incognito tab by long tap menu"/>
</action-suffix>
<action-suffix separator="." ordering="suffix">
<suffix name="LongTapMenu" label="Users closed a tab by long tap menu"/>
<affected-action name="AnAction"/>
<affected-action name="MobileMenuCloseTab"/>
</action-suffix>
</actions>
""".strip()
XML_WITH_WRONG_LINE_BREAK = """
<actions>
<action name="Action1">
<owner>[email protected]</owner>
<description>Description1</description>
</action>
<action name="Action2" not_user_triggered="true">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<description>Description2</description>
</action>
<action name="Action3">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<owner>[email protected]</owner>
<description>Description3</description>
</action>
<action-suffix separator="." ordering="suffix">
<suffix name="AppMenu" label="Users opened a new incognito tab by app menu"/>
<suffix name="LongTapMenu"
label="Users opened a new incognito tab by long tap menu"/>
</action-suffix>
<action-suffix separator="." ordering="suffix">
<suffix name="LongTapMenu"
label="Users closed a tab by long tap menu"/>
<affected-action name="AnAction"/>
<affected-action name="MobileMenuCloseTab"/>
</action-suffix>
</actions>
""".strip()
XML_WITH_WRONG_ORDER = """
<actions>
<action name="Action2" not_user_triggered="true">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<description>Description2</description>
</action>
<action name="Action1">
<owner>[email protected]</owner>
<description>Description1</description>
</action>
<action name="Action3">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<owner>[email protected]</owner>
<description>Description3</description>
</action>
<action-suffix separator="." ordering="suffix">
<suffix name="LongTapMenu"
label="Users opened a new incognito tab by long tap menu"/>
<suffix name="AppMenu" label="Users opened a new incognito tab by app menu"/>
</action-suffix>
<action-suffix separator="." ordering="suffix">
<suffix name="LongTapMenu" label="Users closed a tab by long tap menu"/>
<affected-action name="MobileMenuCloseTab"/>
<affected-action name="AnAction"/>
</action-suffix>
</actions>
""".strip()
XML_WITH_WRONG_CHILDREN_ORDER = """
<actions>
<action name="Action1">
<description>Description1</description>
<owner>[email protected]</owner>
</action>
<action name="Action2" not_user_triggered="true">
<owner>[email protected]</owner>
<obsolete>Obsolete text</obsolete>
<description>Description2</description>
</action>
<action name="Action3">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<description>Description3</description>
<owner>[email protected]</owner>
</action>
<action-suffix separator="." ordering="suffix">
<suffix name="AppMenu" label="Users opened a new incognito tab by app menu"/>
<suffix name="LongTapMenu"
label="Users opened a new incognito tab by long tap menu"/>
</action-suffix>
<action-suffix separator="." ordering="suffix">
<affected-action name="AnAction"/>
<affected-action name="MobileMenuCloseTab"/>
<suffix name="LongTapMenu" label="Users closed a tab by long tap menu"/>
</action-suffix>
</actions>
""".strip()
XML_WITH_WRONG_ATTRIBUTE_ORDER = """
<actions>
<action name="Action1">
<owner>[email protected]</owner>
<description>Description1</description>
</action>
<action not_user_triggered="true" name="Action2">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<description>Description2</description>
</action>
<action name="Action3">
<obsolete>Obsolete text</obsolete>
<owner>[email protected]</owner>
<owner>[email protected]</owner>
<description>Description3</description>
</action>
<action-suffix ordering="suffix" separator=".">
<suffix name="AppMenu" label="Users opened a new incognito tab by app menu"/>
<suffix name="LongTapMenu"
label="Users opened a new incognito tab by long tap menu"/>
</action-suffix>
<action-suffix separator="." ordering="suffix">
<suffix label="Users closed a tab by long tap menu" name="LongTapMenu"/>
<affected-action name="AnAction"/>
<affected-action name="MobileMenuCloseTab"/>
</action-suffix>
</actions>
""".strip()
class ActionXmlTest(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(ActionXmlTest, self).__init__(*args, **kwargs)
self.maxDiff = None
@parameterized.expand([
# Test prettify already pretty XML to verify the pretty-printed version
# is the same.
('AlreadyPrettyXml', PRETTY_XML, PRETTY_XML),
('Indent', XML_WITH_WRONG_INDENT, PRETTY_XML),
('SingleLine', XML_WITH_WRONG_SINGLELINE, PRETTY_XML),
('LineBreak', XML_WITH_WRONG_LINE_BREAK, PRETTY_XML),
('Order', XML_WITH_WRONG_ORDER, PRETTY_XML),
# The children of <action> should be sorted in the order of <obsolete>,
# <owner> and <description>
('ChildrenOrder', XML_WITH_WRONG_CHILDREN_ORDER, PRETTY_XML),
])
def testPrettify(self, _, input_xml, expected_xml):
result = actions_model.PrettifyTree(xml.dom.minidom.parseString(input_xml))
self.assertMultiLineEqual(result.strip(), expected_xml)
@parameterized.expand([
('BadAttributeBoolean', PRETTY_XML, 'true', 'hello', 'hello'),
('BadSuffixNameWithSpace', PRETTY_XML, 'AppMenu', 'App Menu', 'App Menu'),
('BadAffectedActionNameWithSpace', PRETTY_XML, 'AnAction', 'An Action',
'An Action'),
('SuffixWithBadSeparator', PRETTY_XML, '.', '-', '-'),
('BadOrdering_IllegalWord', PRETTY_XML, 'ordering="suffix"',
'ordering="hello"', 'hello'),
])
def testRegex(self, _, pretty_input_xml, original_string, bad_string,
error_string):
BAD_XML = pretty_input_xml.replace(original_string, bad_string)
with self.assertRaises(ValueError) as context:
actions_model.PrettifyTree(xml.dom.minidom.parseString(BAD_XML))
self.assertIn(error_string, str(context.exception))
self.assertIn('does not match regex', str(context.exception))
if __name__ == '__main__':
unittest.main()