imap-backup 1.0.10 → 1.0.11

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.
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: