Merge pull request #3811 from consul/investment_changelog

Use audited to track changes in investments
This commit is contained in:
Javier Martín
2019-11-05 14:46:04 +01:00
committed by GitHub
32 changed files with 228 additions and 228 deletions

View File

@@ -208,6 +208,7 @@ Rails/CreateTableWithTimestamps:
Enabled: true Enabled: true
Exclude: Exclude:
- "db/migrate/201[5-8]*" - "db/migrate/201[5-8]*"
- "db/migrate/*install_audited.rb"
Rails/Date: Rails/Date:
Enabled: true Enabled: true

View File

@@ -6,6 +6,7 @@ gem "acts-as-taggable-on", "~> 5.0.0"
gem "acts_as_votable", "~> 0.11.1" gem "acts_as_votable", "~> 0.11.1"
gem "ahoy_matey", "~> 1.6.0" gem "ahoy_matey", "~> 1.6.0"
gem "ancestry", "~> 3.0.7" gem "ancestry", "~> 3.0.7"
gem "audited", "~> 4.9.0"
gem "autoprefixer-rails", "~> 8.2.0" gem "autoprefixer-rails", "~> 8.2.0"
gem "axlsx", "~> 3.0.0.pre" gem "axlsx", "~> 3.0.0.pre"
gem "axlsx_rails", "~> 0.5.2" gem "axlsx_rails", "~> 0.5.2"

View File

@@ -72,6 +72,8 @@ GEM
activerecord (>= 3.2.0) activerecord (>= 3.2.0)
arel (7.1.4) arel (7.1.4)
ast (2.4.0) ast (2.4.0)
audited (4.9.0)
activerecord (>= 4.2, < 6.1)
autoprefixer-rails (8.2.0) autoprefixer-rails (8.2.0)
execjs execjs
axlsx (3.0.0.pre) axlsx (3.0.0.pre)
@@ -588,6 +590,7 @@ DEPENDENCIES
acts_as_votable (~> 0.11.1) acts_as_votable (~> 0.11.1)
ahoy_matey (~> 1.6.0) ahoy_matey (~> 1.6.0)
ancestry (~> 3.0.7) ancestry (~> 3.0.7)
audited (~> 4.9.0)
autoprefixer-rails (~> 8.2.0) autoprefixer-rails (~> 8.2.0)
axlsx (~> 3.0.0.pre) axlsx (~> 3.0.0.pre)
axlsx_rails (~> 0.5.2) axlsx_rails (~> 0.5.2)

View File

@@ -595,17 +595,6 @@ code {
} }
} }
.log-value {
max-height: rem-calc(65);
overflow: hidden;
max-width: rem-calc(200);
&:hover {
max-height: rem-calc(1000);
transition: max-height 0.9s;
}
}
// 04. Stats // 04. Stats
// --------- // ---------

View File

@@ -0,0 +1,8 @@
class Admin::BudgetInvestmentAuditsController < Admin::BaseController
def show
investment = Budget::Investment.find(params[:budget_investment_id])
@audit = investment.own_and_associated_audits.find(params[:id])
render "admin/audits/show"
end
end

View File

@@ -2,7 +2,6 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
include FeatureFlags include FeatureFlags
include CommentableActions include CommentableActions
include DownloadSettingsHelper include DownloadSettingsHelper
include ChangeLogHelper
include Translatable include Translatable
feature_flag :budgets feature_flag :budgets
@@ -10,12 +9,11 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
has_orders %w[oldest], only: [:show, :edit] has_orders %w[oldest], only: [:show, :edit]
has_filters %w[all], only: [:index, :toggle_selection] has_filters %w[all], only: [:index, :toggle_selection]
before_action :load_budget, except: :show_investment_log before_action :load_budget
before_action :load_investment, only: [:show, :edit, :update, :toggle_selection] before_action :load_investment, only: [:show, :edit, :update, :toggle_selection]
before_action :load_ballot, only: [:show, :index] before_action :load_ballot, only: [:show, :index]
before_action :parse_valuation_filters before_action :parse_valuation_filters
before_action :load_investments, only: [:index, :toggle_selection] before_action :load_investments, only: [:index, :toggle_selection]
before_action :load_change_log, only: [:show]
def index def index
load_tags load_tags
@@ -128,8 +126,4 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
end end
end end
end end
def load_change_log
@logs = Budget::Investment::ChangeLog.by_investment(@investment.id)
end
end end

View File

@@ -15,7 +15,6 @@ class ApplicationController < ActionController::Base
before_action :set_locale before_action :set_locale
before_action :track_email_campaign before_action :track_email_campaign
before_action :set_return_url before_action :set_return_url
before_action :set_current_user
check_authorization unless: :devise_controller? check_authorization unless: :devise_controller?
self.responder = ApplicationResponder self.responder = ApplicationResponder
@@ -121,8 +120,4 @@ class ApplicationController < ActionController::Base
def current_budget def current_budget
Budget.current Budget.current
end end
def set_current_user
User.current_user = current_user
end
end end

View File

@@ -0,0 +1,15 @@
module AuditsHelper
def truncate_audit_value(resource, field, value)
truncate(audit_value(resource, field, value), length: 50)
end
def audit_value(resource, field, value)
if value.is_a?(Array)
value.join(",")
elsif resource.type_for_attribute(field.to_s).type == :boolean
resource.class.human_attribute_name("#{field}_#{value}")
else
value.to_s
end
end
end

View File

@@ -1,6 +0,0 @@
module ChangeLogHelper
def show_investment_log
@log = Budget::Investment::ChangeLog.find_by(id: params[:id])
render "admin/change_logs/show"
end
end

2
app/models/audit.rb Normal file
View File

@@ -0,0 +1,2 @@
class Audit < Audited::Audit
end

View File

@@ -3,7 +3,6 @@ class Budget
class Investment < ApplicationRecord class Investment < ApplicationRecord
SORTING_OPTIONS = { id: "id", supports: "cached_votes_up" }.freeze SORTING_OPTIONS = { id: "id", supports: "cached_votes_up" }.freeze
include ActiveModel::Dirty
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
include Measurable include Measurable
include Sanitizable include Sanitizable
@@ -33,6 +32,13 @@ class Budget
translates :description, touch: true translates :description, touch: true
include Globalizable include Globalizable
audited on: [:update, :destroy]
has_associated_audits
translation_class.class_eval do
audited associated_with: :globalized_model,
only: Budget::Investment.translated_attribute_names
end
belongs_to :author, -> { with_hidden }, class_name: "User", inverse_of: :budget_investments belongs_to :author, -> { with_hidden }, class_name: "User", inverse_of: :budget_investments
belongs_to :heading belongs_to :heading
belongs_to :group belongs_to :group
@@ -115,7 +121,6 @@ class Budget
after_save :recalculate_heading_winners after_save :recalculate_heading_winners
before_validation :set_responsible_name before_validation :set_responsible_name
before_validation :set_denormalized_ids before_validation :set_denormalized_ids
after_update :change_log
def comments_count def comments_count
comments.count comments.count
@@ -404,20 +409,6 @@ class Budget
self.original_heading_id = heading_id self.original_heading_id = heading_id
end end
def change_log
self.changed.each do |field|
unless field == "updated_at"
log = Budget::Investment::ChangeLog.new
log.field = field
log.author_id = User.current_user.id unless User.current_user.nil?
log.investment_id = self.id
log.new_value = self.send field
log.old_value = self.send "#{field}_was"
!log.save
end
end
end
def searchable_translations_definitions def searchable_translations_definitions
{ title => "A", { title => "A",
description => "D" } description => "D" }

View File

@@ -1,13 +0,0 @@
class Budget::Investment::ChangeLog < ApplicationRecord
belongs_to :author, -> { with_hidden },
class_name: "User",
foreign_key: "author_id",
inverse_of: :budget_investment_change_logs,
required: false
validates :old_value, presence: true
validates :new_value, presence: true
validates :field, presence: true
scope :by_investment, ->(investment_id) { where(investment_id: investment_id) }
end

View File

@@ -27,10 +27,6 @@ class User < ApplicationRecord
class_name: "Budget::Investment", class_name: "Budget::Investment",
foreign_key: :author_id, foreign_key: :author_id,
inverse_of: :author inverse_of: :author
has_many :budget_investment_change_logs,
foreign_key: :author_id,
inverse_of: :author,
class_name: "Budget::Investment::ChangeLog"
has_many :comments, -> { with_hidden }, inverse_of: :user has_many :comments, -> { with_hidden }, inverse_of: :user
has_many :failed_census_calls has_many :failed_census_calls
has_many :notifications has_many :notifications
@@ -400,14 +396,6 @@ class User < ApplicationRecord
followables.compact.map { |followable| followable.tags.map(&:name) }.flatten.compact.uniq followables.compact.map { |followable| followable.tags.map(&:name) }.flatten.compact.uniq
end end
def self.current_user
Thread.current[:user]
end
def self.current_user=(user)
Thread.current[:user] = user
end
def send_devise_notification(notification, *args) def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later devise_mailer.send(notification, self, *args).deliver_later
end end

View File

@@ -0,0 +1,46 @@
<h2><%= t("admin.audits.title") %></h2>
<% if resource.audits.empty? %>
<p><%= t("admin.audits.empty") %></p>
<% else %>
<table id="audits">
<thead>
<tr>
<th><%= t("admin.audits.id") %></th>
<th><%= t("admin.audits.field") %></th>
<th><%= t("admin.audits.old_value") %></th>
<th><%= t("admin.audits.new_value") %></th>
<th><%= t("admin.audits.edited_at") %></th>
<th><%= t("admin.audits.edited_by") %></th>
<th><%= t("admin.audits.actions") %></th>
</tr>
</thead>
<tbody>
<% resource.own_and_associated_audits.order(:created_at).each do |audit| %>
<% audit.audited_changes.each do |field, (old_value, new_value)| %>
<tr>
<td class="text-center"><%= audit.id %></td>
<td class="small"><%= sanitize(resource.class.human_attribute_name(field)) %></td>
<td class="small">
<div class="audit-value"><%= truncate_audit_value(resource, field, old_value) %></div>
</td>
<td class="small">
<div class="audit-value"><%= truncate_audit_value(resource, field, new_value) %></div>
</td>
<td class="small">
<%= l audit.created_at.to_date %>
</td>
<td class="small">
<%= audit.user&.name %>
</td>
<td>
<%= link_to t("shared.show"),
polymorphic_path([:admin, *resource_hierarchy_for(audit)]),
class: "button hollow primary" %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
<% end %>

View File

@@ -0,0 +1,20 @@
<% provide(:title) do %>
<%= t("admin.audits.title") %>
<% end %>
<%= back_link_to polymorphic_path([:admin, *resource_hierarchy_for(@audit.associated || @audit.auditable)]) %>
<h2><%= t("admin.audits.title") %></h2>
<p><strong><%= t("admin.audits.edited_at") %></strong> <%= l @audit.created_at.to_date %></p>
<p><strong><%= t("admin.audits.edited_by") %></strong> <%= @audit.user&.name %></p>
<h3><%= t("admin.audits.changes") %></h3>
<% @audit.audited_changes.each do |field, (old_value, new_value)| %>
<strong><%= t("admin.audits.field") %></strong>
<p><%= sanitize(@audit.auditable.class.human_attribute_name(field)) %></p>
<strong><%= t("admin.audits.old_value") %></strong>
<p><%= wysiwyg(audit_value(@audit.auditable, field, old_value)) %></p>
<strong><%= t("admin.audits.new_value") %></strong>
<p><%= wysiwyg(audit_value(@audit.auditable, field, new_value)) %></p>
<% end %>

View File

@@ -41,7 +41,7 @@
<div class="small-12 medium-4 column"> <div class="small-12 medium-4 column">
<p> <p>
<strong><%= t("admin.budget_investments.show.selection.title") %></strong>: <strong><%= t("admin.budget_investments.show.selection.title") %></strong>:
<%= t("admin.budget_investments.show.selection.#{@investment.selected?}") %> <%= @investment.class.human_attribute_name("selected_#{@investment.selected?}") %>
</p> </p>
</div> </div>
<div class="small-12 medium-4 column"> <div class="small-12 medium-4 column">

