# frozen_string_literal: true require "rails_helper" RSpec.describe UsageController, type: :controller do before(:each) do @date = Date.today.last_month.end_of_month @org = create(:org, :organisation) @details = { "by_template": [stat_details], "using_template": [] } @plan_stat = create(:stat_created_plan, date: @date, org: @org, details: @details) @user_stat = create(:stat_joined_user, date: @date, org: @org) sign_in(create(:user, :super_admin, org: @org)) end describe "GET /usage (aka index)" do before(:each) do get :index end it "assigns the correct user stats (@users_per_month)" do expect(assigns(:users_per_month)).to eql(obj_to_hash(obj: @user_stat)) end it "assigns the correct plan stats" do expect(assigns(:plans_per_month)).to eql(obj_to_hash(obj: @plan_stat)) end it "assigns the correct total users" do expect(assigns(:total_org_users)).to eql(@user_stat.count) end it "assigns the correct total plans" do expect(assigns(:total_org_plans)).to eql(@plan_stat.count) end end describe "POST /usage_plans_by_template" do before(:each) do # Skipping the prior month because it was already created above (2..12).each do |i| date = Date.today.months_ago(i).end_of_month details = { "by_template": [stat_details] } create(:stat_created_plan, date: date, org: @org, details: details) end @annual = StatCreatedPlan.all.order(date: :desc) end describe "test for each date range" do [1, 3, 6, 9, 12].each do |months| context "last #{months} months" do before(:each) do @date = Date.today.months_ago(months).end_of_month.strftime("%Y-%m-%d") post :plans_by_template, usage: { template_plans_range: @date }, format: :js end it "returns the expected data" do # Controller returns results in date ascending order so resort the # records after extracting the ones we want first expected = @annual[0..months - 1].sort { |a, b| a.date <=> b.date } .map { |stat| obj_to_hash(obj: stat) } expect(assigns(:plans_per_month)).to eql(expected.flatten) end end end end end describe "GET /usage_global_statistics" do before(:each) do get :global_statistics end it "assigns the correct csv data" do csvified_name = @org.name.include?(",") ? "\"#{@org.name}\"" : @org.name expected = "Org name,Total users,Total plans\n" + "#{csvified_name},#{@user_stat.count},#{@plan_stat.count}\n" expect(response.content_type).to eq("text/csv") expect(response.body).to eql(expected) end end describe "POST /usage_filter" do before(:each) do @date2 = Date.today.months_ago(3).end_of_month.strftime("%Y-%m-%d") @user_stat2 = create(:stat_joined_user, date: @date2, org: @org) @plan_stat2 = create(:stat_created_plan, date: @date2, org: @org, details: @details) end context "date range specified" do before(:each) do @args = { start_date: Date.today.months_ago(3).strftime("%Y-%m-%d"), end_date: @date2 } end it "returns the correct values for users" do post :filter, usage: @args.merge({ topic: "users" }), format: :js expect(assigns(:ranged)).to eql(@user_stat2.count) expect(assigns(:total)).to eql(@user_stat2.count + @user_stat.count) end it "returns the correct values for plans" do post :filter, usage: @args.merge({ topic: "plans" }), format: :js expect(assigns(:ranged)).to eql(@plan_stat2.count) expect(assigns(:total)).to eql(@plan_stat2.count + @plan_stat.count) end end context "no date range specified" do it "returns the correct values for users" do post :filter, usage: { topic: "users" }, format: :js expect(assigns(:ranged)).to eql(@user_stat2.count + @user_stat.count) expect(assigns(:total)).to eql(@user_stat2.count + @user_stat.count) end it "returns the correct values for plans" do post :filter, usage: { topic: "plans" }, format: :js expect(assigns(:ranged)).to eql(@plan_stat2.count + @plan_stat.count) expect(assigns(:total)).to eql(@plan_stat2.count + @plan_stat.count) end end end describe "GET /usage_yearly_users" do before(:each) do get :yearly_users end it "assigns the correct csv data" do expected = "Month,No. Users joined\n" + "#{@date.strftime("%b-%y")},#{@user_stat.count}\n" + "Total,#{@user_stat.count}\n" expect(response.content_type).to eq("text/csv") expect(response.body).to eql(expected) end end describe "GET /usage_yearly_plans" do before(:each) do get :yearly_plans end it "assigns the correct csv data" do expected = "Month,No. Completed Plans\n" + "#{@date.strftime("%b-%y")},#{@plan_stat.count}\n" + "Total,#{@plan_stat.count}\n" expect(response.content_type).to eq("text/csv") expect(response.body).to eql(expected) end end describe "GET /usage_all_plans_by_template" do before(:each) do get :all_plans_by_template end it "assigns the correct csv data" do name = @details[:by_template].first[:name] count = @details[:by_template].first[:count] expected = "Date,#{name},Count\n" + "#{@date.strftime("%b %Y")},#{count},#{@plan_stat.count}\n" expect(response.content_type).to eq("text/csv") expect(response.body).to eql(expected) end end def obj_to_hash(obj:) hash = { "count": obj.count, "date": obj.date.strftime("%Y-%m-%d") } hash["by_template"] = obj.details.fetch("by_template", []) if obj.details.present? hash["using_template"] = obj.details.fetch("using_template", []) if obj.details.present? [hash.to_json] end def stat_details { "name": Faker::Lorem.unique.sentence, "count": Faker::Number.number(digits: 2) } end end