diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb index 4eae73f9..87e56592 100644 --- a/app/controllers/api/v1/reports_controller.rb +++ b/app/controllers/api/v1/reports_controller.rb @@ -1,12 +1,6 @@ class Api::V1::ReportsController < ApplicationController - def features - feature_stats = Reports::FeatureUsageService.new.report - - render json: feature_stats.to_json, status: :ok - end - def add_another_answer_forms - data = Reports::FeatureUsageService.new.add_another_answer_forms + data = Reports::AddAnotherAnswerUsageService.new.add_another_answer_forms render json: data.to_json, status: :ok end diff --git a/app/services/reports/add_another_answer_usage_service.rb b/app/services/reports/add_another_answer_usage_service.rb new file mode 100644 index 00000000..de29d96a --- /dev/null +++ b/app/services/reports/add_another_answer_usage_service.rb @@ -0,0 +1,21 @@ +class Reports::AddAnotherAnswerUsageService + def add_another_answer_forms + forms = Form.includes(:pages) + .where(pages: { is_repeatable: true }) + .map(&method(:form_data)) + + # adding the count even though forms-admin doesn't use it as ActiveResource doesn't like parsing JSON with a single root key + { forms:, count: forms.length } + end + +private + + def form_data(form) + { + form_id: form.id, + name: form.name, + state: form.state, + repeatable_pages: form.pages.map { |page| { page_id: page.id, question_text: page.question_text } if page.is_repeatable }, + } + end +end diff --git a/app/services/reports/feature_usage_service.rb b/app/services/reports/feature_usage_service.rb deleted file mode 100644 index 9b7c8e60..00000000 --- a/app/services/reports/feature_usage_service.rb +++ /dev/null @@ -1,69 +0,0 @@ -class Reports::FeatureUsageService - def report - { - total_live_forms:, - live_forms_with_answer_type:, - live_pages_with_answer_type:, - live_forms_with_payment:, - live_forms_with_routing:, - live_forms_with_add_another_answer:, - live_forms_with_csv_submission_enabled:, - all_forms_with_add_another_answer:, - } - end - - def add_another_answer_forms - forms = all_forms_with_add_another_answer - - # adding the count even though forms-admin doesn't use it as ActiveResource doesn't like parsing JSON with a single root key - { forms:, count: forms.length } - end - -private - - # NOTE: all of these methods currently query the Form table rather than the MadeLiveForm table. - # This means that they may include updates which have been made to forms since they were made live. - # As a result, the figures in the report may vary slightly from the actual live figures. - # TODO: rewrite the queries to only check the content of live forms - - def total_live_forms - Form.where(state: %w[live live_with_draft]).count - end - - def live_forms_with_payment - Form.where(state: %w[live live_with_draft]).where.not(payment_url: [nil, ""]).count - end - - def live_forms_with_routing - Page.joins(:form).where(forms: { state: %w[live live_with_draft] }).where.associated(:routing_conditions).select("forms.id").distinct.count - end - - def live_forms_with_answer_type - Page.joins(:form).where(forms: { state: %w[live live_with_draft] }).select("forms.id,pages.answer_type").distinct.group(:answer_type).count("forms.id").symbolize_keys - end - - def live_pages_with_answer_type - Page.joins(:form).where(forms: { state: %w[live live_with_draft] }).group(:answer_type).count.symbolize_keys - end - - def live_forms_with_add_another_answer - Page.joins(:form).where(forms: { state: %w[live live_with_draft] }).select("forms.id,pages.is_repeatable").where(pages: { is_repeatable: true }).count("forms.id") - end - - def live_forms_with_csv_submission_enabled - Form.where(state: %w[live live_with_draft]).where(submission_type: "email_with_csv").count - end - - def all_forms_with_add_another_answer - forms = Form.includes(:pages).where(pages: { is_repeatable: true }) - - forms.map do |form| - { - form_id: form.id, - name: form.name, - state: form.state, - repeatable_pages: form.pages.map { |page| { page_id: page.id, question_text: page.question_text } if page.is_repeatable }, - } - end - end -end diff --git a/config/routes.rb b/config/routes.rb index 97b859e2..563df0f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,7 +47,6 @@ end scope :reports do - get "/features", to: "api/v1/reports#features" get "/add-another-answer-forms", to: "api/v1/reports#add_another_answer_forms" get "/selection-questions-summary", to: "api/v1/reports#selection_questions_summary" get "/selection-questions-with-autocomplete", to: "api/v1/reports#selection_questions_with_autocomplete" diff --git a/spec/requests/api/v1/reports_controller_spec.rb b/spec/requests/api/v1/reports_controller_spec.rb index 58edf4d7..6e8b2e6d 100644 --- a/spec/requests/api/v1/reports_controller_spec.rb +++ b/spec/requests/api/v1/reports_controller_spec.rb @@ -1,74 +1,6 @@ require "rails_helper" RSpec.describe Api::V1::ReportsController, type: :request do - describe "GET /features" do - let!(:form_with_repeatable_question) { create(:form, state: :live, pages: [repeatable_page]) } - let(:repeatable_page) { build(:page, answer_type: "text", is_repeatable: true) } - - before do - create :form, state: :live, payment_url: Faker::Internet.url(host: "gov.uk"), submission_type: "email_with_csv", pages: [ - (build :page, answer_type: "text"), - (build :page, answer_type: "text"), - ] - - create :form, state: :live, pages: [ - (build :page, answer_type: "name"), - (build :page, answer_type: "organisation_name"), - (build :page, answer_type: "phone_number"), - (build :page, answer_type: "email"), - (build :page, answer_type: "address"), - (build :page, answer_type: "national_insurance_number"), - (build :page, answer_type: "date"), - (build :page, answer_type: "number"), - (build :page, answer_type: "selection", routing_conditions: [(build :condition)]), - (build :page, answer_type: "text"), - ] - - get "/api/v1/reports/features" - end - - it "returns the breakdown of form features used" do - response_hash = JSON.parse(response.body, symbolize_names: true) - - expect(response_hash).to eq({ - total_live_forms: 3, - live_forms_with_answer_type: { - name: 1, - organisation_name: 1, - phone_number: 1, - email: 1, - address: 1, - national_insurance_number: 1, - date: 1, - number: 1, - selection: 1, - text: 3, - }, - live_pages_with_answer_type: { - name: 1, - organisation_name: 1, - phone_number: 1, - email: 1, - address: 1, - national_insurance_number: 1, - date: 1, - number: 1, - selection: 1, - text: 4, - }, - live_forms_with_payment: 1, - live_forms_with_routing: 1, - live_forms_with_add_another_answer: 1, - live_forms_with_csv_submission_enabled: 1, - all_forms_with_add_another_answer: [{ form_id: form_with_repeatable_question.id, name: form_with_repeatable_question.name, state: form_with_repeatable_question.state, repeatable_pages: [{ page_id: repeatable_page.id, question_text: repeatable_page.question_text }] }], - }) - end - - it "returns http success" do - expect(response).to have_http_status(:success) - end - end - describe "GET /add-another-answer-forms" do let!(:form_with_repeatable_question) { create(:form, state: :live, pages: [repeatable_page]) } let(:repeatable_page) { build(:page, answer_type: "text", is_repeatable: true) } diff --git a/spec/services/reports/add_another_answer_usage_service_spec.rb b/spec/services/reports/add_another_answer_usage_service_spec.rb new file mode 100644 index 00000000..368c4bbc --- /dev/null +++ b/spec/services/reports/add_another_answer_usage_service_spec.rb @@ -0,0 +1,45 @@ +require "rails_helper" + +describe Reports::AddAnotherAnswerUsageService do + subject(:features_report_service) { described_class.new } + + describe "#add_another_answer_forms" do + let!(:add_another_answer_draft_form) { create(:form, state: "draft", pages: draft_form_pages) } + let(:draft_form_pages) do + [ + (build :page, answer_type: "name", is_repeatable: true), + ] + end + let!(:add_another_answer_live_form) { create(:form, state: "live", pages: live_form_pages) } + let(:live_form_pages) do + [ + (build :page, answer_type: "name", is_repeatable: true), + (build :page, answer_type: "text", is_repeatable: true), + ] + end + + it "obtains all forms in the add another answer report" do + report = features_report_service.add_another_answer_forms + + expect(report[:forms]).to contain_exactly({ + form_id: add_another_answer_draft_form.id, + name: add_another_answer_draft_form.name, + state: add_another_answer_draft_form.state, + repeatable_pages: contain_exactly({ page_id: draft_form_pages.first.id, question_text: draft_form_pages.first.question_text }), + }, { + form_id: add_another_answer_live_form.id, + name: add_another_answer_live_form.name, + state: add_another_answer_live_form.state, + repeatable_pages: contain_exactly( + { page_id: live_form_pages.first.id, question_text: live_form_pages.first.question_text }, + { page_id: live_form_pages.second.id, question_text: live_form_pages.second.question_text }, + ), + }) + end + + it "returns the count" do + report = features_report_service.add_another_answer_forms + expect(report[:count]).to eq 2 + end + end +end diff --git a/spec/services/reports/feature_usage_service_spec.rb b/spec/services/reports/feature_usage_service_spec.rb deleted file mode 100644 index a3d6a76f..00000000 --- a/spec/services/reports/feature_usage_service_spec.rb +++ /dev/null @@ -1,235 +0,0 @@ -require "rails_helper" - -describe Reports::FeatureUsageService do - let(:features_report_service) { described_class.new } - - let!(:pages_with_all_answer_types) do - [ - (build :page, answer_type: "name"), - (build :page, answer_type: "organisation_name"), - (build :page, answer_type: "phone_number"), - (build :page, answer_type: "email"), - (build :page, answer_type: "address"), - (build :page, answer_type: "national_insurance_number"), - (build :page, answer_type: "date"), - (build :page, answer_type: "number"), - (build :page, answer_type: "selection"), - (build :page, answer_type: "text"), - (build :page, answer_type: "file"), - ] - end - - let!(:pages_with_repeated_answer_type) do - [ - (build :page, answer_type: "name"), - (build :page, answer_type: "organisation_name"), - (build :page, answer_type: "phone_number"), - (build :page, answer_type: "email"), - (build :page, answer_type: "address"), - (build :page, answer_type: "national_insurance_number"), - (build :page, answer_type: "date"), - (build :page, answer_type: "number"), - (build :page, answer_type: "selection"), - (build :page, answer_type: "file"), - (build :page, answer_type: "text"), - (build :page, answer_type: "text"), - ] - end - - let!(:pages_with_a_route) do - [ - (build :page, answer_type: "name"), - (build :page, answer_type: "organisation_name"), - (build :page, answer_type: "phone_number"), - (build :page, answer_type: "email"), - (build :page, answer_type: "address"), - (build :page, answer_type: "national_insurance_number"), - (build :page, answer_type: "date"), - (build :page, answer_type: "number"), - (build :page, answer_type: "selection", routing_conditions: [(build :condition)]), - (build :page, answer_type: "text"), - (build :page, answer_type: "file"), - ] - end - - let!(:pages_with_add_another_answer) do - [ - (build :page, answer_type: "name", is_repeatable: true), - ] - end - - let(:form_1_pages) { pages_with_all_answer_types } - let(:form_2_pages) { pages_with_all_answer_types } - let(:form_3_pages) { pages_with_repeated_answer_type } - let(:form_4_pages) { pages_with_all_answer_types } - let(:form_5_pages) { pages_with_repeated_answer_type } - let(:form_6_pages) { pages_with_with_add_another_answer } - - let(:payment_url) { nil } - let(:submission_type) { "email" } - - describe "#report" do - before do - create(:form, state: "draft", pages: form_1_pages, payment_url:) - create(:form, state: "archived", pages: form_2_pages, payment_url:) - create(:form, state: "archived_with_draft", pages: form_3_pages, payment_url:) - end - - context "when there are live forms" do - before do - create(:form, state: "live", pages: form_4_pages, payment_url:, submission_type:) - create(:form, state: "live_with_draft", pages: form_5_pages, payment_url: nil) - end - - it "includes the number of total live forms in the report" do - response = features_report_service.report - - expect(response[:total_live_forms]).to eq 2 - end - - it "includes the number of live forms that use each answer type" do - response = features_report_service.report - - expect(response[:live_forms_with_answer_type][:name]).to eq 2 - expect(response[:live_forms_with_answer_type][:organisation_name]).to eq 2 - expect(response[:live_forms_with_answer_type][:phone_number]).to eq 2 - expect(response[:live_forms_with_answer_type][:email]).to eq 2 - expect(response[:live_forms_with_answer_type][:address]).to eq 2 - expect(response[:live_forms_with_answer_type][:national_insurance_number]).to eq 2 - expect(response[:live_forms_with_answer_type][:date]).to eq 2 - expect(response[:live_forms_with_answer_type][:number]).to eq 2 - expect(response[:live_forms_with_answer_type][:selection]).to eq 2 - expect(response[:live_forms_with_answer_type][:text]).to eq 2 - expect(response[:live_forms_with_answer_type][:file]).to eq 2 - end - - it "includes the number of live pages that use each answer type" do - response = features_report_service.report - - expect(response[:live_pages_with_answer_type][:name]).to eq 2 - expect(response[:live_pages_with_answer_type][:organisation_name]).to eq 2 - expect(response[:live_pages_with_answer_type][:phone_number]).to eq 2 - expect(response[:live_pages_with_answer_type][:email]).to eq 2 - expect(response[:live_pages_with_answer_type][:address]).to eq 2 - expect(response[:live_pages_with_answer_type][:national_insurance_number]).to eq 2 - expect(response[:live_pages_with_answer_type][:date]).to eq 2 - expect(response[:live_pages_with_answer_type][:number]).to eq 2 - expect(response[:live_pages_with_answer_type][:selection]).to eq 2 - expect(response[:live_forms_with_answer_type][:file]).to eq 2 - expect(response[:live_pages_with_answer_type][:text]).to eq 3 - end - - context "when a live form has a payment url" do - let(:payment_url) { Faker::Internet.url(host: "gov.uk") } - - it "counts the form in the payment part of the report" do - response = features_report_service.report - - expect(response[:live_forms_with_payment]).to eq 1 - end - end - - context "when a live form has a route" do - let(:form_5_pages) { pages_with_a_route } - - it "counts the form in the routing part of the report" do - response = features_report_service.report - - expect(response[:live_forms_with_routing]).to eq 1 - end - end - - context "when a live form uses the add another answer feature" do - let(:form_5_pages) { pages_with_add_another_answer } - - it "counts the form in the add another answer part of the report" do - response = features_report_service.report - - expect(response[:live_forms_with_add_another_answer]).to eq 1 - end - end - - context "when a live form has CSV submission enabled" do - let(:submission_type) { "email_with_csv" } - - it "counts the form in the CSV submission part of the report" do - response = features_report_service.report - - expect(response[:live_forms_with_csv_submission_enabled]).to eq 1 - end - end - - context "when a draft form uses the add another answer feature" do - let!(:add_another_answer_form) { create(:form, state: "draft", pages: form_5_pages) } - let(:form_5_pages) { pages_with_add_another_answer } - - it "obtains all forms in the add another answer report" do - response = features_report_service.report - - expect(response[:all_forms_with_add_another_answer]).to eq([{ form_id: add_another_answer_form.id, name: add_another_answer_form.name, state: add_another_answer_form.state, repeatable_pages: [{ page_id: pages_with_add_another_answer.first.id, question_text: pages_with_add_another_answer.first.question_text }] }]) - end - end - end - - context "when there are no live forms" do - it "has non-live forms in the database" do - draft_forms_count = Form.where(state: "draft").count - archived_forms_count = Form.where(state: "archived").count - archived_with_draft_forms_count = Form.where(state: "archived_with_draft").count - - expect(draft_forms_count).to be > 0 - expect(archived_forms_count).to be > 0 - expect(archived_with_draft_forms_count).to be > 0 - end - - it "does not count the form in any of the report metrics" do - response = features_report_service.report - - expect(response[:total_live_forms]).to eq 0 - - expect(response[:live_forms_with_answer_type]).to eq({}) - expect(response[:live_pages_with_answer_type]).to eq({}) - - expect(response[:live_forms_with_payment]).to eq 0 - expect(response[:live_forms_with_routing]).to eq 0 - expect(response[:live_forms_with_csv_submission_enabled]).to eq 0 - end - end - end - - describe "#add_another_answer_forms" do - let!(:add_another_answer_draft_form) { create(:form, state: "draft", pages: draft_form_pages) } - let(:draft_form_pages) { pages_with_add_another_answer } - let!(:add_another_answer_live_form) { create(:form, state: "live", pages: live_form_pages) } - let(:live_form_pages) do - [ - (build :page, answer_type: "name", is_repeatable: true), - (build :page, answer_type: "text", is_repeatable: true), - ] - end - - it "obtains all forms in the add another answer report" do - report = features_report_service.add_another_answer_forms - - expect(report[:forms]).to contain_exactly({ - form_id: add_another_answer_draft_form.id, - name: add_another_answer_draft_form.name, - state: add_another_answer_draft_form.state, - repeatable_pages: contain_exactly({ page_id: draft_form_pages.first.id, question_text: draft_form_pages.first.question_text }), - }, { - form_id: add_another_answer_live_form.id, - name: add_another_answer_live_form.name, - state: add_another_answer_live_form.state, - repeatable_pages: contain_exactly( - { page_id: live_form_pages.first.id, question_text: live_form_pages.first.question_text }, - { page_id: live_form_pages.second.id, question_text: live_form_pages.second.question_text }, - ), - }) - end - - it "returns the count" do - report = features_report_service.add_another_answer_forms - expect(report[:count]).to eq 2 - end - end -end