Testing for false with the Twitter Gem in rails 3 - ruby-on-rails-3

I'm using the Twitter gem, and I want to take a list of users from my Friend model and test to see if they're being following a Twitter user, then ... unfollow if the Twitter API returns false. Trouble is, it seems the code I'm using below never evaluates as false, even when the API returns false so it's always reverting to the else section.
I've tried variations like if ret == 'false' and it's not worked.
ret = #t.friendship?(#id_str, f.screen_name)
if ret == false
#t.unfollow(f.screen_name)
puts "#{f.screen_name} has been unfollowed."
self.update_unfollowed_column(f.id, false)
else
self.update_following_column(f.id)
end
In the console, though, if I do:
r = t.friendship?('user1', 'user2')
=> false
And then, I can do:
r == false
=> true
So, I'm not sure exactly what I'm doing wrong with the code in my Friend model.

Before the if statement, try debugging what the result is from the friendship? method:
logger.info ret.class.name # => FalseClass if it's actually false,
# => String if it's 'false'
logger.info ret.inspect # => "false" if it's false.
logger.info((ret == false).inspect) # => Should be "true"

Related

How to Rspec system that ActionCable broadcast messages appear in the view

I want to test that messages that are broadcast when some background jobs are completed are actually appearing in the view.
I have unit tests for this which work fine. I would actually like to ensure that the JS gets run so that the view is updated with the correct message.
So far I have not been able to find any way to do this.
Here is the test I have where I would like to add the expectation for the broadcast message:
require 'rails_helper'
require 'sidekiq/testing'
RSpec.describe 'sending a quote request', js: true do
let(:quote_request_form) { build(:quote_request_form) }
before do
create(:job_rate, :proofreading)
create(:proofreader_with_work_events)
end
it 'shows the user their quotation' do
visit new_quote_request_path
fill_in("quote_request_form_name", with: quote_request_form.name)
fill_in("quote_request_form_email", with: quote_request_form.email)
attach_file('customFile','/Users/mitchellgould/RailsProjects/ProvenWordNew/spec/test_documents/quote_request_form/1.docx', make_visible: true)
click_on "Submit"
Sidekiq::Testing.inline! do
page.execute_script("$('#invisible-recaptcha-form').submit()")
expect(current_path).to eq(quote_confirm_path)
#add expectation here:
expect(page).to have_content("Calculating Time Required")
page.execute_script("window.location.pathname = '#{quotation_path(Quotation.first)}'")
expect(current_path).to eq(quotation_path(Quotation.first))
expect(page).to have_content("Here is your quotation")
end
end
end
Here is my .coffee file:
$(document).on 'turbolinks:load', ->
if $("meta[name='current_user']").length > 0
App.notification = App.cable.subscriptions.create "NotificationChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
$('.background_message').html(data.content)
if data.head == 302 && data.path
window.location.pathname = data.path
else if App.notification
App.quotation.unsubscribe()
delete App.notification
Here is one of the background jobs that broadcasts a message when its done:
class CreateParagraphDetailsJob < ApplicationJob
queue_as :default
after_perform :broadcast_message, :calculate_proofreading_job_duration
def perform(document, proofreading_job_id, current_user_id)
document.create_paragraph_details
end
private
def calculate_proofreading_job_duration
CalculateDurationJob.set(wait: 1.seconds).perform_later proofreading_job_id, current_user_id
end
def broadcast_message
ActionCable.server.broadcast "notification_channel_user_#{current_user_id}", content: "Analyzed writing quality of paragraphs"
end
def document
self.arguments.first
end
def proofreading_job_id
self.arguments.second
end
def current_user_id
self.arguments.last
end
end
Any ideas on how to do this?

Needs redirects for routing

