Get a different rspec result than instructor on twitter search app. Any help would be greatly appreciated

After Josh adds the Twitter gem and re-runs the rspec test in the twitter app tutorial (I think it’s the fourth video), it’s green (i.e. zero failures) for him, but that’s not what happens for me. I get this error and I could really use some help.

Failures:

  1. Search twitter for a term searching by a hashtag
    Failure/Error: click_button ‘Search’
    NoMethodError:
    undefined method `search’ for Twitter:Module

    ./app/controllers/searches_controller.rb:7:in `show’

    (eval):2:in `click_button’

    ./spec/integration/search_twitter_spec.rb:7:in `block (2 levels) in <top (required)>’

Finished in 0.31379 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/integration/search_twitter_spec.rb:4 # Search twitter for a term searching by a hashtag

Randomized with seed 15673

Coverage report generated for RSpec to /home/jacqueline/thoughtbot/hashtag2/coverage. 9 / 9 LOC (100.0%) covered.
➜ hashtag2 git:(master) ✗

Twitter gem’s API has changed since the recording. You can try using a previous version or adapting your code to the current version (as I did).

I reset my key and secret on twitter and then stored those values in environment variables by editing my .zshrc file like so:

export TFWS_KEY=‘X9zYij5bfriDQJncDUjGw’
export TFWS_SECRET=‘BPAl93IyLTgzYBdAr6x5nl387bwUuHrivHqVb4wio’
source /usr/local/share/chruby/chruby.sh

Then, I made an initializer file: config/initializers/twitter.rb, like so:

Twitter.configure do |twitter|
twitter.consumer_key = ENV[‘TFWS_KEY’]
twitter.consumer_secret = ENV[‘TFWS_SECRET’]
end

And then I tried re-running rspec and got this error (so it still is not working for me):

➜ hashtag2 git:(master) ✗ sublime-text ~/.zshrc
➜ hashtag2 git:(master) ✗ rspec spec/integration/search_twitter_spec.rb
WARNING: Nokogiri was built against LibXML version 2.8.0, but has dynamically loaded 2.9.0
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
F

