Add widget feeds to homepage

Note there is some funkiness going on with class loadings
Had to create a `feed` and `widget_feed` table even though in this
first version the Widget::Feed includes only uses ActiveModel instead
of ActiveRecord, otherwise some specs failed

We’ll figure it out and clean up 😌
This commit is contained in:
rgarcia
2018-05-22 20:01:06 +02:00
committed by decabeza
parent c7f85c4173
commit 0e097973cc
13 changed files with 242 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
class Widget
class Feed < ActiveRecord::Base
end
end

View File

@@ -6,6 +6,7 @@ class WelcomeController < ApplicationController
def index
@header = Widget::Card.header.first
@feeds = Widget::Feed.active
@cards = Widget::Card.body
end

46
app/models/widget/feed.rb Normal file
View File

@@ -0,0 +1,46 @@
class Widget
class Feed
include ActiveModel::Model
KINDS = %w(proposals debates processes)
attr_accessor :kind
def initialize(attributes={})
super
@kind = attributes[:kind]
end
def active?(kind)
Setting["feature.homepage.widgets.feeds.#{kind}"].present?
end
def self.active
KINDS.collect do |kind|
feed = new(kind: kind)
feed if feed.active?(kind)
end.compact
end
def items
send(kind)
end
def proposals
Proposal.sort_by_hot_score.limit(limit)
end
def debates
Debate.sort_by_hot_score.limit(limit)
end
def processes
Legislation::Process.open.limit(limit)
end
def limit
3
end
end
end

View File

@@ -0,0 +1,16 @@
<h1>Feeds</h1>
<% @feeds.each do |feed| %>
<div>
<strong>Most active <%= feed.kind %></strong>
</div>
<% feed.items.each do |item| %>
<div class="<%= item.class.to_s.parameterize('_') %>">
<%= item.title %>
</div>
<br/>
<% end %>
<% end %>

View File

@@ -24,6 +24,7 @@
</div>
<%= render "header", header: @header %>
<%= render "feeds" %>
<%= render "cards" %>
<% if feature?("user.recommendations") && (@recommended_debates.present? || @recommended_proposals.present?) %>

View File

@@ -63,4 +63,8 @@ section "Creating Settings" do
Setting.create(key: 'map_longitude', value: -3.7)
Setting.create(key: 'map_zoom', value: 10)
Setting.create(key: 'related_content_score_threshold', value: -0.3)
Setting['feature.homepage.widgets.feeds.proposals'] = true
Setting['feature.homepage.widgets.feeds.debates'] = true
Setting['feature.homepage.widgets.feeds.processes'] = true
end

View File

@@ -0,0 +1,6 @@
class CreateWidgetFeeds < ActiveRecord::Migration
def change
create_table :widget_feeds do |t|
end
end
end

View File

@@ -0,0 +1,6 @@
class CreateFeeds < ActiveRecord::Migration
def change
create_table :feeds do |t|
end
end
end

View File

@@ -378,6 +378,9 @@ ActiveRecord::Schema.define(version: 20180519132715) do
add_index "failed_census_calls", ["user_id"], name: "index_failed_census_calls_on_user_id", using: :btree
create_table "feeds", force: :cascade do |t|
end
create_table "flags", force: :cascade do |t|
t.integer "user_id"
t.string "flaggable_type"
@@ -1236,6 +1239,9 @@ ActiveRecord::Schema.define(version: 20180519132715) do
t.datetime "updated_at", null: false
end
create_table "widget_feeds", force: :cascade do |t|
end
add_foreign_key "administrators", "users"
add_foreign_key "annotations", "legacy_legislations"
add_foreign_key "annotations", "users"

View File

@@ -125,3 +125,8 @@ Setting['map_zoom'] = 10
Setting['related_content_score_threshold'] = -0.3
Setting["feature.user.skip_verification"] = 'true'
Setting['feature.homepage.widgets.feeds.proposals'] = true
Setting['feature.homepage.widgets.feeds.debates'] = true
Setting['feature.homepage.widgets.feeds.processes'] = true

View File

@@ -818,6 +818,11 @@ FactoryBot.define do
published false
end
trait :open do
start_date 1.week.ago
end_date 1.week.from_now
end
end
factory :legislation_draft_version, class: 'Legislation::DraftVersion' do
@@ -980,4 +985,7 @@ LOREM_IPSUM
end
end
factory :widget_feed, class: 'Widget::Feed' do
end
end

View File

@@ -6,10 +6,72 @@ feature 'Homepage' do
admin = create(:administrator).user
login_as(admin)
Setting['feature.homepage.widgets.feeds.proposals'] = false
Setting['feature.homepage.widgets.feeds.debates'] = false
Setting['feature.homepage.widgets.feeds.processes'] = false
Setting['feature.user.recommendations'] = false
end
let(:proposals_setting) { Setting.where(key: 'feature.homepage.widgets.feeds.proposals').first }
let(:debates_setting) { Setting.where(key: 'feature.homepage.widgets.feeds.debates').first }
let(:processes_setting) { Setting.where(key: 'feature.homepage.widgets.feeds.processes').first }
scenario "Header" do
end
context "Feeds" do
scenario "Proposals" do
5.times { create(:proposal) }
visit admin_homepage_path
within("#setting_#{proposals_setting.id}") do
click_button "Enable"
end
expect(page).to have_content "Value updated"
visit root_path
expect(page).to have_content "Most active proposals"
expect(page).to have_css(".proposal", count: 3)
end
scenario "Debates" do
5.times { create(:debate) }
visit admin_homepage_path
within("#setting_#{debates_setting.id}") do
click_button "Enable"
end
expect(page).to have_content "Value updated"
visit root_path
expect(page).to have_content "Most active debates"
expect(page).to have_css(".debate", count: 3)
end
scenario "Processes" do
5.times { create(:legislation_process) }
visit admin_homepage_path
within("#setting_#{processes_setting.id}") do
click_button "Enable"
end
expect(page).to have_content "Value updated"
visit root_path
expect(page).to have_content "Most active processes"
expect(page).to have_css(".legislation_process", count: 3)
end
xscenario "Deactivate"
end
scenario "Cards" do
card1 = create(:widget_card, title: "Card text",
description: "Card description",

View File

@@ -0,0 +1,77 @@
require 'rails_helper'
describe Widget::Feed do
let(:feed) { build(:widget_feed) }
context "validations" do
it "is valid" do
expect(feed).to be_valid
end
end
context "kinds" do
describe "#proposals" do
it "returns the most active proposals" do
best_proposal = create(:proposal, title: 'Best proposal')
best_proposal.update_column(:hot_score, 10)
worst_proposal = create(:proposal, title: 'Worst proposal')
worst_proposal.update_column(:hot_score, 2)
even_worst_proposal = create(:proposal, title: 'Worst proposal')
even_worst_proposal.update_column(:hot_score, 1)
medium_proposal = create(:proposal, title: 'Medium proposal')
medium_proposal.update_column(:hot_score, 5)
feed = build(:widget_feed, kind: "proposals")
expect(feed.proposals).to eq([best_proposal, medium_proposal, worst_proposal])
end
end
describe "#debates" do
it "returns the most active debates" do
best_debate = create(:debate, title: 'Best debate')
best_debate.update_column(:hot_score, 10)
worst_debate = create(:debate, title: 'Worst debate')
worst_debate.update_column(:hot_score, 2)
even_worst_debate = create(:debate, title: 'Worst debate')
even_worst_debate.update_column(:hot_score, 1)
medium_debate = create(:debate, title: 'Medium debate')
medium_debate.update_column(:hot_score, 5)
feed = build(:widget_feed, kind: "debates")
expect(feed.debates).to eq([best_debate, medium_debate, worst_debate])
end
end
describe "#processes" do
it "returns open processes" do
open_process1 = create(:legislation_process, :open, title: "Open process 1")
open_process2 = create(:legislation_process, :open, title: "Open process 2")
open_process3 = create(:legislation_process, :open, title: "Open process 3")
open_process4 = create(:legislation_process, :open, title: "Open process 4")
past_process = create(:legislation_process, :past, title: "Past process")
feed = build(:widget_feed, kind: "processes")
expect(feed.processes).to eq([open_process4, open_process3, open_process2])
end
end
end
end