Newer
Older
dmpopidor / test / integration / answer_locking_test.rb
require 'test_helper'

class AnswerLockingTest < ActionDispatch::IntegrationTest
  include Devise::Test::IntegrationHelpers

  setup do
    scaffold_template
    scaffold_plan
    @question = Question.create(text: 'Test question', section: @plan.template.phases.first.sections.first, 
                                question_format: QuestionFormat.where(option_based: false).first, number: 99)
                                                                        
    @collaborator = (User.first == @plan.owner ? User.last : User.first)
    
    # Make the 2nd user an editor of the plan
    Role.create!(user_id: @collaborator.id, plan_id: @plan.id, access: 4)
    @plan.reload
  end
  
  # ----------------------------------------------------------
  test 'user receives a lock notification if the answer was CREATED while they were working' do
    userA = Answer.new(user: @plan.owner, plan: @plan, question: @question, 
                       text: "Initial answer - by UserA")
    
    userB = Answer.new(user: @collaborator, plan: @plan, question: @question,
                       text: "Version conflict at onset - by UserB")
        
    # Signin as UserA and insert the new answer
    sign_in @plan.owner
    put answer_path(FastGettext.locale, userA, format: "json"), obj_to_params(userA.attributes)
    assert_response :success
    assert_equal "application/json", @response.content_type
    updated = Answer.find_by(plan: @plan, question: @question)
    assert_equal "Initial answer - by UserA", updated.text
    assert_equal @plan.owner.id, updated.user_id
    
    # Make sure the answers/locking partial is NOT displayed
    assert_not @response.body.include?(_('The following answer cannot be saved')), "expected there to be no lock error messaging"
    assert @response.body.include?(_('Answered'))
    assert @response.body.include?("#{_(' by')} #{@plan.owner.name}"), "expected the messaging to say the plan was updated by the plan owner"
    
    # Signin as UserB and try to insert the new answer but fail
    sign_in @collaborator
    put answer_path(FastGettext.locale, userB, format: "json"), obj_to_params(userB.attributes)
    assert_response :success
    assert_equal "application/json", @response.content_type
    updated = Answer.find_by(plan: @plan, question: @question)
    assert_equal "Initial answer - by UserA", updated.text
    assert_equal @plan.owner.id, updated.user_id

    # Make sure the answer-notice IS displayed
    assert @response.body.include?(_('The following answer cannot be saved')), "expected there to be lock error messaging"
    assert @response.body.include?(_('since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again.') % { name: @plan.owner.name}), "expected the messaging to STILL say the plan was updated by the plan owner"
    assert @response.body.include?(_('Answered')), "expected the messaging to include the status"
  end
  
  # ----------------------------------------------------------
  test 'user receives a lock notification if the answer was UPDATED while they were working' do
    userA = Answer.create!(user: @plan.owner, plan: @plan, question: @question, 
                           text: "Initial answer - by UserA").attributes
    userB = userA.clone

    # Signin as UserA and insert the new answer
    sign_in @plan.owner
    userA['text'] += " - Updated by userA"
    
    put answer_path(FastGettext.locale, userA['id'], format: "json"), obj_to_params(userA)
    assert_response :success
    assert_equal "application/json", @response.content_type
    updated = Answer.find_by(plan: @plan, question: @question)
    assert_equal "Initial answer - by UserA - Updated by userA", updated.text
    assert_equal @plan.owner.id, updated.user_id
    
    # Make sure the answers/locking partial is NOT displayed
    assert_not @response.body.include?(_('The following answer cannot be saved')), "expected there to be no lock error messaging"
    assert @response.body.include?(_('Answered'))
    assert @response.body.include?("#{_(' by')} #{@plan.owner.name}"), "expected the messaging to say the plan was updated by the plan owner"
    
    # Signin as UserB and try to insert the new answer but fail
    sign_in @collaborator
    userB['text'] += " - Updated by userB"
    
    put answer_path(FastGettext.locale, userB['id'], format: "json"), obj_to_params(userB)
    assert_response :success
    assert_equal "application/json", @response.content_type
    updated = Answer.find_by(plan: @plan, question: @question)
    assert_equal "Initial answer - by UserA - Updated by userA", updated.text
    assert_equal @plan.owner.id, updated.user_id

    # Make sure the answer-notice IS displayed
    assert @response.body.include?(_('The following answer cannot be saved')), "expected there to be lock error messaging"
    assert @response.body.include?(_('since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again.') % { name: @plan.owner.name}), "expected the messaging to STILL say the plan was updated by the plan owner"
    assert @response.body.include?(_('Answered')), "expected the messaging to include the status"
  end

# ----------------------------------------------------------  
  private
    def obj_to_params(attributes)
      { 
       answer: {id: attributes['id'],
                user_id: attributes['user_id'], 
                plan_id: attributes['plan_id'], 
                question_id: attributes['question_id'],
                text: attributes['text'],
                lock_version: attributes['lock_version']}
      }
    end
end