Thursday, March 3, 2016

Rails - Testing Javascripts



  INTRODUCTION

  Developers usually are in a habit of writing specs for all our ruby code , but we tend to skip javascript tests and try writing tests in a high level.

All javascript functionalities are usually tested by manually running the application in the browser which is NOT BAD but there are a scenarios where javascript gets complicated enough.This is where it would be a good practice to introduce unit testing for javascripts. Ofcourse there are couple of ways, gems, plugins etc here we'll be picking up Jasmine.

Jasmine is a behavior-driven development for testing javascript codes and luckily the syntax resembles that of Rspec style, however the tests are written in javascript not in Ruby,Ofcourse!

Integrating Jasmine In Rails Project

 Integrating jasmine into a rails project would be as simple as

group :development, :test do
  gem 'jasmine'
end

To initialize a rails project for Jasmine
rails g jasmine:install

Writing Specs

A test suite begins with a call to the global Jasmine function describe with two parameters: a string and a function. The string is the title for a spec suite. The function is a block of code that implements the suite.

Specs are defined by calling the global Jasmine function it, which takes a string and a function as parameters The string is the title of the spec and the function is the spec, or test. A spec contains one or more expectations that test the state of the code.

Here's our hello world example.As you can see - these javascript specs kind of uses the rspec style - making it easier to grok

app/assets/javascripts/lib/HelloWorld.js
function helloWorld(){
  return "Hello world";
}
spec/javascripts/lib/HelloWorldSpec.js
describe("Hello world", function() {
  it("returns hello world", function() {
    expect(helloWorld()).toEqual("Hello world")
    )};
)};

For getting deeper into how to write more precise javascript specs Jasmine Documentation on Github would be the best place to start off!

Running Specs

Running javascript specs would now be as simple as

rake jasmine
Open localhost:8888  in your browser.This port could be altered with certain configuration settings. To re-run the test suite this page needs to be reloaded - pretty simple.This is how we run specs locally - but how do we integrate this to a CI server like travis - for that we would require GRUNT
Grunt is a javascript task runner for automation. To install grunt, first we would need to install node and npm in our local machines.
After which we need to install Grunt's command line interface (CLI) 
sudo npm install -g grunt-cli

In your project directory, run npm init to create the file package.json for your project. This file contains information about what node.js modules the project depends on.

Now to get up and running, we need the grunt package along with a grunt task that can run the tests.

npm install grunt grunt-contrib-jasmine --save-dev
The --save-dev flag will add the package as a dependency in package.json.

Finally add the configurations to a Gruntfile.js in the project's root. This file will describe different tasks run by grunt.


