diff --git a/.env.test b/.env.test index c312fda..aaf3250 100644 --- a/.env.test +++ b/.env.test @@ -1 +1,2 @@ STRIPE_SUBSCRIPTION_PRICE_ID=test_price +HAPPY_PDF_API_KEY=HAPPY_KEY \ No newline at end of file diff --git a/app/controllers/owners/accept_data_requests_controller.rb b/app/controllers/owners/accept_data_requests_controller.rb new file mode 100644 index 0000000..156ad82 --- /dev/null +++ b/app/controllers/owners/accept_data_requests_controller.rb @@ -0,0 +1,9 @@ +module Owners + class AcceptDataRequestsController < Owners::ApplicationController + def update + data_request = current_owner.data_requests.find(params[:unaccepted_data_request_id]) + result = AcceptDataRequest.call(data_request: data_request) + render json: result.data_request, include: { tickets: { methods: [:encrypted_data, :area_name, :encrypted_data_change_history] } } + end + end +end \ No newline at end of file diff --git a/app/controllers/owners/data_requests_controller.rb b/app/controllers/owners/data_requests_controller.rb index a97e7cd..0307b32 100644 --- a/app/controllers/owners/data_requests_controller.rb +++ b/app/controllers/owners/data_requests_controller.rb @@ -3,11 +3,7 @@ class DataRequestsController < Owners::ApplicationController def show data_request = current_owner.data_requests.find(params[:id]) - if data_request.accepted? - render json: data_request, include: { tickets: { methods: [:encrypted_data, :area_name, :encrypted_data_change_history] } } - else - render json: data_request - end + render json: data_request, include: { tickets: { methods: [:encrypted_data, :area_name, :encrypted_data_change_history] } } end def index diff --git a/app/controllers/owners/unaccepted_data_requests_controller.rb b/app/controllers/owners/unaccepted_data_requests_controller.rb new file mode 100644 index 0000000..48f2f9f --- /dev/null +++ b/app/controllers/owners/unaccepted_data_requests_controller.rb @@ -0,0 +1,15 @@ +module Owners + class UnacceptedDataRequestsController < Owners::ApplicationController + + def index + render json: company.data_requests.unaccepted + end + + private + + def company + current_owner.companies.find(params[:company_id]) + end + + end +end diff --git a/app/interactors/accept_data_request.rb b/app/interactors/accept_data_request.rb new file mode 100644 index 0000000..9681d72 --- /dev/null +++ b/app/interactors/accept_data_request.rb @@ -0,0 +1,13 @@ +class AcceptDataRequest + include Interactor + include RequiredAttributes + + required_attributes %i[data_request] + + def call + if (!data_request.accepted?) + data_request.accept! + end + context.data_request = data_request + end +end \ No newline at end of file diff --git a/app/models/concerns/rails_admin_config/for_data_request.rb b/app/models/concerns/rails_admin_config/for_data_request.rb index abed85d..24ae9f4 100644 --- a/app/models/concerns/rails_admin_config/for_data_request.rb +++ b/app/models/concerns/rails_admin_config/for_data_request.rb @@ -4,7 +4,7 @@ module ForDataRequest included do rails_admin do - fields :company, :from, :to, :reason + fields :company, :from, :to, :reason, :iris_health_department fields :accepted_at, :tickets do read_only true diff --git a/app/models/data_request.rb b/app/models/data_request.rb index b719a76..fbe6186 100644 --- a/app/models/data_request.rb +++ b/app/models/data_request.rb @@ -2,11 +2,13 @@ class DataRequest < ApplicationRecord include ApiSerializable include RailsAdminConfig::ForDataRequest - EXPOSED_ATTRIBUTES = %i[id from to accepted_at] + EXPOSED_ATTRIBUTES = %i[id from to reason accepted_at iris_health_department iris_key_of_health_department] belongs_to :company has_many :tickets, -> (request) { during(request.time_range) }, through: :company + scope :unaccepted, -> { where(accepted_at: nil) } + validates :from, presence: true validates :to, presence: true validates :reason, presence: true diff --git a/config/initializers/rails_admin.rb b/config/initializers/rails_admin.rb index 8fc0856..e9e9ae4 100644 --- a/config/initializers/rails_admin.rb +++ b/config/initializers/rails_admin.rb @@ -5,7 +5,6 @@ require "nested_form/engine" require "nested_form/builder_mixin" -RailsAdmin::Config::Actions.register(RailsAdmin::Config::Actions::AcceptDataRequest) RailsAdmin::Config::Actions.register(RailsAdmin::Config::Actions::BlockOwner) RailsAdmin::Config::Actions.register(RailsAdmin::Config::Actions::GenerateOwnerApiToken) @@ -35,6 +34,5 @@ export block_owner generate_owner_api_token - accept_data_request end end diff --git a/config/locales/en.yml b/config/locales/en.yml index cd470bd..82fe500 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,10 +1,6 @@ en: admin: actions: - accept_data_request: - menu: 'Accept' - title: 'Accept' - breadcrumb: 'Accept' block_owner: menu: 'Block' title: 'Block' diff --git a/config/routes.rb b/config/routes.rb index fb87ae3..f381abd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,6 +28,9 @@ resources :areas, only: %i[index create update show], shallow: true resources :tickets, only: :index resources :data_requests, only: %i[show index create], shallow: true + resources :unaccepted_data_requests, only: %i[index], shallow: true do + patch "accept", to: "accept_data_requests#update" + end get :stats end resource :owner, only: %i[show update] diff --git a/db/migrate/20210422102308_add_iris_fields_to_data_request.rb b/db/migrate/20210422102308_add_iris_fields_to_data_request.rb new file mode 100644 index 0000000..cd4c843 --- /dev/null +++ b/db/migrate/20210422102308_add_iris_fields_to_data_request.rb @@ -0,0 +1,9 @@ +class AddIrisFieldsToDataRequest < ActiveRecord::Migration[6.1] + def change + add_column :data_requests, :iris_submission_url, :string + add_column :data_requests, :iris_health_department, :text + add_column :data_requests, :iris_key_of_health_department, :text + add_column :data_requests, :iris_key_reference, :text + add_index :data_requests, :accepted_at + end +end diff --git a/db/schema.rb b/db/schema.rb index 12a95c9..f2636e1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_04_19_095723) do +ActiveRecord::Schema.define(version: 2021_04_22_102308) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -81,6 +81,11 @@ t.datetime "to" t.datetime "accepted_at" t.string "reason" + t.string "iris_submission_url" + t.text "iris_health_department" + t.text "iris_key_of_health_department" + t.text "iris_key_reference" + t.index ["accepted_at"], name: "index_data_requests_on_accepted_at" t.index ["company_id"], name: "index_data_requests_on_company_id" end diff --git a/lib/rails_admin/actions.rb b/lib/rails_admin/actions.rb index 651ff5f..42fba80 100644 --- a/lib/rails_admin/actions.rb +++ b/lib/rails_admin/actions.rb @@ -36,22 +36,6 @@ class GenerateOwnerApiToken < RailsAdmin::Config::Actions::Base end end - class AcceptDataRequest < RailsAdmin::Config::Actions::Base - register_instance_option :visible? do - bindings[:object].class == DataRequest - end - - register_instance_option(:member) { true } - register_instance_option(:link_icon) { 'icon-check' } - register_instance_option(:pjax) { false} - register_instance_option(:controller) do - Proc.new do - @object.accept! - - redirect_to back_or_index - end - end - end end end end diff --git a/spec/models/data_request_spec.rb b/spec/models/data_request_spec.rb index 9159d36..cce2175 100644 --- a/spec/models/data_request_spec.rb +++ b/spec/models/data_request_spec.rb @@ -1,6 +1,17 @@ require 'rails_helper' RSpec.describe DataRequest do + describe "#unaccepted" do + + it "returns a list of unaccepted data requests" do + data_request = FactoryBot.create(:data_request) + FactoryBot.create(:data_request, accepted_at: Time.zone.now) + + expect(DataRequest.unaccepted).to eq([data_request]) + end + + end + describe "#accept!" do let(:data_request) { FactoryBot.create(:data_request) } @@ -15,5 +26,16 @@ it { is_expected.to change { ticket.reload.status }.to('at_risk') } it { is_expected.to change { data_request.reload.accepted_at }.from(nil) } + + it "only returns tickets from the correct timestamp" do + FactoryBot.create(:ticket, company: data_request.company, + entered_at: data_request.from - 5.minutes, + left_at: data_request.from - 1.minute) + FactoryBot.create(:ticket, company: data_request.company, + entered_at: data_request.to + 1.minute, + left_at: data_request.to + 5.minute) + expect(data_request.tickets).to eq([ticket]) + end + end end diff --git a/spec/requests/authentication_spec.rb b/spec/requests/authentication_spec.rb index 21c85f8..18bc5e8 100644 --- a/spec/requests/authentication_spec.rb +++ b/spec/requests/authentication_spec.rb @@ -24,8 +24,9 @@ expect(response.headers['Authorization']).to be_present end - xit 'returns valid JWT token' do - decoded_token = decoded_jwt_token_from_response(response) + it 'returns valid JWT token' do + token_from_request = response.headers['Authorization'].split(" ").last + decoded_token = JWT.decode(token_from_request, ENV['DEVISE_JWT_SECRET_KEY'], true) expect(decoded_token.first['sub']).to be_present end diff --git a/spec/requests/owners/accept_data_requests_spec.rb b/spec/requests/owners/accept_data_requests_spec.rb new file mode 100644 index 0000000..9948e5c --- /dev/null +++ b/spec/requests/owners/accept_data_requests_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Owners::AcceptDataRequestsController do + include_context 'api request authentication' + + let(:owner) { FactoryBot.create(:owner) } + let(:company) { FactoryBot.create(:company, owner: owner) } + let(:other_company) { FactoryBot.create(:company, owner: owner) } + let(:area) { FactoryBot.create(:area, company: company) } + + before do + sign_in(owner) + end + + context "PATCH accepted_data_request update" do + let!(:data_request) do + FactoryBot.create(:ticket, area: area, encrypted_data: "data", entered_at: Time.zone.now.yesterday - 2.hours, left_at: Time.zone.now.yesterday - 1.hour) + FactoryBot.create(:data_request, + company: company, + from: Time.zone.now.yesterday - 4.hours, + to: Time.zone.now.yesterday, + accepted_at: Time.zone.now.yesterday) + FactoryBot.create(:data_request, + company: other_company, + from: Time.zone.now.yesterday - 4.hours, + to: Time.zone.now.yesterday) + FactoryBot.create(:data_request, + company: company, + from: Time.zone.now.yesterday - 4.hours, + to: Time.zone.now.yesterday) + end + + before do + patch owners_unaccepted_data_request_accept_path(unaccepted_data_request_id: data_request.id) + end + + subject { JSON.parse(response.body) } + + it "has the correct data" do + expect(subject['id']).to eq(data_request.id) + expect(data_request.reload.accepted?).to be(true) + end + end +end \ No newline at end of file diff --git a/spec/requests/owners/area_request_spec.rb b/spec/requests/owners/area_request_spec.rb index 35acf5b..65b0211 100644 --- a/spec/requests/owners/area_request_spec.rb +++ b/spec/requests/owners/area_request_spec.rb @@ -59,7 +59,7 @@ context 'GET qr pdf' do let!(:area) { FactoryBot.create(:area, company: company) } - xit 'requests the pdf from happy pdf' do + it 'requests the pdf from happy pdf' do stub_request(:get, %r{http://app.happypdf.com/api/pdf.*}) get owners_area_path(area, format: :pdf) diff --git a/spec/requests/owners/data_requests_request_spec.rb b/spec/requests/owners/data_requests_request_spec.rb index 90f80c7..653be32 100644 --- a/spec/requests/owners/data_requests_request_spec.rb +++ b/spec/requests/owners/data_requests_request_spec.rb @@ -13,6 +13,28 @@ sign_in(owner) end + context "GET data_request index" do + let!(:data_request) do + FactoryBot.create(:ticket, area: area, encrypted_data: "data", entered_at: Time.zone.now.yesterday - 2.hours, left_at: Time.zone.now.yesterday - 1.hour) + FactoryBot.create(:data_request, + company: company, + from: Time.zone.now.yesterday - 4.hours, + to: Time.zone.now.yesterday, + accepted_at: Time.zone.now.yesterday) + end + + before do + get owners_company_data_requests_path(company_id: company.id) + end + + subject { JSON.parse(response.body) } + + it "has the correct data" do + expect(subject.length).to eq(1) + expect(subject.map{|item| item["id"]}).to eq([data_request.id]) + end + end + context 'POST first data_request' do subject do -> { post owners_company_data_requests_path(company_id: company.id), params: { data_request: { reason: 'for fun' } } } diff --git a/spec/requests/owners/unaccepted_data_requests_spec.rb b/spec/requests/owners/unaccepted_data_requests_spec.rb new file mode 100644 index 0000000..2bb738a --- /dev/null +++ b/spec/requests/owners/unaccepted_data_requests_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Owners::UnacceptedDataRequestsController do + include_context 'api request authentication' + + let(:owner) { FactoryBot.create(:owner) } + let(:company) { FactoryBot.create(:company, owner: owner) } + let(:other_company) { FactoryBot.create(:company, owner: owner) } + let(:area) { FactoryBot.create(:area, company: company) } + + before do + sign_in(owner) + end + + context "GET unaccepted_data_request index" do + let!(:data_request) do + FactoryBot.create(:ticket, area: area, encrypted_data: "data", entered_at: Time.zone.now.yesterday - 2.hours, left_at: Time.zone.now.yesterday - 1.hour) + FactoryBot.create(:data_request, + company: company, + from: Time.zone.now.yesterday - 4.hours, + to: Time.zone.now.yesterday, + accepted_at: Time.zone.now.yesterday) + FactoryBot.create(:data_request, + company: other_company, + from: Time.zone.now.yesterday - 4.hours, + to: Time.zone.now.yesterday) + FactoryBot.create(:data_request, + company: company, + from: Time.zone.now.yesterday - 4.hours, + to: Time.zone.now.yesterday) + end + + before do + get owners_company_unaccepted_data_requests_path(company_id: company.id) + end + + subject { JSON.parse(response.body) } + + it "has the correct data" do + expect(subject.length).to eq(1) + expect(subject.map{|item| item["id"]}).to eq([data_request.id]) + end + end +end \ No newline at end of file