Skip to content

Commit

Permalink
Adding a data_points field to Feed and exposing it on GraphQL API.
Browse files Browse the repository at this point in the history
* Adding a new column/field `data_points` to the `Feed` model, which is an array of integers, empty by default
* Validate that it contains allowed values
* Expose `data_points` on GraphQL API, for feed type and create mutation
* Automated tests added

References: CV2-4034 and CV2-3923.
  • Loading branch information
caiosba committed Jan 8, 2024
1 parent 8c23e7b commit 89c3dd1
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 3 deletions.
1 change: 1 addition & 0 deletions app/graph/mutations/feed_mutations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Create < Mutations::CreateMutation

argument :name, GraphQL::Types::String, required: true
argument :licenses, [GraphQL::Types::Int, null: true], required: true
argument :data_points, [GraphQL::Types::Int, null: true], required: false
end

class Update < Mutations::UpdateMutation
Expand Down
1 change: 1 addition & 0 deletions app/graph/types/feed_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ def feed_invitations

field :teams, TeamType.connection_type, null: false
field :feed_teams, FeedTeamType.connection_type, null: false
field :data_points, [GraphQL::Types::Int, null: true], null: true
end
2 changes: 2 additions & 0 deletions app/models/feed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class Feed < ApplicationRecord
PROHIBITED_FILTERS = ['team_id', 'feed_id', 'clusterize']
LICENSES = { 1 => 'academic', 2 => 'commercial', 3 => 'open_source' }
validates_inclusion_of :licenses, in: LICENSES.keys, if: proc { |feed| feed.discoverable }
DATA_POINTS = { 1 => 'published_fact_checks', 2 => 'media_claim_requests', 3 => 'tags' }
validates_inclusion_of :data_points, in: DATA_POINTS.keys

# Filters for the whole feed: applies to all data from all teams
def get_feed_filters
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20240107223820_add_data_points_to_feeds.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddDataPointsToFeeds < ActiveRecord::Migration[6.1]
def change
add_column :feeds, :data_points, :integer, array: true, default: []
end
end
7 changes: 4 additions & 3 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2023_12_10_015830) do
ActiveRecord::Schema.define(version: 2024_01_07_223820) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -337,6 +337,7 @@
t.string "tags", default: [], array: true
t.integer "licenses", default: [], array: true
t.boolean "discoverable", default: false
t.integer "data_points", default: [], array: true
t.index ["saved_search_id"], name: "index_feeds_on_saved_search_id"
t.index ["team_id"], name: "index_feeds_on_team_id"
t.index ["user_id"], name: "index_feeds_on_user_id"
Expand Down Expand Up @@ -666,6 +667,7 @@
t.datetime "updated_at", null: false
t.string "state"
t.index ["external_id", "state"], name: "index_tipline_messages_on_external_id_and_state", unique: true
t.index ["external_id"], name: "index_tipline_messages_on_external_id"
t.index ["team_id"], name: "index_tipline_messages_on_team_id"
t.index ["uid"], name: "index_tipline_messages_on_uid"
end
Expand Down Expand Up @@ -806,8 +808,7 @@
end

create_table "versions", id: :serial, force: :cascade do |t|
t.string "item_type"
t.string "{:null=>false}"
t.string "item_type", null: false
t.string "item_id", null: false
t.string "event", null: false
t.string "whodunnit"
Expand Down
2 changes: 2 additions & 0 deletions lib/relay.idl
Original file line number Diff line number Diff line change
Expand Up @@ -2311,6 +2311,7 @@ input CreateFeedInput {
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
dataPoints: [Int]
description: String
discoverable: Boolean
licenses: [Int]!
Expand Down Expand Up @@ -8053,6 +8054,7 @@ Feed type
type Feed implements Node {
created_at: String
current_feed_team: FeedTeam
data_points: [Int]
dbid: Int
description: String
discoverable: Boolean
Expand Down
34 changes: 34 additions & 0 deletions public/relay.json
Original file line number Diff line number Diff line change
Expand Up @@ -14294,6 +14294,22 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "dataPoints",
"description": null,
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
Expand Down Expand Up @@ -43761,6 +43777,24 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "data_points",
"description": null,
"args": [

],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "dbid",
"description": null,
Expand Down
18 changes: 18 additions & 0 deletions test/controllers/graphql_controller_12_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,22 @@ def teardown
assert_response :success
assert_equal 1, JSON.parse(@response.body).dig('data', 'search', 'number_of_results')
end

test "should set and get feed data points" do
authenticate_with_user(@u)

query = 'mutation { createFeed(input: { name: "' + random_string + '", dataPoints: [1, 2, 3], licenses: [] }) { feed { dbid, data_points } } }'
assert_difference 'Feed.count' do
post :create, params: { query: query, team: @t.slug }
end
assert_response :success

feed = Feed.find(JSON.parse(@response.body).dig('data', 'createFeed', 'feed', 'dbid'))
assert_equal [1, 2, 3].sort, feed.data_points.sort

query = 'query { feed(id: ' + feed.id.to_s + ') { data_points } }'
post :create, params: { query: query, team: @t.slug }
assert_response :success
assert_equal [1, 2, 3].sort, JSON.parse(@response.body).dig('data', 'feed', 'data_points').sort
end
end
16 changes: 16 additions & 0 deletions test/models/feed_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,20 @@ def setup
f.destroy!
end
end

test "should create feed without data points" do
f = create_feed
assert_equal [], f.data_points
end

test "should create feed with valid data points" do
f = create_feed data_points: [1, 2]
assert_equal [1, 2], f.data_points
end

test "should not create feed with invalid data points" do
assert_raises ActiveRecord::RecordInvalid do
create_feed data_points: [0, 1]
end
end
end

0 comments on commit 89c3dd1

Please sign in to comment.