From 6ee2f05cee17f0b5b0da4bc9f9ce6a75d1e81e67 Mon Sep 17 00:00:00 2001 From: Jay Joshua Date: Wed, 20 Nov 2024 00:45:20 +0100 Subject: [PATCH] Add new field to TeamType to allow bot queries Add a bot_query field to TeamType which will send queries to the backend simulating tipline bot queries. Initially, this is returning the most recent Explainers/FactChecks as TiplineSearchResults, but eventually it will be hooked to the actual bot implementation. --- app/graph/types/team_type.rb | 52 +++++++++++++ app/graph/types/tipline_search_result_type.rb | 11 +++ .../controllers/graphql_controller_11_test.rb | 73 +++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 app/graph/types/tipline_search_result_type.rb diff --git a/app/graph/types/team_type.rb b/app/graph/types/team_type.rb index 25a2d1547..5268ef067 100644 --- a/app/graph/types/team_type.rb +++ b/app/graph/types/team_type.rb @@ -399,4 +399,56 @@ def api_keys def statistics(period:, language: nil, platform: nil) TeamStatistics.new(object, period, language, platform) end + + field :bot_query, [TiplineSearchResultType], null: true do + argument :search_text, GraphQL::Types::String, required: true + end + + def bot_query(search_text:) + unless User.current&.is_admin + raise GraphQL::ExecutionError, "You do not have permission to perform this action" + end + + return nil unless search_text + + explainers = object.explainers.order(created_at: :desc).limit(3) + + fact_checks = FactCheck.joins(:claim_description) + .where(claim_descriptions: { team_id: object.id }) + .order('fact_checks.created_at DESC') + .limit(3) + + combined_records = explainers + fact_checks + sorted_records = combined_records.sort_by(&:created_at).reverse + + top_three = sorted_records.first(3) + + results = top_three.map do |record| + if record.is_a?(Explainer) + TiplineSearchResult.new( + team: object, + title: record.title, + body: record.description, + image_url: nil, + language: record.language, + url: record.url, + type: :explainer, + format: :text + ) + elsif record.is_a?(FactCheck) + TiplineSearchResult.new( + team: object, + title: record.title, + body: record.summary, + image_url: nil, + language: record.language, + url: record.url, + type: :fact_check, + format: :text + ) + end + end + + results + end end diff --git a/app/graph/types/tipline_search_result_type.rb b/app/graph/types/tipline_search_result_type.rb new file mode 100644 index 000000000..15cefacc6 --- /dev/null +++ b/app/graph/types/tipline_search_result_type.rb @@ -0,0 +1,11 @@ +class TiplineSearchResultType < DefaultObject + description "Represents a search result for the tipline" + + field :title, GraphQL::Types::String, null: false + field :body, GraphQL::Types::String, null: true + field :image_url, GraphQL::Types::String, null: true + field :language, GraphQL::Types::String, null: true + field :url, GraphQL::Types::String, null: true + field :type, GraphQL::Types::String, null: false + field :format, GraphQL::Types::String, null: false +end diff --git a/test/controllers/graphql_controller_11_test.rb b/test/controllers/graphql_controller_11_test.rb index 08eb5ded8..2fde50432 100644 --- a/test/controllers/graphql_controller_11_test.rb +++ b/test/controllers/graphql_controller_11_test.rb @@ -301,4 +301,77 @@ def teardown assert_response :success assert_equal 2, JSON.parse(@response.body).dig('data', 'team', 'tipline_requests', 'edges').size end + + test "super admin user should receive the 3 most recent FactChecks or Explainers" do + # Create a super admin user + super_admin = create_user(is_admin: true) + create_team_user team: @t, user: super_admin, role: 'admin' + + # Authenticate with super admin user + authenticate_with_user(super_admin) + + # Create ClaimDescriptions associated with the team + claim_desc1 = create_claim_description(team: @t) + claim_desc2 = create_claim_description(team: @t) + + # Create FactChecks and set created_at + another_fact_check = create_fact_check( + title: "Another FactCheck", + claim_description: claim_desc1 + ) + another_fact_check.update_column(:created_at, 4.days.ago) + + newer_fact_check = create_fact_check( + title: "Newer FactCheck", + claim_description: claim_desc2 + ) + newer_fact_check.update_column(:created_at, 2.days.ago) + + # Create Explainers and set created_at + older_explainer = create_explainer( + team: @t, + title: "Older Explainer" + ) + older_explainer.update_column(:created_at, 3.days.ago) + + newest_explainer = create_explainer( + team: @t, + title: "Newest Explainer" + ) + newest_explainer.update_column(:created_at, 1.day.ago) + + yet_another_explainer = create_explainer( + team: @t, + title: "Yet Another Explainer" + ) + yet_another_explainer.update_column(:created_at, Time.now) + + # Perform the GraphQL query + query = <<~GRAPHQL + query { + team(slug: "#{@t.slug}") { + bot_query(searchText: "test") { + title + type + format + } + } + } + GRAPHQL + + post :create, params: { query: query, team: @t.slug } + assert_response :success + + data = JSON.parse(@response.body)['data']['team']['bot_query'] + assert_equal 3, data.size, "Expected 3 results" + + expected_titles = ["Yet Another Explainer", "Newest Explainer", "Older Explainer"] + actual_titles = data.map { |result| result['title'] } + assert_equal expected_titles, actual_titles, "Results should be the 3 most recent records" + + # Verify types + expected_types = ['explainer', 'explainer', 'explainer'] + actual_types = data.map { |result| result['type'] } + assert_equal expected_types, actual_types, "Types should match the records" + end end