imap-backup 3.2.0 → 3.4.0

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
  SHA256:
3
- metadata.gz: b8661c03b8bf66e47c88fb69c476105945dad6fed867c510a151d62d0c401139
4
- data.tar.gz: 8964a8ef14fd1f8b04d23745513b3bdb8ad8283d3875bd6d559ef00e5092d1f2
3
+ metadata.gz: 44a7f8e8754461ed51afdbd5711ba809ad6b0ed68c0f40ff95a42688d85881b9
4
+ data.tar.gz: a70019109a179506f520b969bb03de78fa67fca66001b182af99427b7a02ecdd
5
5
  SHA512:
6
- metadata.gz: 8da502abc6b622f9261a223001a594e5e528d4f8871d209dd14a3bfd34693415bf5317b89d3bce892b0190027579d43f5c23f106f634423cb8fbf03fb82839e9
7
- data.tar.gz: 610d08941b592e2cbdd29b46404f1e31f83bb31c5c83f57994cbef576ab9ec31b1f11d92851fec55810242661fc31cdb0fffe0816357cfe4177c29ba7c1d3134
6
+ metadata.gz: 5055eea6a69b674f02f2b50c0423df197a4c312171aa04a19b183ce784047699815ac603d8550d28f78ada6f2aa4a904d74d5b7bef8f6ea10633de68752f7a65
7
+ data.tar.gz: 7849285c5b94136b7d5f620eac770630ea4e7cf988b42cc7079021dac95163c271f5fd68d5b620ac9d36326be142557c617459ba890755920c181110cf99531a
@@ -0,0 +1,51 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ ruby: circleci/ruby@1.1.2
5
+
6
+ references:
7
+ restore: &restore
8
+ restore_cache:
9
+ keys:
10
+ - 'imap.backup.<< parameters.ruby_version >>.{{checksum "imap-backup.gemspec"}}'
11
+ bundle: &bundle
12
+ run:
13
+ name: Install Ruby dependencies
14
+ command: |
15
+ bundle install
16
+ bundle clean
17
+ save: &save
18
+ save_cache:
19
+ key: 'imap.backup.<< parameters.ruby_version >>.{{checksum "imap-backup.gemspec"}}'
20
+ paths:
21
+ - vendor/bundle
22
+
23
+ jobs:
24
+ test:
25
+ parameters:
26
+ ruby_version:
27
+ type: string
28
+ environment:
29
+ BUNDLE_PATH: ./vendor/bundle
30
+ DOCKER_IMAP_PORT: 993
31
+ docker:
32
+ - image: "cimg/ruby:<< parameters.ruby_version >>"
33
+ - image: antespi/docker-imap-devel:latest
34
+ environment:
35
+ MAIL_ADDRESS: address@example.org
36
+ MAIL_PASS: pass
37
+ MAILNAME: example.org
38
+ steps:
39
+ - checkout
40
+ - <<: *restore
41
+ - <<: *bundle
42
+ - <<: *save
43
+ - ruby/rspec-test
44
+
45
+ workflows:
46
+ all-tests:
47
+ jobs:
48
+ - test:
49
+ matrix:
50
+ parameters:
51
+ ruby_version: ["2.4", "2.5", "2.6", "2.7"]
data/.rubocop_todo.yml CHANGED
@@ -1,42 +1,129 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2021-01-09 09:21:34 UTC using RuboCop version 0.89.1.
3
+ # on 2021-09-21 15:30:34 UTC using RuboCop version 1.21.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 11
10
- # Configuration parameters: IgnoredMethods.
11
- Metrics/AbcSize:
12
- Max: 33
9
+ # Offense count: 1
10
+ # Cop supports --auto-correct.
11
+ Layout/ElseAlignment:
12
+ Exclude:
13
+ - 'lib/imap/backup/configuration/gmail_oauth2.rb'
13
14
 
14
15
  # Offense count: 2
15
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
16
- # ExcludedMethods: refine
17
- Metrics/BlockLength:
18
- Max: 138
16
+ # Cop supports --auto-correct.
17
+ # Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines.
18
+ Layout/EmptyLineBetweenDefs:
19
+ Exclude:
20
+ - 'lib/google/auth/stores/in_memory_token_store.rb'
21
+
22
+ # Offense count: 1
23
+ # Cop supports --auto-correct.
24
+ # Configuration parameters: EnforcedStyleAlignWith, Severity.
25
+ # SupportedStylesAlignWith: keyword, variable, start_of_line
26
+ Layout/EndAlignment:
27
+ Exclude:
28
+ - 'lib/imap/backup/configuration/gmail_oauth2.rb'
29
+
30
+ # Offense count: 1
31
+ # Cop supports --auto-correct.
32
+ # Configuration parameters: Width, IgnoredPatterns.
33
+ Layout/IndentationWidth:
34
+ Exclude:
35
+ - 'lib/imap/backup/configuration/gmail_oauth2.rb'
36
+
37
+ # Offense count: 34
38
+ # Configuration parameters: AllowedMethods.
39
+ # AllowedMethods: enums
40
+ Lint/ConstantDefinitionInBlock:
41
+ Exclude:
42
+ - 'lib/imap/backup/configuration/asker.rb'
43
+ - 'spec/unit/gmail/authenticator_spec.rb'
44
+ - 'spec/unit/google/auth/stores/in_memory_token_store_spec.rb'
45
+ - 'spec/unit/imap/backup/account/connection_spec.rb'
46
+ - 'spec/unit/imap/backup/account/folder_spec.rb'
47
+ - 'spec/unit/imap/backup/configuration/account_spec.rb'
48
+ - 'spec/unit/imap/backup/configuration/gmail_oauth2_spec.rb'
19
49
 
20
50
  # Offense count: 2
51
+ # Cop supports --auto-correct.
52
+ # Configuration parameters: AllowComments.
53
+ Lint/UselessMethodDefinition:
54
+ Exclude:
55
+ - 'lib/imap/backup/configuration/account.rb'
56
+ - 'lib/imap/backup/configuration/asker.rb'
57
+
58
+ # Offense count: 11
59
+ # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
60
+ Metrics/AbcSize:
61
+ Max: 33
62
+
63
+ # Offense count: 3
21
64
  # Configuration parameters: CountComments, CountAsOne.
22
65
  Metrics/ClassLength:
23
- Max: 167
66
+ Max: 171
24
67
 
25
- # Offense count: 17
26
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
68
+ # Offense count: 19
69
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
27
70
  Metrics/MethodLength:
28
- Max: 25
71
+ Max: 26
29
72
 
30
73
  # Offense count: 2
31
74
  # Configuration parameters: CountComments, CountAsOne.
32
75
  Metrics/ModuleLength:
33
- Max: 141
76
+ Max: 145
77
+
78
+ # Offense count: 2
79
+ # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
80
+ # SupportedStyles: snake_case, normalcase, non_integer
81
+ # AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
82
+ Naming/VariableNumber:
83
+ Exclude:
84
+ - 'lib/email/provider.rb'
85
+ - 'spec/unit/email/provider_spec.rb'
34
86
 
35
- # Offense count: 200
87
+ # Offense count: 209
36
88
  # Configuration parameters: AllowSubject.
37
89
  RSpec/MultipleMemoizedHelpers:
38
90
  Max: 16
39
91
 
40
- # Offense count: 1
92
+ # Offense count: 49
41
93
  RSpec/NestedGroups:
42
94
  Max: 6
