imap-backup 1.0.10 → 1.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21c07957777ccdca22ec2b9b98aa5ee23e03f9d4
4
- data.tar.gz: 7f341ff59529f01e6d7c4ccb7eefa73610b68a57
3
+ metadata.gz: 664cab74407b44814015417f5488f9ebf194554a
4
+ data.tar.gz: 64acb39ad63cf6cf194e813c31c70edcb41afeba
5
5
  SHA512:
6
- metadata.gz: d9cbe70b6dbe617645a4a3fadbaa75a9fa73870b889d361adeb9a3cd9bcee91143736327db1050e6dc4c9383fabe9161413bb6061b5ce26831ed1c0897fa7c2f
7
- data.tar.gz: ce740410c22cfea3f5119cd7a65196db97296d56416b662b575f049bba4e45669a66bccca78af52dcb915ab51ced4690e760246237df1ec85aa3ec10c7fb3669
6
+ metadata.gz: 86a3fac151e45fc4d061e26a8569de2d89fb2b37063b11ae7374ee54400ce67eaa4e385ab37f9daef33fdd011305634cf37f50f908590829f037a7d8ca10fbdb
7
+ data.tar.gz: 292a8b80a095a74091e8b981783f92730a1044c429a761b983770585ead60c5bcd35928193767fdf5daefdb7a1e2f67fbbcfc67df5b7c41e1d9b920d19244f69
data/.travis.yml CHANGED
@@ -1,7 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.8.7
4
- - 1.9.2
5
3
  - 1.9.3
6
4
  - 2.0.0
7
5
  - 2.1.1
data/imap-backup.gemspec CHANGED
@@ -16,23 +16,10 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ['lib']
17
17
  gem.version = Imap::Backup::VERSION
18
18
 
19
- if RUBY_VERSION < '1.9'
20
- gem.add_runtime_dependency 'rake', '< 10.2.0'
21
- else
22
- gem.add_runtime_dependency 'rake'
23
- end
19
+ gem.add_runtime_dependency 'rake'
24
20
  gem.add_runtime_dependency 'highline'
25
21
  gem.add_runtime_dependency 'mail'
26
- if RUBY_VERSION < '1.9'
27
- gem.add_runtime_dependency 'json'
28
- end
29
22
 
30
- gem.add_development_dependency 'pry'
31
- gem.add_development_dependency 'pry-doc'
32
- gem.add_development_dependency 'rspec', '>= 2.12.0'
33
- if RUBY_VERSION < '1.9'
34
- gem.add_development_dependency 'rcov'
35
- else
36
- gem.add_development_dependency 'simplecov'
37
- end
23
+ gem.add_development_dependency 'rspec', '>= 3.0.0'
24
+ gem.add_development_dependency 'simplecov'
38
25
  end
@@ -4,29 +4,32 @@ module Email; end
4
4
 
5
5
  module Email::Mboxrd
6
6
  class Message
7
- def initialize(body)
8
- @body = body.clone
9
- @body.force_encoding('binary') if RUBY_VERSION >= '1.9.0'
7
+ attr_reader :supplied_body
8
+
9
+ def initialize(supplied_body)
10
+ @supplied_body = supplied_body.clone
11
+ @supplied_body.force_encoding('binary') if RUBY_VERSION >= '1.9.0'
10
12
  end
11
13
 
12
14
  def to_s
13
- 'From ' + from + "\n" + body + "\n"
15
+ 'From ' + from + "\n" + mboxrd_body + "\n"
14
16
  end
15
17
 
16
18
  private
17
19
 
18
20
  def parsed
19
- @parsed ||= Mail.new(@body)
21
+ @parsed ||= Mail.new(supplied_body)
20
22
  end
21
23
 
22
24
  def from
23
25
  parsed.from[0] + ' ' + asctime
24
26
  end
25
27
 
26
- def body
27
- mbox = @body.gsub(/\n(>*From)/, "\n>\\1")
28
- mbox += "\n" unless mbox.end_with?("\n")
29
- mbox
28
+ def mboxrd_body
29
+ return @mboxrd_body if @mboxrd_body
30
+ @mboxrd_body = supplied_body.gsub(/\n(>*From)/, "\n>\\1")
31
+ @mboxrd_body += "\n" unless @mboxrd_body.end_with?("\n")
32
+ @mboxrd_body
30
33
  end
31
34
 
32
35
  def asctime
@@ -4,12 +4,14 @@ module Imap::Backup
4
4
  module Account; end
5
5
 
6
6
  class Account::Connection
7
- attr_reader :username, :local_path, :backup_folders, :server
7
+ attr_reader :username
8
+ attr_reader :local_path
9
+ attr_reader :backup_folders
8
10
 
9
11
  def initialize(options)
10
12
  @username, @password = options[:username], options[:password]
11
13
  @local_path, @backup_folders = options[:local_path], options[:folders]
12
- @server = options[:server] || host_for(username)
14
+ @server = options[:server]
13
15
  end
14
16
 
15
17
  def folders
@@ -38,6 +40,10 @@ module Imap::Backup
38
40
  imap.disconnect
39
41
  end
40
42
 
43
+ def server
44
+ @server ||= host_for(username)
45
+ end
46
+
41
47
  def imap
42
48
  return @imap unless @imap.nil?
43
49
  options = options_for(server)
@@ -6,25 +6,28 @@ module Imap::Backup
6
6
  class Account::Folder
7
7
  REQUESTED_ATTRIBUTES = ['RFC822', 'FLAGS', 'INTERNALDATE']
8
8
 
9
+ attr_reader :connection
10
+ attr_reader :folder
11
+
9
12
  def initialize(connection, folder)
10
13
  @connection, @folder = connection, folder
11
14
  end
12
15
 
13
16
  def uids
14
- @connection.imap.examine(@folder)
15
- @connection.imap.uid_search(['ALL']).sort
17
+ connection.imap.examine(folder)
18
+ connection.imap.uid_search(['ALL']).sort
16
19
  rescue Net::IMAP::NoResponseError => e
17
- Imap::Backup.logger.warn "Folder '#{@folder}' does not exist"
20
+ Imap::Backup.logger.warn "Folder '#{folder}' does not exist"
18
21
  []
19
22
  end
20
23
 
21
24
  def fetch(uid)
22
- @connection.imap.examine(@folder)
23
- message = @connection.imap.uid_fetch([uid.to_i], REQUESTED_ATTRIBUTES)[0][1]
25
+ connection.imap.examine(folder)
26
+ message = connection.imap.uid_fetch([uid.to_i], REQUESTED_ATTRIBUTES)[0][1]
24
27
  message['RFC822'].force_encoding('utf-8') if RUBY_VERSION > '1.9'
25
28
  message
26
29
  rescue Net::IMAP::NoResponseError => e
27
- Imap::Backup.logger.warn "Folder '#{@folder}' does not exist"
30
+ Imap::Backup.logger.warn "Folder '#{folder}' does not exist"
28
31
  nil
29
32
  end
30
33
  end
@@ -4,6 +4,10 @@ module Imap::Backup
4
4
  module Configuration; end
5
5
 
6
6
  class Configuration::Account < Struct.new(:store, :account, :highline)
7
+ def initialize(store, account, highline)
8
+ super
9
+ end
10
+
7
11
  def run
8
12
  catch :done do
9
13
  loop do
@@ -6,6 +6,10 @@ module Imap::Backup
6
6
  class Configuration::Asker < Struct.new(:highline)
7
7
  EMAIL_MATCHER = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
8
8
 
9
+ def initialize(highline)
10
+ super
11
+ end
12
+
9
13
  def email(default = '')
10
14
  highline.ask('email address: ') do |q|
11
15
  q.default = default
@@ -4,54 +4,79 @@ module Imap::Backup
4
4
  module Configuration; end
5
5
 
6
6
  class Configuration::FolderChooser
7
+ attr_reader :account
8
+
7
9
  def initialize(account)
8
10
  @account = account
9
11
  end
10
12
 
11
13
  def run
12
- begin
13
- @connection = Account::Connection.new(@account)
14
- rescue => e
14
+ if connection.nil?
15
15
  Imap::Backup.logger.warn 'Connection failed'
16
- Configuration::Setup.highline.ask 'Press a key '
16
+ highline.ask 'Press a key '
17
17
  return
18
18
  end
19
- @folders = @connection.folders
20
- if @folders.nil?
19
+
20
+ if folders.nil?
21
21
  Imap::Backup.logger.warn 'Unable to get folder list'
22
- Configuration::Setup.highline.ask 'Press a key '
22
+ highline.ask 'Press a key '
23
23
  return
24
24
  end
