Plugin RSpec "get" problems

My “learning experience” plugin works. Not everything I have tried worked, but I have been able to find ways to do much of what I’ve been interested in having it do.

Experience has taught me that I prefer to test often and fix problems before things get more complex. I understand that developers might feel that testing is boring, or at least not as much fun as writing “real” code. But I know myself well enough that if I tell myself “I’ll do it later”, there will be a good chance I will never do it, and even if I do the task will have become so large it will be intimidating.

Hence my interest in writing QUnit and RSpec tests earlier rather than later.

I often look at examples of what works to guide my learning. Sadly, most plugins I have looked at do not have RSpec tests. Discourse itself has many, and for the most part they all pass. (jhead and svgo being the pesky exceptions for me)

I am particularly interested in finding a way for the "get"s to work.
Frustratingly, when I try a path I get a “no matching action” message, and when I try an action I get a “no matching path” message.

The tests as they are now are a bit of a mishmash. some meaningless, some that pass but not for the reason I’d hoped, and there are a lot of commented out lines.
That is, the tests are very much in a “pre-alpha newbie” state.

https://github.com/Mittineague/discourse-newpage/tree/master/spec

I imagine most of my problems result from my newbieness and hope I’m just missing something simple. I have been mostly using the Relish documentation, but mabye I should be looking elsewhere?

1 Like

Babble has tests! :smiley:

https://github.com/gdpelican/babble/blob/master/spec/controllers/topics_controller_spec.rb

I have strong opinions on testing these types of things, but I won’t bore anyone with them here. PM me if you’d like a download.

3 Likes

Thanks, I had thought that finding plugins that had QUnit tests was the proverbial “needle in a haystack” until I started looking for those with RSpec tests.

I have not done TDD, but I do appreciate the benefits that having tests can provide. And l would prefer to not “write them later” but as I go along.

Having an example should prove to be very helpful. I’ll download a copy from the repo and start studying it, then start experimenting.

One thing I found was that I had to run rspec from the discourse root directory, rather than in the plugin directory

(ie, I have to do

cd ~/workspace/discourse
rspec plugins/babble/spec

rather than

cd ~/workspace/discourse/plugins/babble
rspec spec

)

This is probably a failing of my environment or my tests somehow, but don’t have motivation to find out why.

4 Likes

Hello @gdpelican, I tried to run the babble controller specs and I got about 16 errors with the following form:

ActionController::UrlGenerationError:
No route matches {:action=>"destroy_post", :controller=>"babble/topics", :id=>"5979", :post_id=>"5727"}

Which were unexpected since the routeset was specified like this:

describe ::Babble::TopicsController do
  routes { ::Babble::Engine.routes }
end

as shown in the rspec docs for engine routes.

I must say I didn’t modify babble code and also I got the same errors with the specs of a plugin I’m writing.

What do you think could be the problem?

1 Like

Hm, not sure. I’ll have a play in a bit and see if I can repro.

You’ll need to run the plugin specs with

LOAD_PLUGINS=1 rspec plugins/babble/spec

or

rake plugin:spec["babble"]
7 Likes

That’s the proper way to run the specs, right?

However, perhaps I didn’t explain myself correctly in my previous message, but I do get the specs to run. The problem is that I get the following errors:

