From c955714613bfba93b77a94b55c8bb6db3de06d29 Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Mon, 9 Sep 2024 11:23:47 +0300 Subject: [PATCH 01/39] CSV-5225: ignore nested documents that exceeds nested_objects_limit (#2025) * CSV-5225: ignore nested documents that exceeds nested_objects_limit * CV2-5225: add tests * CV2-5225: cleanup * CV2-5225: apply nested_objects_limit on tags and requests --- app/lib/check_elastic_search.rb | 1 + app/models/annotations/tag.rb | 7 +++++++ app/models/tipline_request.rb | 5 +++++ test/controllers/elastic_search_9_test.rb | 23 ++++++++++++++++++++++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/app/lib/check_elastic_search.rb b/app/lib/check_elastic_search.rb index 00cb5681ab..35268006bb 100644 --- a/app/lib/check_elastic_search.rb +++ b/app/lib/check_elastic_search.rb @@ -82,6 +82,7 @@ def get_fresh_value(data) def add_update_nested_obj(options) return if self.disable_es_callbacks || RequestStore.store[:disable_es_callbacks] + return if options[:op] == 'create' && self.respond_to?(:hit_nested_objects_limit?) && self.hit_nested_objects_limit? model = { klass: self.class.name, id: self.id } ElasticSearchWorker.perform_in(1.second, YAML::dump(model), YAML::dump(options), 'create_update_doc_nested') end diff --git a/app/models/annotations/tag.rb b/app/models/annotations/tag.rb index d365976f03..4755b39d62 100644 --- a/app/models/annotations/tag.rb +++ b/app/models/annotations/tag.rb @@ -84,6 +84,13 @@ def self.run_bulk_create_callbacks(ids_json, pmids_json) ProjectMedia.where(id: pmids).find_each { |pm| pm.tags_as_sentence } end + def hit_nested_objects_limit? + ret = false + pm = self.project_media + ret = pm.get_annotations(self.annotation_type).count > CheckConfig.get('nested_objects_limit', 10000, :integer) unless pm.nil? + ret + end + private def get_tag_text_reference diff --git a/app/models/tipline_request.rb b/app/models/tipline_request.rb index 385f64d258..ad0fb75147 100644 --- a/app/models/tipline_request.rb +++ b/app/models/tipline_request.rb @@ -64,6 +64,11 @@ def associated_graphql_id Base64.encode64("#{self.associated_type}/#{self.associated_id}") end + def hit_nested_objects_limit? + associated = self.associated + associated.tipline_requests.count > CheckConfig.get('nested_objects_limit', 10000, :integer) + end + private def set_team_and_user diff --git a/test/controllers/elastic_search_9_test.rb b/test/controllers/elastic_search_9_test.rb index a015628a52..6493472a94 100644 --- a/test/controllers/elastic_search_9_test.rb +++ b/test/controllers/elastic_search_9_test.rb @@ -206,7 +206,7 @@ def setup test "shoud add team filter by default" do t = create_team t2 = create_team - pm1 = create_project_media team: t, quote: 'test', disable_es_callbacks: false + pm1 = create_project_media team: t, quote: 'test', disable_es_callbacks: false pm2 = create_project_media team: t2, quote: 'test', disable_es_callbacks: false ProjectMedia.where(id: [pm1.id, pm2.id]).update_all(project_id: nil) options = { @@ -230,5 +230,26 @@ def setup Team.unstub(:current) end + test "should ignore index document that exceeds nested objects limit" do + team = create_team + pm = create_project_media team: team + stub_configs({ 'nested_objects_limit' => 2 }) do + tr = create_tipline_request associated: pm, disable_es_callbacks: false + tr2 = create_tipline_request associated: pm, disable_es_callbacks: false + tr3 = create_tipline_request associated: pm, disable_es_callbacks: false + t = create_tag annotated: pm, disable_es_callbacks: false + t2 = create_tag annotated: pm, disable_es_callbacks: false + t3 = create_tag annotated: pm, disable_es_callbacks: false + sleep 2 + es = $repository.find(pm.get_es_doc_id) + requests = es['requests'] + assert_equal 2, requests.size + assert_equal [tr.id, tr2.id], requests.collect{|r| r['id']}.sort + tags = es['tags'] + assert_equal 2, tags.size + assert_equal [t.id, t2.id], tags.collect{|i| i['id']}.sort + end + end + # Please add new tests to test/controllers/elastic_search_10_test.rb end From b603a4c401ec677062a02de96cf4e8aa49ac0c52 Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Mon, 9 Sep 2024 14:04:53 +0300 Subject: [PATCH 02/39] CV2-5206: fix sentry issue (#2026) * CV2-5206: fix sentry issue * CV2-5206: fix spaces --- lib/check_search.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/check_search.rb b/lib/check_search.rb index ce8746209e..bc05bf21d0 100644 --- a/lib/check_search.rb +++ b/lib/check_search.rb @@ -225,7 +225,7 @@ def self.upload_file(file) def feed_query? if @feed.nil? - @feed = (@options['feed_id'] && Team.current.is_part_of_feed?(@options['feed_id'])) ? Feed.find(@options['feed_id']) : false + @feed = (@options['feed_id'] && Team.current&.is_part_of_feed?(@options['feed_id'])) ? Feed.find(@options['feed_id']) : false end !!@feed end From dab3b7d43c4d6a5b299a5d17814321ab817a5a88 Mon Sep 17 00:00:00 2001 From: Manu Vasconcelos <87862340+vasconsaurus@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:59:53 -0300 Subject: [PATCH 03/39] Update imported fact-check tag creation (#2027) While I was testing backlog imports locally, I noticed that the tags were being created, but not added to the fact check. This happened because we associate them with the project media (here:check-api/app/models/bot/fetch.rb ) and not the fact-check itself, and those are now separate things. Meaning, we need to add them to the fact-check itself. Relates to: 5227 PR: https://github.com/meedan/check-api/pull/2027 --- app/models/bot/fetch.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/bot/fetch.rb b/app/models/bot/fetch.rb index 915aa0ed66..32ebccdb31 100644 --- a/app/models/bot/fetch.rb +++ b/app/models/bot/fetch.rb @@ -259,6 +259,7 @@ def self.set_claim_and_fact_check(claim_review, pm, user, team) fc.title = self.get_title(claim_review).to_s fc.url = claim_review['url'].to_s fc.summary = self.get_summary(claim_review).to_s + fc.tags = claim_review['keywords'].to_s.split(',').map(&:strip).reject{ |r| r.blank? } fc.user = user fc.language = fc_language fc.publish_report = true From 7fed86c22c466af307b26ec8b406e7a4fc326e12 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Mon, 9 Sep 2024 23:34:02 -0300 Subject: [PATCH 04/39] Be able to export a full list of media clusters. (#2024) The current export limit for media lists is 10.000 because this is the maximum size of a result window in ElasticSearch. The solution is to paginate the results. Fixes: CV2-5205. --- .codeclimate.yml | 2 +- lib/check_search.rb | 82 ++++++++++++++++++++++++------------ test/lib/list_export_test.rb | 45 +++++++++++++++++--- 3 files changed, 97 insertions(+), 32 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 773f85a550..ff19a8b13d 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -10,7 +10,7 @@ checks: enabled: false method-complexity: config: - threshold: 22 + threshold: 25 method-count: config: threshold: 65 diff --git a/lib/check_search.rb b/lib/check_search.rb index bc05bf21d0..d9fbb18b2d 100644 --- a/lib/check_search.rb +++ b/lib/check_search.rb @@ -89,6 +89,10 @@ def team Team.find_by_id(team_id) end + def feed + @feed + end + def teams [] end @@ -335,40 +339,66 @@ def medias_get_search_result(query) def self.get_exported_data(query, team_id) team = Team.find(team_id) + Team.current = team search = CheckSearch.new(query, nil, team_id) + feed_sharing_only_fact_checks = (search.feed && search.feed.data_points == [1]) # Prepare the export data = [] - header = ['Claim', 'Item page URL', 'Status', 'Created by', 'Submitted at', 'Published at', 'Number of media', 'Tags'] - fields = team.team_tasks.sort - fields.each { |tt| header << tt.label } + header = nil + if feed_sharing_only_fact_checks + header = ['Fact-check title', 'Fact-check summary', 'Fact-check URL', 'Tags', 'Workspace', 'Updated at', 'Rating'] + else + header = ['Claim', 'Item page URL', 'Status', 'Created by', 'Submitted at', 'Published at', 'Number of media', 'Tags'] + fields = team.team_tasks.sort + fields.each { |tt| header << tt.label } + end data << header - # No pagination for the export - search.set_option('esoffset', 0) - search.set_option('eslimit', CheckConfig.get(:export_csv_maximum_number_of_results, 10000, :integer)) - - # Iterate through each result and generate an output row for the CSV - search.medias.find_each do |pm| - row = [ - pm.claim_description&.description, - pm.full_url, - pm.status_i18n, - pm.author_name.to_s.gsub(/ \[.*\]$/, ''), - pm.created_at.strftime("%Y-%m-%d %H:%M:%S"), - pm.published_at&.strftime("%Y-%m-%d %H:%M:%S"), - pm.linked_items_count, - pm.tags_as_sentence - ] - annotations = pm.get_annotations('task').map(&:load) - fields.each do |field| - annotation = annotations.find { |a| a.team_task_id == field.id } - answer = (annotation ? (begin annotation.first_response_obj.file_data[:file_urls].join("\n") rescue annotation.first_response.to_s end) : '') - answer = begin JSON.parse(answer).collect{ |x| x['url'] }.join(', ') rescue answer end - row << answer + # Paginate + search_after = [0] + while !search_after.empty? + result = $repository.search(_source: 'annotated_id', query: search.medias_query, sort: [{ annotated_id: { order: :asc } }], size: 10000, search_after: search_after).results + ids = result.collect{ |i| i['annotated_id'] }.uniq.compact.map(&:to_i) + + # Iterate through each result and generate an output row for the CSV + ProjectMedia.where(id: ids, team_id: search.team_condition(team_id)).find_each do |pm| + row = nil + if feed_sharing_only_fact_checks + row = [ + pm.fact_check_title, + pm.fact_check_summary, + pm.fact_check_url, + pm.tags_as_sentence, + pm.team_name, + pm.updated_at_timestamp, + pm.status + ] + else + row = [ + pm.claim_description&.description, + pm.full_url, + pm.status_i18n, + pm.author_name.to_s.gsub(/ \[.*\]$/, ''), + pm.created_at.strftime("%Y-%m-%d %H:%M:%S"), + pm.published_at&.strftime("%Y-%m-%d %H:%M:%S"), + pm.linked_items_count, + pm.tags_as_sentence + ] + annotations = pm.get_annotations('task').map(&:load) + fields.each do |field| + annotation = annotations.find { |a| a.team_task_id == field.id } + answer = (annotation ? (begin annotation.first_response_obj.file_data[:file_urls].join("\n") rescue annotation.first_response.to_s end) : '') + answer = begin JSON.parse(answer).collect{ |x| x['url'] }.join(', ') rescue answer end + row << answer + end + end + data << row end - data << row + + search_after = [ids.max].compact end + data end diff --git a/test/lib/list_export_test.rb b/test/lib/list_export_test.rb index 668797d6e6..15551ba12d 100644 --- a/test/lib/list_export_test.rb +++ b/test/lib/list_export_test.rb @@ -26,21 +26,26 @@ def teardown end end - test "should export media CSV" do + test "should export media (including child media) CSV" do + setup_elasticsearch t = create_team create_team_task team_id: t.id, fieldset: 'tasks' - 2.times { create_project_media team: t } + parent = create_project_media team: t, disable_es_callbacks: false + child = create_project_media team: t, disable_es_callbacks: false + create_relationship source_id: parent.id, target_id: child.id, relationship_type: Relationship.confirmed_type - export = ListExport.new(:media, '{}', t.id) + sleep 2 # Wait for indexing + + export = ListExport.new(:media, { show_similar: true }.to_json, t.id) csv_url = export.generate_csv_and_send_email(create_user) response = Net::HTTP.get_response(URI(csv_url)) assert_equal 200, response.code.to_i csv_content = CSV.parse(response.body, headers: true) - assert_equal 2, csv_content.size assert_equal 2, export.number_of_rows + assert_equal 2, csv_content.size end - test "should export feed CSV" do + test "should export media feed CSV" do t = create_team f = create_feed team: t 2.times { f.clusters << create_cluster } @@ -54,6 +59,36 @@ def teardown assert_equal 2, export.number_of_rows end + test "should export fact-check feed CSV" do + setup_elasticsearch + RequestStore.store[:skip_cached_field_update] = false + + pender_url = CheckConfig.get('pender_url_private') + WebMock.stub_request(:get, /#{pender_url}/).to_return(body: '{}', status: 200) + + t = create_team + 2.times do + pm = create_project_media team: t, disable_es_callbacks: false + r = publish_report(pm, {}, nil, { language: 'en', use_visual_card: false }) + r = Dynamic.find(r.id) + r.disable_es_callbacks = false + r.set_fields = { state: 'published' }.to_json + r.save! + end + ss = create_saved_search team: t + f = create_feed team: t, data_points: [1], saved_search: ss, published: true + + sleep 2 # Wait for indexing + + export = ListExport.new(:media, { feed_id: f.id, feed_view: 'fact_check' }.to_json, t.id) + csv_url = export.generate_csv_and_send_email(create_user) + response = Net::HTTP.get_response(URI(csv_url)) + assert_equal 200, response.code.to_i + csv_content = CSV.parse(response.body, headers: true) + assert_equal 2, export.number_of_rows + assert_equal 2, csv_content.size + end + test "should export fact-checks CSV" do t = create_team 2.times do From 3107813b3d8d8cb31df6812ca8050e6e0b708a44 Mon Sep 17 00:00:00 2001 From: Caio <117518+caiosba@users.noreply.github.com> Date: Mon, 9 Sep 2024 23:36:16 -0300 Subject: [PATCH 05/39] Deleting unused method --- lib/check_search.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/check_search.rb b/lib/check_search.rb index d9fbb18b2d..8093d57d20 100644 --- a/lib/check_search.rb +++ b/lib/check_search.rb @@ -60,10 +60,6 @@ def initialize(options, file = nil, team_id = Team.current&.id) 'fact_check_published_on' => 'fact_check_published_on' } - def set_option(key, value) - @options[key] = value - end - def team_condition(team_id = nil) if feed_query? feed_teams = @options['feed_team_ids'].is_a?(Array) ? (@feed.team_ids & @options['feed_team_ids']) : @feed.team_ids From 69fb57ddd687af5d1aa6d05899279af6a900c12e Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:28:13 -0300 Subject: [PATCH 06/39] Update cache key for permissions. (#2032) Fixes CV2-5153. --- app/lib/check_permissions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/check_permissions.rb b/app/lib/check_permissions.rb index 2e6d2b4f7a..3d5aa074de 100644 --- a/app/lib/check_permissions.rb +++ b/app/lib/check_permissions.rb @@ -54,7 +54,7 @@ def permissions(ability = nil, klass = self.class) if self.class.name == 'Team' role = User.current.role(self) role ||= 'authenticated' - cache_key = "team_permissions_#{self.private.to_i}_#{role}_role_20231208120701" + cache_key = "team_permissions_#{self.private.to_i}_#{role}_role_20240911175315" perms = Rails.cache.read(cache_key) if Rails.cache.exist?(cache_key) end if perms.blank? From ab0331b9042a5b25ce0388b88095d894aa5954ee Mon Sep 17 00:00:00 2001 From: Caio <117518+caiosba@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:09:38 -0300 Subject: [PATCH 07/39] Update cache key for permissions (2) --- app/lib/check_permissions.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/lib/check_permissions.rb b/app/lib/check_permissions.rb index 3d5aa074de..3b6cce194a 100644 --- a/app/lib/check_permissions.rb +++ b/app/lib/check_permissions.rb @@ -54,6 +54,7 @@ def permissions(ability = nil, klass = self.class) if self.class.name == 'Team' role = User.current.role(self) role ||= 'authenticated' + role = 'super_admin' if User.current.is_admin? cache_key = "team_permissions_#{self.private.to_i}_#{role}_role_20240911175315" perms = Rails.cache.read(cache_key) if Rails.cache.exist?(cache_key) end From 836a1270077e8578e4512070f467436b83cdc70f Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Thu, 12 Sep 2024 02:25:17 +0300 Subject: [PATCH 08/39] CV2-5191: Fix Replace by action (#2029) * CV2-5191: log replace_by action * CV2-5177: merge assignments * CV2-5177: add tests * CV2-5177: fix CC * CV2-5177: fix typo * CV2-5177: fix test coverage --- app/models/claim_description.rb | 4 ++- app/models/project_media.rb | 53 ++++++++++++++++++++++++++--- app/models/version.rb | 4 ++- test/models/project_media_5_test.rb | 20 +++++++++-- 4 files changed, 71 insertions(+), 10 deletions(-) diff --git a/app/models/claim_description.rb b/app/models/claim_description.rb index 24bed73609..64f8ff5391 100644 --- a/app/models/claim_description.rb +++ b/app/models/claim_description.rb @@ -1,4 +1,6 @@ class ClaimDescription < ApplicationRecord + attr_accessor :disable_replace_media + include Article has_paper_trail on: [:create, :update], ignore: [:updated_at, :created_at], if: proc { |_x| User.current.present? }, versions: { class_name: 'Version' } @@ -14,7 +16,7 @@ class ClaimDescription < ApplicationRecord validates_uniqueness_of :project_media_id, allow_nil: true after_commit :update_fact_check, on: [:update] after_update :update_report_status - after_update :replace_media + after_update :replace_media, unless: proc { |cd| cd.disable_replace_media } after_update :migrate_claim_and_fact_check_logs, if: proc { |cd| cd.saved_change_to_project_media_id? && !cd.project_media_id.nil? } # To avoid GraphQL conflict with name `context` diff --git a/app/models/project_media.rb b/app/models/project_media.rb index 534b506698..8fc1969578 100644 --- a/app/models/project_media.rb +++ b/app/models/project_media.rb @@ -264,6 +264,7 @@ def replace_by(new_pm, skip_send_report = false) elsif self.media.media_type != 'blank' raise I18n.t(:replace_blank_media_only) else + assignments_ids = [] ProjectMedia.transaction do # Save the new item RequestStore.store[:skip_check_ability] = true @@ -271,13 +272,19 @@ def replace_by(new_pm, skip_send_report = false) new_pm.skip_check_ability = true new_pm.channel = { main: CheckChannels::ChannelCodes::FETCH } # Point the claim and consequently the fact-check - new_pm.claim_description = self.claim_description if self.claim_description + cd = self.claim_description + if cd + cd.disable_replace_media = true + new_pm.claim_description = cd + end new_pm.save(validate: false) # To skip channel validation RequestStore.store[:skip_check_ability] = false - # All annotations from the old item should point to the new item + # Get assignment for new items + assignments_ids = begin new_pm.last_status_obj.assignments.map(&:id) rescue [] end # Remove any status and report from the new item Annotation.where(annotation_type: ['verification_status', 'report_design'], annotated_type: 'ProjectMedia', annotated_id: new_pm.id).delete_all + # All annotations from the old item should point to the new item Annotation.where(annotated_type: 'ProjectMedia', annotated_id: self.id).where.not(annotation_type: ['tag', 'task']).update_all(annotated_id: new_pm.id) # All versions from the old item should point to the new item @@ -295,14 +302,22 @@ def replace_by(new_pm, skip_send_report = false) Rails.cache.write("check_cached_field:ProjectMedia:#{new_pm.id}:creator_name", 'Import') # Apply other stuff in background - self.class.delay_for(5.seconds).apply_replace_by(self.id, new_pm.id, skip_send_report) + options = { + author_id: User.current&.id, + assignments_ids: assignments_ids, + skip_send_report: skip_send_report + } + self.class.delay_for(1.second).apply_replace_by(self.id, new_pm.id, options.to_json) end end - def self.apply_replace_by(old_pm_id, new_pm_id, skip_send_report = false) + def self.apply_replace_by(old_pm_id, new_pm_id, options_json) old_pm = ProjectMedia.find_by_id(old_pm_id) new_pm = ProjectMedia.find_by_id(new_pm_id) + options = begin JSON.parse(options_json) rescue {} end unless new_pm.nil? + # Merge assignment + new_pm.replace_merge_assignments(options['assignments_ids']) # Merge tags new_item_tags = new_pm.annotations('tag').map(&:tag) unless new_item_tags.blank? || old_pm.nil? @@ -313,13 +328,41 @@ def self.apply_replace_by(old_pm_id, new_pm_id, skip_send_report = false) Annotation.where(id: deleted_tags).delete_all end Annotation.where(annotation_type: 'tag', annotated_type: 'ProjectMedia', annotated_id: old_pm_id).update_all(annotated_id: new_pm.id) + # Log a version for replace_by action + replace_v = Version.new({ + item_type: 'ProjectMedia', + item_id: new_pm.id.to_s, + event: 'replace', + whodunnit: options['author_id'].to_s, + object_changes: { pm_id: [old_pm.id, new_pm.id] }.to_json, + associated_id: new_pm.id, + associated_type: 'ProjectMedia', + team_id: new_pm.team_id, + }) + replace_v.save! # Re-index new items in ElasticSearch new_pm.create_elasticsearch_doc_bg({ force_creation: true }) end # Destroy old item old_pm.destroy! unless old_pm.nil? # Send a published report if any - ::Bot::Smooch.send_report_from_parent_to_child(new_pm.id, new_pm.id) unless skip_send_report + ::Bot::Smooch.send_report_from_parent_to_child(new_pm.id, new_pm.id) unless options['skip_send_report'] + end + + def replace_merge_assignments(assignments_ids) + unless assignments_ids.blank? + status = self.last_status_obj + assignments_uids = status.assignments.map(&:user_id) + Assignment.where(id: assignments_ids).find_each do |as| + if assignments_uids.include?(as.user_id) + as.skip_check_ability = true + as.delete + else + as.update_columns(assigned_id: status.id) + as.send(:increase_assignments_count) + end + end + end end def method_missing(method, *args, &block) diff --git a/app/models/version.rb b/app/models/version.rb index 7c13f00601..5714b5d7e9 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -155,6 +155,8 @@ def get_associated ['ProjectMedia', self.item.claim_description.project_media_id] when 'create_explaineritem', 'destroy_explaineritem' ['ProjectMedia', self.item.project_media_id] + else + [self.associated_type, self.associated_id] end end @@ -190,7 +192,7 @@ def get_associated_from_assignment end def set_project_association - associated = self.get_associated || [nil, nil] + associated = self.get_associated self.associated_type = associated[0] self.associated_id = associated[1] end diff --git a/test/models/project_media_5_test.rb b/test/models/project_media_5_test.rb index 60c8868625..709aa4450b 100644 --- a/test/models/project_media_5_test.rb +++ b/test/models/project_media_5_test.rb @@ -899,7 +899,9 @@ def setup t = create_team u = create_user u2 = create_user + u3 = create_user create_team_user team: t, user: u2 + create_team_user team: t, user: u3 at = create_annotation_type annotation_type: 'task_response_single_choice', label: 'Task' ft1 = create_field_type field_type: 'single_choice', label: 'Single Choice' fi1 = create_field_instance annotation_type_object: at, name: 'response_task', label: 'Response', field_type_object: ft1 @@ -911,9 +913,15 @@ def setup create_team_user team: t, user: u, role: 'admin' with_current_user_and_team(u, t) do RequestStore.store[:skip_clear_cache] = true - old = create_project_media team: t, media: Blank.create!, channel: { main: CheckChannels::ChannelCodes::FETCH }, disable_es_callbacks: false + old = create_project_media team: t, media: Blank.create!, channel: { main: CheckChannels::ChannelCodes::FETCH }, disable_es_callbacks: false + cd = create_claim_description project_media: old + fc = create_fact_check claim_description: cd old_r = publish_report(old) old_s = old.last_status_obj + # assign to + s_old = Dynamic.find(old_s.id) + s_old.assigned_to_ids =[u.id, u2.id].join(',') + s_old.save! new = create_project_media team: t, media: create_uploaded_video, disable_es_callbacks: false new_r = publish_report(new) new_s = new.last_status_obj @@ -932,7 +940,7 @@ def setup # assign to s = new.last_verification_status_obj s = Dynamic.find(s.id) - s.assigned_to_ids = u2.id.to_s + s.assigned_to_ids = [u2.id, u3.id].join(',') s.save! old.replace_by(new) assert_nil ProjectMedia.find_by_id(old.id) @@ -946,13 +954,19 @@ def setup assert_equal data, new.channel assert_equal 3, new.annotations('tag').count assert_equal 2, new.annotations('comment').count + # Verify replace log entry + replace_v = Version.from_partition(new.team_id).where(event_type: 'replace_projectmedia', associated_id: new.id, associated_type: 'ProjectMedia') + assert_not_empty replace_v + # Verifiy assignment + s = new.last_verification_status_obj + assert_equal [u.id, u2.id, u3.id], s.assignments.map(&:user_id).sort # Verify ES result = $repository.find(get_es_id(new)) assert_equal [CheckChannels::ChannelCodes::FETCH], result['channel'] assert_equal [old_c.id, new_c.id], result['comments'].collect{ |c| c['id'] }.sort assert_equal [new_tag_a.id, new_tag_c.id, old_tag_b.id].sort, result['tags'].collect{ |tag| tag['id'] }.sort assert_equal [new_tt.id, new_tt2.id].sort, result['task_responses'].collect{ |task| task['id'] }.sort - assert_equal [u2.id], result['assigned_user_ids'] + assert_equal [u.id, u2.id, u3.id], result['assigned_user_ids'].sort end end From a9609601d6c32c4b30ebe58c7114fc7486c84c43 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Fri, 13 Sep 2024 16:01:14 -0300 Subject: [PATCH 09/39] Make claim/fact-check standalone when associated item is deleted (#2035) * Ticket CV2-5283: Make claim/fact-check standalone when associated item is deleted * Fixing test --- app/models/concerns/project_media_associations.rb | 2 +- test/models/project_media_test.rb | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/models/concerns/project_media_associations.rb b/app/models/concerns/project_media_associations.rb index 40378101ab..01568cf458 100644 --- a/app/models/concerns/project_media_associations.rb +++ b/app/models/concerns/project_media_associations.rb @@ -18,7 +18,7 @@ module ProjectMediaAssociations has_many :project_media_requests, dependent: :destroy has_many :cluster_project_medias, dependent: :destroy has_many :clusters, through: :cluster_project_medias - has_one :claim_description, dependent: :destroy + has_one :claim_description, dependent: :nullify belongs_to :source, optional: true has_many :tipline_requests, as: :associated has_many :explainer_items, dependent: :destroy diff --git a/test/models/project_media_test.rb b/test/models/project_media_test.rb index eb876b0d07..e2d0ed7cef 100644 --- a/test/models/project_media_test.rb +++ b/test/models/project_media_test.rb @@ -312,17 +312,19 @@ def perform(id) assert_equal 'Shared Database', pm.creator_name end - test "should delete claims and fact-checks when item is deleted" do + test "should make claims and fact-checks standalone when item is deleted" do pm = create_project_media cd = create_claim_description project_media: pm fc = create_fact_check claim_description: cd assert_difference 'ProjectMedia.count', -1 do - assert_difference 'ClaimDescription.count', -1 do - assert_difference 'FactCheck.count', -1 do + assert_no_difference 'ClaimDescription.count' do + assert_no_difference 'FactCheck.count' do pm.destroy! end end end + assert_nil cd.reload.project_media + assert_equal cd, fc.reload.claim_description end test "should delete project_media_requests and requests when item is deleted" do From e18ec057d481dac3f5462f9c885573f58c9ae4f0 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Fri, 13 Sep 2024 16:57:20 -0300 Subject: [PATCH 10/39] Adding a method `responded_at` to tipline requests (#2036) This PR adds a new data point for tipline requests, which is the first time they are responded. "Responded" means: when the tipline request received the first fact-check/report from Check. For search queries that returned results, the time is the same as the request time itself. Steps: - Add a responded_at attribute to TiplineRequest - Expose it in the respective GraphQL type - Add unit tests to it --- app/graph/types/tipline_request_type.rb | 1 + app/models/tipline_request.rb | 8 ++++++++ lib/relay.idl | 1 + public/relay.json | 14 ++++++++++++++ test/models/tipline_request_test.rb | 19 +++++++++++++++++++ 5 files changed, 43 insertions(+) diff --git a/app/graph/types/tipline_request_type.rb b/app/graph/types/tipline_request_type.rb index 80a47e14f6..7ed2a91b7a 100644 --- a/app/graph/types/tipline_request_type.rb +++ b/app/graph/types/tipline_request_type.rb @@ -13,6 +13,7 @@ class TiplineRequestType < DefaultObject field :smooch_report_correction_sent_at, GraphQL::Types::Int, null: true field :smooch_request_type, GraphQL::Types::String, null: true field :associated_graphql_id, GraphQL::Types::String, null: true + field :responded_at, GraphQL::Types::Int, null: true field :smooch_user_external_identifier, GraphQL::Types::String, null: true diff --git a/app/models/tipline_request.rb b/app/models/tipline_request.rb index ad0fb75147..7b14b383f0 100644 --- a/app/models/tipline_request.rb +++ b/app/models/tipline_request.rb @@ -18,6 +18,14 @@ def self.request_types after_commit :update_elasticsearch_field, on: :update after_commit :destroy_elasticsearch_field, on: :destroy + def returned_search_results? + self.smooch_request_type =~ /search/ + end + + def responded_at + self.returned_search_results? ? self.created_at.to_i : self.smooch_report_sent_at.to_i + end + def smooch_user_slack_channel_url return if self.smooch_data.blank? slack_channel_url = '' diff --git a/lib/relay.idl b/lib/relay.idl index 5edaad82c4..90c0493bcf 100644 --- a/lib/relay.idl +++ b/lib/relay.idl @@ -13919,6 +13919,7 @@ type TiplineRequest implements Node { dbid: Int id: ID! permissions: String + responded_at: Int smooch_data: JsonStringType smooch_report_correction_sent_at: Int smooch_report_received_at: Int diff --git a/public/relay.json b/public/relay.json index 8f9e81dfe1..f62898b0fa 100644 --- a/public/relay.json +++ b/public/relay.json @@ -73519,6 +73519,20 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "responded_at", + "description": null, + "args": [ + + ], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "smooch_data", "description": null, diff --git a/test/models/tipline_request_test.rb b/test/models/tipline_request_test.rb index 3bbfdd22c8..008ede6362 100644 --- a/test/models/tipline_request_test.rb +++ b/test/models/tipline_request_test.rb @@ -1,6 +1,13 @@ require_relative '../test_helper' class TiplineRequestTest < ActiveSupport::TestCase + def setup + User.current = Team.current = nil + end + + def teardown + end + test "should create tipline request" do assert_difference 'TiplineRequest.count' do create_tipline_request @@ -53,4 +60,16 @@ class TiplineRequestTest < ActiveSupport::TestCase tr = create_tipline_request assert_kind_of String, tr.associated_graphql_id end + + test "should return the time it was responded" do + tr = create_tipline_request smooch_request_type: 'default_requests' + assert_equal 0, tr.responded_at + + tr = create_tipline_request smooch_request_type: 'relevant_search_result_requests' + assert_equal tr.created_at.to_i, tr.responded_at + + now = Time.now.to_i + tr = create_tipline_request smooch_request_type: 'default_requests', smooch_report_sent_at: now + assert_equal now, tr.responded_at + end end From f37c8e7c4b0e951bfda944ee20266d46b7dbdc13 Mon Sep 17 00:00:00 2001 From: Caio <117518+caiosba@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:42:01 -0300 Subject: [PATCH 11/39] Ticket CV2-5238: Expanding logic for calculating the `responded_at` attribute for tipline requests --- app/models/tipline_request.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/tipline_request.rb b/app/models/tipline_request.rb index 7b14b383f0..62e5bf28d8 100644 --- a/app/models/tipline_request.rb +++ b/app/models/tipline_request.rb @@ -23,7 +23,8 @@ def returned_search_results? end def responded_at - self.returned_search_results? ? self.created_at.to_i : self.smooch_report_sent_at.to_i + report_sent_at = [self.smooch_report_received_at, self.smooch_report_update_received_at, self.smooch_report_sent_at, self.smooch_report_correction_sent_at].map(&:to_i).select{ |timestamp| timestamp > 0 }.min + self.returned_search_results? ? self.created_at.to_i : report_sent_at.to_i end def smooch_user_slack_channel_url From 1498c6671e9b804692103afe42973dabd16a53eb Mon Sep 17 00:00:00 2001 From: Jay Joshua <7008757+jayjay-w@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:00:46 +0200 Subject: [PATCH 12/39] Add filter parameter for skip_save_request to FeedResource (#2038) * Add filter parameter for skip_save_request to FeedResource This will allow callers to this API to pass the parameter to prevent saving of requests to the database. --- app/resources/api/v2/feed_resource.rb | 5 ++++- test/controllers/feeds_controller_test.rb | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/resources/api/v2/feed_resource.rb b/app/resources/api/v2/feed_resource.rb index 5ba7db8c82..2c31ed97f3 100644 --- a/app/resources/api/v2/feed_resource.rb +++ b/app/resources/api/v2/feed_resource.rb @@ -18,6 +18,7 @@ class FeedResource < BaseResource filter :after, apply: ->(records, _value, _options) { records } filter :feed_id, apply: ->(records, _value, _options) { records } filter :webhook_url, apply: ->(records, _value, _options) { records } + filter :skip_save_request, apply: ->(records, value, _options) { records } paginator :none @@ -32,6 +33,8 @@ def self.records(options = {}, skip_save_request = false) after = filters.dig(:after, 0) after = Time.parse(after) unless after.blank? feed_id = filters.dig(:feed_id, 0).to_i + skip_save_request = skip_save_request || filters.dig(:skip_save_request, 0) == 'true' + return ProjectMedia.none if team_ids.blank? || query.blank? if feed_id > 0 @@ -53,7 +56,7 @@ def self.get_results_from_feed_teams(team_ids, feed_id, query, type, after, webh RequestStore.store[:pause_database_connection] = true # Release database connection during Bot::Alegre.request_api RequestStore.store[:smooch_bot_settings] = feed.get_smooch_bot_settings.to_h results = Bot::Smooch.search_for_similar_published_fact_checks(type, query, feed.team_ids, after, feed_id) - Feed.delay({ retry: 0, queue: 'feed' }).save_request(feed_id, type, query, webhook_url, results.to_a.map(&:id)) unless skip_save_request + Feed.delay({ retry: 0, queue: 'feed' }).save_request(feed_id, type, query, webhook_url, results.to_a.map(&:id)) unless skip_save_request results end diff --git a/test/controllers/feeds_controller_test.rb b/test/controllers/feeds_controller_test.rb index cd7b60666a..b9bfde93a7 100644 --- a/test/controllers/feeds_controller_test.rb +++ b/test/controllers/feeds_controller_test.rb @@ -4,6 +4,7 @@ class FeedsControllerTest < ActionController::TestCase def setup @controller = Api::V2::FeedsController.new super + RequestStore.clear! RequestStore.store[:skip_cached_field_update] = false [FeedTeam, Feed, ProjectMediaRequest, Request].each { |klass| klass.delete_all } create_verification_status_stuff @@ -130,6 +131,17 @@ def teardown Bot::Alegre.unstub(:request) end + test "should not save request when skip_save_request is true" do + Bot::Alegre.stubs(:request).returns({}) + Sidekiq::Testing.inline! + authenticate_with_token @a + assert_no_difference 'Request.count' do + get :index, params: { filter: { type: 'text', query: 'Foo', feed_id: @f.id, skip_save_request: 'true' }} + end + assert_response :success + Bot::Alegre.unstub(:request) + end + test "should parse the full query" do Bot::Smooch.unstub(:search_for_similar_published_fact_checks) Bot::Alegre.stubs(:request).returns({}) From 5bf7c346c493beafbdc6529837132f24cd427c2a Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Tue, 17 Sep 2024 13:48:15 +0300 Subject: [PATCH 13/39] CV2-5273: fix sentry issue (#2041) --- app/models/bot/smooch.rb | 4 +++- app/models/concerns/smooch_messages.rb | 15 +++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/models/bot/smooch.rb b/app/models/bot/smooch.rb index 765a8363c7..136f065c11 100644 --- a/app/models/bot/smooch.rb +++ b/app/models/bot/smooch.rb @@ -835,7 +835,9 @@ def self.save_text_message(message) end else extra = { url: link.url } - pm = ProjectMedia.joins(:media).where('medias.url' => link.url, 'project_medias.team_id' => team.id).last + # Normalized url before query DB + url_from_pender = Link.normalized(link.url, team.get_pender_key) + pm = ProjectMedia.joins(:media).where('medias.url' => url_from_pender, 'project_medias.team_id' => team.id).last end if pm.nil? type = link.nil? ? 'Claim' : 'Link' diff --git a/app/models/concerns/smooch_messages.rb b/app/models/concerns/smooch_messages.rb index 2e8a2d590e..140670c39a 100644 --- a/app/models/concerns/smooch_messages.rb +++ b/app/models/concerns/smooch_messages.rb @@ -426,12 +426,15 @@ def relate_item_and_caption(message, associated, app_id, author, request_type, a target = self.create_project_media_from_message(message) unless target.nil? smoooch_post_save_message_actions(message, target, app_id, author, request_type, associated_obj) - r = Relationship.new - r.skip_check_ability = true - r.relationship_type = Relationship.suggested_type - r.source_id = associated.id - r.target_id = target.id - r.save! + r_exists = Relationship.where(source_id: associated.id, target_id: target.id).exists? + unless r_exists + r = Relationship.new + r.skip_check_ability = true + r.relationship_type = Relationship.suggested_type + r.source_id = associated.id + r.target_id = target.id + r.save! + end end end From 89dd5f745d789d9cabe88a87083b3fb6b9824926 Mon Sep 17 00:00:00 2001 From: Alexandre Amoedo Amorim Date: Tue, 17 Sep 2024 10:10:58 -0300 Subject: [PATCH 14/39] Sort tags alphabetically (#2039) * Sort tags alphabetically * Fix tag_texts sorting --- app/graph/types/project_media_type.rb | 2 +- app/graph/types/team_type.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/graph/types/project_media_type.rb b/app/graph/types/project_media_type.rb index 398a083944..794c033264 100644 --- a/app/graph/types/project_media_type.rb +++ b/app/graph/types/project_media_type.rb @@ -206,7 +206,7 @@ def flags field :tags, TagType.connection_type, null: true def tags - object.get_annotations('tag').map(&:load) + object.get_annotations('tag').map(&:load).sort_by { |tag| tag.tag_text.downcase } end field :comments, CommentType.connection_type, null: true diff --git a/app/graph/types/team_type.rb b/app/graph/types/team_type.rb index 2ad5021e9b..33b0c691b0 100644 --- a/app/graph/types/team_type.rb +++ b/app/graph/types/team_type.rb @@ -224,7 +224,7 @@ def sources(keyword: nil) end def tag_texts(keyword: nil) - object.tag_texts_by_keyword(keyword) + object.tag_texts_by_keyword(keyword).order('text ASC') end field :tag_texts_count, GraphQL::Types::Int, null: true do From dd49775e8c50c17d018f22ec419abea2c251bb73 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Tue, 17 Sep 2024 23:14:40 -0300 Subject: [PATCH 15/39] Make `ProjectMedia.set_original_claim` work as expected for a video URL with arguments (#2040) This PR fixes a bug with `ProjectMedia.set_original_claim` attribute for video URLs that contained arguments, for example: https://test.xyz/video.mp4?foo=bar. The item wouldn't be created, since the extension validation would fail. The fix is to use `File.ext` over the URL path, not the full URL, since the former strips the arguments, while the latter contains them. Since I'm here, I also fixed a couple of unrelated Code Climate issues. Fixes: CV2-5232. --- app/models/concerns/project_media_creators.rb | 15 ++++++++------- app/resources/api/v2/feed_resource.rb | 4 ++-- config/locales/en.yml | 1 + test/models/project_media_test.rb | 8 ++++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/app/models/concerns/project_media_creators.rb b/app/models/concerns/project_media_creators.rb index 6b4e405b7a..011bca7ef9 100644 --- a/app/models/concerns/project_media_creators.rb +++ b/app/models/concerns/project_media_creators.rb @@ -35,14 +35,15 @@ def create_original_claim if claim.match?(/\A#{URI::DEFAULT_PARSER.make_regexp(['http', 'https'])}\z/) uri = URI.parse(claim) content_type = fetch_content_type(uri) + ext = File.extname(uri.path) case content_type when /^image\// - self.media = create_media_from_url('UploadedImage', claim) + self.media = create_media_from_url('UploadedImage', claim, ext) when /^video\// - self.media = create_media_from_url('UploadedVideo', claim) + self.media = create_media_from_url('UploadedVideo', claim, ext) when /^audio\// - self.media = create_media_from_url('UploadedAudio', claim) + self.media = create_media_from_url('UploadedAudio', claim, ext) else self.media = create_link_media(claim) end @@ -56,19 +57,19 @@ def fetch_content_type(uri) response['content-type'] end - def create_media_from_url(type, url) + def create_media_from_url(type, url, ext) klass = type.constantize - file = download_file(url) + file = download_file(url, ext) m = klass.new m.file = file m.save! m end - def download_file(url) + def download_file(url, ext) raise "Invalid URL when creating media from original claim attribute" unless url =~ /\A#{URI::DEFAULT_PARSER.make_regexp(['http', 'https'])}\z/ - file = Tempfile.new(['download', File.extname(url)]) + file = Tempfile.new(['download', ext]) file.binmode file.write(URI(url).open.read) file.rewind diff --git a/app/resources/api/v2/feed_resource.rb b/app/resources/api/v2/feed_resource.rb index 2c31ed97f3..4aeaaf71f3 100644 --- a/app/resources/api/v2/feed_resource.rb +++ b/app/resources/api/v2/feed_resource.rb @@ -18,7 +18,7 @@ class FeedResource < BaseResource filter :after, apply: ->(records, _value, _options) { records } filter :feed_id, apply: ->(records, _value, _options) { records } filter :webhook_url, apply: ->(records, _value, _options) { records } - filter :skip_save_request, apply: ->(records, value, _options) { records } + filter :skip_save_request, apply: ->(records, _value, _options) { records } paginator :none @@ -56,7 +56,7 @@ def self.get_results_from_feed_teams(team_ids, feed_id, query, type, after, webh RequestStore.store[:pause_database_connection] = true # Release database connection during Bot::Alegre.request_api RequestStore.store[:smooch_bot_settings] = feed.get_smooch_bot_settings.to_h results = Bot::Smooch.search_for_similar_published_fact_checks(type, query, feed.team_ids, after, feed_id) - Feed.delay({ retry: 0, queue: 'feed' }).save_request(feed_id, type, query, webhook_url, results.to_a.map(&:id)) unless skip_save_request + Feed.delay({ retry: 0, queue: 'feed' }).save_request(feed_id, type, query, webhook_url, results.to_a.map(&:id)) unless skip_save_request results end diff --git a/config/locales/en.yml b/config/locales/en.yml index e947f62ab1..20598d446e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -81,6 +81,7 @@ en: description: 'Conclusion: the source is a sockpuppet' errors: messages: + extension_whitelist_error: extension is not supported invalid_password: Invalid password invalid_qrcode: Invalid validation code # This string is preceded by the name of the file being validated. diff --git a/test/models/project_media_test.rb b/test/models/project_media_test.rb index e2d0ed7cef..cb8de03b95 100644 --- a/test/models/project_media_test.rb +++ b/test/models/project_media_test.rb @@ -465,4 +465,12 @@ def perform(id) assert_equal 2, ProjectMedia.where(id: [pm_s.id, pm_t.id], archived: CheckArchivedFlags::FlagCodes::NONE).count assert_not_nil Relationship.where(id: r.id).last end + + test "should create item with original claim video with arguments" do + video_url = 'https://test.xyz/video.mp4?foo=bar' + WebMock.stub_request(:get, video_url).to_return(body: File.read(File.join(Rails.root, 'test', 'data', 'rails.mp4')), headers: { 'Content-Type' => 'video/mp4' }) + assert_difference 'ProjectMedia.count' do + create_project_media media: nil, set_original_claim: video_url + end + end end From 63e868440b5ed9bd52a23c99457924fb9073e491 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Wed, 18 Sep 2024 11:43:03 -0300 Subject: [PATCH 16/39] Articles "trash" feature (#2037) Allow articles (explainers and fact-checks) to be sent to / restored from the trash. Steps: - Add a trashed attribute to database, GraphQL type and GraphQL update mutation for explainers and fact-checks - Add a trashed filter to articles queries, which is false by default - When a fact-check is trashed, make sure it's detached and unpublished - When an explainer is trashed, make sure that it's detached from all items - Validate: Can't apply trashed article to item - Delete article permanently automatically after 30 days in the trash (Sidekiq scheduled job) (for fact-checks, both the claim and the fact-check must be deleted) - Add automated tests Reference: CV2-5068. --- app/graph/mutations/explainer_mutations.rb | 2 + app/graph/mutations/fact_check_mutations.rb | 1 + app/graph/types/explainer_type.rb | 1 + app/graph/types/fact_check_type.rb | 1 + app/graph/types/team_type.rb | 2 + app/models/claim_description.rb | 5 ++ app/models/concerns/article.rb | 16 ++++ app/models/explainer.rb | 10 ++- app/models/explainer_item.rb | 5 ++ app/models/fact_check.rb | 9 +++ app/models/team.rb | 6 ++ config/locales/en.yml | 1 + .../20240913210101_add_trashed_to_articles.rb | 6 ++ db/schema.rb | 4 +- lib/relay.idl | 7 +- lib/sample_data.rb | 2 +- public/relay.json | 76 +++++++++++++++++++ test/models/claim_description_test.rb | 12 +++ test/models/explainer_item_test.rb | 9 +++ test/models/explainer_test.rb | 32 ++++++++ test/models/fact_check_test.rb | 52 ++++++++++++- test/models/team_test.rb | 19 ++++- 22 files changed, 271 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20240913210101_add_trashed_to_articles.rb diff --git a/app/graph/mutations/explainer_mutations.rb b/app/graph/mutations/explainer_mutations.rb index 03c217c2e2..2a9b865f0a 100644 --- a/app/graph/mutations/explainer_mutations.rb +++ b/app/graph/mutations/explainer_mutations.rb @@ -20,6 +20,8 @@ class Create < Mutations::CreateMutation class Update < Mutations::UpdateMutation include SharedCreateAndUpdateFields + + argument :trashed, GraphQL::Types::Boolean, required: false end class Destroy < Mutations::DestroyMutation; end diff --git a/app/graph/mutations/fact_check_mutations.rb b/app/graph/mutations/fact_check_mutations.rb index b6378feabd..ee9348a86f 100644 --- a/app/graph/mutations/fact_check_mutations.rb +++ b/app/graph/mutations/fact_check_mutations.rb @@ -26,6 +26,7 @@ class Update < Mutations::UpdateMutation argument :title, GraphQL::Types::String, required: false argument :summary, GraphQL::Types::String, required: false + argument :trashed, GraphQL::Types::Boolean, required: false end class Destroy < Mutations::DestroyMutation; end diff --git a/app/graph/types/explainer_type.rb b/app/graph/types/explainer_type.rb index c27bcf75c9..33d994c5bb 100644 --- a/app/graph/types/explainer_type.rb +++ b/app/graph/types/explainer_type.rb @@ -13,4 +13,5 @@ class ExplainerType < DefaultObject field :user, UserType, null: true field :team, PublicTeamType, null: true field :tags, [GraphQL::Types::String, null: true], null: true + field :trashed, GraphQL::Types::Boolean, null: true end diff --git a/app/graph/types/fact_check_type.rb b/app/graph/types/fact_check_type.rb index 0befd82e5b..eb0f62fd4f 100644 --- a/app/graph/types/fact_check_type.rb +++ b/app/graph/types/fact_check_type.rb @@ -14,4 +14,5 @@ class FactCheckType < DefaultObject field :rating, GraphQL::Types::String, null: true field :imported, GraphQL::Types::Boolean, null: true field :report_status, GraphQL::Types::String, null: true + field :trashed, GraphQL::Types::Boolean, null: true end diff --git a/app/graph/types/team_type.rb b/app/graph/types/team_type.rb index 33b0c691b0..f8d96424af 100644 --- a/app/graph/types/team_type.rb +++ b/app/graph/types/team_type.rb @@ -306,6 +306,7 @@ def tipline_messages(uid:) argument :rating, [GraphQL::Types::String, null: true], required: false, camelize: false argument :imported, GraphQL::Types::Boolean, required: false, camelize: false # Only for fact-checks argument :target_id, GraphQL::Types::Int, required: false, camelize: false # Exclude articles already applied to the `ProjectMedia` with this ID + argument :trashed, GraphQL::Types::Boolean, required: false, camelize: false, default_value: false end def articles(**args) @@ -336,6 +337,7 @@ def articles(**args) argument :rating, [GraphQL::Types::String, null: true], required: false, camelize: false argument :imported, GraphQL::Types::Boolean, required: false, camelize: false # Only for fact-checks argument :target_id, GraphQL::Types::Int, required: false, camelize: false # Exclude articles already applied to the `ProjectMedia` with this ID + argument :trashed, GraphQL::Types::Boolean, required: false, camelize: false, default_value: false end def articles_count(**args) diff --git a/app/models/claim_description.rb b/app/models/claim_description.rb index 64f8ff5391..7e2f8fed92 100644 --- a/app/models/claim_description.rb +++ b/app/models/claim_description.rb @@ -14,6 +14,7 @@ class ClaimDescription < ApplicationRecord validates_presence_of :team validates_uniqueness_of :project_media_id, allow_nil: true + validate :cant_apply_article_to_item_if_article_is_in_the_trash after_commit :update_fact_check, on: [:update] after_update :update_report_status after_update :replace_media, unless: proc { |cd| cd.disable_replace_media } @@ -115,4 +116,8 @@ def migrate_claim_and_fact_check_logs .where.not(event: 'create').update_all(associated_id: self.project_media_id) end end + + def cant_apply_article_to_item_if_article_is_in_the_trash + errors.add(:base, I18n.t(:cant_apply_article_to_item_if_article_is_in_the_trash)) if self.project_media && self.fact_check&.trashed + end end diff --git a/app/models/concerns/article.rb b/app/models/concerns/article.rb index e4b1ed48be..ee981866b5 100644 --- a/app/models/concerns/article.rb +++ b/app/models/concerns/article.rb @@ -14,6 +14,7 @@ module Article after_commit :update_elasticsearch_data, :send_to_alegre, :notify_bots, on: [:create, :update] after_commit :destroy_elasticsearch_data, on: :destroy after_save :create_tag_texts_if_needed + after_update :schedule_for_permanent_deletion_if_sent_to_trash, if: proc { |obj| obj.is_a?(FactCheck) || obj.is_a?(Explainer) } end def text_fields @@ -68,6 +69,13 @@ def create_tag_texts_if_needed self.class.delay.create_tag_texts_if_needed(self.team_id, self.tags) if self.respond_to?(:tags) && !self.tags.blank? end + def schedule_for_permanent_deletion_if_sent_to_trash + if self.trashed && !self.trashed_before_last_save + interval = CheckConfig.get('empty_trash_interval', 30, :integer) + self.class.delay_for(interval.days, { queue: 'trash', retry: 0 }).delete_permanently(self.id) + end + end + module ClassMethods def create_tag_texts_if_needed(team_id, tags) tags.to_a.map(&:strip).each do |tag| @@ -87,5 +95,13 @@ def send_to_alegre(id) ::Bot::Alegre.send_field_to_similarity_index(obj.project_media, field) end unless obj.nil? end + + def delete_permanently(id) + obj = self.find_by_id(id) + if obj && obj.trashed + obj.destroy! + obj.claim_description.destroy! if obj.is_a?(FactCheck) + end + end end end diff --git a/app/models/explainer.rb b/app/models/explainer.rb index 5b55a57694..5e2992bd8d 100644 --- a/app/models/explainer.rb +++ b/app/models/explainer.rb @@ -19,6 +19,7 @@ class Explainer < ApplicationRecord validate :language_in_allowed_values, unless: proc { |e| e.language.blank? } after_save :update_paragraphs_in_alegre + after_update :detach_explainer_if_trashed def notify_bots # Nothing to do for Explainer @@ -57,7 +58,8 @@ def self.get_exported_data(query, team) end def self.update_paragraphs_in_alegre(id, previous_paragraphs_count, timestamp) - explainer = Explainer.find(id) + explainer = Explainer.find_by_id(id) + return if explainer.nil? # Skip if the explainer was saved since this job was created (it means that there is a more recent job) return if explainer.updated_at.to_f > timestamp @@ -131,4 +133,10 @@ def language_in_allowed_values allowed_languages << 'und' errors.add(:language, I18n.t(:"errors.messages.invalid_article_language_value")) unless allowed_languages.include?(self.language) end + + def detach_explainer_if_trashed + if self.trashed && !self.trashed_before_last_save + self.project_medias = [] + end + end end diff --git a/app/models/explainer_item.rb b/app/models/explainer_item.rb index 7fc5be1f49..0fba5d12d9 100644 --- a/app/models/explainer_item.rb +++ b/app/models/explainer_item.rb @@ -7,6 +7,7 @@ class ExplainerItem < ApplicationRecord validates_presence_of :explainer, :project_media validate :same_team + validate :cant_apply_article_to_item_if_article_is_in_the_trash def version_metadata(_changes) { explainer_title: self.explainer.title }.to_json @@ -17,4 +18,8 @@ def version_metadata(_changes) def same_team errors.add(:base, I18n.t(:explainer_and_item_must_be_from_the_same_team)) unless self.explainer&.team_id == self.project_media&.team_id end + + def cant_apply_article_to_item_if_article_is_in_the_trash + errors.add(:base, I18n.t(:cant_apply_article_to_item_if_article_is_in_the_trash)) if self.explainer&.trashed + end end diff --git a/app/models/fact_check.rb b/app/models/fact_check.rb index 5830494615..777c4787cd 100644 --- a/app/models/fact_check.rb +++ b/app/models/fact_check.rb @@ -20,6 +20,7 @@ class FactCheck < ApplicationRecord after_save :update_report, unless: proc { |fc| fc.skip_report_update || !DynamicAnnotation::AnnotationType.where(annotation_type: 'report_design').exists? || fc.project_media.blank? } after_save :update_item_status, if: proc { |fc| fc.saved_change_to_rating? } + after_update :detach_claim_if_trashed def text_fields ['fact_check_title', 'fact_check_summary'] @@ -143,4 +144,12 @@ def set_initial_rating default_rating = self.claim_description.team.verification_statuses('media', nil)['default'] self.rating = pm_rating || default_rating end + + def detach_claim_if_trashed + if self.trashed && !self.trashed_before_last_save + cd = self.claim_description + cd.project_media = nil + cd.save! + end + end end diff --git a/app/models/team.rb b/app/models/team.rb index be43ee2c7b..c1f33d07f3 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -494,6 +494,9 @@ def filtered_explainers(filters = {}) # Filter by date query = query.where(updated_at: Range.new(*format_times_search_range_filter(JSON.parse(filters[:updated_at]), nil))) unless filters[:updated_at].blank? + # Filter by trashed + query = query.where(trashed: !!filters[:trashed]) + # Filter by text query = self.filter_by_keywords(query, filters, 'Explainer') if filters[:text].to_s.size > 2 @@ -534,6 +537,9 @@ def filtered_fact_checks(filters = {}) # Filter by report status query = query.where('fact_checks.report_status' => [filters[:report_status]].flatten.map(&:to_s)) unless filters[:report_status].blank? + # Filter by trashed + query = query.where('fact_checks.trashed' => !!filters[:trashed]) + # Filter by text query = self.filter_by_keywords(query, filters) if filters[:text].to_s.size > 2 diff --git a/config/locales/en.yml b/config/locales/en.yml index 20598d446e..5994644484 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -830,6 +830,7 @@ en: send_on_must_be_in_the_future: can't be in the past. cant_delete_default_folder: The default folder can't be deleted explainer_and_item_must_be_from_the_same_team: Explainer and item must be from the same workspace. + cant_apply_article_to_item_if_article_is_in_the_trash: This article is in the trash so it can't be added to this media cluster. Please first restore it from the trash. shared_feed_imported_media_already_exist: |- No media eligible to be imported into your workspace. The media selected to import already exist in your workspace in the following items: diff --git a/db/migrate/20240913210101_add_trashed_to_articles.rb b/db/migrate/20240913210101_add_trashed_to_articles.rb new file mode 100644 index 0000000000..e3f58fa8ac --- /dev/null +++ b/db/migrate/20240913210101_add_trashed_to_articles.rb @@ -0,0 +1,6 @@ +class AddTrashedToArticles < ActiveRecord::Migration[6.1] + def change + add_column :fact_checks, :trashed, :boolean, default: false, index: true + add_column :explainers, :trashed, :boolean, default: false, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 6cd154b4ef..b92f4f4639 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_08_13_155311) do +ActiveRecord::Schema.define(version: 2024_09_13_210101) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -324,6 +324,7 @@ t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.string "tags", default: [], array: true + t.boolean "trashed", default: false t.index ["tags"], name: "index_explainers_on_tags", using: :gin t.index ["team_id"], name: "index_explainers_on_team_id" t.index ["user_id"], name: "index_explainers_on_user_id" @@ -344,6 +345,7 @@ t.integer "report_status", default: 0 t.string "rating" t.boolean "imported", default: false + t.boolean "trashed", default: false t.index ["claim_description_id"], name: "index_fact_checks_on_claim_description_id", unique: true t.index ["imported"], name: "index_fact_checks_on_imported" t.index ["language"], name: "index_fact_checks_on_language" diff --git a/lib/relay.idl b/lib/relay.idl index 90c0493bcf..f327c115ea 100644 --- a/lib/relay.idl +++ b/lib/relay.idl @@ -8265,6 +8265,7 @@ type Explainer implements Node { team: PublicTeam team_id: Int title: String + trashed: Boolean updated_at: String url: String user: User @@ -8418,6 +8419,7 @@ type FactCheck implements Node { summary: String tags: [String] title: String + trashed: Boolean updated_at: String url: String user: User @@ -13167,10 +13169,11 @@ type Team implements Node { tags: [String] target_id: Int text: String + trashed: Boolean = false updated_at: String user_ids: [Int] ): ArticleUnionConnection - articles_count(article_type: String, imported: Boolean, language: [String], publisher_ids: [Int], rating: [String], report_status: [String], standalone: Boolean, tags: [String], target_id: Int, text: String, updated_at: String, user_ids: [Int]): Int + articles_count(article_type: String, imported: Boolean, language: [String], publisher_ids: [Int], rating: [String], report_status: [String], standalone: Boolean, tags: [String], target_id: Int, text: String, trashed: Boolean = false, updated_at: String, user_ids: [Int]): Int available_newsletter_header_types: JsonStringType avatar: String check_search_spam: CheckSearch @@ -15590,6 +15593,7 @@ input UpdateExplainerInput { language: String tags: [String] title: String + trashed: Boolean url: String } @@ -15620,6 +15624,7 @@ input UpdateFactCheckInput { summary: String tags: [String] title: String + trashed: Boolean url: String } diff --git a/lib/sample_data.rb b/lib/sample_data.rb index 37c5eca8f3..a4e3499ac7 100644 --- a/lib/sample_data.rb +++ b/lib/sample_data.rb @@ -899,7 +899,7 @@ def create_claim_description(options = {}) description: random_string, context: random_string, user: options[:user] || create_user, - project_media: options[:project_media] || create_project_media + project_media: options.has_key?(:project_media) ? options[:project_media] : create_project_media }.merge(options)) end diff --git a/public/relay.json b/public/relay.json index f62898b0fa..89102460d5 100644 --- a/public/relay.json +++ b/public/relay.json @@ -44795,6 +44795,20 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "trashed", + "description": null, + "args": [ + + ], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "updated_at", "description": null, @@ -45621,6 +45635,20 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "trashed", + "description": null, + "args": [ + + ], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "updated_at", "description": null, @@ -69084,6 +69112,18 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "trashed", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null } ], "type": { @@ -69265,6 +69305,18 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "trashed", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null } ], "type": { @@ -85404,6 +85456,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "trashed", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "clientMutationId", "description": "A unique identifier for the client performing the mutation.", @@ -85584,6 +85648,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "trashed", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "clientMutationId", "description": "A unique identifier for the client performing the mutation.", diff --git a/test/models/claim_description_test.rb b/test/models/claim_description_test.rb index 2ff78762df..3a8418606d 100644 --- a/test/models/claim_description_test.rb +++ b/test/models/claim_description_test.rb @@ -197,4 +197,16 @@ def setup cd.save! assert_equal pm, cd.project_media_was end + + test "should not attach to item if fact-check is in the trash" do + t = create_team + cd = create_claim_description team: t, project_media: nil + fc = create_fact_check claim_description: cd, trashed: true + pm = create_project_media team: t + assert_raises ActiveRecord::RecordInvalid do + cd = ClaimDescription.find(cd.id) + cd.project_media = pm + cd.save! + end + end end diff --git a/test/models/explainer_item_test.rb b/test/models/explainer_item_test.rb index 39fff5a3c9..1565fd88c5 100644 --- a/test/models/explainer_item_test.rb +++ b/test/models/explainer_item_test.rb @@ -109,4 +109,13 @@ def teardown end end end + + test "should not attach to item if explainer is in the trash" do + t = create_team + pm = create_project_media team: t + ex = create_explainer team: t, trashed: true + assert_raises ActiveRecord::RecordInvalid do + ex.project_medias << pm + end + end end diff --git a/test/models/explainer_test.rb b/test/models/explainer_test.rb index a902379b6c..a74124c711 100644 --- a/test/models/explainer_test.rb +++ b/test/models/explainer_test.rb @@ -120,4 +120,36 @@ def setup pm.destroy! end end + + test "should detach from items when explainer is sent to the trash" do + Sidekiq::Testing.fake! + t = create_team + ex = create_explainer team: t + pm = create_project_media team: t + pm.explainers << ex + assert_equal [ex], pm.reload.explainers + assert_equal [pm], ex.reload.project_medias + assert_difference 'ExplainerItem.count', -1 do + ex = Explainer.find(ex.id) + ex.trashed = true + ex.save! + end + assert_equal [], pm.reload.explainers + assert_equal [], ex.reload.project_medias + end + + test "should delete after days in the trash" do + t = create_team + pm = create_project_media team: t + ex = create_explainer team: t + Sidekiq::Testing.inline! do + assert_no_difference 'ProjectMedia.count' do + assert_difference 'Explainer.count', -1 do + ex = Explainer.find(ex.id) + ex.trashed = true + ex.save! + end + end + end + end end diff --git a/test/models/fact_check_test.rb b/test/models/fact_check_test.rb index 670cd0e599..54baa29f6d 100644 --- a/test/models/fact_check_test.rb +++ b/test/models/fact_check_test.rb @@ -181,7 +181,7 @@ def setup assert_nil pm.reload.published_url d = create_dynamic_annotation annotation_type: 'report_design', annotator: u, annotated: pm, set_fields: { options: { language: 'en', use_text_message: true, title: 'Text report created title', text: 'Text report created summary', published_article_url: 'http://text.report/created' } }.to_json, action: 'save' - fc = cd.fact_check + fc = cd.reload.fact_check assert_equal 'Text report created title', pm.reload.fact_check_title assert_equal 'Text report created summary', pm.reload.fact_check_summary assert_equal 'http://text.report/created', pm.reload.published_url @@ -423,7 +423,7 @@ def setup s.status = 'verified' s.save! r = publish_report(pm) - fc = cd.fact_check + fc = cd.reload.fact_check fc.title = 'Foo Bar' fc.save! fc = fc.reload @@ -548,4 +548,52 @@ def setup fc = create_fact_check assert_not_nil fc.team end + + test "should unpublish report when fact-check is sent to the trash" do + Sidekiq::Testing.fake! + RequestStore.store[:skip_cached_field_update] = false + pm = create_project_media + cd = create_claim_description(project_media: pm) + fc = create_fact_check claim_description: cd + r = publish_report(pm) + assert_equal pm, cd.reload.project_media + assert_equal 'published', pm.reload.report_status + assert_equal 'published', fc.reload.report_status + assert_equal 'published', r.reload.data['state'] + + fc = FactCheck.find(fc.id) + fc.trashed = true + fc.save! + + assert_nil cd.reload.project_media + assert_equal 'paused', pm.reload.report_status + assert_equal 'paused', fc.reload.report_status + assert_equal 'paused', r.reload.data['state'] + + fc = FactCheck.find(fc.id) + fc.trashed = false + fc.save! + + assert_nil cd.reload.project_media + assert_equal 'paused', pm.reload.report_status + assert_equal 'paused', fc.reload.report_status + assert_equal 'paused', r.reload.data['state'] + end + + test "should delete after days in the trash" do + pm = create_project_media + cd = create_claim_description(project_media: pm) + fc = create_fact_check claim_description: cd + Sidekiq::Testing.inline! do + assert_no_difference 'ProjectMedia.count' do + assert_difference 'FactCheck.count', -1 do + assert_difference 'ClaimDescription.count', -1 do + fc = FactCheck.find(fc.id) + fc.trashed = true + fc.save! + end + end + end + end + end end diff --git a/test/models/team_test.rb b/test/models/team_test.rb index 2b0f0c176d..12023ccad7 100644 --- a/test/models/team_test.rb +++ b/test/models/team_test.rb @@ -1076,7 +1076,7 @@ def setup assert_equal 'Custom Status 2 Changed', r.reload.data.dig('options', 'status_label') end - test "should add trashed link to duplicated team" do + test "should add trash link to duplicated team" do m = create_valid_media t1 = create_team t2 = Team.duplicate(t1) @@ -1251,4 +1251,21 @@ def setup t = create_team assert_equal [], t.fact_checks.to_a end + + test "should return trashed and non-trashed articles" do + Sidekiq::Testing.fake! + t = create_team + create_explainer team: t, trashed: true + create_explainer team: t, trashed: false + create_explainer team: t, trashed: false + create_fact_check claim_description: create_claim_description(project_media: create_project_media(team: t)), trashed: true + create_fact_check claim_description: create_claim_description(project_media: create_project_media(team: t)), trashed: false + create_fact_check claim_description: create_claim_description(project_media: create_project_media(team: t)), trashed: false + assert_equal 2, t.filtered_explainers.count + assert_equal 2, t.filtered_explainers(trashed: false).count + assert_equal 1, t.filtered_explainers(trashed: true).count + assert_equal 2, t.filtered_fact_checks.count + assert_equal 2, t.filtered_fact_checks(trashed: false).count + assert_equal 1, t.filtered_fact_checks(trashed: true).count + end end From a82855ce1a0ac1eb2e790435942fe3d6e61c22d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:31:38 +0200 Subject: [PATCH 17/39] Bump google-protobuf from 3.19.6 to 3.25.5 (#2042) Bumps [google-protobuf](https://github.com/protocolbuffers/protobuf) from 3.19.6 to 3.25.5. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.19.6...v3.25.5) --- updated-dependencies: - dependency-name: google-protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 42fdb78704..c9a02a733f 100644 --- a/Gemfile +++ b/Gemfile @@ -83,7 +83,7 @@ gem 'request_store' gem 'geojsonlint' gem 'jsonpath', '~> 0.8.8' gem 'graphql-batch', '~> 0.4.2' -gem 'google-protobuf', '3.19.6' +gem 'google-protobuf', '3.25.5' gem 'concurrent-ruby', require: 'concurrent' gem 'rubyzip', '1.3.0' gem 'rack-protection', '2.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 160a12b73b..08d390edc2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -328,7 +328,7 @@ GEM google-apis-core (>= 0.4, < 2.a) google-apis-sheets_v4 (0.12.0) google-apis-core (>= 0.4, < 2.a) - google-protobuf (3.19.6) + google-protobuf (3.25.5) google_drive (3.0.7) google-apis-drive_v3 (>= 0.5.0, < 1.0.0) google-apis-sheets_v4 (>= 0.4.0, < 1.0.0) @@ -920,7 +920,7 @@ DEPENDENCIES gem-licenses geocoder (= 1.6.4) geojsonlint - google-protobuf (= 3.19.6) + google-protobuf (= 3.25.5) google_drive graphiql-rails! graphql (~> 1.11.0) From aee73289dc8f05929c85cc2df19575871a4b5d44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 16:30:03 -0300 Subject: [PATCH 18/39] Bump puma from 5.6.8 to 5.6.9 (#2045) Bumps [puma](https://github.com/puma/puma) from 5.6.8 to 5.6.9. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/compare/v5.6.8...v5.6.9) --- updated-dependencies: - dependency-name: puma dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 08d390edc2..4217108931 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -446,7 +446,7 @@ GEM net-smtp (0.4.0.1) net-protocol netrc (0.11.0) - nio4r (2.7.0) + nio4r (2.7.3) nokogiri (1.16.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) @@ -627,7 +627,7 @@ GEM phony (>= 2.18.12) promise.rb (0.7.4) public_suffix (4.0.7) - puma (5.6.8) + puma (5.6.9) nio4r (~> 2.0) pusher (2.0.2) httpclient (~> 2.8) From 637d04ee98767e9de0fb97b90d38094c0b331791 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:00:38 -0300 Subject: [PATCH 19/39] Validate maximum file size after converting audio/video file for tipline content. (#2046) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We validate the size of a file uploaded to be the header of a newsletter or resource. But, depending on the file (for example, videos and audios) they get converted to the formats and codecs accepted by WhatsApp. It’s important to also validate the file size after converting, since in some (rare) cases they can be larger than the original file. For example, when the input file is a video that uses the H.265 codec, which is usually much lighter than the H.264 output codec. Fixes: CV2-5326. --- .../concerns/tipline_content_multimedia.rb | 4 +++- app/models/concerns/tipline_content_video.rb | 6 +++++- test/data/h265-video.mp4 | Bin 0 -> 326453 bytes test/models/tipline_newsletter_test.rb | 11 +++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 test/data/h265-video.mp4 diff --git a/app/models/concerns/tipline_content_multimedia.rb b/app/models/concerns/tipline_content_multimedia.rb index 6a7c9f18a6..210ef27ea3 100644 --- a/app/models/concerns/tipline_content_multimedia.rb +++ b/app/models/concerns/tipline_content_multimedia.rb @@ -3,6 +3,7 @@ # Attached file: image, audio or video module TiplineContentMultimedia + class ConvertedFileTooLarge < StandardError; end extend ActiveSupport::Concern included do @@ -50,11 +51,12 @@ def convert_header_file_audio_or_video(type) output_path = File.join(Rails.root, 'tmp', "#{content_name}-#{type}-output-#{self.id}-#{now}.mp4") video = FFMPEG::Movie.new(input.path) video.transcode(output_path, options) + raise TiplineContentMultimedia::ConvertedFileTooLarge.new('Converted file for tipline content is too large') if (File.size(output_path).to_f / 1024000.0) > self.header_file_video_max_size path = "#{content_name}/video/#{content_name}-#{type}-#{self.id}-#{now}" CheckS3.write(path, 'video/mp4', File.read(output_path)) url = CheckS3.public_url(path) rescue StandardError => e - CheckSentry.notify(e) + CheckSentry.notify(e, class: self.class, id: self.id) ensure FileUtils.rm_f input.path FileUtils.rm_f output_path diff --git a/app/models/concerns/tipline_content_video.rb b/app/models/concerns/tipline_content_video.rb index 161d1c71ab..668247151c 100644 --- a/app/models/concerns/tipline_content_video.rb +++ b/app/models/concerns/tipline_content_video.rb @@ -4,8 +4,12 @@ module TiplineContentVideo extend ActiveSupport::Concern # MP4 less than 10 MB (WhatsApp supports 16 MB, let's be safe) + def header_file_video_max_size + 10 + end + def validate_header_file_video - self.validate_header_file(10, ['mp4'], 'errors.messages.video_too_large') + self.validate_header_file(self.header_file_video_max_size, ['mp4'], 'errors.messages.video_too_large') end def should_convert_header_video? diff --git a/test/data/h265-video.mp4 b/test/data/h265-video.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..c799f564a18870f33764ae6e251087ff288803b9 GIT binary patch literal 326453 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�`#ZxXLiTB1f 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

+^W1B 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 Date: Mon, 23 Sep 2024 14:06:52 -0300 Subject: [PATCH 20/39] =?UTF-8?q?5120=20=E2=80=93=20Create=20Tags=20in=20t?= =?UTF-8?q?he=20background=20(#2005)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context While working on API/Zapier Error: The app did not respond in-time. It may or may not have completed successfully we thought tags creation could be causing the slow response. We couldn’t pinpoint it as the cause, but it’s still a good performance improvement and should help improve the response time. So we are moving forward with it. Sidekiq’s delayed extensions were deprecated in version 5 and removed in 7. So we are taking this opportunity to create a GenericJob, and eventually substitute the instances of .delay/.delay_for we have. Implementation Notes - We created a GenericWorker. - Used that to create Tags in the background while creating a ProjectMedia. We are making sure only 1 job is created. - Pass User.current to the GenericWorker, to make sure we are logging this action - Added Sentry Notification and logging. - We created a helper method so this is easier to read. - We did so by extending Class with a module. Tests rails test test/models/tag_test.rb:288 rails test test/workers/generic_worker_test.rb rails test test/lib/generic_worker_helpers_test.rb References: 5120, 4959 PR: 2005 --- app/lib/generic_worker_helpers.rb | 9 +++ app/models/concerns/project_media_creators.rb | 8 +- app/models/project_media.rb | 14 +++- app/workers/generic_worker.rb | 18 +++++ config/initializers/class_extensions.rb | 3 + lib/sample_data.rb | 1 + test/lib/generic_worker_helpers_test.rb | 34 ++++++++ test/models/project_media_8_test.rb | 72 +++++++++++++++++ test/workers/generic_worker_test.rb | 79 +++++++++++++++++++ 9 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 app/lib/generic_worker_helpers.rb create mode 100644 app/workers/generic_worker.rb create mode 100644 config/initializers/class_extensions.rb create mode 100644 test/lib/generic_worker_helpers_test.rb create mode 100644 test/models/project_media_8_test.rb create mode 100644 test/workers/generic_worker_test.rb diff --git a/app/lib/generic_worker_helpers.rb b/app/lib/generic_worker_helpers.rb new file mode 100644 index 0000000000..0fbfeec70a --- /dev/null +++ b/app/lib/generic_worker_helpers.rb @@ -0,0 +1,9 @@ +module GenericWorkerHelpers + def run_later(klass_method, *method_args) + GenericWorker.perform_async(self.to_s, klass_method, *method_args) + end + + def run_later_in(time, klass_method, *method_args) + GenericWorker.perform_in(time, self.to_s, klass_method, *method_args) + end +end diff --git a/app/models/concerns/project_media_creators.rb b/app/models/concerns/project_media_creators.rb index 011bca7ef9..4652e01df8 100644 --- a/app/models/concerns/project_media_creators.rb +++ b/app/models/concerns/project_media_creators.rb @@ -263,7 +263,11 @@ def create_claim_description_and_fact_check fc end - def create_tags - self.set_tags.each { |tag| Tag.create!(annotated: self, tag: tag.strip, skip_check_ability: true) } if self.set_tags.is_a?(Array) + def create_tags_in_background + if self.set_tags.is_a?(Array) + project_media_id = self.id + tags_json = self.set_tags.to_json + ProjectMedia.run_later_in(1.second, 'create_tags', project_media_id, tags_json, user_id: self.user_id) + end end end diff --git a/app/models/project_media.rb b/app/models/project_media.rb index 8fc1969578..20674d674a 100644 --- a/app/models/project_media.rb +++ b/app/models/project_media.rb @@ -33,7 +33,7 @@ class ProjectMedia < ApplicationRecord before_validation :set_team_id, :set_channel, :set_project_id, on: :create before_validation :create_original_claim, if: proc { |pm| pm.set_original_claim.present? }, on: :create - after_create :create_annotation, :create_metrics_annotation, :send_slack_notification, :create_relationship, :create_team_tasks, :create_claim_description_and_fact_check, :create_tags + after_create :create_annotation, :create_metrics_annotation, :send_slack_notification, :create_relationship, :create_team_tasks, :create_claim_description_and_fact_check, :create_tags_in_background after_create :add_source_creation_log, unless: proc { |pm| pm.source_id.blank? } after_commit :apply_rules_and_actions_on_create, :set_quote_metadata, :notify_team_bots_create, on: [:create] after_commit :create_relationship, on: [:update] @@ -528,6 +528,18 @@ def add_nested_objects(ms) ms.attributes[:requests] = requests end + def self.create_tags(project_media_id, tags_json) + project_media = ProjectMedia.find_by_id(project_media_id) + + if !project_media.nil? + tags = JSON.parse(tags_json) + tags.each { |tag| Tag.create! annotated: project_media, tag: tag.strip, skip_check_ability: true } + else + error = StandardError.new("[ProjectMedia] Exception creating project media's tags in background. Project media is nil.") + CheckSentry.notify(error, project_media_id: project_media_id) + end + end + # private # # Please add private methods to app/models/concerns/project_media_private.rb diff --git a/app/workers/generic_worker.rb b/app/workers/generic_worker.rb new file mode 100644 index 0000000000..4915f97c26 --- /dev/null +++ b/app/workers/generic_worker.rb @@ -0,0 +1,18 @@ +class GenericWorker + + include Sidekiq::Worker + + def perform(klass_name, klass_method, *method_args) + klass = klass_name.constantize + options = method_args.extract_options!.with_indifferent_access + unless options.blank? + user_id = options.delete(:user_id) if options.key?(:user_id) + current_user = User.current + User.current = User.find_by_id(user_id) + klass.public_send(klass_method, *method_args, **options) + User.current = current_user + else + klass.public_send(klass_method) + end + end +end diff --git a/config/initializers/class_extensions.rb b/config/initializers/class_extensions.rb new file mode 100644 index 0000000000..b6fffb32ff --- /dev/null +++ b/config/initializers/class_extensions.rb @@ -0,0 +1,3 @@ +class Class +include GenericWorkerHelpers +end diff --git a/lib/sample_data.rb b/lib/sample_data.rb index a4e3499ac7..e7ba63368e 100644 --- a/lib/sample_data.rb +++ b/lib/sample_data.rb @@ -517,6 +517,7 @@ def create_project_media(options = {}) end options[:skip_autocreate_source] = true unless options.has_key?(:skip_autocreate_source) pm.source = create_source({ team: options[:team], skip_check_ability: true }) if options[:skip_autocreate_source] + pm.set_tags = options[:tags] if options[:tags] pm.save! create_cluster_project_media({ cluster: options[:cluster], project_media: pm}) if options[:cluster] pm.reload diff --git a/test/lib/generic_worker_helpers_test.rb b/test/lib/generic_worker_helpers_test.rb new file mode 100644 index 0000000000..11d390d999 --- /dev/null +++ b/test/lib/generic_worker_helpers_test.rb @@ -0,0 +1,34 @@ +require_relative '../test_helper' + +class GenericWorkerHelpersTest < ActionView::TestCase + def setup + require 'sidekiq/testing' + Sidekiq::Worker.clear_all + end + + def teardown + end + + test "should run a job, without raising an error, for a method that takes a hash as a parameter" do + Sidekiq::Testing.inline! + + assert_difference "Team.where(name: 'BackgroundTeam', slug: 'background-team').count" do + Team.run_later('create!', name: 'BackgroundTeam', slug: 'background-team') + end + end + + test "should run a job, without raising an error, for a method that takes standalone parameters" do + Sidekiq::Testing.inline! + + team = create_team + project = create_project team: team + pm = create_project_media project: project + + project_media_id = pm.id + tags_json = ['one', 'two', 'three'].to_json + + ProjectMedia.run_later_in(0.second, 'create_tags', project_media_id, tags_json, user_id: pm.user_id) + + assert_equal 3, pm.annotations('tag').count + end +end diff --git a/test/models/project_media_8_test.rb b/test/models/project_media_8_test.rb new file mode 100644 index 0000000000..42f9b9c41d --- /dev/null +++ b/test/models/project_media_8_test.rb @@ -0,0 +1,72 @@ +require_relative '../test_helper' + +class ProjectMedia8Test < ActiveSupport::TestCase + def setup + require 'sidekiq/testing' + Sidekiq::Worker.clear_all + end + + def teardown + end + + test ":create_tags should create tags when project media id and tags are present" do + team = create_team + project = create_project team: team + pm = create_project_media project: project + + project_media_id = pm.id + tags_json = ['one', 'two'].to_json + + assert_nothing_raised do + ProjectMedia.create_tags(project_media_id, tags_json) + end + assert_equal 2, pm.annotations('tag').count + end + + test ":create_tags should not raise an error when no project media is sent" do + project_media_id = nil + tags_json = ['one', 'two'].to_json + + assert_nothing_raised do + CheckSentry.expects(:notify).once + ProjectMedia.create_tags(project_media_id, tags_json) + end + end + + test "when creating an item with tag/tags, after_create :create_tags_in_background callback should create tags in the background" do + Sidekiq::Testing.inline! + + team = create_team + project = create_project team: team + pm = create_project_media project: project, tags: ['one'] + + assert_equal 1, pm.annotations('tag').count + end + + test "when creating an item with multiple tags, after_create :create_tags_in_background callback should only schedule one job" do + Sidekiq::Testing.fake! + + team = create_team + project = create_project team: team + + assert_nothing_raised do + create_project_media project: project, tags: ['one', 'two', 'three'] + end + assert_equal 1, GenericWorker.jobs.size + end + + test "when using :run_later_in to schedule multiple tags creation, it should only schedule one job" do + Sidekiq::Testing.fake! + + team = create_team + project = create_project team: team + pm = create_project_media project: project + + project_media_id = pm.id + tags_json = ['one', 'two', 'three'].to_json + + ProjectMedia.run_later_in(0.second, 'create_tags', project_media_id, tags_json, user_id: pm.user_id) + + assert_equal 1, GenericWorker.jobs.size + end +end diff --git a/test/workers/generic_worker_test.rb b/test/workers/generic_worker_test.rb new file mode 100644 index 0000000000..628602a0da --- /dev/null +++ b/test/workers/generic_worker_test.rb @@ -0,0 +1,79 @@ +require 'test_helper' + +class GenericWorkerTest < ActiveSupport::TestCase + def setup + require 'sidekiq/testing' + Sidekiq::Worker.clear_all + end + + def teardown + end + + test "should run a job, without raising an error, for a method that takes no parameters" do + Sidekiq::Testing.inline! + + assert_difference 'Blank.count' do + GenericWorker.perform_async('Blank', 'create!') + end + end + + test "should run a job, without raising an error, for a method that takes a hash as a parameter" do + Sidekiq::Testing.inline! + + assert_difference "Team.where(name: 'BackgroundTeam', slug: 'background-team').count" do + GenericWorker.perform_async('Team', 'create!', name: 'BackgroundTeam', slug: 'background-team') + end + end + + test "should run a job, without raising an error, for a method that takes standalone parameters" do + Sidekiq::Testing.inline! + + t = create_team + p = create_project team: t + pm = create_project_media project: p + + project_media_id = pm.id + tags_json = ['one', 'two'].to_json + + assert_difference "Tag.where(annotation_type: 'tag').count", difference = 2 do + GenericWorker.perform_async('ProjectMedia', 'create_tags', project_media_id, tags_json, user_id: pm.user_id) + end + end + + test "should schedule a job, without raising an error, for a method that takes no parameters" do + Sidekiq::Testing.fake! + + assert_nothing_raised do + GenericWorker.perform_async('Media', 'types') + end + + assert_equal 1, GenericWorker.jobs.size + end + + test "should schedule a job, without raising an error, for a method that takes a hash as a parameter" do + Sidekiq::Testing.fake! + + assert_nothing_raised do + GenericWorker.perform_async('Team', 'create!', name: 'BackgroundTeam', slug: 'background-team') + end + + assert_equal 1, GenericWorker.jobs.size + end + + test "should schedule a job, without raising an error, for a method that takes standalone parameters" do + Sidekiq::Testing.fake! + + t = create_team + p = create_project team: t + pm = create_project_media project: p + + project_media_id = pm.id + tags_json = ['one', 'two'].to_json + + assert_nothing_raised do + GenericWorker.perform_async('ProjectMedia', 'create_tags', project_media_id, tags_json, user_id: pm.user_id) + end + + assert_equal 1, GenericWorker.jobs.size + end +end From 56c1463261ba8ce6ffe4cdce67c61d6cb1bfbf8c Mon Sep 17 00:00:00 2001 From: Jay Joshua <7008757+jayjay-w@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:49:03 +0200 Subject: [PATCH 21/39] Improve IP blocking after unsuccessful logins (#2047) * Improve IP blocking after unsuccessful logins - Only add IPs to the track list on unsuccessful login - On successful login, remove IP completely from tracklist We have also moved code related to authentication blocking to devise.rb --- config/config.yml.example | 2 +- config/initializers/devise.rb | 39 +++++++++++++++++++++++++++--- config/initializers/rack_attack.rb | 23 ------------------ test/lib/check_rack_attack_test.rb | 26 ++++++++++---------- 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/config/config.yml.example b/config/config.yml.example index 44749ca977..a94a6131e2 100644 --- a/config/config.yml.example +++ b/config/config.yml.example @@ -273,7 +273,7 @@ development: &default nlu_user_rate_limit: 30 devise_maximum_attempts: 5 devise_unlock_accounts_after: 1 - login_rate_limit: 10 + login_block_limit: 100 api_rate_limit: 100 export_csv_maximum_number_of_results: 10000 export_csv_expire: 604800 # Seconds: Default is 7 days diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 795bf0eb2e..e358463912 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -51,10 +51,43 @@ def http_auth_body config.mailer = 'DeviseMailer' config.invite_for = 1.month + extract_client_ip = Proc.new do |request| + if request.env['HTTP_CF_CONNECTING_IP'] + request.env['HTTP_CF_CONNECTING_IP'].split(',').first.strip + else + request.ip + end + end + Warden::Manager.after_authentication do |user, auth, opts| - @redis = Redis.new(REDIS_CONFIG) - ip = auth.request.ip - @redis.decr("track:#{ip}") + redis = Redis.new(REDIS_CONFIG) + request = auth.request + ip = extract_client_ip.call(request) + redis.del("track:#{ip}") + end + + Warden::Manager.before_failure do |env, opts| + if opts[:attempted_path] == '/api/users/sign_in' + redis = Redis.new(REDIS_CONFIG) + request = Rack::Request.new(env) + ip = extract_client_ip.call(request) + + begin + count = redis.incr("track:#{ip}") + redis.expire("track:#{ip}", 3600) + redis.set("track:#{ip}", 0) if count.to_i < 0 + + login_block_limit = CheckConfig.get('login_block_limit', 100, :integer) + + # Add IP to blocklist if count exceeds the threshold + if count.to_i >= login_block_limit + redis.set("block:#{ip}", true) # No expiration, IP is blocked + Rails.logger.info("IP #{ip} has been blocked after #{count} failed login attempts.") + end + rescue => e + Rails.logger.error("Warden before_failure Error: #{e.message}") + end + end end end diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index ba10bb09da..bc7dc20962 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -27,29 +27,6 @@ def self.authenticated?(req) redis.get("block:#{real_ip(req)}") == "true" end - # Track excessive login attempts for permanent blocking - track('track excessive logins/ip') do |req| - if req.path == '/api/users/sign_in' && req.post? - ip = real_ip(req) - begin - # Increment the counter for the IP and check if it should be blocked - count = redis.incr("track:#{ip}") - redis.expire("track:#{ip}", 3600) # Set the expiration time to 1 hour - - redis.set("track:#{ip}", 0) if count < 0 - - # Add IP to blocklist if count exceeds the threshold - if count.to_i >= CheckConfig.get('login_block_limit', 100, :integer) - redis.set("block:#{ip}", true) # No expiration - end - rescue => e - Rails.logger.error("Rack::Attack Error: #{e.message}") - end - - ip - end - end - # Response to blocked requests self.blocklisted_responder = lambda do |req| [403, {}, ['Blocked - Your IP has been permanently blocked due to suspicious activity.']] diff --git a/test/lib/check_rack_attack_test.rb b/test/lib/check_rack_attack_test.rb index efd8a46466..b8278bf39b 100644 --- a/test/lib/check_rack_attack_test.rb +++ b/test/lib/check_rack_attack_test.rb @@ -87,41 +87,41 @@ def real_ip(request) end test "should not increment counter on successful login" do - stub_configs({ 'login_block_limit' => 3 }) do + stub_configs({ 'login_block_limit' => 2 }) do password = random_complex_password user = create_user password: password user_params = { api_user: { email: user.email, password: password } } - # Successful logins - 2.times do + 3.times do post api_user_session_path, params: user_params, as: :json assert_response :success end ip = real_ip(@request) counter_value = @redis.get("track:#{ip}") - assert_equal "0", counter_value, "Counter should not be incremented for successful logins" + assert_nil counter_value, "Counter should not exist after successful logins" + end + end - delete destroy_api_user_session_path, as: :json - assert_response :success + test "should block IP after excessive invalid login attempts" do + stub_configs({ 'login_block_limit' => 2 }) do + password = random_complex_password + user = create_user password: password - # Unsuccessful login attempts 2.times do post api_user_session_path, params: { api_user: { email: user.email, password: 'wrong_password' } }, as: :json assert_response :unauthorized end - # Check counter value after unsuccessful logins + ip = real_ip(@request) counter_value = @redis.get("track:#{ip}") assert_equal "2", counter_value, "Counter should be incremented for unsuccessful logins" - # Ensure that the IP is not blocked after successful logins - post api_user_session_path, params: user_params, as: :json - assert_response :success - - # Subsequent unsuccessful login attempts should result in a block + # Subsequent unsuccessful login attempts should result in a blocked IP post api_user_session_path, params: { api_user: { email: user.email, password: 'wrong_password' } }, as: :json assert_response :forbidden + + assert_equal "true", @redis.get("block:#{ip}") end end end From 27270fc5a9c878447b87179ca04981b565b552ca Mon Sep 17 00:00:00 2001 From: Jay Joshua <7008757+jayjay-w@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:49:22 +0200 Subject: [PATCH 22/39] Allow deletion of api keys with media (#2044) Allow deletion of API keys even if the key's user has been used to create media. --- app/models/api_key.rb | 12 +++++++++++- app/models/concerns/user_private.rb | 3 +-- app/models/user.rb | 5 +++++ test/models/api_key_test.rb | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/models/api_key.rb b/app/models/api_key.rb index 3a7adcd977..f48060d2b1 100644 --- a/app/models/api_key.rb +++ b/app/models/api_key.rb @@ -16,7 +16,9 @@ class ApiKey < ApplicationRecord validate :validate_team_api_keys_limit, on: :create - has_one :bot_user, dependent: :destroy + has_one :bot_user + + after_destroy :delete_bot_user # Reimplement this method in your application def self.applications @@ -52,6 +54,14 @@ def create_bot_user end end + def delete_bot_user + if bot_user.present? && bot_user.owns_media? + bot_user.update(api_key_id: nil) + else + bot_user.destroy + end + end + def set_user_and_team self.user = User.current unless User.current.nil? self.team = Team.current unless Team.current.nil? diff --git a/app/models/concerns/user_private.rb b/app/models/concerns/user_private.rb index 8c0d6a0639..c48d1d8b99 100644 --- a/app/models/concerns/user_private.rb +++ b/app/models/concerns/user_private.rb @@ -86,8 +86,7 @@ def set_blank_email_for_unconfirmed_user end def can_destroy_user - count = ProjectMedia.where(user_id: self.id).count - throw :abort if count > 0 + throw :abort if owns_media? end def set_user_notification_settings(type, enabled) diff --git a/app/models/user.rb b/app/models/user.rb index 9c226d378d..94167341d6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -435,6 +435,11 @@ def self.reset_change_password(inputs) user end + def owns_media? + ProjectMedia.where(user_id: self.id).count > 0 + end + + # private # # Please add private methods to app/models/concerns/user_private.rb diff --git a/test/models/api_key_test.rb b/test/models/api_key_test.rb index 683b3e223b..9b2669457c 100644 --- a/test/models/api_key_test.rb +++ b/test/models/api_key_test.rb @@ -64,4 +64,22 @@ class ApiKeyTest < ActiveSupport::TestCase end end end + + test "should delete API key even if key's user has been used to create media" do + a = create_api_key + b = create_bot_user + b.api_key = a + b.save! + pm = create_project_media user: b + + assert_equal b, pm.user + + assert_difference 'ApiKey.count', -1 do + a.destroy + end + + assert_raises ActiveRecord::RecordNotFound do + ApiKey.find(a.id) + end + end end From 8779b3279cc4510f46279409ec0b3ddf3c1e2052 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:14:54 -0300 Subject: [PATCH 23/39] Need to split the maximum size for tipline content video files. (#2048) We need one maximum size for the Check upload and another one that is actually the maximum size supported by WhatsApp. Fixes: CV2-5326. --- app/models/concerns/tipline_content_multimedia.rb | 2 +- app/models/concerns/tipline_content_video.rb | 13 +++++++++---- config/config.yml.example | 2 ++ test/models/tipline_newsletter_test.rb | 3 ++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/models/concerns/tipline_content_multimedia.rb b/app/models/concerns/tipline_content_multimedia.rb index 210ef27ea3..94fe7af856 100644 --- a/app/models/concerns/tipline_content_multimedia.rb +++ b/app/models/concerns/tipline_content_multimedia.rb @@ -51,7 +51,7 @@ def convert_header_file_audio_or_video(type) output_path = File.join(Rails.root, 'tmp', "#{content_name}-#{type}-output-#{self.id}-#{now}.mp4") video = FFMPEG::Movie.new(input.path) video.transcode(output_path, options) - raise TiplineContentMultimedia::ConvertedFileTooLarge.new('Converted file for tipline content is too large') if (File.size(output_path).to_f / 1024000.0) > self.header_file_video_max_size + raise TiplineContentMultimedia::ConvertedFileTooLarge.new('Converted file for tipline content is too large') if (File.size(output_path).to_f / 1024000.0) > self.header_file_video_max_size_whatsapp path = "#{content_name}/video/#{content_name}-#{type}-#{self.id}-#{now}" CheckS3.write(path, 'video/mp4', File.read(output_path)) url = CheckS3.public_url(path) diff --git a/app/models/concerns/tipline_content_video.rb b/app/models/concerns/tipline_content_video.rb index 668247151c..9b67c601d1 100644 --- a/app/models/concerns/tipline_content_video.rb +++ b/app/models/concerns/tipline_content_video.rb @@ -3,13 +3,18 @@ module TiplineContentVideo extend ActiveSupport::Concern - # MP4 less than 10 MB (WhatsApp supports 16 MB, let's be safe) - def header_file_video_max_size - 10 + # Max size that WhatsApp supports + def header_file_video_max_size_whatsapp + CheckConfig.get(:header_file_video_max_size_whatsapp, 16, :integer) + end + + # Max size for Check (we need to convert it to H.264, so let's be safe and use a value less than what WhatsApp supports) + def header_file_video_max_size_check + CheckConfig.get(:header_file_video_max_size_check, 10, :integer) end def validate_header_file_video - self.validate_header_file(self.header_file_video_max_size, ['mp4'], 'errors.messages.video_too_large') + self.validate_header_file(self.header_file_video_max_size_check, ['mp4'], 'errors.messages.video_too_large') end def should_convert_header_video? diff --git a/config/config.yml.example b/config/config.yml.example index a94a6131e2..506fe4156d 100644 --- a/config/config.yml.example +++ b/config/config.yml.example @@ -277,6 +277,8 @@ development: &default api_rate_limit: 100 export_csv_maximum_number_of_results: 10000 export_csv_expire: 604800 # Seconds: Default is 7 days + header_file_video_max_size_whatsapp: 16 # Megabytes + header_file_video_max_size_check: 10 # Megabytes, should be less than WhatsApp limit # Session # diff --git a/test/models/tipline_newsletter_test.rb b/test/models/tipline_newsletter_test.rb index 4f9dfcd9cb..a209216c7c 100644 --- a/test/models/tipline_newsletter_test.rb +++ b/test/models/tipline_newsletter_test.rb @@ -484,7 +484,8 @@ def teardown # This test file is 300 KB, but 1.6 MB after converting WebMock.stub_request(:get, /:9000/).to_return(body: File.read(File.join(Rails.root, 'test', 'data', 'h265-video.mp4'))) TiplineNewsletter.any_instance.stubs(:new_file_uploaded?).returns(true) - TiplineNewsletter.any_instance.stubs(:header_file_video_max_size).returns(1) # Maximum 1 MB + TiplineNewsletter.any_instance.stubs(:header_file_video_max_size_check).returns(2) # Maximum 2 MB + TiplineNewsletter.any_instance.stubs(:header_file_video_max_size_whatsapp).returns(1) # Maximum 1 MB CheckSentry.stubs(:notify).once Sidekiq::Testing.inline! do create_tipline_newsletter header_type: 'video', header_file: 'h265-video.mp4' From 63da4c30d8a90c5ff7f125ca0896acdb60b535a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 21:24:16 +0200 Subject: [PATCH 24/39] Bump rexml from 3.3.3 to 3.3.6 (#2003) Bumps [rexml](https://github.com/ruby/rexml) from 3.3.3 to 3.3.6. - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.3.3...v3.3.6) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4217108931..08737381e5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -726,7 +726,7 @@ GEM mime-types (>= 1.16, < 4.0) netrc (~> 0.8) retriable (3.1.2) - rexml (3.3.3) + rexml (3.3.6) strscan rotp (6.3.0) rqrcode (2.1.1) From 0c7e2ab7a4c7fc368832ce07599f312973f47850 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 17:13:12 -0300 Subject: [PATCH 25/39] Bump webrick from 1.7.0 to 1.8.2 (#2050) Bumps [webrick](https://github.com/ruby/webrick) from 1.7.0 to 1.8.2. - [Release notes](https://github.com/ruby/webrick/releases) - [Commits](https://github.com/ruby/webrick/compare/v1.7.0...v1.8.2) --- updated-dependencies: - dependency-name: webrick dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 08737381e5..49626f6677 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -873,7 +873,7 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.7.0) + webrick (1.8.2) webrobots (0.1.2) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) From 00f575f9a574b48532386caad5a88d08e0e5a59d Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Wed, 25 Sep 2024 08:46:58 +0300 Subject: [PATCH 26/39] CV2-5138: Data Dashboard: Write and analyze queries (#2033) * CV2-5138: initiate a class for data points * CV2-5138: add extra data points * CV2-5138: add newsletters_sent report * CV2-5138: add users report * CV2-5138: add top cluster and top media tags * CV2-5138: add users data * CV2-5138: more updates for user data * CV2-5138: apply PR comments * CV2-5138: add tests * CV2-5138: add more index to improve performance * CV2-5138: update schema.rb file * CV2-5138: fix CC * CV2-5138: test coverage --- ...index_to_created_at_for_tipline_request.rb | 10 + ...index_to_created_at_for_tipline_message.rb | 10 + ...24_add_created_at_index_for_data_points.rb | 7 + db/schema.rb | 17 +- lib/check_data_points.rb | 149 +++++++++++++++ lib/check_search.rb | 2 +- lib/sample_data.rb | 12 ++ test/lib/check_data_points_test.rb | 177 ++++++++++++++++++ 8 files changed, 382 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20240924121509_add_index_to_created_at_for_tipline_request.rb create mode 100644 db/migrate/20240924121533_add_index_to_created_at_for_tipline_message.rb create mode 100644 db/migrate/20240924130424_add_created_at_index_for_data_points.rb create mode 100644 lib/check_data_points.rb create mode 100644 test/lib/check_data_points_test.rb diff --git a/db/migrate/20240924121509_add_index_to_created_at_for_tipline_request.rb b/db/migrate/20240924121509_add_index_to_created_at_for_tipline_request.rb new file mode 100644 index 0000000000..7d780e1f3f --- /dev/null +++ b/db/migrate/20240924121509_add_index_to_created_at_for_tipline_request.rb @@ -0,0 +1,10 @@ +class AddIndexToCreatedAtForTiplineRequest < ActiveRecord::Migration[6.1] + def change + execute "CREATE INDEX tipline_request_created_at_year ON tipline_requests (date_trunc('year', created_at))" + execute "CREATE INDEX tipline_request_created_at_quarter ON tipline_requests (date_trunc('quarter', created_at))" + execute "CREATE INDEX tipline_request_created_at_month ON tipline_requests (date_trunc('month', created_at))" + execute "CREATE INDEX tipline_request_created_at_week ON tipline_requests (date_trunc('week', created_at))" + execute "CREATE INDEX tipline_request_created_at_day ON tipline_requests (date_trunc('day', created_at))" + add_index :tipline_requests, :created_at + end +end diff --git a/db/migrate/20240924121533_add_index_to_created_at_for_tipline_message.rb b/db/migrate/20240924121533_add_index_to_created_at_for_tipline_message.rb new file mode 100644 index 0000000000..9209bccc63 --- /dev/null +++ b/db/migrate/20240924121533_add_index_to_created_at_for_tipline_message.rb @@ -0,0 +1,10 @@ +class AddIndexToCreatedAtForTiplineMessage < ActiveRecord::Migration[6.1] + def change + execute "CREATE INDEX tipline_message_created_at_year ON tipline_messages (date_trunc('year', created_at))" + execute "CREATE INDEX tipline_message_created_at_quarter ON tipline_messages (date_trunc('quarter', created_at))" + execute "CREATE INDEX tipline_message_created_at_month ON tipline_messages (date_trunc('month', created_at))" + execute "CREATE INDEX tipline_message_created_at_week ON tipline_messages (date_trunc('week', created_at))" + execute "CREATE INDEX tipline_message_created_at_day ON tipline_messages (date_trunc('day', created_at))" + add_index :tipline_messages, :created_at + end +end diff --git a/db/migrate/20240924130424_add_created_at_index_for_data_points.rb b/db/migrate/20240924130424_add_created_at_index_for_data_points.rb new file mode 100644 index 0000000000..4a422c05ac --- /dev/null +++ b/db/migrate/20240924130424_add_created_at_index_for_data_points.rb @@ -0,0 +1,7 @@ +class AddCreatedAtIndexForDataPoints < ActiveRecord::Migration[6.1] + def change + add_index :tipline_subscriptions, :created_at + add_index :tipline_newsletter_deliveries, :created_at + add_index :annotations, :created_at + end +end diff --git a/db/schema.rb b/db/schema.rb index b92f4f4639..827431a9f8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_09_13_210101) do +ActiveRecord::Schema.define(version: 2024_09_24_130424) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -168,6 +168,7 @@ t.index ["annotated_type", "annotated_id"], name: "index_annotations_on_annotated_type_and_annotated_id" t.index ["annotation_type"], name: "index_annotation_type_order", opclass: :varchar_pattern_ops t.index ["annotation_type"], name: "index_annotations_on_annotation_type" + t.index ["created_at"], name: "index_annotations_on_created_at" end create_table "api_keys", id: :serial, force: :cascade do |t| @@ -733,6 +734,12 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "state" + t.index "date_trunc('day'::text, created_at)", name: "tipline_message_created_at_day" + t.index "date_trunc('month'::text, created_at)", name: "tipline_message_created_at_month" + t.index "date_trunc('quarter'::text, created_at)", name: "tipline_message_created_at_quarter" + t.index "date_trunc('week'::text, created_at)", name: "tipline_message_created_at_week" + t.index "date_trunc('year'::text, created_at)", name: "tipline_message_created_at_year" + t.index ["created_at"], name: "index_tipline_messages_on_created_at" t.index ["external_id", "state"], name: "index_tipline_messages_on_external_id_and_state", unique: true t.index ["team_id"], name: "index_tipline_messages_on_team_id" t.index ["uid"], name: "index_tipline_messages_on_uid" @@ -746,6 +753,7 @@ t.bigint "tipline_newsletter_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["created_at"], name: "index_tipline_newsletter_deliveries_on_created_at" t.index ["tipline_newsletter_id"], name: "index_tipline_newsletter_deliveries_on_tipline_newsletter_id" end @@ -798,8 +806,14 @@ t.integer "smooch_report_sent_at", default: 0 t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.index "date_trunc('day'::text, created_at)", name: "tipline_request_created_at_day" + t.index "date_trunc('month'::text, created_at)", name: "tipline_request_created_at_month" + t.index "date_trunc('quarter'::text, created_at)", name: "tipline_request_created_at_quarter" + t.index "date_trunc('week'::text, created_at)", name: "tipline_request_created_at_week" + t.index "date_trunc('year'::text, created_at)", name: "tipline_request_created_at_year" t.index ["associated_type", "associated_id"], name: "index_tipline_requests_on_associated" t.index ["associated_type", "associated_id"], name: "index_tipline_requests_on_associated_type_and_associated_id" + t.index ["created_at"], name: "index_tipline_requests_on_created_at" t.index ["language"], name: "index_tipline_requests_on_language" t.index ["platform"], name: "index_tipline_requests_on_platform" t.index ["smooch_message_id"], name: "index_tipline_requests_on_smooch_message_id", unique: true, where: "((smooch_message_id IS NOT NULL) AND ((smooch_message_id)::text <> ''::text))" @@ -835,6 +849,7 @@ t.string "platform" t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" }, null: false t.datetime "updated_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + t.index ["created_at"], name: "index_tipline_subscriptions_on_created_at" t.index ["language", "team_id"], name: "index_tipline_subscriptions_on_language_and_team_id" t.index ["language"], name: "index_tipline_subscriptions_on_language" t.index ["platform"], name: "index_tipline_subscriptions_on_platform" diff --git a/lib/check_data_points.rb b/lib/check_data_points.rb new file mode 100644 index 0000000000..160056f0a4 --- /dev/null +++ b/lib/check_data_points.rb @@ -0,0 +1,149 @@ +class CheckDataPoints + class << self + SEARCH_RESULT_TYPES = ['relevant_search_result_requests', 'irrelevant_search_result_requests', 'timeout_search_requests'] + GRANULARITY_VALUES = ['year', 'quarter', 'month', 'week', 'day'] + + # Number of tipline messages + def tipline_messages(team_id, start_date, end_date, granularity = nil) + start_date, end_date = parse_start_end_dates(start_date, end_date) + query = TiplineMessage.where(team_id: team_id, created_at: start_date..end_date) + query_based_on_granularity(query, granularity) + end + + # Number of tipline requests + def tipline_requests(team_id, start_date, end_date, granularity = nil) + start_date, end_date = parse_start_end_dates(start_date, end_date) + query = TiplineRequest.where(team_id: team_id, created_at: start_date..end_date) + query_based_on_granularity(query, granularity) + end + + # Number of tipline requests grouped by type of search result + def tipline_requests_by_search_type(team_id, start_date, end_date) + start_date, end_date = parse_start_end_dates(start_date, end_date) + TiplineRequest.where( + team_id: team_id, + smooch_request_type: SEARCH_RESULT_TYPES, + created_at: start_date..end_date, + ).group('smooch_request_type').count + end + + # Number of Subscribers + def tipline_subscriptions(team_id, start_date, end_date, granularity = nil) + start_date, end_date = parse_start_end_dates(start_date, end_date) + query = TiplineSubscription.where(team_id: team_id, created_at: start_date..end_date) + query_based_on_granularity(query, granularity) + end + + # Number of Newsletters sent + def newsletters_sent(team_id, start_date, end_date, granularity = nil) + start_date, end_date = parse_start_end_dates(start_date, end_date) + query = TiplineNewsletterDelivery + .joins(:tipline_newsletter) + .where('tipline_newsletters.team_id': team_id) + .where(created_at: start_date..end_date) + query_based_on_granularity(query, granularity, 'newsletter') + end + + # Number of Media received, by type + def media_received_by_type(team_id, start_date, end_date) + bot = BotUser.smooch_user + start_date, end_date = parse_start_end_dates(start_date, end_date) + ProjectMedia.where(team_id: team_id, user_id: bot.id, created_at: start_date..end_date) + .joins(:media).group('medias.type').count + end + + # Top clusters + def top_clusters(team_id, start_date, end_date, limit = 5) + elastic_search_top_items(team_id, start_date, end_date, limit) + end + + # Top media tags + def top_media_tags(team_id, start_date, end_date, limit = 5) + elastic_search_top_items(team_id, start_date, end_date, limit, true) + end + + # Articles sent + def articles_sent(team_id, start_date, end_date) + start_date, end_date = parse_start_end_dates(start_date, end_date) + # Get number of articles sent as search results + search_result_c = TiplineRequest.where(team_id: team_id, smooch_request_type: SEARCH_RESULT_TYPES, created_at: start_date..end_date).count + # Get the number of articles sent as reports + reports_c = TiplineRequest + .where(team_id: team_id, created_at: start_date..end_date) + .where('smooch_report_received_at > 0 OR smooch_report_update_received_at > 0 OR smooch_report_sent_at > 0 OR smooch_report_correction_sent_at > 0').count + search_result_c + reports_c + end + + # Average response time + def average_response_time(team_id, start_date, end_date) + TiplineRequest + .where(team_id: team_id, smooch_report_received_at: start_date.to_datetime.to_i..end_date.to_datetime.to_i) + .average("smooch_report_received_at - CAST(DATE_PART('EPOCH', created_at::timestamp) AS INTEGER)").to_f + end + + # All users + def all_users(team_id, start_date, end_date) + start_date, end_date = parse_start_end_dates(start_date, end_date) + TiplineRequest.where(team_id: team_id, created_at: start_date..end_date) + .count('DISTINCT(tipline_user_uid)') + end + + # Returning users + def returning_users(team_id, start_date, end_date) + # Number of returning users (at least one session in the current month, and at least one session in the last previous 2 months) + start_date, end_date = parse_start_end_dates(start_date, end_date) + uids = TiplineRequest.where(team_id: team_id, created_at: start_date.ago(2.months)..start_date).map(&:tipline_user_uid).uniq + TiplineRequest.where(team_id: team_id, tipline_user_uid: uids, created_at: start_date..end_date) + .count('DISTINCT(tipline_user_uid)') + end + + # New users + def new_users(team_id, start_date, end_date) + start_date, end_date = parse_start_end_dates(start_date, end_date) + Annotation.where(annotation_type: 'smooch_user', annotated_type: 'Team', annotated_id: team_id) + .joins("INNER JOIN dynamic_annotation_fields fs ON fs.annotation_id = annotations.id AND fs.field_name = 'smooch_user_id'") + .where('annotations.created_at': start_date..end_date) + .count + end + + private + + def parse_start_end_dates(start_date, end_date) + # date format is `2023-08-23` + start_date = Time.parse(start_date) + end_date = Time.parse(end_date) + raise 'End date should be greater than start date' if start_date > end_date + return start_date, end_date + end + + def query_based_on_granularity(query, granularity, type = nil) + # For PG the allowed values for granularity can be one of the following + # [millennium, century, decade, year, quarter, month, week, day, hour, + # minute, second, milliseconds, microseconds] + # But I'll limit the value to the following [year, quarter, month, week, day] + if GRANULARITY_VALUES.include?(granularity) + if type == 'newsletter' + query.group("date_trunc('#{granularity}', tipline_newsletter_deliveries.created_at)").count + else + query.group("date_trunc('#{granularity}', created_at)").count + end + else + query.count + end + end + + def elastic_search_top_items(team_id, start_date, end_date, limit, with_tags = false) + data = {} + query = { + range: { 'created_at': { start_time: start_date, end_time: end_date } }, + demand: { min: 1 }, + sort: 'demand', + eslimit: limit + } + query[:tags_as_sentence] = { min: 1 } if with_tags + result = CheckSearch.new(query.to_json, nil, team_id) + result.medias.each{ |pm| data[pm.id] = pm.demand } + data + end + end +end diff --git a/lib/check_search.rb b/lib/check_search.rb index 8093d57d20..89bc0e067f 100644 --- a/lib/check_search.rb +++ b/lib/check_search.rb @@ -434,7 +434,7 @@ def adjust_channel_filter def adjust_numeric_range_filter @options['range_numeric'] = {} - [:linked_items_count, :suggestions_count, :demand, :positive_tipline_search_results_count, :negative_tipline_search_results_count].each do |field| + [:linked_items_count, :suggestions_count, :demand, :positive_tipline_search_results_count, :negative_tipline_search_results_count, :tags_as_sentence].each do |field| if @options.has_key?(field) && !@options[field].blank? @options['range_numeric'][field] = @options[field] end diff --git a/lib/sample_data.rb b/lib/sample_data.rb index e7ba63368e..b8ff091220 100644 --- a/lib/sample_data.rb +++ b/lib/sample_data.rb @@ -1000,6 +1000,18 @@ def create_tipline_newsletter(options = {}) newsletter end + def create_tipline_newsletter_delivery(options = {}) + newsletter_delivery = TiplineNewsletterDelivery.new({ + recipients_count: 100, + content: 'Test', + started_sending_at: Time.now.ago(1.minute), + finished_sending_at: Time.now, + tipline_newsletter: options[:tipline_newsletter] || create_tipline_newsletter + }.merge(options)) + newsletter_delivery.save! + newsletter_delivery + end + def create_rss_feed(custom_url = nil) url = custom_url || random_url rss = %{ diff --git a/test/lib/check_data_points_test.rb b/test/lib/check_data_points_test.rb new file mode 100644 index 0000000000..678df2bdb7 --- /dev/null +++ b/test/lib/check_data_points_test.rb @@ -0,0 +1,177 @@ +require_relative '../test_helper' + +class CheckDataPointsTest < ActiveSupport::TestCase + def setup + @team = create_team + @team2 = create_team + @start_date = (Time.now - 1.month).strftime("%Y-%m-%d") + @end_date = (Time.now + 1.month).strftime("%Y-%m-%d") + end + + def teardown + end + + test "should calculate tipline messages" do + create_tipline_message team_id: @team.id + create_tipline_message team_id: @team.id + create_tipline_message team_id: @team2.id + Time.stubs(:now).returns(Time.new - 2.months) + create_tipline_message team_id: @team.id + Time.unstub(:now) + assert_equal 2, CheckDataPoints.tipline_messages(@team.id, @start_date, @end_date) + assert_equal 1, CheckDataPoints.tipline_messages(@team2.id, @start_date, @end_date) + from = (Time.now - 4.month).strftime("%Y-%m-%d") + assert_equal 3, CheckDataPoints.tipline_messages(@team.id, from, @end_date) + end + + test "should calculate tipline requests, articles sent and average response time" do + pm = create_project_media team: @team + pm2 = create_project_media team: @team + tr = create_tipline_request team_id: @team.id, associated: pm + create_tipline_request team_id: @team.id, associated: pm, smooch_request_type: 'relevant_search_result_requests' + create_tipline_request team_id: @team.id, associated: pm, smooch_request_type: 'irrelevant_search_result_requests' + create_tipline_request team_id: @team.id, associated: pm, smooch_request_type: 'timeout_search_requests' + create_tipline_request team_id: @team.id, associated: pm, smooch_request_type: 'relevant_search_result_requests' + create_tipline_request team_id: @team2.id, associated: pm2 + Time.stubs(:now).returns(Time.new - 2.months) + create_tipline_request team_id: @team.id, associated: pm + create_tipline_request team_id: @team.id, associated: pm, smooch_request_type: 'relevant_search_result_requests' + create_tipline_request team_id: @team2.id, associated: pm2 + Time.unstub(:now) + # Verify all tipline requests + assert_equal 5, CheckDataPoints.tipline_requests(@team.id, @start_date, @end_date) + assert_equal 1, CheckDataPoints.tipline_requests(@team2.id, @start_date, @end_date) + # Verify granularity + from = (Time.now - 4.month).strftime("%Y-%m-%d") + result_g = CheckDataPoints.tipline_requests(@team.id, from, @end_date, 'month') + assert_equal [2, 5], result_g.values.sort + # Verify tipline requests by search_type + result = CheckDataPoints.tipline_requests_by_search_type(@team.id, @start_date, @end_date) + actual = { "irrelevant_search_result_requests" => 1, "relevant_search_result_requests" => 2, "timeout_search_requests" => 1 } + assert_equal actual, result + result = CheckDataPoints.tipline_requests_by_search_type(@team.id, from, @end_date) + actual = { "irrelevant_search_result_requests" => 1, "relevant_search_result_requests" => 3, "timeout_search_requests" => 1 } + assert_equal actual, result + # Verify articles sent + time_i = Time.now.to_i + create_tipline_request team_id: @team.id, associated: pm, smooch_report_received_at: time_i + create_tipline_request team_id: @team.id, associated: pm, smooch_report_update_received_at: time_i + create_tipline_request team_id: @team.id, associated: pm, smooch_report_sent_at: time_i + create_tipline_request team_id: @team.id, associated: pm, smooch_report_correction_sent_at: time_i + assert_equal 8, CheckDataPoints.articles_sent(@team.id, @start_date, @end_date) + # Verify average response time + tr.smooch_report_received_at = time_i + tr.save! + assert_not_nil CheckDataPoints.average_response_time(@team.id, @start_date, @end_date) + end + + test "should calculate tipline subscriptions" do + create_tipline_subscription team_id: @team.id + create_tipline_subscription team_id: @team.id + create_tipline_subscription team_id: @team2.id + Time.stubs(:now).returns(Time.new - 2.months) + create_tipline_subscription team_id: @team.id + Time.unstub(:now) + assert_equal 2, CheckDataPoints.tipline_subscriptions(@team.id, @start_date, @end_date) + assert_equal 1, CheckDataPoints.tipline_subscriptions(@team2.id, @start_date, @end_date) + from = (Time.now - 4.month).strftime("%Y-%m-%d") + assert_equal 3, CheckDataPoints.tipline_subscriptions(@team.id, from, @end_date) + end + + test "should calculate newsletters sent" do + newsletter = create_tipline_newsletter team: @team + newsletter2 = create_tipline_newsletter team: @team2 + create_tipline_newsletter_delivery tipline_newsletter: newsletter + create_tipline_newsletter_delivery tipline_newsletter: newsletter + create_tipline_newsletter_delivery tipline_newsletter: newsletter2 + Time.stubs(:now).returns(Time.new - 2.months) + create_tipline_newsletter_delivery tipline_newsletter: newsletter + create_tipline_newsletter_delivery tipline_newsletter: newsletter2 + Time.unstub(:now) + assert_equal 2, CheckDataPoints.newsletters_sent(@team.id, @start_date, @end_date) + assert_equal 1, CheckDataPoints.newsletters_sent(@team2.id, @start_date, @end_date) + from = (Time.now - 4.month).strftime("%Y-%m-%d") + assert_equal 3, CheckDataPoints.newsletters_sent(@team.id, from, @end_date) + result_g = CheckDataPoints.newsletters_sent(@team.id, from, @end_date, 'month') + assert_equal [1, 2], result_g.values.sort + end + + test "should calculate media_received_by_type" do + bot = create_team_bot login: 'smooch', name: 'Smooch', set_approved: true + create_project_media team: @team, user: bot, media: create_claim_media + create_project_media team: @team, user: bot, media: create_claim_media + create_project_media team: @team, user: bot, media: create_link + create_project_media team: @team, user: bot, media: create_uploaded_image + create_project_media team: @team2, user: bot, media: create_claim_media + Time.stubs(:now).returns(Time.new - 2.months) + create_project_media team: @team, user: bot, media: create_claim_media + Time.unstub(:now) + result = CheckDataPoints.media_received_by_type(@team.id, @start_date, @end_date) + actual = { "Claim" => 2, "Link" => 1, "UploadedImage" =>1 } + assert_equal actual, result + result = CheckDataPoints.media_received_by_type(@team2.id, @start_date, @end_date) + actual = { "Claim" => 1} + assert_equal actual, result + from = (Time.now - 4.month).strftime("%Y-%m-%d") + result = CheckDataPoints.media_received_by_type(@team.id, from, @end_date) + actual = { "Claim" => 3, "Link" => 1, "UploadedImage" =>1 } + assert_equal actual, result + end + + test "should calculate top clusters and top media tags" do + setup_elasticsearch + RequestStore.store[:skip_cached_field_update] = false + pm = create_project_media team: @team, disable_es_callbacks: false + create_tipline_request team: @team.id, associated: pm + pm2 = create_project_media team: @team, disable_es_callbacks: false + 3.times { create_tipline_request(team_id: @team.id, associated: pm2) } + pm3 = create_project_media team: @team, disable_es_callbacks: false + 2.times { create_tipline_request(team_id: @team.id, associated: pm3) } + pm4 = create_project_media team: @team, disable_es_callbacks: false + 4.times { create_tipline_request(team_id: @team.id, associated: pm4) } + pm5 = create_project_media team: @team, disable_es_callbacks: false + sleep 2 + # Verify top clusters + result = CheckDataPoints.top_clusters(@team.id, @start_date, @end_date) + actual = { pm4.id => 4, pm2.id => 3, pm3.id => 2, pm.id => 1 } + assert_equal actual, result + # Verify top media tags + create_tipline_request team: @team.id, associated: pm5 + create_tag annotated: pm2, disable_es_callbacks: false + create_tag annotated: pm3, disable_es_callbacks: false + create_tag annotated: pm5, disable_es_callbacks: false + sleep 2 + result = CheckDataPoints.top_media_tags(@team.id, @start_date, @end_date) + actual = { pm2.id => 3, pm3.id => 2, pm5.id => 1 } + assert_equal actual, result + end + + test "should calculate users" do + create_annotation_type_and_fields('Smooch User', { 'Id' => ['Text', false] }) + pm = create_project_media team: @team + author_id = random_string + author_id2 = random_string + smooch_data = { language: 'en', authorId: author_id, source: { type: 'whatsapp' } } + create_tipline_request team_id: @team.id, smooch_data: smooch_data + create_tipline_request team_id: @team.id, smooch_data: smooch_data + create_tipline_request team_id: @team.id + smooch_data[:authorId] = author_id2 + create_tipline_request team_id: @team.id, smooch_data: smooch_data + create_tipline_request team_id: @team.id, smooch_data: smooch_data + create_tipline_request team_id: @team2.id + Time.stubs(:now).returns(Time.new - 3.months) + create_tipline_request team_id: @team.id, associated: pm, smooch_data: smooch_data + Time.unstub(:now) + # All users + assert_equal 3, CheckDataPoints.all_users(@team.id, @start_date, @end_date) + # returning_users + assert_equal 1, CheckDataPoints.returning_users(@team.id, @start_date, @end_date) + # new_users + create_dynamic_annotation annotated: @team, annotation_type: 'smooch_user', set_fields: { smooch_user_id: random_string }.to_json + create_dynamic_annotation annotated: @team, annotation_type: 'smooch_user', set_fields: { smooch_user_id: random_string }.to_json + Time.stubs(:now).returns(Time.new - 3.months) + create_dynamic_annotation annotated: @team, annotation_type: 'smooch_user', set_fields: { smooch_user_id: random_string }.to_json + Time.unstub(:now) + assert_equal 2, CheckDataPoints.new_users(@team.id, @start_date, @end_date) + end +end From c1666996d8a74dae1b1d0043f875876ba8a8f4e7 Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Wed, 25 Sep 2024 17:22:25 +0300 Subject: [PATCH 27/39] CV2-5297: fix sentry issue (#2051) --- app/models/fact_check.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/fact_check.rb b/app/models/fact_check.rb index 777c4787cd..8a4f58b599 100644 --- a/app/models/fact_check.rb +++ b/app/models/fact_check.rb @@ -74,7 +74,7 @@ def language_in_allowed_values end def rating_in_allowed_values - unless self.rating.blank? + unless self.rating.blank? || self.claim_description.nil? team = self.claim_description.team allowed_statuses = team.verification_statuses('media', nil)['statuses'].collect{ |s| s[:id] } errors.add(:rating, I18n.t(:workflow_status_is_not_valid, status: self.rating, valid: allowed_statuses.join(', '))) unless allowed_statuses.include?(self.rating) From 269590bcc686109f75eac7c3d7a55416b1f5ebc8 Mon Sep 17 00:00:00 2001 From: Manu Vasconcelos <87862340+vasconsaurus@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:52:27 -0300 Subject: [PATCH 28/39] set sidekiq_options retry to 3 for the GenericWorker (#2052) Pretty straight forward. Sets the maximum retry count to 3. Note We want to add custom retry logic, but that works differently between Sidekiq 5 and 6. So we think it is better to focus later on the Sidekiq upgrade, and until there, worker instances can handle their exceptions instead of relying on the generic worker for that. References: 5120, https://github.com/meedan/check-api/pull/2005 PR: 2052 --- app/workers/generic_worker.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/workers/generic_worker.rb b/app/workers/generic_worker.rb index 4915f97c26..012c9b06c0 100644 --- a/app/workers/generic_worker.rb +++ b/app/workers/generic_worker.rb @@ -2,6 +2,8 @@ class GenericWorker include Sidekiq::Worker + sidekiq_options retry: 3 + def perform(klass_name, klass_method, *method_args) klass = klass_name.constantize options = method_args.extract_options!.with_indifferent_access From 6d03ce54b859f1abb88472720616a296e8f0f589 Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Fri, 27 Sep 2024 06:26:31 +0300 Subject: [PATCH 29/39] CV2-5324: create a method for create relationship and use it everywhere (#2053) --- app/models/bot/alegre.rb | 38 +++++++++---------- app/models/concerns/project_media_creators.rb | 7 +--- app/models/concerns/smooch_messages.rb | 10 +---- app/models/relationship.rb | 16 ++++++++ test/models/relationship_test.rb | 17 +++++++++ 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/app/models/bot/alegre.rb b/app/models/bot/alegre.rb index b7e4488040..2e02d4bec1 100644 --- a/app/models/bot/alegre.rb +++ b/app/models/bot/alegre.rb @@ -621,7 +621,6 @@ def self.create_relationship(source, target, pm_id_scores, relationship_type, or target.save! end r = self.fill_in_new_relationship(source, target, pm_id_scores, relationship_type, original_source, original_relationship_type) - r.save! self.report_exception_if_bad_relationship(r, pm_id_scores, relationship_type) Rails.logger.info "[Alegre Bot] [ProjectMedia ##{target.id}] [Relationships 5/6] Created new relationship for relationship ID Of #{r.id}" elsif self.is_relationship_upgrade?(r, relationship_type) @@ -640,26 +639,23 @@ def self.is_relationship_upgrade?(relationship, relationship_type) def self.fill_in_new_relationship(source, target, pm_id_scores, relationship_type, original_source, original_relationship_type) score_with_context = pm_id_scores[source.id] || {} - r = Relationship.new - r.skip_check_ability = true - r.relationship_type = relationship_type - r.model = self.get_indexing_model(source, score_with_context) - r.weight = score_with_context[:score] - r.details = score_with_context[:context] - r.source_id = source.id - r.target_id = target.id - r.source_field = score_with_context[:source_field] - r.target_field = score_with_context[:target_field] - if original_source - r.original_weight = pm_id_scores[original_source.id][:score] - r.original_details = pm_id_scores[original_source.id][:context] - r.original_relationship_type = original_relationship_type - r.original_model = self.get_indexing_model(original_source, pm_id_scores[original_source.id]) - r.original_source_id = original_source.id - r.original_source_field = pm_id_scores[original_source.id][:source_field] - end - r.user_id ||= BotUser.alegre_user&.id - r + options = { + model: self.get_indexing_model(source, score_with_context), + weight: score_with_context[:score], + details: score_with_context[:context], + source_field: score_with_context[:source_field], + target_field: score_with_context[:target_field], + } + options.merge!({ + original_weight: pm_id_scores[original_source.id][:score], + original_details: pm_id_scores[original_source.id][:context], + original_relationship_type: original_relationship_type, + original_model: self.get_indexing_model(original_source, pm_id_scores[original_source.id]), + original_source_id: original_source.id, + original_source_field: pm_id_scores[original_source.id][:source_field], + }) if original_source + options[:user_id] = BotUser.alegre_user&.id + Relationship.create_unless_exists(source.id, target.id, relationship_type, options) end def self.can_create_relationship?(source, target, relationship_type) diff --git a/app/models/concerns/project_media_creators.rb b/app/models/concerns/project_media_creators.rb index 4652e01df8..b8be45cb28 100644 --- a/app/models/concerns/project_media_creators.rb +++ b/app/models/concerns/project_media_creators.rb @@ -229,12 +229,7 @@ def create_relationship(type = Relationship.confirmed_type) unless self.related_to_id.nil? related = ProjectMedia.where(id: self.related_to_id).last unless related.nil? - r = Relationship.new - r.skip_check_ability = true - r.relationship_type = type - r.source_id = related.id - r.target_id = self.id - r.save! + Relationship.create_unless_exists(related.id, self.id, type) else raise 'Could not create related item' end diff --git a/app/models/concerns/smooch_messages.rb b/app/models/concerns/smooch_messages.rb index 140670c39a..e6db0de495 100644 --- a/app/models/concerns/smooch_messages.rb +++ b/app/models/concerns/smooch_messages.rb @@ -426,15 +426,7 @@ def relate_item_and_caption(message, associated, app_id, author, request_type, a target = self.create_project_media_from_message(message) unless target.nil? smoooch_post_save_message_actions(message, target, app_id, author, request_type, associated_obj) - r_exists = Relationship.where(source_id: associated.id, target_id: target.id).exists? - unless r_exists - r = Relationship.new - r.skip_check_ability = true - r.relationship_type = Relationship.suggested_type - r.source_id = associated.id - r.target_id = target.id - r.save! - end + Relationship.create_unless_exists(associated.id, target.id, Relationship.suggested_type) end end diff --git a/app/models/relationship.rb b/app/models/relationship.rb index efe056edea..bf782b96ee 100644 --- a/app/models/relationship.rb +++ b/app/models/relationship.rb @@ -153,6 +153,22 @@ def create_or_update_parent_id self.source_id end + def self.create_unless_exists(source_id, target_id, relationship_type, options = {}) + r = Relationship.where(source_id: source_id, target_id: target_id).last + if r.nil? + r = Relationship.new + r.skip_check_ability = true + r.relationship_type = relationship_type + r.source_id = source_id + r.target_id = target_id + options.each do |key, value| + r.send("#{key}=", value) if r.respond_to?("#{key}=") + end + r.save! + end + r + end + protected def update_elasticsearch_parent(action = 'create_or_update') diff --git a/test/models/relationship_test.rb b/test/models/relationship_test.rb index 455ba30880..696b37b3a1 100644 --- a/test/models/relationship_test.rb +++ b/test/models/relationship_test.rb @@ -239,4 +239,21 @@ def setup create_relationship source_id: pm3.id, target_id: pm3.id end end + + test "should create relationship unless exists" do + t = create_team + u = create_user + source = create_project_media team: t + target = create_project_media team: t + r = nil + assert_difference 'Relationship.count' do + r = Relationship.create_unless_exists(source.id, target.id, Relationship.confirmed_type, { user_id: u.id }) + end + assert_equal u.id, r.user_id + r2 = nil + assert_no_difference 'Relationship.count' do + r2 = Relationship.create_unless_exists(source.id, target.id, Relationship.confirmed_type) + end + assert_equal r, r2 + end end From d7ec467db68f4c6dc0c9cdffe62378a924278e1e Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:31:31 -0300 Subject: [PATCH 30/39] Ticket CV2-5364: Make sure that "test" controller also enqueues and executes bot events in background like the GraphQL controller does (#2055) --- app/controllers/test_controller.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/test_controller.rb b/app/controllers/test_controller.rb index df4e6cf99c..efc12a92a0 100644 --- a/app/controllers/test_controller.rb +++ b/app/controllers/test_controller.rb @@ -1,7 +1,8 @@ require 'sample_data' class TestController < ApplicationController - before_action :check_environment + before_action :check_environment, :init_bot_events + after_action :trigger_bot_events include SampleData @@ -250,4 +251,12 @@ def new_media(type) def check_environment (render(plain: 'Only available in test mode', status: 400) and return) unless Rails.env === 'test' end + + def init_bot_events + BotUser.init_event_queue if Rails.env.test? + end + + def trigger_bot_events + BotUser.trigger_events if Rails.env.test? + end end From dbb7863b577c4b691b87780c521612336326c591 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Sat, 28 Sep 2024 11:15:15 -0300 Subject: [PATCH 31/39] A couple of improvements for shared feeds (#2056) * Making sure that the way the feed Cluster.last_request_date field is calculated is the same as the ClusterTeam.last_request_date * Make sure that if a parent item is tagged, all child items are also included in the cluster, even if, individually, they are not tagged Reference: CV2-5331. --- lib/tasks/check_khousheh.rake | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/tasks/check_khousheh.rake b/lib/tasks/check_khousheh.rake index 98f467258f..e516ddb586 100644 --- a/lib/tasks/check_khousheh.rake +++ b/lib/tasks/check_khousheh.rake @@ -92,9 +92,11 @@ namespace :check do search_after = [pm_ids.max] puts "\nDone for page #{page}/#{pages}\n" end - file = File.open(File.join(Rails.root, 'tmp', 'feed-clusters-input', "#{TIMESTAMP}-#{feed.uuid}.json"), 'w+') + output_file_path = File.join(Rails.root, 'tmp', 'feed-clusters-input', "#{TIMESTAMP}-#{feed.uuid}.json") + file = File.open(output_file_path, 'w+') file.puts output.to_json file.close + puts "[#{Time.now}] Output file saved to #{output_file_path}." Team.current = nil end end @@ -219,10 +221,18 @@ namespace :check do pages = (total / PER_PAGE.to_f).ceil search_after = [0] page = 0 + processed = [] while true result = $repository.search(_source: 'annotated_id', query: es_query, sort: sort, search_after: search_after, size: PER_PAGE).results pm_ids = result.collect{ |i| i['annotated_id'] }.uniq break if pm_ids.empty? + + # Append IDs of child items but ignore the ones that were already processed + pm_ids += Relationship.where(source_id: pm_ids).where('relationship_type = ?', Relationship.confirmed_type.to_yaml).select(:target_id).map(&:target_id) + pm_ids.uniq! + pm_ids.reject!{ |id| processed.include?(id) } + processed += pm_ids + page += 1 puts "\nIterating on page #{page}/#{pages}\n" pm_media_mapping = {} # Project Media ID => Media ID @@ -268,7 +278,7 @@ namespace :check do updated_cluster_attributes[:channels] = (cluster.channels.to_a + pm.channel.to_h['others'].to_a + [pm.channel.to_h['main']]).uniq.compact_blank updated_cluster_attributes[:media_count] = cluster.media_count + 1 updated_cluster_attributes[:requests_count] = cluster.requests_count + pm.requests_count - updated_cluster_attributes[:last_request_date] = (pm.last_seen > cluster.last_request_date.to_i) ? Time.at(pm.last_seen) : cluster.last_request_date + updated_cluster_attributes[:last_request_date] = (pm.tipline_requests.last&.created_at.to_i > cluster.last_request_date.to_i) ? pm.tipline_requests.last.created_at : cluster.last_request_date updated_cluster_attributes[:fact_checks_count] = cluster.fact_checks_count updated_cluster_attributes[:last_fact_check_date] = cluster.last_fact_check_date unless pm_fc_mapping[pm.id].blank? From 451d96439dbd4dc3d1dbca02c14b7b82f63c29f0 Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Mon, 30 Sep 2024 18:44:13 +0300 Subject: [PATCH 32/39] CV2-5371: fix sentry issue (#2058) --- app/models/project_media.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project_media.rb b/app/models/project_media.rb index 20674d674a..9992c02b3b 100644 --- a/app/models/project_media.rb +++ b/app/models/project_media.rb @@ -258,7 +258,7 @@ def self.destroy_related_medias(project_media, user_id = nil) end def replace_by(new_pm, skip_send_report = false) - return if self.id == new_pm.id + return if self.id == new_pm.id || new_pm.nil? if self.team_id != new_pm.team_id raise I18n.t(:replace_by_media_in_the_same_team) elsif self.media.media_type != 'blank' From 527c1d815e51497a067ff39393ca97fa57c4d80c Mon Sep 17 00:00:00 2001 From: Martin Peck <51542678+sonoransun@users.noreply.github.com> Date: Mon, 30 Sep 2024 11:30:24 -0700 Subject: [PATCH 33/39] Update setuptools module and pin to known good version. (#2059) --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 29fab2e14d..e15698ceb6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,6 +35,7 @@ deploy_qa: AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION GITHUB_TOKEN: $GITHUB_TOKEN script: + - pip install setuptools==75.1.0 - pip install urllib3==2.0.6 - pip install botocore==1.31.62 - pip install boto3==1.28.62 @@ -106,6 +107,7 @@ deploy_live: AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION GITHUB_TOKEN: $GITHUB_TOKEN script: + - pip install setuptools==75.1.0 - pip install urllib3==2.0.6 - pip install botocore==1.31.62 - pip install boto3==1.28.62 From 77f2e18868017e454763d44ad2aaf47383a381c0 Mon Sep 17 00:00:00 2001 From: Manu Vasconcelos <87862340+vasconsaurus@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:48:15 -0300 Subject: [PATCH 34/39] =?UTF-8?q?5120=20=E2=80=93=20Dont=20create=20duplic?= =?UTF-8?q?ate=20tags=20and=20clean=20up=20`#`=20(#2054)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context While looking into a tags issue I noticed a few things: - when we made a request with duplicate tags: - we got an error, so the job was retried - the tag was added twice to the FactCheck - the tag is added once to the ProjectMedia - when we made a request with a tag with a # - we got an error, so the job was retried - there seem to have been two errors related to this: - ActiveRecord::RecordInvalid: Tag already exists - ActiveRecord::RecordInvalid: Text has already been taken - the tag with the # is added to the FactCheck - the tag is not added to the ProjectMedia What was happening There are a few things happening at the same time: - Creation of a ProjectMedia with tags - Creation of a FactCheck with tags - Tags are an Object from the Tag Class for ProjectMedia, but are a simple array for FactCheck For the ProjectMedia: - It would create the tag, then it would try to create the same tag again, and then it would fail and retry again, and so on - This happen because we have validations in place for the Tag class For FactCheck: - It would just create the tags twice - Because we have no validations for the tags array TLDR: There were some issues in the tags clean-up before we create them for ProjectMedia and FactCheck, and there was a mismatch between them. How it was fixed - I created a helper to clean up the tags before creating them - We need to make sure tags are: - stripped - unique - don't have a prepending `#` - We use this helper both in FactCheck.rb and Tag.rb References: 5120 PR: 2054 --- app/models/annotations/tag.rb | 13 +++++ app/models/concerns/project_media_creators.rb | 2 +- app/models/concerns/tag_helpers.rb | 9 ++++ app/models/fact_check.rb | 7 +++ app/models/project_media.rb | 12 ----- .../controllers/graphql_controller_12_test.rb | 51 ++++++++++++++++++ test/lib/generic_worker_helpers_test.rb | 6 +-- test/models/fact_check_test.rb | 22 ++++++++ test/models/project_media_8_test.rb | 37 ++----------- test/models/tag_test.rb | 54 +++++++++++++++++++ test/workers/generic_worker_test.rb | 4 +- 11 files changed, 166 insertions(+), 51 deletions(-) create mode 100644 app/models/concerns/tag_helpers.rb diff --git a/app/models/annotations/tag.rb b/app/models/annotations/tag.rb index 4755b39d62..d5ac548f2d 100644 --- a/app/models/annotations/tag.rb +++ b/app/models/annotations/tag.rb @@ -1,5 +1,6 @@ class Tag < ApplicationRecord include AnnotationBase + extend TagHelpers # "tag" is a reference to a TagText object field :tag, GraphQL::Types::Int, presence: true @@ -91,6 +92,18 @@ def hit_nested_objects_limit? ret end + def self.create_project_media_tags(project_media_id, tags_json) + project_media = ProjectMedia.find_by_id(project_media_id) + + if !project_media.nil? + tags = JSON.parse(tags_json) + clean_tags(tags).each { |tag| Tag.create! annotated: project_media, tag: tag.strip, skip_check_ability: true } + else + error = StandardError.new("[ProjectMedia] Exception creating project media's tags in background. Project media is nil.") + CheckSentry.notify(error, project_media_id: project_media_id) + end + end + private def get_tag_text_reference diff --git a/app/models/concerns/project_media_creators.rb b/app/models/concerns/project_media_creators.rb index b8be45cb28..032bd86d5c 100644 --- a/app/models/concerns/project_media_creators.rb +++ b/app/models/concerns/project_media_creators.rb @@ -262,7 +262,7 @@ def create_tags_in_background if self.set_tags.is_a?(Array) project_media_id = self.id tags_json = self.set_tags.to_json - ProjectMedia.run_later_in(1.second, 'create_tags', project_media_id, tags_json, user_id: self.user_id) + Tag.run_later_in(1.second, 'create_project_media_tags', project_media_id, tags_json, user_id: self.user_id) end end end diff --git a/app/models/concerns/tag_helpers.rb b/app/models/concerns/tag_helpers.rb new file mode 100644 index 0000000000..ef02ca9a7a --- /dev/null +++ b/app/models/concerns/tag_helpers.rb @@ -0,0 +1,9 @@ +require 'active_support/concern' + +module TagHelpers + extend ActiveSupport::Concern + + def clean_tags(tags) + tags.map { |tag| tag.strip.gsub(/^#/, '') }.uniq + end +end diff --git a/app/models/fact_check.rb b/app/models/fact_check.rb index 8a4f58b599..7804c51eb9 100644 --- a/app/models/fact_check.rb +++ b/app/models/fact_check.rb @@ -1,5 +1,6 @@ class FactCheck < ApplicationRecord include Article + include TagHelpers has_paper_trail on: [:create, :update], ignore: [:updated_at, :created_at, :rating, :report_status], if: proc { |_x| User.current.present? }, versions: { class_name: 'Version' } @@ -18,6 +19,7 @@ class FactCheck < ApplicationRecord validates_format_of :url, with: URI.regexp, allow_blank: true, allow_nil: true validate :language_in_allowed_values, :title_or_summary_exists, :rating_in_allowed_values + before_save :clean_fact_check_tags after_save :update_report, unless: proc { |fc| fc.skip_report_update || !DynamicAnnotation::AnnotationType.where(annotation_type: 'report_design').exists? || fc.project_media.blank? } after_save :update_item_status, if: proc { |fc| fc.saved_change_to_rating? } after_update :detach_claim_if_trashed @@ -56,6 +58,11 @@ def self.get_exported_data(query, team) data end + def clean_fact_check_tags + return if self.tags.blank? + self.tags = clean_tags(self.tags) + end + private def set_language diff --git a/app/models/project_media.rb b/app/models/project_media.rb index 9992c02b3b..7d6ccb67f0 100644 --- a/app/models/project_media.rb +++ b/app/models/project_media.rb @@ -528,18 +528,6 @@ def add_nested_objects(ms) ms.attributes[:requests] = requests end - def self.create_tags(project_media_id, tags_json) - project_media = ProjectMedia.find_by_id(project_media_id) - - if !project_media.nil? - tags = JSON.parse(tags_json) - tags.each { |tag| Tag.create! annotated: project_media, tag: tag.strip, skip_check_ability: true } - else - error = StandardError.new("[ProjectMedia] Exception creating project media's tags in background. Project media is nil.") - CheckSentry.notify(error, project_media_id: project_media_id) - end - end - # private # # Please add private methods to app/models/concerns/project_media_private.rb diff --git a/test/controllers/graphql_controller_12_test.rb b/test/controllers/graphql_controller_12_test.rb index a4e5a9e84d..bf666da1ef 100644 --- a/test/controllers/graphql_controller_12_test.rb +++ b/test/controllers/graphql_controller_12_test.rb @@ -680,4 +680,55 @@ def teardown assert_response :success assert_equal 'science', JSON.parse(@response.body)['data']['createProjectMedia']['project_media']['tags']['edges'][0]['node']['tag_text'] end + + test "should not create duplicate tags for the ProjectMedia and FactCheck" do + Sidekiq::Testing.inline! + t = create_team + a = ApiKey.create! + b = create_bot_user api_key_id: a.id + create_team_user team: t, user: b + p = create_project team: t + authenticate_with_token(a) + + query1 = ' mutation create { + createProjectMedia(input: { + project_id: ' + p.id.to_s + ', + media_type: "Blank", + channel: { main: 1 }, + set_tags: ["science", "science", "#science"], + set_status: "verified", + set_claim_description: "Claim #1.", + set_fact_check: { + title: "Title #1", + language: "en", + } + }) { + project_media { + full_url + claim_description { + fact_check { + tags + } + } + tags { + edges { + node { + tag_text + } + } + } + } + } + } ' + + post :create, params: { query: query1, team: t.slug } + assert_response :success + + pm = JSON.parse(@response.body)['data']['createProjectMedia']['project_media'] + pm_tags = pm['tags']['edges'] + fc_tags = pm['claim_description']['fact_check']['tags'] + + assert_equal 1, pm_tags.count + assert_equal 1, fc_tags.count + end end diff --git a/test/lib/generic_worker_helpers_test.rb b/test/lib/generic_worker_helpers_test.rb index 11d390d999..9b9311d43f 100644 --- a/test/lib/generic_worker_helpers_test.rb +++ b/test/lib/generic_worker_helpers_test.rb @@ -9,7 +9,7 @@ def setup def teardown end - test "should run a job, without raising an error, for a method that takes a hash as a parameter" do + test "should run a job async, without raising an error, for a method that takes a hash as a parameter" do Sidekiq::Testing.inline! assert_difference "Team.where(name: 'BackgroundTeam', slug: 'background-team').count" do @@ -17,7 +17,7 @@ def teardown end end - test "should run a job, without raising an error, for a method that takes standalone parameters" do + test "should run a job in a specified time, without raising an error, for a method that takes standalone parameters" do Sidekiq::Testing.inline! team = create_team @@ -27,7 +27,7 @@ def teardown project_media_id = pm.id tags_json = ['one', 'two', 'three'].to_json - ProjectMedia.run_later_in(0.second, 'create_tags', project_media_id, tags_json, user_id: pm.user_id) + Tag.run_later_in(0.second, 'create_project_media_tags', project_media_id, tags_json, user_id: pm.user_id) assert_equal 3, pm.annotations('tag').count end diff --git a/test/models/fact_check_test.rb b/test/models/fact_check_test.rb index 54baa29f6d..43cf6e4662 100644 --- a/test/models/fact_check_test.rb +++ b/test/models/fact_check_test.rb @@ -596,4 +596,26 @@ def setup end end end + + test "should not have duplicate tags" do + pm = create_project_media + cd = create_claim_description(project_media: pm) + fc = create_fact_check claim_description: cd, tags: ['one', 'one', '#one'] + + assert_equal 1, fc.tags.count + assert_equal 'one', fc.tags.first + end + + test "should add existing tag to a new fact check" do + pm = create_project_media + cd = create_claim_description(project_media: pm) + create_fact_check claim_description: cd, tags: ['one'] + + pm2 = create_project_media + cd2 = create_claim_description(project_media: pm2) + fc2 = create_fact_check claim_description: cd2, tags: ['#one'] + + assert_equal 1, fc2.tags.count + assert_equal 'one', fc2.tags.first + end end diff --git a/test/models/project_media_8_test.rb b/test/models/project_media_8_test.rb index 42f9b9c41d..9323805f3d 100644 --- a/test/models/project_media_8_test.rb +++ b/test/models/project_media_8_test.rb @@ -9,30 +9,6 @@ def setup def teardown end - test ":create_tags should create tags when project media id and tags are present" do - team = create_team - project = create_project team: team - pm = create_project_media project: project - - project_media_id = pm.id - tags_json = ['one', 'two'].to_json - - assert_nothing_raised do - ProjectMedia.create_tags(project_media_id, tags_json) - end - assert_equal 2, pm.annotations('tag').count - end - - test ":create_tags should not raise an error when no project media is sent" do - project_media_id = nil - tags_json = ['one', 'two'].to_json - - assert_nothing_raised do - CheckSentry.expects(:notify).once - ProjectMedia.create_tags(project_media_id, tags_json) - end - end - test "when creating an item with tag/tags, after_create :create_tags_in_background callback should create tags in the background" do Sidekiq::Testing.inline! @@ -55,18 +31,13 @@ def teardown assert_equal 1, GenericWorker.jobs.size end - test "when using :run_later_in to schedule multiple tags creation, it should only schedule one job" do - Sidekiq::Testing.fake! + test "when creating an item with multiple tags, after_create :create_tags_in_background callback should not create duplicate tags" do + Sidekiq::Testing.inline! team = create_team project = create_project team: team - pm = create_project_media project: project + pm = create_project_media project: project, tags: ['one', 'one', '#one'] - project_media_id = pm.id - tags_json = ['one', 'two', 'three'].to_json - - ProjectMedia.run_later_in(0.second, 'create_tags', project_media_id, tags_json, user_id: pm.user_id) - - assert_equal 1, GenericWorker.jobs.size + assert_equal 1, pm.annotations('tag').count end end diff --git a/test/models/tag_test.rb b/test/models/tag_test.rb index 0439f55832..c1b7e14f53 100644 --- a/test/models/tag_test.rb +++ b/test/models/tag_test.rb @@ -284,4 +284,58 @@ def setup create_tag tag: ' foo', annotated: pm2 end end + + test ":create_project_media_tags should create tags when project media id and tags are present" do + team = create_team + project = create_project team: team + pm = create_project_media project: project + + project_media_id = pm.id + tags_json = ['one', 'two'].to_json + + assert_nothing_raised do + Tag.create_project_media_tags(project_media_id, tags_json) + end + assert_equal 2, pm.annotations('tag').count + end + + test ":create_project_media_tags should not raise an error when no project media is sent" do + project_media_id = nil + tags_json = ['one', 'two'].to_json + + assert_nothing_raised do + CheckSentry.expects(:notify).once + Tag.create_project_media_tags(project_media_id, tags_json) + end + end + + test ":create_project_media_tags should not try to create duplicate tags" do + Sidekiq::Testing.fake! + + team = create_team + project = create_project team: team + pm = create_project_media project: project + Tag.create_project_media_tags(pm.id, ['one', 'one', '#one'].to_json) + + tags = pm.reload.annotations('tag') + tag_text_id = tags.last.data['tag'] + tag_text = TagText.find(tag_text_id).text + + assert_equal 1, tags.count + assert_equal 'one', tag_text + end + + test ":create_project_media_tags should be able to add an existing tag to a new project media" do + Sidekiq::Testing.fake! + + team = create_team + project = create_project team: team + pm = create_project_media project: project + Tag.create_project_media_tags(pm.id, ['one'].to_json) + + pm2 = create_project_media project: project + Tag.create_project_media_tags(pm2.id, ['#one'].to_json) + + assert_equal 1, pm2.reload.annotations('tag').count + end end diff --git a/test/workers/generic_worker_test.rb b/test/workers/generic_worker_test.rb index 628602a0da..baf671cecd 100644 --- a/test/workers/generic_worker_test.rb +++ b/test/workers/generic_worker_test.rb @@ -36,7 +36,7 @@ def teardown tags_json = ['one', 'two'].to_json assert_difference "Tag.where(annotation_type: 'tag').count", difference = 2 do - GenericWorker.perform_async('ProjectMedia', 'create_tags', project_media_id, tags_json, user_id: pm.user_id) + GenericWorker.perform_async('Tag', 'create_project_media_tags', project_media_id, tags_json, user_id: pm.user_id) end end @@ -71,7 +71,7 @@ def teardown tags_json = ['one', 'two'].to_json assert_nothing_raised do - GenericWorker.perform_async('ProjectMedia', 'create_tags', project_media_id, tags_json, user_id: pm.user_id) + GenericWorker.perform_async('Tag', 'create_project_media_tags', project_media_id, tags_json, user_id: pm.user_id) end assert_equal 1, GenericWorker.jobs.size From 1237fc2cb36cab0e4ef5794503d0d30b5a6d7f0f Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Tue, 1 Oct 2024 04:59:38 +0300 Subject: [PATCH 35/39] CV2-5005: Sentry issue related to ES (#2057) * CV2-5005: limit ES date to updated fields only * CV2-5005: fix tests * CV2-5005: test coverage --- app/lib/check_cached_fields.rb | 6 ++- app/models/concerns/project_association.rb | 37 ++++++++----------- .../concerns/project_media_cached_fields.rb | 2 +- app/workers/elastic_search_worker.rb | 4 +- test/controllers/elastic_search_test.rb | 28 +++++++------- test/controllers/graphql_controller_3_test.rb | 14 +++---- test/models/bot/fetch_2_test.rb | 2 +- test/models/project_media_3_test.rb | 28 +++++++------- test/models/project_media_6_test.rb | 6 +++ 9 files changed, 66 insertions(+), 61 deletions(-) diff --git a/app/lib/check_cached_fields.rb b/app/lib/check_cached_fields.rb index 16ffc8e10c..601b8b87cd 100644 --- a/app/lib/check_cached_fields.rb +++ b/app/lib/check_cached_fields.rb @@ -66,8 +66,10 @@ def index_and_pg_cached_field(options, value, name, target) if should_update_cached_field?(options, target) update_index = options[:update_es] || false value = target.send(update_index, value) if update_index.is_a?(Symbol) && target.respond_to?(update_index) - field_name = options[:es_field_name] || name - es_options = { keys: [field_name], data: { field_name => value } } + field_name = options[:es_field_name].nil? ? [name] : [options[:es_field_name]]&.flatten + data = {} + field_name.each{ |f| data[f] = value } + es_options = { keys: field_name, data: data } es_options[:pm_id] = target.id if target.class.name == 'ProjectMedia' model = { klass: target.class.name, id: target.id } ElasticSearchWorker.new.perform(YAML::dump(model), YAML::dump(es_options), 'update_doc') diff --git a/app/models/concerns/project_association.rb b/app/models/concerns/project_association.rb index 0200e8ebca..c1d482507b 100644 --- a/app/models/concerns/project_association.rb +++ b/app/models/concerns/project_association.rb @@ -60,7 +60,7 @@ def belonged_to_project(objid, pid, tid) validate :is_unique, on: :create, unless: proc { |p| p.is_being_copied } after_commit :add_elasticsearch_data, on: :create - after_commit :update_elasticsearch_data, on: :update + after_update :update_elasticsearch_data after_commit :destroy_elasticsearch_media , on: :destroy def get_versions_log(event_types = nil, field_names = nil, annotation_types = nil, whodunnit = nil, include_related = false) @@ -86,26 +86,21 @@ def add_elasticsearch_data def update_elasticsearch_data return if self.disable_es_callbacks || RequestStore.store[:disable_es_callbacks] - obj = self.class.find_by_id(self.id) - return if obj.nil? - data = { - 'team_id' => obj.team_id, - 'archived' => { method: 'archived', klass: obj.class.name, id: obj.id, type: 'int' }, - 'sources_count' => { method: 'sources_count', klass: 'ProjectMedia', id: obj.id, type: 'int' }, - 'user_id' => obj.user_id, - 'read' => obj.read.to_i, - 'media_published_at' => obj.media_published_at, - 'source_id' => obj.source_id, - 'source_name' => obj.source&.name, - 'project_id' => obj.project_id, - 'unmatched' => obj.unmatched, - 'channel' => obj.channel.values.flatten.map(&:to_i), - 'updated_at' => obj.updated_at.utc, - 'title' => obj.title - } - options = { keys: data.keys, data: data, pm_id: obj.id } - model = { klass: obj.class.name, id: obj.id } - ElasticSearchWorker.perform_in(1.second, YAML::dump(model), YAML::dump(options), 'update_doc') + data = {} + ['team_id', 'user_id', 'read', 'source_id', 'project_id', 'unmatched'].each do |fname| + data[fname] = self.send(fname).to_i if self.send("saved_change_to_#{fname}?") + end + ['archived', 'sources_count'].each do |fname| + data[fname] = { method: fname, klass: 'ProjectMedia', id: self.id, type: 'int' } if self.send("saved_change_to_#{fname}?") + end + data['channel'] = self.channel.values.flatten.map(&:to_i) if self.send(:saved_change_to_channel?) + data['source_name'] = self.source&.name if self.send(:saved_change_to_source_id?) + unless data.blank? + data['updated_at'] = self.updated_at.utc + options = { keys: data.keys, data: data, pm_id: self.id } + model = { klass: self.class.name, id: self.id } + ElasticSearchWorker.perform_in(1.second, YAML::dump(model), YAML::dump(options), 'update_doc') + end end def destroy_elasticsearch_media diff --git a/app/models/concerns/project_media_cached_fields.rb b/app/models/concerns/project_media_cached_fields.rb index 87ccf7dd17..d5f1161aef 100644 --- a/app/models/concerns/project_media_cached_fields.rb +++ b/app/models/concerns/project_media_cached_fields.rb @@ -210,7 +210,7 @@ def title_or_description_update cached_field :title, update_es: true, - es_field_name: :title_index, + es_field_name: [:title, :title_index], recalculate: :recalculate_title, update_on: title_or_description_update diff --git a/app/workers/elastic_search_worker.rb b/app/workers/elastic_search_worker.rb index 787d272d0b..87ca4da87c 100644 --- a/app/workers/elastic_search_worker.rb +++ b/app/workers/elastic_search_worker.rb @@ -2,9 +2,9 @@ class ElasticSearchWorker include Sidekiq::Worker - sidekiq_options :queue => :esqueue, :retry => 5 + sidekiq_options :queue => :esqueue, :retry => 3 - sidekiq_retry_in { |_count, _e| 5 } + sidekiq_retry_in { |_count, _e| 3 } def perform(model_data, options, type) model_data = begin YAML::load(model_data) rescue nil end diff --git a/test/controllers/elastic_search_test.rb b/test/controllers/elastic_search_test.rb index 4c669225c6..71bddc19f2 100644 --- a/test/controllers/elastic_search_test.rb +++ b/test/controllers/elastic_search_test.rb @@ -9,19 +9,20 @@ def setup test "should search media" do u = create_user @team = create_team - p = create_project team: @team m1 = create_valid_media - pm1 = create_project_media project: p, media: m1, disable_es_callbacks: false + pm1 = create_project_media team: @team, media: m1, disable_es_callbacks: false authenticate_with_user(u) pender_url = CheckConfig.get('pender_url_private') + '/api/medias' url = 'http://test.com' response = '{"type":"media","data":{"url":"' + url + '/normalized","type":"item", "title": "title_a", "description":"search_desc"}}' WebMock.stub_request(:get, pender_url).with({ query: { url: url } }).to_return(body: response) m2 = create_media(account: create_valid_account, url: url) - pm2 = create_project_media project: p, media: m2, disable_es_callbacks: false - sleep 10 - query = 'query Search { search(query: "{\"keyword\":\"title_a\",\"projects\":[' + p.id.to_s + ']}") { number_of_results, medias(first: 10) { edges { node { dbid } } } } }' + pm2 = create_project_media team: @team, media: m2, disable_es_callbacks: false + sleep 2 + Team.stubs(:current).returns(@team) + query = 'query Search { search(query: "{\"keyword\":\"title_a\"}") { number_of_results, medias(first: 10) { edges { node { dbid } } } } }' post :create, params: { query: query } + Team.unstub(:current) assert_response :success ids = [] JSON.parse(@response.body)['data']['search']['medias']['edges'].each do |id| @@ -29,9 +30,11 @@ def setup end assert_equal [pm2.id], ids create_comment text: 'title_a', annotated: pm1, disable_es_callbacks: false - sleep 20 - query = 'query Search { search(query: "{\"keyword\":\"title_a\",\"sort\":\"recent_activity\",\"projects\":[' + p.id.to_s + ']}") { medias(first: 10) { edges { node { dbid } } } } }' + sleep 2 + Team.stubs(:current).returns(@team) + query = 'query Search { search(query: "{\"keyword\":\"title_a\",\"sort\":\"recent_activity\"}") { medias(first: 10) { edges { node { dbid } } } } }' post :create, params: { query: query } + Team.unstub(:current) assert_response :success ids = [] JSON.parse(@response.body)['data']['search']['medias']['edges'].each do |id| @@ -57,7 +60,7 @@ def setup m2 = create_media(account: create_valid_account, url: url2) pm = create_project_media project: p, media: m, disable_es_callbacks: false pm2 = create_project_media project: p2, media: m2, disable_es_callbacks: false - sleep 10 + sleep 2 query = 'query Search { search(query: "{\"keyword\":\"title_a\",\"projects\":[' + p.id.to_s + ',' + p2.id.to_s + ']}") { medias(first: 10) { edges { node { dbid } } } } }' post :create, params: { query: query } assert_response :success @@ -67,7 +70,7 @@ def setup end assert_equal [pm.id, pm2.id], m_ids.sort pm2.analysis = { content: 'new_description' } - sleep 10 + sleep 2 query = 'query Search { search(query: "{\"keyword\":\"title_a\",\"projects\":[' + p.id.to_s + ',' + p2.id.to_s + ']}") { medias(first: 10) { edges { node { dbid, description } } } } }' post :create, params: { query: query } assert_response :success @@ -104,7 +107,6 @@ def setup test "should search with keyword" do t = create_team - p = create_project team: t pender_url = CheckConfig.get('pender_url_private') + '/api/medias' url = 'http://test.com' author_url = 'http://facebook.com/123456' @@ -119,7 +121,7 @@ def setup WebMock.stub_request(:get, pender_url).with({ query: { url: author_url } }).to_return(body: response) m = create_media url: url, account_id: nil, user_id: nil, account: nil, user: nil - pm = create_project_media project: p, media: m, disable_es_callbacks: false + pm = create_project_media team: t, media: m, disable_es_callbacks: false sleep 1 Team.current = t result = CheckSearch.new({keyword: "non_exist_title"}.to_json) @@ -143,13 +145,13 @@ def setup response = '{"type":"media","data":' + data.to_json + '}' WebMock.stub_request(:get, pender_url).with({ query: { url: media_url } }).to_return(body: response) m2 = create_media url: media_url, account_id: nil, user_id: nil, account: nil, user: nil - pm2 = create_project_media project: p, media: m2, disable_es_callbacks: false + pm2 = create_project_media team: t, media: m2, disable_es_callbacks: false sleep 1 result = CheckSearch.new({keyword: "search_desc"}.to_json) assert_equal [pm.id, pm2.id].sort, result.medias.map(&:id).sort # search in quote (with and operator) m = create_claim_media quote: 'keyworda and keywordb' - pm = create_project_media project: p, media: m, disable_es_callbacks: false + pm = create_project_media team: t, media: m, disable_es_callbacks: false sleep 1 result = CheckSearch.new({keyword: "keyworda and keywordb"}.to_json) assert_equal [pm.id], result.medias.map(&:id) diff --git a/test/controllers/graphql_controller_3_test.rb b/test/controllers/graphql_controller_3_test.rb index 5b22bc464d..267a64dc83 100644 --- a/test/controllers/graphql_controller_3_test.rb +++ b/test/controllers/graphql_controller_3_test.rb @@ -320,17 +320,15 @@ def setup test "should return updated offset from ES" do RequestStore.store[:skip_cached_field_update] = false - u = create_user is_admin: true authenticate_with_user(u) t = create_team - p = create_project team: t - pm1 = create_project_media project: p - create_relationship source_id: pm1.id, target_id: create_project_media(project: p).id, relationship_type: Relationship.confirmed_type - pm2 = create_project_media project: p - create_relationship source_id: pm2.id, target_id: create_project_media(project: p).id, relationship_type: Relationship.confirmed_type - create_relationship source_id: pm2.id, target_id: create_project_media(project: p).id, relationship_type: Relationship.confirmed_type - sleep 10 + pm1 = create_project_media team: t, disable_es_callbacks: false + create_relationship source_id: pm1.id, target_id: create_project_media(team: t).id, relationship_type: Relationship.confirmed_type + pm2 = create_project_media team: t, disable_es_callbacks: false + create_relationship source_id: pm2.id, target_id: create_project_media(team: t).id, relationship_type: Relationship.confirmed_type + create_relationship source_id: pm2.id, target_id: create_project_media(team: t).id, relationship_type: Relationship.confirmed_type + sleep 2 query = 'query CheckSearch { search(query: "{\"sort\":\"related\",\"id\":' + pm1.id.to_s + ',\"esoffset\":0,\"eslimit\":1}") {item_navigation_offset,medias(first:20){edges{node{dbid}}}}}' post :create, params: { query: query, team: t.slug } assert_response :success diff --git a/test/models/bot/fetch_2_test.rb b/test/models/bot/fetch_2_test.rb index 6e7024d8c4..a457b66bf4 100644 --- a/test/models/bot/fetch_2_test.rb +++ b/test/models/bot/fetch_2_test.rb @@ -107,7 +107,7 @@ def setup pm = ProjectMedia.last result = $repository.find(get_es_id(pm)) assert_equal pm.media.type, result['associated_type'] - assert_equal pm.original_title, result['title'] + assert_equal pm.title, result['title'] assert_equal "Earth isn't flat", pm.title end diff --git a/test/models/project_media_3_test.rb b/test/models/project_media_3_test.rb index de82676dee..e9b6503915 100644 --- a/test/models/project_media_3_test.rb +++ b/test/models/project_media_3_test.rb @@ -60,19 +60,21 @@ def setup test "should cache media published at" do RequestStore.store[:skip_cached_field_update] = false - url = 'http://twitter.com/test/123456' - pender_url = CheckConfig.get('pender_url_private') + '/api/medias' - response = '{"type":"media","data":{"url":"' + url + '","type":"item","published_at":"1989-01-25 08:30:00"}}' - WebMock.stub_request(:get, pender_url).with({ query: { url: url } }).to_return(body: response) - pm = create_project_media media: nil, url: url - assert_queries(0, '=') { assert_equal 601720200, pm.media_published_at } - response = '{"type":"media","data":{"url":"' + url + '","type":"item","published_at":"1989-01-25 08:31:00"}}' - WebMock.stub_request(:get, pender_url).with({ query: { url: url, refresh: '1' } }).to_return(body: response) - pm = ProjectMedia.find(pm.id) - pm.refresh_media = true - pm.save! - pm = ProjectMedia.find(pm.id) - assert_queries(0, '=') { assert_equal 601720260, pm.media_published_at } + Sidekiq::Testing.inline! do + url = 'http://twitter.com/test/123456' + pender_url = CheckConfig.get('pender_url_private') + '/api/medias' + response = '{"type":"media","data":{"url":"' + url + '","type":"item","published_at":"1989-01-25 08:30:00"}}' + WebMock.stub_request(:get, pender_url).with({ query: { url: url } }).to_return(body: response) + pm = create_project_media media: nil, url: url + assert_queries(0, '=') { assert_equal 601720200, pm.media_published_at } + response = '{"type":"media","data":{"url":"' + url + '","type":"item","published_at":"1989-01-25 08:31:00"}}' + WebMock.stub_request(:get, pender_url).with({ query: { url: url, refresh: '1' } }).to_return(body: response) + pm = ProjectMedia.find(pm.id) + pm.refresh_media = true + pm.save! + pm = ProjectMedia.find(pm.id) + assert_queries(0, '=') { assert_equal 601720260, pm.media_published_at } + end end test "should cache number of related items" do diff --git a/test/models/project_media_6_test.rb b/test/models/project_media_6_test.rb index 921e03dcfa..b5f46bd20d 100644 --- a/test/models/project_media_6_test.rb +++ b/test/models/project_media_6_test.rb @@ -475,6 +475,12 @@ def setup pm.save! assert_match /^text-/, pm.get_title # Uncached assert_match /^text-/, pm.title # Cached + # Verify save the title as a custom title + ProjectMedia.stubs(:get_title).returns(nil) + pm = create_project_media custom_title: 'Custom Title' + assert_equal 'Custom Title', pm.title + assert_equal 'custom_title', pm.reload.title_field + ProjectMedia.unstub(:get_title) end test "should avoid N + 1 queries problem when loading the team avatar of many items at once" do From 80fbcbf89366c9366ccb6709330e007805c340c0 Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Tue, 1 Oct 2024 12:23:12 +0300 Subject: [PATCH 36/39] CV2-5371: fix sentry error (#2062) --- app/models/project_media.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project_media.rb b/app/models/project_media.rb index 7d6ccb67f0..223403cc93 100644 --- a/app/models/project_media.rb +++ b/app/models/project_media.rb @@ -258,7 +258,7 @@ def self.destroy_related_medias(project_media, user_id = nil) end def replace_by(new_pm, skip_send_report = false) - return if self.id == new_pm.id || new_pm.nil? + return if new_pm.nil? || self.id == new_pm.id if self.team_id != new_pm.team_id raise I18n.t(:replace_by_media_in_the_same_team) elsif self.media.media_type != 'blank' From eaf9d8e384f956636ed304aed388f1832e3482c2 Mon Sep 17 00:00:00 2001 From: Martin Peck <51542678+sonoransun@users.noreply.github.com> Date: Tue, 1 Oct 2024 07:33:48 -0700 Subject: [PATCH 37/39] Fix setuptools version pin for check-api builds (#2063) * Pin version for this distribution. --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e15698ceb6..5884718d18 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,7 +35,7 @@ deploy_qa: AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION GITHUB_TOKEN: $GITHUB_TOKEN script: - - pip install setuptools==75.1.0 + - pip install setuptools==68.0.0 - pip install urllib3==2.0.6 - pip install botocore==1.31.62 - pip install boto3==1.28.62 @@ -107,7 +107,7 @@ deploy_live: AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION GITHUB_TOKEN: $GITHUB_TOKEN script: - - pip install setuptools==75.1.0 + - pip install setuptools==68.0.0 - pip install urllib3==2.0.6 - pip install botocore==1.31.62 - pip install boto3==1.28.62 From 6cae6c32716a13e56cc6c55b10f4a44543099e68 Mon Sep 17 00:00:00 2001 From: Mohamed El-Sawy Date: Tue, 1 Oct 2024 17:36:24 +0300 Subject: [PATCH 38/39] CV2-5391: use save instead of save! to avoid raising error (#2061) * CV2-5391: use save instead of save! to avoid raising error * CV2-5391: fix archived validation error --- app/models/bot/smooch.rb | 2 +- app/models/relationship.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/bot/smooch.rb b/app/models/bot/smooch.rb index 136f065c11..77f9d279a9 100644 --- a/app/models/bot/smooch.rb +++ b/app/models/bot/smooch.rb @@ -852,7 +852,7 @@ def self.save_text_message(message) end def self.create_project_media(message, type, extra) - extra.merge!({ archived: message['archived'] }) + extra.merge!({ archived: message['archived'] }) unless message['archived'].blank? channel_value = self.get_smooch_channel(message) extra.merge!({ channel: {main: channel_value }}) unless channel_value.nil? pm = ProjectMedia.create!({ media_type: type, smooch_message: message }.merge(extra)) diff --git a/app/models/relationship.rb b/app/models/relationship.rb index bf782b96ee..e0f79cf0aa 100644 --- a/app/models/relationship.rb +++ b/app/models/relationship.rb @@ -164,7 +164,7 @@ def self.create_unless_exists(source_id, target_id, relationship_type, options = options.each do |key, value| r.send("#{key}=", value) if r.respond_to?("#{key}=") end - r.save! + r.save ? r : nil end r end From 1e56f87a8776c755102bd8a9120fc5f9572dc566 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Tue, 1 Oct 2024 22:08:49 -0300 Subject: [PATCH 39/39] Reset item status to default one when claim/fact-check is detached. (#2064) Fixes CV2-4502. --- app/models/claim_description.rb | 15 +++++++ test/models/fact_check_test.rb | 72 +++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/app/models/claim_description.rb b/app/models/claim_description.rb index 7e2f8fed92..d331358166 100644 --- a/app/models/claim_description.rb +++ b/app/models/claim_description.rb @@ -17,6 +17,7 @@ class ClaimDescription < ApplicationRecord validate :cant_apply_article_to_item_if_article_is_in_the_trash after_commit :update_fact_check, on: [:update] after_update :update_report_status + after_update :reset_item_rating_if_removed after_update :replace_media, unless: proc { |cd| cd.disable_replace_media } after_update :migrate_claim_and_fact_check_logs, if: proc { |cd| cd.saved_change_to_project_media_id? && !cd.project_media_id.nil? } @@ -120,4 +121,18 @@ def migrate_claim_and_fact_check_logs def cant_apply_article_to_item_if_article_is_in_the_trash errors.add(:base, I18n.t(:cant_apply_article_to_item_if_article_is_in_the_trash)) if self.project_media && self.fact_check&.trashed end + + # If claim/fact-check is detached from item, reset the item status/rating back to the default one (unstarted, undetermined, etc.) + def reset_item_rating_if_removed + if self.project_media_id.nil? && !self.project_media_id_before_last_save.nil? + old_pm = ProjectMedia.find_by_id(self.project_media_id_before_last_save) + return if old_pm.nil? + status = old_pm.last_status_obj + default_status = old_pm.team.verification_statuses('media')[:default] + if status && status.status != default_status + status.status = default_status + status.save + end + end + end end diff --git a/test/models/fact_check_test.rb b/test/models/fact_check_test.rb index 43cf6e4662..9e2a887f0c 100644 --- a/test/models/fact_check_test.rb +++ b/test/models/fact_check_test.rb @@ -618,4 +618,76 @@ def setup assert_equal 1, fc2.tags.count assert_equal 'one', fc2.tags.first end + + test "should move item to default core status when fact-check is removed from it" do + RequestStore.store[:skip_cached_field_update] = false + create_verification_status_stuff + Sidekiq::Testing.inline! do + pm = create_project_media + assert_equal 'undetermined', pm.reload.status + cd = create_claim_description(project_media: pm) + fc = create_fact_check claim_description: cd, rating: 'false' + assert_equal 'false', pm.reload.status + cd.project_media = nil + cd.save! + assert_equal 'undetermined', pm.reload.status + end + end + + test "should move item to default custom status when fact-check is removed from it" do + RequestStore.store[:skip_cached_field_update] = false + create_verification_status_stuff + t = create_team + custom_statuses = { + "label": "Custom Status Label", + "active": "in_progress", + "default": "unstarted", + "statuses": [ + { + "id": "unstarted", + "style": { + "color": "blue" + }, + "locales": { + "en": { + "label": "Unstarted", + "description": "An item that did not start yet" + }, + "pt": { + "label": "Não iniciado ainda", + "description": "Um item que ainda não começou a ser verificado" + } + } + }, + { + "id": "in_progress", + "style": { + "color": "yellow" + }, + "locales": { + "en": { + "label": "Working on it", + "description": "We are working on it" + }, + "pt": { + "label": "Estamos trabalhando nisso", + "description": "Estamos trabalhando nisso" + } + } + } + ] + } + t.set_media_verification_statuses(custom_statuses) + t.save! + Sidekiq::Testing.inline! do + pm = create_project_media team: t + assert_equal 'unstarted', pm.reload.status + cd = create_claim_description(project_media: pm) + fc = create_fact_check claim_description: cd, rating: 'in_progress' + assert_equal 'in_progress', pm.reload.status + cd.project_media = nil + cd.save! + assert_equal 'unstarted', pm.reload.status + end + end end