I'm very excited about Camaleon cms for rails 5; however, I've noticed a significant problem with posts that have parent slugs or have post-type slugs in the url as a url format.
For background, it's very important that a post's content can only be reached via one single url. Otherwise, you have the potential for getting penalized in google for having duplicate content. For those who rely on search engine traffic (basically everyone who would ever use a CMS), this is a very serious issue.
The following is an example of the issue. All of these urls will render the same post content:
http://www.example.com/parent_slug/post_slug
http://www.example.com/post_slug
http://www.example.com/parent_slug_blah_blah/post_slug
Or
http://www.example.com/post_type/post_slug
http://www.example.com/post_slug
http://www.example.com/post_type_blah_blah/post_slug
The way Wordpress deals with this issue is to redirect to the proper url with the correct parent slug if it doesn't exist or if it is misspelled.
My question here is for those in the know, is this perhaps a priority issue in one of the upcoming releases?
I'm not sure if this will work for everyone, but here's my solution to this issue.
Requirements: this will only work for posts that have the "post_of_posttype", "heirarchy_post" or "post_of_category_post_type" route formats.
The following code is extending the functionality of Camaleon's frontend controller method render_post by simply adding a redirect when the params don't match the #post.the_path. Seems to work for my purposes. Hopefully it will help someone else.
Create a new file in your config/initializers folder and place the following code:
# config/initializers/camaleon_custom_post.rb
CamaleonCms::FrontendController.class_eval do
# render a post
# post_or_slug_or_id: slug_post | id post | post object
# from_url: true/false => true (true, permit eval hooks "on_render_post")
def render_post(post_or_slug_or_id, from_url = false, status = nil)
if post_or_slug_or_id.is_a?(String) # slug
#post = current_site.the_posts.find_by_slug(post_or_slug_or_id)
elsif post_or_slug_or_id.is_a?(Integer) # id
#post = current_site.the_posts.where(id: post_or_slug_or_id).first
else # model
#post = post_or_slug_or_id
end
unless #post.present?
if params[:format] == 'html' || !params[:format].present?
page_not_found()
else
head 404
end
else
#post = #post.decorate
if ["post_of_posttype","hierarchy_post"].include? #post.the_post_type.contents_route_format
if params[:parent_title].nil? && params[:post_type_title].nil?
params_path = "/" + params[:slug]
elsif !params[:parent_title].nil?
params_path = "/" + params[:parent_title] + "/" + params[:slug]
elsif !params[:post_type_title].nil?
params_path = "/" + params[:post_type_title] + "/" + params[:slug]
end
unless (#post.the_path === params_path)
redirect_to #post.the_url, status: 301 and return
end
elsif #post.the_post_type.contents_route_format === "post_of_category_post_type"
if [params[:post_type_title],params[:label_cat],params[:category_id],params[:title]].all?
params_path = [params[:post_type_title],params[:label_cat],params[:category_id] + "-" + params[:title],params[:slug]].join("/")
params_path.prepend("/")
unless (#post.the_path === params_path)
redirect_to #post.the_url, status: 301 and return
end
else
redirect_to #post.the_url, status: 301 and return
end
end
#object = #post
#cama_visited_post = #post
#post_type = #post.the_post_type
#comments = #post.the_comments
#categories = #post.the_categories
#post.increment_visits!
# todo: can_visit? if not redirect home page
home_page = #_site_options[:home_page] rescue nil
if lookup_context.template_exists?("page_#{#post.id}")
r_file = "page_#{#post.id}"
elsif #post.get_template(#post_type).present? && lookup_context.template_exists?(#post.get_template(#post_type))
r_file = #post.get_template(#post_type)
elsif home_page.present? && #post.id.to_s == home_page
r_file = "index"
elsif lookup_context.template_exists?("post_types/#{#post_type.the_slug}/single")
r_file = "post_types/#{#post_type.the_slug}/single"
elsif lookup_context.template_exists?("#{#post_type.slug}")
r_file = "#{#post_type.slug}"
else
r_file = "single"
end
layout_ = nil
meta_layout = #post.get_layout(#post_type)
layout_ = meta_layout if meta_layout.present? && lookup_context.template_exists?("layouts/#{meta_layout}")
r = {post: #post, post_type: #post_type, layout: layout_, render: r_file}
hooks_run("on_render_post", r) if from_url
if status.present?
render r[:render], (!r[:layout].nil? ? {layout: r[:layout], status: status} : {status: status})
else
render r[:render], (!r[:layout].nil? ? {layout: r[:layout]} : {})
end
end
end
end
Seems kind of strange the mandatory redirect for non-accurate urls is not in the core camaleon application, but perhaps most people who use this cms are creating internally facing apps. Anyway, if that's not the case, I think this should be a priority fix.

Rails 3: accept all params except a specific value

I have a Rails 3.2.13 Application to maintenance.
Because of authorization rules i want to limit the find(params[:file_registry_id]) method to accept all parameters except 752. (Only user tehen should be able to get it.)
def show
if current_user.tehen?
#file_registry = FileRegistry.find(752)
else
#file_registry = FileRegistry.find(params[:file_registry_id])
end
#rubric = Rubric.find(params[:id])
#rubrics = expanded_rubrics #rubric.ancestors_with_self.collect(&:id)
set_favorites
render :action => 'index'
end
Is there a method available to filter an element (here id 752) from the params hash? Or what's the best way to go?
Simple solution:
def show
#file_registry = get_file_registry
#....
end
private
def get_file_registry
if current_user.tehen?
FileRegistry.find(752)
else
unless params[:file_registry_id] == FORBIDDEN_ID_FOR_GUEST
FileRegistry.find(params[:file_registry_id])
else
false
end
end
end
FORBIDDEN_ID_FOR_GUEST should be defined outside of the controller, for example inside of a initializer.
But I suggest to use a authorization library like CanCan (https://github.com/ryanb/cancan) where you can define permissions for every use case.

record_timestamp = false not working from model

I want to track the last_login DateTime of my user, without changing the updated_at attribute.
So inside my Model attribut I put:
def login!(session)
session[:user_id] = id
User.record_timestamp = false
self.touch(:last_login_at)
User.record_timestamp = true
end
also tried, which is the same:
def login!(session)
session[:user_id] = id
self.last_login_at = Time.now
User.record_timestamps = false
self.save(:validate => false)
User.record_timestamps = true
end
But update_at column still is updated after each login.
It seems that User.record_timestamps = false doesn't have any effect when being called from the model directly. (I use to call this method from controller or rake tasks without any problem)
please don't tell me to use update_attribute :last_login_at, Time.now which in Rails 3.1 doesnt set the updated_at column: I'm using rails 3.0.9!
Any idea?
It's really more DRY for me to do this update from the model and not from any controller...
--------------------
[edit] Hummmmmm seems like a bug in rails: I have a nested Class SubUser < User.
When I replace User.record_timestamps = false by self.class.record_timestamps = false then it's working. It's quite strange because:
1) I'm calling #user.login! with a real class User (User.first.login!)
2) even if I were calling SubUser.first.login! the command User.record_timestamps should affect too SubUser class, right?
This is the way I did this before, please give a shot.
def login!(session)
session[:user_id] = id
class << self
def record_timestamps; false; end
end
self.last_login_at = Time.now
self.save(:validate => false)
class << self
remove_method :record_timestamps
end
end
Let me know if it helps you anyway.
I would try using update_attribute because it doesn't do validations so maybe it doesn't update the timestamps either. I'm not sure if it will work:
def login!(session)
update_attribute :last_login_at, Time.now
end

Undefined Method `authorize_from_request' using OAuth and Twitter Gem in Ruby on Rails 3

Im getting the following error:
undefined method `authorize_from_request'
Based on the documenation here: http://oauth.rubyforge.org/rdoc/classes/OAuth/Consumer.html
That method doesnt exist, but I saw this method used here:
http://teachmetocode.com/screencasts/oauth-with-the-twitter-gem/ and
so I'm guessing it was deprecated some time ago, but I can't seem to
find its replacement and was wondering what other way could I go about
solving this issue?
Thanks in Advance!
Controller Code:
class TwitterController < ApplicationController
def index
end
def login
oauth_request_token = oauth.get_request_token(:oauth_callback => "http://gnome.local/twitter/finalize")
session[:request_token] = oauth_request_token.token
session[:request_secret] = oauth_request_token.secret
redirect_url = oauth_request_token.authorize_url
redirect_url = "http://" + redirect_url unless redirect_url.match(/^http:\/\//)
redirect_to redirect_url
end
def finalize
oauth.authorize_from_request(session[:request_token], session[:request_secret], params[:oauth_verifier])
#client = Twitter::Client.new(oauth).verify_credentials
session[:request_token] = nil
session[:request_secret] = nil
oauth_access_token = oauth.get_access_token
#oauth_token = session[:oauth_token] = oauth_access_token.token
session[:oauth_secret] = oauth_access_token.secret
end
def client
oauth.authorize_from_access(session[:auth_token])
end
def oauth
#oauth ||= OAuth::Consumer.new(APP_CONFIG[:twitter][:consumer_key], APP_CONFIG[:twitter][:consumer_secret], :site => "http://api.twitter.com", :request_endpoint => "http://api.twitter.com", :sign_in => true);
end
end
(Original Post: http://groups.google.com/group/oauth-ruby/browse_thread/thread/614b27e4f5d80fab)
Got the same problem, the solution is to use according to the (old) Twitter gem:
request_token.get_access_token(oauth_verifier: params[:oauth_verifier])