25
- loop do
26
- system('clear')
27
- Configuration::Setup.highline.choose do |menu|
28
- menu.header = 'Add/remove folders'
29
- menu.index = :number
30
- @folders.each do |folder|
31
- name = folder.name
32
- found = @account[:folders].find { |f| f[:name] == name }
33
- mark =
34
- if found
35
- '+'
36
- else
37
- '-'
38
- end
39
- menu.choice("#{mark} #{name}") do
40
- if found
41
- @account[:folders].reject! { |f| f[:name] == name }
42
- else
43
- @account[:folders] << { :name => name }
44
- end
45
- end
46
- end
47
- menu.choice('return to the account menu') do
48
- return
49
- end
50
- menu.hidden('quit') do
51
- return
52
- end
25
+
26
+ catch :done do
27
+ loop do
28
+ system('clear')
29
+ show_menu
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def show_menu
37
+ highline.choose do |menu|
38
+ menu.header = 'Add/remove folders'
39
+ menu.index = :number
40
+ add_folders menu
41
+ menu.choice('return to the account menu') { throw :done }
42
+ menu.hidden('quit') { throw :done }
43
+ end
44
+ end
45
+
46
+ def add_folders(menu)
47
+ folders.each do |folder|
48
+ name = folder.name
49
+ mark = is_selected?(name) ? '+' : '-'
50
+ menu.choice("#{mark} #{name}") do
51
+ toggle_selection name
53
52
  end
54
53
  end
55
54
  end
55
+
56
+ def is_selected?(folder_name)
57
+ account[:folders].find { |f| f[:name] == folder_name }
58
+ end
59
+
60
+ def toggle_selection(folder_name)
61
+ if is_selected?(folder_name)
62
+ account[:folders].reject! { |f| f[:name] == folder_name }
63
+ else
64
+ account[:folders] << { :name => folder_name }
65
+ end
66
+ end
67
+
68
+ def connection
69
+ @connection ||= Account::Connection.new(account)
70
+ rescue => e
71
+ nil
72
+ end
73
+
74
+ def folders
75
+ @folders ||= connection.folders
76
+ end
77
+
78
+ def highline
79
+ Configuration::Setup.highline
80
+ end
56
81
  end
57
82
  end
@@ -4,27 +4,37 @@ module Imap::Backup
4
4
  module Configuration; end
5
5
 
6
6
  class Configuration::List
7
- attr_reader :accounts
7
+ attr_reader :required_accounts
8
8
 
9
- def initialize(accounts = nil)
10
- if not Configuration::Store.exist?
11
- raise ConfigurationNotFound.new("Configuration file '#{Configuration::Store.default_pathname}' not found")
12
- end
13
- @config = Configuration::Store.new
14
-
15
- if accounts.nil?
16
- @accounts = @config.data[:accounts]
17
- else
18
- @accounts = @config.data[:accounts].select{ |account| accounts.include?(account[:username]) }
19
- end
9
+ def initialize(required_accounts = nil)
10
+ @required_accounts = required_accounts
20
11
  end
21
12
 
22
13
  def each_connection
23
- @accounts.each do |account|
14
+ accounts.each do |account|
24
15
  connection = Account::Connection.new(account)
25
16
  yield connection
26
17
  connection.disconnect
27
18
  end
28
19
  end
20
+
21
+ private
22
+
23
+ def config
24
+ return @config if @config
25
+ if not Configuration::Store.exist?
26
+ raise ConfigurationNotFound.new("Configuration file '#{Configuration::Store.default_pathname}' not found")
27
+ end
28
+ @config = Configuration::Store.new
29
+ end
30
+
31
+ def accounts
32
+ return @accounts if @accounts
33
+ if required_accounts.nil?
34
+ @accounts = config.data[:accounts]
35
+ else
36
+ @accounts = config.data[:accounts].select{ |account| required_accounts.include?(account[:username]) }
37
+ end
38
+ end
29
39
  end
30
40
  end
@@ -13,32 +13,48 @@ module Imap::Backup
13
13
 
14
14
  def run
15
15
  setup_logging
16
- loop do
17
- system('clear')
18
- self.class.highline.choose do |menu|
19
- menu.header = 'Choose an action'
20
- config.data[:accounts].each do |account|
21
- menu.choice("#{account[:username]}") do
22
- edit_account account[:username]
23
- end
24
- end
25
- menu.choice('add account') do
26
- username = Configuration::Asker.email
27
- edit_account username
28
- end
29
- menu.choice('save and exit') do
30
- config.save
31
- return
32
- end
33
- menu.choice(:quit) do
34
- return
35
- end
16
+ catch :done do
17
+ loop do
18
+ system('clear')
19
+ show_menu
36
20
  end
37
21
  end
38
22
  end
39
23
 
40
24
  private
41
25
 
26
+ def show_menu
27
+ self.class.highline.choose do |menu|
28
+ menu.header = 'Choose an action'
29
+ account_items menu
30
+ add_account_item menu
31
+ menu.choice('add account') do
32
+ username = Configuration::Asker.email
33
+ edit_account username
34
+ end
35
+ menu.choice('save and exit') do
36
+ config.save
37
+ throw :done
38
+ end
39
+ menu.choice(:quit) { throw :done }
40
+ end
41
+ end
42
+
43
+ def account_items(menu)
44
+ config.data[:accounts].each do |account|
45
+ menu.choice("#{account[:username]}") do
46
+ edit_account account[:username]
47
+ end
48
+ end
49
+ end
50
+
51
+ def add_account_item(menu)
52
+ menu.choice('add account') do
53
+ username = Configuration::Asker.email
54
+ edit_account username
55
+ end
56
+ end
57
+
42
58
  def config
43
59
  @config ||= Configuration::Store.new
44
60
  end
@@ -52,21 +68,20 @@ module Imap::Backup
52
68
  end
53
69
  end
54
70
 
55
- def add_account(username)
71
+ def default_account_config(username)
56
72
  account = {
57
73
  :username => username,
58
74
  :password => '',
59
75
  :local_path => File.join(config.path, username.gsub('@', '_')),
60
76
  :folders => []
61
77
  }
62
- config.data[:accounts] << account
63
- account
64
78
  end
65
79
 
66
80
  def edit_account(username)
67
81
  account = config.data[:accounts].find { |a| a[:username] == username }
68
82
  if account.nil?
69
- account = add_account(username)
83
+ account = default_account_config(username)
84
+ config.data[:accounts] << account
70
85
  end
71
86
  Configuration::Account.new(config, account, Configuration::Setup.highline).run
72
87
  end
@@ -8,8 +8,7 @@ module Imap::Backup
8
8
  class Configuration::Store
9
9
  CONFIGURATION_DIRECTORY = File.expand_path('~/.imap-backup')
10
10
 
11
- attr_reader :data
12
- attr_reader :path
11
+ attr_reader :pathname
13
12
 
14
13
  def self.default_pathname
15
14
  File.join(CONFIGURATION_DIRECTORY, 'config.json')
@@ -21,21 +20,19 @@ module Imap::Backup
21
20
 
22
21
  def initialize(pathname = self.class.default_pathname)
23
22
  @pathname = pathname
24
- if File.directory?(path)
25
- Utils.check_permissions path, 0700
26
- end
27
- if File.exist?(@pathname)
28
- Utils.check_permissions @pathname, 0600
29
- @data = JSON.parse(File.read(@pathname), :symbolize_names => true)
30
- else
31
- @data = {:accounts => []}
32
- end
23
+ end
24
+
25
+ def path
26
+ File.dirname(pathname)
33
27
  end
34
28
 
35
29
  def save
30
+ if File.directory?(path)
31
+ Utils.check_permissions path, 0700
32
+ end
36
33
  mkdir_private path
37
- File.open(@pathname, 'w') { |f| f.write(JSON.pretty_generate(@data)) }
38
- FileUtils.chmod 0600, @pathname
34
+ File.open(pathname, 'w') { |f| f.write(JSON.pretty_generate(data)) }
35
+ FileUtils.chmod 0600, pathname
39
36
  @data[:accounts].each do |account|
40
37
  mkdir_private account[:local_path]
41
38
  account[:folders].each do |f|
@@ -49,12 +46,18 @@ module Imap::Backup
49
46
  end
50
47
  end
51
48
 
52
- def path
53
- File.dirname(@pathname)
54
- end
55
-
56
49
  private
57
50
 
51
+ def data
52
+ return @data if @data
53
+ if File.exist?(pathname)
54
+ Utils.check_permissions pathname, 0600
55
+ @data = JSON.parse(File.read(pathname), :symbolize_names => true)
56
+ else
57
+ @data = {:accounts => []}
58
+ end
59
+ end
60
+
58
61
  def mkdir_private(path)
59
62
  if ! File.directory?(path)
60
63
  FileUtils.mkdir path
@@ -4,16 +4,19 @@ require 'json'
4
4
 
5
5
  module Imap::Backup
6
6
  class Downloader
7
+ attr_reader :folder
8
+ attr_reader :serializer
9
+
7
10
  def initialize(folder, serializer)
8
11
  @folder, @serializer = folder, serializer
9
12
  end
10
13
 
11
14
  def run
12
- uids = @folder.uids - @serializer.uids
15
+ uids = folder.uids - serializer.uids
13
16
  uids.each do |uid|
14
- message = @folder.fetch(uid)
17
+ message = folder.fetch(uid)
15
18
  next if message.nil?
16
- @serializer.save(uid, message)
19
+ serializer.save(uid, message)
17
20
  end
18
21
  end
19
22
  end
@@ -37,7 +37,7 @@ module Imap::Backup
37
37
  imap = File.open(imap_pathname, 'ab')
38
38
  mbox.write mboxrd_message.to_s
39
39
  imap.write uid + "\n"
40
- rescue ArgumentError => e
40
+ rescue => e
41
41
  Imap::Backup.logger.warn "Failed to save message #{uid}:\n#{body}. #{e}"
42
42
  ensure
43
43
  mbox.close if mbox
@@ -3,6 +3,6 @@ module Imap; end
3
3
  module Imap::Backup
4
4
  MAJOR = 1
5
5
  MINOR = 0
6
- REVISION = 10
6
+ REVISION = 11
7
7
  VERSION = [MAJOR, MINOR, REVISION].map(&:to_s).join('.')
8
8
  end
@@ -43,7 +43,9 @@ describe Imap::Backup::Account::Connection do
43
43
  [:local_path, 'local_path'],
44
44
  [:backup_folders, [folder_config]],
45
45
  ].each do |attr, expected|
46
- its(attr) { should eq(expected) }
46
+ it "expects #{attr}" do
47
+ expect(subject.send(attr)).to eq(expected)
48
+ end
47
49
  end
48
50
 
49
51
  context 'server' do
@@ -118,7 +120,7 @@ describe Imap::Backup::Account::Connection do
118
120
  before { subject.disconnect }
119
121
 
120
122
  it 'disconnects from the server' do
121
- expect(imap).to have_received(:disconnect).with()
123
+ expect(imap).to have_received(:disconnect)
122
124
  end
123
125
 
124
126
  include_examples 'connects to IMAP'
@@ -19,6 +19,26 @@ describe Imap::Backup::Configuration::Account do
19
19
  end
20
20
  end
21
21
 
22
+ context '#initialize' do
23
+ it 'requires 3 parameters' do
24
+ expect do
25
+ described_class.new('foo')
26
+ end.to raise_error(ArgumentError, /1 for 3/)
27
+ end
28
+
29
+ let(:store) { 'store' }
30
+ let(:account) { 'account' }
31
+ let(:highline) { 'highline' }
32
+
33
+ subject { described_class.new(store, account, highline) }
34
+
35
+ [:store, :account, :highline].each do |param|
36
+ it "expects #{param}" do
37
+ expect(subject.send(param)).to eq(send(param))
38
+ end
39
+ end
40
+ end
41
+
22
42
  context '#run' do
23
43
  let(:highline) { double('Highline') }
24
44
  let(:menu) { MockHighlineMenu.new }
@@ -225,7 +245,7 @@ describe Imap::Backup::Configuration::Account do
225
245
  end
226
246
 
227
247
  it 'validates that the path is not used by other backups' do
228
- expect(@validator.call(other_existing_path)).to be_false
248
+ expect(@validator.call(other_existing_path)).to be_falsey
229
249
  end
230
250
  end
231
251
 
@@ -45,7 +45,15 @@ module Imap::Backup
45
45
  end
46
46
 
47
47
  context '#initialize' do
48
- its(:highline) { should eq(highline) }
48
+ it 'requires 1 parameter' do
49
+ expect do
50
+ described_class.new
51
+ end.to raise_error(ArgumentError, /0 for 1/)
52
+ end
53
+
54
+ it 'expects a higline' do
55
+ expect(subject.highline).to eq(highline)
56
+ end
49
57
  end
50
58
 
51
59
  context '#email' do
@@ -56,7 +64,7 @@ module Imap::Backup
56
64
  @result = subject.email
57
65
  end
58
66
 
59
- it 'asks for an email' do
67
+ it 'asks for an email' do
60
68
  expect(highline).to have_received(:ask).with(/email/)
61
69
  end
62
70
 
@@ -26,7 +26,7 @@ describe Imap::Backup::Configuration::FolderChooser do
26
26
  end
27
27
 
28
28
  it 'should show the menu' do
29
- @output.string.should =~ %r{Add/remove folders}
29
+ expect(@output.string).to match %r{Add/remove folders}
30
30
  end
31
31
  end
32
32
 
@@ -12,26 +12,39 @@ describe Imap::Backup::Configuration::List do
12
12
  double('Imap::Backup::Configuration::Store', :data => {:accounts => accounts})
13
13
  end
14
14
  let(:exists) { true }
15
+ let(:connection1) { double('Imap::Backup::Account::Connection', :disconnect => nil) }
16
+ let(:connection2) { double('Imap::Backup::Account::Connection', :disconnect => nil) }
15
17
 
16
18
  before do
17
19
  allow(Imap::Backup::Configuration::Store).to receive(:new).and_return(store)
18
20
  allow(Imap::Backup::Configuration::Store).to receive(:exist?).and_return(exists)
21
+ allow(Imap::Backup::Account::Connection).to receive(:new).with(accounts[0]).and_return(connection1)
22
+ allow(Imap::Backup::Account::Connection).to receive(:new).with(accounts[1]).and_return(connection2)
19
23
  end
20
24
 
21
25
  subject { described_class.new }
22
26
 
23
27
  context '#initialize' do
28
+ end
29
+
30
+ context '#each_connection' do
31
+ specify "calls the block with each account's connection" do
32
+ connections = []
33
+
34
+ subject.each_connection { |a| connections << a }
35
+
36
+ expect(connections).to eq([connection1, connection2])
37
+ end
38
+
24
39
  context 'with account parameter' do
25
40
  subject { described_class.new(['a2@example.com']) }
26
41
 
27
42
  it 'should only create requested accounts' do
28
- expect(subject.accounts).to eq([accounts[1]])
29
- end
30
- end
43
+ connections = []
44
+
45
+ subject.each_connection { |a| connections << a }
31
46
 
32
- context 'without an account parameter' do
33
- it 'selects all accounts' do
34
- expect(subject.accounts).to eq(accounts)
47
+ expect(connections).to eq([connection2])
35
48
  end
36
49
  end
37
50
 
@@ -40,29 +53,9 @@ describe Imap::Backup::Configuration::List do
40
53
 
41
54
  it 'fails' do
42
55
  expect {
43
- described_class.new
56
+ subject.each_connection {}
44
57
  }.to raise_error(Imap::Backup::ConfigurationNotFound, /not found/)
45
58
  end
46
59
  end
47
60
  end
48
-
49
- context 'instance methods' do
50
- let(:connection1) { double('Imap::Backup::Account::Connection', :disconnect => nil) }
51
- let(:connection2) { double('Imap::Backup::Account::Connection', :disconnect => nil) }
52
-
53
- before do
54
- allow(Imap::Backup::Account::Connection).to receive(:new).with(accounts[0]).and_return(connection1)
55
- allow(Imap::Backup::Account::Connection).to receive(:new).with(accounts[1]).and_return(connection2)
56
- end
57
-
58
- context '#each_connection' do
59
- specify "calls the block with each account's connection" do
60
- connections = []
61
-
62
- subject.each_connection { |a| connections << a }
63
-
64
- expect(connections).to eq([connection1, connection2])
65
- end
66
- end
67
- end
68
61
  end
@@ -20,7 +20,8 @@ describe Imap::Backup::Configuration::Setup do
20
20
  double(
21
21
  'Imap::Backup::Configuration::Store',
22
22
  :data => data,
23
- :path => '/base/path'
23
+ :path => '/base/path',
24
+ :save => nil
24
25
  )
25
26
  end
26
27
 
@@ -45,15 +46,15 @@ describe Imap::Backup::Configuration::Setup do
45
46
  end
46
47
 
47
48
  it 'clears the screen' do
48
- subject.should_receive(:system).with('clear')
49
-
50
49
  subject.run
50
+
51
+ expect(subject).to have_received(:system).with('clear')
51
52
  end
52
53
 
53
54
  it 'should list accounts' do
54
55
  subject.run
55
56
 
56
- @output.string.should =~ /account@example.com/
57
+ expect(@output.string).to match /account@example.com/
57
58
  end
58
59
 
59
60
  context 'adding accounts' do
@@ -80,14 +81,15 @@ describe Imap::Backup::Configuration::Setup do
80
81
  end
81
82
 
82
83
  it 'should save the configuration' do
83
- @input.should_receive(:gets).with().and_return("save\n")
84
- store.should_receive(:save).with()
84
+ allow(@input).to receive(:gets).and_return("save\n")
85
85
 
86
86
  subject.run
87
+
88
+ expect(store).to have_received(:save)
87
89
  end
88
90
 
89
91
  it 'should exit' do
90
- @input.should_receive(:gets).with().and_return("quit\n")
92
+ allow(@input).to receive(:gets).and_return("quit\n")
91
93
 
92
94
  subject.run
93
95
  end
@@ -3,9 +3,9 @@ require 'spec_helper'
3
3
  require 'json'
4
4
 
5
5
  describe Imap::Backup::Configuration::Store do
6
- let(:file_path) { '/base/path/config.json' }
7
- let(:file_exists) { true }
8
6
  let(:directory) { '/base/path' }
7
+ let(:file_path) { File.join(directory, '/config.json') }
8
+ let(:file_exists) { true }
9
9
  let(:directory_exists) { true }
10
10
  let(:data) { {:the => :config} }
11
11
  let(:configuration) { data.to_json }
@@ -31,41 +31,9 @@ describe Imap::Backup::Configuration::Store do
31
31
  end
32
32
  end
33
33
 
34
- context '#initialize' do
35
- before :each do
36
- allow(Imap::Backup::Utils).to receive(:check_permissions).and_return(nil)
37
- end
38
-
39
- context 'loading' do
40
- subject { described_class.new }
41
-
42
- it 'sets data' do
43
- expect(subject.data).to eq(data)
44
- end
45
- end
46
-
47
- context 'if the configuration file is missing' do
48
- let(:file_exists) { false }
49
-
50
- it "doesn't fail" do
51
- expect do
52
- described_class.new
53
- end.to_not raise_error
54
- end
55
- end
56
-
57
- context 'if the config file permissions are too lax' do
58
- let(:file_exists) { true }
59
-
60
- before do
61
- allow(Imap::Backup::Utils).to receive(:check_permissions).with(file_path, 0600).and_raise('Error')
62
- end
63
-
64
- it 'fails' do
65
- expect do
66
- described_class.new
67
- end.to raise_error(RuntimeError, 'Error')
68
- end
34
+ context '#path' do
35
+ it 'is the directory containing the configuration file' do
36
+ expect(subject.path).to eq(directory)
69
37
  end
70
38
  end
71
39
 
@@ -79,6 +47,7 @@ describe Imap::Backup::Configuration::Store do
79
47
  allow(FileUtils).to receive(:chmod)
80
48
  allow(Imap::Backup::Utils).to receive(:stat).with(directory).and_return(0700)
81
49
  allow(Imap::Backup::Utils).to receive(:stat).with(file_path).and_return(0600)
50
+ allow(Imap::Backup::Utils).to receive(:check_permissions).and_return(nil)
82
51
  allow(File).to receive(:open).with(file_path, 'w') { |&b| b.call file }
83
52
  allow(JSON).to receive(:pretty_generate).and_return('JSON output')
84
53
  end
@@ -103,6 +72,30 @@ describe Imap::Backup::Configuration::Store do
103
72
  expect(FileUtils).to have_received(:chmod).with(0600, file_path)
104
73
  end
105
74
 
75
+ context 'if the configuration file is missing' do
76
+ let(:file_exists) { false }
77
+
78
+ it "doesn't fail" do
79
+ expect do
80
+ subject.save
81
+ end.to_not raise_error
82
+ end
83
+ end
84
+
85
+ context 'if the config file permissions are too lax' do
86
+ let(:file_exists) { true }
87
+
88
+ before do
89
+ allow(Imap::Backup::Utils).to receive(:check_permissions).with(file_path, 0600).and_raise('Error')
90
+ end
91
+
92
+ it 'fails' do
93
+ expect do
94
+ subject.save
95
+ end.to raise_error(RuntimeError, 'Error')
96
+ end
97
+ end
98
+
106
99
  context 'saving accounts' do
