keyrack 0.3.0.pre → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +8 -15
  4. data/Guardfile +6 -0
  5. data/LICENSE.txt +4 -2
  6. data/Rakefile +2 -56
  7. data/keyrack.gemspec +22 -104
  8. data/lib/keyrack.rb +9 -1
  9. data/lib/keyrack/database.rb +64 -98
  10. data/lib/keyrack/event.rb +13 -0
  11. data/lib/keyrack/exceptions.rb +4 -0
  12. data/lib/keyrack/group.rb +225 -0
  13. data/lib/keyrack/migrator.rb +45 -0
  14. data/lib/keyrack/runner.rb +98 -44
  15. data/lib/keyrack/site.rb +92 -0
  16. data/lib/keyrack/ui/console.rb +234 -95
  17. data/lib/keyrack/utils.rb +0 -18
  18. data/lib/keyrack/version.rb +3 -0
  19. data/test/fixtures/database-3.dat +0 -0
  20. data/test/helper.rb +11 -1
  21. data/test/integration/test_interactive_console.rb +139 -0
  22. data/test/unit/store/test_filesystem.rb +21 -0
  23. data/test/unit/store/test_ssh.rb +32 -0
  24. data/test/unit/test_database.rb +201 -0
  25. data/test/unit/test_event.rb +41 -0
  26. data/test/unit/test_group.rb +703 -0
  27. data/test/unit/test_migrator.rb +105 -0
  28. data/test/unit/test_runner.rb +407 -0
  29. data/test/unit/test_site.rb +181 -0
  30. data/test/unit/test_store.rb +13 -0
  31. data/test/unit/test_utils.rb +8 -0
  32. data/test/unit/ui/test_console.rb +495 -0
  33. metadata +98 -94
  34. data/Gemfile.lock +0 -45
  35. data/TODO +0 -4
  36. data/VERSION +0 -1
  37. data/features/console.feature +0 -103
  38. data/features/step_definitions/keyrack_steps.rb +0 -61
  39. data/features/support/env.rb +0 -16
  40. data/test/fixtures/aes +0 -0
  41. data/test/fixtures/config.yml +0 -4
  42. data/test/fixtures/id_rsa +0 -54
  43. data/test/keyrack/store/test_filesystem.rb +0 -25
  44. data/test/keyrack/store/test_ssh.rb +0 -36
  45. data/test/keyrack/test_database.rb +0 -111
  46. data/test/keyrack/test_runner.rb +0 -111
  47. data/test/keyrack/test_store.rb +0 -15
  48. data/test/keyrack/test_utils.rb +0 -41
  49. data/test/keyrack/ui/test_console.rb +0 -308
