Ruby ArgumentError when actually providing correct arguments - ruby

Ruby complains i am not providing enough arguments to my script, which is:
#!/usr/bin/ruby
require 'mail'
def send(file,recipients_csv)
recipients=recipients_csv.split(",")
recipients.each do |recipient|
Mail.defaults do
delivery_method :smtp,{ :address => 'localhost', :port => 25,:openssl_verify_mode => OpenSSL::SSL::VERIFY_NONE}
end
mail = Mail.new do
from 'noreply#mydomain.com'
to "#{recipient}"
subject "test"
body "test"
add_file :filename => "a_testfile.tsv", :content => File.read(file.path)
end
mail.deliver!
end
end
testfile=File.new("newfile.tsv","w")
send(testfile,"name#mydomain.com")
What i get back is:
Mailer.rb:4:in `send': wrong number of arguments (1 for 2) (ArgumentError)
from /usr/lib64/ruby/gems/1.9.1/gems/treetop-1.4.15/lib/treetop/runtime/compiled_parser.rb:18:in `parse'
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/elements/address_list.rb:26:in `initialize'
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/fields/common/common_address.rb:9:in `new'
I dont get this, the arguments i provide are obviously 2

This might be conflicting with the Ruby base send method. Try renaming send to send_mail (or something), to avoid overwriting the send method

This error isn't coming from when you are running the script yourself on line 22, you are clearly passing it two arguments. It is actually coming from one of the three files you see in your error stack.
from /usr/lib64/ruby/gems/1.9.1/gems/treetop-1.4.15/lib/treetop/runtime/compiled_parser.rb:18:in `parse'
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/elements/address_list.rb:26:in `initialize'
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/fields/common/common_address.rb:9:in `new'
If you go into those files send is being called with only one argument as opposed to two.

Related

ruby mailgun send mail fails with 400 bad request

I'm trying out mailgun API with ruby. First thing I did was register an account. I have the api_key and the sandbox domain active. I then add my own email to authorized recipients from the sandbox domain.
I did exactly like in the docs:
def send_simple_message
RestClient.post "https://api:key-mykey"\
"#api.mailgun.net/v3/sandboxe5148e9bfa2d4e99a1b02d237a8546fe.mailgun.org/messages",
:from => "Excited User <postmaster#sandboxe5148e9bfa2d4e99a1b02d237a8546fe.mailgun.org>",
:to => "my#email.com, postmaster#sandboxe5148e9bfa2d4e99a1b02d237a8546fe.mailgun.org",
:subject => "Hello",
:text => "Testing some Mailgun awesomness!",
:multipart => true
end
send_simple_message
But it always returns 400 bad request, here's the trace from the terminal:
/home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient/abstract_response.rb:223:in `exception_with_response': 400 Bad Request (RestClient::BadRequest)
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient/abstract_response.rb:103:in `return!'
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient/request.rb:860:in `process_result'
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient/request.rb:776:in `block in transmit'
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/2.3.0/net/http.rb:853:in `start'
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient/request.rb:766:in `transmit'
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient/request.rb:215:in `execute'
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient/request.rb:52:in `execute'
from /home/ys/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rest-client-2.0.0/lib/restclient.rb:71:in `post'
from mailgunner.rb:24:in `send_simple_message'
from mailgunner.rb:33:in `<main>'
What did I do wrong here? I installed rest-client gem so I think there's some problems in my registration or something?
I had a similar problem and saw the documentation here:
https://github.com/rest-client/rest-client (in the exceptions section)
where they surrounded the RestClient.post with a rescue. And I made it print:
def send_simple_message
begin
RestClient.post ...
rescue RestClient::ExceptionWithResponse => e
puts e.response
end
end
then I got an error string with this:
{"message": "'from' parameter is not a valid address. please check documentation"}
then saw that in my test I had an error in the from field:
:from => "Test <alert#mg.example.com", # missing '>' at the end
Maybe you can use a similar approach, to solve your problem.
We've been experiencing this issue, which for us is caused by people entering their email incorrectly into a form. In every occurrence I've combed through, the recipient's address is written as something#gmail.con or ...#hotmail.comm where Mailgun can't validate the domain and sends it back as invalid.

"ArgumentError: wrong number of arguments (2 for 0)" though method requires two parameters