107
100
  let(:folders) { [{ :name => 'A folder' }] }
108
101
  let(:data) do
@@ -18,7 +18,7 @@ describe Imap::Backup::Downloader do
18
18
  :prepare => nil,
19
19
  :exist? => true,
20
20
  :uids => [],
21
- :save => nil
21
+ :save => nil,
22
22
  )
23
23
  end
24
24
 
@@ -29,7 +29,7 @@ describe Imap::Backup::Downloader do
29
29
  context '#run' do
30
30
  context 'with folder' do
31
31
  it 'should list messages' do
32
- folder.should_receive(:uids).and_return([])
32
+ allow(folder).to receive(:uids).and_return([])
33
33
 
34
34
  subject.run
35
35
  end
@@ -39,19 +39,12 @@ describe Imap::Backup::Downloader do
39
39
  allow(folder).to receive(:uids).and_return(['123', '999', '1234'])
40
40
  end
41
41
 
42
- it 'should skip messages that are downloaded' do
43
- allow(File).to receive(:exist?).and_return(true)
44
-
45
- serializer.should_not_receive(:fetch)
46
-
47
- subject.run
48
- end
49
-
50
42
  it 'skips failed fetches' do
51
- folder.should_receive(:fetch).with('999').and_return(nil)
52
- serializer.should_not_receive(:save).with('999', anything)
43
+ allow(folder).to receive(:fetch).with('999').and_return(nil)
53
44
 
54
45
  subject.run
46
+
47
+ expect(serializer).to_not have_received(:save).with('999', anything)
55
48
  end
56
49
 
57
50
  context 'to download' do
@@ -65,18 +58,18 @@ describe Imap::Backup::Downloader do
65
58
  end
66
59
  end
67
60
 
68
- it 'should request messages' do
69
- folder.should_receive(:fetch).with('999')
70
- folder.should_receive(:fetch).with('1234')
71
-
61
+ it 'requests messages' do
72
62
  subject.run
73
- end
74
63
 
75
- it 'should save messages' do
76
- serializer.should_receive(:save).with('999', message)
77
- serializer.should_receive(:save).with('1234', message)
64
+ expect(folder).to have_received(:fetch).with('999')
65
+ expect(folder).to have_received(:fetch).with('1234')
66
+ end
78
67
 
68
+ it 'saves messages' do
79
69
  subject.run
70
+
71
+ expect(serializer).to have_received(:save).with('999', message)
72
+ expect(serializer).to have_received(:save).with('1234', message)
80
73
  end
81
74
  end
82
75
  end
@@ -24,14 +24,14 @@ describe Imap::Backup::Serializer::Directory do
24
24
  end
25
25
 
26
26
  it 'returns the backed-up uids' do
27
- subject.uids.should == [1, 123]
27
+ expect(subject.uids).to eq([1, 123])
28
28
  end
29
29
 
30
30
  context 'if the directory does not exist' do
31
31
  let(:folder_exists) { false }
32
32
 
33
33
  it 'returns an empty array' do
34
- subject.uids.should == []
34
+ expect(subject.uids).to eq([])
35
35
  end
36
36
  end
37
37
  end
@@ -40,7 +40,7 @@ describe Imap::Backup::Serializer::Directory do
40
40
  it 'checks if the file exists' do
41
41
  allow(File).to receive(:exist?).with(%r{/base/path/my_folder/0+123.json}).and_return(true)
42
42
 
43
- subject.exist?(123).should be_true
43
+ expect(subject.exist?(123)).to be_truthy
44
44
  end
45
45
  end
46
46
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-15 00:00:00.000000000 Z
11
+ date: 2014-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -52,48 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: pry
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: pry-doc
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: rspec
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
59
  - - ">="
88
60
  - !ruby/object:Gem::Version
89
- version: 2.12.0
61
+ version: 3.0.0
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - ">="
95
67
  - !ruby/object:Gem::Version
96
- version: 2.12.0
68
+ version: 3.0.0
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: simplecov
99
71
  requirement: !ruby/object:Gem::Requirement
@@ -203,4 +175,3 @@ test_files:
203
175
  - spec/unit/serializer/directory_spec.rb
204
176
  - spec/unit/serializer/mbox_spec.rb
205
177
  - spec/unit/utils_spec.rb
206
- has_rdoc: