4

I am testing a controller which has actions rendering views in format .js.erb . The tests on these actions raise the following error :

Minitest::UnexpectedError: ActionController::InvalidCrossOriginRequest: Security warning: an embedded tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.

The forgery protection causes this error, as when I put an exception on these actions its ok, but I dont want to disable it.

Here is my controller :

class TasksController < ApplicationController

  def new
    # TODO add blah later
    @task = Task.new
    render 'tasks/show_form.js.erb'
  end

  def create
    # FIXME there is bug here
    @task = Task.new(task_params)
    @task.user = current_user
    authorize! :create, @task
    save_task
  end

  def edit
    @task = Task.find(params[:id])
    authorize! :edit, @task
    render 'tasks/show_form.js.erb'
  end

  def update
    @task = Task.find(params[:id])
    @task.assign_attributes(task_params)
    authorize! :update, @task
    save_task
  end

  def destroy
    @task = Task.find(params[:id])
    authorize! :destroy, @task
    @task.destroy
    @tasks = Task.accessible_by(current_ability)
  end

  private

  def save_task
    if @task.save
      @tasks = Task.accessible_by(current_ability)
      render 'tasks/hide_form.js.erb'
    else
      render 'tasks/show_form.js.erb'
    end
  end

  def task_params
    params.require(:task).permit(:title, :note, :completed)
  end
end

Here is my test for this controller :

require 'test_helper'

class TasksControllerTest < ActionDispatch::IntegrationTest
  #include Devise::Test::ControllerHelpers

  def setup
    @task = tasks(:one)
    @password = "password"
    @confirmed_user = User.create(email: "#{rand(50000)}@example.com",
                                  password: @password,
                                  confirmed_at: "2020-02-01 11:35:56")
    @unconfirmed_user = User.create(email: "#{rand(50000)}@example.com",
                                    password: @password,
                                    confirmed_at: "")
    sign_in(user: @confirmed_user, password: @password)

  end

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

  test "should create task" do
    assert_difference('Task.count') do

      post tasks_url, params: {task: {title: 'Dont fail test !'}}
    end

    assert_redirected_to task_url(Task.last)
  end

  test "should get edit" do
    get edit_task_url(@task)
    assert_response :success
  end

  test "should update task" do
    patch task_url(@task), params: {task: {title: 'updated'}}
    assert_redirected_to task_url(@task)
    article.reload
    assert_equal "updated", article.title
  end

  test "should destroy task" do
    assert_difference('Task.count', -1) do
      delete task_url(@task)
    end

    assert_redirected_to tasks_url
  end
end

Do any of you has an idea on how to correct this error ?

Thank you in advance

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
V. Déhaye
  • 493
  • 6
  • 20
  • Do you want to do cors in your app purposely, or unexpectedly happened to? If you want to do cors, how about using [rack-cors](https://github.com/cyu/rack-cors)? – YTorii Sep 20 '16 at 09:17
  • I would say unexpectedly as I'm only using my own resources. Thank you for your help, I found the solution :) – V. Déhaye Sep 20 '16 at 15:37

2 Answers2

6

You might try changing your get request to use the same mechanism that the browser would for an AJAX request, a XMLHttpRequest. You can do this in rails testing with xhr

In your case:

xhr :get, new_task_url

This means you aren't bypassing rails defaults just to get your test to pass.

John Naegle
  • 8,077
  • 3
  • 38
  • 47
-3

The solution was to put at the beginning of my controller

skip_before_action :verify_authenticity_token, :only => [:edit, :new]

Hope this can help someone

V. Déhaye
  • 493
  • 6
  • 20
  • My understanding is that this is disabling a security feature. The impact is that an attacker somehow able to compromise the page served by that action could request malicious javascript from a remote source and render it to the user. – dgmstuart Jun 18 '18 at 09:58
  • I completely agree, this was just monkey patching. – V. Déhaye Jun 22 '18 at 08:42