95
+
96
+ # Offense count: 8
97
+ # Cop supports --auto-correct.
98
+ # Configuration parameters: EnforcedStyle.
99
+ # SupportedStyles: nested, compact
100
+ Style/ClassAndModuleChildren:
101
+ Exclude:
102
+ - 'lib/email/mboxrd/message.rb'
103
+ - 'lib/imap/backup/downloader.rb'
104
+ - 'lib/imap/backup/serializer.rb'
105
+ - 'lib/imap/backup/serializer/mbox.rb'
106
+ - 'lib/imap/backup/serializer/mbox_enumerator.rb'
107
+ - 'lib/imap/backup/serializer/mbox_store.rb'
108
+ - 'lib/imap/backup/uploader.rb'
109
+ - 'lib/imap/backup/utils.rb'
110
+
111
+ # Offense count: 1
112
+ # Cop supports --auto-correct.
113
+ Style/RedundantBegin:
114
+ Exclude:
115
+ - 'lib/imap/backup/account/connection.rb'
116
+
117
+ # Offense count: 1
118
+ # Cop supports --auto-correct.
119
+ # Configuration parameters: MinSize, WordRegex.
120
+ # SupportedStyles: percent, brackets
121
+ Style/WordArray:
122
+ EnforcedStyle: percent
123
+
124
+ # Offense count: 1
125
+ # Cop supports --auto-correct.
126
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
127
+ # URISchemes: http, https
128
+ Layout/LineLength:
129
+ Max: 133
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://secure.travis-ci.org/joeyates/imap-backup.svg)][Continuous Integration]
1
+ [![Build Status](https://circleci.com/gh/joeyates/imap-backup.svg?style=svg)][Continuous Integration]
2
2
  [![Source Analysis](https://codeclimate.com/github/joeyates/imap-backup/badges/gpa.svg)](https://codeclimate.com/github/joeyates/imap-backup)
3
3
  [![Test Coverage](https://codeclimate.com/github/joeyates/imap-backup/badges/coverage.svg)](https://codeclimate.com/github/joeyates/imap-backup/coverage)
4
4
 
@@ -14,13 +14,21 @@
14
14
  [Source Code]: https://github.com/joeyates/imap-backup "Source code at GitHub"
15
15
  [API documentation]: http://rubydoc.info/gems/imap-backup/frames "RDoc API Documentation at Rubydoc.info"
16
16
  [Rubygem]: http://rubygems.org/gems/imap-backup "Ruby gem at rubygems.org"
17
- [Continuous Integration]: http://travis-ci.org/joeyates/imap-backup "Build status by Travis-CI"
17
+ [Continuous Integration]: https://circleci.com/gh/joeyates/imap-backup "Build status by CirceCI"
18
18
 
19
- ## GMail
19
+ # GMail
20
20
 
21
- GMail OAuth2 authentication is supported.
21
+ To use imap-backup with GMail, you will need to enable 'App passwords' on your account.
22
22
 
23
- To set it up, [follow the HOWTO](docs/setting-up-gmail.md).
23
+ ## GMail OAuth2
24
+
25
+ GMail OAuth2 authentication is supported, but as GMail's policy requires
26
+ users to set up an application specific to their account, the feature
27
+ is disabled by default.
28
+
29
+ You will need to set the environment variable IMAP_BACKUP_ENABLE_GMAIL_OAUTH2.
30
+
31
+ To set it up, [follow the HOWTO](docs/setting-up-gmail-with-oauth2.md).
24
32
 
25
33
  # Installation
26
34
 
@@ -212,6 +220,12 @@ $ rake
212
220
 
213
221
  To exclude Docker-based tests:
214
222
 
223
+ ```sh
224
+ rake no-docker
225
+ ```
226
+
227
+ or
228
+
215
229
  ```sh
216
230
  $ rspec --tag ~docker
217
231
  ```
data/Rakefile CHANGED
@@ -6,6 +6,12 @@ RSpec::Core::RakeTask.new do |t|
6
6
  t.pattern = "spec/**/*_spec.rb"
7
7
  end
8
8
 
9
+ desc "Run RSpec examples, excluding ones relying on Docker IMAP"
10
+ RSpec::Core::RakeTask.new("no-docker") do |t|
11
+ t.pattern = "spec/**/*_spec.rb"
12
+ t.rspec_opts = "--tag ~docker"
13
+ end
14
+
9
15
  RuboCop::RakeTask.new
10
16
 
11
17
  task default: :spec
data/bin/imap-backup CHANGED
@@ -82,7 +82,7 @@ when "folders"
82
82
  warn "Unable to list account folders"
83
83
  exit 1
84
84
  end
85
- folders.each { |f| puts "\t#{f.name}" }
85
+ folders.each { |f| puts "\t#{f}" }
86
86
  end
87
87
  when "restore"
88
88
  configuration.each_connection(&:restore)
data/imap-backup.gemspec CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |gem|
29
29
  gem.add_development_dependency "pry-byebug"
30
30
  end
31
31
  gem.add_development_dependency "rspec", ">= 3.0.0"
32
+ gem.add_development_dependency "rspec_junit_formatter"
32
33
  gem.add_development_dependency "rubocop-rspec"
33
34
  gem.add_development_dependency "simplecov"
34
35
  end
@@ -64,7 +64,12 @@ module Imap::Backup
64
64
 
65
65
  Imap::Backup.logger.debug "[#{folder.name}] running backup"
66
66
  serializer.apply_uid_validity(folder.uid_validity)
67
- Downloader.new(folder, serializer).run
67
+ begin
68
+ Downloader.new(folder, serializer).run
69
+ rescue Net::IMAP::ByeResponseError
70
+ reconnect
71
+ retry
72
+ end
68
73
  end
69
74
  end
70
75
 
@@ -91,7 +96,7 @@ module Imap::Backup
91
96
  "Creating IMAP instance: #{server}, options: #{options.inspect}"
92
97
  )
93
98
  imap = Net::IMAP.new(server, options)
94
- if gmail? && Gmail::Authenticator.refresh_token?(password)
99
+ if use_gmail_oauth2? && Gmail::Authenticator.refresh_token?(password)
95
100
  authenticator = Gmail::Authenticator.new(email: username, token: password)
96
101
  credentials = authenticator.credentials
97
102
  raise InvalidGmailOauth2RefreshToken if !credentials
@@ -163,8 +168,10 @@ module Imap::Backup
163
168
  password.gsub(/./, "x")
164
169
  end
165
170
 
166
- def gmail?
167
- server == Email::Provider::GMAIL_IMAP_SERVER
171
+ def use_gmail_oauth2?
172
+ # TODO: test use of ENV
173
+ server == Email::Provider::GMAIL_IMAP_SERVER &&
174
+ ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"]
168
175
  end
169
176
 
170
177
  def local_folders
@@ -69,7 +69,7 @@ module Imap::Backup
69
69
  def modify_password(menu)
70
70
  menu.choice("modify password") do
71
71
  password =
72
- if account[:server] == Email::Provider::GMAIL_IMAP_SERVER
72
+ if use_gmail_oauth2?(account)
73
73
  Configuration::GmailOauth2.new(account).run
74
74
  else
75
75
  Configuration::Asker.password
@@ -82,6 +82,11 @@ module Imap::Backup
82
82
  end
83
83
  end
84
84
 
85
+ def use_gmail_oauth2?(account)
86
+ account[:server] == Email::Provider::GMAIL_IMAP_SERVER &&
87
+ ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"]
88
+ end
89
+
85
90
  def modify_server(menu)
86
91
  menu.choice("modify server") do
87
92
  server = highline.ask("server: ")
@@ -8,7 +8,7 @@ module Imap::Backup
8
8
  You need to authorize imap_backup to get access to your email.
9
9
  To do so, please follow the instructions here:
10
10
 
11
- https://github.com/joeyates/imap-backup/docs/setting-up-gmail.md
11
+ https://github.com/joeyates/imap-backup/blob/main/docs/setting-up-gmail-with-oauth2.md
12
12
 
13
13
  BANNER
14
14
 
@@ -26,8 +26,20 @@ module Imap::Backup
26
26
  def run
27
27
  Kernel.system("clear")
28
28
  Kernel.puts BANNER
29
- @client_id = highline.ask("client_id: ")
30
- @client_secret = highline.ask("client_secret: ")
29
+
30
+ keep = if token.valid?
31
+ highline.agree("Use existing client info?")
32
+ else
33
+ false
34
+ end
35
+
36
+ if keep
37
+ @client_id = token.client_id
38
+ @client_secret = token.client_secret
39
+ else
40
+ @client_id = highline.ask("client_id: ")
41
+ @client_secret = highline.ask("client_secret: ")
42
+ end
31
43
 
32
44
  Kernel.puts <<~MESSAGE
33
45
 
@@ -46,9 +58,9 @@ module Imap::Backup
46
58
 
47
59
  raise "Failed" if !@credentials
48
60
 
49
- token = JSON.parse(token_store.load(email))
50
- token["client_secret"] = client_secret
51
- token.to_json
61
+ new_token = JSON.parse(token_store.load(email))
62
+ new_token["client_secret"] = client_secret
63
+ new_token.to_json
52
64
  end
53
65
 
54
66
  private
@@ -57,6 +69,14 @@ module Imap::Backup
57
69
  account[:username]
58
70
  end
59
71
 
72
+ def password
73
+ account[:password]
74
+ end
75
+
76
+ def token
77
+ @token ||= Gmail::Authenticator::ImapBackupToken.new(password)
78
+ end
79
+
60
80
  def highline
61
81
  Configuration::Setup.highline
62
82
  end
@@ -2,7 +2,7 @@ module Imap; end
2
2
 
3
3
  module Imap::Backup
4
4
  MAJOR = 3
5
- MINOR = 2
5
+ MINOR = 4
6
6
  REVISION = 0
7
7
  PRE = nil
8
8
  VERSION = [MAJOR, MINOR, REVISION, PRE].compact.map(&:to_s).join(".")
@@ -2,6 +2,6 @@
2
2
  :username: 'address@example.org'
3
3
  :password: 'pass'
4
4
  :connection_options:
5
- :port: 8993
5
+ :port: <%= ENV.fetch("DOCKER_IMAP_SERVER", 8993) %>
6
6
  :ssl:
7
7
  :verify_mode: 0
@@ -1,6 +1,11 @@
1
+ require "erb"
2
+ require "yaml"
3
+
1
4
  def fixture(name)
2
5
  spec_root = File.expand_path("..", File.dirname(__FILE__))
3
6
  fixture_path = File.join(spec_root, "fixtures", "#{name}.yml")
4
- fixture = File.read(fixture_path)
5
- YAML.safe_load(fixture, [Symbol])
7
+ content = File.read(fixture_path)
8
+ template = ERB.new(content)
9
+ yaml = template.result(binding)
10
+ YAML.safe_load(yaml, [Symbol])
6
11
  end
@@ -85,7 +85,7 @@ describe Gmail::Authenticator do
85
85
 
86
86
  it "is expected" do
87
87
  expect { subject }.to raise_error(
88
- ArgumentError, /missing keyword: :#{param}/
88
+ ArgumentError, /missing keyword: :?#{param}/
89
89
  )
90
90
  end
91
91
  end
@@ -111,7 +111,15 @@ describe Imap::Backup::Account::Connection do
111
111
  with(email: USERNAME, token: PASSWORD) { authenticator }
112
112
  end
113
113
 
114
- context "when the password is our copy of a GMail refresh token" do
114
+ context "when the password is our copy of a GMail refresh token and the environment IMAP_BACKUP_ENABLE_GMAIL_OAUTH2 is set" do
115
+ before do
116
+ ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"] = "1"
117
+ end
118
+
119
+ after do
120
+ ENV.delete("IMAP_BACKUP_ENABLE_GMAIL_OAUTH2")
121
+ end
122
+
115
123
  it "uses the OAuth2 access_token to authenticate" do
116
124
  subject.imap
117
125
 
@@ -288,6 +296,24 @@ describe Imap::Backup::Account::Connection do
288
296
  end
289
297
  end
290
298
 
299
+ context "when the IMAP session expires" do
300
+ before do
301
+ data = OpenStruct.new(data: "Session expired")
302
+ response = OpenStruct.new(data: data)
303
+ outcomes = [
304
+ -> { raise Net::IMAP::ByeResponseError, response },
305
+ -> { nil }
306
+ ]
307
+ allow(downloader).to receive(:run) { outcomes.shift.call }
308
+ end
309
+
310
+ it "reconnects" do
311
+ expect(downloader).to receive(:run).exactly(:twice)
312
+
313
+ subject.run_backup
314
+ end
315
+ end
316
+
291
317
  context "when run" do
292
318
  before { subject.run_backup }
293
319
 
@@ -214,16 +214,10 @@ describe Imap::Backup::Configuration::Account do
214
214
 
215
215
  describe "choosing 'modify password'" do
216
216
  let(:new_password) { "new_password" }
217
- let(:gmail_oauth2) do
218
- instance_double(Imap::Backup::Configuration::GmailOauth2, run: nil)
219
- end
220
217
 
221
218
  before do
222
219
  allow(Imap::Backup::Configuration::Asker).
223
220
  to receive(:password) { new_password }
224
- allow(Imap::Backup::Configuration::GmailOauth2).
225
- to receive(:new).
226
- with(account) { gmail_oauth2 }
227
221
  subject.run
228
222
  menu.choices["modify password"].call
229
223
  end
@@ -245,14 +239,49 @@ describe Imap::Backup::Configuration::Account do
245
239
 
246
240
  include_examples "it doesn't flag the account as modified"
247
241
  end
242
+ end
248
243
 
249
- context "when the server is for GMail" do
250
- let(:current_server) { GMAIL_IMAP_SERVER }
244
+ describe "choosing 'modify password' when the server is for GMail" do
245
+ let(:new_password) { "new_password" }
246
+ let(:current_server) { GMAIL_IMAP_SERVER }
247
+ let(:gmail_oauth2) do
248
+ instance_double(Imap::Backup::Configuration::GmailOauth2, run: nil)
249
+ end
250
+
251
+ before do
252
+ allow(Imap::Backup::Configuration::Asker).
253
+ to receive(:password) { new_password }
254
+ allow(Imap::Backup::Configuration::GmailOauth2).
255
+ to receive(:new).
256
+ with(account) { gmail_oauth2 }
257
+ end
258
+
259
+ context "when the environment IMAP_BACKUP_ENABLE_GMAIL_OAUTH2 is set" do
260
+ before do
261
+ ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"] = "1"
262
+ subject.run
263
+ menu.choices["modify password"].call
264
+ end
265
+
266
+ after do
267
+ ENV.delete("IMAP_BACKUP_ENABLE_GMAIL_OAUTH2")
268
+ end
251
269
 
252
270
  it "sets up GMail OAuth2" do
253
271
  expect(gmail_oauth2).to have_received(:run)
254
272
  end
255
273
  end
274
+
275
+ context "when the environment IMAP_BACKUP_ENABLE_GMAIL_OAUTH2 is not set" do
276
+ before do
277
+ subject.run
278
+ menu.choices["modify password"].call
279
+ end
280
+
281
+ it "sets up GMail OAuth2" do
282
+ expect(gmail_oauth2).to_not have_received(:run)
283
+ end
284
+ end
256
285
  end
257
286
 
258
287
  describe "choosing 'modify server'" do
@@ -1,6 +1,9 @@
1
1
  describe Imap::Backup::Configuration::GmailOauth2 do
2
2
  include HighLineTestHelpers
3
3
 
4
+ CLIENT_ID = "my_client_id".freeze
5
+ CLIENT_SECRET = "my_client_secret".freeze
6
+
4
7
  subject { described_class.new(account) }
5
8
 
6
9
  let(:authorization_url) { "some long authorization_url" }
@@ -11,6 +14,7 @@ describe Imap::Backup::Configuration::GmailOauth2 do
11
14
  let(:input) { highline_streams[0] }
12
15
  let(:output) { highline_streams[1] }
13
16
  let(:account) { {} }
17
+ let(:user_input) { %W(my_client_id\n my_secret\n my_code\n) }
14
18
 
15
19
  let(:authorizer) do
16
20
  instance_double(
@@ -25,23 +29,31 @@ describe Imap::Backup::Configuration::GmailOauth2 do
25
29
  load: json_token
26
30
  )
27
31
  end
32
+ let(:token) do
33
+ instance_double(
34
+ Gmail::Authenticator::ImapBackupToken,
35
+ valid?: valid,
36
+ client_id: CLIENT_ID,
37
+ client_secret: CLIENT_SECRET
38
+ )
39
+ end
40
+ let(:valid) { false }
28
41
 
29
42
  before do
30
43
  allow(Google::Auth::UserAuthorizer).
31
44
  to receive(:new) { authorizer }
32
45
  allow(Google::Auth::Stores::InMemoryTokenStore).
33
46
  to receive(:new) { token_store }
47
+ allow(Gmail::Authenticator::ImapBackupToken).
48
+ to receive(:new) { token }
34
49
 
35
50
  allow(highline).to receive(:ask).and_call_original
51
+ allow(highline).to receive(:agree).and_call_original
36
52
 
37
53
  allow(Kernel).to receive(:system)
38
54
  allow(Kernel).to receive(:puts)
39
55
 
40
- allow(input).to receive(:gets).and_return(
41
- "my_client_id\n",
42
- "my_secret\n",
43
- "my_code\n"
44
- )
56
+ allow(input).to receive(:gets).and_return(*user_input)
45
57
  end
46
58
 
47
59
  describe "#run" do
@@ -80,5 +92,30 @@ describe Imap::Backup::Configuration::GmailOauth2 do
80
92
  it "includes the client_secret in the credentials" do
81
93
  expect(result).to match('"client_secret":"my_secret"')
82
94
  end
95
+
96
+ context "when the account already has client info" do
97
+ let(:valid) { true }
98
+ let(:user_input) { %W(yes\n) }
99
+
100
+ it "requests confirmation of client info" do
101
+ expect(highline).to have_received(:agree).with("Use existing client info?")
102
+ end
103
+
104
+ context "when yhe user says 'no'" do
105
+ let(:user_input) { %W(no\n) }
106
+
107
+ it "requests client_id" do
108
+ expect(highline).to have_received(:ask).with("client_id: ")
109
+ end
110
+
111
+ it "requests client_secret" do
112
+ expect(highline).to have_received(:ask).with("client_secret: ")
113
+ end
114
+
115
+ it "requests the success code" do
116
+ expect(highline).to have_received(:ask).with("success code: ")
117
+ end
118
+ end
119
+ end
83
120
  end
84
121
  end
@@ -43,7 +43,7 @@ describe Imap::Backup::Configuration::Setup do
43
43
  describe "main menu" do
44
44
  before { subject.run }
45
45
 
46
- %w(add\ account save\ and\ exit exit\ without\ saving).each do |choice|
46
+ ["add account", "save and exit", "exit without saving"].each do |choice|
47
47
  it "includes #{choice}" do
48
48
  expect(output.string).to include(choice)
49
49
  end
@@ -12,7 +12,6 @@ describe Imap::Backup::Utils do
12
12
  describe ".check_permissions" do
13
13
  let(:requested) { 0o345 }
14
14
 
15
- # rubocop:disable RSpec/EmptyExampleGroup
16
15
  context "with existing files" do
17
16
  [
18
17
  [0o100, "less than the limit", true],
@@ -37,7 +36,6 @@ describe Imap::Backup::Utils do
37
36
  end
38
37
  end
39
38
  end
40
- # rubocop:enable RSpec/EmptyExampleGroup
41
39
 
42
40
  context "with non-existent files" do
43
41
  let(:exists) { false }
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: 3.2.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-07 00:00:00.000000000 Z
11
+ date: 2021-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gmail_xoauth
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 3.0.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec_junit_formatter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: rubocop-rspec
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -158,12 +172,12 @@ executables:
158
172
  extensions: []
159
173
  extra_rdoc_files: []
160
174
  files:
175
+ - ".circleci/config.yml"
161
176
  - ".gitignore"
162
177
  - ".rspec"
163
178
  - ".rspec-all"
164
179
  - ".rubocop.yml"
165
180
  - ".rubocop_todo.yml"
166
- - ".travis.yml"
167
181
  - Gemfile
168
182
  - LICENSE
169
183
  - README.md
@@ -196,7 +210,7 @@ files:
196
210
  - docs/26-type-code-into-imap-backup.png
197
211
  - docs/27-success.png
198
212
  - docs/docker-imap.md
199
- - docs/setting-up-gmail.md
213
+ - docs/setting-up-gmail-with-oauth2.md
200
214
  - imap-backup.gemspec
201
215
  - lib/email/mboxrd/message.rb
202
216
  - lib/email/provider.rb
@@ -276,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
276
290
  - !ruby/object:Gem::Version
277
291
  version: '0'
278
292
  requirements: []
279
- rubygems_version: 3.1.2
293
+ rubygems_version: 3.1.4
280
294
  signing_key:
281
295
  specification_version: 4
282
296
  summary: Backup GMail (or other IMAP) accounts to disk
data/.travis.yml DELETED
@@ -1,25 +0,0 @@
1
- language: ruby
2
-
3
- services:
4
- - docker
5
-
6
- rvm:
7
- - 2.4
8
- - 2.5
9
- - 2.6
10
- - 2.7
11
- - jruby-19mode
12
-
13
- branches:
14
- only:
15
- - master
16
-
17
- before_install:
18
- - gem update --system
19
- - gem update bundler
20
-
21
- script:
22
- - docker pull antespi/docker-imap-devel:latest
23
- - docker run -d --env MAIL_ADDRESS=address@example.org --env MAIL_PASS=pass --env MAILNAME=example.org --publish 8993:993 antespi/docker-imap-devel:latest
24
- - sleep 10
25
- - bundle exec rake