From 9405188ae65b440ec67882a5ceb68c3e6f80f816 Mon Sep 17 00:00:00 2001 From: Syd Young Date: Wed, 7 Aug 2019 23:03:54 -0700 Subject: [PATCH] Create status enum on action pages --- app/models/action_page.rb | 61 +++++-------------- app/queries/action_page_filters.rb | 7 ++- ...190808043221_add_status_to_action_pages.rb | 38 ++++++++++++ db/schema.rb | 9 +-- spec/factories/action_page.rb | 13 +++- spec/models/action_page_spec.rb | 56 ++++------------- spec/queries/action_page_filters_spec.rb | 3 +- 7 files changed, 87 insertions(+), 100 deletions(-) create mode 100644 db/migrate/20190808043221_add_status_to_action_pages.rb diff --git a/app/models/action_page.rb b/app/models/action_page.rb index 07c1cb88e..b1b236f35 100644 --- a/app/models/action_page.rb +++ b/app/models/action_page.rb @@ -39,6 +39,8 @@ class ActionPage < ActiveRecord::Base foreign_key: "archived_redirect_action_page_id" belongs_to :author, class_name: "User", foreign_key: :user_id, optional: true + enum status: %i(draft live victory archived) + accepts_nested_attributes_for :tweet, :petition, :email_campaign, :call_campaign, :congress_message_campaign, reject_if: :all_blank @@ -54,6 +56,9 @@ class ActionPage < ActiveRecord::Base do_not_validate_attachment_file_type [:featured_image, :background_image, :og_image] #validates_length_of :og_title, maximum: 65 + before_validation :publish, if: -> { live? } + before_validation :live!, if: -> { draft? && published } + validate :published_status after_save :no_drafts_on_homepage scope :categorized, ->(category) { joins(:category).where(categories: { title: category }) } @@ -78,20 +83,6 @@ def action_type nil end - def self.status(status) - unless %w(archived victory live draft).include?(status) - raise ArgumentError, "unrecognized status #{status}" - end - case status - when "live" - where(published: true, archived: false, victory: false) - when "draft" - where(published: false, archived: false, victory: false) - else - where(status => true) - end - end - def should_generate_new_friendly_id? # create slugs with FriendlyId and respect our custom slugs # set a custom slug with `page.update(slug: new_slug)` @@ -143,43 +134,19 @@ def image og_image || background_image || featured_image end - def status - if archived? - "archived" - elsif victory? - "victory" - elsif published? - "live" - else - "draft" - end + def no_drafts_on_homepage + FeaturedActionPage.where(action_page_id: id).destroy_all unless published? end - def status=(status) - case status - when "live" - self.published = true - self.archived = false - self.victory = false - - when "archived" - self.published = false - self.archived = true - self.victory = false - - when "victory" - self.published = false - self.archived = false - self.victory = true + private - when "draft" - self.published = false - self.archived = false - self.victory = false - end + def publish + self.published = true end - def no_drafts_on_homepage - FeaturedActionPage.where(action_page_id: id).destroy_all unless published? + def published_status + return if (draft? && !published) || (!draft? && published) + errors.add(:published, "#{status} action pages must be "\ + "#{published ? 'un' : ''}published") end end diff --git a/app/queries/action_page_filters.rb b/app/queries/action_page_filters.rb index 98d379cd9..5d5655212 100644 --- a/app/queries/action_page_filters.rb +++ b/app/queries/action_page_filters.rb @@ -14,7 +14,9 @@ def run filters.each do |f, val| next unless valid_query?(f, val) - @relation = if NAMED_SCOPES.include? f + @relation = if ENUM_QUERY == f + relation.send f + elsif NAMED_SCOPES.include? f relation.send(f, val) else relation.where(f => val) @@ -25,7 +27,8 @@ def run private - NAMED_SCOPES = %i(type status).freeze + ENUM_QUERY = "status".freeze + NAMED_SCOPES = %i(type).freeze VALID_FILTERS = %i(type status author category).freeze attr_accessor :relation, :filters diff --git a/db/migrate/20190808043221_add_status_to_action_pages.rb b/db/migrate/20190808043221_add_status_to_action_pages.rb new file mode 100644 index 000000000..fadeb4a28 --- /dev/null +++ b/db/migrate/20190808043221_add_status_to_action_pages.rb @@ -0,0 +1,38 @@ +class AddStatusToActionPages < ActiveRecord::Migration[5.0] + def change + add_column :action_pages, :status, :integer, null: false, default: 0 + + reversible do |dir| + dir.up do + # ---------------------------------------------------------- + # new values | existing values + # -------------------------|-------------------------------- + # enum int | semantic name | published | victory | archived + # ---------|---------------|-----------|---------|---------- + # 0 | draft | 0 | 0 | 0 + # 1 | live | 1 | 0 | 0 + # 2 | victory | 0 or 1 | 1 | 0 + # 3 | archived | 0 or 1 | 0 or 1 | 1 + # ---------------------------------------------------------- + + # Drafts + execute("UPDATE action_pages SET status = 0 "\ + "WHERE published = FALSE AND victory = FALSE AND "\ + "archived = FALSE") + # Live + execute("UPDATE action_pages SET status = 1 "\ + "WHERE published = TRUE AND victory = FALSE AND "\ + "archived = FALSE") + # Victories + execute("UPDATE action_pages SET status = 2 "\ + "WHERE victory = TRUE AND archived = FALSE") + + # Archived + execute("UPDATE action_pages SET status = 3 WHERE archived = TRUE") + end + end + + rename_column :action_pages, :victory, :old_victory + rename_column :action_pages, :archived, :old_archived + end +end diff --git a/db/schema.rb b/db/schema.rb index 05772ccf9..d98f588db 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190806005510) do +ActiveRecord::Schema.define(version: 20190808043221) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -64,18 +64,19 @@ t.boolean "enable_redirect", default: false t.string "redirect_url" t.text "email_text" - t.boolean "victory", default: false + t.boolean "old_victory", default: false t.text "victory_message" - t.boolean "archived", default: false + t.boolean "old_archived", default: false t.integer "archived_redirect_action_page_id" t.integer "category_id" t.boolean "enable_congress_message", default: false, null: false t.integer "congress_message_campaign_id" t.string "related_content_url" t.integer "user_id" - t.index ["archived"], name: "index_action_pages_on_archived", using: :btree + t.integer "status", default: 0, null: false t.index ["call_campaign_id"], name: "index_action_pages_on_call_campaign_id", using: :btree t.index ["email_campaign_id"], name: "index_action_pages_on_email_campaign_id", using: :btree + t.index ["old_archived"], name: "index_action_pages_on_old_archived", using: :btree t.index ["petition_id"], name: "index_action_pages_on_petition_id", using: :btree t.index ["slug"], name: "index_action_pages_on_slug", using: :btree t.index ["tweet_id"], name: "index_action_pages_on_tweet_id", using: :btree diff --git a/spec/factories/action_page.rb b/spec/factories/action_page.rb index 1ef32505e..1d031ea87 100644 --- a/spec/factories/action_page.rb +++ b/spec/factories/action_page.rb @@ -4,6 +4,7 @@ summary "not filling in summary" description "not filling desc in" published true + status "live" email_text "$NAME, thanks for taking action!" victory_message "We won" @@ -36,9 +37,17 @@ end factory :archived_action_page, parent: :action_page do - archived true + status "archived" association :active_action_page_for_redirect, factory: :action_page - victory false + end + + factory :victory_action_page, parent: :action_page do + status "victory" + end + + factory :draft_action_page, parent: :action_page do + status "draft" + published false end factory :action_page_with_views, parent: :action_page do diff --git a/spec/models/action_page_spec.rb b/spec/models/action_page_spec.rb index c2108cc61..e0e285631 100644 --- a/spec/models/action_page_spec.rb +++ b/spec/models/action_page_spec.rb @@ -14,16 +14,6 @@ expect(action_page.redirect_from_archived_to_active_action?).to be_truthy end - # The test was a no-go because of the ajaxy html requiring nils... and Then - # changing them from nils to ""??? Needs effeciency review before crashyness review - # it "should not allow the creation of a model with so few attrs that it would crash the views" do - # expect { - # ActionPage.create!({ }) - # }.to raise_exception(ActiveRecord::RecordInvalid) - # - # expect(ActionPage.count).to eq 0 - # end - describe "slug" do let(:page) { FactoryGirl.create(:action_page) } let(:new_slug) { "a-better-slug" } @@ -80,6 +70,19 @@ end end + describe "status callbacks" do + it "becomes published when live" do + action = FactoryGirl.create(:draft_action_page) + action.update!(status: "live") + expect(action.reload.published).to eq(true) + end + it "drafts become live when published" do + action = FactoryGirl.create(:draft_action_page) + action.update!(published: true) + expect(action.reload).to be_live + end + end + describe ".type(types)" do let(:call) { FactoryGirl.create(:action_page_with_call) } let(:congress_message) { FactoryGirl.create(:action_page_with_congress_message) } @@ -106,37 +109,4 @@ expect { ActionPage.type("unknown") }.to raise_error(ArgumentError) end end - - describe ".status(status)" do - shared_examples "returns only the given status" do |status, action| - it status do - action = FactoryGirl.create(*action) - result = ActionPage.status(status) - expect(result).to contain_exactly(action) - end - end - - context "not live" do - before { FactoryGirl.create(:action_page) } - - it_behaves_like "returns only the given status", "archived", - [:action_page, { archived: true }] - - it_behaves_like "returns only the given status", "victory", - [:action_page, { victory: true }] - - it_behaves_like "returns only the given status", "draft", - [:action_page, { published: false }] - end - - context "live action" do - before { FactoryGirl.create(:action_page, published: false) } - it_behaves_like "returns only the given status", "live", - [:action_page, { published: true }] - end - - it "raises an ArgumentError when an invalid status is given" do - expect { ActionPage.status("unknown") }.to raise_error(ArgumentError) - end - end end diff --git a/spec/queries/action_page_filters_spec.rb b/spec/queries/action_page_filters_spec.rb index c232c9d2f..a6f7450e0 100644 --- a/spec/queries/action_page_filters_spec.rb +++ b/spec/queries/action_page_filters_spec.rb @@ -7,9 +7,8 @@ category_action = FactoryGirl.create(:action_page, enable_tweet: true, category: category) - draft_old = FactoryGirl.create(:action_page, + draft_old = FactoryGirl.create(:draft_action_page, enable_tweet: true, - published: false, created_at: Time.zone.today - 7.days) authored_old = FactoryGirl.create(:action_page, enable_tweet: true,