~nskaggs/help-app/functional-test-template

« back to all changes in this revision

Viewing changes to internals/tests/test_links.py

  • Committer: Daniel Holbach
  • Date: 2015-05-13 09:27:57 UTC
  • mto: This revision was merged to the branch mainline in revision 135.
  • Revision ID: daniel.holbach@canonical.com-20150513092757-vh6ekrve7rc8pjel
simplify code in link checking somewhat, this will allow us to add more tests to check links, add more atomic tests test_simple_local_broken_link, test_simple_local_working_link, test_non_existing_build

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
)
14
14
 
15
15
 
16
 
def require_build(build):
17
 
    tempdir = tempfile.mkdtemp()
18
 
    env = {}
19
 
    if build == 'app':
20
 
        env = {'OUTPUTDIR_APP': tempdir}
21
 
    if build == 'web':
22
 
        env = {'OUTPUTDIR_WEB': tempdir}
23
 
    pwd = use_top_level_dir()
24
 
    ret = subprocess.call(['make', '-es', build], env=env)
25
 
    os.chdir(pwd)
26
 
    return (ret, tempdir)
 
16
class BuildRunner():
 
17
    def __init__(self, build):
 
18
        self.tempdir = tempfile.mkdtemp()
 
19
        self.env = {}
 
20
        self.build = build
 
21
        self.html_files = []
 
22
        self.rc = None
 
23
        if self.build == 'app':
 
24
            self.env = {'OUTPUTDIR_APP': self.tempdir}
 
25
        if self.build == 'web':
 
26
            self.env = {'OUTPUTDIR_WEB': self.tempdir}
 
27
        self.run_build()
 
28
        self.find_html_files()
 
29
 
 
30
    def run_build(self):
 
31
        pwd = use_top_level_dir()
 
32
        self.rc = subprocess.call(['make', '-es', self.build], env=self.env)
 
33
        os.chdir(pwd)
 
34
 
 
35
    def find_html_files(self):
 
36
        for dirpath, dirnames, filenames in os.walk(self.tempdir):
 
37
            self.html_files.extend([os.path.join(dirpath, fn)
 
38
                                    for fn in filenames
 
39
                                    if fn.endswith('.html')])
 
40
 
 
41
    def __del__(self):
 
42
        clean_tempdir(self.tempdir)
27
43
 
28
44
 
29
45
def clean_tempdir(tempdir):
41
57
                   link_is_local(value):
42
58
                    self.links += [value]
43
59
 
44
 
    def reload(self):
45
 
        links = self.links
 
60
    def feed(self, data):
46
61
        self.links = []
47
 
        return links
 
62
        super(MyHTMLParser, self).feed(data)
 
63
 
 
64
 
 
65
class HTMLLinkChecker():
 
66
    def __init__(self):
 
67
        self.local_link_results = []
 
68
        self.htmlparser = MyHTMLParser()
 
69
 
 
70
    def check_local_links(self, html_files):
 
71
        self.local_link_results = []
 
72
        for fn in html_files:
 
73
            html = codecs.open(fn, encoding='utf-8').read()
 
74
            self.local_link_results = \
 
75
                self._verify_local_links_in_html(fn, html)
 
76
 
 
77
    def _verify_local_links_in_html(self, filename, html):
 
78
        results = []
 
79
        self.htmlparser.feed(html)
 
80
        pwd = os.getcwd()
 
81
        for link in self.htmlparser.links:
 
82
            os.chdir(os.path.dirname(filename))
 
83
            full_link_fn = os.path.join(os.path.dirname(filename), link)
 
84
            rel_path = os.path.relpath(full_link_fn, filename)
 
85
            path = os.path.normpath(os.path.join(filename, rel_path))
 
86
            results += [os.path.exists(path)]
 
87
        os.chdir(pwd)
 
88
        return results
48
89
 
49
90
 
50
91
class HelpTestCase(TestCase):
51
92
    def __init__(self, *args):
52
93
        self.pwd = os.getcwd()
53
 
        self.htmlparser = MyHTMLParser()
 
94
        self.build_runner = None
54
95
        TestCase.__init__(self, *args)
 
96
        self.html_link_checker = HTMLLinkChecker()
55
97
 
56
98
    def __del__(self):
57
99
        os.chdir(self.pwd)
58
100
 
 
101
    def _require_build(self, build):
 
102
        if self.build_runner is None or \
 
103
           self.build_runner.build != build:
 
104
            self.build_runner = BuildRunner(build)
 
105
 
59
106
    def _test_local_links(self, build):
60
 
        (ret, tempdir) = require_build(build)
61
 
        self.assertEqual(ret, 0)
62
 
        for dirpath, dirnames, filenames in os.walk(tempdir):
63
 
            for fn in filenames:
64
 
                full_fn = os.path.join(dirpath, fn)
65
 
                os.chdir(dirpath)
66
 
                if full_fn.endswith('.html'):
67
 
                    html = codecs.open(full_fn, encoding='utf-8').read()
68
 
                    self.htmlparser.feed(html)
69
 
                links = self.htmlparser.reload()
70
 
                for link in links:
71
 
                    rel_path = os.path.relpath(link, full_fn)
72
 
                    path = os.path.normpath(os.path.join(full_fn, rel_path))
73
 
                    self.assertTrue(os.path.exists(path))
74
 
        clean_tempdir(tempdir)
75
 
        return True
76
 
 
77
 
    def test_local_phone_links(self):
78
 
        return self._test_local_links('html')
79
 
 
80
 
    def test_local_web_links(self):
81
 
        return self._test_local_links('web')
 
107
        self._require_build(build)
 
108
        self.html_link_checker.check_local_links(self.build_runner.html_files)
 
109
 
 
110
    def test_simple_local_broken_link(self):
 
111
        dirname = tempfile.mkdtemp()
 
112
        filename = os.path.join(dirname, 'first-test.html')
 
113
        with open(filename, 'w') as f:
 
114
            f.write('<html><body>' +
 
115
                    '<a href="nonexisting-test.html">broken test link</a>' +
 
116
                    '</body><html>')
 
117
        self.html_link_checker.check_local_links([filename])
 
118
        self.assertNotIn(True, self.html_link_checker.local_link_results)
 
119
        clean_tempdir(dirname)
 
120
 
 
121
    def test_simple_local_working_link(self):
 
122
        html = '<html><body>' + \
 
123
               '<a href="second-test.html">broken test link</a>' + \
 
124
               '</body><html>'
 
125
        dirname = tempfile.mkdtemp()
 
126
        filename1 = os.path.join(dirname, 'first-test.html')
 
127
        with open(filename1, 'w') as f:
 
128
            f.write(html)
 
129
        filename2 = os.path.join(dirname, 'second-test.html')
 
130
        with open(filename2, 'w') as f:
 
131
            f.write(html)
 
132
        self.html_link_checker.check_local_links([filename1])
 
133
        self.assertEqual([True], self.html_link_checker.local_link_results)
 
134
        clean_tempdir(dirname)
 
135
 
 
136
    def test_non_existing_build(self):
 
137
        self._require_build('not-existing')
 
138
        self.assertNotEqual(self.build_runner.rc, 0)
 
139
 
 
140
    def test_local_links_in_phone_build(self):
 
141
        self._test_local_links('app')
 
142
        self.assertEqual(self.build_runner.rc, 0)
 
143
        self.assertNotEqual(self.build_runner.html_files, [])
 
144
        self.assertNotIn(False, self.html_link_checker.local_link_results)
 
145
 
 
146
    def test_local_links_in_web_build(self):
 
147
        self._test_local_links('web')
 
148
        self.assertEqual(self.build_runner.rc, 0)
 
149
        self.assertNotEqual(self.build_runner.html_files, [])
 
150
        self.assertNotIn(False, self.html_link_checker.local_link_results)