Newer
Older
dmpopidor / test / unit / template_test.rb
@bhavi bhavi on 23 May 2018 7 KB Ruby Upgrade v2.4.4
require 'test_helper'

class TemplateTest < ActiveSupport::TestCase

  setup do
    @org = Org.last
    
    scaffold_template
  end

  def settings(extras = {})
    {margin:    (@margin || { top: 10, bottom: 10, left: 10, right: 10 }),
     font_face: (@font_face || Settings::Template::VALID_FONT_FACES.first),
     font_size: (@font_size || 11)
    }.merge(extras)
  end

  def default_formatting
    Settings::Template::DEFAULT_SETTINGS[:formatting]
  end

  # ---------------------------------------------------
  test "required fields are required" do
    assert_not Template.new.valid?
    assert_not Template.new(version: 1, title: 'Tester').valid?, "expected the 'org' field to be required"
    assert_not Template.new(org: @org, version: 1).valid?, "expected the 'title' field to be required"
    
    # Ensure the bare minimum and complete versions are valid
    a = Template.new(org: @org, title: 'Tester')
    assert a.valid?, "expected the 'org', 'version' and 'title' fields to be enough to create an Template! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
  end

  # ---------------------------------------------------
  test "family_ids scope only returns the dmptemplate_ids for the specific Org" do
    Org.all.each do |org|
      family_ids = Template.valid.all.pluck(:dmptemplate_id).uniq
      scoped = Template.dmptemplate_ids
      assert_equal family_ids.count, scoped.count
      
      family_ids.each do |id|
        assert scoped.include?(id), "expected the family_ids scope to contain #{id} for Org: #{org.id}"
      end
      scoped.each do |id|
        assert family_ids.include?(id), "expected #{id} to be a valid dmptemplate_id for Org: #{org.id}"
      end
    end
  end

  # ---------------------------------------------------
  test "current scope only returns the most recent version for each dmptemplate_id" do
    Org.all.each do |org|
      Template.dmptemplate_ids.each do |dmptemplate_id|
        latest = Template.where(dmptemplate_id: dmptemplate_id).order(updated_at: :desc).first
        
        assert_equal latest, Template.current(dmptemplate_id), "Expected the template.id #{latest.id} to be the current record for Org: #{org.id}, dmptemplate_id: #{dmptemplate_id}"
      end
    end
  end
  
  # ---------------------------------------------------
  test "published scope only returns the current published version for each dmptemplate_id" do
    Org.all.each do |org|
      Template.dmptemplate_ids.each do |dmptemplate_id|
        latest = Template.where(dmptemplate_id: dmptemplate_id, published: true).order(updated_at: :desc).first
        if latest.nil?
          "Expected the template to have never been published" 
        else
          assert_equal latest, Template.live(dmptemplate_id), "Expected the template.id #{latest.id} to be the published record for Org: #{org.id}, dmptemplate_id: #{dmptemplate_id}"
        end
      end
    end
  end
  
  # ---------------------------------------------------
  test "deep copy" do
    verify_deep_copy(@template, ['id', 'created_at', 'updated_at'])
  end

  # ---------- has_customisations? ----------
  test "has_customisations? correctly identifies if a given org has customised the template" do
    @template.phases.first.modifiable = false
    assert @template.has_customisations?(@org.id, @template), "expected the template to have customisations if it's phase is NOT modifiable"

    @template.phases.first.modifiable = true
    assert_not @template.has_customisations?(@org.id, @template), "expected the template to NOT have customisations if it's phase is modifiable"
    
    @template.phases << Phase.new(title: 'New phase test', modifiable: false)
    assert @template.has_customisations?(@org.id, @template), "expected the template to have customisations if all of its phases is NOT modifiable"
    
    @template.phases.last.modifiable = true
    assert_not @template.has_customisations?(@org.id, @template), "expected the template to NOT have customisations if one of its phases is modifiable"
  end

  
  # ---------------------------------------------------
  test "can CRUD Template" do
    tmplt = Template.create(org: @org, version: 1, title: 'Tester')
    assert_not tmplt.id.nil?, "was expecting to be able to create a new Template!"

    tmplt.description = 'Testing an update'
    tmplt.save!
    tmplt.reload
    assert_equal 'Testing an update', tmplt.description, "Was expecting to be able to update the description of the Template!"
  
    assert tmplt.destroy!, "Was unable to delete the Template!"
  end
  
  # ---------------------------------------------------
  test "can manage has_many relationship with Phase" do
    phase = Phase.new(title: 'Test Phase', number: 2)
    verify_has_many_relationship(@template, phase, @template.phases.count)
  end
  
  # ---------------------------------------------------
  test "can manage has_many relationship with Plan" do
    plan = Plan.new(title: 'Test Plan', visibility: :is_test)
    verify_has_many_relationship(@template, plan, @template.plans.count)
  end

  # ---------------------------------------------------
  test "can manage belongs_to relationship with Org" do
    tmplt = Template.new(title: 'My test', version: 1)
    verify_belongs_to_relationship(tmplt, @org)
  end

  test 'should be invalid when links is not a hash' do
    t = Template.new(title: 'My test', version: 1, org: @org)
    t.links = []
    refute(t.valid?)
    assert_equal(['A hash is expected for links'], t.errors.messages[:links])
  end

  test 'should be invalid when links hash does not have the expected keys' do
    t = Template.new(title: 'My test', version: 1, org: @org)
    t.links = { "foo" => [], "bar" => [] }
    refute(t.valid?)
    assert_equal(['A key funder is expected for links hash', 'A key sample_plan is expected for links hash'], t.errors.messages[:links])
  end

  test 'should be invalid when links hash keys are not compliant to object links format' do
    t = Template.new(title: 'My test', version: 1, org: @org)
    t.links = { "funder" => [{}], "sample_plan" => [{}] }
    refute(t.valid?)
    assert_equal(['The key funder does not have a valid set of object links', 'The key sample_plan does not have a valid set of object links'], t.errors.messages[:links])
  end

  test 'should be valid when links hash keys are compliant to object links format' do
    t = Template.new(title: 'My test', version: 1, org: @org)
    t.links = { "funder" => [{ "link" => "foo", "text" => "bar" }], "sample_plan" => [] }
    assert(t.valid?)
    assert_nil t.errors.messages[:links]
  end
  
  test 'should return the latest customizations for the Org' do
    tA = Template.create!(title: 'My test A', version: 0, org: @org)
    tB = Template.create!(title: 'My test B', version: 0, org: @org)
    tC = Template.create!(title: 'My test C', version: 0, org: @org)
    
    # Test 1 - Multiple versions
    cAv0 = Template.create!(title: 'My test customization A', version: 0, customization_of: tA.dmptemplate_id, org: Org.first)
    cAv1 = Template.deep_copy(cAv0)
    cAv1.update_attributes(version: 1)
    
    # Test 2 - Only one version
    cBv0 = Template.create!(title: 'My test customization B', version: 0, customization_of: tB.dmptemplate_id, org: Org.first)

    # Test 3 - Make sure it always returns the latest version regardless of published statuses
    cCv0 = Template.create!(title: 'My test customization C', version: 0, customization_of: tC.dmptemplate_id, org: Org.first)
    cCv1 = Template.deep_copy(cCv0)
    cCv1.update_attributes(version: 1, published: true)
    cCv2 = Template.deep_copy(cCv1)
    cCv2.update_attributes(version: 2)
    
    latest = Template.org_customizations([tA, tB, tC].collect(&:dmptemplate_id), Org.first.id)
    assert latest.include?(cAv1), 'expected to get customization A - version 1.'
    assert latest.include?(cBv0), 'expected to get customization B - version 0.'
    assert latest.include?(cCv2), 'expected to get customization C - version 2.'
  end
end