View File

@@ -66,6 +66,6 @@
<%= render "valuation/budget_investments/valuation_comments" %> <%= render "valuation/budget_investments/valuation_comments" %>
<%= render "admin/change_logs/change_log", logs: @logs %> <%= render "admin/audits/audits", resource: @investment %>
<%= render "admin/milestones/milestones", milestoneable: @investment %> <%= render "admin/milestones/milestones", milestoneable: @investment %>

View File

@@ -1,44 +0,0 @@
<h2 class="inline-block"><%= t("admin.change_log.title") %></h2>
<% if logs.empty? %>
<label><%= t("admin.change_log.empty") %></label>
<% else %>
<table>
<thead>
<tr>
<th><%= t("admin.change_log.id") %></th>
<th><%= t("admin.change_log.field") %></th>
<th><%= t("admin.change_log.old_value") %></th>
<th><%= t("admin.change_log.new_value") %></th>
<th><%= t("admin.change_log.edited_at") %></th>
<th><%= t("admin.change_log.edited_by") %></th>
<th><%= t("admin.change_log.actions") %></th>
</tr>
</thead>
<tbody>
<% logs.each do |log| %>
<tr id="log_<%= log.id %>">
<td class="text-center"><%= log.id %></td>
<td class="small"><%= log.field.capitalize %></td>
<td class="small">
<div class="log-value"><%= log.old_value %></div>
</td>
<td class="small">
<div class="log-value"><%= log.new_value %></div>
</td>
<td class="small">
<%= log.created_at.to_date %>
</td>
<td class="small">
<%= log.author.name unless log.author.nil? %>
</td>
<td>
<%= link_to admin_change_log_path(id: log) do %>
<button class="button hollow primary"><%= t("shared.show") %></button>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>

View File

@@ -1,12 +0,0 @@
<h2 class="inline-block"><%= t("admin.change_log.title") %></h2>
<label><strong><%= t("admin.change_log.id") %></strong></label>
<p><%= @log.id %></p>
<label><strong><%= t("admin.change_log.old_value") %></strong></label>
<p><%= @log.old_value %></p>
<label><strong><%= t("admin.change_log.new_value") %></strong></label>
<p><%= @log.new_value %></p>
<label><strong><%= t("admin.change_log.edited_at") %></strong></label>
<p><%= @log.created_at.to_date %></p>
<label><strong><%= t("admin.change_log.edited_by") %></strong></label>
<p><%= @log.author.name unless @log.author.nil? %></p>

View File

@@ -0,0 +1,3 @@
Audited.config do |config|
config.audit_class = ::Audit
end

View File

@@ -13,6 +13,8 @@ module ActionDispatch::Routing::UrlFor
[*resource_hierarchy_for(resource.milestoneable), resource] [*resource_hierarchy_for(resource.milestoneable), resource]
when "ProgressBar" when "ProgressBar"
[*resource_hierarchy_for(resource.progressable), resource] [*resource_hierarchy_for(resource.progressable), resource]
when "Audit"
[*resource_hierarchy_for(resource.associated || resource.auditable), resource]
when "Legislation::Annotation" when "Legislation::Annotation"
[resource.draft_version.process, resource.draft_version, resource] [resource.draft_version.process, resource.draft_version, resource]
when "Legislation::Proposal", "Legislation::Question", "Legislation::DraftVersion" when "Legislation::Proposal", "Legislation::Question", "Legislation::DraftVersion"

View File

@@ -161,6 +161,8 @@ en:
milestone_tag_list: "Milestone tags" milestone_tag_list: "Milestone tags"
price_explanation: "Price explanation" price_explanation: "Price explanation"
selected: "Mark as selected" selected: "Mark as selected"
selected_true: "Selected"
selected_false: "Not selected"
unfeasibility_explanation: "Feasibility explanation" unfeasibility_explanation: "Feasibility explanation"
valuation_finished: "Valuation finished" valuation_finished: "Valuation finished"
valuator_ids: "Groups" valuator_ids: "Groups"

View File

@@ -241,8 +241,6 @@ en:
"false": Compatible "false": Compatible
selection: selection:
title: Selection title: Selection
"true": Selected
"false": Not selected
winner: winner:
title: Winner title: Winner
"true": "Yes" "true": "Yes"
@@ -1583,8 +1581,9 @@ en:
submit_header: Save header submit_header: Save header
card_title: Edit card card_title: Edit card
submit_card: Save card submit_card: Save card
change_log: audits:
title: "Change Log" title: "Change Log"
changes: "List of changes"
id: "ID" id: "ID"
field: "Field" field: "Field"
new_value: "New Value" new_value: "New Value"
@@ -1592,7 +1591,7 @@ en:
edited_at: "Edited at" edited_at: "Edited at"
edited_by: "Edited by" edited_by: "Edited by"
actions: "Actions" actions: "Actions"
empty: "There are not changes logged" empty: "There are no changes logged"
local_census_records: local_census_records:
index: index:
title: Manage local census title: Manage local census

View File

@@ -163,6 +163,8 @@ es:
milestone_tag_list: "Etiquetas de Seguimiento" milestone_tag_list: "Etiquetas de Seguimiento"
price_explanation: "Informe de coste <small>(opcional, dato público)</small>" price_explanation: "Informe de coste <small>(opcional, dato público)</small>"
selected: "Marcar como seleccionado" selected: "Marcar como seleccionado"
selected_true: "Seleccionado"
selected_false: "No seleccionado"
unfeasibility_explanation: "Informe de inviabilidad <small>(en caso de que lo sea, dato público)</small>" unfeasibility_explanation: "Informe de inviabilidad <small>(en caso de que lo sea, dato público)</small>"
valuation_finished: "Informe finalizado" valuation_finished: "Informe finalizado"
valuator_ids: "Grupos" valuator_ids: "Grupos"

View File

@@ -241,8 +241,6 @@ es:
"false": Compatible "false": Compatible
selection: selection:
title: Selección title: Selección
"true": Seleccionado
"false": No seleccionado
winner: winner:
title: Ganador title: Ganador
"true": "Si" "true": "Si"
@@ -1582,8 +1580,9 @@ es:
submit_header: Guardar encabezado submit_header: Guardar encabezado
card_title: Editar tarjeta card_title: Editar tarjeta
submit_card: Guardar tarjeta submit_card: Guardar tarjeta
change_log: audits:
title: "Historial" title: "Historial"
changes: "Lista de cambios"
id: "ID" id: "ID"
field: "Campo" field: "Campo"
new_value: "Valor nuevo" new_value: "Valor nuevo"

View File

@@ -63,6 +63,7 @@ namespace :admin do
resources :budget_investments, only: [:index, :show, :edit, :update] do resources :budget_investments, only: [:index, :show, :edit, :update] do
member { patch :toggle_selection } member { patch :toggle_selection }
resources :audits, only: :show, controller: "budget_investment_audits"
resources :milestones, controller: "budget_investment_milestones" resources :milestones, controller: "budget_investment_milestones"
resources :progress_bars, except: :show, controller: "budget_investment_progress_bars" resources :progress_bars, except: :show, controller: "budget_investment_progress_bars"
end end
@@ -250,8 +251,6 @@ namespace :admin do
get "download_settings/:resource", to: "download_settings#edit", as: "edit_download_settings" get "download_settings/:resource", to: "download_settings#edit", as: "edit_download_settings"
put "download_settings/:resource", to: "download_settings#update", as: "update_download_settings" put "download_settings/:resource", to: "download_settings#update", as: "update_download_settings"
get "/change_log/:id", to: "budget_investments#show_investment_log", as: "change_log"
resources :local_census_records resources :local_census_records
namespace :local_census_records do namespace :local_census_records do
resources :imports, only: [:new, :create, :show] resources :imports, only: [:new, :create, :show]

View File

@@ -121,13 +121,16 @@ section "Creating Investments" do
100.times do 100.times do
heading = Budget::Heading.all.sample heading = Budget::Heading.all.sample
investment = Budget::Investment.create!( translation_attributes = random_locales.each_with_object({}) do |locale, attributes|
attributes["title_#{locale.to_s.underscore}"] = "Title for locale #{locale}"
attributes["description_#{locale.to_s.underscore}"] = "<p>Description for locale #{locale}</p>"
end
investment = Budget::Investment.create!({
author: User.all.sample, author: User.all.sample,
heading: heading, heading: heading,
group: heading.group, group: heading.group,
budget: heading.group.budget, budget: heading.group.budget,
title: Faker::Lorem.sentence(3).truncate(60),
description: "<p>#{Faker::Lorem.paragraphs.join("</p><p>")}</p>",
created_at: rand((Time.current - 1.week)..Time.current), created_at: rand((Time.current - 1.week)..Time.current),
feasibility: %w[undecided unfeasible feasible feasible feasible feasible].sample, feasibility: %w[undecided unfeasible feasible feasible feasible feasible].sample,
unfeasibility_explanation: Faker::Lorem.paragraph, unfeasibility_explanation: Faker::Lorem.paragraph,
@@ -136,15 +139,7 @@ section "Creating Investments" do
price: rand(1..100) * 100000, price: rand(1..100) * 100000,
skip_map: "1", skip_map: "1",
terms_of_service: "1" terms_of_service: "1"
) }.merge(translation_attributes))
random_locales.map do |locale|
Globalize.with_locale(locale) do
investment.title = "Title for locale #{locale}"
investment.description = "<p>Description for locale #{locale}</p>"
investment.save!
end
end
add_image_to(investment) if Random.rand > 0.5 add_image_to(investment) if Random.rand > 0.5
end end

View File

@@ -0,0 +1,26 @@
class InstallAudited < ActiveRecord::Migration[5.0]
def change
create_table :audits, force: true do |t|
t.column :auditable_id, :integer
t.column :auditable_type, :string
t.column :associated_id, :integer
t.column :associated_type, :string
t.column :user_id, :integer
t.column :user_type, :string
t.column :username, :string
t.column :action, :string
t.column :audited_changes, :jsonb
t.column :version, :integer, default: 0
t.column :comment, :string
t.column :remote_address, :string
t.column :request_uuid, :string
t.column :created_at, :datetime
end
add_index :audits, [:auditable_type, :auditable_id, :version], name: "auditable_index"
add_index :audits, [:associated_type, :associated_id], name: "associated_index"
add_index :audits, [:user_id, :user_type], name: "user_index"
add_index :audits, :request_uuid
add_index :audits, :created_at
end
end

View File

@@ -0,0 +1,13 @@
class DropBudgetInvestmentChangeLogs < ActiveRecord::Migration[5.0]
def change
drop_table :budget_investment_change_logs do |t|
t.integer :investment_id
t.integer :author_id
t.string :field
t.string :new_value
t.string :old_value
t.timestamps null: false
end
end
end

