简体   繁体   中英

Ruby on Rails controller test

I have a problem with my testing. I have used scaffolds to create my app, but changed something in my controllers. My first controller looks as follow

 class ChildrenController < ApplicationController
   before_action :set_child, only: [:show, :edit, :update, :destroy]

 require 'httparty'
 #  require 'open-uri'
  include HTTParty
  # include I18n


 def child_admin
   @children = Child.all
 end

   # GET /children
   # GET /children.json
   def index
     @children = Child.all

   end

   # GET /children/1
   # GET /children/1.json
   def show
     @child = Child.find(params[:id])
     authorize! :read, @child
   end

  # GET /children/new
   def new
     @child = Child.new
   end

  # GET /children/1/edit
   def edit
   end

   # POST /children
   # POST /children.json
   def create
     @kigas = Kiga.all
     @relations = Relation.all
     @child = Child.new child_params
     @child.user = current_user

     url = "https://maps.googleapis.com/maps/api/geocode/json?address=#{I18n.transliterate(@child.city)}+#{I18n.transliterate(@child.streed)}+#{@child.add_number}&key=AIzaSyBWwoVj5WQMN9-Ij7IJWxQL1CzuigzBsYc"
latlongchild = HTTParty.get(url)
     # puts latlongchild
     # puts latlongchild["results"].first["geometry"]["location"]
     childlat=latlongchild["results"].first["geometry"]["location"]["lat"]
     childlng=latlongchild["results"].first["geometry"]["location"]["lng"]
   #  @child.save
     respond_to do |format|
       if @child.save
         format.html { redirect_to @child, notice: 'Kind wurde erfolgreich registriert.' }
         format.json { render :show, status: :created, location: @child }
       else
         format.html { render :new }
         format.json { render json: @child.errors, status: :unprocessable_entity }
       end
     end
     @kigas.each do |kiga|
       url2 = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=#{I18n.transliterate(@child.city)}+#{I18n.transliterate(@child.streed)}+#{@child.add_number}&destinations=#{I18n.transliterate(kiga.city)}+#{I18n.transliterate(kiga.streed)}+#{kiga.add_number}&key=AIzaSyDjh9hMXm_lnIyaj_HLQpGvDcDasLjyhxk"
       response = HTTParty.get(url2)
       mesponse=response["rows"].first["elements"].first["distance"]["value"]
            url3 = "https://maps.googleapis.com/maps/api/geocode/json?address=#{I18n.transliterate(kiga.city)}+#{I18n.transliterate(kiga.streed)}+#{kiga.add_number}&key=AIzaSyBWwoVj5WQMN9-Ij7IJWxQL1CzuigzBsYc"
            response2 = HTTParty.get(url3)
            kigalat=response2["results"].first["geometry"]["location"]["lat"]
            kigalng=response2["results"].first["geometry"]["location"]["lng"]
            # puts mesponse
            # puts mysponse
            # puts @child.id
           # puts kiga.id
       @relation = Relation.new relation_params
       @relation.child_id = @child.id
       @relation.kiga_id = kiga.id
       @relation.distance = mesponse
       @relation.kigalat = kigalat
       @relation.kigalong = kigalng
       @relation.childlat = childlat
       @relation.childlong = childlng
       @relation.user_id = @child.user_id
       @relation.save
     end
   end

   # PATCH/PUT /children/1
   # PATCH/PUT /children/1.json
   def update
     respond_to do |format|
       if @child.update(child_params)
         format.html { redirect_to @child, notice: 'Kind wurde erfolgreich angepasst.' }
         format.json { render :show, status: :ok, location: @child }
       else
         format.html { render :edit }
         format.json { render json: @child.errors, status: :unprocessable_entity }
       end
     end
   end

   # DELETE /children/1
   # DELETE /children/1.json
   def destroy
     @child.destroy
     respond_to do |format|
       format.html { redirect_to children_url, notice: 'Kind wurde erfolgreich ausgetragen.' }
  format.json { head :no_content }
     end
   end

   private

     # Use callbacks to share common setup or constraints between actions.
     def set_child
       @child = Child.find(params[:id])
     end

     # Never trust parameters from the scary internet, only allow the white list through.
     def child_params
       params.require(:child).permit(:name, :city, :postalcode, :streed, :add_number, :disability, :halal, :koscha, :vegetarian, :vegan, :allday, :gender)
     end

     def set_relation
       @relation = Relation.find(params[:id])
     end

     # Never trust parameters from the scary internet, only allow the white list through.
     def relation_params
       # params.require(:relation).permit(:kiga_id, :child_id, :assignment, :preference, :distance)
     end
 end

and my controller test as follows:

 require 'test_helper'

 class ChildrenControllerTest < ActionDispatch::IntegrationTest
   setup do
     @child = children(:one)
   end

    test "should get index" do
      get children_url
      assert_response :success
    end

   test "should get new" do
     get new_child_url
     assert_response :success
   end

     test "should create child" do
       assert_difference('Child.count') do
         post children_url, params: { child: { add_number: @child.add_number, allday: @child.allday, city: @child.city, disability: @child.disability, gender: @child.gender, halal: @child.halal, koscha: @child.koscha, name: @child.name, postalcode: @child.postalcode, streed: @child.streed, vegan: @child.vegan, vegetarian: @child.vegetarian } }
       end

       assert_redirected_to child_url(Child.last)
     end

    test "should show child" do
      get child_url(@child)
      assert_response :success
    end

   test "should get edit" do
     get edit_child_url(@child)
     assert_response :success
   end

    test "should update child" do
      patch child_url(@child), params: { child: { add_number: @child.add_number, allday: @child.allday, city: @child.city, disability: @child.disability, gender: @child.gender, halal: @child.halal, koscha: @child.koscha, name: @child.name, postalcode: @child.postalcode, streed: @child.streed, vegan: @child.vegan, vegetarian: @child.vegetarian } }
      assert_redirected_to child_url(@child)
         end

   test "should destroy child" do
     assert_difference('Child.count', -1) do
       delete child_url(@child)
     end

     assert_redirected_to children_url
   end
 end

and I've also defined some abilities:

  class Ability
    include CanCan::Ability

    def initialize(user)

      if user.admin?
        can :manage, :all
        can :view, Child
        can :view, Kiga
        can :read, Kiga
        can :read, Child
        can :read, User

      elsif user.role == 'Eltern'
         can [:update, :destroy], Child do |child|
           child.user_id == user.id
         end
         can :view, Child do |child|
           child.user_id == user.id
         end

         can :read, Child do |child|
           child.user_id == user.id
         end
         can :create, Child

         can :read, Kiga

         can :results_child, Child

         can [:read, :view], Relation do |relation|
           relation.user_id == user.id
           end

     else

   end

   end
 end

I'm using test_helper and cancan for the abilities. I thought my change in the abilities destroyed my testing, because my index , show , create and update test produces errors with the following massage ActionView::Template::Error: undefined method 'admin?' for nil:NilClass ActionView::Template::Error: undefined method 'admin?' for nil:NilClass

Can someone help me and can tell me, how I have to rearrange my controller and tests? Or is there another big mistake? Thank you very much!

The user.admin? call is what's causing the error.

The ability.rb that gets generated by cancancan includes a commented out line as part of the example:

# user ||= User.new # guest user (not logged in)

This is because when you don't have a signed in user nil gets passed in to create the Ability instance.

With user ||= User.new it means that you have an actual, although not saved, user instance to interact with. Putting that line as the first in your initialize method for Ability is probably easier than making all your user checks something like if user && user.admin? .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM