~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-12 09:58:49 UTC
  • mfrom: (133 trunk)
  • mto: This revision was merged to the branch mainline in revision 135.
  • Revision ID: daniel.holbach@canonical.com-20150512095849-lyfl6iy1zvi1p48j
mergeĀ fromĀ trunk

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)
 
27
 
 
28
 
16
29
def clean_tempdir(tempdir):
17
30
    if os.path.exists(tempdir):
18
31
        shutil.rmtree(tempdir)
19
32
 
20
33
 
21
 
class BuildRunner():
22
 
    def __init__(self, build):
23
 
        self.tempdir = tempfile.mkdtemp()
24
 
        self.env = {}
25
 
        self.build = build
26
 
        self.html_files = []
27
 
        self.rc = None
28
 
        if self.build == 'app':
29
 
            self.env = {'APP_DIR': self.tempdir}
30
 
        if self.build == 'web':
31
 
            self.env = {'OUTPUTDIR_WEB': self.tempdir}
32
 
        self.pwd = use_top_level_dir()
33
 
        self.run_build()
34
 
        self.find_html_files()
35
 
 
36
 
    def run_build(self):
37
 
        self.rc = subprocess.call(['make', '-es', self.build], env=self.env)
38
 
        os.chdir(self.pwd)
39
 
 
40
 
    def find_html_files(self):
41
 
        for dirpath, dirnames, filenames in os.walk(self.tempdir):
42
 
            self.html_files.extend([os.path.join(dirpath, fn)
43
 
                                    for fn in filenames
44
 
                                    if fn.endswith('.html')])
45
 
 
46
 
    def __del__(self):
47
 
        os.chdir(self.pwd)
48
 
        clean_tempdir(self.tempdir)
49
 
 
50
 
 
51
34
class MyHTMLParser(HTMLParser):
52
35
    links = []
53
36
 
54
37
    def handle_starttag(self, tag, attrs):
55
 
        if tag == 'a':
56
 
            found = {}
 
38
        if tag == "a":
57
39
            for name, value in attrs:
58
 
                if name == 'href' and \
59
 
                   not link_is_anchor(value) and \
60
 
                   value != '/':
61
 
                    found['href'] = value
62
 
                if name == 'target':
63
 
                    found['target'] = value
64
 
            if found != {}:
65
 
                self.links += [found]
 
40
                if name == "href" and not link_is_anchor(value) and \
 
41
                   link_is_local(value):
 
42
                    self.links += [value]
66
43
 
67
 
    def feed(self, data):
 
44
    def reload(self):
 
45
        links = self.links
68
46
        self.links = []
69
 
        super(MyHTMLParser, self).feed(data)
70
 
 
71
 
 
72
 
class HTMLLinkChecker():
73
 
    def __init__(self, html_files):
74
 
        self.local_link_results = []
75
 
        self.htmlparser = MyHTMLParser()
76
 
        self.links = {}
77
 
        for fn in html_files:
78
 
            html = codecs.open(fn, encoding='utf-8').read()
79
 
            self.links[fn] = self._read_links(html)
80
 
 
81
 
    def _read_links(self, html):
82
 
        self.htmlparser.feed(html)
83
 
        return self.htmlparser.links
84
 
 
85
 
    def check_local_links(self):
86
 
        self.local_link_results = []
87
 
        pwd = os.getcwd()
88
 
        for filename in self.links:
89
 
            for link in [a['href'] for a
90
 
                         in self.links[filename]
91
 
                         if link_is_local(a['href'])]:
92
 
                os.chdir(os.path.dirname(filename))
93
 
                full_link_fn = os.path.join(os.path.dirname(filename), link)
94
 
                rel_path = os.path.relpath(full_link_fn, filename)
95
 
                path = os.path.normpath(os.path.join(filename, rel_path))
96
 
                self.local_link_results += [os.path.exists(path)]
97
 
        os.chdir(pwd)
98
 
 
99
 
    def check_external_links(self):
100
 
        self.external_link_results = []
101
 
        for filename in self.links:
