test_lps_gen.py 35 KB

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