Skip to content

Commit

Permalink
Fix csv download bug for users and refactor and functional tests (#5257)
Browse files Browse the repository at this point in the history
* Extract to_csv method in a module

* refactor stats controller

* add stats download tests
  • Loading branch information
cesswairimu authored and jywarren committed Mar 29, 2019
1 parent a8ff914 commit e7d1315
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 62 deletions.
75 changes: 32 additions & 43 deletions app/controllers/stats_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ def range
params[:start] = Time.now - to_keyword(params[:options])
params[:end] = Time.now
end
@start = params[:start] ? Time.parse(params[:start].to_s) : Time.now - 3.months
@end = params[:end] ? Time.parse(params[:end].to_s) : Time.now
@start = start
@end = fin
@notes = Node.published.select(%i(created type))
.where(type: 'note', created: @start.to_i..@end.to_i)
.count(:all)
Expand Down Expand Up @@ -76,72 +76,61 @@ def index
end

def notes
time
export_as_json(@start, @end, 'note')
export_as_json('note')
end

def wikis
time
export_as_json(@start, @end, 'page')
export_as_json('page')
end

def users
time
data = User.where(created_at: @start..@end)
.where(status: 1)
.select(:username, :role, :bio, :photo_file_name, :id, :created_at)
respond_to do |format|
format.csv { send_data data.to_csv }
format.json { send_data data.to_json, type: 'application/json; header=present', disposition: "attachment; filename=user.json" }
end
data = User.where(created_at: start..fin)
.where(status: 1)
.select(:username, :role, :bio, :photo_file_name, :id, :created_at)
format(data, 'users')
end

def questions
time
data = Node.published.questions.where(created: @start.to_i..@end.to_i).all
respond_to do |format|
format.csv { send_data data.to_csv }
format.json { send_data data.to_json, type: 'application/json; header=present', disposition: "attachment; filename=questions.json" }
end
data = Node.published.questions.where(created: start.to_i..fin.to_i).all
format(data, 'questions')
end

def answers
time
data = Answer.where(created_at: @start..@end).all
respond_to do |format|
format.csv { send_data data.to_csv }
format.json { send_data data.to_json, type: 'application/json; header=present', disposition: "attachment; filename=answers.json" }
end
data = Answer.where(created_at: start..fin).all
format(data, 'answers')
end

def comments
time
data = Comment.select(%i(status timestamp)).where(status: 1, timestamp: @start.to_i...@end.to_i).all
respond_to do |format|
format.csv { send_data data.to_csv }
format.json { send_data data.to_json, type: 'application/json; header=present', disposition: "attachment; filename=comment.json" }
end
data = Comment.where(status: 1, timestamp: start.to_i...fin.to_i).all
format(data, 'comment')
end

def export_as_json(starting, ending, type)
data = Node.published.select(%i(created type))
.where(type: type, created: starting.to_i..ending.to_i)
def export_as_json(type)
data = Node.published
.where(type: type, created: start.to_i..fin.to_i)
.all
respond_to do |format|
format.csv { send_data data.to_csv }
format.json { send_data data.to_json, type: 'application/json; header=present', disposition: "attachment; filename=#{type}.json" }
end
format(data, type)
end

private

def time
@start = params[:start] ? Time.parse(params[:start].to_s) : Time.now - 1.month
@end = params[:end] ? Time.parse(params[:end].to_s) : Time.now
def start
params[:start] ? Time.parse(params[:start].to_s) : Time.now - 3.months
end

def fin
params[:end] ? Time.parse(params[:end].to_s) : Time.now
end

def to_keyword(param)
str = param.split.second
str = param.split.second
1.send(str.downcase)
end

def format(data, name)
respond_to do |format|
format.csv { send_data data.to_csv, type: 'text/csv' }
format.json { send_data data.to_json, type: 'application/json; header=present', disposition: "attachment; filename=#{name}.json" }
end
end
end
1 change: 1 addition & 0 deletions app/models/answer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Answer < ApplicationRecord
include CommentsShared
include NodeShared
extend RawStats

belongs_to :node, foreign_key: 'nid'
belongs_to :user, foreign_key: 'uid'
Expand Down
10 changes: 0 additions & 10 deletions app/models/application_record.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
class ApplicationRecord < ActiveRecord::Base
require 'csv'
self.abstract_class = true

def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |object|
csv << object.attributes.values_at(*column_names)
end
end
end
end
1 change: 1 addition & 0 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Comment < ApplicationRecord
include CommentsShared
extend RawStats

belongs_to :node, foreign_key: 'nid', touch: true, counter_cache: true
belongs_to :user, foreign_key: 'uid'
Expand Down
13 changes: 13 additions & 0 deletions app/models/concerns/raw_stats.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'csv'
module RawStats
extend ActiveSupport::Concern

def to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |object|
csv << object.attributes.values_at(*column_names)
end
end
end
end
10 changes: 1 addition & 9 deletions app/models/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def validate(record)
end

class Node < ActiveRecord::Base
extend RawStats
include NodeShared # common methods for node-like models

self.table_name = 'node'
Expand Down Expand Up @@ -146,15 +147,6 @@ def generate_path
end
end

def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |object|
csv << object.attributes.values_at(*column_names)
end
end
end

private

def set_path_and_slug
Expand Down
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def validate(record)
class User < ActiveRecord::Base
extend Utils
include Statistics
extend RawStats
self.table_name = 'rusers'
alias_attribute :name, :username

Expand Down
3 changes: 3 additions & 0 deletions app/views/stats/_range.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@
<li>
<%= link_to "Wikis", stats_wikis_path(format: 'csv', start: params[:start], end: params[:end]) %>
</li>
<li>
<%= link_to "Comments", stats_comments_path(format: 'csv', start: params[:start], end: params[:end]) %>
</li>
<li>
<li>
<%= link_to "Users", stats_users_path(format: 'csv', start: params[:start], end: params[:end]) %>
Expand Down
23 changes: 23 additions & 0 deletions test/functional/stats_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
require 'test_helper'
require 'csv'

class StatsControllerTest < ActionController::TestCase
def setup
@start = 1.month.ago.to_time
@end = Date.today.to_time
@stats = [:notes, :comments, :users, :wikis, :questions, :answers]
end

test 'should assign correct value to graph_notes on GET stats' do
Expand Down Expand Up @@ -45,4 +47,25 @@ def setup
assert_response :success
end

def csv_stats_download
@stats.each do |action|
test "should download #{action} as csv" do
get action, params: { format: 'csv' }
assert_response :success
assert_equal "text/csv", response.content_type
assert_equal "attachment", response['Content-Disposition']
end
end
end

def json_stats_downloads
@stats.each do |action|
test "should download #{action} as json" do
get action, params: { format: 'json' }
assert_response :success
assert_equal "application/json", response.content_type
assert_equal "attachment", response['Content-Disposition']
end
end
end
end

0 comments on commit e7d1315

Please sign in to comment.