module.exports = function(grunt) {
  grunt.initConfig({
    jasmine: {
      tappy: {
        src: 'app/assets/javascripts/lib/*.js',
        options: {
          specs: 'spec/javascripts/lib/*Spec.js',
          vendor: 'vendor/assets/javascripts/jquery-1.8.2.min.js'
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.registerTask('default', 'jasmine');
};


* src describes where your javascript files are located.
* specs describes where your tests are located.
* vendor denotes if you have used any third-party libraries like Jquery
* loadNpmTasks enables the specified plugin .
* registerTask - default is the rask that is run when grunt is run i.e when grunt is invoked without any task being specified.

Finally run the test suite with 
grunt jasmine












Tuesday, October 6, 2015

Building a Rails API

What is an API ?

An API defines an abstraction layer for software services and resources.  The API describes the rules and the expected behavior so that the service or resource can be accessed as a black box, without a need to understand the details of how it is implemented.


So here are a few tips on how to build a Rails API :



Namespace 


One of the best ways to maintain a good API code is to keep it independent from the rest of the controllers by moving it to app/controllers/api/ folder and name-spacing it.

config/routes.rb

  namespace :api do
    # End User APIs
    resource  :users, only: :index
  end

You can also use comments to give more idea about who's going to use your api.

So here we go!
 app/controllers/api/users_controller.rb

module Api
  class UsersController < ApiController
     #insert some code
  end
end

Versioning


It is always advisable that a publicly available API should never be modified except for bug fixes because making any alteration would break client applications using APIs .So one of the best ways to tackle this would be introduce versioning.

config/routes.rb

  namespace :api do
    namespace :v1 do
      resource  :users, only: :index
     end  
   end


 app/controllers/api/v1/users_controller.rb

module Api
  module v1
    class UsersController < ApiController
       #insert some code
     end
   end
end

Introducing a second versioning would be as simple as 

  namespace :api do
    namespace :v1 do
      resource  :users, only: :index
     end  

     namespace :v2 do
      resource  :users, only: :index
     end  
   end

With comprehensive test coverage, backwards compatibility can be ensured. 

Authentication

A base API controller is useful to handle authentication and extract common API  functionality.So here EndUserApiController takes care of our authorisation logic and UsersController makes use of this base API to handle authentication.

module Api
  module v1
    class UsersController <  EndUserApiController 
       #insert some code
     end
   end
end


 app/controllers/api/v1/users_controller.rb

class EndUserApiController < ApplicationController
  include Authorizable
  before_filter :authorize_user!

  def authorize_user!
    #insert your authorisation logic here
  end
end

Rendering Response

The most commonly used rendering responses are XML and JSON. JSON being more popular than XML because of its simpler syntax, faster both in parsing and due to small size transmission over net and is widely supported by most of the languages. 

module Api
  module v1
    class UsersController < ApiController
        def index
          render json: { users:  users }
        end

        private
           def users
              User.all.map do |user|
                 { username: user.name, role: user.role }
              end 
       end
   end
end

 HTTP Status Codes


Response from an API is only complete with correct HTTP response code.It is always advisable to 
return status codes which make sense. You can also use symbols instead of numbers so instead of status: 200 you can status: :ok which makes the code more readable.

However there is an exception to this - If an AP user does not have access privileges instead of returning 401(unauthorised) you could trick the user by returning 
404(not_found) so as to misguide the attacker about the existence of such an object.

So now we have something like this:

module Api
  module v1
    class UsersController < ApiController
        def index
          render json: { users:  users }, status: :ok
        end

        private
           def users
              User.all.map do |user|
                 { username: user.name, role: user.role }
              end 
       end
   end
end

Testing


Controller level tests are usually written to test an API wherein the response body is compared with the expected end result.This is however no different from our normal controller tests except that
we need to frame up the JSON response body before we do any comparison.

spec/controllers/api/users_controller_spec.rb

require 'spec_helper'

describe Api::UserController do
  describe '#index' do
    let(:token) { user.authentication_token }
    let(:json) { JSON.parse(response.body) }
    let!(:user) { FactoryGirl.create(:user) }
    let!(:another_user) { FactoryGirl.create(:buyer_user)  }
    end

    it 'returns a list of associated dealerships' do
      get :index, auth_token: token, format: :json
      expect(json['users']).to eql [
        {"username": user.name, "role": user.role},
        {"username": user.name, "role": user.role}
      ]
    end
end

Documenting

Documenting the API is another important task.One should make sure the following points are included in your documentation

  • a short one-liner description of the api
  • list of required and optional parameters that can be passed to the method
  • possible response codes and format of response
  • sample calls

module Api
  class UsersController < EndUserApiController
    respond_to :json

    ##
    # Get a listing of a users
    #
    # @resource /api/users
    # @action GET
    #
    # @required [String] auth_token
    #
    # @example_request
    #   ```json
    #   {
    #     "auth_token": "ASZNfqL4kFFMezw6xTW5"
    #   }
    #   ```
    #
    # @example_response
    #   ```json
    #   {
    #     "users": [
    #       {"username": "Sithu", "role": "Technical Assistant"},
    #       {"username": "Kiran", "role": "Technical Head"}
    #     ]
    #   }
    #   ```
        def index
          render json: { users:  users }
        end

        private
          def users
             User.all.map do |user|
                 { username: user.name, role: user.role }
             end 
          end
  end
end

So, with this we have covered the basic concepts to keep in mind for building a third party api in an existing Rails application.










Tuesday, June 16, 2015

Decorators And Presenters In Rails

  Decorators And Presenters In Rails 

Stuffing ALL THE THINGS into view templates is a pain for front end developersis error proneviolates the DRY principle and is difficult to test.

What would be the solution ?
* Helpers
* Decorators
* Presenters
..many more design patterns ..

Helper is very familiar among Rails Community and needs no introduction.But a question that comes to mind is Why do we need decorators when we have HELPERS ?
  
  Aside from not being very object oriented, helpers have a host of problems related to their global availability. Helpers should be avoided if they are specifically tied to a single model.Meaning to say use helpers only when there are concepts which affect the presentation logic across the application.

In Rails4 all methods inside helper directory are available to all views by default, isn't that a problem ?

Example: 

app/helpers/application_helper.rb
module ApplicationHelper
  def back_button(options = {})
    link_to t('forms.back'), :back, class: 'btn'
  end
end

app/helpers/user_helper.rb
module BlogHelper
  def published_at(blog)
    if blog && blog.published_at.present?
     "Posted: #{blog.published_at.strftime('%m, %d, %y')}"
    end
  end
end
and can be accessed using <%= published_at(blog_object ) %>

The back_button in ApplicationHelper is a presentation logic which is required across the app and is apt to be put in the helper. However we wouldn't need the formatted Blog#publised_at in all our views.So this calls for a DECORATOR !


Decorator Pattern is a design pattern that is used to extend the functionality of a specific object by wrapping it, without affecting the behaviour of other objects from the same class.
Decorators stand between the model and the view.The decorator object will know of the model and have access to the view’s helper method.Decorators works a great solution for model based presentation code.

Draper is a popular rails decorator gem.For more information DIG IN.

Example:

app/decorators/blog_decorator.rb
class BlogDecorator < Draper:Decorator def published_at "Published #{object.published_at.strftime('%A, %B %e')}" end end

app/controller/blogs_controller.rb
def show
@blog = Blog.find(params[:id]).decorate end
app/views/blogs/show.html.erb
<%= @blog.published_at %>
As you can see, the decorator pattern is a very good example of the Open-Close-Principle (OCP) which states that an class is closed to modification but open to extension. One thing to note here is that the unlike helpers the formatted published_at  will be available only to the blog objects.

Now let's move on to Presenters. Presenter is  a form of decorator. Then what would be the difference between a decorator and a presenter.

Presenter design pattern  is a way of simplifying controller logic by extracting it out into its own class which has one or more methods. 

Presenters make it easier to test controller logic by usually transforming each assigned instance variable in a controller action into its own method within the presenter class. Anytime you see a controller action which has many instances variables, it needs to be refactored to use a presenter.

The main difference between the two is that a decorator pattern is a composing operation whereas the presenter pattern is a decomposing operation.

Example: 

app/controllers/blogs_controller.rb
class BlogsController < ApplicationController def show  
blog = Blog.find(params[:id]) @blog = blog.decorate
@author = blog.author.decorate
@contributions = @author.contributions.decorate
@followers = @blog.followers.decorate end
end
So now can see you controllers growing making it difficult to test and maintain.Now this calls for a PRESENTER !

Presenters are simply Plain Old Ruby Objects(PORO) with the help of which you can clean up this messy code.

Example:


class BlogPresenter

 def initialize(blog_id)
   @blog = Blog.find(blog_id)
 end

 def decorated_blog
   @decorated_blog ||= @blog.decorate
 end

 def author
   @author ||= @blog.author.decorate
 end

 def contributions
   @contributions ||= @author.contributions.decorate
 end

 def followers
   @followers ||= @author.followers.decorate
 end
end
app/controller/blogs_controller.rb
class BlogsController < ApplicationController def show   @presenter = BlogPresenter.new(params[:id]) end end
and can be accessed using <%= @presenter.author %> 

So in this way we could decompose the controller actions and maintain a clean code base.


Finally the PROS in using  Presenters & Decorators 

- More maintainable and clean codebase
- DRY
- Clarity
- Easy to Write Tests