PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/test/pyxpcom/test_koWindowsIntegration.py

https://gitlab.com/Smileyt/KomodoEdit
Python | 247 lines | 241 code | 5 blank | 1 comment | 6 complexity | af3971ee0342568502dbeb1456bc30e0 MD5 | raw file
  1. from xpcom import components, COMException
  2. from xpcom.server import WrapObject, UnwrapObject
  3. from os.path import abspath, join, split
  4. import inspect, imp, sys
  5. import unittest, testlib
  6. import logging
  7. log = logging.getLogger("TestKoWindowsIntegrationService")
  8. if sys.platform.startswith("win"):
  9. class TestKoWindowsIntegrationService(unittest.TestCase):
  10. def __init__(self, methodName):
  11. unittest.TestCase.__init__(self, methodName)
  12. self.real_import = __builtins__["__import__"]
  13. self.winIntegSvc = None
  14. def setUp(self):
  15. if not sys.platform.startswith("win"):
  16. raise testlib.TestSkipped()
  17. self.winIntegSvc = components.classes["@activestate.com/koWindowsIntegrationService;1"]\
  18. .getService(components.interfaces.koIWindowsIntegrationService)
  19. sys.path.insert(0, self._libpath)
  20. try:
  21. import fake_winreg
  22. finally:
  23. sys.path.pop(0)
  24. self.fakeWinReg = fake_winreg
  25. self.fakeWinReg.elevated = False
  26. __builtins__["__import__"] = self.fake_import
  27. def tearDown(self):
  28. if not sys.platform.startswith("win"):
  29. return
  30. __builtins__["__import__"] = self.real_import
  31. self.winIntegSvc = None
  32. @property
  33. def _libpath(self):
  34. """ The path needed to be inserted into sys.path to find fake_winreg """
  35. return join(split(abspath(__file__))[0], "windowsIntegration")
  36. def fake_import(self, name, *args, **kwargs):
  37. """Fake __import__ that redirects requests for "_winreg" to the
  38. "fake_winreg" module
  39. """
  40. #print "\nimport %r [%r]\n" % (name, inspect.stack()[1])
  41. if name == "_winreg":
  42. caller = split(inspect.stack()[1][1])[-1] # caller frame, file name, leaf
  43. log.debug("__import__ caller: %s", caller)
  44. if caller in ("koWindowsIntegration.py", "wininteg.py"):
  45. sys.path.insert(0, self._libpath)
  46. try:
  47. return self.real_import("fake_winreg", *args, **kwargs)
  48. finally:
  49. sys.path.pop(0)
  50. return self.real_import(name, *args, **kwargs)
  51. @property
  52. def _appName(self):
  53. """ Getter for the app name """
  54. return components.classes["@mozilla.org/xre/app-info;1"]\
  55. .getService(components.interfaces.nsIXULAppInfo)\
  56. .name
  57. @property
  58. def _appExe(self):
  59. """ Getter for the application executable """
  60. koDirs = components.classes["@activestate.com/koDirs;1"]\
  61. .getService(components.interfaces.koIDirs)
  62. exe = join(koDirs.binDir, "komodo.exe")
  63. if " " in exe:
  64. exe = '"%s"' % (exe,)
  65. return exe
  66. @property
  67. def _HKLM_edit(self):
  68. return r"HKLM\Software\ActiveState\Komodo\editAssociations"
  69. @property
  70. def _HKLM_editWith(self):
  71. return r"HKLM\Software\ActiveState\Komodo\editWithAssociations"
  72. @property
  73. def _HKCU_edit(self):
  74. return r"HKCU\Software\ActiveState\%s\editAssociations" % self._appName
  75. @property
  76. def _HKCU_editWith(self):
  77. return r"HKCU\Software\ActiveState\%s\editWithAssociations" % self._appName
  78. @property
  79. def _commandLine(self):
  80. return '%s "%%1" %%*' % (self._appExe,)
  81. @property
  82. def _editWith(self):
  83. return "Edit with %s" % (self._appName,)
  84. def test_getEditAssociations_empty(self):
  85. """ Test that having no existing associations works correctly """
  86. self.fakeWinReg.setData({})
  87. assoc = self.winIntegSvc.getEditAssociations()
  88. self.assertEquals(assoc, "")
  89. assoc = self.winIntegSvc.getEditWithAssociations()
  90. self.assertEquals(assoc, "")
  91. def test_getEditAssociations_existing_system(self):
  92. """ Test that system associations are honoured """
  93. self.fakeWinReg.setData({self._HKLM_edit: ".pikachu"})
  94. assoc = self.winIntegSvc.getEditAssociations()
  95. self.assertEquals(assoc, ".pikachu")
  96. assoc = self.winIntegSvc.getEditWithAssociations()
  97. self.assertEquals(assoc, "")
  98. def test_getEditWithAssociations_existing_system_case(self):
  99. """ Test that system associations are honoured, case-normalizing """
  100. self.fakeWinReg.setData({self._HKLM_editWith: ".hello;.WORLD"})
  101. assoc = self.winIntegSvc.getEditAssociations()
  102. self.assertEquals(assoc, "")
  103. assoc = self.winIntegSvc.getEditWithAssociations()
  104. self.assertEquals(assoc, ".hello;.world")
  105. def test_getEditAssociations_existing_user_system(self):
  106. """ Test that user associations win over system associations """
  107. self.fakeWinReg.setData({self._HKLM_edit: ".pikachu",
  108. self._HKCU_edit: ".foo"})
  109. assoc = self.winIntegSvc.getEditAssociations()
  110. self.assertEquals(assoc, ".foo")
  111. assoc = self.winIntegSvc.getEditWithAssociations()
  112. self.assertEquals(assoc, "")
  113. def test_getEditWithAssociations_existing_user_system(self):
  114. """ Test that existing associations are fetched case-normalizing """
  115. self.fakeWinReg.setData({self._HKLM_editWith: ".hello;.WORLD",
  116. self._HKCU_editWith: ".bar"})
  117. assoc = self.winIntegSvc.getEditAssociations()
  118. self.assertEquals(assoc, "")
  119. assoc = self.winIntegSvc.getEditWithAssociations()
  120. self.assertEquals(assoc, ".bar")
  121. def test_setEditAssociations_clean(self):
  122. """ Test that setting associations are correct with no existing data """
  123. self.fakeWinReg.setData({})
  124. self.winIntegSvc.setEditAssociations(".pikachu")
  125. self.assertEquals(self.fakeWinReg.getData(), {
  126. r'HKCU\Software\Classes\.pikachu''\\': 'PIKACHUFile',
  127. r'HKCU\Software\Classes\PIKACHUFile\shell\Edit\command''\\': self._commandLine,
  128. self._HKCU_edit: ".pikachu"})
  129. def test_setEditAssociations_customType(self):
  130. """ Test that we correctly handle extensions with an existing custom type """
  131. self.fakeWinReg.setData({
  132. r'HKLM\Software\Classes\.hello''\\': 'hello_auto_file'})
  133. self.winIntegSvc.setEditAssociations(".hello")
  134. self.assertEquals(self.fakeWinReg.getData(), {
  135. r'HKLM\Software\Classes\.hello''\\': 'hello_auto_file',
  136. r'HKCU\Software\Classes\hello_auto_file\shell\Edit\command''\\': self._commandLine,
  137. self._HKCU_edit: ".hello"})
  138. def test_setEditWithAssociations_existing_user(self):
  139. """ Test that we correctly remove existing HKCU-based associations """
  140. self.fakeWinReg.setData({
  141. r'HKCU\Software\Classes\.pants''\\': "pantaloons",
  142. r'HKCU\Software\Classes\pantaloons\shell\Edit''\\': self._editWith,
  143. r'HKCU\Software\Classes\pantaloons\shell\Edit\command''\\': self._commandLine,
  144. self._HKCU_editWith: ".pants"})
  145. self.winIntegSvc.setEditWithAssociations(".fjords")
  146. self.assertEquals(self.fakeWinReg.getData(), {
  147. r'HKCU\Software\Classes\.fjords''\\': "FJORDSFile",
  148. r'HKCU\Software\Classes\FJORDSFile\shell\Edit''\\': self._editWith,
  149. r'HKCU\Software\Classes\FJORDSFile\shell\Edit\command''\\': self._commandLine,
  150. self._HKCU_editWith: ".fjords"})
  151. def test_setEditWithAssociations_existing_system_other(self):
  152. """ Test that we handle having existing HKLM-based commands gracefully """
  153. self.fakeWinReg.setData({
  154. r'HKLM\Software\Classes\.moo''\\': 'silly_walks',
  155. r'HKLM\Software\Classes\silly_walks\shell\Edit\command''\\': 'pants'})
  156. self.winIntegSvc.setEditWithAssociations(".moo")
  157. self.assertEquals(self.fakeWinReg.getData(), {
  158. r'HKLM\Software\Classes\.moo''\\': 'silly_walks',
  159. r'HKLM\Software\Classes\silly_walks\shell\Edit\command''\\': 'pants',
  160. r'HKCU\Software\Classes\silly_walks\shell\Edit2''\\': self._editWith,
  161. r'HKCU\Software\Classes\silly_walks\shell\Edit2\command''\\': self._commandLine,
  162. self._HKCU_editWith: ".moo"})
  163. def test_setEditAssociations_existing_system_elevated(self):
  164. """ Test that we attempt to remove old HKLM-based associations when elevated """
  165. self.fakeWinReg.elevated = True
  166. self.fakeWinReg.setData({
  167. r'HKLM\Software\Classes\.rabbit''\\': 'vicious',
  168. r'HKLM\Software\Classes\vicious\shell\Edit\command''\\': self._commandLine,
  169. self._HKLM_edit: ".rabbit"})
  170. self.winIntegSvc.setEditAssociations(".coconuts")
  171. self.assertEquals(self.fakeWinReg.getData(), {
  172. r'HKCU\Software\Classes\.coconuts''\\': 'COCONUTSFile',
  173. r'HKCU\Software\Classes\COCONUTSFile\shell\Edit\command''\\': self._commandLine,
  174. self._HKCU_edit: ".coconuts"})
  175. def test_setEditAssociations_existing_system_no_permissions(self):
  176. """ Test that attempting to change existing system permissions when not elevated fails """
  177. self.fakeWinReg.setData({
  178. r'HKLM\Software\Classes\.rabbit''\\': 'vicious',
  179. r'HKLM\Software\Classes\vicious\shell\Edit\command''\\': self._commandLine,
  180. self._HKLM_edit: ".rabbit"})
  181. self.assertRaises(COMException, self.winIntegSvc.setEditAssociations, ".coconuts")
  182. self.assertEquals(self.fakeWinReg.getData(), {
  183. r'HKLM\Software\Classes\.rabbit''\\': 'vicious',
  184. r'HKLM\Software\Classes\vicious\shell\Edit\command''\\': self._commandLine,
  185. self._HKLM_edit: ".rabbit"})
  186. def test_setEditWithAssociations_existing_system_migrate_no_permissions(self):
  187. """ Test attempting to migrate existing Edit With associations without permissions """
  188. self.fakeWinReg.setData({
  189. r'HKLM\Software\Classes\.ni''\\': 'flesh_wound',
  190. r'HKLM\Software\Classes\flesh_wound\shell\Edit''\\': 'Edit with Komodo',
  191. r'HKLM\Software\Classes\flesh_wound\shell\Edit\command''\\': self._commandLine,
  192. self._HKLM_editWith: ".ni"})
  193. self.winIntegSvc.setEditWithAssociations(".ni")
  194. self.assertEquals(self.fakeWinReg.getData(), {
  195. r'HKLM\Software\Classes\.ni''\\': 'flesh_wound',
  196. r'HKLM\Software\Classes\flesh_wound\shell\Edit''\\': 'Edit with Komodo',
  197. r'HKLM\Software\Classes\flesh_wound\shell\Edit\command''\\': self._commandLine,
  198. self._HKCU_editWith: ".ni",
  199. self._HKLM_editWith: ".ni"})
  200. def test_setEditWithAssociations_existing_system_migrate_yes_permissions(self):
  201. """ Test attempting to migrate existing Edit With associations with permissions """
  202. self.fakeWinReg.elevated = True
  203. self.fakeWinReg.setData({
  204. r'HKLM\Software\Classes\.ni''\\': 'flesh_wound',
  205. r'HKLM\Software\Classes\flesh_wound\shell\Edit''\\': 'Edit with Komodo',
  206. r'HKLM\Software\Classes\flesh_wound\shell\Edit\command''\\': self._commandLine,
  207. self._HKLM_editWith: ".ni"})
  208. self.winIntegSvc.setEditWithAssociations(".ni")
  209. self.assertEquals(self.fakeWinReg.getData(), {
  210. r'HKCU\Software\Classes\.ni''\\': 'NIFile',
  211. r'HKCU\Software\Classes\NIFile\shell\Edit''\\': self._editWith,
  212. r'HKCU\Software\Classes\NIFile\shell\Edit\command''\\': self._commandLine,
  213. self._HKCU_editWith: ".ni"})
  214. #---- mainline
  215. def suite():
  216. return unittest.makeSuite(TestKoWindowsIntegrationService)
  217. def test_main():
  218. runner = unittest.TextTestRunner(verbosity=2)
  219. result = runner.run(suite())
  220. if __name__ == "__main__":
  221. test_main()