I have a MiniTest like this:
describe Message do
describe "#is_getting_unavailable" do
let( :message ) { Message.new() }
it "should be false when user does not exist in the database" do
message.handle
assert_equal(false, message.is_getting_unavailable)
end
end
end
Running this gives me complaint from assert_equal:
Message::#is_getting_unavailable#test_0001_should be false when user does not exist in the database
ArgumentError: wrong number of arguments (2 for 0)
test/unit/message_test.rb:148:in `(root)'
org/jruby/RubyBasicObject.java:1703:in `__send__'
org/jruby/RubyKernel.java:2209:in `send'
org/jruby/RubyArray.java:1617:in `each'
org/jruby/RubyArray.java:1617:in `each'
I did not understand this, so I included the test (just before the call of assert_equal):
puts method(:assert_equal).inspect
puts method(:assert_equal).arity
puts method(:assert_equal).source_location.inspect
The output is:
#<Method: #<Class:0x1d1e394d>(Minitest::Assertions)#assert_equal>
-3
["/home/rjung/.rvm/gems/jruby-1.7.4/gems/minitest-5.0.6/lib/minitest/assertions.rb", 155]
So the method is correct, and the arity is correct. What's the issue here?
We also use rr, timecop. Any other questions, that could help me find a solution?
It took me a while, but I could narrow the problem down to this failing test:
require 'minitest/autorun'
describe 'Message' do
let( :message ) { Hash.new }
it "should not fail awkwardly" do
assert_equal false, message.nil?
end
end
The output of this test is
1) Error:
Message#test_0001_should not fail awkwardly:
ArgumentError: wrong number of arguments (2 for 0)
test/unit/message_test.rb:7:in `(root)'
org/jruby/RubyBasicObject.java:1703:in `__send__'
org/jruby/RubyKernel.java:2209:in `send'
org/jruby/RubyArray.java:1617:in `each'
org/jruby/RubyArray.java:1617:in `each'
So I filed a Bug for https://github.com/seattlerb/minitest/issues/343.
Minitest does have a method message that was overwritten, so don't use message as a variable.
What I still wonder is, why the stacktrace says the wrong number of arguments happen in message_test.rb:7, because the method that takes no arguments (message) is definitive called from somewhere else.

Why is Mechanize returning "undefined method 'value=' for nil:NilClass" when trying to set a password?

I wrote a script with Mechanize to scrape some links, which later I will write code to put into an Excel file.
For now I can't authenticate past the first page. I keep getting an undefined method value= for nil:NilClass when attempting to set the password in the form and haven't been able to find any information on it.
I don't even have the method value= in my code so I don't understand what is going on. The code runs fine for the username, but once I enter the password and hit enter I get the error:
users.rb:11:in `block (2 levels) in <main>': undefined method `value=' for nil:NilClass (NoMethodError)
from (eval):23:in `form_with'
from formity_users.rb:7:in `block in <main>'
from /home/codelitt/.rvm/gems/ruby-2.0.0-p247/gems/mechanize-2.7.1/lib/mechanize.rb:433:in `get'
from formity_users.rb:5:in `<main>'
This is my users.rb script:
require 'rubygems'
require 'mechanize'
a = Mechanize.new
a.get('https://www.example.com') do |page|
#Enter information into forms
logged_in = page.form_with(:id => 'frmLogin') do |f|
puts "Username?"
f.field_with(:name => "LoginCommand.EmailAddress").value = gets.chomp
puts "Password?"
f.field_with(:name => "Login.Password").value = gets.chomp
end.click_button
#Click drop down
admin_page = logged_in.click.link_with(:text => /Admin/)
#Click Users and enter user admin section
user_admin = admin_page.click.link_with(:text => /Users/)
#Scrape and print links for now
user_admin.links.each do |link|
text = link.text.strip
next unless text.length > 0
puts text
end
end
I think your error is coming from
f.field_with(:name => "Login.Password")
which seems to be nil. For username, I see that you have specified input name LoginCommand.EmailAddress and for password input name is Login.Password.
I'd expect anybody who has written this markup to use consistent names. Maybe you should look that the underlying html to see you're using correct field names in your code.

Parsing Email with Ruby: unexpected token ATOM (expected SPACE) (Net::IMAP::ResponseParseError)

