mail_runner 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c867be342a949392aa028eab45d263043929f6a7
4
- data.tar.gz: 3f1eef044f8e09e8783e9b9de6938a7f0dd2248b
3
+ metadata.gz: ea440f11b72d87c1092c0d42120549bffbe0c997
4
+ data.tar.gz: 9ec7d59c90a08b354ccf904e3f21dec2372f9865
5
5
  SHA512:
6
- metadata.gz: 2f3766091b2c171e155f6138b6f17df1a82387262e283f4caa5b46d8b64a4fb294bbb9b80bbade7b9049f826c8a61a8c080cf0ac1c00a9f75fc8603e03a0695f
7
- data.tar.gz: 7a03821b4edace1182ba1e4c32f3801147c46333635e3964be3ff228e346a9961258cbb7157724bf4c19a190bb8ba3a4daeb1a277103c812d83eb895145704de
6
+ metadata.gz: a262d9ee7a41d399ac11ef6849ec6fe87dcb606b2ac53a423e916e87ede61120915f6d19c3918ee569af4d6342ab7caabcbf22ee968c18e089aa1cd6ba4e376c
7
+ data.tar.gz: fdb1fc94033e3cf60b00264700184eba923973aee4c93eacfdcc42d96e6b28fc69ec030fd69cf59849ac7d80e8bde43a9e9c85a6b3a88c4c8bb5f2d5d3e2ff6a
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
1
  #mail_runner
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/mail_runner.svg)](https://badge.fury.io/rb/mail_runner) [![Code Climate](https://codeclimate.com/github/kert-io/mail_runner/badges/gpa.svg)](https://codeclimate.com/github/kert-io/mail_runner)
4
+
2
5
  **WORK IN PROGRESS**. See Roadmap below for features not yet completed.
3
6
 
4
7
  MailRunner acts as your mailman picking up your email from an [MTA](https://en.wikipedia.org/wiki/Message_transfer_agent), such as Postfix, and then delivering it directly to your app sending each email object as json to webhook. You can tell it to deliver locally or send it to any active webhook making it a functional mailserver for several apps.
@@ -105,28 +108,151 @@ keys | Value
105
108
  If for any reason, mailrunner is not able to deliver the mail to the specified webhook, it will add it to the mailrunner mail queue to process later. The usual reason this occurs is the webhook is unresponsive, it returns an error code or the server is down. Mailrunner will intermittently test the server if this occurs and once it is working properly, it will process the queue. If mail is not being delivered, you can check the mailrunner log for details on what is happening on mailrunners end.
106
109
 
107
110
  ## Additional Options
108
- ####Daemonize
111
+ ###Daemonize
109
112
  Use the `-d ` flag to turn mailrunner into a [daemon](https://en.wikipedia.org/wiki/Daemon_(computing)) & keep it running in the the background. When running as a daemon, be sure to set the logfile path using the ` -L ` flag.
110
113
 
111
- ####Logging
112
- Mailrunner wil output all logging info to STDOUT if no logfile path is set. To set a logfile path, use the `-L path/to/logfile.log ` flag followed by the absolute path to the logfile location. If the file doesn't exist, it will be created, but the directory path must still be valid.
114
+ ###Logging
115
+ Mailrunner wil output all logging info to STDOUT if no logfile path is set.
116
+
117
+ To set a logfile path, use the `-L path/to/logfile.log ` flag followed by the absolute path to the logfile location. If the file doesn't exist, it will be created, but the directory path must still be valid.
118
+
119
+ Mailrunner logging is designed for leaving it running continuously in the background. So the log doesn't become unusable, logs will automatically archive themselves in the same directory and start a new log each week.
113
120
 
114
- ####archive
115
- ####Config
121
+ ###Archive
122
+ Alongside delivery to any webhook hook, Mailrunner also supports archiving your emails. Beyond archival purposes, this is super convenient for chasing down bugs, feature testing, and system error recovery. Mailrunner can archive locally or to a cloud storage device. Mailrunner currently supports AWS & Rackspace.
123
+
124
+ Use the Config file option when using the archive feature to simplify passing archive parameters to mailrunner. Archive option notes are included directly in the [sample config file](https://gist.github.com/kert-io/3d8d24d048dd25801b7f)
125
+
126
+ **File Naming**
127
+ All archived messages are saved as json and use the unique message-id as the file name. (NOTE: All illegal file system characters have been replaced with underscores; check the message-id in the message header section when seeking the actual id.)
128
+
129
+ When looking for an archived copy of a message, you must locate it by the message-id. To do so, run the id through the same name-scrubbing process used during the archive process: `/[#<$+%>!&*?=\/:@]/` are replaced with '_'.
130
+
131
+ ###Config File
116
132
 
117
133
  Mailrunner can also be launched with a config file storing all defaults in one place. When using a config file, you can launch a mailrunner instance with `mailrunner -c /path/to/config.yml` leaving off all typically required flags. [sample config file](https://gist.github.com/kert-io/3d8d24d048dd25801b7f)
118
134
 
119
135
  When using a config file you can set your defaults in the config file but still override them for one-off instances using flags. The instance will launch according to the config file, but override only the options passed manually with each flag.
120
136
 
121
- # Other usage Scenarios
122
- ####dtach
123
- ####Monit
137
+ ## Other usage Scenarios
138
+ ###Monit
139
+ NOTE: before setting up Monit, test manually with desired config file settings.
140
+
141
+ I prefer to use [Monit](https://mmonit.com/monit/) to manage my worker bots. Why Monit? Because I like working with native linux config files when working at the system level. (Many others try to blend conventions and I find it leads to holes in seeing your system and its bugs completely.)
142
+
143
+ Monit will monitor your daemonized processes, restart them in case of failure and dutifully send you a notification or email with each action. It makes it possible to pretty much start and walk away. (psst, it does a ton more too!!)
144
+
145
+ You can tweak mailrunner to run with your preferred monitor, but I offer the monit setup here:
124
146
 
147
+ **step 1 - Configure Upstart to manage mailrunner at the system service level**
148
+
149
+ While monit monitors, it uses Upstart control processes directly. [Upstart](http://upstart.ubuntu.com) is the native linux process for starting and stopping processes and keeping track of all system processes.
150
+
151
+ * navigate to init folder where all Upstart config files are stored. Create a new .conf file for mailrunner & open it with text editor:
152
+
153
+ ```sh
154
+ cd /etc/init
155
+ sudo touch mailrunner.conf
156
+ sudo vim mailrunner.conf
157
+ ```
158
+
159
+ * Paste the following inside the .conf file. Substitute your username into the setuid & HOME variables in the User Variables section to suit your deployment and save.
160
+ * **setuid** - login name of user account you used when installing mailrunner.
161
+ * **HOME** - Note this is to locate your locally installed gems using rbenv. You can also modify uncomment th global install setup included as well.
162
+
163
+ ```sh
164
+ # sudo start mailrunner
165
+ # sudo stop mailrunner
166
+ # sudo status mailrunner
167
+ #
168
+ # or use the service command:
169
+ # sudo service mailrunner {start,stop,restart,status}
170
+
171
+ description "Upstart control over MailRunner bots. From ruby gem mail_runner"
172
+
173
+ # no "start on", we don't want to automatically start
174
+ stop on (runlevel [06])
175
+
176
+ ##########################################
177
+ # change to match your deployment user
178
+ setuid username
179
+ env HOME="/home/username"
180
+ ############################################
181
+ script
182
+ # this script runs in /bin/sh by default
183
+ # respawn as bash so we can source in rbenv
184
+ exec /bin/bash <<'EOT'
185
+
186
+ # pull in system rbenv
187
+ # source /etc/profile.d/rbenv.sh
188
+ # or
189
+ # pull in user installed rbenv
190
+ export PATH="$HOME/.rbenv/bin:$PATH"
191
+ eval "$(rbenv init -)"
192
+ export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
193
+
194
+ #launch mailrunner
195
+ exec mail_runner -c $HOME/mailrunner_config.yml
196
+
197
+ EOT
198
+ end script
199
+ ```
200
+
201
+ * You can now start and stop mailrunner with the the following system level commands:
202
+
203
+ ```sh
204
+ sudo start mailrunner
205
+ sudo stop mailrunner
206
+ sudo restart mailrunner
207
+ ```
208
+
209
+ * NOTE: You must use the Mailrunner Config file to use Upstart and Monit. See Mailrunner config section above. This Upstart config assumes you store the mailrunner_config.yml file in your home directory.
210
+
211
+ **step 2 - Install and set up Monit to monitor & manage Mailrunner**
212
+
213
+ * Install Monit. see this [gist]() for guidance
214
+
215
+ With Monit installed, it is easy to set it up to monitor Mailrunner. Monit stores the config files for each process it monitors in the conf.d folder.
216
+
217
+ * navigate to conf.d folder. Create a new conf file for mailrunner & open it with text editor:
218
+
219
+ ```sh
220
+ cd /etc/monit/conf.d
221
+ sudo touch mailrunner
222
+ sudo vim mailrunner
223
+ ```
224
+ * Paste the following inside the .conf file & save. You can modify the triggers to suit your workload and resource allocation, but best to just let it run and watch it for a while and fine tune it for you setup.
225
+
226
+ ```sh
227
+ # mailrunner
228
+ check process mailrunner
229
+ with matching mail_runner
230
+
231
+ start program = "/bin/bash -c 'start mailrunner'"
232
+ stop program = "/bin/bash -c 'stop mailrunner'"
233
+
234
+ #process monitor triggers
235
+ if cpu is greater than 10% for 2 cycles then alert
236
+ if mem is greater than 3% for 1 cycles then restart
237
+ if 3 restarts within 5 cycles then timeout
238
+ ```
239
+
240
+ * reload monit settings to pull in your new config
241
+
242
+ ```sh
243
+ sudo monit reload
244
+ ```
245
+ * Start mailrunner using monit. Check status to see it initializing
246
+
247
+ ```sh
248
+ sudo monit start mailrunner
249
+ sudo monit status
250
+ ```
251
+ * Monit has a ton more features like alerts & notifications. I highly recommend setting these up and monit will let you know whenever it needs your attention. Now, relax;-)
252
+
253
+
125
254
  #Roadmap
126
- * Archiving
127
- * Run from Config file
128
255
  * Single bot managing several mailboxes and webhooks
129
- * Run bots from config file
130
256
  * test server
131
257
 
132
258
 
@@ -0,0 +1,107 @@
1
+ module MailRunner
2
+ module ArchivistBot
3
+
4
+ def self.add_to_archive_stack(msg, archive)
5
+ que_packet = [msg, archive]
6
+ $redis.lpush("archive_stack", que_packet.to_json)
7
+ $logger.info("Archivist") { "#add_to_archive_stack:: email added to queue for processing later." }
8
+ end
9
+
10
+ def self.stack_height
11
+ return $redis.llen("archive_stack")
12
+ end
13
+
14
+ def self.archive_stack
15
+ $logger.info("Archivist") { "Stack Height:: #{stack_height}"}
16
+ while stack_height > 0
17
+ $logger.info("Archivist") { "#archive_stack:: Processing stack item:: #{stack_height}"}
18
+ msg, archive = pop_from_stack
19
+
20
+ if archive["destination"] == 'local'
21
+ deliver_to_local_archive(msg, archive)
22
+ else
23
+ deliver_to_cloud_archive(msg, archive)
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.pop_from_stack
29
+ key, que_packet = $redis.blpop("archive_stack", :timeout => 5) #timeout needed for MockRedis in Testing Env.
30
+ $logger.info("Archivist") { "#item popped from stack for processing"}
31
+ data = JSON::parse(que_packet)
32
+ msg = data[0]
33
+ archive = data[1]
34
+ return msg, archive
35
+ end
36
+
37
+ def self.deliver_to_local_archive(msg, archive_opts)
38
+ begin
39
+ filename = name_msg(msg)
40
+ target = File.open("#{archive_opts["local_archive"]}/#{filename}", 'w')
41
+ target.write(msg)
42
+ target.close()
43
+ $logger.info("Archivist") { "#Message archived to local"}
44
+ rescue => e
45
+ $logger.error("Archivist") { "#deliver_to_local_archive:: failed: #{e.inspect}"}
46
+ add_to_archive_stack(msg,archive_opts)
47
+ end
48
+ end
49
+
50
+ def self.deliver_to_cloud_archive(msg, archive_opts)
51
+ attempts = 0
52
+ begin
53
+ archive = establish_archive_link(archive_opts)
54
+ filename = name_msg(msg)
55
+ mimetype = "application/json"
56
+
57
+ saved = archive.files.create :key => filename, :body => msg, :Content_type => mimetype
58
+ $logger.info("Archivist") { "#Message archived to cloud"}
59
+ return saved #explicit for testing
60
+ rescue => e
61
+ $logger.error("Archivist") { "#deliver_to_cloud_archive:: attempt #{attempts} failed: #{e.inspect}"}
62
+ attempts += 1
63
+ retry unless attempts > 1
64
+ unless saved
65
+ $logger.info("Archivist") { "Too many failed attempts, restacking msg."}
66
+ add_to_archive_stack(msg,archive_opts)
67
+ end
68
+ end
69
+ end
70
+
71
+ def self.name_msg(msg)
72
+ msg_id = JSON.parse(msg)[0]["msg"]["headers"]["Message-ID"]
73
+ return "#{msg_id.gsub(/[#<$+%>!&*?=\/:@]/,'_')}.json"#clean illegal charaters
74
+ end
75
+
76
+ def self.establish_archive_link(archive_opts)
77
+ service = new_storage_object(archive_opts)
78
+ dir_name = archive_opts["directory"]
79
+ archive_directory = service.directories.new :key => dir_name
80
+ return archive_directory
81
+ end
82
+
83
+ def self.new_storage_object(archive_opts)
84
+ options = format_options(archive_opts)
85
+ Fog::Storage.new(options)
86
+ end
87
+
88
+ def self.format_options(archive_opts)
89
+ provider = archive_opts["provider"].downcase
90
+
91
+ options = {
92
+ :provider => archive_opts["provider"]
93
+ }
94
+ if provider == "rackspace"
95
+ options[:"#{provider}_username"] = archive_opts["username"]
96
+ options[:"#{provider}_api_key"] = archive_opts["api_key"]
97
+ options[:"#{provider}_region"] = archive_opts["region"]
98
+ elsif provider == "aws"
99
+ options[:"#{provider}_access_key_id"] = archive_opts["api_key"]
100
+ options[:"#{provider}_secret_access_key"] = archive_opts["secret_key"]
101
+ end
102
+
103
+ return options
104
+ end
105
+
106
+ end
107
+ end
@@ -7,8 +7,14 @@ module BotHelpers
7
7
  def self.print_monitoring_started_msg(bot)
8
8
  $logger.info("Helpers") { "mailbox: #{bot.mailbox}" }
9
9
  $logger.info("Helpers") { "path: #{bot.webhook}"}
10
- $logger.info("Helpers") {"archive: #{bot.archive}"}
11
- puts "Getter Bot is on the Job!"
10
+ unless bot.archive.nil?
11
+ if bot.archive[:destination] == 'cloud'
12
+ $logger.info("Helpers") {"archive: #{bot.archive[:provider]} :: #{bot.archive[:directory]}"}
13
+ else
14
+ $logger.info("Helpers") {"archive: #{bot.archive[:destination]} :: #{bot.archive[:local_archive]}"}
15
+ end
16
+ end
17
+ puts "Getter Bot is on the Job!"
12
18
  end
13
19
 
14
20
  def self.convert_raw_mail_to_json(mail)
@@ -1,14 +1,10 @@
1
1
  module BotHelpers
2
2
  module Tests #series of initial command validation tests on launch.
3
- def self.all_args_included?(args)
3
+
4
+ def self.all_args_included?(args)
4
5
  if args[:mailbox].nil? or args[:webhook].nil?
5
6
  raise ArgumentError, 'You must include mailbox & webhook minimum. Archive argument is optional. Add -h to see help.'
6
7
  end
7
- #if args.size > 3
8
- # raise ArgumentError, 'You can only include mailbox, webhook & Archive argument. 3 max! Add -h to see help.'
9
- #end
10
- #?test format of mailbox?
11
- #? test valid webhook format?
12
8
  end
13
9
 
14
10
  def self.test_mailbox (path)
@@ -21,7 +17,7 @@ module BotHelpers
21
17
  begin
22
18
  response = RestClient.head url
23
19
  MailRunner.manager_bot.update_webhook_status("live")
24
- rescue
20
+ rescue
25
21
  raise ArgumentError, "ERROR: \nMake sure the server is running and the webhook exists.\nNOTE: Server must respond to http HEAD method.\nSee README.md for proper setup.\n"
26
22
  end
27
23
  unless response.code == 200
@@ -38,6 +34,30 @@ module BotHelpers
38
34
  end
39
35
  end
40
36
 
41
- end
37
+ def self.test_archive(a_set)
38
+ if a_set[:destination] == 'local'
39
+ test_local_archive(a_set)
40
+ elsif a_set[:destination] == 'cloud'
41
+ test_cloud_archive_connection(a_set)
42
+ else
43
+ raise ArgumentError, "ERROR: Archive destination setting invalid."
44
+ end
45
+ end
46
+
47
+ def self.test_local_archive(a_set)
48
+ unless File.directory?(a_set[:local_archive])
49
+ raise ArgumentError, "ERROR: Invalid local archive path."
50
+ end
51
+ end
52
+
53
+ def self.test_cloud_archive_connection(a_set)
54
+ a_set = JSON.parse(a_set.to_json) #Must parse as json, similar to redis queues. Stringifies symbol keys.
55
+ begin
56
+ response = MailRunner::ArchivistBot.establish_archive_link(a_set)
57
+ rescue => e
58
+ raise ArgumentError, "ERROR: Archive connection failed. Check your archive config options or disable."
59
+ end
60
+ end
42
61
 
62
+ end
43
63
  end
@@ -26,7 +26,7 @@ module MailRunner
26
26
  opts[:webhook] = arg
27
27
  end
28
28
 
29
- o.on '-a', '--archive', "Set to true id you want mail archived." do |arg|
29
+ o.on '-a', '--archive', "Use config file to setup archive option." do |arg|
30
30
  opts[:archive] = arg
31
31
  end
32
32
 
@@ -93,23 +93,6 @@ module MailRunner
93
93
  def self.set_globals
94
94
  MailRunner.set_globals
95
95
  end
96
-
97
- def self.banner
98
- %q{
99
- m,
100
- `$b
101
- .ss, $$: .,d$
102
- `$$P,d$P' .,md$P"'
103
- ,$$$$$bmmd$$$P^'
104
- .d$$$$$$$$$$P'
105
- $$^' `"^$$$' ____ _ _ _ _
106
- $: ,$$: / ___|(_) __| | ___| | _(_) __ _
107
- `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` |
108
- $$: ___) | | (_| | __/ <| | (_| |
109
- $$ |____/|_|\__,_|\___|_|\_\_|\__, |
110
- .d$$ |_|
111
- }
112
- end
113
96
  end
114
97
  end
115
98
 
@@ -3,6 +3,7 @@ require 'json'
3
3
  require 'base64'
4
4
  require 'rest-client'
5
5
  require 'redis'
6
+ require 'fog'
6
7
 
7
8
  module MailRunner
8
9
 
@@ -24,7 +25,7 @@ module MailRunner
24
25
  def initialize
25
26
  @mailbox = nil
26
27
  @webhook = nil
27
- @archive = false
28
+ @archive = nil
28
29
  @webhook_status = nil
29
30
  end
30
31
 
@@ -39,7 +40,7 @@ module MailRunner
39
40
 
40
41
  @mailbox = "/var/mail/#{opts[:mailbox]}"
41
42
  @webhook = opts[:webhook]
42
- @archive = opts[:archive] == "true" ? true : false
43
+ @archive = opts[:archive].nil? ? nil : opts[:archive]
43
44
  end
44
45
 
45
46
  def update_webhook_status(status)
@@ -47,8 +48,9 @@ module MailRunner
47
48
  end
48
49
 
49
50
  def test_options
50
- BotHelpers::Tests.test_mailbox(self.mailbox)
51
- BotHelpers::Tests.test_webhook(self.webhook)
51
+ BotHelpers::Tests.test_mailbox(self.mailbox)
52
+ BotHelpers::Tests.test_webhook(self.webhook)
53
+ BotHelpers::Tests.test_archive(self.archive) unless self.archive.nil?
52
54
  end
53
55
 
54
56
  def run
@@ -64,10 +66,15 @@ module MailRunner
64
66
  delegate_delayed_queue_processing
65
67
  end
66
68
 
69
+ if archive_stack?
70
+ delegate_archive_stack_processing
71
+ end
72
+
67
73
  sleep 5
68
74
  end
69
75
  end
70
76
 
77
+ #### Delegation Methods ####
71
78
 
72
79
  def inbound_manager
73
80
  MailRunner::InboundManagerBot
@@ -97,6 +104,22 @@ module MailRunner
97
104
  puts msg.inspect
98
105
  end
99
106
  end
107
+
108
+ def archivist
109
+ MailRunner::ArchivistBot
110
+ end
111
+
112
+ def archive_stack?
113
+ archivist.stack_height > 0
114
+ end
115
+
116
+ def delegate_archive_stack_processing
117
+ begin
118
+ archivist.archive_stack
119
+ rescue Exception => msg
120
+ puts msg.inspect
121
+ end
122
+ end
100
123
 
101
124
  end
102
125
  end
@@ -2,7 +2,7 @@ module MailRunner
2
2
 
3
3
  module InboundManagerBot
4
4
 
5
- def self.process_inbound(mailbox, webhook, archive)
5
+ def self.process_inbound(mailbox, webhook, archive=nil)
6
6
  raw_mail = get_mail(mailbox)
7
7
 
8
8
  unless raw_mail.nil?
@@ -13,15 +13,18 @@ module MailRunner
13
13
  json_packet = BotHelpers::Helpers.convert_raw_mail_to_json(mail)
14
14
 
15
15
  deliver_mail(webhook, json_packet)
16
-
17
- if archive == true && queued.nil?
18
- puts "we will archive email.\n"
16
+
17
+ #Mail archived regardless of delivery errors.
18
+ #Delayed mail processed by queue manager, so only archived once on initial pickup.
19
+ if archive
20
+ MailRunner::ArchivistBot.add_to_archive_stack(json_packet, archive)
19
21
  end
20
-
21
22
  end
22
23
  end
23
24
  end
24
25
 
26
+ ###Delegation Methods###
27
+
25
28
  def self.get_mail(mailbox)
26
29
  BotHelpers::Runner.get_contents_from_mailbox(mailbox)
27
30
  end
@@ -40,6 +43,6 @@ module MailRunner
40
43
  end
41
44
  end
42
45
 
43
- end
44
46
 
47
+ end
45
48
  end
@@ -1,3 +1,3 @@
1
1
  module MailRunner
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency "mail", "~> 2.5.4"
25
25
  s.add_dependency "json", "~> 1.8.1"
26
26
  s.add_dependency "rest-client", "~> 1.8.0"
27
+ s.add_dependency "fog", "~> 1.23.0"
27
28
 
28
29
 
29
30
  s.add_development_dependency 'rake', "~> 10.3.2"
@@ -5,6 +5,7 @@ require 'minitest/spec'
5
5
  require "minitest/reporters"
6
6
  require 'minitest-spec-context'
7
7
  require 'mock_redis'
8
+ require 'fog'
8
9
  require_relative '../lib/mail_runner.rb'
9
10
 
10
11
  #Use Mock Redis during testing - Can't use any blocking methods!!
@@ -0,0 +1,90 @@
1
+ #####################
2
+
3
+
4
+
5
+ ######################
6
+ require_relative 'helper'
7
+
8
+ class TestArchivist < Minitest::Test
9
+
10
+ ####### Top Level Call Tests ##########
11
+ describe"Archivist::stack_height" do
12
+ before do
13
+ @archivist = MailRunner::ArchivistBot
14
+ end
15
+ it "returns an integer" do
16
+ assert_instance_of Fixnum, @archivist.stack_height
17
+ end
18
+ end
19
+
20
+ describe "Archivist::deliver_to_local_archive" do
21
+ before do
22
+ `mkdir /tmp/local_test_archive`
23
+ $redis.del("archive_stack") #zero list
24
+ @archivist = MailRunner::ArchivistBot
25
+ @filename = "_1447427485391-46840973-67af09f8-7a989c0d_mixmax.com_.json"
26
+ @msg = File.read("#{Dir[File.dirname(__FILE__)][0] + '/test_assets/' + @filename}")
27
+ @archive_opts = {"local_archive" => '/tmp/local_test_archive'}
28
+ end
29
+ after do
30
+ `rm -rf /tmp/local_test_archive`
31
+ end
32
+ context 'when local path is valid' do
33
+ it "successfully adds msg to archive" do
34
+ assert_silent { @archivist.deliver_to_local_archive(@msg, @archive_opts) }
35
+ assert_equal true, File.file?("#{@archive_opts["local_archive"]}" + "/" + "#{@filename}")
36
+ end
37
+ end
38
+
39
+ context 'when local path is invalid' do
40
+ it "adds msg to archive_stack" do
41
+ @archivist.deliver_to_local_archive(@msg, "/home/invalid_path")
42
+ assert_equal 1, $redis.llen('archive_stack')
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "Archivist::deliver_to_cloud_archive" do
48
+ before do
49
+ $redis.del("archive_stack") #zero list
50
+ @archive_opts = JSON.parse(File.read("#{Dir[File.dirname(__FILE__)][0] + '/test_assets/archive_opts.json'}"))[0]
51
+ @msg = File.read("#{Dir[File.dirname(__FILE__)][0] + '/test_assets/_1447427485391-46840973-67af09f8-7a989c0d_mixmax.com_.json'}")
52
+ @archivist = MailRunner::ArchivistBot
53
+ #set for Mocking only.
54
+ Fog.mock!
55
+ #Must create fake directory in mock stub
56
+ service = @archivist.new_storage_object(@archive_opts)
57
+ service.directories.create :key => 'raw_msg_archive'
58
+ end
59
+
60
+ context "when cloud archive credentials valid" do
61
+ it "successfully adds msg to archive" do
62
+ assert_instance_of Fog::Storage::Rackspace::File, @archivist.deliver_to_cloud_archive(@msg, @archive_opts)
63
+ assert_equal 0, $redis.llen('archive_stack') #doesn't hit stack
64
+ end
65
+ end
66
+
67
+ context "When cloud archive credentials invalid" do
68
+ before do
69
+ @archive_opts["api_key"] = nil
70
+ @archivist.deliver_to_cloud_archive(@msg, @archive_opts)
71
+ end
72
+ it "adds msg to archive_stack" do
73
+ assert_equal 1, $redis.llen('archive_stack')
74
+ end
75
+ end
76
+ end
77
+
78
+ describe 'Archivist::establish_archive_link' do
79
+ it 'Test included under: test BotHelpers:: Tests :: archive_tests' do
80
+ end
81
+ end
82
+
83
+ describe 'Archivist::format_options' do
84
+ it 'Test included under: test BotHelpers:: Tests :: archive_tests' do
85
+ end
86
+ end
87
+
88
+ ########################################
89
+
90
+ end
@@ -0,0 +1 @@
1
+ [{"msg":{"raw_msg":"Return-Path: <Coming Soon_account@gmail.com>\r\nReceived: from Coming Soon.domain.co (localhost [127.0.0.1]) by mail.Coming Soon.domain.co (Postfix) with ESMTP id A11E62202F2 for <test@Coming Soon.domain.co>; Fri, 13 Nov 2015 10:11:33 -0500\r\nReceived: by mail.Coming Soon.domain.co (Postfix, from userid 1001) id 886C222199E; Fri, 13 Nov 2015 10:11:33 -0500\r\nReceived: from mail-qk0-f175.google.com (mail-qk0-f175.google.com [209.85.220.175]) by mail.Coming Soon.domain.co (Postfix) with ESMTPS id EBFDB22F2 for <test@Coming Soon.domain.co>; Fri, 13 Nov 2015 10:11:26 -0500\r\nReceived: by qkas77 with SMTP id s77so494528qka.0 for <test@Coming Soon.domain.co>; Fri, 13 Nov 2015 07:11:26 -0800\r\nReceived: from [127.0.0.1] (ec2-54-85-60-240.compute-1.amazonaws.com. [54.85.60.240]) by smtp.gmail.com with ESMTPSA id 31sm5383325qgy.13.2015.11.13.07.11.25 for <test@Coming Soon.domain.co> (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Nov 2015 07:11:25 -0800\r\nDate: Fri, 13 Nov 2015 15:11:25 +0000\r\nFrom: Coming Soon_account@gmail.com>\r\nTo: test <test@Coming Soon.domain.co>\r\nMessage-ID: <1447427485391-46840973-67af09f8-7a989c0d@mixmax.com>\r\nSubject: Local Archive\r\nMime-Version: 1.0\r\nContent-Type: multipart/alternative;\r\n boundary=\"----sinikael-?=_1-14474274854200.5982260059099644\";\r\n charset=UTF-8\r\nContent-Transfer-Encoding: 7bit\r\nX-Original-To: test@Coming Soon.domain.co\r\nDelivered-To: talkt@Coming Soon.domain.co\r\nAuthentication-Results: mail.Coming Soon.domain.co; dkim=pass reason=\"2048-bit key;\r\n unprotected key\" header.d=gmail.com header.i=@gmail.com header.b=bkC0SRlC;\r\n dkim-adsp=pass; dkim-atps=neutral\r\nX-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dev.fake.co\r\nX-Spam-Level: \r\nX-Spam-Status: No, score=0.8 required=5.0 tests=FREEMAIL_FROM,\r\n HTML_IMAGE_RATIO_02,HTML_MESSAGE,MIME_HTML_MOSTLY,RCVD_IN_MSPIKE_H2,\r\n T_DKIM_INVALID,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.0\r\nDKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\r\n h=content-type:from:to:subject:message-id:date:mime-version;\r\n bh=OvFWnVTuQzHtF6tDRv5J3zWMNR04gofxsqdKPQBrJOA=;\r\n b=bkC0SRlCOMx0TAfP1Xo6YxpFkUtwEO/cSPiZUE9MNXyKEx6EgMOkHpNJoNuwUrQDZx\r\n NkfERwLbmeP8qTmikvrbBnsDDg6QWQX05T99B5QSf7LOJ511eorgvrnP5rPrFdhDq4EK\r\n JwjTKDvFuCSHtx3WUlvo0Gw9rqrQRGNRjUTNSU1Rc5oRIZZdspPuFVkL7lsSnVGx0j5B\r\n Jh2Qq93bnh1FOTJ+xKCIRGSGuYcohkumwV8J5dmaebTPkUv56wj+E5T3mkLFN8zPiKz1\r\n kFlKq1CsB4XcFnSs48LEbswsAhXstUYbYFtZqwXWrDohvBIoLMlRN2gdGanMXP2iRA64 XCrg==\r\nX-Received: by 10.140.16.21 with SMTP id 21mr22446073qga.87.1447427486385;\r\n Fri, 13 Nov 2015 07:11:26 -0800 (PST)\r\nX-Mailer: Mixmax (mixmax.com)\r\nX-Virus-Scanned: ClamAV using ClamSMTP\r\n\r\n\r\n------sinikael-?=_1-14474274854200.5982260059099644\r\nContent-Type: text/plain;\r\n charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nLocal Arhive\r\n\r\n\r\nSent with Mixmax=\r\n\r\n------sinikael-?=_1-14474274854200.5982260059099644\r\nContent-Type: text/html;\r\n charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://ww=\r\nw.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n\r\n<html xmlns=3D\"http://www.w3.org/1999/xhtml\" xmlns:v=3D\"urn:schemas-micro=\r\nsoft-com:vml\" xmlns:o=3D\"urn:schemas-microsoft-com:office:office\">\r\n\r\n <head>\r\n <meta name=3D\"viewport\" content=3D\"width=3Ddevice-width, initial-scal=\r\ne=3D1.0\">\r\n =\r\n\r\n =\r\n\r\n <!--[if gte mso 9]>\r\n <xml>\r\n <o:OfficeDocumentSettings>\r\n <o:AllowPNG/>\r\n <o:PixelsPerInch>96</o:PixelsPerInch>\r\n </o:OfficeDocumentSettings>\r\n </xml>\r\n <![endif]-->\r\n =\r\n\r\n =\r\n\r\n <style type=3D\"text/css\">* a:hover{cursor:pointer;}</style>\r\n =\r\n\r\n\r\n <style>body {-webkit-animation:bugfix infinite 1s;}@-webkit-keyframes=\r\n bugfix {from {position:relative;}to {position:relative;}}</style>\r\n\r\n </head>\r\n\r\n <body yahoo=3D\"fix\" style=3D\"word-wrap:normal; word-break:break-word;\"=\r\n>\r\n\r\n =\r\n\r\n <!--[if (gte mso 9)|(IE)]>\r\n <style>a,body {font-family:'Calibri',Arial,sans-serif;}img {border:=\r\nnone !important;-ms-interpolation-mode:bicubic;}td {mso-line-height-rule:=\r\nexactly !important;}table.border-outer {margin-bottom:15px !important;}.b=\r\norder-middle,.border-inner {width:100%;}td.mso-card-inner table {border-c=\r\nollapse:collapse !important;mso-table-lspace:0pt;mso-table-rspace:0pt;ver=\r\ntical-align:top;}.border-outer,.border-middle,.border-inner {border:none =\r\n!important;}.mso-border-outer,.mso-border-middle,.mso-border-inner {paddi=\r\nng:1px;}.mso-border-outer {background-color:rgb(245,255,255);}.mso-border=\r\n-middle {background-color:rgb(223,246,255);}.mso-border-inner {background=\r\n-color:rgb(153,176,225);}.preview-card {margin-bottom:0 !important;paddin=\r\ng:0 !important;}.outlook-only {display:block !important;max-height:none !=\r\nimportant;overflow:visible !important;}.outlook-com-only {display:none !i=\r\nmportant;font-size:0 !important;}#mso-one-whole {width:100% !important;}<=\r\n/style>\r\n <![endif]-->\r\n =\r\n\r\n =\r\n\r\n <style>a {word-wrap:normal;word-break:break-word;}@media only screen =\r\nand (max-width:600px) {.container[not-yahoo] {-webkit-text-size-adjust:no=\r\nne !important;}.container[not-yahoo],.container[not-yahoo] .palm-one-whol=\r\ne {width:100% !important;min-width:100% !important;}.container[not-yahoo]=\r\n .palm-one-half {width:50% !important;min-width:50% !important;box-sizing=\r\n:border-box;}blockquote table[lang=3D\"container\"],blockquote table[lang=3D=\r\n\"container\"] div,blockquote table[lang=3D\"container\"] table {width:auto !=\r\nimportant;min-width:0 !important;position:relative !important;}img {max-w=\r\nidth:100%;}[class=3D\"border-outer\"],[class=3D\"border-middle\"],[class=3D\"b=\r\norder-inner\"],[title=3D\"separator\"],[class=3D\"inner\"] {width:100% !import=\r\nant;}[class=3D\"innercell\"] {padding:8px !important;}.palm-block {display:=\r\nblock !important;}.container[not-yahoo] td.palm-one-whole {display:inline=\r\n-block !important;padding:0;}.container[not-yahoo] td.palm-one-whole:firs=\r\nt-child:not(:only-child) {margin-bottom:16px;}td.hostname {padding-top:3p=\r\nx !important;}}@media only screen and (min-width:601px) {.preview-card {m=\r\nax-width:600px !important;}}@media only screen and (min-device-width :320=\r\npx) and (max-device-width :568px),only screen and (min-device-width :768p=\r\nx) and (max-device-width :1024px),only screen and (max-device-width:640px=\r\n),only screen and (max-device-width:667px),only screen and (max-width:480=\r\npx){table[class=3D\"container\"] {width:100% !important;min-width:100% !imp=\r\nortant;}.p,.small,li,font[size=3D\"2\"],font[size=3D\"3\"] {font-size:17px !i=\r\nmportant;line-height:1.5 !important;}audio {margin-bottom:10px;}.backgrou=\r\nnd-contain {background-size:contain;}}@media only screen and (min-device-=\r\nwidth :320px) and (max-device-width :568px),only screen and (min-device-w=\r\nidth :768px) and (max-device-width :1024px),only screen and (min-device-w=\r\nidth :1224px) {.container[not-yahoo] .message-wrapper {padding-top:6px;}=\r\n.container[not-yahoo] .apple-only[style] {display:block !important;max-he=\r\night:none !important;line-height:normal !important;overflow:visible !impo=\r\nrtant;height:auto !important;width:100% !important;position:relative !imp=\r\nortant;}.ExternalClass .ecxapple-only {display:none !important;}.containe=\r\nr[not-yahoo] .no-apple {display:none !important;}.container[not-yahoo] .n=\r\no-apple {display:block;}.container[not-yahoo] form {font-size:inherit;}.c=\r\nontainer[not-yahoo] form input[type=3D\"text\"] {height:43px;padding-left:4=\r\npx !important;}.container[not-yahoo] form button:hover {cursor:pointer;}@=\r\nmedia only screen and (min-device-width :1224px) {.apple-mail-form {disp=\r\nlay:block !important;background-color:white !important;}}}</style>\r\n =\r\n\r\n =\r\n\r\n <style>.ExternalClass {width:100%;}.ExternalClass .outlook-com-button=\r\n {display:block;}.ExternalClass button {height:auto;}.ExternalClass .outl=\r\nook-com-hidden {display:none !important;}.ExternalClass .outlook-com-only=\r\n {display:block !important;max-height:none !important;line-height:normal =\r\n!important;overflow:visible !important;height:auto !important;width:100% =\r\n!important;position:relative !important;}</style>\r\n =\r\n\r\n\r\n <table class=3D\"container\" lang=3D\"container\" not-yahoo=3D\"fix\" borde=\r\nr=3D\"0\" cellpadding=3D\"0\" cellspacing=3D\"0\" valign=3D\"top\" style=3D\"width=\r\n:100%; margin-top:6px;\">\r\n <tr>\r\n <td valign=3D\"top\" class=3D\"message-wrapper\" style=3D\"line-height=\r\n: 1.31; color: #222; font-family: arial, sans-serif;\">\r\n\r\n <!--[if mso]><table border=3D\"0\" cellpadding=3D\"0\" cellspacing=\r\n=3D\"0\" valign=3D\"top\" style=3D\"border-collapse:separate;\"><tr><td valign=3D=\r\n\"top\"><![endif]-->\r\n <div>Local Arhive</div><div><br></div><div><br></div><div><br=\r\n></div><div>\r\n <div class=3D\"signature\" style=3D\"color:#999999;\">\r\n Sent with <a target=3D\"_blank\" href=3D\"https://mixmax.com/s/LDQhPf8Ft=\r\n5nm5ccBu?utm_source=3Dmixmax&amp;utm_medium=3Demail&amp;utm_campaign=3Dsi=\r\ngnature_link&amp;utm_content=3Dsent_with_mixmax\">Mixmax</a>\r\n =\r\n\r\n </div>\r\n =\r\n\r\n</div><img width=3D\"0\" height=3D\"0\" style=3D\"border:0; width:0px; height:=\r\n0px;\" src=3D\"https://app.mixmax.com/api/track/v2/eoHCRmlPtUqTlCTRt/i02bj5=\r\nCbpFWbnBEdy9GcrN2byBnI/gIvNmL1JXdrF2cuQ3cvBHQ0NXZ09VdyV3ahNnI/ISe0lmb11Wb=\r\nvNEI0NXZ09VdyV3ahNnI\" alt=3D\"\">\r\n <!--[if mso]></td></tr></table><![endif]-->\r\n </td>\r\n </tr>\r\n </table>\r\n\r\n </body>\r\n</html>\r\n\r\n------sinikael-?=_1-14474274854200.5982260059099644--\r\n","headers":{"Received":"from [127.0.0.1] (ec2-54-85-60-240.compute-1.amazonaws.com. [54.85.60.240]) by smtp.gmail.com with ESMTPSA id 31sm5383325qgy.13.2015.11.13.07.11.25 for <fake_test@post.fake.co> (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Nov 2015 07:11:25 -0800","Date":"Fri, 13 Nov 2015 15:11:25 +0000","From":"Fake <fake_account@gmail.com>","To":"fake_test Community <fake_test@post.fake.co>","Message-ID":"<1447427485391-46840973-67af09f8-7a989c0d@mixmax.com>","Subject":"Local Archive","Mime-Version":"1.0","Content-Type":"multipart/alternative;","X-Original-To":"fake_test@post.fake.co","Delivered-To":"talkpost@dev.fake.co","Authentication-Results":"mail.dev.fake.co; dkim=pass reason=\"2048-bit key;","X-Spam-Checker-Version":"SpamAssassin 3.4.0 (2014-02-07) on dev.fake.co","X-Spam-Level":"","X-Spam-Status":"No, score=0.8 required=5.0 tests=FREEMAIL_FROM,","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;","h=content-type":"from:to:subject:message-id:date:mime-version;","X-Received":"by 10.140.16.21 with SMTP id 21mr22446073qga.87.1447427486385;","Fri, 13 Nov 2015 07":"11:26 -0800 (PST)","X-Mailer":"Mixmax (mixmax.com)","X-Virus-Scanned":"ClamAV using ClamSMTP"},"from_email":"fake_account@gmail.com","from_name":"K H","to":"test Community <test@Coming Soon.domain.co>","email":"test@post.fake.co","subject":"Local Archive","tags":"","sender":null,"spam_report":"spam report","text":"Local Arhive\n\n\nSent with Mixmax","html":"\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\">\n\n <head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n \n \n <!--[if gte mso 9]>\n <xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/>\n <o:PixelsPerInch>96</o:PixelsPerInch>\n </o:OfficeDocumentSettings>\n </xml>\n <![endif]-->\n \n \n <style type=\"text/css\">* a:hover{cursor:pointer;}</style>\n \n\n <style>body {-webkit-animation:bugfix infinite 1s;}@-webkit-keyframes bugfix {from {position:relative;}to {position:relative;}}</style>\n\n </head>\n\n <body yahoo=\"fix\" style=\"word-wrap:normal; word-break:break-word;\">\n\n \n <!--[if (gte mso 9)|(IE)]>\n <style>a,body {font-family:'Calibri',Arial,sans-serif;}img {border:none !important;-ms-interpolation-mode:bicubic;}td {mso-line-height-rule:exactly !important;}table.border-outer {margin-bottom:15px !important;}.border-middle,.border-inner {width:100%;}td.mso-card-inner table {border-collapse:collapse !important;mso-table-lspace:0pt;mso-table-rspace:0pt;vertical-align:top;}.border-outer,.border-middle,.border-inner {border:none !important;}.mso-border-outer,.mso-border-middle,.mso-border-inner {padding:1px;}.mso-border-outer {background-color:rgb(245,255,255);}.mso-border-middle {background-color:rgb(223,246,255);}.mso-border-inner {background-color:rgb(153,176,225);}.preview-card {margin-bottom:0 !important;padding:0 !important;}.outlook-only {display:block !important;max-height:none !important;overflow:visible !important;}.outlook-com-only {display:none !important;font-size:0 !important;}#mso-one-whole {width:100% !important;}</style>\n <![endif]-->\n \n \n <style>a {word-wrap:normal;word-break:break-word;}@media only screen and (max-width:600px) {.container[not-yahoo] {-webkit-text-size-adjust:none !important;}.container[not-yahoo],.container[not-yahoo] .palm-one-whole {width:100% !important;min-width:100% !important;}.container[not-yahoo] .palm-one-half {width:50% !important;min-width:50% !important;box-sizing:border-box;}blockquote table[lang=\"container\"],blockquote table[lang=\"container\"] div,blockquote table[lang=\"container\"] table {width:auto !important;min-width:0 !important;position:relative !important;}img {max-width:100%;}[class=\"border-outer\"],[class=\"border-middle\"],[class=\"border-inner\"],[title=\"separator\"],[class=\"inner\"] {width:100% !important;}[class=\"innercell\"] {padding:8px !important;}.palm-block {display:block !important;}.container[not-yahoo] td.palm-one-whole {display:inline-block !important;padding:0;}.container[not-yahoo] td.palm-one-whole:first-child:not(:only-child) {margin-bottom:16px;}td.hostname {padding-top:3px !important;}}@media only screen and (min-width:601px) {.preview-card {max-width:600px !important;}}@media only screen and (min-device-width :320px) and (max-device-width :568px),only screen and (min-device-width :768px) and (max-device-width :1024px),only screen and (max-device-width:640px),only screen and (max-device-width:667px),only screen and (max-width:480px){table[class=\"container\"] {width:100% !important;min-width:100% !important;}.p,.small,li,font[size=\"2\"],font[size=\"3\"] {font-size:17px !important;line-height:1.5 !important;}audio {margin-bottom:10px;}.background-contain {background-size:contain;}}@media only screen and (min-device-width :320px) and (max-device-width :568px),only screen and (min-device-width :768px) and (max-device-width :1024px),only screen and (min-device-width :1224px) {.container[not-yahoo] .message-wrapper {padding-top:6px;}.container[not-yahoo] .apple-only[style] {display:block !important;max-height:none !important;line-height:normal !important;overflow:visible !important;height:auto !important;width:100% !important;position:relative !important;}.ExternalClass .ecxapple-only {display:none !important;}.container[not-yahoo] .no-apple {display:none !important;}.container[not-yahoo] .no-apple {display:block;}.container[not-yahoo] form {font-size:inherit;}.container[not-yahoo] form input[type=\"text\"] {height:43px;padding-left:4px !important;}.container[not-yahoo] form button:hover {cursor:pointer;}@media only screen and (min-device-width :1224px) {.apple-mail-form {display:block !important;background-color:white !important;}}}</style>\n \n \n <style>.ExternalClass {width:100%;}.ExternalClass .outlook-com-button {display:block;}.ExternalClass button {height:auto;}.ExternalClass .outlook-com-hidden {display:none !important;}.ExternalClass .outlook-com-only {display:block !important;max-height:none !important;line-height:normal !important;overflow:visible !important;height:auto !important;width:100% !important;position:relative !important;}</style>\n \n\n <table class=\"container\" lang=\"container\" not-yahoo=\"fix\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" valign=\"top\" style=\"width:100%; margin-top:6px;\">\n <tr>\n <td valign=\"top\" class=\"message-wrapper\" style=\"line-height: 1.31; color: #222; font-family: arial, sans-serif;\">\n\n <!--[if mso]><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" valign=\"top\" style=\"border-collapse:separate;\"><tr><td valign=\"top\"><![endif]-->\n <div>Local Arhive</div><div><br></div><div><br></div><div><br></div><div>\n <div class=\"signature\" style=\"color:#999999;\">\n Sent with <a target=\"_blank\" href=\"https://mixmax.com/s/LDQhPf8Ft5nm5ccBu?utm_source=mixmax&amp;utm_medium=email&amp;utm_campaign=signature_link&amp;utm_content=sent_with_mixmax\">Mixmax</a>\n \n </div>\n \n</div><img width=\"0\" height=\"0\" style=\"border:0; width:0px; height:0px;\" src=\"https://app.mixmax.com/api/track/v2/eoHCRmlPtUqTlCTRt/i02bj5CbpFWbnBEdy9GcrN2byBnI/gIvNmL1JXdrF2cuQ3cvBHQ0NXZ09VdyV3ahNnI/ISe0lmb11WbvNEI0NXZ09VdyV3ahNnI\" alt=\"\">\n <!--[if mso]></td></tr></table><![endif]-->\n </td>\n </tr>\n </table>\n\n </body>\n</html>\n"}}]
@@ -0,0 +1,7 @@
1
+ [{
2
+ "destination": "cloud",
3
+ "provider": "Rackspace",
4
+ "username": "test_username",
5
+ "api_key": "RACKSPACE__API_KEY",
6
+ "directory": "raw_msg_archive"
7
+ }]
@@ -4,16 +4,19 @@
4
4
  #absolute means '~/' must be written as '/home/username/...'
5
5
  ################################################
6
6
 
7
- :mailbox: test_mailbox #mbox file name
8
- :webhook: localhost:4000/test_hook
9
- :archive:
10
- :provider: rackspace
11
- :username: name
12
- :api_key: key
13
- :region: :iad
7
+ :mailbox: test_mailbox #mbox file name
8
+ :webhook: localhost:4000/test_hook #or any remote or local url endpoint
14
9
  :logfile: /home/user/mailrunner.log
15
10
  :daemon: false
16
- :verbose: false #run in debug mode - adds a few more notes to help track down bugs.
17
-
18
-
11
+ :verbose: false #run in debug mode - adds a few more notes to help track down bugs.
19
12
 
13
+ #comment out all below to skip archive feature.
14
+ :archive:
15
+ :destination: local #local or cloud
16
+ :local_archive: /path/to/local_archive #path/to/archive_directory #only if destination set to local. folder must exist prior to launching!!
17
+ # :provider: rackspace #Rackspace, AWS
18
+ # :username: my_name #Rackspace only
19
+ # :api_key: my_api_key #rackspace 'api_key' or aws 'access_key_id'
20
+ # :secret_key: some_key #aws only - 'secret_access_key'
21
+ # :region: :iad #must be set for aws & Rackspace
22
+ # :directory: raw_msg_archive #name of cloud directory
@@ -0,0 +1,22 @@
1
+ # Mailrunner config file.
2
+ #To use the config file, just add teh -c flag when launching mailrunner.
3
+ # mailrunner -c /absolute/path_to/config.yml
4
+ #absolute means '~/' must be written as '/home/username/...'
5
+ ################################################
6
+
7
+ :mailbox: test_mailbox #mbox file name
8
+ :webhook: localhost:4000/test_hook #or any remote or local url endpoint
9
+ :logfile: /home/user/mailrunner.log
10
+ :daemon: false
11
+ :verbose: false #run in debug mode - adds a few more notes to help track down bugs.
12
+
13
+ #comment out all below to skip archive feature.
14
+ :archive:
15
+ :destination: cloud #local or cloud
16
+ # :local_archive: /path/to/local_archive #path/to/archive_directory #only if destination set to local. folder must exist prior to launching!!
17
+ :provider: rackspace #Rackspace, AWS
18
+ :username: my_name #Rackspace only
19
+ :api_key: my_api_key #rackspace 'api_key' or aws 'access_key_id'
20
+ # :secret_key: some_key #aws only - 'secret_access_key'
21
+ :region: :iad #must be set for aws & Rackspace
22
+ :directory: raw_msg_archive #name of cloud directory
@@ -44,6 +44,73 @@ class TestBotHelpers < Minitest::Test
44
44
  assert_raises(ArgumentError) {@test.test_webhook("http://127.0.0.1:4000/faulty_hook")}
45
45
  end
46
46
  end
47
+
48
+ describe "test BotHelpers:: Tests :: archive_tests" do
49
+ context "method : test_archive" do
50
+ before do
51
+ @arch_opts ={:destination => 'random'}
52
+ @test = BotHelpers::Tests
53
+ end
54
+ it "raises argument error if destination not cloud or local" do
55
+ assert_raises(ArgumentError) {@test.test_archive(@arch_opts)}
56
+ end
57
+ end
58
+
59
+ context "method : test_local_archive" do
60
+ before do
61
+ `mkdir /tmp/temp_archive`
62
+ @arch_opts = {
63
+ :destination => 'local',
64
+ :local_archive => '/tmp/temp_archive'
65
+ }
66
+ @test = BotHelpers::Tests
67
+ end
68
+ after do
69
+ `rm -rf /tmp/temp_archive`
70
+ end
71
+
72
+ it "is silent if directory exists" do
73
+ assert_silent {@test.test_local_archive(@arch_opts)}
74
+ end
75
+
76
+ it "raises error if directory doesn't exist" do
77
+ @arch_opts[:local_archive] = '/tmp/other_archive'
78
+ assert_raises(ArgumentError) {@test.test_local_archive(@arch_opts)}
79
+ end
80
+
81
+ end
82
+
83
+ context "method : test_cloud_archive_connection" do
84
+ before do
85
+ require '~/.apikeys'
86
+ #Set to test live Rackspace account. pulls in keys from require location above.
87
+ #to test live, make .apikeys file in home directory and add keys there to keep out of git.
88
+ #to test only stub, uncomment #Fog.mock! & change username & api_key in arch_opts
89
+ @test = BotHelpers::Tests
90
+ #Fog.mock!
91
+ @arch_opts = {
92
+ :destination => 'cloud',
93
+ :provider => 'Rackspace',
94
+ :username => "#{RACKSPACE_USERNAME}",
95
+ :api_key => "#{RACKSPACE__API_KEY}",
96
+ :secret_key => "sdsd34d334",
97
+ :directory => 'raw_msg_archive'
98
+ }
99
+ end
100
+ it "successfully connects to cloud archive" do
101
+ assert_silent {@test.test_cloud_archive_connection(@arch_opts)}
102
+ end
103
+
104
+ it "raises error if fails connect to cloud archive" do
105
+ @arch_opts[:api_key] = nil
106
+ assert_raises(ArgumentError) {@test.test_cloud_archive_connection(@arch_opts)}
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+
47
114
  ########################################
48
115
 
49
116
 
@@ -135,5 +135,39 @@ class TestCLI< Minitest::Test
135
135
  assert_equal '/home/user/flag.log', @options[:logfile]
136
136
  end
137
137
  end
138
+
139
+ describe 'local archive setup via config' do
140
+ before do
141
+ @cli = MailRunner::CLI
142
+ @options = @cli.parse_options(['mailrunner', '-c', './test/test_assets/test_config.yml'])
143
+ end
144
+
145
+ it 'sets destination to local' do
146
+ assert_equal 'local', @options[:archive][:destination]
147
+ end
148
+
149
+ it 'sets local archive path' do
150
+ assert_equal '/path/to/local_archive', @options[:archive][:local_archive]
151
+ end
152
+ end
153
+
154
+ describe 'remote archive setup via config' do
155
+ before do
156
+ @cli = MailRunner::CLI
157
+ @options = @cli.parse_options(['mailrunner', '-c', './test/test_assets/test_config_archive_cloud.yml'])
158
+ end
159
+
160
+ it 'sets destination to cloud' do
161
+ assert_equal 'cloud', @options[:archive][:destination]
162
+ end
163
+
164
+ it 'sets all cloud destination params' do
165
+ assert_equal 'rackspace', @options[:archive][:provider]
166
+ assert_equal 'my_name', @options[:archive][:username]
167
+ assert_equal 'my_api_key', @options[:archive][:api_key]
168
+ assert_equal :iad, @options[:archive][:region]
169
+ assert_equal 'raw_msg_archive', @options[:archive][:directory]
170
+ end
171
+ end
138
172
 
139
- end
173
+ end
@@ -1,16 +1,16 @@
1
1
  #####################
2
2
  # Several tests require a live server behind the test webhook.
3
- # will cause sveral fails if not. Must be Post method.
3
+ # will cause several fails if not. Must be Post method.
4
4
 
5
5
 
6
6
 
7
7
  ######################
8
8
  require_relative 'helper'
9
9
 
10
- class TestMailRunnerManager < Minitest::Test
10
+ class TestHeadManager < Minitest::Test
11
11
 
12
12
  ####### Top Level Call Tests ##########
13
- describe 'MailRunner Manager initialize' do
13
+ describe 'MR Manager::MailRunner Manager initialize' do
14
14
  before do
15
15
  @bot = MailRunner.initialize_manager_bot
16
16
  end
@@ -19,14 +19,14 @@ class TestMailRunnerManager < Minitest::Test
19
19
  assert_instance_of MailRunner::ManagerBot, @bot
20
20
  assert_equal nil, @bot.mailbox
21
21
  assert_equal nil, @bot.webhook
22
- assert_equal false, @bot.archive
22
+ assert_equal nil, @bot.archive
23
23
  end
24
24
 
25
25
  it "includes BotHelpers" do
26
26
  end
27
27
  end
28
28
 
29
- describe "Parse Options method" do
29
+ describe "MR Manager::Parse Options method" do
30
30
  before do
31
31
  @bot = MailRunner.initialize_manager_bot
32
32
  @opts = {:mailbox => "box_name", :webhook => "webhook/path"}
@@ -36,17 +36,17 @@ class TestMailRunnerManager < Minitest::Test
36
36
  @bot.parse_options(@opts)
37
37
  assert_equal "/var/mail/box_name", @bot.mailbox
38
38
  assert_equal "webhook/path", @bot.webhook
39
- assert_equal false, @bot.archive
39
+ assert_equal nil, @bot.archive
40
40
  end
41
41
 
42
42
  it "archive = true if passed archive argument" do
43
- @opts[:archive] = "true"
43
+ @opts[:archive] = true
44
44
  @bot.parse_options(@opts)
45
45
  assert_equal true, @bot.archive
46
46
  end
47
47
  end
48
48
 
49
- describe "Run Method" do
49
+ describe "MR Manager::Run Method" do
50
50
  before do
51
51
  @bot = MailRunner.initialize_manager_bot
52
52
  @bot.mailbox = "/var/mail/root" #app
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail_runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kert Heinecke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-07 00:00:00.000000000 Z
11
+ date: 2015-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mail
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.8.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: fog
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.23.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.23.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +178,7 @@ files:
164
178
  - Rakefile
165
179
  - bin/mail_runner
166
180
  - lib/mail_runner.rb
181
+ - lib/mail_runner/archive_manager.rb
167
182
  - lib/mail_runner/bot_helpers/helpers.rb
168
183
  - lib/mail_runner/bot_helpers/runner.rb
169
184
  - lib/mail_runner/bot_helpers/tests.rb
@@ -176,16 +191,20 @@ files:
176
191
  - lib/mail_runner/version.rb
177
192
  - mail_runner.gemspec
178
193
  - test/helper.rb
194
+ - test/test_archivist.rb
195
+ - test/test_assets/_1447427485391-46840973-67af09f8-7a989c0d_mixmax.com_.json
196
+ - test/test_assets/archive_opts.json
179
197
  - test/test_assets/empty.txt
180
198
  - test/test_assets/inline_attachments.email
181
199
  - test/test_assets/test.email
182
200
  - test/test_assets/test.json
183
201
  - test/test_assets/test_config.yml
202
+ - test/test_assets/test_config_archive_cloud.yml
184
203
  - test/test_assets/with_attachments.email
185
204
  - test/test_bot_helpers.rb
186
205
  - test/test_cli.rb
206
+ - test/test_head_manager_bot.rb
187
207
  - test/test_inbound_manager_bot.rb
188
- - test/test_mail_runner.rb
189
208
  - test/test_queue_manager_bot.rb
190
209
  homepage: https://github.com/kert-io/mailRunner
191
210
  licenses: