diff --git a/app/models/relationship.rb b/app/models/relationship.rb index 10eb6c898..a920fd015 100644 --- a/app/models/relationship.rb +++ b/app/models/relationship.rb @@ -12,6 +12,7 @@ class Relationship < ApplicationRecord before_validation :set_user, on: :create before_validation :set_confirmed, if: :is_being_confirmed?, on: :update + before_validation :move_fact_check_and_report_to_main, on: :create validate :relationship_type_is_valid, :items_are_from_the_same_team validate :target_not_published_report, on: :create validate :similar_item_exists, on: :create, if: proc { |r| r.is_suggested? } @@ -366,4 +367,32 @@ def destroy_same_suggested_item def cant_be_related_to_itself errors.add(:base, I18n.t(:item_cant_be_related_to_itself)) if self.source_id == self.target_id end + + def move_fact_check_and_report_to_main + Relationship.transaction do + source = self.source + target = self.target + if source && target && source.team_id == target.team_id # Must verify since this method runs before the validation + target_report = target.get_annotations('report_design').to_a.map(&:load).last + + # If the child item has a claim/fact-check and published report but the parent item doesn't, then move the claim/fact-check/report from the child to the parent + if !source.claim_description && target.claim_description && target_report && target_report.get_field_value('state') == 'published' + # Move report + target_report.annotated_id = source.id + target_report.save! + + # Move claim/fact-check + claim_description = target.claim_description + claim_description.project_media = source + claim_description.save! + + # Clear caches + source.clear_cached_fields + target.clear_cached_fields + source.reload + target.reload + end + end + end + end end diff --git a/test/models/relationship_2_test.rb b/test/models/relationship_2_test.rb index 50ec8c3f6..cf4aca555 100644 --- a/test/models/relationship_2_test.rb +++ b/test/models/relationship_2_test.rb @@ -2,12 +2,15 @@ class Relationship2Test < ActiveSupport::TestCase def setup - super - Sidekiq::Testing.inline! + Sidekiq::Testing.fake! @team = create_team @project = create_project team: @team end + def teardown + User.current = Team.current = nil + end + test "should create relationship" do assert_difference 'Relationship.count' do create_relationship @@ -54,6 +57,7 @@ def setup end test "should destroy relationships when project media is destroyed" do + Sidekiq::Testing.inline! pm = create_project_media team: @team pm2 = create_project_media team: @team pm3 = create_project_media team: @team @@ -140,6 +144,7 @@ def setup end test "should archive or restore medias when source is archived or restored" do + Sidekiq::Testing.inline! RequestStore.store[:skip_delete_for_ever] = true s = create_project_media project: @project t1 = create_project_media project: @project @@ -159,6 +164,7 @@ def setup end test "should delete medias when source is deleted" do + Sidekiq::Testing.inline! s = create_project_media project: @project t1 = create_project_media project: @project t2 = create_project_media project: @project @@ -205,6 +211,7 @@ def setup end test "should have versions" do + Sidekiq::Testing.inline! with_versioning do u = create_user is_admin: true t = create_team @@ -243,6 +250,7 @@ def setup end test "should propagate change if source and target are swapped" do + Sidekiq::Testing.inline! u = create_user is_admin: true t = create_team with_current_user_and_team(u, t) do @@ -342,6 +350,7 @@ def setup test "should cache the name of who confirmed a similar item and store confirmation information" do RequestStore.store[:skip_cached_field_update] = false + Sidekiq::Testing.inline! t = create_team u = create_user is_admin: true pm1 = create_project_media team: t @@ -361,4 +370,54 @@ def setup r.destroy! assert_queries(0, '=') { assert_nil pm2.confirmed_as_similar_by_name } end + + test "should move fact-check from child to parent when creating relationship if child has a fact-check but parent does not" do + t = create_team + child = create_project_media team: t + create_claim_description project_media: child + parent = create_project_media team: t + relationship = nil + + # No report for any of them: No failure + assert_difference 'Relationship.count' do + assert_nothing_raised do + relationship = create_relationship source: parent, target: child, relationship_type: Relationship.confirmed_type + end + end + relationship.destroy! + + # Child has a published report, but parent doesn't: No failure; claim/fact-check/report should be moved from the child to the parent + child = ProjectMedia.find(child.id) + parent = ProjectMedia.find(parent.id) + report = publish_report(child) + claim = child.reload.claim_description + assert_not_nil report + assert_not_nil claim + assert_not_nil child.reload.claim_description + assert_not_nil child.reload.get_dynamic_annotation('report_design') + assert_nil parent.reload.claim_description + assert_nil parent.reload.get_dynamic_annotation('report_design') + assert_difference 'Relationship.count' do + assert_nothing_raised do + relationship = create_relationship source: parent, target: child, relationship_type: Relationship.confirmed_type + end + end + assert_not_nil parent.reload.claim_description + assert_not_nil parent.reload.get_dynamic_annotation('report_design') + assert_equal claim, parent.reload.claim_description + assert_equal report, parent.reload.get_dynamic_annotation('report_design') + assert_nil child.reload.claim_description + assert_nil child.reload.get_dynamic_annotation('report_design') + relationship.destroy! + + # Child has a published report, and parent has one too: Failure + child = ProjectMedia.find(child.id) + parent = ProjectMedia.find(parent.id) + publish_report(child) + assert_no_difference 'Relationship.count' do + assert_raises 'ActiveRecord::RecordInvalid' do + create_relationship source: parent, target: child, relationship_type: Relationship.confirmed_type + end + end + end end