keyrack 0.3.0.pre → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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