View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20191101183155) do ActiveRecord::Schema.define(version: 20191102002238) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -84,6 +84,28 @@ ActiveRecord::Schema.define(version: 20191101183155) do
t.index ["visit_id"], name: "index_ahoy_events_on_visit_id", using: :btree t.index ["visit_id"], name: "index_ahoy_events_on_visit_id", using: :btree
end end
create_table "audits", force: :cascade do |t|
t.integer "auditable_id"
t.string "auditable_type"
t.integer "associated_id"
t.string "associated_type"
t.integer "user_id"
t.string "user_type"
t.string "username"
t.string "action"
t.jsonb "audited_changes"
t.integer "version", default: 0
t.string "comment"
t.string "remote_address"
t.string "request_uuid"
t.datetime "created_at"
t.index ["associated_type", "associated_id"], name: "associated_index", using: :btree
t.index ["auditable_type", "auditable_id", "version"], name: "auditable_index", using: :btree
t.index ["created_at"], name: "index_audits_on_created_at", using: :btree
t.index ["request_uuid"], name: "index_audits_on_request_uuid", using: :btree
t.index ["user_id", "user_type"], name: "user_index", using: :btree
end
create_table "banner_sections", force: :cascade do |t| create_table "banner_sections", force: :cascade do |t|
t.integer "banner_id" t.integer "banner_id"
t.integer "web_section_id" t.integer "web_section_id"
@@ -203,16 +225,6 @@ ActiveRecord::Schema.define(version: 20191101183155) do
t.index ["group_id"], name: "index_budget_headings_on_group_id", using: :btree t.index ["group_id"], name: "index_budget_headings_on_group_id", using: :btree
end end
create_table "budget_investment_change_logs", force: :cascade do |t|
t.integer "investment_id"
t.integer "author_id"
t.string "field"
t.string "new_value"
t.string "old_value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "budget_investment_milestone_translations", force: :cascade do |t| create_table "budget_investment_milestone_translations", force: :cascade do |t|
t.integer "budget_investment_milestone_id", null: false t.integer "budget_investment_milestone_id", null: false
t.string "locale", null: false t.string "locale", null: false

View File

@@ -0,0 +1,38 @@
require "rails_helper"
describe "Admin change log" do
let(:administrator) { create(:administrator, user: create(:user, username: "Ana")) }
before { login_as(administrator.user) }
context "Investments Participatory Budgets" do
scenario "Changes" do
investment = create(:budget_investment, title: "Good old times")
visit admin_budget_budget_investment_path(investment.budget, investment)
expect(page).to have_content "There are no changes logged"
click_link "Edit"
fill_in "Title", with: "Modern times"
click_button "Update"
expect(page).not_to have_content "There are no changes logged"
expect(page).to have_content "Change Log"
within("#audits thead") do
expect(page).to have_content "Field"
expect(page).to have_content "Old Value"
expect(page).to have_content "New Value"
expect(page).to have_content "Edited at"
expect(page).to have_content "Edited by"
end
within("#audits tbody") do
expect(page).to have_content "Title"
expect(page).to have_content "Good old times"
expect(page).to have_content "Modern times"
expect(page).to have_content "Ana"
end
end
end
end

View File

@@ -1,68 +0,0 @@
require "rails_helper"
describe "Admin change log" do
let(:budget) { create(:budget) }
let(:administrator) do
create(:administrator, user: create(:user, username: "Ana", email: "ana@admins.org"))
end
context "Investments Participatory Budgets" do
before do
login_as(create(:administrator).user)
end
scenario "No changes" do
budget_investment = create(:budget_investment,
:unfeasible,
unfeasibility_explanation: "It is impossible",
price: 1234,
price_first_year: 1000,
administrator: administrator)
visit admin_budget_budget_investments_path(budget_investment.budget)
click_link budget_investment.title
expect(page).to have_content(budget_investment.title)
expect(page).to have_content(budget_investment.description)
expect(page).to have_content(budget_investment.author.name)
expect(page).to have_content(budget_investment.heading.name)
expect(page).to have_content("There are not changes logged")
end
scenario "Changes" do
budget_investment = create(:budget_investment,
:unfeasible,
unfeasibility_explanation: "It is impossible",
price: 1234,
price_first_year: 1000,
administrator: administrator)
visit admin_budget_budget_investments_path(budget_investment.budget)
click_link budget_investment.title
expect(page).to have_content(budget_investment.title)
expect(page).to have_content(budget_investment.description)
expect(page).to have_content(budget_investment.author.name)
expect(page).to have_content(budget_investment.heading.name)
expect(page).to have_content("There are not changes logged")
budget_investment.update!(title: "test")
visit admin_budget_budget_investments_path(budget_investment.budget)
click_link budget_investment.title
expect(page).not_to have_content("There are not changes logged")
expect(page).to have_content("Change Log")
expect(page).to have_content("Title")
expect(page).to have_content("test")
expect(page).to have_content("Field")
expect(page).to have_content("Old Value")
expect(page).to have_content("New Value")
expect(page).to have_content("Edited at")
expect(page).to have_content("Edited by")
end
end
end