@@ -1,308 +0,0 @@
1
- require 'helper'
2
-
3
- module Keyrack
4
- module UI
5
- class TestConsole < Test::Unit::TestCase
6
- def setup
7
- @database = stub('database', :sites => %w{Twitter Google}, :groups => [], :dirty? => false) do
8
- stubs(:get).with('Twitter', {}).returns({
9
- :username => 'username', :password => 'password'
10
- })
11
- stubs(:get).with('Google', {}).returns([
12
- { :username => 'username_1', :password => 'password' },
13
- { :username => 'username_2', :password => 'password' }
14
- ])
15
- end
16
- @highline = stub('highline')
17
- @highline.stubs(:color).with("Keyrack Main Menu", :yellow).returns("yellowKeyrack Main Menu")
18
- @highline.stubs(:say)
19
- HighLine.expects(:new).returns(@highline)
20
- @console = Console.new
21
- end
22
-
23
- def test_select_entry_from_menu
24
- seq = sequence('say')
25
- @console.database = @database
26
- @highline.expects(:say).with("=== yellowKeyrack Main Menu ===")
27
- @highline.expects(:say).with(" 1. Twitter [username]")
28
- @highline.expects(:say).with(" 2. Google [username_1]")
29
- @highline.expects(:say).with(" 3. Google [username_2]")
30
- @highline.expects(:say).with("Mode: copy")
31
- @highline.expects(:say).with("Commands: [n]ew [d]elete [g]roup [m]ode [q]uit")
32
-
33
- question = mock('question')
34
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 d g}) }).returns('1')
35
- @console.expects(:Copier).with('password')
36
- @highline.expects(:say).with("The password has been copied to your clipboard.")
37
- assert_nil @console.menu
38
- end
39
-
40
- def test_select_entry_from_menu_in_print_mode
41
- seq = sequence('say')
42
- @console.database = @database
43
- @console.mode = :print
44
- @highline.expects(:say).with("=== yellowKeyrack Main Menu ===")
45
- @highline.expects(:say).with(" 1. Twitter [username]")
46
- @highline.expects(:say).with(" 2. Google [username_1]")
47
- @highline.expects(:say).with(" 3. Google [username_2]")
48
- @highline.expects(:say).with("Mode: print")
49
- @highline.expects(:say).with("Commands: [n]ew [d]elete [g]roup [m]ode [q]uit")
50
-
51
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 d g}) }).returns('1')
52
- @highline.expects(:color).with('password', :cyan).returns('cyan[password]').in_sequence(seq)
53
- question = mock do
54
- expects(:echo=).with(false)
55
- if HighLine::SystemExtensions::CHARACTER_MODE != 'stty'
56
- expects(:character=).with(true)
57
- expects(:overwrite=).with(true)
58
- end
59
- end
60
- @highline.expects(:ask).
61
- with('Here you go: cyan[password]. Done? ').
62
- yields(question).
63
- returns('')
64
-
65
- assert_nil @console.menu
66
- end
67
-
68
- def test_select_new_from_menu
69
- @console.database = @database
70
-
71
- # === yellowKeyrack Main Menu ===
72
- # 1. Twitter [username]
73
- # n. New entry
74
- # d. Delete entry
75
- # g. New group
76
- # q. Quit
77
-
78
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 d g}) }).returns('n')
79
- assert_equal :new, @console.menu
80
- end
81
-
82
- def test_select_delete_from_menu
83
- @console.database = @database
84
-
85
- # === yellowKeyrack Main Menu ===
86
- # 1. Twitter [username]
87
- # n. New entry
88
- # d. Delete entry
89
- # g. New group
90
- # q. Quit
91
-
92
- question = mock('question')
93
- question.expects(:in=).with(%w{n q m 1 2 3 d g})
94
- @highline.expects(:ask).yields(question).returns('d')
95
- assert_equal :delete, @console.menu
96
- end
97
-
98
- def test_select_quit_from_menu
99
- @console.database = @database
100
-
101
- # === yellowKeyrack Main Menu ===
102
- # 1. Twitter [username]
103
- # n. New entry
104
- # d. Delete entry
105
- # g. New group
106
- # q. Quit
107
-
108
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 d g}) }).returns('q')
109
- assert_equal :quit, @console.menu
110
- end
111
-
112
- def test_select_quit_from_menu_when_database_is_dirty
113
- @console.database = @database
114
- @database.stubs(:dirty?).returns(true)
115
-
116
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 d g s}) }).returns('q')
117
- @highline.expects(:agree).with("Really quit? You have unsaved changes! [yn] ").returns(false)
118
- assert_equal nil, @console.menu
119
- end
120
-
121
- def test_select_save_from_menu
122
- @console.database = @database
123
- @database.stubs(:dirty?).returns(true)
124
-
125
- @highline.expects(:say).with { |string| string =~ /\[s\]ave/ }
126
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 d g s}) }).returns('s')
127
- assert_equal :save, @console.menu
128
- end
129
-
130
- def test_select_group_from_menu
131
- @console.database = @database
132
- @database.stubs(:groups).returns(["Blargh"])
133
-
134
- @highline.expects(:color).with('Blargh', :green).returns('greenBlargh')
135
- @highline.expects(:say).with(" 1. greenBlargh")
136
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 4 d g}) }).returns('1')
137
- assert_equal({:group => 'Blargh'}, @console.menu)
138
- end
139
-
140
- def test_select_entry_from_group_menu
141
- @console.database = @database
142
- @database.expects(:sites).with(:group => "Foo").returns(["Facebook"])
143
- @database.expects(:get).with('Facebook', :group => "Foo").returns({:username => 'username', :password => 'password'})
144
-
145
- @highline.expects(:color).with("Foo", :green).returns("greenFoo")
146
- @highline.expects(:say).with("===== greenFoo =====")
147
- @highline.expects(:say).with(" 1. Facebook [username]")
148
- @highline.expects(:say).with("Mode: copy")
149
- @highline.expects(:say).with("Commands: [n]ew [d]elete [t]op [m]ode [q]uit")
150
-
151
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 d t}) }).returns('1')
152
- @console.expects(:Copier).with('password')
153
- @highline.expects(:say).with("The password has been copied to your clipboard.")
154
- assert_nil @console.menu(:group => 'Foo')
155
- end
156
-
157
- def test_get_password
158
- question = mock('question')
159
- question.expects(:echo=).with(false)
160
- @highline.expects(:ask).with("Keyrack password: ").yields(question).returns("foobar")
161
- assert_equal "foobar", @console.get_password
162
- end
163
-
164
- def test_get_new_entry_with_manual_password
165
- seq = sequence("new entry")
166
- @highline.expects(:ask).with("Label: ").returns("Foo").in_sequence(seq)
167
- @highline.expects(:ask).with("Username: ").returns("bar").in_sequence(seq)
168
- @highline.expects(:agree).with("Generate password? [yn] ").returns(false).in_sequence(seq)
169
- @highline.expects(:ask).with("Password: ").yields(mock { expects(:echo=).with(false) }).returns("baz").in_sequence(seq)
170
- @highline.expects(:ask).with("Password (again): ").yields(mock { expects(:echo=).with(false) }).returns("bar").in_sequence(seq)
171
- @highline.expects(:say).with("Passwords didn't match. Try again!").in_sequence(seq)
172
- @highline.expects(:ask).with("Password: ").yields(mock { expects(:echo=).with(false) }).returns("baz").in_sequence(seq)
173
- @highline.expects(:ask).with("Password (again): ").yields(mock { expects(:echo=).with(false) }).returns("baz").in_sequence(seq)
174
- assert_equal({:site => "Foo", :username => "bar", :password => "baz"}, @console.get_new_entry)
175
- end
176
-
177
- def test_get_new_entry_generated_password
178
- seq = sequence("new entry")
179
- @highline.expects(:ask).with("Label: ").returns("Foo").in_sequence(seq)
180
- @highline.expects(:ask).with("Username: ").returns("bar").in_sequence(seq)
181
- @highline.expects(:agree).with("Generate password? [yn] ").returns(true).in_sequence(seq)
182
- Utils.expects(:generate_password).returns('foobar').in_sequence(seq)
183
- @highline.expects(:color).with('foobar', :cyan).returns('cyanfoobar').in_sequence(seq)
184
- @highline.expects(:agree).with("Generated cyanfoobar. Sound good? [yn] ").returns(false).in_sequence(seq)
185
- Utils.expects(:generate_password).returns('foobar').in_sequence(seq)
186
- @highline.expects(:color).with('foobar', :cyan).returns('cyanfoobar').in_sequence(seq)
187
- @highline.expects(:agree).with("Generated cyanfoobar. Sound good? [yn] ").returns(true).in_sequence(seq)
188
- assert_equal({:site => "Foo", :username => "bar", :password => "foobar"}, @console.get_new_entry)
189
- end
190
-
191
- def test_display_first_time_notice
192
- @highline.expects(:say).with("This looks like your first time using Keyrack. I'll need to ask you a few questions first.")
193
- @console.display_first_time_notice
194
- end
195
-
196
- def test_rsa_setup
197
- seq = sequence("rsa setup")
198
- @highline.expects(:ask).with("New passphrase: ").yields(mock{expects(:echo=).with(false)}).returns('huge').in_sequence(seq)
199
- @highline.expects(:ask).with("Confirm passphrase: ").yields(mock{expects(:echo=).with(false)}).returns('small').in_sequence(seq)
200
- @highline.expects(:say).with("Passphrases didn't match.").in_sequence(seq)
201
- @highline.expects(:ask).with("New passphrase: ").yields(mock{expects(:echo=).with(false)}).returns('huge').in_sequence(seq)
202
- @highline.expects(:ask).with("Confirm passphrase: ").yields(mock{expects(:echo=).with(false)}).returns('huge').in_sequence(seq)
203
- expected = {'password' => 'huge', 'path' => 'rsa'}
204
- assert_equal expected, @console.rsa_setup
205
- end
206
-
207
- def test_store_setup_for_filesystem
208
- @highline.expects(:choose).yields(mock {
209
- expects(:header=).with("Choose storage type")
210
- expects(:choices).with("filesystem", "ssh")
211
- }).returns("filesystem")
212
-
213
- expected = {'type' => 'filesystem', 'path' => 'database'}
214
- assert_equal expected, @console.store_setup
215
- end
216
-
217
- def test_store_setup_for_ssh
218
- seq = sequence("store setup")
219
- @highline.expects(:choose).yields(mock {
220
- expects(:header=).with("Choose storage type")
221
- expects(:choices).with("filesystem", "ssh")
222
- }).returns("ssh").in_sequence(seq)
223
- @highline.expects(:ask).with("Host: ").returns("example.com").in_sequence(seq)
224
- @highline.expects(:ask).with("User: ").returns("dudeguy").in_sequence(seq)
225
- @highline.expects(:ask).with("Remote path: ").returns(".keyrack/database").in_sequence(seq)
226
-
227
- expected = {'type' => 'ssh', 'host' => 'example.com', 'user' => 'dudeguy', 'path' => '.keyrack/database'}
228
- assert_equal expected, @console.store_setup
229
- end
230
-
231
- def test_get_new_group
232
- @highline.expects(:ask).with("Group: ").yields(mock {
233
- expects(:validate=).with(/^\w[\w\s]*$/)
234
- }).returns("Foo")
235
- assert_equal({:group => "Foo"}, @console.get_new_group)
236
- end
237
-
238
- def test_delete_entry
239
- @console.database = @database
240
- @database.stubs(:sites).returns(%w{Twitter Facebook})
241
- @database.stubs(:get).with('Facebook', {}).returns({
242
- :username => 'username', :password => 'password'
243
- })
244
-
245
- seq = sequence("deleting")
246
- @highline.expects(:say).with("Choose entry to delete:").in_sequence(seq)
247
- @highline.expects(:say).with(" 1. Twitter [username]").in_sequence(seq)
248
- @highline.expects(:say).with(" 2. Facebook [username]").in_sequence(seq)
249
- @highline.expects(:say).with(" c. Cancel").in_sequence(seq)
250
- @highline.expects(:ask).yields(mock {
251
- expects(:in=).with(%w{c 1 2})
252
- }).returns('1').in_sequence(seq)
253
- @highline.expects(:color).with("Twitter [username]", :red).returns("redTwitter").in_sequence(seq)
254
- @highline.expects(:agree).with("You're about to delete redTwitter. Are you sure? [yn] ").returns(true).in_sequence(seq)
255
- @database.expects(:delete).with("Twitter", 'username', {}).in_sequence(seq)
256
- @console.delete_entry
257
- end
258
-
259
- def test_delete_one_entry_from_site_with_multiple_entries
260
- @console.database = @database
261
-
262
- seq = sequence("deleting")
263
- @highline.expects(:say).with("Choose entry to delete:").in_sequence(seq)
264
- @highline.expects(:say).with(" 1. Twitter [username]").in_sequence(seq)
265
- @highline.expects(:say).with(" 2. Google [username_1]").in_sequence(seq)
266
- @highline.expects(:say).with(" 3. Google [username_2]").in_sequence(seq)
267
- @highline.expects(:say).with(" c. Cancel").in_sequence(seq)
268
- @highline.expects(:ask).yields(mock {
269
- expects(:in=).with(%w{c 1 2 3})
270
- }).returns('3').in_sequence(seq)
271
- @highline.expects(:color).with("Google [username_2]", :red).returns("redGoogle").in_sequence(seq)
272
- @highline.expects(:agree).with("You're about to delete redGoogle. Are you sure? [yn] ").returns(true).in_sequence(seq)
273
- @database.expects(:delete).with("Google", 'username_2', {}).in_sequence(seq)
274
- @console.delete_entry
275
- end
276
-
277
- def test_delete_group_entry
278
- @console.database = @database
279
- @database.stubs(:sites).returns(%w{Quora Foursquare})
280
- @database.stubs(:get).with(kind_of(String), {:group => 'Social'}).returns({
281
- :username => 'username', :password => 'password'
282
- })
283
-
284
- seq = sequence("deleting")
285
- @highline.expects(:say).with("Choose entry to delete:").in_sequence(seq)
286
- @highline.expects(:say).with(" 1. Quora [username]").in_sequence(seq)
287
- @highline.expects(:say).with(" 2. Foursquare [username]").in_sequence(seq)
288
- @highline.expects(:say).with(" c. Cancel").in_sequence(seq)
289
- @highline.expects(:ask).yields(mock {
290
- expects(:in=).with(%w{c 1 2})
291
- }).returns('2').in_sequence(seq)
292
- @highline.expects(:color).with("Foursquare [username]", :red).returns("redFoursquare").in_sequence(seq)
293
- @highline.expects(:agree).with("You're about to delete redFoursquare. Are you sure? [yn] ").returns(true).in_sequence(seq)
294
- @database.expects(:delete).with("Foursquare", 'username', :group => 'Social').in_sequence(seq)
295
- @console.delete_entry(:group => 'Social')
296
- end
297
-
298
- def test_switch_mode_from_menu
299
- @console.database = @database
300
- @console.mode = :copy
301
-
302
- @highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 d g}) }).returns('m')
303
- assert_nil @console.menu
304
- assert_equal :print, @console.mode
305
- end
306
- end
307
- end
308
- end