tests.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. import datetime
  2. import json
  3. import os
  4. import unittest
  5. import pytz
  6. from rd import RD, Link, Property, Title, jrd, xrd
  7. PWD = os.path.abspath(os.path.dirname(__file__))
  8. class TestXRDProperty(unittest.TestCase):
  9. def testassignment(self):
  10. # test RD object
  11. rd = RD()
  12. rd.properties.append('http://example.com/lang')
  13. rd.properties.append(('http://example.com/lang', 'en-US'))
  14. rd.properties.append(Property('http://example.com/lang'))
  15. rd.properties.append(Property('http://example.com/lang', 'en-US'))
  16. prop = rd.properties[0]
  17. self.assertEqual(prop.type, "http://example.com/lang")
  18. self.assertIsNone(prop.value)
  19. prop = rd.properties[1]
  20. self.assertEqual(prop.type, "http://example.com/lang")
  21. self.assertEqual(prop.value, "en-US")
  22. prop = rd.properties[2]
  23. self.assertEqual(prop.type, "http://example.com/lang")
  24. self.assertIsNone(prop.value)
  25. prop = rd.properties[3]
  26. self.assertEqual(prop.type, "http://example.com/lang")
  27. self.assertEqual(prop.value, "en-US")
  28. expected = [None, 'en-US', None, 'en-US']
  29. actual = [p.value for p in rd.properties("http://example.com/lang")]
  30. self.assertEqual(expected, actual)
  31. # test Link object
  32. link = Link()
  33. link.properties.append('http://example.com/lang')
  34. link.properties.append(('http://example.com/lang', 'en-US'))
  35. link.properties.append(Property('http://example.com/lang'))
  36. link.properties.append(Property('http://example.com/lang', 'en-US'))
  37. prop = link.properties[0]
  38. self.assertEqual(prop.type, "http://example.com/lang")
  39. self.assertIsNone(prop.value)
  40. prop = link.properties[1]
  41. self.assertEqual(prop.type, "http://example.com/lang")
  42. self.assertEqual(prop.value, "en-US")
  43. prop = link.properties[2]
  44. self.assertEqual(prop.type, "http://example.com/lang")
  45. self.assertIsNone(prop.value)
  46. prop = link.properties[3]
  47. self.assertEqual(prop.type, "http://example.com/lang")
  48. self.assertEqual(prop.value, "en-US")
  49. expected = [None, 'en-US', None, 'en-US']
  50. actual = [p.value for p in rd.properties("http://example.com/lang")]
  51. self.assertEqual(expected, actual)
  52. def testequals(self):
  53. # same type and value
  54. p1 = Property('http://example.com/p1', '1234')
  55. p2 = Property('http://example.com/p1', '1234')
  56. self.assertTrue(p1 == p2)
  57. # same type, no value
  58. p1 = Property('http://example.com/p1')
  59. p2 = Property('http://example.com/p1')
  60. self.assertTrue(p1 == p2)
  61. def testnotequals(self):
  62. # same value, different type
  63. p1 = Property('http://example.com/p1', '1234')
  64. p2 = Property('http://example.com/p2', '1234')
  65. self.assertFalse(p1 == p2)
  66. # same type, different value
  67. p1 = Property('http://example.com/p1', '1234')
  68. p2 = Property('http://example.com/p1', '9876')
  69. self.assertFalse(p1 == p2)
  70. # same type, one value missing
  71. p1 = Property('http://example.com/p1')
  72. p2 = Property('http://example.com/p1', '12345')
  73. self.assertFalse(p1 == p2)
  74. # different type, no value
  75. p1 = Property('http://example.com/p1')
  76. p2 = Property('http://example.com/p2')
  77. self.assertFalse(p1 == p2)
  78. class TestXRDTitle(unittest.TestCase):
  79. def testassignment(self):
  80. link = Link()
  81. link.titles.append('myfeed')
  82. link.titles.append(('myfeed', 'en-US'))
  83. link.titles.append(Title('myfeed'))
  84. link.titles.append(Title('myfeed', 'en-US'))
  85. title = link.titles[0]
  86. self.assertEqual(title.value, "myfeed")
  87. self.assertIsNone(title.lang)
  88. title = link.titles[1]
  89. self.assertEqual(title.value, "myfeed")
  90. self.assertEqual(title.lang, "en-US")
  91. title = link.titles[2]
  92. self.assertEqual(title.value, "myfeed")
  93. self.assertIsNone(title.lang)
  94. title = link.titles[3]
  95. self.assertEqual(title.value, "myfeed")
  96. self.assertEqual(title.lang, "en-US")
  97. def testequals(self):
  98. # same title and lang
  99. t1 = Title('myfeed', lang='en-US')
  100. t2 = Title('myfeed', lang='en-US')
  101. self.assertTrue(t1 == t2)
  102. # same title, no lang
  103. t1 = Title('myfeed')
  104. t2 = Title('myfeed')
  105. self.assertTrue(t1 == t2)
  106. def testnotequals(self):
  107. # same title, different lang
  108. t1 = Title('myfeed', 'en-US')
  109. t2 = Title('myfeed', 'en-GB')
  110. self.assertTrue(t1 != t2)
  111. # same lang, different title
  112. t1 = Title('myfeed', 'en-US')
  113. t2 = Title('yourfeed', 'en-US')
  114. self.assertTrue(t1 != t2)
  115. # same title, one missing lang
  116. t1 = Title('myfeed')
  117. t2 = Title('myfeed', 'en-GB')
  118. self.assertTrue(t1 != t2)
  119. # different title, no lang
  120. t1 = Title('myfeed')
  121. t2 = Title('yourfeed')
  122. self.assertTrue(t1 != t2)
  123. class TestJRDDeserialization(unittest.TestCase):
  124. def setUp(self):
  125. self.rd = jrd.loads("""{
  126. "links": [
  127. {
  128. "template": "http://google.com/{uri}",
  129. "titles": {
  130. "en_us": "this is my rel",
  131. "default": "the real rel"
  132. }
  133. }
  134. ],
  135. "properties": {
  136. "mimetype": "text/plain"
  137. }
  138. }""")
  139. def testproperty(self):
  140. prop = self.rd.properties[0]
  141. self.assertEqual(prop.type, "mimetype")
  142. self.assertEqual(prop.value, "text/plain")
  143. def testlink(self):
  144. link = self.rd.links[0]
  145. self.assertEqual(link.template, "http://google.com/{uri}")
  146. for title in link.titles:
  147. if title.lang == "en_us":
  148. self.assertEqual(title.value, "this is my rel")
  149. elif title.lang == "none":
  150. self.assertEqual(title.value, "the real rel")
  151. class TestXRDDeserialization(unittest.TestCase):
  152. def setUp(self):
  153. self.rd = xrd.loads("""<?xml version="1.0" ?>
  154. <XRD xml:id="1234" xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
  155. <Property type="mimetype">text/plain</Property>
  156. <Property type="none"></Property>
  157. <Link template="http://google.com/{uri}">
  158. <Title xml:lang="en_us">this is my rel</Title>
  159. </Link>
  160. </XRD>
  161. """)
  162. def testxmlid(self):
  163. self.assertEqual(self.rd.xml_id, "1234")
  164. def testproperty(self):
  165. prop = self.rd.properties[0]
  166. self.assertEqual(prop.type, "mimetype")
  167. self.assertEqual(prop.value, "text/plain")
  168. def testnilproperty(self):
  169. prop = self.rd.properties[1]
  170. self.assertEqual(prop.type, "none")
  171. self.assertTrue(prop.value is None)
  172. def testlink(self):
  173. link = self.rd.links[0]
  174. self.assertEqual(link.template, "http://google.com/{uri}")
  175. class TestJRDSerialization(unittest.TestCase):
  176. def setUp(self):
  177. self.rd = RD()
  178. self.rd.properties.append(('mimetype', 'text/plain'))
  179. self.rd.links.append(Link(template="http://google.com/{uri}"))
  180. self.doc = json.loads(self.rd.to_json())
  181. def testproperty(self):
  182. props = self.doc['properties']
  183. self.assertTrue('mimetype' in props)
  184. self.assertEqual(props['mimetype'], 'text/plain')
  185. def testlink(self):
  186. link = self.doc['links'][0]
  187. self.assertEqual(link['template'], "http://google.com/{uri}")
  188. class TestXRDSerialization(unittest.TestCase):
  189. def setUp(self):
  190. self.rd = RD('9876')
  191. self.rd.properties.append(('mimetype', 'text/plain'))
  192. self.rd.properties.append('none')
  193. self.rd.links.append(Link(template="http://google.com/{uri}"))
  194. self.doc = self.rd.to_xml().documentElement
  195. def testxmlid(self):
  196. self.assertEqual(self.doc.getAttribute('xml:id'), '9876')
  197. def testproperty(self):
  198. prop = self.doc.getElementsByTagName('Property')[0]
  199. self.assertEqual(prop.getAttribute('type'), 'mimetype')
  200. self.assertEqual(xrd._get_text(prop), 'text/plain')
  201. def testnilproperty(self):
  202. prop = self.doc.getElementsByTagName('Property')[1]
  203. self.assertEqual(prop.getAttribute('type'), 'none')
  204. self.assertEqual(prop.getAttribute('xsi:nil'), 'true')
  205. self.assertTrue(xrd._get_text(prop) is None)
  206. def testlink(self):
  207. link = self.doc.getElementsByTagName('Link')[0]
  208. self.assertEqual(link.getAttribute('template'), "http://google.com/{uri}")
  209. class ExamplesTestCase(unittest.TestCase):
  210. def load_example(self, filename):
  211. path = os.path.join(PWD, 'examples', filename)
  212. with open(path) as infile:
  213. data = infile.read()
  214. return data
  215. class TextConversionExamples(ExamplesTestCase):
  216. def testrfc6415a(self):
  217. data = self.load_example("xrd-rfc6415-A.xml")
  218. x = xrd.loads(data)
  219. data = self.load_example("jrd-rfc6415-A.json")
  220. j = jrd.loads(data)
  221. self.assertEqual(x.subject, j.subject)
  222. self.assertEqual(x.expires, j.expires)
  223. self.assertEqual(x.aliases[0], j.aliases[0])
  224. self.assertEqual(x.aliases[1], j.aliases[1])
  225. xprops = [str(p) for p in x.properties]
  226. jprops = [str(p) for p in j.properties]
  227. self.assertCountEqual(xprops, jprops)
  228. xlink = list(x.links("copyright"))[0]
  229. jlink = list(j.links("copyright"))[0]
  230. self.assertEqual(xlink.template, jlink.template)
  231. xauthors = list(x.links("author"))
  232. jauthors = list(j.links("author"))
  233. self.assertEqual(len(xauthors), len(jauthors))
  234. # first authors link
  235. xlink = xauthors[0]
  236. jlink = jauthors[0]
  237. self.assertEqual(xlink.type, jlink.type)
  238. self.assertEqual(xlink.href, jlink.href)
  239. self.assertEqual(sorted(xlink.properties), sorted(jlink.properties))
  240. self.assertEqual(sorted(xlink.titles), sorted(jlink.titles))
  241. # second authors link
  242. xlink = xauthors[1]
  243. jlink = jauthors[1]
  244. self.assertEqual(xlink.href, jlink.href)
  245. self.assertEqual(sorted(xlink.titles), sorted(jlink.titles))
  246. class TestXRDExamples(ExamplesTestCase):
  247. def test10b1(self):
  248. data = self.load_example("xrd-1.0-b1.xml")
  249. rd = xrd.loads(data)
  250. self.assertEqual(rd.expires, datetime.datetime(1970, 1, 1, tzinfo=pytz.utc))
  251. self.assertEqual(rd.subject, "http://example.com/gpburdell")
  252. prop = rd.properties[0]
  253. self.assertEqual(prop.type, "http://spec.example.net/type/person")
  254. self.assertIsNone(prop.value)
  255. link = rd.links[0]
  256. self.assertEqual(link.rel, "http://spec.example.net/auth/1.0")
  257. self.assertEqual(link.href, "http://services.example.com/auth")
  258. # this is a big, multipart link
  259. link = rd.links[1]
  260. self.assertEqual(link.rel, "http://spec.example.net/photo/1.0")
  261. self.assertEqual(link.href, "http://photos.example.com/gpburdell.jpg")
  262. self.assertEqual(link.type, "image/jpeg")
  263. title = link.titles[0]
  264. self.assertEqual(title.value, "User Photo")
  265. self.assertEqual(title.lang, "en")
  266. title = link.titles[1]
  267. self.assertEqual(title.value, "Benutzerfoto")
  268. self.assertEqual(title.lang, "de")
  269. prop = link.properties[0]
  270. self.assertEqual(prop.type, "http://spec.example.net/created/1.0")
  271. self.assertEqual(prop.value, "1970-01-01")
  272. # signature stuff is not yet supported
  273. # def test10b2(self):
  274. # data = self.load_example("xrd-1.0-b2.xml")
  275. # xrd.loads(data)
  276. class TestJRDExamples(ExamplesTestCase):
  277. def test41hostmeta(self):
  278. data = self.load_example("jrd-wf02-4.1-hostmeta.json")
  279. rd = jrd.loads(data)
  280. link = rd.find_link('lrdd')
  281. self.assertEqual(link.type, "application/json")
  282. self.assertEqual(link.template, "https://example.com/lrdd/?f=json&uri={uri}")
  283. def test41lrdd(self):
  284. data = self.load_example("jrd-wf02-4.1-lrdd.json")
  285. rd = jrd.loads(data)
  286. self.assertEqual(rd.subject, "acct:bob@example.com")
  287. self.assertEqual(rd.expires, datetime.datetime(2012, 10, 12, 20, 56, 11, tzinfo=pytz.utc))
  288. self.assertEqual(rd.aliases[0], "http://www.example.com/~bob/")
  289. links = {
  290. "http://webfinger.net/rel/avatar": "http://www.example.com/~bob/bob.jpg",
  291. "http://webfinger.net/rel/profile-page": "http://www.example.com/~bob/",
  292. "http://packetizer.com/rel/blog": "http://blogs.example.com/bob/",
  293. "vcard": "http://www.example.com/~bob/bob.vcf",
  294. }
  295. for rel, href in list(links.items()):
  296. link = rd.find_link(rel)
  297. self.assertEqual(link.href, href)
  298. def test42hostmeta(self):
  299. data = self.load_example("jrd-wf02-4.2-hostmeta.json")
  300. rd = jrd.loads(data)
  301. self.assertEqual(rd.subject, "acct:carol@example.com")
  302. links = {
  303. "http://webfinger.net/rel/avatar": "http://example.com/~alice/alice.jpg",
  304. "http://specs.openid.net/auth/2.0/provider": "https://openid.example.com/carol",
  305. }
  306. for rel, href in list(links.items()):
  307. link = rd.find_link(rel)
  308. self.assertEqual(link.href, href)
  309. if __name__ == '__main__':
  310. unittest.main()