]> git.scottworley.com Git - paperdoorknob/blob - glowfic_test.py
befd0b57a584d6a18624dbd48b7352b17dafa053
[paperdoorknob] / glowfic_test.py
1 # paperdoorknob: Print glowfic
2 #
3 # This program is free software: you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License as published by the
5 # Free Software Foundation, version 3.
6
7 from io import BytesIO
8 from sys import stderr
9 import unittest
10
11 from typing import Optional
12
13 from fetch import FakeFetcher
14 from images import FakeImageStore
15 from glowfic import makeChunk, Thread
16 from spec import Spec
17 from texify import PandocTexifier
18
19
20 def spec_for_testing(html: bytes, outbuf: Optional[BytesIO] = None) -> Spec:
21 return Spec('https://fake/test',
22 FakeFetcher({'https://fake/test': html,
23 'https://fake/test?view=flat': html}),
24 FakeImageStore(),
25 lambda x: x,
26 lambda x: None,
27 PandocTexifier('pandoc'),
28 lambda x: x,
29 20,
30 b'',
31 None,
32 stderr.buffer if outbuf is None else outbuf,
33 lambda x: None)
34
35
36 class TestSplit(unittest.TestCase):
37
38 def testSplit1(self) -> None:
39 t = Thread(spec_for_testing(b'''
40 <html><body><div class="post-container post-post">
41 The "post"
42 </div></body></html>'''))
43 self.assertEqual([list(t.stripped_strings) for t in t.chunkDOMs()],
44 [['The "post"']])
45
46 def testSplit2(self) -> None:
47 t = Thread(spec_for_testing(b'''
48 <html><body>
49 <div class="post-container post-post">The "post"</div>
50 <div class="flat-post-replies">
51 <div class="post-container post-reply">The "reply"</div>
52 </div>
53 </body></html>'''))
54 self.assertEqual([list(t.stripped_strings) for t in t.chunkDOMs()],
55 [['The "post"'], ['The "reply"']])
56
57 def testSplit3(self) -> None:
58 t = Thread(spec_for_testing(b'''
59 <html><body>
60 <div class="post-container post-post">The "post"</div>
61 <div class="flat-post-replies">
62 <div class="post-container post-reply">1st reply</div>
63 <div class="post-container post-reply">2nd reply</div>
64 </div>
65 </body></html>'''))
66 self.assertEqual([list(t.stripped_strings) for t in t.chunkDOMs()],
67 [['The "post"'], ['1st reply'], ['2nd reply']])
68
69
70 class TestMakeChunk(unittest.TestCase):
71
72 def testEmptyContent(self) -> None:
73 with open('testdata/empty-content.html', 'rb') as f:
74 t = Thread(spec_for_testing(f.read((9999))))
75 c = makeChunk(next(iter(t.chunkDOMs())), FakeImageStore())
76 self.assertEqual(
77 c.icon,
78 'stored:https://d1anwqy6ci9o1i.cloudfront.net/' +
79 'users%2F366%2Ficons%2Fxqmypqvflgdy28aorw9ml_shock.png')
80 assert c.character
81 assert c.screen_name
82 assert c.author
83 self.assertEqual(list(c.character.stripped_strings), ['Keltham'])
84 self.assertEqual(
85 list(c.screen_name.stripped_strings), ['lawful chaotic'])
86 self.assertEqual(list(c.author.stripped_strings), ['Iarwain'])
87 self.assertEqual(str(c.content),
88 '<div class="post-content"><p></p></div>')
89
90 self.assertEqual(
91 PandocTexifier("pandoc").texify(c.character), b'{Keltham}\n')
92
93 def testMinimal(self) -> None:
94 t = Thread(spec_for_testing(b'''
95 <html><body>
96 <div class="post-container post-post">
97 <div class="post-content">Just content</div>
98 </div>
99 </body></html>'''))
100 c = makeChunk(next(iter(t.chunkDOMs())), FakeImageStore())
101 self.assertIsNone(c.icon)
102 self.assertIsNone(c.character)
103 self.assertIsNone(c.screen_name)
104 self.assertIsNone(c.author)
105 self.assertEqual(str(c.content),
106 '<div class="post-content">Just content</div>')
107
108
109 class TestThread(unittest.TestCase):
110
111 def testTitle(self) -> None:
112 t = Thread(spec_for_testing(b'''
113 <html><body>
114 <div class="content-header">
115 <span id="post-title">
116 <a href="/posts/1234">Teh Story!</a>
117 </span>
118 </div>
119 <div class="post-container post-post">The "post"</div>
120 </body></html>'''))
121 self.assertEqual(t.title(), 'Teh Story!')
122
123 def testNextThreadRelative(self) -> None:
124 t = Thread(spec_for_testing(b'''
125 <html><body>
126 <div class="post-navheader">
127 <a class="view-button-link" href="/posts/4567"><div class="view-button">Next Post &raquo;</div>
128 </a><a class="view-button-link" href="/posts/4321"><div class="view-button float-none">&laquo; Previous Post</div>
129 </a>
130 </div>
131 <div class="post-container post-post">The "post"</div>
132 </body></html>'''))
133 self.assertEqual(t.next_thread(), 'https://fake/posts/4567')
134
135 def testNextThreadAbsolute(self) -> None:
136 t = Thread(spec_for_testing(b'''
137 <html><body>
138 <div class="post-navheader">
139 <a class="view-button-link" href="https://elsewhere/posts/4567"><div class="view-button">Next Post &raquo;</div>
140 </a><a class="view-button-link" href="https://elsewhere/posts/4321"><div class="view-button float-none">&laquo; Previous Post</div>
141 </a>
142 </div>
143 <div class="post-container post-post">The "post"</div>
144 </body></html>'''))
145 self.assertEqual(t.next_thread(), 'https://elsewhere/posts/4567')
146
147
148 class TestEmit(unittest.TestCase):
149
150 def testEmit(self) -> None:
151 buf = BytesIO()
152 Thread(spec_for_testing(b'''
153 <html><body>
154 <div class="post-container post-post">
155 <div class="post-content">A</div>
156 </div>
157 <div class="flat-post-replies">
158 <div class="post-container post-reply">
159 <div class="post-content">B</div>
160 </div>
161 </div>
162 </body></html>''', buf)).emit()
163 self.assertEqual(buf.getvalue(), rb'''\glowhead{}{}{}{}A
164 \glowhead{}{}{}{}B
165 ''')
166
167
168 if __name__ == '__main__':
169 unittest.main()