You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

689 lines
33 KiB

  1. defmodule Microformats2ItemsTest do
  2. use ExUnit.Case
  3. doctest Microformats2.Items
  4. test "successfully parses a whole document" do
  5. str = """
  6. <!DOCTYPE html>
  7. <html>
  8. <head>
  9. <title>Blub</title>
  10. </head>
  11. <body>
  12. <h1>Blah</h1>
  13. <article class="h-card">
  14. <span class="p-name">Luke <span>lulu</span></span>
  15. <a href="blub" class="u-url">blah</a>
  16. </article>
  17. </body>
  18. </html>
  19. """
  20. ret = Microformats2.parse(str, "http://localhost")
  21. assert not Enum.empty?(ret[:items])
  22. end
  23. test "minimal h-card" do
  24. assert %{rels: _, rel_urls: _, items: [%{type: ["h-card"], properties: %{name: ["Frances Berriman"]}}]} =
  25. Microformats2.parse("<span class=\"h-card\">Frances Berriman</span>", "http://localhost")
  26. assert %{
  27. rels: _,
  28. rel_urls: _,
  29. items: [%{type: ["h-card"], properties: %{name: ["Ben Ward"], url: ["http://benward.me"]}}]
  30. } = Microformats2.parse("<a class=\"h-card\" href=\"http://benward.me\">Ben Ward</a>", "http://localhost")
  31. assert %{
  32. rels: _,
  33. rel_urls: _,
  34. items: [
  35. %{
  36. type: ["h-card"],
  37. properties: %{
  38. name: ["Rohit Khare"],
  39. url: ["http://rohit.khare.org/"],
  40. photo: [
  41. "https://s3.amazonaws.com/twitter_production/profile_images/53307499/180px-Rohit-sq_bigger.jpg"
  42. ]
  43. }
  44. }
  45. ]
  46. } =
  47. Microformats2.parse(
  48. """
  49. <a class="h-card" href="http://rohit.khare.org/">
  50. <img alt="Rohit Khare"
  51. src="https://s3.amazonaws.com/twitter_production/profile_images/53307499/180px-Rohit-sq_bigger.jpg">
  52. </a>
  53. """,
  54. "http://localhost"
  55. )
  56. end
  57. test "successfully parses a h-card with author name" do
  58. {:ok, str} = File.read("./test/documents/h_card_with_author.html")
  59. assert %{
  60. rels: _,
  61. rel_urls: _,
  62. items: [
  63. %{
  64. type: ["h-card"],
  65. properties: %{
  66. photo: ["https://webfwd.org/content/about-experts/300.mitchellbaker/mentor_mbaker.jpg"],
  67. name: ["Mitchell Baker"],
  68. url: ["http://blog.lizardwrangler.com/", "https://twitter.com/MitchellBaker"],
  69. org: ["Mozilla Foundation"],
  70. note: [
  71. "Mitchell is responsible for setting the direction and scope of the Mozilla Foundation and its activities."
  72. ],
  73. category: ["Strategy", "Leadership"]
  74. }
  75. }
  76. ]
  77. } = Microformats2.parse(str, "http://localhost")
  78. end
  79. test "successfully parses a h-event combined with h-card" do
  80. {:ok, str} = File.read("./test/documents/h_event_combined_h_card.html")
  81. assert %{
  82. rels: _,
  83. rel_urls: _,
  84. items: [
  85. %{
  86. type: ["h-event"],
  87. properties: %{
  88. name: ["IndieWebCamp 2012"],
  89. url: ["http://indiewebcamp.com/2012"],
  90. start: ["2012-06-30"],
  91. end: ["2012-07-01"],
  92. location: [
  93. %{
  94. value: "Geoloqi",
  95. type: ["h-card"],
  96. properties: %{
  97. name: ["Geoloqi"],
  98. org: ["Geoloqi"],
  99. url: ["http://geoloqi.com/"],
  100. street_address: ["920 SW 3rd Ave. Suite 400"],
  101. locality: ["Portland"],
  102. region: ["Oregon"]
  103. }
  104. }
  105. ]
  106. }
  107. }
  108. ]
  109. } = Microformats2.parse(str, "http://localhost")
  110. end
  111. test "successfully parses a h-card with org" do
  112. {:ok, str} = File.read("./test/documents/h_card_org.html")
  113. assert %{
  114. rels: _,
  115. rel_urls: _,
  116. items: [
  117. %{
  118. type: ["h-card"],
  119. properties: %{
  120. name: ["Mitchell Baker"],
  121. url: ["http://blog.lizardwrangler.com/"],
  122. org: ["Mozilla Foundation"]
  123. }
  124. }
  125. ]
  126. } = Microformats2.parse(str, "http://localhost")
  127. end
  128. test "successfully parses a h-card with h-card and org" do
  129. {:ok, str} = File.read("./test/documents/h_card_with_h_card_org.html")
  130. assert %{
  131. rels: _,
  132. rel_urls: _,
  133. items: [
  134. %{
  135. type: ["h-card"],
  136. properties: %{
  137. name: ["Mitchell Baker"],
  138. url: ["http://blog.lizardwrangler.com/"],
  139. org: [
  140. %{
  141. value: "Mozilla Foundation",
  142. type: ["h-card"],
  143. properties: %{name: ["Mozilla Foundation"], url: ["http://mozilla.org/"]}
  144. }
  145. ]
  146. }
  147. }
  148. ]
  149. } = Microformats2.parse(str, "http://localhost")
  150. end
  151. test "successfully parses a nested h-card h-org h-card" do
  152. {:ok, str} = File.read("./test/documents/nested_h_card_h_org_h_card.html")
  153. assert %{
  154. rels: _,
  155. rel_urls: _,
  156. items: [
  157. %{
  158. type: ["h-card"],
  159. properties: %{
  160. name: ["Mitchell Baker"],
  161. url: ["http://blog.lizardwrangler.com/"],
  162. org: [
  163. %{
  164. value: "Mozilla Foundation",
  165. type: ["h-card", "h-org"],
  166. properties: %{name: ["Mozilla Foundation"], url: ["http://mozilla.org/"]}
  167. }
  168. ]
  169. }
  170. }
  171. ]
  172. } = Microformats2.parse(str, "http://localhost")
  173. end
  174. test "successfully parses a nested h-card w/o attached property" do
  175. {:ok, str} = File.read("./test/documents/h_card_org_h_card.html")
  176. assert %{
  177. rels: _,
  178. rel_urls: _,
  179. items: [
  180. %{
  181. type: ["h-card"],
  182. properties: %{name: ["Mitchell Baker"], url: ["http://blog.lizardwrangler.com/"]},
  183. children: [
  184. %{type: ["h-card"], properties: %{name: ["Mozilla Foundation"], url: ["http://mozilla.org/"]}}
  185. ]
  186. }
  187. ]
  188. } = Microformats2.parse(str, "http://localhost")
  189. end
  190. test "resolves explicit url to absolute URL" do
  191. assert %{
  192. rels: _,
  193. rel_urls: _,
  194. items: [%{type: ["h-card"], properties: %{name: ["Ben Ward"], url: ["http://benward.me/foo"]}}]
  195. } =
  196. Microformats2.parse(
  197. "<div class=\"h-card\"><a class=\"u-url\" href=\"/foo\">Ben Ward</a></div>",
  198. "http://benward.me"
  199. )
  200. assert %{
  201. rels: _,
  202. rel_urls: _,
  203. items: [%{type: ["h-card"], properties: %{name: ["Ben Ward"], url: ["http://benward.me/foo"]}}]
  204. } = Microformats2.parse("<div class=\"h-card\"><a href=\"/foo\">Ben Ward</a></div>", "http://benward.me")
  205. end
  206. test "jeena entry" do
  207. {:ok, str} = File.read("./test/documents/real_world_note.html")
  208. assert %{
  209. rels: _,
  210. rel_urls: _,
  211. items: [
  212. %{
  213. properties: %{
  214. author: [
  215. %{
  216. properties: %{
  217. name: ["Jeena"],
  218. photo: ["http://localhost/avatar.jpg"],
  219. url: ["http://localhost/"]
  220. },
  221. type: ["h-card"],
  222. value: "Jeena"
  223. }
  224. ],
  225. comment: [
  226. %{
  227. properties: %{
  228. author: [
  229. %{
  230. properties: %{
  231. name: ["Christian Kruse"],
  232. photo: [
  233. "http://localhost/cache?size=40x40>&url=https%3A%2F%2Fwwwtech.de%2Fimages%2Fchristian-kruse-242470c34a3671da4cab3e3b0d941729.jpg%3Fvsn%3Dd"
  234. ],
  235. url: ["https://wwwtech.de/notes/132"]
  236. },
  237. type: ["h-card"],
  238. value: "Christian Kruse"
  239. }
  240. ],
  241. content: [%{html: "Of course he is!", text: "Of course he is!"}],
  242. name: ["Christian Kruse,\n\t\t 4 days ago\n\t\t Of course he is!"],
  243. published: ["2016-02-19T10:50:17Z"],
  244. url: ["https://wwwtech.de/notes/132"]
  245. },
  246. type: ["h-cite"],
  247. value: "Christian Kruse,\n\t\t 4 days ago\n\t\t Of course he is!"
  248. }
  249. ],
  250. content: [%{html: "<p>He&apos;s right, you know?</p>", text: "He's right, you know?"}],
  251. in_reply_to: ["https://wwwtech.de/pictures/51"],
  252. name: ["Note #587"],
  253. published: ["2016-02-18T19:33:25Z"],
  254. updated: ["2016-02-18T19:33:25Z"],
  255. url: ["http://localhost/comments/587"]
  256. },
  257. type: ["h-as-note", "h-entry"]
  258. }
  259. ]
  260. } = Microformats2.parse(str, "http://localhost")
  261. end
  262. test "Aaron Parecki: https://aaronparecki.com/2018/12/17/7/blocking-domains" do
  263. {:ok, str} = File.read("./test/documents/blocking-domains.html")
  264. assert %{
  265. items: [
  266. %{
  267. properties: %{
  268. author: ["http://localhost/"],
  269. category: ["webmention", "p3k", "block", "spam"],
  270. comment: [
  271. %{
  272. children: [
  273. %{
  274. properties: %{
  275. name: ["@freakazoid"],
  276. url: ["https://retro.social/@freakazoid"]
  277. },
  278. type: ["h-card"]
  279. },
  280. %{
  281. properties: %{
  282. name: ["@aaronpk"],
  283. url: ["https://aaronparecki.com/aaronpk"]
  284. },
  285. type: ["h-card"]
  286. }
  287. ],
  288. properties: %{
  289. author: [
  290. %{
  291. properties: %{
  292. name: ["Jacky Alciné"],
  293. photo: [
  294. "https://pkcdn.xyz/playvicious.social/9b9144f41aa329413223cc8779b82ed39e7256a5f28e1fdb1ea4e5e6c901cd47.png"
  295. ],
  296. url: ["https://playvicious.social/@jalcine"]
  297. },
  298. type: ["h-card"],
  299. value: "Jacky Alciné"
  300. }
  301. ],
  302. content: [
  303. %{
  304. html:
  305. "<p><span class=\"h-card\"><a href=\"https://retro.social/@freakazoid\" class=\"u-url\" rel=\"nofollow\">@<span>freakazoid</span></a></span> This is a case for handling an attack vector (in the realm of spam) from <span class=\"h-card\"><a href=\"https://aaronparecki.com/aaronpk\" class=\"u-url\" rel=\"nofollow\">@<span>aaronpk</span></a></span> on the topic <a href=\"https://aaronparecki.com/2018/12/17/7/blocking-domains\" rel=\"nofollow\"><span>https://</span><span>aaronparecki.com/2018/12/17/7/</span><span>blocking-domains</span></a></p>",
  306. text:
  307. "@freakazoid This is a case for handling an attack vector (in the realm of spam) from @aaronpk on the topic https://aaronparecki.com/2018/12/17/7/blocking-domains"
  308. }
  309. ],
  310. name: [
  311. "@freakazoid This is a case for handling an attack vector (in the realm of spam) from @aaronpk on the topic https://aaronparecki.com/2018/12/17/7/blocking-domains"
  312. ],
  313. published: ["2018-12-17T21:56:53+00:00"],
  314. url: ["https://playvicious.social/@jalcine/101258612771728535"]
  315. },
  316. type: ["h-cite"],
  317. value:
  318. "@freakazoid This is a case for handling an attack vector (in the realm of spam) from @aaronpk on the topic https://aaronparecki.com/2018/12/17/7/blocking-domains"
  319. },
  320. %{
  321. properties: %{
  322. author: [
  323. %{
  324. properties: %{
  325. name: ["fireburn.ru"],
  326. photo: ["/assets/images/no-profile-photo.png"],
  327. url: ["https://fireburn.ru"]
  328. },
  329. type: ["h-card"],
  330. value: "fireburn.ru"
  331. }
  332. ],
  333. content: [
  334. %{
  335. html:
  336. "<p>Finally there is a blocklist interface! Now I can send webmentions from myself and not block my domain.</p><p>Do you plan on building a premoderation queue tied to Vouch support?</p>",
  337. text:
  338. "Finally there is a blocklist interface! Now I can send webmentions from myself and not block my domain.Do you plan on building a premoderation queue tied to Vouch support?"
  339. }
  340. ],
  341. name: [
  342. "Finally there is a blocklist interface! Now I can send webmentions from myself and not block my domain.Do you plan on building a premoderation queue tied to Vouch support?"
  343. ],
  344. published: ["2018-12-18T09:45:49+03:00"],
  345. url: ["https://fireburn.ru/reply/1545115549"]
  346. },
  347. type: ["h-cite"],
  348. value:
  349. "Finally there is a blocklist interface! Now I can send webmentions from myself and not block my domain.Do you plan on building a premoderation queue tied to Vouch support?"
  350. },
  351. %{
  352. properties: %{
  353. author: [
  354. %{
  355. properties: %{
  356. name: ["chrisburnell.com"],
  357. photo: ["/assets/images/no-profile-photo.png"],
  358. url: ["https://chrisburnell.com"]
  359. },
  360. type: ["h-card"],
  361. value: "chrisburnell.com"
  362. }
  363. ],
  364. name: ["Chris Burnell"],
  365. photo: [
  366. "https://pkcdn.xyz/chrisburnell.com/9ac30b63aeddbcb10a6b8b9e231022d86fe3d30e6e279c1bc0c341e103b64119.png"
  367. ],
  368. published: ["2018-12-18T08:58:31-08:00"],
  369. url: ["https://chrisburnell.com/"]
  370. },
  371. type: ["h-cite"],
  372. value: "Chris Burnell"
  373. }
  374. ],
  375. content: [
  376. %{
  377. html:
  378. "<p>For the past week or so, I&apos;ve been getting a series of Pingbacks from a spam blog that reposts a blog post a couple times a day as a new post each time. It&apos;s up to about 220 copies of the post, each one having sent me a Pingback, and each one showing up in my <a href=\"https://aaronparecki.com/2018/04/20/46/indieweb-reader-my-new-home-on-the-internet\">reader</a> as a notification, which also causes it to be sent to my phone.</p><img src=\"https://aaronparecki.com/2018/12/17/7/image-1.jpg\" alt=\"\"/><p>Since I use <a href=\"https://webmention.io\">webmention.io</a> to handle my incoming Webmentions (and Pingbacks), this would be the best place to block the site, rather than filtering it out in my reader or my website. </p><p>Webmention.io previously had no way to actually completely block a domain. As Webmentions have started growing in popularity, it&apos;s become obvious that we need more tools to combat spam and abuse. While this site was actually sending me Pingbacks, the same applies to Webmentions.</p><p>Today I added a new feature to <a href=\"https://webmention.io\">webmention.io</a> to allow people to entirely block a domain, and delete any webmentions received from that domain. </p><img src=\"https://aaronparecki.com/2018/12/17/7/image-2.png\" alt=\"\"/><p>From the dashboard, you can click the &quot;X&quot; on any recent webmention, or you can paste a URL from one you&apos;ve received in the past. You&apos;ll be taken to this screen where you can either delete just the one webmention, or entirely block the domain.</p><p>Once you&apos;ve blocked the domain, it will show up in your blocklists page!</p><img src=\"https://aaronparecki.com/2018/12/17/7/image-3.png\" alt=\"\"/><p>I hope this helps others keep out spam as well! I&apos;m sure looking forward to never seeing that notification on my phone again!</p><div id=\"codefund_ad\"></div>",
  379. text:
  380. "For the past week or so, I've been getting a series of Pingbacks from a spam blog that reposts a blog post a couple times a day as a new post each time. It's up to about 220 copies of the post, each one having sent me a Pingback, and each one showing up in my reader as a notification, which also causes it to be sent to my phone.Since I use webmention.io to handle my incoming Webmentions (and Pingbacks), this would be the best place to block the site, rather than filtering it out in my reader or my website. Webmention.io previously had no way to actually completely block a domain. As Webmentions have started growing in popularity, it's become obvious that we need more tools to combat spam and abuse. While this site was actually sending me Pingbacks, the same applies to Webmentions.Today I added a new feature to webmention.io to allow people to entirely block a domain, and delete any webmentions received from that domain. From the dashboard, you can click the \"X\" on any recent webmention, or you can paste a URL from one you've received in the past. You'll be taken to this screen where you can either delete just the one webmention, or entirely block the domain.Once you've blocked the domain, it will show up in your blocklists page!I hope this helps others keep out spam as well! I'm sure looking forward to never seeing that notification on my phone again!"
  381. }
  382. ],
  383. like: [
  384. %{
  385. # properties: %{
  386. # author: [
  387. # %{
  388. # properties: %{
  389. # name: ["Eddie Hinkle"],
  390. # photo: [
  391. # "https://pkcdn.xyz/eddiehinkle.com/cf9f85e26d4be531bc908d37f69bff1c50b50b87fd066b254f1332c3553df1a8.jpg"
  392. # ],
  393. # url: ["https://eddiehinkle.com/"]
  394. # },
  395. # type: ["h-card"],
  396. # value: "Eddie Hinkle"
  397. # }
  398. # ],
  399. # name: [
  400. # "https://pkcdn.xyz/eddiehinkle.com/cf9f85e26d4be531bc908d37f69bff1c50b50b87fd066b254f1332c3553df1a8.jpgEddie Hinkle"
  401. # ],
  402. # url: ["https://eddiehinkle.com/2018/12/18/1/like/"]
  403. # },
  404. # type: ["h-cite"],
  405. # value:
  406. # "https://pkcdn.xyz/eddiehinkle.com/cf9f85e26d4be531bc908d37f69bff1c50b50b87fd066b254f1332c3553df1a8.jpgEddie Hinkle"
  407. },
  408. %{
  409. # properties: %{
  410. # author: [
  411. # %{
  412. # properties: %{
  413. # name: ["Vika"],
  414. # photo: [
  415. # "https://pkcdn.xyz/fireburn.ru/2c643998489fa0cea4689c0a154470f6e133f3ea0547fcce463eaf99312f3e42.png"
  416. # ],
  417. # url: ["https://fireburn.ru/"]
  418. # },
  419. # type: ["h-card"],
  420. # value: "Vika"
  421. # }
  422. # ],
  423. # name: [
  424. # "https://pkcdn.xyz/fireburn.ru/2c643998489fa0cea4689c0a154470f6e133f3ea0547fcce463eaf99312f3e42.pngVika"
  425. # ],
  426. # url: ["https://fireburn.ru/like/1545115461"]
  427. # },
  428. # type: ["h-cite"],
  429. # value:
  430. # "https://pkcdn.xyz/fireburn.ru/2c643998489fa0cea4689c0a154470f6e133f3ea0547fcce463eaf99312f3e42.pngVika"
  431. }
  432. ],
  433. location: [
  434. %{
  435. properties: %{
  436. latitude: [""],
  437. locality: ["Portland"],
  438. longitude: [""],
  439. name: ["Portland,\n Oregon•\n 52°F"],
  440. region: ["Oregon"]
  441. },
  442. type: ["h-adr"],
  443. value: "Portland,\n Oregon•\n 52°F"
  444. }
  445. ],
  446. name: ["Blocking Domains in webmention.io"],
  447. pk_num_likes: ["2"],
  448. pk_num_mentions: ["1"],
  449. pk_num_replies: ["2"],
  450. published: ["2018-12-17T13:24:28-08:00"],
  451. url: ["https://aaronparecki.com/2018/12/17/7/blocking-domains"]
  452. },
  453. type: ["h-entry"]
  454. },
  455. %{
  456. properties: %{
  457. bday: ["--12-28"],
  458. callsign: ["W7APK"],
  459. name: ["Aaron Parecki"],
  460. note: [
  461. "Hi, I'm Aaron Parecki, co-founder of\nIndieWebCamp.\nI maintain oauth.net, write and consult about OAuth, and\nam the editor of several W3C specfications. I record videos for local conferences and help run a podcast studio in Portland.I wrote 100 songs in 100 days! I've been tracking my location since 2008,\nand write down everything I eat and drink.\nI've spoken at conferences around the world about\nowning your data,\nOAuth,\nquantified self,\nand explained why R is a vowel. Read more."
  462. ],
  463. org: [
  464. %{
  465. properties: %{
  466. name: ["IndieWebCamp"],
  467. url: ["https://indieweb.org/"]
  468. },
  469. type: ["h-card"],
  470. value: "IndieWebCamp"
  471. },
  472. %{
  473. properties: %{name: ["oauth.net"], url: ["https://oauth.net/"]},
  474. type: ["h-card"],
  475. value: "oauth.net"
  476. },
  477. %{
  478. properties: %{
  479. name: ["Okta"],
  480. photo: ["http://localhost/images/okta.png"],
  481. role: ["Developer Advocate"],
  482. url: ["https://developer.okta.com/"]
  483. },
  484. type: ["h-card"],
  485. value: "Okta"
  486. },
  487. %{
  488. properties: %{
  489. name: ["IndieWebCamp"],
  490. photo: ["http://localhost/images/indiewebcamp.png"],
  491. role: ["Founder"],
  492. url: ["https://indieweb.org/"]
  493. },
  494. type: ["h-card"],
  495. value: "IndieWebCamp"
  496. },
  497. %{
  498. properties: %{
  499. name: ["W3C"],
  500. photo: ["http://localhost/images/w3c.png"],
  501. role: ["Editor"],
  502. url: ["https://www.w3.org/"]
  503. },
  504. type: ["h-card"],
  505. value: "W3C"
  506. },
  507. %{
  508. properties: %{
  509. name: ["Stream PDX"],
  510. photo: ["http://localhost/images/streampdx.png"],
  511. role: ["Co-Founder"],
  512. url: ["https://streampdx.com"]
  513. },
  514. type: ["h-card"],
  515. value: "Stream PDX"
  516. },
  517. %{
  518. properties: %{
  519. name: ["backpedal.tv"],
  520. photo: ["http://localhost/images/backpedal.png"],
  521. url: ["https://backpedal.tv"]
  522. },
  523. type: ["h-card"],
  524. value: "backpedal.tv"
  525. }
  526. ],
  527. photo: ["http://localhost/images/profile.jpg"],
  528. uid: ["http://localhost/"],
  529. url: ["http://localhost/", "https://w7apk.com"]
  530. },
  531. type: ["h-card"]
  532. }
  533. ],
  534. rel_urls: %{
  535. "http://creativecommons.org/licenses/by/3.0/" => %{
  536. rels: ["license"],
  537. text: "Creative Commons Attribution 3.0 License"
  538. },
  539. "http://localhost/assets/admin.css" => %{rels: ["stylesheet"]},
  540. "http://localhost/assets/carbon.css" => %{rels: ["stylesheet"]},
  541. "http://localhost/assets/featherlight-1.5.0/featherlight.min.css" => %{
  542. rels: ["stylesheet"]
  543. },
  544. "http://localhost/assets/icomoon/style.css" => %{rels: ["stylesheet"]},
  545. "http://localhost/assets/pulse.css" => %{rels: ["stylesheet"]},
  546. "http://localhost/assets/story.css" => %{rels: ["stylesheet"]},
  547. "http://localhost/assets/styles.4.css" => %{rels: ["stylesheet"]},
  548. "http://localhost/assets/weather-icons/css/weather-icons.css" => %{
  549. rels: ["stylesheet"]
  550. },
  551. "http://localhost/key.txt" => %{rels: ["pgpkey"]},
  552. "http://localhost/semantic/2.2.6/semantic.min.css" => %{
  553. rels: ["stylesheet"],
  554. type: "text/css"
  555. },
  556. "http://localhost/site/styles.1.css" => %{rels: ["stylesheet"]},
  557. "https://aaronparecki.com/" => %{rels: ["openid.delegate"]},
  558. "https://aaronparecki.com/2018/12/17/7/blocking-domains" => %{
  559. rels: ["nofollow"],
  560. text: "https://aaronparecki.com/2018/12/17/7/blocking-domains"
  561. },
  562. "https://aaronparecki.com/2018/12/17/7/blocking-domains.as2" => %{
  563. rels: ["alternate"],
  564. type: "application/activity+json"
  565. },
  566. "https://aaronparecki.com/2018/12/17/7/blocking-domains.jf2" => %{
  567. rels: ["alternate"],
  568. type: "application/jf2+json"
  569. },
  570. "https://aaronparecki.com/2018/12/17/7/blocking-domains.json" => %{
  571. rels: ["alternate"],
  572. type: "application/mf2+json"
  573. },
  574. "https://aaronparecki.com/aaronpk" => %{
  575. rels: ["nofollow"],
  576. text: "@aaronpk"
  577. },
  578. "https://micro.blog/aaronpk" => %{rels: ["me"]},
  579. "https://openid.indieauth.com/openid" => %{rels: ["openid.server"]},
  580. "https://retro.social/@freakazoid" => %{
  581. rels: ["nofollow"],
  582. text: "@freakazoid"
  583. },
  584. "https://webmention.io/aaronpk/webmention" => %{rels: ["webmention"]},
  585. "sms:+15035678642" => %{rels: ["me"]}
  586. },
  587. rels: %{
  588. "alternate" => [
  589. "https://aaronparecki.com/2018/12/17/7/blocking-domains.json",
  590. "https://aaronparecki.com/2018/12/17/7/blocking-domains.jf2",
  591. "https://aaronparecki.com/2018/12/17/7/blocking-domains.as2"
  592. ],
  593. "license" => ["http://creativecommons.org/licenses/by/3.0/"],
  594. "me" => ["sms:+15035678642", "https://micro.blog/aaronpk"],
  595. "nofollow" => [
  596. "https://retro.social/@freakazoid",
  597. "https://aaronparecki.com/aaronpk",
  598. "https://aaronparecki.com/2018/12/17/7/blocking-domains"
  599. ],
  600. "openid.delegate" => ["https://aaronparecki.com/"],
  601. "openid.server" => ["https://openid.indieauth.com/openid"],
  602. "pgpkey" => ["http://localhost/key.txt"],
  603. "stylesheet" => [
  604. "http://localhost/semantic/2.2.6/semantic.min.css",
  605. "http://localhost/assets/icomoon/style.css",
  606. "http://localhost/assets/weather-icons/css/weather-icons.css",
  607. "http://localhost/assets/featherlight-1.5.0/featherlight.min.css",
  608. "http://localhost/assets/admin.css",
  609. "http://localhost/assets/pulse.css",
  610. "http://localhost/assets/styles.4.css",
  611. "http://localhost/site/styles.1.css",
  612. "http://localhost/assets/carbon.css",
  613. "http://localhost/assets/story.css"
  614. ],
  615. "webmention" => ["https://webmention.io/aaronpk/webmention"]
  616. }
  617. } = Microformats2.parse(str, "http://localhost")
  618. end
  619. test "invalid attrs" do
  620. str = File.read!("./test/documents/invalid-attrs.html")
  621. assert %{
  622. items: [
  623. %{
  624. properties: %{
  625. author: [
  626. %{
  627. properties: %{
  628. name: [
  629. "http://localhost:9000/koype-dev/photos/floating/original_self-portrait.jpgJacky Alciné"
  630. ],
  631. photo: ["http://localhost:9000/koype-dev/photos/floating/original_self-portrait.jpg"],
  632. url: ["http://localhost/"]
  633. },
  634. type: ["h-card"],
  635. value: "http://localhost/"
  636. }
  637. ],
  638. like_of: [
  639. %{
  640. properties: %{
  641. name: ["67efebc0.ngrok.io"],
  642. url: ["http://67efebc0.ngrok.io/post/b5a600c5-98a0-4112-b2d5-9df7c600f5e2"]
  643. },
  644. type: ["h-cite"],
  645. value: "http://67efebc0.ngrok.io/post/b5a600c5-98a0-4112-b2d5-9df7c600f5e2"
  646. }
  647. ],
  648. name: ["LikedLiked\n 67efebc0.ngrok.io"],
  649. published: ["2018-12-19T00:19:04.410503Z"],
  650. summary: ["LikedLiked\n 67efebc0.ngrok.io"],
  651. uid: ["http://localhost/post/a4ab5c98-c476-4800-9f09-2f7f5a337f32"],
  652. updated: ["2018-12-19 00:19:04.406330"],
  653. url: ["http://localhost/post/a4ab5c98-c476-4800-9f09-2f7f5a337f32"]
  654. },
  655. type: ["h-entry"]
  656. }
  657. ],
  658. rel_urls: %{"http://localhost/" => %{rels: ["me"], text: "Jacky Alciné"}},
  659. rels: %{"me" => ["http://localhost/"]}
  660. } =
  661. Microformats2.parse(str, "http://localhost")
  662. end
  663. end