Add new GraphQL types for budget investments
- added 2 new types - modified the models to get data through graphQL - modified the corresponding spec - also testing that hidden comments do not show up - modified comments specs bc now it returns comments on budget investments
This commit is contained in:
13
app/graphql/types/budget_investment_type.rb
Normal file
13
app/graphql/types/budget_investment_type.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
module Types
|
||||||
|
class BudgetInvestmentType < Types::BaseObject
|
||||||
|
field :id, ID, null: false
|
||||||
|
field :public_author, Types::UserType, null: true
|
||||||
|
field :price, GraphQL::Types::BigInt, null: true
|
||||||
|
field :feasibility, String, null: true
|
||||||
|
field :title, String, null: true
|
||||||
|
field :description, String, null: true
|
||||||
|
field :location, String, null: true
|
||||||
|
field :comments, Types::CommentType.connection_type, null: true
|
||||||
|
field :comments_count, Integer, null: true
|
||||||
|
end
|
||||||
|
end
|
||||||
19
app/graphql/types/budget_type.rb
Normal file
19
app/graphql/types/budget_type.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
module Types
|
||||||
|
class BudgetType < Types::BaseObject
|
||||||
|
field :id, ID, null: false
|
||||||
|
field :name, String, null: true
|
||||||
|
field :phase, String, null: true
|
||||||
|
field :investments, Types::BudgetInvestmentType.connection_type, "Returns all investments", null: false
|
||||||
|
field :investment, Types::BudgetInvestmentType, null: false do
|
||||||
|
argument :id, ID, required: true, default_value: false
|
||||||
|
end
|
||||||
|
|
||||||
|
def investments
|
||||||
|
Budget::Investment.public_for_api
|
||||||
|
end
|
||||||
|
|
||||||
|
def investment(id:)
|
||||||
|
Budget::Investment.find(id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
module Types
|
module Types
|
||||||
class QueryType < Types::BaseObject
|
class QueryType < Types::BaseObject
|
||||||
|
field :budgets, Types::BudgetType.connection_type, "Returns all budgets", null: false
|
||||||
|
field :budget, Types::BudgetType, "Returns budget for ID", null: false do
|
||||||
|
argument :id, ID, required: true, default_value: false
|
||||||
|
end
|
||||||
|
|
||||||
field :comments, Types::CommentType.connection_type, "Returns all comments", null: false
|
field :comments, Types::CommentType.connection_type, "Returns all comments", null: false
|
||||||
field :comment, Types::CommentType, "Returns comment for ID", null: false do
|
field :comment, Types::CommentType, "Returns comment for ID", null: false do
|
||||||
argument :id, ID, required: true, default_value: false
|
argument :id, ID, required: true, default_value: false
|
||||||
@@ -47,6 +52,14 @@ module Types
|
|||||||
argument :id, ID, required: true, default_value: false
|
argument :id, ID, required: true, default_value: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def budgets
|
||||||
|
Budget.public_for_api
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget(id:)
|
||||||
|
Budget.find(id)
|
||||||
|
end
|
||||||
|
|
||||||
def comments
|
def comments
|
||||||
Comment.public_for_api
|
Comment.public_for_api
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class Budget < ApplicationRecord
|
|||||||
scope :balloting, -> { where(phase: "balloting") }
|
scope :balloting, -> { where(phase: "balloting") }
|
||||||
scope :reviewing_ballots, -> { where(phase: "reviewing_ballots") }
|
scope :reviewing_ballots, -> { where(phase: "reviewing_ballots") }
|
||||||
scope :finished, -> { where(phase: "finished") }
|
scope :finished, -> { where(phase: "finished") }
|
||||||
|
scope :public_for_api, -> { published }
|
||||||
|
|
||||||
class << self; undef :open; end
|
class << self; undef :open; end
|
||||||
scope :open, -> { where.not(phase: "finished") }
|
scope :open, -> { where.not(phase: "finished") }
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class Budget
|
|||||||
include Mappable
|
include Mappable
|
||||||
include Documentable
|
include Documentable
|
||||||
include SDG::Relatable
|
include SDG::Relatable
|
||||||
|
include HasPublicAuthor
|
||||||
|
|
||||||
acts_as_taggable_on :valuation_tags
|
acts_as_taggable_on :valuation_tags
|
||||||
acts_as_votable
|
acts_as_votable
|
||||||
@@ -111,6 +112,7 @@ class Budget
|
|||||||
end
|
end
|
||||||
|
|
||||||
scope :for_render, -> { includes(:heading) }
|
scope :for_render, -> { includes(:heading) }
|
||||||
|
scope :public_for_api, -> { where(budget: Budget.public_for_api) }
|
||||||
|
|
||||||
def self.by_valuator(valuator_id)
|
def self.by_valuator(valuator_id)
|
||||||
where(budget_valuator_assignments: { valuator_id: valuator_id }).joins(:valuator_assignments)
|
where(budget_valuator_assignments: { valuator_id: valuator_id }).joins(:valuator_assignments)
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ class Comment < ApplicationRecord
|
|||||||
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||||
scope :public_for_api, -> do
|
scope :public_for_api, -> do
|
||||||
not_valuations
|
not_valuations
|
||||||
.where(commentable: [Debate.public_for_api, Proposal.public_for_api, Poll.public_for_api])
|
.where(commentable: [Debate.public_for_api,
|
||||||
|
Proposal.public_for_api,
|
||||||
|
Poll.public_for_api,
|
||||||
|
Budget::Investment.public_for_api])
|
||||||
end
|
end
|
||||||
|
|
||||||
scope :sort_by_most_voted, -> { order(confidence_score: :desc, created_at: :desc) }
|
scope :sort_by_most_voted, -> { order(confidence_score: :desc, created_at: :desc) }
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ The models are the following:
|
|||||||
| `User` | Users |
|
| `User` | Users |
|
||||||
| `Debate` | Debates |
|
| `Debate` | Debates |
|
||||||
| `Proposal` | Proposals |
|
| `Proposal` | Proposals |
|
||||||
|
| `Budget` | Participatory budgets |
|
||||||
|
| `Budget::Investment` | Budget investments |
|
||||||
| `Comment` | Comments on debates, proposals and other comments |
|
| `Comment` | Comments on debates, proposals and other comments |
|
||||||
| `Geozone` | Geozones (districts) |
|
| `Geozone` | Geozones (districts) |
|
||||||
| `ProposalNotification` | Notifications related to proposals |
|
| `ProposalNotification` | Notifications related to proposals |
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ La lista de modelos es la siguiente:
|
|||||||
| `User` | Usuarios |
|
| `User` | Usuarios |
|
||||||
| `Debate` | Debates |
|
| `Debate` | Debates |
|
||||||
| `Proposal` | Propuestas |
|
| `Proposal` | Propuestas |
|
||||||
|
| `Budget` | Presupuestos participativos |
|
||||||
|
| `Budget::Investment` | Proyectos de gasto |
|
||||||
| `Comment` | Comentarios en debates, propuestas y otros comentarios |
|
| `Comment` | Comentarios en debates, propuestas y otros comentarios |
|
||||||
| `Geozone` | Geozonas (distritos) |
|
| `Geozone` | Geozonas (distritos) |
|
||||||
| `ProposalNotification` | Notificaciones asociadas a propuestas |
|
| `ProposalNotification` | Notificaciones asociadas a propuestas |
|
||||||
|
|||||||
@@ -193,6 +193,17 @@ describe "Consul Schema" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Budgets" do
|
||||||
|
it "does not include unpublished budgets" do
|
||||||
|
create(:budget, :drafting, name: "Draft")
|
||||||
|
|
||||||
|
response = execute("{ budgets { edges { node { name } } } }")
|
||||||
|
received_names = extract_fields(response, "budgets", "name")
|
||||||
|
|
||||||
|
expect(received_names).to eq []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "Debates" do
|
describe "Debates" do
|
||||||
it "does not include hidden debates" do
|
it "does not include hidden debates" do
|
||||||
create(:debate, title: "Visible")
|
create(:debate, title: "Visible")
|
||||||
@@ -252,16 +263,17 @@ describe "Consul Schema" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "Comments" do
|
describe "Comments" do
|
||||||
it "only returns comments from proposals, debates and polls" do
|
it "only returns comments from proposals, debates, polls and Budget::Investment" do
|
||||||
create(:comment, commentable: create(:proposal))
|
create(:comment, commentable: create(:proposal))
|
||||||
create(:comment, commentable: create(:debate))
|
create(:comment, commentable: create(:debate))
|
||||||
create(:comment, commentable: create(:poll))
|
create(:comment, commentable: create(:poll))
|
||||||
build(:comment, commentable: create(:budget_investment)).save!(skip_validation: true)
|
create(:comment, commentable: create(:topic))
|
||||||
|
create(:comment, commentable: create(:budget_investment))
|
||||||
|
|
||||||
response = execute("{ comments { edges { node { commentable_type } } } }")
|
response = execute("{ comments { edges { node { commentable_type } } } }")
|
||||||
received_commentables = extract_fields(response, "comments", "commentable_type")
|
received_commentables = extract_fields(response, "comments", "commentable_type")
|
||||||
|
|
||||||
expect(received_commentables).to match_array ["Proposal", "Debate", "Poll"]
|
expect(received_commentables).to match_array ["Proposal", "Debate", "Poll", "Budget::Investment"]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "displays comments of authors even if public activity is set to false" do
|
it "displays comments of authors even if public activity is set to false" do
|
||||||
@@ -336,6 +348,19 @@ describe "Consul Schema" do
|
|||||||
expect(received_comments).to match_array ["I can see the poll"]
|
expect(received_comments).to match_array ["I can see the poll"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not include comments from hidden investments" do
|
||||||
|
visible_investment = create(:budget_investment)
|
||||||
|
hidden_investment = create(:budget_investment, :hidden)
|
||||||
|
|
||||||
|
create(:comment, commentable: visible_investment, body: "I can see the investment")
|
||||||
|
create(:comment, commentable: hidden_investment, body: "This investment is hidden!")
|
||||||
|
|
||||||
|
response = execute("{ comments { edges { node { body } } } }")
|
||||||
|
received_comments = extract_fields(response, "comments", "body")
|
||||||
|
|
||||||
|
expect(received_comments).to match_array ["I can see the investment"]
|
||||||
|
end
|
||||||
|
|
||||||
it "does not include comments of debates that are not public" do
|
it "does not include comments of debates that are not public" do
|
||||||
not_public_debate = create(:debate, :hidden)
|
not_public_debate = create(:debate, :hidden)
|
||||||
not_public_debate_comment = create(:comment, commentable: not_public_debate)
|
not_public_debate_comment = create(:comment, commentable: not_public_debate)
|
||||||
@@ -369,6 +394,16 @@ describe "Consul Schema" do
|
|||||||
expect(received_comments).not_to include(not_public_poll_comment.body)
|
expect(received_comments).not_to include(not_public_poll_comment.body)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not include comments of investments that are not public" do
|
||||||
|
investment = create(:budget_investment, budget: create(:budget, :drafting))
|
||||||
|
not_public_investment_comment = create(:comment, commentable: investment)
|
||||||
|
|
||||||
|
response = execute("{ comments { edges { node { body } } } }")
|
||||||
|
received_comments = extract_fields(response, "comments", "body")
|
||||||
|
|
||||||
|
expect(received_comments).not_to include(not_public_investment_comment.body)
|
||||||
|
end
|
||||||
|
|
||||||
it "only links public comments" do
|
it "only links public comments" do
|
||||||
user = create(:administrator).user
|
user = create(:administrator).user
|
||||||
create(:comment, author: user, body: "Public")
|
create(:comment, author: user, body: "Public")
|
||||||
@@ -642,4 +677,35 @@ describe "Consul Schema" do
|
|||||||
expect(Time.zone.parse(received_timestamps.first)).to eq Time.zone.parse("2017-12-31 9:00:00")
|
expect(Time.zone.parse(received_timestamps.first)).to eq Time.zone.parse("2017-12-31 9:00:00")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Budget investment" do
|
||||||
|
it "does not include hidden comments" do
|
||||||
|
budget = create(:budget)
|
||||||
|
investment = create(:budget_investment, budget: budget)
|
||||||
|
|
||||||
|
create(:comment, commentable: investment, body: "Visible")
|
||||||
|
create(:comment, :hidden, commentable: investment, body: "Hidden")
|
||||||
|
|
||||||
|
query = <<~GRAPHQL
|
||||||
|
{
|
||||||
|
budget(id: #{budget.id}) {
|
||||||
|
investment(id: #{investment.id}) {
|
||||||
|
comments {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GRAPHQL
|
||||||
|
|
||||||
|
response = execute(query)
|
||||||
|
received_bodies = extract_fields(response, "budget.investment.comments", "body")
|
||||||
|
|
||||||
|
expect(received_bodies).to eq ["Visible"]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -175,8 +175,14 @@ describe Comment do
|
|||||||
expect(Comment.public_for_api).to be_empty
|
expect(Comment.public_for_api).to be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not return comments on elements which are not debates or proposals" do
|
it "returns comments on budget investments" do
|
||||||
create(:comment, commentable: create(:budget_investment))
|
comment = create(:comment, commentable: create(:budget_investment))
|
||||||
|
|
||||||
|
expect(Comment.public_for_api).to eq [comment]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not return comments on elements which are not debates, proposals or budget investments" do
|
||||||
|
create(:comment, commentable: create(:topic))
|
||||||
|
|
||||||
expect(Comment.public_for_api).to be_empty
|
expect(Comment.public_for_api).to be_empty
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user