So I'm working on a gem that provides helpers for use with the Jeditable jQuery plugin, called jeditable-rails. These helpers are essentially writing javascript that create forms.
I am looking to stub templates within the request/controller specs, doing something like this:
gadget = Gadget.create!(:name => 'foo')
stub_template 'gadgets/edit.html.erb' => "<%= editable_field(#gadget, :name) %>"
# using Capybara
visit edit_gadget_path(gadget)
# fill out form, submit, etc.
When I run this in a request spec, I get the error undefined method 'stub_template'. Is it possible to use stub_template in request specs, or is there a different way to go about it?
This is Ruby, so it's probably possible, but it's not a given.
RSpec request specs delegate most of their work to Rails integration tests, which support multiple requests and, therefore, multiple controllers/views. stub_template requires access to a view instance, which we don't have access to in request specs.
Related
I want to test the workings and functionality of the basic CakePHP 3.x Authentication form, and the associated logic behind that action. However, I have gone round and round trying to write a unit test for the login page generated with CakePHP 3.x - you know, for completeness of code coverage - and have found available information seriously lacking or absent.
I can find plenty of information for unit testing the login form on CakePHP 2.x, which is mostly useless because of the changes between CakePHP 2.x & 3.x. Can anyone point me to some detailed information regarding, or provide an explanation of, testing the login page?
EDIT I am not looking for tutorials (but not gonna turn them away if the expose requested info), tools, or other shortcuts; I don't want/need a copy & paste solution. What I am looking for is more info about the data structures so that I can put a unit test together.
EDIT 2 I am attempting to accomplish this but with CakePHP 3.x instead.
Check this out!
public function testAddUnauthenticatedFails()
{
// No session data set.
$this->get('/articles/add');
$this->assertRedirect(['controller' => 'Users', 'action' => 'login']);
}
public function testAddAuthenticated()
{
// Set session data
$this->session([
'Auth' => [
'User' => [
'id' => 1,
'username' => 'testing',
// other keys.
]
]
]);
$this->get('/articles/add');
$this->assertResponseOk();
// Other assertions.
}
Copied from Cake 3 cookbook on testing
EDIT:
Didn't realize that the question was about testing of the interns of the Authentication - but here's a link for that: https://github.com/cakephp/cakephp/tree/master/tests/TestCase/Auth
Today I came across some strange (and very inconvenient) Ruby on Rails behavior that even persistent combing of the net did not yield a satisfying answer to.
Note: I translated the method and route names to be easier to read in English, and hope I did not introduce any inconsistencies.
Situation
Environment
Ruby on Rails 4.2.0 executing under Ruby 2.0 (also tested under Ruby 2.2.0)
Relevant Code
consider a controller with these actions, among others:
class AssignmentsController < ApplicationController
def update
...
end
def takeover_confirmation
...
end
end
routes.rb
Since I use a lot of manually defined routes, I did not use resources in routes.rb. The routes in question are defined as follows:
...
post 'assignments/:id' => 'assignments#update', as: 'assignment'
post 'assignments/takeover_confirmation' => 'assignments#takeover_confirmation'
...
The relevant output of rake routes:
assignment POST /assignments/:id(.:format) assignments#update
assignments_takeover_confirmation POST /assignments/takeover_confirmation(.:format) assignments#takeover_confirmation
Problem
When I do a POST to the assignments_takeover_confirmation_path, rails routes it to the update method instead. Server log:
Started POST "/assignments/takeover_confirmation" for ::1 at ...
Processing by AssignmentsController#update as HTML
Mitigation
If I put the update route definition after the takeover_confirmation one, it works as intended (didn't check a POST to update though).
Furthermore, after writing all this I found out I used the wrong request type for the update method in routes.rb (POST instead of PATCH). Doing this in routes.rb does indeed solve my problem:
patch 'assignments/:id' => 'assignments#update', as: 'assignment'
However, even when defining it as POST, Rails should not direct a POST request to the existing path "/assignments/takeover_confirmation" to a completely different action, should it?
I fear the next time I use two POST routes for the same controller it will do the same thing again.
It seems I have a severe misconception of Rails routing, but cannot lay my finger on it...
Edit: Solution
As katafrakt explained, the above request to /assignments/takeover_confirmation matched the route assignments/:id because Rails interpreted the "takeover_confirmation" part as string and used it for the :id parameter. Thus, this is perfectly expected behavior.
Working Example
For the sake of completeness, here is a working (if minimalistic) route-definition that does as it should, inspired by Chris's comment:
resources :assignments do
collection do
post 'takeover_confirmation'
end
end
In this example, only my manually created route is explicitly defined. The routes for update, show, etc. (that I defined manually at first) are now implicitly defined by resources: :assignments.
Corresponding excerpt from rake routes:
...
takeover_confirmation_assignments POST /assignments/takeover_confirmation(.:format) assignments#takeover_confirmation
...
assignment GET /assignments/:id(.:format) assignments#show
PATCH /assignments/:id(.:format) assignments#update
PUT /assignments/:id(.:format) assignments#update
DELETE /assignments/:id(.:format) assignments#destroy
....
Thanks for the help!
However, even when defining it as POST, Rails should not direct a POST request to the existing path "/assignments/takeover_confirmation" to a completely different action, should it?
It should. Rails routing is matched in exact same order as defined in routes.rb file (from top to bottom). So if it matches a certain rule (and /assignments/takeover_confirmation matches assignments/:id rule) it stops processing the routing.
This behaviour is simple and efficient. I imagine that any kind of "smart" matching the best route would result in cumbersome and unexpected results.
BTW that's why catch-all route used to be defined at the very bottom of routing file.
I want to know the difference between them.
get "public/show"
get "public#show"
get "show/:something", :to => "public#show"
Thanks,
Mezbah
1) public/show
Since you do not specify a controller or action, Rails uses it's convention to map the URL "public/show" to the show action of the PublicController.
2) public#show
This is not a valid route.
3) show/:something
You define a parameter called "something" in the URL. This means that a URL such as "show/dog" and "show/cat" will call the show action of the PublicController. You can get the parameter as a string ("cat" or "dog) by using params[:something] in the controller.
The Rails documentation is really good. A good source of more information on routing: http://guides.rubyonrails.org/routing.html
I make an application writed in Rails, it's growing fast and I learning with it. But I'm don't understand about helpers.
application_helper.rb
module ApplicationHelper
# This file it's empty
end
users_helper.rb
module UsersHelper
def avatar
# Do something
end
end
customer_helper.rb
module CustomerHelper
# This file it's empty
end
Why in any customer's view can call avatar helper method on user helper module?
Then, why separate helpers in many files?
Thanks in advance.
P.S: Rails' version 4.
Because all helpers are included in all controllers, by default. The separate files are really just for logical separation in this scenario. You can change that behaviour though:
By default, each controller will include all helpers.
In previous versions of Rails the controller will include a helper
whose name matches that of the controller, e.g., MyController will
automatically include MyHelper. To return old behavior set
config.action_controller.include_all_helpers to false.
http://api.rubyonrails.org/classes/ActionController/Helpers.html
To add to Mike Campbell's answer:
Framework
As magic as it is, Rails is a set of files which are called
sequentially
These files hold classes, methods, etc; but they're still files.
And that means that when you run an action through Rails, it loads up
a series of other dependent files to help it run (that's what a
framework is)
The design of Rails is such that your helper methods are all
loaded each time you run an action. I don't know why, but it helps
administer the methods for different areas of your app
So to answer your question, there's no real reason why the helpers are split up, at least with Rails 4
I have a number of simple controller classes that use Doctrine's entity manager to retrieve data and pass it to a view.
public function indexAction() {
$pages = $this->em->getRepository('Model_Page')->findAll();
$this->view->pages = $pages;
}
What exactly should we be testing here?
I could test routing on the action to ensure that's configured properly
I could potentially test that the appropriate view variables are being set, but this is cumbersome
The findAll() method should probably be in a repository layer which can be tested using mock data, but then this constitutes a different type of test and brings us back to the question of
What should we be testing as part of controller tests?
Controller holds core logic for your application. Though simple "index" controller actions don't have any specific functions, those that verify/actively use data and generate viewmodels have pretty much the most functionality of the system.
For example, consider login form. Whenever the login data is posted, controller should validate login/password and return: 1) to index page whenever logins are good. Show welcome,{user} text. 2) to the login page saying that login is not found in db. 3) to the login page saying that password is not found in db.
These three types of outputs make perfect test cases. You should validate that correct viewmodels/views are being sent back to the client with the appropriate actions.
You shouldn't look at a controller like at something mysterious. It's just another code piece, and it's tested as any other code - any complicated logic that gives business-value to the user should be tested.
Also, I'd recommend using acceptance testing with framework like Cucumber to generate meaningful test cases.
Probably the controller is the hardest thing to test, as it has many dependencies. In theory you should test it in full isolation, but as you already seen - it has no sense.
Probably you should start with functional or acceptance test. It tests your controller action in a whole. I agree with previous answer, that you should try acceptance testing tools. But Cucumber is for Ruby, for PHP you can try using Codeception. It makes tests simple and meaningful.
Also on a Codeception page there is an article on how to test sample controllers.