Skip to content

Commit

Permalink
in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeBlyth committed Sep 30, 2012
1 parent 0853c40 commit 9542da2
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 24 deletions.
24 changes: 17 additions & 7 deletions app/controllers/incoming_mails_controller.rb
Expand Up @@ -71,7 +71,10 @@ def process_message_response
end

def validation_string
encrypted = encrypt([@user_email, Time.now].to_yaml)
puts "**** @from_address=#{@from_address}"
puts "**** No @from_address for validation string" if @from_address.blank?
return nil if @from_address.blank?
encrypted = encrypt([@from_address, Time.now].to_yaml)
"Validation: #{encrypted}***********"
end

Expand All @@ -84,7 +87,7 @@ def check_validation_string(vstring=@body)
decrypted = decrypt(vstring) # just look for validation string in whole body
return nil if decrypted.nil?
email, time_s = YAML.load(decrypted)
return (email == @user_email) && (Time.now - time_s < 1.day)
return (email == @from_address) && (Time.now - time_s < 1.day)
rescue
puts "**** Error #{$!}"
return nil
Expand Down Expand Up @@ -142,6 +145,8 @@ def process_commands
Notifier.send_help(from).deliver
when 'change', 'update'
update_member(command[1]) # command[1] is the parameter string
when 'add', 'new'
create_member(command[1])
when 'test'
Notifier.send_test(from,
"You sent 'test' with parameter string (#{command[1]})").deliver
Expand Down Expand Up @@ -201,21 +206,25 @@ def send_pls_verify_email(update_hash)
).deliver
end

def create_member(values)
params_hash = Member.parse_update_command(values)
end

def update_member(values)
update_hash = Member.parse_update_command(values)
puts "**** update_hash=#{update_hash}"
#puts "**** update_hash=#{update_hash}"
AppLog.create(:code=>'Email.update', :description => "updates hash=#{update_hash.to_s}", :severity=>'Info')
case
when update_hash.nil?
puts "**** Delivering error response"
#puts "**** Delivering error response"
Notifier.send_generic_hashed(
:to=> @from_address,
:subject => 'Error in your update command',
:body => "Error in your update command. The name was not found or not given.\n\n" +
values).deliver
when update_hash[:members].many?
names = update_hash[:members].map {|m| m.name}.join('; ')
puts "**** Delivering multiple targets response"
#puts "**** Delivering multiple targets response"
Notifier.send_generic_hashed(
:to=> @from_address,
:subject => 'More info needed for your update command',
Expand All @@ -228,10 +237,11 @@ def update_member(values)
if update_authorized?(target)
if check_validation_string(@body)
target.update_attributes(update_hash[:updates])
puts "**** Delivering confirmation"
#puts "**** Delivering confirmation"
send_confirmation_email(update_hash)
else
puts "**** Delivering verify request"
#puts "**** Delivering verify request"
puts "**** @from_address=#{@from_address}"
send_pls_verify_email(update_hash)
end
else
Expand Down
29 changes: 29 additions & 0 deletions app/helpers/application_helper.rb
Expand Up @@ -172,6 +172,35 @@ def extract_commands(body, command_delim=SiteSetting.email_command_delimiter)
def change_locale_to(new_locale)
url_for(params.merge(:locale => new_locale))
end

#******* METHODS TO DO WITH NAMES ************#
#**** see also names_helper *****#
def add_indexed_name(name_hash)
name_hash[:name] = name_hash[:last_name] +
(name_hash[:first_name] ? ", #{name_hash[:first_name]}" : '') +
(name_hash[:middle_name] ? " #{name_hash[:middle_name]}" : '')
return name_hash
end

def parse_namestring(name)
return {} if name.blank?
names = name.split("\s").map {|n| n.gsub(/[_\+]/, ' ')}
name_hash = {}
case names.count
when 1
name_hash[:last_name] = names[0]
when 2
name_hash[:last_name] = names[1]
name_hash[:first_name] = names[0]
when 3..100
name_hash[:last_name] = names[-1]
name_hash[:first_name] = names[0]
name_hash[:middle_name] = names[1]
end
add_indexed_name(name_hash)
end


#******* Anything below this point is not in the module itself *********
end # ApplicationHelper module

Expand Down
10 changes: 9 additions & 1 deletion app/models/member.rb
Expand Up @@ -36,6 +36,7 @@


############## JOSLINK ###################

class Member < ActiveRecord::Base
include NameHelper
require 'sessions_helper'
Expand Down Expand Up @@ -107,6 +108,7 @@ def self.parse_update_command(str)
names = []
phones = []
emails = []
groups = []
updates = {}
tokens.each do |token|
case
Expand All @@ -118,14 +120,20 @@ def self.parse_update_command(str)
names << token if (phones + emails).empty?
end
end
return nil if (member = Member.find_with_name(names.join(' '))).empty?
(0..1).each do |i|
updates["phone_#{i+1}".to_sym] = phones[i] if phones[i]
updates["email_#{i+1}".to_sym] = emails[i] if emails[i]
end
name_string = names.join(' ')
member = Member.find_with_name(name_string) # may match none, one, or many members
return add_member_params(name_string, updates) if member.empty? # assume it's for adding a new member
#puts "**** member=#{member}, updates=#{updates}"
return {:members => member, :updates => updates}
end

def self.add_member_params(name, updates)
{:members => [], :updates => parse_namestring(name).merge(updates)}
end

def self.find_by_phone(phone_number)
target_phone = (phone_number[0] == '+' ? phone_number[1..20] : phone_number)
Expand Down
43 changes: 30 additions & 13 deletions spec/controllers/incoming_mails_controller_spec.rb
Expand Up @@ -31,6 +31,18 @@ def add_member_string(member)
member.groups.map {|g| g.abbrev}.join(' ')
end

# Directly access the controller's validation_string method
# This also sets @from_address in the controller to email_address, so
# subsequent testing of checking validation string will expect to see
# email_address in the encrypted validation string
def create_validation_string(email_address)
# saved_from_address = controller.instance_variable_get(:@from_address)
controller.instance_variable_set(:@from_address, email_address)
vstring = controller.validation_string
# controller.instance_variable_set(:@from_address, saved_from_address)
vstring
end

describe IncomingMailsController do
before(:each) do
@params = HashWithIndifferentAccess.new(
Expand Down Expand Up @@ -162,13 +174,16 @@ def add_member_string(member)
# With a validated request, the new name should be added if it is still unique
context 'when incoming email is validated' do
before(:each) do
controller.instance_variable_set(:@user_email, @params_from)
@vstring = controller.validation_string
@params['plain'] = "add xxxxx vvvvv\n\n#@vstring" # include validation
@vstring = create_validation_string(@params[:from])
@member = FactoryGirl.build(:member, :email_2=>'second@test.com', :phone_2=>'08094444444')
@params['plain'] = "add #{add_member_string(@member)}\n\n#@vstring" # include validation
end

context 'when name is still unique' do
#
it 'adds the member' do
Member.should_receive(:create).and_return(true)
post :create, @params
end
end

context 'when name has been taken' do
Expand Down Expand Up @@ -387,8 +402,7 @@ def add_member_string(member)
context 'a single member matches request' do
context 'incoming email is validated' do
before(:each) do
controller.instance_variable_set(:@user_email, @params_from)
@vstring = controller.validation_string
@vstring = create_validation_string(@params[:from])
@params['plain'] = "update xxxxx vvvvv\n\n#@vstring" # include validation
end

Expand Down Expand Up @@ -470,6 +484,7 @@ def add_member_string(member)
it 'sends validation email' do
target.stub(:update_attributes).and_return true
target.stub(:name).and_return("Some name")
puts "**** @params=#{@params}"
lambda{post :create, @params}.should change(ActionMailer::Base.deliveries, :length).by(1)
ActionMailer::Base.deliveries.last.to.should == [@params['from']]
mail = ActionMailer::Base.deliveries.last.to_s.gsub("\r", "")
Expand Down Expand Up @@ -782,9 +797,12 @@ def add_member_string(member)

describe "is formed and checked correctly" do

it 'returning nil when @from_address is empty' do
create_validation_string('').should be_nil
end

it 'accepting its own generated validation' do
controller.instance_variable_set(:@user_email, 'user@something.com')
v = controller.validation_string
v = create_validation_string('user@something.com')
body = "All kinds of\n\nheaders and other stuff \n\n #{v} and even more garbage"
controller.check_validation_string(body).should be_true
end
Expand All @@ -794,15 +812,14 @@ def add_member_string(member)
end

it 'rejecting validition with wrong email' do
controller.instance_variable_set(:@user_email, 'user@something.com')
v = controller.validation_string
controller.instance_variable_set(:@user_email, 'someone_else@something.com')
v = create_validation_string('user@something.com')
# Make it appear that the email is from someone_else
controller.instance_variable_set(:@from_address, 'someone_else@something.com')
controller.check_validation_string(v).should be_false
end

it 'rejecting out of date validation' do
controller.instance_variable_set(:@user_email, 'user@something.com')
v = controller.validation_string
v = create_validation_string('user@something.com')
Timecop.travel(Date.today + 10.days)
result = controller.check_validation_string(v)
Timecop.return # We don't really want to error-out of test before returning to real time
Expand Down
15 changes: 15 additions & 0 deletions spec/helpers/application_helper_spec.rb
Expand Up @@ -164,6 +164,21 @@
AppLog.count.should eq 5
end
end #

describe 'parse_namestring' do
it 'parses names correctly' do
parse_namestring('Jack Spratt').should eq ({:last_name=>'Spratt', :first_name=>'Jack', :name => 'Spratt, Jack'})
parse_namestring('Jack R. Spratt').should ==
({:last_name=>'Spratt', :first_name=>'Jack', :middle_name => "R.", :name => 'Spratt, Jack R.'})
parse_namestring('Jack_Box R. Spratt').should ==
({:last_name=>'Spratt', :first_name=>'Jack Box', :middle_name => "R.", :name => 'Spratt, Jack Box R.'})
parse_namestring('Spratt,+Inc.').should ==
({:last_name=>'Spratt, Inc.', :name => 'Spratt, Inc.'})
parse_namestring('').should == {}
parse_namestring(nil).should == {}
end
end

end # various tools


Expand Down
8 changes: 5 additions & 3 deletions spec/models/member_spec.rb
Expand Up @@ -549,13 +549,15 @@ def set_redis_user_role(user, role=nil)
let(:email_1){"abc@example.com"}
let(:phone_2){"2349993334444"}
let(:email_2){"xyz@example.com"}
let(:s){"#{member.name} #{phone_1} #{email_1}"}
let(:s2){"#{member.name} #{phone_1} #{email_1} #{phone_2} #{email_2}"}
let(:s){"#{member_name} #{phone_1} #{email_1}"}
let(:s2){"#{member_name} #{phone_1} #{email_1} #{phone_2} #{email_2}"}

context 'when member is not found' do
it 'returns nil if member not found' do
Member.should_receive(:find_with_name).and_return([])
Member.parse_update_command(s).should be_nil
result = Member.parse_update_command(s)
result[:members].should be_empty
result[:updates][:first_name].should eq member.first_name.gsub('_', ' ')
end
end

Expand Down

0 comments on commit 9542da2

Please sign in to comment.