Skip to content

Commit

Permalink
Update open data exports for Proposals (decidim#13702)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrés Pereira de Lucena <[email protected]>
  • Loading branch information
greenwoodt and andreslucena authored Dec 18, 2024
1 parent 9278ee0 commit 82b3f38
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 5 deletions.
10 changes: 9 additions & 1 deletion decidim-proposals/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -450,10 +450,16 @@ en:
attachments: The number of attachments this proposal has
author: The data for the author of this proposal
body: The proposal body
coauthorships_count: The number of co-authorships the proposal represents
comments: The number of comments this proposal has
component: The component that the proposal belongs to
cost: The total cost of the proposal in question
cost_report: A report of costs for the proposal
created_at: The date the proposal was created
created_in_meeting: Whether the proposal was created in a meeting
endorsements: The number of endorsements ("likes") this proposal has
followers: The number of followers this proposal has
execution_period: The period at which the proposal ran from beginning to end
follows_count: The number of followers this proposal has
id: The unique identifier for the proposal
is_amend: Wheter this proposal is ammedning another proposal
latitude: The latitude of the proposal in case it has a physical location
Expand All @@ -465,8 +471,10 @@ en:
reference: The unique identifier of the resource in this platform
related_proposals: The proposals related to this proposal
state: The status of this proposal (e.g. "Accepted")
state_published_at: A time stamp of the state of the proposal when published
taxonomies: The taxonomies that this proposal belongs to
title: The proposal title
updated_at: The date the proposal was last updated
url: The URL where this proposal can be found
votes: The number of votes this proposal has
withdrawn: Wheter this proposal has been withdrawn
Expand Down
12 changes: 10 additions & 2 deletions decidim-proposals/lib/decidim/proposals/proposal_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def serialize
latitude: proposal.latitude,
longitude: proposal.longitude,
state: proposal.state.to_s,
state_published_at: proposal.state_published_at,
reference: proposal.reference,
answer: ensure_translatable(proposal.answer),
answered_at: proposal.answered_at,
Expand All @@ -48,7 +49,7 @@ def serialize
},
comments: proposal.comments_count,
attachments: proposal.attachments.size,
followers: proposal.follows.size,
follows_count: proposal.follows_count,
published_at: proposal.published_at,
url:,
meeting_urls: meetings,
Expand All @@ -59,7 +60,14 @@ def serialize
url: original_proposal_url
},
withdrawn: proposal.withdrawn?,
withdrawn_at: proposal.withdrawn_at
withdrawn_at: proposal.withdrawn_at,
created_at: proposal.created_at,
updated_at: proposal.updated_at,
created_in_meeting: proposal.created_in_meeting,
coauthorships_count: proposal.coauthorships_count,
cost: proposal.cost,
cost_report: proposal.cost_report,
execution_period: proposal.execution_period
}
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module Proposals
subject do
described_class.new(proposal)
end

let!(:body) { { en: ::Faker::Lorem.sentence } }
let!(:proposal) { create(:proposal, :accepted, body:) }
let!(:taxonomies) { create_list(:taxonomy, 2, :with_parent, organization: component.organization) }
let(:participatory_process) { component.participatory_space }
Expand All @@ -19,7 +19,8 @@ module Proposals

let!(:proposals_component) { create(:component, manifest_name: "proposals", participatory_space: participatory_process) }
let(:other_proposals) { create_list(:proposal, 2, component: proposals_component) }
let(:body) { Decidim::Faker::Localized.localized { ::Faker::Lorem.sentences(number: 3).join("\n") } }

let(:serialized) { subject.serialize }

let(:expected_answer) do
answer = proposal.answer
Expand Down Expand Up @@ -209,6 +210,18 @@ module Proposals
expect(serialized).to include(attachments: proposal.attachments.count)
end

it "serializes the state at which the proposal was published at" do
expect(serialized).to include(state_published_at: proposal.state_published_at)
end

it "serializes the how many co-authorships exist" do
expect(serialized).to include(coauthorships_count: proposal.coauthorships_count)
end

it "serializes the number of followers of the proposal" do
expect(serialized).to include(follows_count: proposal.follows_count)
end

it "serializes the endorsements" do
expect(serialized[:endorsements]).to include(total_count: proposal.endorsements.count)
expect(serialized[:endorsements]).to include(user_endorsements: proposal.endorsements.for_listing.map { |identity| identity.normalized_author&.name })
Expand All @@ -228,6 +241,62 @@ module Proposals
expect(serialized[:original_proposal][:url]).to be_nil || include("http", proposal.id.to_s)
end

it "serialize the created at date" do
expect(serialized).to include(created_at: proposal.created_at)
end

it "serialize the updated at date" do
expect(serialized).to include(updated_at: proposal.updated_at)
end

it "serializes whether the proposal was created in a meeting" do
expect(serialized).to include(created_in_meeting: proposal.created_in_meeting)
end

it "serializes the cost of the proposal" do
expect(serialized).to include(cost: proposal.cost)
end

it "serializes the execution period of the proposal" do
expect(serialized).to include(execution_period: proposal.execution_period)
end

# This is an internal field for admins which should not be published
context "when proposal notes count are hidden" do
it "does not publish them" do
expect(serialized).not_to include(proposal_notes_count: proposal.proposal_notes_count)
end
end

# This is an internal field for admins which should not be published
context "when valuation assignments are hidden" do
it "does not publish them" do
expect(serialized).not_to include(valuation_assignments_count: proposal.valuation_assignments_count)
end
end

context "when proposals with costs that are not published" do
let!(:proposal) { create(:proposal, :with_answer) }
let(:cost) { proposal.cost }
let(:cost_report) { proposal.cost_report }
let(:execution_period) { proposal.execution_period }
let(:answer) { proposal.answer }

before do
proposal.update!(cost: nil, cost_report: nil, execution_period: nil, answer: nil, state_published_at: nil)
end

it "includes costs with a proposal not published" do
expect(serialized).to include(
cost: nil,
cost_report: nil,
execution_period: nil,
answer: expected_answer,
state_published_at: nil
)
end
end

context "with proposal having an answer" do
let!(:proposal) { create(:proposal, :with_answer) }

Expand All @@ -236,6 +305,37 @@ module Proposals
end
end

context "when the proposal is answered but not published" do
before do
proposal.update!(answered_at:, state_published_at: nil)
end

let(:answered_at) { Time.current }

it "includes the answered_at timestamp and leaves state_published_at nil" do
expect(serialized).to include(
answered_at:,
state_published_at: nil
)
end
end

context "when the proposal is answered and published" do
before do
proposal.update!(answered_at:, state_published_at:)
end

let(:answered_at) { Time.current }
let(:state_published_at) { answered_at + 1.day }

it "includes both answered_at and state_published_at timestamps" do
expect(serialized).to include(
answered_at:,
state_published_at:
)
end
end

context "when the votes are hidden" do
let!(:component) { create(:proposal_component, :with_votes_hidden) }
let!(:proposal) { create(:proposal, component:) }
Expand Down

0 comments on commit 82b3f38

Please sign in to comment.