102
 
            for link in [a for a
103
 
                         in self.links[filename]
104
 
                         if not link_is_local(a['href'])]:
105
 
                self.external_link_results += [('target' in link and
106
 
                                                link['target'] == '_blank')]
 
47
        return links
107
48
 
108
49
 
109
50
class HelpTestCase(TestCase):
110
51
    def __init__(self, *args):
111
52
        self.pwd = os.getcwd()
112
 
        self.build_runner = None
 
53
        self.htmlparser = MyHTMLParser()
113
54
        TestCase.__init__(self, *args)
114
 
        self.html_link_checker = None
115
55
 
116
56
    def __del__(self):
117
57
        os.chdir(self.pwd)
118
58
 
119
 
    def _require_build(self, build):
120
 
        if self.build_runner is None or \
121
 
           self.build_runner.build != build:
122
 
            self.build_runner = BuildRunner(build)
123
 
 
124
59
    def _test_local_links(self, build):
125
 
        self._require_build(build)
126
 
        self.html_link_checker = HTMLLinkChecker(self.build_runner.html_files)
127
 
        self.html_link_checker.check_local_links()
128
 
 
129
 
    def _test_external_links(self, build):
130
 
        self._require_build(build)
131
 
        self.html_link_checker = HTMLLinkChecker(self.build_runner.html_files)
132
 
        self.html_link_checker.check_external_links()
133
 
 
134
 
    def test_simple_local_broken_link(self):
135
 
        dirname = tempfile.mkdtemp()
136
 
        filename = os.path.join(dirname, 'first-test.html')
137
 
        with open(filename, 'w') as f:
138
 
            f.write('<html><body>' +
139
 
                    '<a href="nonexisting-test.html">broken test link</a>' +
140
 
                    '</body><html>')
141
 
        self.html_link_checker = HTMLLinkChecker([filename])
142
 
        self.html_link_checker.check_local_links()
143
 
        self.assertNotIn(True, self.html_link_checker.local_link_results)
144
 
        clean_tempdir(dirname)
145
 
 
146
 
    def test_simple_local_working_link(self):
147
 
        html = '<html><body>' + \
148
 
               '<a href="second-test.html">broken test link</a>' + \
149
 
               '</body><html>'
150
 
        dirname = tempfile.mkdtemp()
151
 
        filename1 = os.path.join(dirname, 'first-test.html')
152
 
        with open(filename1, 'w') as f:
153
 
            f.write(html)
154
 
        filename2 = os.path.join(dirname, 'second-test.html')
155
 
        with open(filename2, 'w') as f:
156
 
            f.write(html)
157
 
        self.html_link_checker = HTMLLinkChecker([filename1])
158
 
        self.html_link_checker.check_local_links()
159
 
        self.assertEqual([True], self.html_link_checker.local_link_results)
160
 
        clean_tempdir(dirname)
161
 
 
162
 
    def test_non_existing_build(self):
163
 
        self._require_build('not-existing')
164
 
        self.assertNotEqual(self.build_runner.rc, 0)
165
 
 
166
 
    def test_local_links_in_phone_build(self):
167
 
        self._test_local_links('app')
168
 
        self.assertEqual(self.build_runner.rc, 0)
169
 
        self.assertNotEqual(self.build_runner.html_files, [])
170
 
        self.assertNotIn(False, self.html_link_checker.local_link_results)
171
 
 
172
 
    def test_external_links_in_phone_build(self):
173
 
        self._test_external_links('app')
174
 
        self.assertEqual(self.build_runner.rc, 0)
175
 
        self.assertNotEqual(self.build_runner.html_files, [])
176
 
        self.assertNotIn(False, self.html_link_checker.external_link_results)
177
 
 
178
 
    def test_local_links_in_web_build(self):
179
 
        self._test_local_links('web')
180
 
        self.assertEqual(self.build_runner.rc, 0)
181
 
        self.assertNotEqual(self.build_runner.html_files, [])
182
 
        self.assertNotIn(False, self.html_link_checker.local_link_results)
 
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')