test_lps_gen.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2015-2016 lpschedule-generator contributors. See CONTRIBUTORS.
  4. #
  5. # This file is part of lpschedule-generator.
  6. #
  7. # lpschedule-generator is free software: you can redistribute it
  8. # and/or modify it under the terms of the GNU General Public License
  9. # as published by the Free Software Foundation, either version 3 of
  10. # the License, or (at your option) any later version.
  11. #
  12. # lpschedule-generator is distributed in the hope that it will be useful, but
  13. # WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. # General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with lpschedule-generator (see COPYING). If not, see
  19. # <http://www.gnu.org/licenses/>.
  20. import json
  21. import os
  22. import pprint
  23. import mistune
  24. import mock
  25. from collections import OrderedDict
  26. from os import path
  27. from StringIO import StringIO
  28. from bs4 import BeautifulSoup
  29. from icalendar import vCalAddress, vText, vDatetime
  30. from nose.tools import *
  31. from pytz import timezone
  32. from lps_gen import *
  33. class TestJSONUtils(object):
  34. """Class that tests json utils in `lps_gen` module.
  35. """
  36. @classmethod
  37. def setup_class(self):
  38. """Runs before running any tests in this class."""
  39. self.speakers_ids = OrderedDict({
  40. unicode('Daniel Kahn Gillmor'): 'gillmor',
  41. unicode('Edward Snowden'): 'snowden',
  42. unicode('Richard Stallman'): 'stallman',
  43. unicode('Clara Snowden'): 'clara_snowden',
  44. unicode('Ludovic Courtès'): 'courtes',
  45. unicode('Jonas Öberg'): 'aberg',
  46. })
  47. self.ids_filename = 'speakers.ids'
  48. self.speakers_noids = [
  49. unicode('Daniel Kahn Gillmor'),
  50. unicode('Richard Stallman'),
  51. unicode('Ludovic Courtès'),
  52. unicode('Jonas Öberg'),
  53. ]
  54. self.noids_filename = 'speakers.noids'
  55. # Change current working directory to the tests directory.
  56. self.old_cwd = os.getcwd()
  57. os.chdir('tests')
  58. def setup(self):
  59. """Runs before each test in this class."""
  60. pass
  61. def test_json_write(self):
  62. """Testing json_write function."""
  63. json_write(self.ids_filename, self.speakers_ids)
  64. assert_equal(json.loads(read_file(self.ids_filename),
  65. object_pairs_hook=OrderedDict),
  66. self.speakers_ids)
  67. json_write(self.noids_filename, self.speakers_noids)
  68. assert_equal(json.loads(read_file(self.noids_filename),
  69. object_pairs_hook=OrderedDict),
  70. self.speakers_noids)
  71. def test_json_read(self):
  72. """Testing json_read function."""
  73. write_file(self.ids_filename, json.dumps(self.speakers_ids,
  74. indent=4))
  75. assert_equal(json_read(self.ids_filename), self.speakers_ids)
  76. write_file(self.noids_filename, json.dumps(self.speakers_noids,
  77. indent=4))
  78. assert_equal(json_read(self.noids_filename), self.speakers_noids)
  79. def teardown(self):
  80. """Cleans up things after each test in this class."""
  81. # Remove `speakers.ids` file if it exists.
  82. if path.isfile(self.ids_filename):
  83. os.remove(self.ids_filename)
  84. # Remove `speakers.noids` file if it exists.
  85. if path.isfile(self.noids_filename):
  86. os.remove(self.noids_filename)
  87. @classmethod
  88. def teardown_class(self):
  89. """Clean up the mess created by this test."""
  90. # Change back to the old cwd
  91. os.chdir(self.old_cwd)
  92. class TestLPiCal(object):
  93. """
  94. Testing LPiCal class.
  95. """
  96. @classmethod
  97. def setup_class(self):
  98. """Setting up things for Testing LPiCal class.
  99. """
  100. # Change current working directory to the tests directory.
  101. self.old_cwd = os.getcwd()
  102. os.chdir('tests')
  103. self.MD_FILE = path.join('files', 'lp-sch.md')
  104. self.MD_FILE_CONTENT = read_file(self.MD_FILE)
  105. self.MD_FILE_S_ONLY = path.join('files', 'lp-sch-sessions-only.md')
  106. self.MD_FILE_S_ONLY_CONTENT = read_file(self.MD_FILE_S_ONLY)
  107. self.SCH_TEMPLATE = path.join('..', 'libreplanet-templates/2016',
  108. 'lp-schedule.jinja2')
  109. self.markdown = LPSMarkdown()
  110. self.lps_dict = self.markdown(self.MD_FILE_CONTENT)
  111. self.lps_dict_s_only = self.markdown(self.MD_FILE_S_ONLY_CONTENT)
  112. self.purge_list = ['speakers.noids']
  113. def setup(self):
  114. """Setting up things for a new test.
  115. """
  116. self.lp_ical = LPiCal(self.lps_dict, '2016')
  117. def test_gen_uid(self):
  118. """Testing LPiCal.gen_uid.
  119. """
  120. uid_fmt = ''.join(['{id}@LP', self.lp_ical.lp_year,
  121. '@libreplanet.org'])
  122. for i in range(40):
  123. assert_equals(self.lp_ical.gen_uid(),
  124. uid_fmt.format(id=i+1))
  125. def test_get_timeslot(self):
  126. """
  127. Testing LPiCal.get_timeslot.
  128. """
  129. timeslots = {
  130. '09:00-09:45: Registration and Breakfast':
  131. ['09:00', '09:45', 'Registration and Breakfast'],
  132. ' 09:45 - 10:45: Opening Keynote':
  133. ['09:45', '10:45', 'Opening Keynote'],
  134. '10:5 - 10:55: Break':
  135. ['10:5', '10:55', 'Break'],
  136. ' 10:55 - 11:40: Session Block 1A':
  137. ['10:55', '11:40', 'Session Block 1A'],
  138. ' 11:40 - 11:50: Break':
  139. ['11:40', '11:50', 'Break'],
  140. '9:45 - 10:30: Keynote ':
  141. ['9:45', '10:30', 'Keynote'],
  142. '16:55 - 17:40:Session Block 6B':
  143. ['16:55', '17:40', 'Session Block 6B'],
  144. '17:50 - 18:35: Closing keynote':
  145. ['17:50', '18:35', 'Closing keynote'],
  146. '':
  147. [None, None, None],
  148. '\t\t\t':
  149. [None, None, None],
  150. ' ':
  151. [None, None, None],
  152. }
  153. for string, timeslot in timeslots.iteritems():
  154. start, end, name = self.lp_ical.get_timeslot(string)
  155. assert_equal(start, timeslot[0])
  156. assert_equal(end, timeslot[1])
  157. assert_equal(name, timeslot[2])
  158. def test_get_month_day(self):
  159. """Testing LPiCal.get_month_day.
  160. """
  161. month_days = {
  162. 'Sunday, March 20': ['March', '20'],
  163. 'Saturday, March 19': ['March', '19'],
  164. 'Monday,March 20 ': ['March', '20'],
  165. 'Tuesday,March21': ['March', '21'],
  166. ' Wednesday, March 22': ['March', '22'],
  167. 'Thursday, March 23 ': ['March', '23'],
  168. '': [None, None],
  169. '\t\t': [None, None],
  170. ' ': [None, None],
  171. }
  172. for string, month_day in month_days.iteritems():
  173. month, day = self.lp_ical.get_month_day(string)
  174. assert_equal(month, month_day[0])
  175. assert_equal(day, month_day[1])
  176. def test_mk_datetime(self):
  177. """Testing LPiCal.mk_datetime
  178. """
  179. datetimes = [
  180. {
  181. 'params': ['February', '28','08:00'],
  182. 'datetime': '2016-02-28 08:00:00',
  183. },
  184. {
  185. 'params': ['March', '21', '9:0'],
  186. 'datetime': '2016-03-21 09:00:00',
  187. },
  188. {
  189. 'params': ['March', '23', '15:30'],
  190. 'datetime': '2016-03-23 15:30:00',
  191. },
  192. ]
  193. for test in datetimes:
  194. month = test['params'][0]
  195. day = test['params'][1]
  196. time = test['params'][2]
  197. dt_obj = self.lp_ical.mk_datetime(month, day, time)
  198. assert str(dt_obj.dt.tzinfo) == 'US/Eastern'
  199. assert str(dt_obj.dt)[:-6] == test['datetime']
  200. def test_mk_attendee(self):
  201. """Testing LPiCal.mk_attendee
  202. """
  203. speakers = [
  204. 'Richard Stallman',
  205. 'ginger coons',
  206. '<a href="speakers.htmll#corvellec">Marianne Corvellec</a>',
  207. '<a href="speakers.html#le-lous">Jonathan Le Lous</a>',
  208. 'Jonas \xc3\x96berg',
  209. ]
  210. for speaker in speakers:
  211. attendee = self.lp_ical.mk_attendee(speaker)
  212. assert str(attendee) == 'invalid:nomail'
  213. assert attendee.params.get('cn') == BeautifulSoup(
  214. speaker, 'html.parser').get_text()
  215. assert attendee.params.get('ROLE') == 'REQ-PARTICIPANT'
  216. assert attendee.params.get('CUTYPE') == 'INDIVIDUAL'
  217. def test_add_event(self):
  218. """Testing LPiCal.add_event
  219. """
  220. uids = []
  221. for day_str, timeslots in self.lps_dict.iteritems():
  222. month, day = self.lp_ical.get_month_day(day_str)
  223. for timeslot_str, sessions in timeslots.iteritems():
  224. t_start, t_end, t_name = self.lp_ical.get_timeslot(timeslot_str)
  225. for session, session_info in sessions.iteritems():
  226. event = self.lp_ical.add_event(month, day,
  227. t_start, t_end, t_name,
  228. session, session_info)
  229. assert event['uid'] not in uids
  230. uids.append(event['uid'])
  231. assert event['dtstamp'] == self.lp_ical.dtstamp
  232. assert event['class'] == 'PUBLIC'
  233. assert event['status'] == 'CONFIRMED'
  234. assert event['method'] == 'PUBLISH'
  235. if session == 'st-from-ts':
  236. assert event['summary'] == t_name
  237. else:
  238. assert event['summary'] == session
  239. assert event['location'] == session_info['room']
  240. assert event['description'] == BeautifulSoup(' '.join(
  241. session_info['desc']).replace(
  242. '\n',' '), 'html.parser').get_text()
  243. if type(event['attendee']) is list:
  244. for attendee in event['attendee']:
  245. assert isinstance(attendee, vCalAddress)
  246. else:
  247. assert isinstance(event['attendee'], vCalAddress)
  248. assert isinstance(event['dtstart'], vDatetime)
  249. assert isinstance(event['dtend'], vDatetime)
  250. def test_gen_ical(self):
  251. """Testing LPiCal.gen_ical.
  252. """
  253. print self.lp_ical.gen_ical()
  254. def test_gen_ical_sessions_only(self):
  255. """Testing LPiCal.gen_ical with sessions only schedule.
  256. """
  257. print LPiCal(self.lps_dict_s_only, '2016').gen_ical()
  258. def test_to_ical(self):
  259. """Testing LPiCal.to_ical.
  260. """
  261. self.purge_list.append(self.lp_ical.to_ical())
  262. @classmethod
  263. def teardown_class(self):
  264. """
  265. Tearing down the mess created by Testing LPiCal class.
  266. """
  267. # remove files in the purge_list.
  268. for f in self.purge_list:
  269. if path.isfile(f):
  270. os.remove(f)
  271. # Change back to the old cwd
  272. os.chdir(self.old_cwd)
  273. class TestLPS(object):
  274. """
  275. Class that tests everything related LP Schedule.
  276. """
  277. @classmethod
  278. def setup_class(self):
  279. """Runs before running any tests in this class."""
  280. # Change current working directory to the tests directory.
  281. self.old_cwd = os.getcwd()
  282. os.chdir('tests')
  283. self.MD_FILE = path.join('files', 'lp-sch.md')
  284. self.MD_FILE_CONTENT = read_file(self.MD_FILE)
  285. self.SCH_TEMPLATE = path.join('..', 'libreplanet-templates/2018',
  286. 'lp-schedule.jinja2')
  287. self.markdown = LPSMarkdown()
  288. self.lps_dict = self.markdown(self.MD_FILE_CONTENT)
  289. def setup(self):
  290. """Runs before each test in this class."""
  291. pass
  292. def test_LPSMarkdown_day(self):
  293. """
  294. Testing `LPSMarkdown` class - Day.
  295. """
  296. days = ['Saturday, March 19',
  297. 'Sunday, March 20']
  298. i = 0
  299. for day in self.lps_dict.keys():
  300. assert_equal(day, days[i])
  301. i = i + 1
  302. def test_LPSMarkdown_timeslot(self):
  303. """
  304. Testing `LPSMarkdown` class - Timeslot.
  305. """
  306. timeslots = [
  307. '09:00 - 09:45: Registration and Breakfast',
  308. '09:45 - 10:45: Opening Keynote: Richard Stallman',
  309. '10:55 - 11:40: Session Block 1A',
  310. '11:40 - 11:50: Break',
  311. '11:50 - 12:35: Session Block 2A',
  312. '09:00 - 09:45: Registration and breakfast',
  313. '09:45 - 10:30: Keynote: Access without empowerment',
  314. '10:30 - 10:40: Break',
  315. '10:40 - 11:25: Session Block 1B',
  316. ]
  317. i = 0
  318. for lps_timeslots in self.lps_dict.values():
  319. for timeslot in lps_timeslots.keys():
  320. assert_equal(timeslot, timeslots[i])
  321. i = i + 1
  322. def test_LPSMarkdown_session(self):
  323. """
  324. Testing `LPSMarkdown` class - Session.
  325. """
  326. sessions = [
  327. 'Free software, free hardware, and other things',
  328. 'Federation and GNU',
  329. 'Dr. Hyde and Mr. Jekyll: advocating for free software in nonfree academic contexts',
  330. 'TAFTA, CETA, TISA: traps and threats to Free Software Everywhere',
  331. 'Let\'s encrypt!',
  332. 'Attribution revolution -- turning copyright upside-down',
  333. 'st-from-ts',
  334. 'Fork and ignore: fighting a GPL violation by coding instead',
  335. 'Who did this? Just wait until your father gets home',
  336. ]
  337. i = 0
  338. for lps_timeslots in self.lps_dict.values():
  339. for lps_sessions in lps_timeslots.values():
  340. for session in lps_sessions.keys():
  341. assert_equal(session, sessions[i])
  342. i = i + 1
  343. def test_LPSMarkdown_speaker(self):
  344. """
  345. Testing `LPSMarkdown` class - Speaker
  346. """
  347. speakers = [
  348. ['Richard Stallman'],
  349. ['<a href="http://dustycloud.org">Christopher Webber</a>'],
  350. ['ginger coons'],
  351. ['<a href="/2015/program/speakers.html#corvellec">Marianne Corvellec</a>',
  352. '<a href="/2015/program/speakers.html#le-lous">Jonathan Le Lous</a>'],
  353. ['Seth Schoen'],
  354. ['Jonas Öberg'],
  355. ['Benjamin Mako Hill'],
  356. ['Bradley Kuhn'],
  357. ['Ken Starks'],
  358. ]
  359. i = 0
  360. for lps_timeslots in self.lps_dict.values():
  361. for lps_sessions in lps_timeslots.values():
  362. for session_info in lps_sessions.values():
  363. assert_equal(session_info['speakers'], speakers[i])
  364. i = i + 1
  365. def test_LPSMarkdown_room(self):
  366. """
  367. Testing `LPSMarkdown` class - Room
  368. """
  369. rooms = [
  370. 'Room 32-123',
  371. 'Room 32-123',
  372. 'Room 32-141',
  373. 'Room 32-155',
  374. 'Room 32-123',
  375. 'Room 32-141',
  376. 'Room 32-123',
  377. 'Room 32-123',
  378. 'Room 32-141',
  379. ]
  380. i = 0
  381. for lps_timeslots in self.lps_dict.values():
  382. for lps_sessions in lps_timeslots.values():
  383. for session_info in lps_sessions.values():
  384. assert_equal(session_info['room'], rooms[i])
  385. i = i + 1
  386. def test_LPSMarkdown_video(self):
  387. """Testing `LPSMarkdown` class - Video
  388. """
  389. videos = [
  390. 'https://media.libre.planet/rms-free-everything',
  391. 'https://media.libre.planet/gnu-fed',
  392. 'VideoTBA',
  393. 'https://media.libre.planet/tafta-ceta-tisa',
  394. 'https://media.libre.planet/letsencrypt',
  395. 'VideoTBA',
  396. 'https://media.libre.planet/mako-keynote',
  397. 'https://media.libre.planet/fork-ignore',
  398. 'VideoTBA',
  399. ]
  400. i = 0
  401. for lps_timeslots in self.lps_dict.values():
  402. for lps_sessions in lps_timeslots.values():
  403. for session_info in lps_sessions.values():
  404. assert_equal(session_info['video'], videos[i])
  405. i = i + 1
  406. def test_LPSMarkdown_desc(self):
  407. """Testing `LPSMarkdown` class - Video
  408. """
  409. descriptions = [
  410. 'Preceded by a welcome address from',
  411. 'The effort to re-decentralize the web has',
  412. 'What if the classic horror trope of the',
  413. 'TAFTA, CETA, and TISA are far-reaching',
  414. 'This year a robotic certificate authority will',
  415. 'Reusing works licensed under free licenses seems',
  416. 'In order to relate effectively to the digital works',
  417. 'The free software movement has twin',
  418. 'Typically, GPL enforcement activity',
  419. 'While traditional enforcement is often',
  420. 'Recently, Software Freedom Conservancy',
  421. 'This talk discusses which scenarios make this remedy',
  422. 'What\'s going on in here? Computer parts',
  423. ]
  424. i = 0
  425. for lps_timeslots in self.lps_dict.values():
  426. for lps_sessions in lps_timeslots.values():
  427. for session_info in lps_sessions.values():
  428. for desc in session_info['desc']:
  429. assert_true(desc.startswith(descriptions[i]))
  430. i = i + 1
  431. def test_RenderHTML(self):
  432. """Testing `RenderHTML` function with LP schedule
  433. """
  434. lps_html = RenderHTML(self.lps_dict, self.SCH_TEMPLATE)
  435. print lps_html # TODO: Scrape and test html output
  436. def test_RenderHTML_sessions_only(self):
  437. """Testing `RenderHTML` function - LP schedule - sessions only
  438. """
  439. md_content = read_file(path.join('files',
  440. 'lp-sch-sessions-only.md'))
  441. lps_html = RenderHTML(self.markdown(md_content),
  442. self.SCH_TEMPLATE)
  443. print lps_html # TODO: Scrape and test html output
  444. @raises(SystemExit)
  445. def test_RenderHTML_nonexistent_template(self):
  446. """Testing `RenderHTML` function - LP schedule - ith non-existent template
  447. """
  448. with mock.patch('sys.stdout', new_callable=StringIO) as out:
  449. nonexistent_template = 'lpsch-template.null'
  450. lps_html = RenderHTML(self.lps_dict, nonexistent_template)
  451. expected_out = 'Template %s not found.\n' % template_name
  452. assert out.getvalue() == expected_out
  453. def teardown(self):
  454. """Cleans up things after each test in this class."""
  455. pass
  456. @classmethod
  457. def teardown_class(self):
  458. """Clean up the mess created by this test."""
  459. # Remove `speakers.noids` file if it exists.
  460. if path.isfile('speakers.noids'):
  461. os.remove('speakers.noids')
  462. # Change back to the old cwd
  463. os.chdir(self.old_cwd)
  464. class TestLPSTBA(object):
  465. """Class tests TBAs in the LP schedule.
  466. """
  467. @classmethod
  468. def setup_class(self):
  469. """Runs before running any tests in this class.
  470. """
  471. # Change current working directory to the tests directory.
  472. self.old_cwd = os.getcwd()
  473. os.chdir('tests')
  474. self.MD_FILE = path.join('files', 'lp-sch-tba.md')
  475. self.MD_FILE_CONTENT = read_file(self.MD_FILE)
  476. self.SCH_TEMPLATE = path.join('..', 'libreplanet-templates/2018',
  477. 'lp-schedule.jinja2')
  478. self.markdown = LPSMarkdown()
  479. self.lps_dict = self.markdown(self.MD_FILE_CONTENT)
  480. def setup(self):
  481. """Runs before each test in this class.
  482. """
  483. lp_html = RenderHTML(self.lps_dict, self.SCH_TEMPLATE)
  484. self.soup = BeautifulSoup(lp_html, 'html.parser')
  485. def cleanup_speaker(self, sp):
  486. return ' '.join([s.strip() for s in sp.string.split('\n')
  487. if len(s.strip())])
  488. def cleanup_desc(self, desc):
  489. return desc.replace('\n', '').strip()
  490. def test_LP_speakers(self):
  491. """Tests the non-existence of `SpeakerTBA` in gen. HTML.
  492. """
  493. speakers = [
  494. 'Paige Peterson, MaidSoft',
  495. 'George Chriss and others, Kat Walsh (moderator)',
  496. 'Andrew Seeder, Dudley Street Neighborhood Initiative',
  497. 'Marina Zhurakhinskaya, Red Hat',
  498. 'Marianne Corvellec, April and Jonathan Le Lous, April',
  499. 'Scott Dexter and Evan Misshula, CUNY, and Erin Glass, UCSD',
  500. 'Michaela R. Brown',
  501. ]
  502. for sp in self.soup.find_all(class_='program-session-speaker'):
  503. sp_block = self.cleanup_speaker(sp)
  504. assert_equal(sp_block, speakers.pop(0))
  505. def test_LP_room(self):
  506. """Tests the non-existence of `RoomTBA` in gen. HTML.
  507. """
  508. rooms = [
  509. 'Room 32-141',
  510. 'Room 32-144',
  511. 'Room 31-123',
  512. 'Room 32-144',
  513. 'Room 42-042',
  514. ]
  515. for sp in self.soup.find_all(class_='room'):
  516. room_block = sp.string
  517. assert_equal(room_block, rooms.pop(0))
  518. def test_LP_description(self):
  519. """Tests the non-existence of `DescTBA` in gen. HTML.
  520. """
  521. descriptions = [
  522. 'Your workplace can exert a lot of control over how',
  523. 'Free software developers and users tend to be most',
  524. 'This talk will help you gather information, frame',
  525. 'A look back at free software history',
  526. 'Academic Institutions and their researchers',
  527. 'At CUNY, we have taken steps to change this',
  528. 'Being a free software user isn\'t easy,',
  529. 'In this session, I\'ll give students tips',
  530. ]
  531. for descs in self.soup.find_all(class_='session-desc'):
  532. for desc in descs.strings:
  533. desc = self.cleanup_desc(desc)
  534. if desc:
  535. assert desc.startswith(descriptions.pop(0))
  536. def teardown(self):
  537. """Cleans up things after each test in this class.
  538. """
  539. # Remove `speakers.noids` file if it exists.
  540. if path.isfile('speakers.noids'):
  541. os.remove('speakers.noids')
  542. @classmethod
  543. def teardown_class(self):
  544. """Cleans up the mess after running all tests in this class.
  545. """
  546. # Change back to the old cwd
  547. os.chdir(self.old_cwd)
  548. class TestLPSpeakers(object):
  549. """
  550. Class that tests everything related LP Speakers
  551. """
  552. @classmethod
  553. def setup_class(self):
  554. """Runs before running any tests in this class."""
  555. # Change current working directory to the tests directory.
  556. self.old_cwd = os.getcwd()
  557. os.chdir('tests')
  558. self.MD_FILE = path.join('files', 'lp-speakers.md')
  559. self.MD_FILE_CONTENT = read_file(self.MD_FILE)
  560. self.SPEAKERS_TEMPLATE = path.join('..', 'libreplanet-templates/2016',
  561. 'lp-speakers.jinja2')
  562. self.markdown = LPSpeakersMarkdown()
  563. self.lpspeakers_dict = self.markdown(self.MD_FILE_CONTENT)
  564. def setup(self):
  565. """Runs before each test in this class."""
  566. pass
  567. def test_speakers_id_file_exists(self):
  568. """
  569. Testing if LPSpeakersMardown created speakers.ids file.
  570. """
  571. speakers_ids = self.markdown.speakers_renderer.speakers_ids
  572. assert path.isfile('speakers.ids')
  573. assert_equal(json_read('speakers.ids'), speakers_ids)
  574. def test_LPSpeakersMarkdown_keynotespeakers_name(self):
  575. """Testing LPSpeakersMarkdown keynote speakers' names.
  576. """
  577. keynote_speakers = ['Daniel Kahn Gillmor',
  578. 'Edward Snowden',
  579. 'Richard Stallman',
  580. 'Clara Snowden',
  581. 'Ludovic Courtès']
  582. i = 0
  583. for kspeaker in self.lpspeakers_dict['keynote-speakers']:
  584. assert_equal(kspeaker['speaker'], keynote_speakers[i])
  585. i = i + 1
  586. def test_LPSpeakersMarkdown_keynotespeakers_id(self):
  587. """Testing LPSpeakersMarkdown keynote speakers' id.
  588. """
  589. keynote_speaker_ids = ['gillmor',
  590. 'snowden',
  591. 'stallman',
  592. 'clara_snowden',
  593. 'courtes']
  594. i = 0
  595. for kspeaker in self.lpspeakers_dict['keynote-speakers']:
  596. assert_equal(kspeaker['id'], keynote_speaker_ids[i])
  597. i = i + 1
  598. def test_LPSpeakersMarkdown_keynotespeakers_imgurl(self):
  599. """Testing LPSpeakersMarkdown keynote speakers' image url.
  600. """
  601. keynote_speaker_img_urls = [
  602. '//static.fsf.org/nosvn/libreplanet/speaker-pics/dkg.jpg',
  603. '//static.fsf.org/nosvn/libreplanet/speaker-pics/snowden.jpg',
  604. '//static.fsf.org/nosvn/libreplanet/speaker-pics/stallman.jpg',
  605. '//static.fsf.org/nosvn/libreplanet/speaker-pics/c_snowden.jpg'
  606. ]
  607. i = 0
  608. for kspeaker in self.lpspeakers_dict['keynote-speakers']:
  609. if kspeaker.has_key('img_url'):
  610. assert_equal(kspeaker['img_url'],
  611. keynote_speaker_img_urls[i])
  612. i = i + 1
  613. def test_LPSpeakersMarkdown_keynotespeakers_imgalt(self):
  614. """Testing LPSpeakersMarkdown keynote speakers' image alt text.
  615. """
  616. keynote_speaker_img_alts = ['Daniel Kahn Gillmor - Photo',
  617. 'Edward Snowden - Photo',
  618. 'Richard Stallman - Photo',
  619. '']
  620. i = 0
  621. for kspeaker in self.lpspeakers_dict['keynote-speakers']:
  622. if kspeaker.has_key('img_alt'):
  623. assert_equal(kspeaker['img_alt'],
  624. keynote_speaker_img_alts[i])
  625. i = i + 1
  626. def test_LPSpeakersMarkdown_keynotespeakers_bio(self):
  627. """Testing LPSpeakersMarkdown keynote speakers' bio.
  628. """
  629. keynote_speaker_bios = [
  630. ['Daniel Kahn Gillmor is a technologist with the ACLU\'s Speech, Privacy'],
  631. ['Edward Snowden is a former intelligence officer who served the CIA,'],
  632. ['Richard is a software developer and software freedom activist. In 1983',
  633. 'Since the mid-1990s, Richard has spent most of his time in political',],
  634. [],
  635. ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam',
  636. 'Ut turpis felis, pulvinar a semper sed, adipiscing id']
  637. ]
  638. i = 0
  639. for kspeaker in self.lpspeakers_dict['keynote-speakers']:
  640. if kspeaker.has_key('bio'):
  641. j = 0
  642. for p in kspeaker['bio']:
  643. p.startswith(keynote_speaker_bios[i][j])
  644. j = j + 1
  645. i = i + 1
  646. def test_LPSpeakersMarkdown_speakers_name(self):
  647. """Testing LPSpeakersMarkdown speakers' names.
  648. """
  649. speakers = ['Emmanuel',
  650. 'George Chriss',
  651. 'Marianne Corvellec',
  652. 'Richard Fontana',
  653. 'Mike Gerwitz',
  654. 'Bassam Kurdali',
  655. 'Jonathan Le Lous',
  656. 'M. C. McGrath',
  657. 'Deb Nicholson',
  658. 'Stefano Zacchiroli']
  659. i = 0
  660. for kspeaker in self.lpspeakers_dict['speakers']:
  661. assert_equal(kspeaker['speaker'], speakers[i])
  662. i = i + 1
  663. def test_LPSpeakersMarkdown_speakers_id(self):
  664. """Testing LPSpeakersMarkdown speakers' id.
  665. """
  666. speaker_ids = ['emmanuel',
  667. 'chriss',
  668. 'corvellec',
  669. 'fontana',
  670. 'gerwitz',
  671. 'kurdali',
  672. 'lous',
  673. 'mcgrath',
  674. 'nicholson',
  675. 'zacchiroli']
  676. i = 0
  677. for kspeaker in self.lpspeakers_dict['speakers']:
  678. assert_equal(kspeaker['id'], speaker_ids[i])
  679. i = i + 1
  680. def test_LPSpeakersMarkdown_speakers_imgurl(self):
  681. """Testing LPSpeakersMarkdown speakers' image url.
  682. """
  683. speaker_img_urls = [
  684. '', '',
  685. '//static.fsf.org/nosvn/libreplanet/speaker-pics/corvellec.jpg',
  686. '', '',
  687. '//static.fsf.org/nosvn/libreplanet/speaker-pics/kurdali.png',
  688. '//static.fsf.org/nosvn/libreplanet/speaker-pics/lelous.jpg',
  689. '',
  690. '//static.fsf.org/nosvn/libreplanet/speaker-pics/nicholson.jpg',
  691. '//static.fsf.org/nosvn/libreplanet/speaker-pics/zacchiroli.jpg'
  692. ]
  693. i = 0
  694. for kspeaker in self.lpspeakers_dict['speakers']:
  695. if kspeaker.has_key('img_url'):
  696. assert_equal(kspeaker['img_url'],
  697. speaker_img_urls[i])
  698. i = i + 1
  699. def test_LPSpeakersMarkdown_speakers_imgalt(self):
  700. """Testing LPSpeakersMarkdown speakers' image alt text.
  701. """
  702. speaker_img_alts = [
  703. '', '',
  704. 'Marianne Corvellec - Photo',
  705. '', '',
  706. 'Bassam Kurdali - Photo',
  707. 'Jonathan Le Lous - Photo',
  708. '',
  709. 'Deb Nicholson - Photo',
  710. 'Stefano Zacchiroli - Photo']
  711. i = 0
  712. for kspeaker in self.lpspeakers_dict['speakers']:
  713. if kspeaker.has_key('img_alt'):
  714. assert_equal(kspeaker['img_alt'],
  715. speaker_img_alts[i])
  716. i = i + 1
  717. def test_LPSpeakersMarkdown_speakers_bio(self):
  718. """Testing LPSpeakersMarkdown speakers' bio.
  719. """
  720. speaker_bios = [
  721. ['Emmanuel is a Division III student at Hampshire College, studying how'],
  722. [],
  723. ['Marianne Corvellec has been a Free Software activist with April'],
  724. ['Richard Fontana is a lawyer at Red Hat. He leads support for Red Hat\'s'],
  725. [],
  726. ['Bassam is a 3D animator/filmmaker whose 2006 short, Elephants Dream,'],
  727. ['Jonathan has been involved with the Free Software Movement for ten'],
  728. ['M. C. is the founder of Transparency Toolkit, a free software project'],
  729. [],
  730. ['Stefano Zacchiroli is Associate Professor of Computer Science at']
  731. ]
  732. i = 0
  733. for kspeaker in self.lpspeakers_dict['speakers']:
  734. if kspeaker.has_key('bio'):
  735. j = 0
  736. for p in kspeaker['bio']:
  737. p.startswith(speaker_bios[i][j])
  738. j = j + 1
  739. i = i + 1
  740. def test_RenderHTML(self):
  741. """Testing `RenderHTML` function with LP speakers
  742. """
  743. lps_html = RenderHTML(self.lpspeakers_dict, self.SPEAKERS_TEMPLATE)
  744. print lps_html # TODO: Scrape and test html output.
  745. def teardown(self):
  746. """Cleans up things after each test in this class."""
  747. pass
  748. @classmethod
  749. def teardown_class(self):
  750. """Purge the mess created by this test."""
  751. # Remove `speakers.ids` file if it exists.
  752. if path.isfile('speakers.ids'):
  753. os.remove('speakers.ids')
  754. # Change back to the old cwd
  755. os.chdir(self.old_cwd)
  756. class TestSpeakersAutoLinking(object):
  757. """Class tests autolinking of speakers in sessions MD.
  758. """
  759. @classmethod
  760. def setup_class(self):
  761. """Runs before running any tests in this class."""
  762. # Change current working directory to the tests directory.
  763. self.old_cwd = os.getcwd()
  764. os.chdir('tests')
  765. self.ids_filename = 'speakers.ids'
  766. self.noids_filename = 'speakers.noids'
  767. self.SPEAKERS_MD = path.join('files', 'lp-speakers-autolink.md')
  768. self.SPEAKERS_MD_CONTENT = read_file(self.SPEAKERS_MD)
  769. self.SPEAKERS_TEMPLATE = path.join('..', 'libreplanet-templates/2016',
  770. 'lp-speakers.jinja2')
  771. self.SESSIONS_MD = path.join('files', 'lp-sessions-autolink.md')
  772. self.SESSIONS_MD_CONTENT = read_file(self.SESSIONS_MD)
  773. self.SESSIONS_TEMPLATE = path.join('..', 'libreplanet-templates/2018',
  774. 'lp-schedule.jinja2')
  775. def setup(self):
  776. """Runs before each test in this class."""
  777. pass
  778. def test_sessions_autolinking(self):
  779. """Testing autolinking of speakers in sessions. """
  780. self.speakers_markdown = LPSpeakersMarkdown()
  781. self.lpspeakers_dict = self.speakers_markdown(
  782. self.SPEAKERS_MD_CONTENT)
  783. assert (path.isfile(self.ids_filename) and
  784. json.loads(read_file(self.ids_filename)))
  785. self.sessions_markdown = LPSMarkdown()
  786. self.lps_dict = self.sessions_markdown(self.SESSIONS_MD_CONTENT)
  787. assert (path.isfile(self.noids_filename) and
  788. json.loads(read_file(self.noids_filename)))
  789. speakers = [
  790. [
  791. '<a href="speakers.html#snowden">Edward Snowden</a>',
  792. '<a href="speakers.html#gillmor">Daniel Kahn Gillmor</a>',
  793. ],
  794. [
  795. '<a href="speakers.html#nicholson">Deb Nicholson</a>',
  796. '<a href="speakers.html#fontana">Richard Fontana</a>',
  797. ],
  798. [
  799. 'Paige Peterson', 'MaidSoft'
  800. ],
  801. [
  802. 'George Chriss',
  803. 'Kat Walsh (moderator)',
  804. ],
  805. [
  806. '<a href="speakers.html#zacchiroli">Stefano Zacchiroli</a>',
  807. 'Debian', 'OSI', 'IRILL'
  808. ],
  809. [
  810. '<a href="speakers.html#corvellec">Marianne Corvellec</a>',
  811. 'April and Jonathan Le Lous',
  812. 'April'
  813. ],
  814. [
  815. '<a href="speakers.html#brown">Michaela R. Brown</a>',
  816. ],
  817. [
  818. '<a href="speakers.html#gott">Molly Gott</a>'
  819. ],
  820. [
  821. 'Christopher Webber',
  822. '<a href="speakers.html#thompson">David Thompson</a>',
  823. 'Ludovic Courtès',
  824. ],
  825. ]
  826. i = 0
  827. for lps_timeslots in self.lps_dict.values():
  828. for lps_sessions in lps_timeslots.values():
  829. for session_info in lps_sessions.values():
  830. assert_equal(session_info['speakers'], speakers[i])
  831. i = i + 1
  832. speakers_noids = [
  833. 'Paige Peterson',
  834. 'George Chriss',
  835. 'Kat Walsh',
  836. 'Jonathan Le Lous',
  837. 'Christopher Webber',
  838. 'Ludovic Courtès',
  839. ]
  840. assert_equal(json_read(self.noids_filename), speakers_noids)
  841. def test_sessions_autolinking_nospeakerids(self):
  842. """Testing autolinked speakrs in sessions MD when speakers.id not available. """
  843. assert not path.isfile(self.ids_filename)
  844. self.sessions_markdown = LPSMarkdown()
  845. self.lps_dict = self.sessions_markdown(self.SESSIONS_MD_CONTENT)
  846. assert (path.isfile(self.noids_filename) and
  847. json.loads(read_file(self.noids_filename)))
  848. speakers = [
  849. [
  850. 'Edward Snowden',
  851. 'Daniel Kahn Gillmor',
  852. ],
  853. [
  854. 'Deb Nicholson',
  855. 'Richard Fontana',
  856. ],
  857. [
  858. 'Paige Peterson', 'MaidSoft'
  859. ],
  860. [
  861. 'George Chriss',
  862. 'Kat Walsh (moderator)',
  863. ],
  864. [
  865. 'Stefano Zacchiroli',
  866. 'Debian', 'OSI', 'IRILL'
  867. ],
  868. [
  869. 'Marianne Corvellec',
  870. 'April and Jonathan Le Lous',
  871. 'April'
  872. ],
  873. [
  874. 'Michaela R. Brown',
  875. ],
  876. [
  877. 'Molly Gott'
  878. ],
  879. [
  880. 'Christopher Webber',
  881. 'David Thompson',
  882. 'Ludovic Courtès',
  883. ],
  884. ]
  885. i = 0
  886. for lps_timeslots in self.lps_dict.values():
  887. for lps_sessions in lps_timeslots.values():
  888. for session_info in lps_sessions.values():
  889. assert_equal(session_info['speakers'], speakers[i])
  890. i = i + 1
  891. speakers_noids = [
  892. 'Edward Snowden',
  893. 'Daniel Kahn Gillmor',
  894. 'Deb Nicholson',
  895. 'Richard Fontana',
  896. 'Paige Peterson',
  897. 'George Chriss',
  898. 'Kat Walsh',
  899. 'Stefano Zacchiroli',
  900. 'Marianne Corvellec',
  901. 'Jonathan Le Lous',
  902. 'Michaela R. Brown',
  903. 'Molly Gott',
  904. 'Christopher Webber',
  905. 'David Thompson',
  906. 'Ludovic Courtès',
  907. ]
  908. assert_equal(json_read(self.noids_filename), speakers_noids)
  909. def teardown(self):
  910. """Cleans up things after each test in this class."""
  911. # Remove `speakers.ids` file if it exists.
  912. if path.isfile(self.ids_filename):
  913. os.remove(self.ids_filename)
  914. # Remove `speakers.noids` file if it exists.
  915. if path.isfile(self.noids_filename):
  916. os.remove(self.noids_filename)
  917. @classmethod
  918. def teardown_class(self):
  919. """Clean up the mess created by this test class"""
  920. # Change back to the old cwd
  921. os.chdir(self.old_cwd)