I am getting started parsing email with Ruby. I'm trying to read from my GMail account:
require 'rubygems'
require 'mail'
Mail.defaults do
retriever_method :imap, :address => "imap.gmail.com",
:port => 995,
:user_name => 'example#gmail.com',
:password => 'password',
:enable_ssl => true
end
emails = Mail.all
emails.each do |email|
puts email.inspect
end
...but I'm getting this error:
/Users/andrew/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/imap.rb:3277:in `parse_error': unexpected token ATOM (expected SPACE) (Net::IMAP::ResponseParseError)
from /Users/andrew/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/imap.rb:3129:in `match'
from /Users/andrew/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/imap.rb:2100:in `continue_req'
from /Users/andrew/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/imap.rb:2087:in `response'
from /Users/andrew/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/imap.rb:2015:in `parse'
from /Users/andrew/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/imap.rb:1166:in `get_response'
from /Users/andrew/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/imap.rb:1051:in `initialize'
from /Users/andrew/.rvm/gems/ruby-1.9.3-p194/gems/mail-2.4.4/lib/mail/network/retriever_methods/imap.rb:143:in `new'
from /Users/andrew/.rvm/gems/ruby-1.9.3-p194/gems/mail-2.4.4/lib/mail/network/retriever_methods/imap.rb:143:in `start'
from /Users/andrew/.rvm/gems/ruby-1.9.3-p194/gems/mail-2.4.4/lib/mail/network/retriever_methods/imap.rb:65:in `find'
from /Users/andrew/.rvm/gems/ruby-1.9.3-p194/gems/mail-2.4.4/lib/mail/network/retriever_methods/base.rb:41:in `all'
from /Users/andrew/.rvm/gems/ruby-1.9.3-p194/gems/mail-2.4.4/lib/mail/mail.rb:171:in `all'
Ruby's IMAP parser has had bugs. Your error output shows that the problem isn't likely to be in your code, it's likely to be the Ruby IMAP parser code that you can't easily change without patching Ruby.
If you're just interested in Gmail, and want to try a easier solution, try the Gmail gem:
https://github.com/nu7hatch/gmail
If you're interested in knowing the details of what's happening and possily how to patch Ruby:
http://claudiofloreani.blogspot.com/2012/01/monkeypatching-ruby-imap-class-to-build.html
This error message is typical if you try to do IMAP on a POP3 mail server.
Google Mail's IMAP port is 993. The port you tried is for POP3.

rails rspec mock_model Object expected, got String

I have a Directory controller and a Files controller. I'm testing the Files controller. I've created valid attributes for the File and I'm trying to mock_model the Directory to get the test to pass. The GET tests all work, but none of the POST tests work. The POST tests all give the error: "Directory expected, got String."
describe FilesController do
def valid_attributes {
:name => "test",
:reference_id => 1,
:location => "/path/to/directory",
:software => "excel",
:software_version => "2010",
:directory => mock_model(Directory)
}
end
describe "POST create" do
describe "with valid params" do
it "creates a new AssemblyFile" do
expect {
post :create, :assembly_file => valid_attributes
}.to change(AssemblyFile, :count).by(1)
end
it "assigns a newly created assembly_file as #assembly_file" do
post :create, :assembly_file => valid_attributes
assigns(:assembly_file).should be_a(AssemblyFile)
assigns(:assembly_file).should be_persisted
end
it "redirects to the created assembly_file" do
post :create, :assembly_file => valid_attributes
response.should redirect_to(AssemblyFile.last)
end
end
end
1) FilesController POST create with valid params creates a new File
Failure/Error: post :create, :file => valid_attributes
ActiveRecord::AssociationTypeMismatch:
Directory(#87017560) expected, got String(#49965220)
# ./app/controllers/files_controller.rb:60:in `new'
# ./app/controllers/files_controller.rb:60:in `create'
# ./spec/controllers/files_controller_spec.rb:79:in `block (5 levels) in <top (required)>'
# ./spec/controllers/files_controller_spec.rb:78:in `block (4 levels) in <top (required)>'
If I look at the test.log file, it shows that assembly is a string ("assembly" => "1011"). So I'm not sure why the mock_model isn't creating an object?
I've tried using stub! instead of mock_model, but that gets complicated because the create! used for stub! needs a lot of its own valid variables set and I don't really want to have to set a whole bunch of other valid attributes for that when I'm not trying to even test the Directory controller at all.
What am I doing wrong in my approach here?
Pass the id of the mock in the params hash instead of the mock itself. You'll also need to stub the find method so the mock is available in the controller action:
#directory = mock_model(Directory)
Directory.stub(:find).with(#directory.id).and_return(#directory)
post :create, :assembly_file => valid_attributes.merge(:directory_id => #directory.id)
# in controller
#directory = Directory.find(params[:assembly_file][:directory_id]) # => returns the mock

Resources