← Back to Upcase

Matching problems with TDD Twitter app


(Jon Seidel) #1

I’ve created the twitter app and things looked fine, but then I ran into some problems with the spec

   expect(tweet.text(.to match /#rails/i

Problem is it succeeds sometimes and fails others. I’ve loaded the app in the browser to see what gets returned and here’s what I think is happening:

The results include things that clearly having nothing to do with the hashtag #rails… it’s picking up any tweet that has the word ‘rails’ in it, including things like:

DELL POWEREDGE R710 2 x QUAD CORE E5540 2.53GHz 64GB RAM 2 x 1TB SATA
RAILS $1649.00 #server #computer http://t.co/mXdaHJfhHW

Could it be that the search was expecting to specify a hashtag but is instead just searching for the word?

All I had to do was change the matcher to /rails/i

EDIT: And now it occasionally fails with

expected css “li.tweet” to return something

when I run rake for the whole thing

EDIT2: And I’ve noticed that when I run the app in a browser, there are occasions when there is no response; only what was previously displayed remains on screen.

EDIT3: In fact, even with the hashtag taken out of the matcher, it still fails occasionally:

expected "\n Gettin some finances together (@ PNC Bank)
http://t.co/lplBBNu1Gi\n " to match /rails/i


(Ben Orenstein) #2

Hey there,

Sorry you’re having trouble with this exercise!

I’m not well-versed with how this example app works, so I don’t think I can offer good advice. Josh is teaching a workshop today, but I think he’ll be able to respond to this thread tomorrow.

Until then, I’ll offer one thought: it looks like you’re actually hitting Twitter’s service in your tests. Since you can’t be sure what will be returned for a search of Rails, you’re getting intermittent results. I almost never write tests that hit real-world services because of exactly this issue (they also tend to be slower).

Are you sure your tests are supposed to hit Twitter live? If you instead meant to fake that service, is the fake actually functioning?


(Jon Seidel) #3

Thanks…this was in the early part of the lesson, before Josh introduced the Fake. I think that the exercise may have been incorrectly structured for exactly that reason… or the changes to the API invalidated what used to work.


(Ben Orenstein) #4

Thanks for the feedback. Can we check this out @joshclayton?


(Josh Clayton) #5

@JESii as Ben mentioned, I gave this workshop yesterday and we were able to get this working just fine. Can you point me to your fork of the GitHub repo with the code you’ve written so I can take a peek at it to see if I can troubleshoot?

Thanks!


(Jon Seidel) #6

Thanks, Josh… repo is here. this is part way through the last steps of adding the Fake, but I haven’t pushed the final set of changes. I just ran rspec and it failed with:

Failures:

  1) Search twitter for a term searching by a hashtag

     Failure/Error: expect(tweet.text).to match /rails/i
       expected "\n      RT @NRA: Bloomberg used his commencement address at an #Ohio college to attack the #NRA & push #guncontrol http://t.co/E4IPjeTo5G\n    " to match /rails/i
 # ./spec/integration/search_twitter_spec.rb:11:in `block (3 levels) in <top (required)>'
 # ./spec/integration/search_twitter_spec.rb:10:in `each'
 # ./spec/integration/search_twitter_spec.rb:10:in `block (2 levels) in <top (required)>'
 # -e:1:in `<main>'

Note that I’ve already changed the match term from /#rails/ to /rails and it still fails.


(Josh Clayton) #7

@JESii What’s happening is you’re not actually searching for a hashtag. This line of code from your controller @tweets = Searcher.new("#{params[:id]}").results passes params[:id] straight through without ensuring the string is prefixed with a #; that lack of the pound has pretty large implications, the biggest being that Twitter will return search results which contain links that match rails (case-insensitive) without the pound. The link gets shortened and the test fails.

If you add another pound to the argument you pass to Searcher.new, it should pass (I verified this locally).

I’d also change the test to search for #rails instead of Rails (see https://github.com/JESii/test-driven-rails-app2/blob/edd88298f396bf4f4b1e07a1739c058527b458c9/spec/integration/search_twitter_spec.rb#L6), which will hopefully guide a couple more changes in your controller. Good luck!


(Jon Seidel) #8

Very interesting; What I still find confusing is that this identical issue was happening well before we got into the part of adding Searcher.I’ll try all your changes and see how that goes. I’ll also see if I can go back to the commit before this latest stuff and see if it still happens.

Thanks for the review…jon


(Jon Seidel) #9

That did the trick - thanks! I went over that many times and missed the missing hashtag.


(Damien Hogan) #10

Looks like I am having the same issue as @JESii, however the above solution did not work for me.

my controller is

class SearchesController < ApplicationController
def create
 redirect_to search_path(params[:twitter][:search])
end

def show
 @tweets = TwitterClient.new.search("##{params[:id]}")
end
end

and my spec is

require 'spec_helper'

feature 'search twitter for a term' do
scenario 'searching by a hashtag' do
visit root_path
fill_in 'Search', with: 'Rails'
click_button 'Search'
all('li.tweet').each do |tweet|
  expect(tweet.text).to match /#rails/i
end
end
end

I am having to use the newer gem which means the creation of this class

class TwitterClient
 def initialize
 @client = Twitter::REST::Client.new do |config|
  config.consumer_key = ENV['TWITTER_CONSUMER_KEY']
  config.consumer_secret = ENV['TWITTER_CONSUMER_SECRET']
  config.oauth_token = ENV['TWITTER_ACCESS_TOKEN']
  config.oauth_token_secret = ENV['TWITTER_ACCESS_TOKEN_SECRET']
end
end

def search(query)
 @client.search(query)
end
end

I am a bit stumped on what it could be.


(Damien Hogan) #11

so weird but its passed today with no changes. It must be something thats getting picked up by searches at some point