Failures:

  1) Babble::TopicsController post does not affect user's post count
     Failure/Error: expect { xhr :post, :create_post, raw: "I am a test post", id: topic.id }.not_to change { user.post_count }
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"create_post", :controller=>"babble/topics", :id=>"6073", :raw=>"I am a test post"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:128:in `block (4 levels) in <top (required)>'
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:128:in `block (3 levels) in <top (required)>'

  2) Babble::TopicsController post cannot create a post in a topic the user does not have access to
     Failure/Error: expect { xhr :post, :create_post, raw: "I am a test post!", id: topic.id }.not_to change { topic.posts.count }
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"create_post", :controller=>"babble/topics", :id=>"6075", :raw=>"I am a test post!"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:117:in `block (4 levels) in <top (required)>'
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:117:in `block (3 levels) in <top (required)>'

  3) Babble::TopicsController post does not allow posts from users who are not logged in
     Failure/Error: expect { xhr :post, :create_post, raw: "I am a test post", id: topic.id }.not_to change { topic.posts.count }
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"create_post", :controller=>"babble/topics", :id=>"6077", :raw=>"I am a test post"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:122:in `block (4 levels) in <top (required)>'
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:122:in `block (3 levels) in <top (required)>'

  4) Babble::TopicsController post adds a new post to the chat topic
     Failure/Error: expect { xhr :post, :create_post, raw: "I am a test post", id: topic.id }.to change { topic.posts.count }.by(1)
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"create_post", :controller=>"babble/topics", :id=>"6079", :raw=>"I am a test post"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:93:in `block (4 levels) in <top (required)>'
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:93:in `block (3 levels) in <top (required)>'

  5) Babble::TopicsController post can add a short post to the chat topic
     Failure/Error: expect { xhr :post, :create_post, raw: "Hi!", id: topic.id }.to change { topic.posts.count }.by(1)
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"create_post", :controller=>"babble/topics", :id=>"6081", :raw=>"Hi!"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:105:in `block (4 levels) in <top (required)>'
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:105:in `block (3 levels) in <top (required)>'

  6) Babble::TopicsController post does not allow posts with no content to be made
     Failure/Error: expect { xhr :post, :create_post, id: topic.id }.not_to change { topic.posts.count }
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"create_post", :controller=>"babble/topics", :id=>"6083"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:111:in `block (4 levels) in <top (required)>'
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:111:in `block (3 levels) in <top (required)>'

  7) Babble::TopicsController post returns the raw value of the post
     Failure/Error: xhr :post, :create_post, raw: "I am a test post", id: topic.id
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"create_post", :controller=>"babble/topics", :id=>"6085", :raw=>"I am a test post"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:99:in `block (3 levels) in <top (required)>'

  8) Babble::TopicsController update_post ensures the post belongs to the topic
     Failure/Error: xhr :post, :update_post, raw: raw, id: another_topic.id, post_id: topic_post.id
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"update_post", :controller=>"babble/topics", :id=>"6098", :post_id=>"5842", :raw=>"Here is an updated post!"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:201:in `block (3 levels) in <top (required)>'

  9) Babble::TopicsController update_post does not allow updates from users who are not logged in
     Failure/Error: xhr :post, :update_post, raw: raw, id: topic.id, post_id: topic_post.id
     
     ActionController::UrlGenerationError:
       No route matches {:action=>"update_post", :controller=>"babble/topics", :id=>"6099", :post_id=>"5844", :raw=>"Here is an updated post!"}
     # ./plugins/babble/spec/controllers/topics_controller_spec.rb:189:in `block (3 levels) in <top (required)>'

  10) Babble::TopicsController update_post does not allow updates to posts the user can't edit
      Failure/Error: xhr :post, :update_post, raw: raw, id: topic.id, post_id: another_post.id
      
      ActionController::UrlGenerationError:
        No route matches {:action=>"update_post", :controller=>"babble/topics", :id=>"6101", :post_id=>"5847", :raw=>"Here is an updated post!"}
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:175:in `block (3 levels) in <top (required)>'

  11) Babble::TopicsController update_post does not allow posts to be updated to no content
      Failure/Error: xhr :post, :update_post, raw: '', id: topic.id, post_id: topic_post.id
      
      ActionController::UrlGenerationError:
        No route matches {:action=>"update_post", :controller=>"babble/topics", :id=>"6103", :post_id=>"5848", :raw=>""}
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:195:in `block (3 levels) in <top (required)>'

  12) Babble::TopicsController update_post updates an existing post
      Failure/Error: expect { xhr :post, :update_post, raw: raw, id: topic.id, post_id: topic_post.id }.not_to change { topic.posts.count }
      
      ActionController::UrlGenerationError:
        No route matches {:action=>"update_post", :controller=>"babble/topics", :id=>"6105", :post_id=>"5850", :raw=>"Here is an updated post!"}
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:167:in `block (4 levels) in <top (required)>'
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:167:in `block (3 levels) in <top (required)>'

  13) Babble::TopicsController update_post allows admins to update others' posts
      Failure/Error: xhr :post, :update_post, raw: raw, id: topic.id, post_id: topic_post.id
      
      ActionController::UrlGenerationError:
        No route matches {:action=>"update_post", :controller=>"babble/topics", :id=>"6107", :post_id=>"5852", :raw=>"Here is an updated post!"}
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:183:in `block (3 levels) in <top (required)>'

  14) Babble::TopicsController destroy_post allows admins to delete others' posts
      Failure/Error: expect { xhr :post, :destroy_post, id: topic.id, post_id: target_post.id }.to change { topic.posts.count }.by(-1)
      
      ActionController::UrlGenerationError:
        No route matches {:action=>"destroy_post", :controller=>"babble/topics", :id=>"6111", :post_id=>"5858"}
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:157:in `block (4 levels) in <top (required)>'
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:157:in `block (3 levels) in <top (required)>'

  15) Babble::TopicsController destroy_post deletes an existing post
      Failure/Error: expect { xhr :post, :destroy_post, id: topic.id, post_id: target_post.id }.to_not change { topic.posts.count }
      
      ActionController::UrlGenerationError:
        No route matches {:action=>"destroy_post", :controller=>"babble/topics", :id=>"6113", :post_id=>"5861"}
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:141:in `block (4 levels) in <top (required)>'
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:141:in `block (3 levels) in <top (required)>'

  16) Babble::TopicsController destroy_post does not allow deleting of posts the user can't delete
      Failure/Error: xhr :post, :destroy_post, id: topic.id, post_id: another_post.id
      
      ActionController::UrlGenerationError:
        No route matches {:action=>"destroy_post", :controller=>"babble/topics", :id=>"6115", :post_id=>"5863"}
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:149:in `block (3 levels) in <top (required)>'

  17) Babble::TopicsController update does not allow non-admins to update topics
      Failure/Error: expect(Babble::Topic.find(id: topic.id).title).to_not eq chat_params[:title]
      
      NoMethodError:
        undefined method `find' for Babble::Topic:Class
        Did you mean?  find_by
      # ./plugins/babble/spec/controllers/topics_controller_spec.rb:301:in `block (3 levels) in <top (required)>'

Finished in 21.43 seconds (files took 7.29 seconds to load)
43 examples, 17 failures

Yes that is the right way to run the specs. The routes are not matching because the plugin isn’t being loaded in test so the routes are not drawn.

I understand. However, I run the specs that way and I still get the same errors. Also, as you can see in the output, the failing examples are 17 (that all perform post requests, by the way) from a total of 43, so there are some other routes that are matching, the specs for show or create for example.

Thank you so much for posting LOAD_PLUGINS=1
l wouldn’t have guessed that on my own.

I tried every possible syntax variation that I could find or think of and kept getting FAILs. Very frustrating.
On a positive note, the experience did spur me on to spend more time with documentation than l normally would have otherwise. :smiley: