Rspec view test not working out, help me troubleshoot - ruby-on-rails

I'm writing Rspec view tests, and the tests are not passing, but I'm not sure why. In other words there are no errors in the way the test is written, it's just that the expectation is not meeting the result. Would love help troubleshooting here.
In the test below, I initially thought the problem was that the link I'm looking for is in the navbar in the application layout. So following advice from this post: getting Rspec view specs to render application layout, I explicitly called which template and layout to render. However, the right link still cannot be found.
The href tag that I've written is copied directly from the inspect element on the actual page. I have also tried to write the new_request_path that the routes gives me, and that didn't work either.
Thanks for any help!
RSpec View test code:
describe 'signups/new.html.erb' do
it 'displays link to request pages not signup page' do
assign(:signup, FactoryGirl.build(:signup))
render template: "signups/new", layout: "layouts/application"
rendered.should have_link(href: "/new")
end
end
FYI, Inspect Element:
<a class="navbar-brand" href="/new">Make a new request</a>
FYI, Routes:
get 'new', to: 'requests#new', as: 'new_request'
FYI, the application layout being rendered:
<nav class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="<%= root_path %>">Home</a>
<a class="navbar-brand" href="<%= new_request_path %>">Make a new request</a>
I don't see the need to post anything from the new template being rendered since hte test is looking only inside the application layout. (But it's not a layout based view test, because 1) I'm testing pages as a whole and there are different flash messages triggered in the layout and because 2) other tests that I'm writing [similarly stuck but I think I can figure them out if I get help on one] look at the actual new template)

Somewhat figured this out, here are some short hand notes:
Render_view in controller never worked, I just removed it
completely (at least controller tests pass!)
So terrible, but reason view tests weren't passing is because my
model is named Request so my variables were #request, which
apparently is a class already, so there was a name conflict. I
basically had to change every instance of #request to #requestrecord
There were indeed some syntax errors in the tests. have_selector('csstag') MUST be prefixed with either a . for css class or # for css id. As well, have_link MUST take a name of link, e.g., have_link("Home", href: root_path). If latter can be changed, that'd be great, because I think it's worrisome to have a hard written title of the link, which can easily change.
In two views that were tested, the first lines of code in the actual view were if/then statements testing for errors in form submission (and then flashing up an appropriate message) of a certain variable. This tripped up the view because in isolation, these variables were never defined. So in the tests, I had to always add a before block that just passed through some arbitrary data for the variable.

Related

Sightly # extension='html' adding a space a the end of the URL

We're having a weird problem in our AEM 6.3 application.
For some reason, the link to the contact-us page gets rendered with a space at its end, making it useless.
I'm trying to figure this out but I'm kinda new to sightly (I used to be working on CQ5).
To visualize it better, the configured link in the page properties is:
/content/app-name/hk/hk/info/contact-us
And the code in the HTML/sightly page is:
<a href="${inheritedPageProperties.linkToContactUsPage # extension='html'} ">
Contact Us
</a>
While what gets rendered in the actual page is:
<a href="/hk/hk/info/contact-us%20.html">
Contact Us
</a>
This happens only in the chinese pages of the site, I'm not sure if this is relevant or just a coincidence.
At first I thought the problem could be the blank space at the end of the href attribute, but shouldn't it result in "/hk/hk/info/contact-us.html%20" then? Also why would this problem affect only the chinese language pages and not all the other languages?
AFAICT you do have a space in the page properties link:
Please remove the space in your
<a href="${inheritedPageProperties.linkToContactUsPage # extension='html'} ">
like this
<a href="${inheritedPageProperties.linkToContactUsPage # extension='html'}">

pjax -- must links be inside the pjax-container?