Failures:

  1. Search twitter for a term searching by a hashtag
    Failure/Error: click_button ‘Search’
    Twitter::Error::ClientError:
    execution expired

    ./app/controllers/searches_controller.rb:7:in `show’

    (eval):2:in `click_button’

    ./spec/integration/search_twitter_spec.rb:7:in `block (2 levels) in <top (required)>’

Finished in 5.83 seconds
1 example, 1 failure

The test can’t find the ‘Search’ button. Is it present in your form? Does it have the ‘Search’ text (please check the lettercase).

Nope. lettercase was OK. My forgetting to SAVE some of the file changes was the problem. And I did not even notice that until I went through switching from chruby to rvm earlier today after a different project I am working on w/ my former Rails Girls coach for our anti-trafficking group required a Ruby that chruby wasn’t “seeing”, and therefore allowing me to run. So…after an exhausting day of uninstallation problems and installation of rvm problems and finally getting that squared away, is when I caught it. ::looks sheepish::

1 Like

Haha, we’ve all been there at some point :slight_smile: Some editors have a “save files when focus gets lost” setting, I always enable it to prevent this issue. If you use Textmate or Sublime Text, here are instructions to activate this feature.

Thank you for the cool tip :slight_smile: I am on Ubuntu so all I did was go into Preferences in my Sublime editor to fix that up by doing a CTRL + F on the word “focus” to find that line of code to change to true.

However, at the next stage of test-writing, after creating the Searcher class and initializing search_term and setting :results to attr_reader, I re-run rspec and get this same error as earlier:

Twitter::Error::ClientError
Execution expired

So…putting my research skills to use, I found that a bunch of other devs were discussing this very same problem in their respective apps on Github (see here: Getting Twitter::Error::ClientError: execution expired · Issue #401 · sferik/twitter · GitHub ), and they were of the opinion that it might be either a problem with the Twitter API or a heroku bug. I am not deploying this app on heroku nor have I initialized a heroku repo for it. Only Github. So…I am at a loss as to what else could be causing it other than an API issue.

It’s difficult to diagnose the problem without seeing your code: is it visible on GitHub?

@Jacqueline there are actually four keys you’ll need to set when configuring Twitter, not just two. The Twitter gem has changed pretty significantly in the past couple years I’ve been running this course, so it’s difficult to diagnose specifically.

If you’re running the latest version of the gem, you should be able to configure Twitter like @raul did in his commit; if you’re running version 4.8.x, you can configure Twitter globally, within an initializer.

Once Twitter is configured correctly, you should be able to search (either from calling search('term') on the client instance in version 5 or Twitter.search('term') in version 4) from a Rails console. Once Twitter is configured correctly, that should resolve the failure you’re seeing.

@joshclayton: OK, thank you Josh. I will try that and see how it works.

@raul: Yes, my code for this app tutorial is in my github repo here: GitHub - jacqueline-homan/hashtag2: This app interacts with the twitter gem. At the home page, you can type in a term and it will search the twitter API returning any tweets containing that term..

To be honest, I got totally lost at the point where Josh did the fake twitter part. I am an advanced beginner without a computer science educational background.

I did not even own a computer until 2008 and was barely savvy enough at using one. I did not even know what the terminal was until late March/early April of 2013 when a friend and ally in the anti-trafficking movement offered to teach me a little bit of computer literacy and programming using Ruby on Rails. There is no Rails Bridge or Rails Girls workshop within an 8 hour drive from where I live.

So you can imagine what it is like for me to try and learn a difficult new skill without any real support other than who I can reach out to online, including my friend in the anti-trafficking movement who coached me over Google video chats as he lives three states away from me. I ended up being on a 100% remote Rails Girls Summer of Code team and while I learned a lot, I also know there is so much more I need to learn, too.

So I am struggling to master a ton of difficult new things and I apologize if any of my questions or things I get stuck on seem silly.

I just added the token keys and the code for configuring them and this is what I got when I tried re-running the rspec

Failures:

  1. Search twitter for a term searching by a hashtag
    Failure/Error: expect(page).to have_css ‘li.tweet’, count: 15
    expected css “li.tweet” to return something

    ./spec/integration/search_twitter_spec.rb:8:in `block (2 levels) in <top (required)>’

    ./spec/support/searcher.rb:4:in `block (2 levels) in <top (required)>’

  2. Search twitter for a term searching with known results
    Failure/Error: expect(page).to have_css ‘li.tweet’, count: 3
    expected css “li.tweet” to return something

    ./spec/integration/search_twitter_spec.rb:20:in `block (2 levels) in <top (required)>’

    ./spec/support/searcher.rb:4:in `block (2 levels) in <top (required)>’

Finished in 2.89 seconds
2 examples, 2 failures

So I undid the changes and am back to square one because I am unable to get this to work for me.

@Jacqueline let’s tackle this one item at a time, since there’s a few things going on.

First, you’ll want to ensure you can actually search via Twitter from the Rails app. This is important because the tests are actually hitting Twitter live - and if that doesn’t work and you can’t talk to Twitter, the tests will fail.

The litmus test I use to verify the app is configured to talk to Twitter correctly is to call Twitter.search('foo') from a Rails console. If that works, Twitter is configured correctly and set to go. You’ll likely want to install the dotenv-rails gem by adding it to the :development, :test group in your Gemfile - this gem will load environment variables defined in your .env file so when you configure Twitter (in your case, within config/initializers/twitter.rb) the values are defined.

Once you can search Twitter from the Rails console, I’d rerun the test suite and track down the errors one at a time. I focus on one type of test at a time (so, integration first, then model, then lib, etc.).

I just checked out your repo locally and started tinkering to see what was happening and was able to get a passing test - but also noticed that searching for #Rails only returned 13 results instead of 15 (this is a reason why relying on live data from Twitter sometimes backfires :-)).

Stick with it! Testing is a lot of fun but, like everything else, takes a while to understand because there are plenty of subtleties that take a long time to recognize. I’m still learning and improving my testing abilities and I’ve been doing it for more than five years.

If you run into anything else, please at-reply me so I’m notified, and keep everyone posted as you continue forward!

@joshclayton: Thank you for the encouragement. I also did not know (until now) that a live search can (and often does) backfire. That is VERY good to know.

So…Taking the first step to try and get this problem solved, I hopped into the rails console. I was unsure of the proper syntax to use so I just did “Twitter.search(‘foo’)” but got this nasty stack trace that does NOT look good at all and I am clueless as to how to interpret it correctly and get a handle on what’s going on - other than apparently I don’t have Twitter configured correctly, and since not, how then do I do it (configure Twitter correctly)?

➜ hashtag2 git:(master) ✗ rails c
Loading development environment (Rails 3.2.14)
1.9.3-p484 :001 > Twitter.search(‘foo’)
Twitter::Error::BadRequest: Bad Authentication data
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter/response/raise_error.rb:21:in on_complete' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/faraday-0.8.8/lib/faraday/response.rb:9:in block in call’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/faraday-0.8.8/lib/faraday/response.rb:63:in on_complete' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/faraday-0.8.8/lib/faraday/response.rb:8:in call’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/faraday-0.8.8/lib/faraday/request/url_encoded.rb:14:in call' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/faraday-0.8.8/lib/faraday/request/multipart.rb:13:in call’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter/request/multipart_with_file.rb:14:in call' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/faraday-0.8.8/lib/faraday/connection.rb:253:in run_request’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/faraday-0.8.8/lib/faraday/connection.rb:106:in get' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter/client.rb:108:in request’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter/client.rb:66:in get' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter/api/utils.rb:82:in object_from_response’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter/api/search.rb:32:in search' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter.rb:60:in method_missing’
from (irb):1
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/commands/console.rb:47:in start' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/commands/console.rb:8:in start’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/commands.rb:41:in <top (required)>' from script/rails:6:in require’
from script/rails:6:in `'1.9.3-p484 :002 >

