Austin Story

Ruby, Rails and Javascript Blog

Powered by Genesis

Testing Mulitenancy with Minitest and Capybara

February 16, 2015 By Austin Story Leave a Comment

Lately I have used an outside in approach to building my web application in ruby on rails.  What that means is that I am driving my application development by building integration tests.  I picked up this technique a year or so ago from thoughtbot.  So far, i have really enjoyed the insight it has given me and how much less code I write than when i was doing things by building models first.

Many of the applications I end up building as a consultant are multi-tenant application.  So there are many customers that have to live in strict or limited scope from each other.  I have built a really simple helper that I have been using and wanted to share it below in my TestCase class description

[code]

class ActiveSupport::TestCaseActiveRecord::Migration.check_pending!
include Warden::Test::Helpers
fixtures :all

def as_user(user)
login_as users(user.to_sym)
yield
logout
end
end

[/code]

 

It is super simple and I was a little hesitant to put it out there.  All it does is a login the user, execute the block that is passed in and then log the user out.  In a multitenant app though it is really imporant to check your scopes based on the type of user that is logging in (admin, super admin, org admin, user, anonymous, etc).  On top of that it adds to some very understandable tests.  Ozark and nixa are just two random cities in my area.

 

[code]

scenario "Employee cannot visit other organizations tickets" do
as_user(:ozark_employee) do
ozark_ticket = organizations(:ozark).tickets.first
visit ticket_path(ozark_ticket)

page.text.must_include unauthorized_error
end
end

scenario "Can edit own tickets" do
as_user(:ozark_employee) do
visit tickets_path
click_link 'Edit'
fill_in 'Description', :with => 'Some new description xxx'
click_button 'Update Ticket'

page.text.must_include 'successfully updated'
page.text.must_include 'Some new description xxx'
end
end

[/code]

This one simple helper has really tied in with my multitenant outside in development and sped up my dev time when building out how different types of users should experience an application.

Filed Under: Minitest, Programming, Testing Tagged With: bdd, minitest, ruby on Rails, tdd

Script to generate fixtures from a database

February 7, 2015 By Austin Story 1 Comment

So I have used minitest for about 8 months now for testing and all in all it turns out that I loved it more than I expected.  I just moved back to an in progress in house project written using Rspec with FactoryGirl and realized I want my minitest and  fixtures back.  So i found a great script that will generate fixturess based on my database seed.

 

[ruby]
sql = "SELECT * FROM %s"
skip_tables = ["schema_info"]
ActiveRecord::Base.establish_connection
ActiveRecord::Base.connection.tables.each do |table_name|
i = "000"
File.open("#{Rails.root}/test/fixtures/#{table_name}.yml", 'w') do |file|
data = ActiveRecord::Base.connection.select_all(sql % table_name)
file.write data.inject({}) { |hash, record|
hash["#{table_name}_#{i.succ!}"] = record
hash
}.to_yaml
end
end

[/ruby]

Filed Under: Minitest, Ruby, Ruby on Rails

Understand how Ruby on Rails Dropdown Menus Work – Rails Select Tag and Options For Select

November 25, 2014 By Austin Story 4 Comments

I have programmed using rails for a while, but while helping with a Stackoverflow question i realized I didn’t have a very firm grasp of the interworkings of select_tag or options_for_select. So I wrote this blog post in order to get a better understanding of it.

Both of these tags are located in ActionView::Helpers and are used to turn some collection of stuff into an intelligently grouped options list that can be selected.

Rails provides several ways to do this ranging from simple to intimidating (meaning, you pass in 5 different options to a method and hope that the order is correct). The latter can be a little daunting for beginner developers and frustrating for more advanced developers who use the components only often enough to forget the order before the next time they use them.

To start with, let’s create a simple select box in html.

[ruby]
<select name="user_id" id="user_id">
</select>
[/ruby]

This html is the minimum you can generate with a select_tag call, you must supply either a name or symbol that is converted using ruby into the name=” and id=” above. The above select tag would look like this.

[ruby]
<%= select_tag(:user_id) %>
[/ruby]

Note that you cannot just call select_tag with no options. The element for the name/id is required.

Now that we have a select box that will submit a user_id in the form, we will want to put some options in the box. A quick and dirty way to accomplish this task is to add a string representing the options.

[ruby]
<%= select_tag(:user_id, '<option value="1">Jemmy Legs</option><option value="2">Talos</option>') %>
[/ruby]

However, this string will not work. If you put this in a rails project it will display an empty dropdown box because select_tag is actually a facade for content_tag. The options in the second argument are passed to a call to content_tag in the helper. Content tag sends this to another helper which passes your content options to ERB::Util.unwrapped_html_escape.

So ultimately, it is escaped in a way where it is ‘safer’ before it leaves the server

To get it to work you can chain on the html_safe method method.

[ruby]
<%= select_tag(:user_id, '<option value="1">Jemmy Legs</option><option value="2">Talos</option>'.html_safe) %>
[/ruby]

Now that we are creating getting a dropdown box, we will want an easier way to build the options. This can be accomplished using the method options_for_select to generate our options AND set them as html_safe without having to type out all the html.

The options_for_select arguments is a set of name and value pair represented by a hash, array, enumerable, or some other type. Below is a nested array demonstrating their format.

[
[‘textdisplayed in dropdown box’, ‘value_sent_to_server’],
[‘Jemmy Legs’, 1],
[‘Talos’, 2]
]

In action it looks like this

[ruby]
#just the options
<%= options_for_select([['Jemmy Legs', 1], ['Talos', 2]])%>

#combined together with select tag
<%= select_tag(:user_id, options_for_select([['Jemmy Legs', 1], ['Talos', 2]]))%>
[/ruby]

Options_for_select is located in ActionView::Helpers::FormOptionsHelper. If the object passed to it (the nested array, hash, etc) responds to .map and provides a text and value through option_text_and_value, then it calls the content_tag_string helper on each text-value pair, joins them with a new line and finally calls html_safe on the results.

My next blog I plan to dive deeper in the helpers mentioned above. Here are some good links in the meantime.

Good Links
Source
https://github.com/rails/rails/blob/7e375afba30951b60a3e606ccbfe3f28b0df5e1a/actionview/lib/action_view/helpers/form_tag_helper.rb

Rails Guides
http://guides.rubyonrails.org/form_helpers.html#making-select-boxes-with-ease

http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select

http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html

facade pattern
http://en.wikipedia.org/wiki/Facade_pattern

Filed Under: Ruby on Rails Tagged With: ActionView, Content Tag, Helpers, Options For Select, Rails, Select Tag, select_tag

  • « Previous Page
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 7
  • Next Page »

Categories

  • AngularJS
  • Books
  • Devise
  • Elasticsearch
  • ES6
  • Information Security
  • Integrations
  • Javascript
  • Linux
  • Minitest
  • PhoneGap
  • Programming
  • React
  • Redux
  • Ruby
  • Ruby on Rails
  • Stripe
  • Testing
  • Theory
  • TypeScript
  • Uncategorized
  • Vue
  • Webpack