1# -*- coding: utf-8 -*- 2# Pitivi video editor 3# Copyright (c) 2016, Jakub Brindza <jakub.brindza@gmail.com> 4# 5# This program is free software; you can redistribute it and/or 6# modify it under the terms of the GNU Lesser General Public 7# License as published by the Free Software Foundation; either 8# version 2.1 of the License, or (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public 16# License along with this program; if not, write to the 17# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18# Boston, MA 02110-1301, USA. 19"""Test the keyboard shortcuts.""" 20import os 21import tempfile 22from unittest import mock 23 24from pitivi.shortcuts import ShortcutsManager 25from tests import common 26 27 28class TestShortcutsManager(common.TestCase): 29 """Tests for the ShortcutsManager.""" 30 31 def test_groups(self): 32 """Checks the group in which the shortcut ends up.""" 33 app = mock.MagicMock() 34 manager = ShortcutsManager(app) 35 36 # Test register_group method 37 manager.register_group("alpha_group", "One", position=20) 38 with self.assertRaises(AssertionError): 39 manager.register_group("alpha_group", "", position=0) 40 manager.register_group("beta_group", "Two", position=10) 41 self.assertEqual(manager.groups, ["beta_group", "alpha_group"]) 42 43 # Test grouping using the stripping away group name from action name 44 manager.add("alpha_group.first", ["<Primary>A"], "First action") 45 self.assertIn(("alpha_group.first", "First action"), 46 manager.group_actions["alpha_group"]) 47 manager.add("alpha_group.second", ["<Primary>B"], "Second action") 48 self.assertIn(("alpha_group.second", "Second action"), 49 manager.group_actions["alpha_group"]) 50 manager.add("beta_group.first", ["<Primary>C"], "First beta action") 51 self.assertIn(("beta_group.first", "First beta action"), 52 manager.group_actions["beta_group"]) 53 54 # Test grouping using the group optional argument 55 # if group parameter is set, the action prefix can be anything, 56 # it should be disregarded in favour of the group value. 57 manager.add("anything.third_action", ["<Primary>D"], "Third action", 58 group="beta_group") 59 self.assertIn(("anything.third_action", "Third action"), 60 manager.group_actions["beta_group"]) 61 62 def test_add_shortcut(self): 63 """Checks the number of calls to set_accels_for_action.""" 64 app = mock.MagicMock() 65 with mock.patch("pitivi.shortcuts.xdg_config_home") as xdg_config_home,\ 66 tempfile.TemporaryDirectory() as temp_dir: 67 xdg_config_home.return_value = temp_dir 68 manager = ShortcutsManager(app) 69 # Test the add is calling set_accels_for_action(), 70 # since there is no shortcuts.conf in the directory. 71 manager.register_group("general", "General group", position=0) 72 manager.add("prefix.action1", ["<Primary>P"], "Action one") 73 self.assertEqual(app.set_accels_for_action.call_count, 1) 74 75 # Create the temporary shortcuts.conf file 76 # and test that add is not calling set_accels_for_action() 77 open(os.path.sep.join([temp_dir, "shortcuts.conf"]), "w").close() 78 manager2 = ShortcutsManager(app) 79 manager2.register_group("other", "Other group", position=0) 80 81 manager2.add("prefix.action4", ["<Primary>W"], 82 "Action addition not invoking set_accels_for_action") 83 # No. of calls to set_accels_for_action should be unchanged now 84 # because calling set_accels_for_action isn't allowed with .conf existing 85 self.assertEqual(app.set_accels_for_action.call_count, 1) 86 87 def test_load_save(self): 88 """Checks saved shortcuts are loaded by a new instance.""" 89 app = mock.MagicMock() 90 with mock.patch("pitivi.shortcuts.xdg_config_home") as xdg_config_home,\ 91 tempfile.TemporaryDirectory() as temp_dir: 92 xdg_config_home.return_value = temp_dir 93 manager = ShortcutsManager(app) 94 # No file exists so set_accels_for_action() is not called. 95 self.assertEqual(app.set_accels_for_action.call_count, 0) 96 97 # Set default shortcuts 98 manager.register_group("group", "Test group", position=0) 99 manager.add("group.action1", ["<Primary>i"], "Action 1") 100 manager.add("group.action2", ["<Shift>p", "<Primary>m"], "Action 2") 101 manager.add("group.action3", ["<Primary><Shift>a", "a"], "Action 3") 102 103 # After saving the shortcuts, the accels should be set when 104 # initializing a ShortcutsManger. 105 app.get_accels_for_action.side_effect = [(["<Primary>i"]), 106 (["<Shift>p", "<Primary>m"]), 107 (["<Primary><Shift>a", "a"])] 108 manager.save() 109 app.reset_mock() 110 unused_manager2 = ShortcutsManager(app) 111 self.assertEqual(app.set_accels_for_action.call_count, 3) 112 calls = [mock.call("group.action1", ["<Primary>i"]), 113 mock.call("group.action2", ["<Shift>p", "<Primary>m"]), 114 mock.call("group.action3", ["<Primary><Shift>a", "a"])] 115 app.set_accels_for_action.assert_has_calls(calls, any_order=True) 116 117 def test_reset_accels(self): 118 """Checks if accelerators have been reset to the default settings.""" 119 app = mock.MagicMock() 120 with mock.patch("pitivi.shortcuts.xdg_config_home") as xdg_config_home,\ 121 tempfile.TemporaryDirectory() as temp_dir,\ 122 mock.patch("os.remove") as os_remove_mock: 123 xdg_config_home.return_value = temp_dir 124 manager = ShortcutsManager(app) 125 126 # Set default shortcuts - they will be stored in self.defaults_accelerators. 127 manager.register_group("group", "Test group", position=0) 128 manager.add("group.action1", ["<Primary>i"], "Action 1") 129 manager.add("group.action2", ["<Shift>p"], "Action 2") 130 131 # Test reset of a single action. The shortcuts are saved and no file removed. 132 # Only one call to set_accels_for_action() should be made. 133 app.reset_mock() 134 manager.save = mock.MagicMock() 135 manager.reset_accels(action="group.action1") 136 self.assertEqual(manager.save.call_count, 1) 137 self.assertEqual(os_remove_mock.call_count, 0) 138 self.assertEqual(app.set_accels_for_action.call_count, 1) 139 140 # Test reset of all actions. Nothing is saved and the file is removed. 141 # Both actions should have accelerators set. 142 app.reset_mock() 143 os_remove_mock.reset_mock() 144 manager.save.reset_mock() 145 manager.reset_accels() 146 self.assertEqual(manager.save.call_count, 0) 147 self.assertEqual(os_remove_mock.call_count, 1) 148 self.assertEqual(app.set_accels_for_action.call_count, 2) 149