I am using https://github.com/rails/pjax_rails.
I want to have my links inside a "permanent" portion of the page. I.e. in my layout I have
<%= link_to "Some Action", some_action_path %>
Then inside the view:
<div data-pjax-container>Content to be replaced</div>
Here is my javascript where I invoke pjax:
('[data-pjax-container]').pjax('a');
[You may note that this is different than the invocation method in the readme, but as a reported issue points out, the method in the readme doesn't work at all.]
This is not working (the link reloads the entire page).
If I move the link inside the div with the data-pjax-container attribute, it works (the page is not reloaded and only the container is updated).
I have not seen any examples where the link was actually outside of the container. Can anyone tell me how to get this to work?
I was probably focusing too much on the pjax-rails readme (not great). I went to the source (https://github.com/defunkt/jquery-pjax) which led me to changing my js to this:
$(document).pjax('a', '[data-pjax-container]')
..which got me back on the right track.

Where can I find (and change) the markup used by "render 'flashes'"?

This is my first project using Ruby on Rails and I'm working on the front-end code; the back-end developer is new to rails too. One template includes the code render 'flashes', which is triggered when there is an error on a form submission; but the markup it generates is messed up, and I'd like to fix it. Here's an example. The <!-- comments --> are mine:
<div id="flash">
<div class="wrapper">
<div title="Error" class="error"></div> <!-- Empty div -->
<p>Please enter a valid email</p> <!-- p element sibling of div.error -->
</div> <!-- Closes div.wrapper -->
</div> <!-- Closes div#flash -->
</div> <!-- Extra /div closes parent div -->
I would prefer to use one div for the message, but the biggest problem is the extra closing div tag at the end, which closes a parent division, messing up the layout.
I see that the error message is defined in the controller as flash[:error] = "Please enter a valid email", but I don't know where rails is getting this bogus markup. Is there a _flashes partial I can edit to fix this problem? I've pored over the project's filesystem, and it's not clear to me where this markup lives.
There is no _flashes.html.erb file in the Rails source. If you're seeing
render 'flashes'
in your application, you or some generator you ran put it there. Look through the files in app/views/ for one called _flashes.html.erb that contains the markup you provided in your Question. Once you find that file you should be able to modify it however you need to fix your broken HTML issue.
If you can't find it there, look at your list of gems in your Gemfile, specifically for one that relates to theming/templating. It's possilbe you've included a gem that contains this template file (though much less likely than the file existing in app/views/).

How to select from multiple CSS selectors with Capybara

Using RSpec and Capybara to test for the existence of an element within a div with class 'foo'.
<div class="foo">
<p>Text zzz</p>
Looking for element here
</div>
<div class="foo">
<p>Text aaa</p>
Element should not exist within this div.
</div>
There are many divs with class 'foo' on the page, and I can give them different ID's based on foo's ID in the database.
But I don't know foo's ID from within the test. And, I don't want to test the parent of the divs because an element should be present in one div and absent in another.
What is the best way to test for an element in this case?
If I understand the question correctly (and I'm not 100% confident I do), I think this should work:
el1 = find(:xpath, '//div[#class="foo"][./p[contains(.,"Text zzz")]]')
el2 = find(:xpath, '//div[#class="foo"][./p[contains(.,"Text aaa")]]')
There's probably a slightly simpler way to do this using css instead of xpath, but I've found that this works for this type of situation. (Note: I haven't actually tested this code.)
parent = find("p[text()='zzz']").find(:xpath,"..")
within parent do
...
https://github.com/jnicklas/capybara/pull/505

How do you handle widgets in rails?

StackOverflow, for example, has a user's reputation displayed up top. Clearly, this is grabbed from the database, and it's displayed on every page. Of course, this isn't in every controller action on every page, because that would be incredibly redundant.
How do you handle this kind of situation in rails? The only way I can think of it is to use before_filters to pass the models into the page, but that just seems like abuse of that feature. There seems to be the cells gem that does what I want, but I'd imagine this is a common problem and there must be a simple solution for it in rails without having to resort to plugins or gems.
What you are looking for is the layout. In rails this is where you define headers, footers, and sidebars that frame your site. Look for app/views/layouts/application.html.erb in your generated rails code. Towards the bottom you will see:
<body>
<%= yield %>
</body>
The yield is where rest of the app gets invoked. Everything before and after the yield will appear on every page. So, using your example, you might query the database and set the instance variable #reputation in the application controller:
#reputation = User.find( current_user ).reputation
then display it in the layout like this:
<body>
<%= #reputation %>
<%= yield %>
</body>
This is covered thoroughly in the book "Agile Web Development With Rails". If you are going to develop in Rails I recommend getting the latest edition.
I would just make a partial with the widget in it and render it in the layout(s) where you want it to appear. Let it do whatever it needs to do, eg connect to the db, run some js to connect to an external site, etc.
If you're concerned about optimisation then deal with it when it becomes a problem.
I guess, you can put the code you need into a view helper. And then render some partial, like it was said before, in the layouts where you want it to appear, calling helper's function.
Look here:
Rails view helpers in helper file

Resources