@Jacqueline based on the commits in your repo, you’ll still need to change a couple things. First, still unable to get this tutorial app to work for me · jacqueline-homan/hashtag2@fb8142c · GitHub comments out the oauth token and token secret - you’ll actually need those.

How are you setting your env variables in the Rails app? I’d mentioned adding the dotenv-rails gem - have you done that and written the credentials to your .env file within the Rails root directory?

@Jacqueline you’ll want to add the dotenv-rails gem to the development and test groups within your Gemfile and then create a .env file (which doesn’t get checked into the repo - add it to your .gitignore) and contains your environment variables setting the four pieces of information Twitter needs - similar to what @raul did here: https://github.com/raul/tdd-rails-twitter-search/blob/623b0575e44c5974ea43d1704b8835de065fa368/.env-sample. You’ll want to verify the keys line up with the configuration.

@Jacqueline you’ll have to create a .env file within the application directory (in this case, hashtag2). Make sure to add .env to your .gitignore file (also at the root of the Rails directory) so your auth tokens aren’t posted on GitHub (you should also avoid posting them here, since other people can use them to sign into your Twitter account and compromise it).

Once you’ve created the .env file, be sure to add the dotenv-rails gem as I mentioned before.

Finally, make sure the keys you’re setting in your .env file line up with the Ruby code that they’re reading from. In the exports you just posted, the keys TWITTER_KEY and TWITTER_SECRET don’t actually match your Ruby code: hashtag2/twitter.rb at fb8142c13e688853fc41d1d561ab9ec45f854599 · jacqueline-homan/hashtag2 · GitHub (the Ruby code is referencing the keys TFWS_KEY and TFWS_SECRET). This is likely why you’re not able to query Twitter.

@joshclayton: ZMOG! ::faceplm:: We must have cross-posted. I NOW see what you mean. The .env file is something I have to create.

@joshclayton
I just created the .env file and added it to my gitignore. I made sure that everything matched and changed “oauth” to “access” and made sure that the environment variables all matched…and it’s still not working for me and I cannot seem to get rspec to run properly at all now:

➜ hashtag2 git:(master) ✗ rspec spec/lib/fake_twitter_spec.rb
/home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter.rb:59:in method_missing': undefined method access_token=’ for Twitter:Module (NoMethodError)
from /home/jacqueline/thoughtbot/hashtag2/config/initializers/twitter.rb:4:in block in <top (required)>' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/twitter-4.8.1/lib/twitter/configurable.rb:35:in configure’
from /home/jacqueline/thoughtbot/hashtag2/config/initializers/twitter.rb:1:in <top (required)>' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/activesupport-3.2.14/lib/active_support/dependencies.rb:245:in load’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/activesupport-3.2.14/lib/active_support/dependencies.rb:245:in block in load' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/activesupport-3.2.14/lib/active_support/dependencies.rb:236:in load_dependency’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/activesupport-3.2.14/lib/active_support/dependencies.rb:245:in load' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/engine.rb:593:in block (2 levels) in class:Engine
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/engine.rb:592:in each' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/engine.rb:592:in block in class:Engine
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/initializable.rb:30:in instance_exec' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/initializable.rb:30:in run’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/initializable.rb:55:in block in run_initializers' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/initializable.rb:54:in each’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/initializable.rb:54:in run_initializers' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/application.rb:136:in initialize!’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/railties-3.2.14/lib/rails/railtie/configurable.rb:30:in method_missing' from /home/jacqueline/thoughtbot/hashtag2/config/environment.rb:5:in <top (required)>’
from /home/jacqueline/thoughtbot/hashtag2/spec/spec_helper.rb:5:in require' from /home/jacqueline/thoughtbot/hashtag2/spec/spec_helper.rb:5:in <top (required)>’
from /home/jacqueline/thoughtbot/hashtag2/spec/lib/fake_twitter_spec.rb:1:in require' from /home/jacqueline/thoughtbot/hashtag2/spec/lib/fake_twitter_spec.rb:1:in <top (required)>’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896:in load' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896:in block in load_spec_files’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896:in each' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896:in load_spec_files’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:22:in run' from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/rspec-core-2.14.7/lib/rspec/core/runner.rb:80:in run’
from /home/jacqueline/.rvm/gems/ruby-1.9.3-p484@hashtag2/gems/rspec-core-2.14.7/lib/rspec/core/runner.rb:17:in `block in autorun’
Coverage report generated for RSpec to /home/jacqueline/thoughtbot/hashtag2/coverage. 0 / 0 LOC (0.0%) covered.
➜ hashtag2 git:(master) ✗

@Jacqueline if you look at the failure, you’ll see there’s no access_token= method (and likely access_token_secret= won’t work either) - from hashtag2/twitter.rb at master · jacqueline-homan/hashtag2 · GitHub.

I think the configuration methods you’ll need are these: hashtag/twitter.rb at master · joshuaclayton/hashtag · GitHub

@joshclayton: You’re right. I just went back and changed my initializers/twitter.rb file accordingly and this part now works (as far as not having the rspec break) . YAY :smile:

➜ hashtag2 git:(master) ✗ rspec spec/lib/fake_twitter_spec.rb

Finished in 0.07942 seconds
3 examples, 0 failures

Now, when I go to run the rspec on the integration file, I get this error which I am unsure about. :

➜ hashtag2 git:(master) ✗ rspec spec/integration/search_twitter_spec.rb
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
.F

Failures:

  1. Search twitter for a term searching with known results
    Failure/Error: expect(page).to have_css ‘li.tweet’, count: 3, text: ‘Testing is awesome’
    expected css “li.tweet” with text “Testing is awesome” to return something

    ./spec/integration/search_twitter_spec.rb:18:in `block (2 levels) in <top (required)>’

    ./spec/support/searcher.rb:4:in `block (2 levels) in <top (required)>’

Finished in 2.69 seconds
2 examples, 1 failure

Failed examples:

rspec ./spec/integration/search_twitter_spec.rb:13 # Search twitter for a term searching with known results

Randomized with seed 10827

Coverage report generated for RSpec to /home/jacqueline/thoughtbot/hashtag2/coverage. 24 / 32 LOC (75.0%) covered.

What I do know now for sure is that Twitter is configured right because I hopped back into the rails console and did a "Twitter.search(‘foo’) and got a ton of interesting search results on ‘foo.’ So that part is working. :smile: