diff --git a/app/controllers/schools/low_carbon_hub_installations_controller.rb b/app/controllers/schools/low_carbon_hub_installations_controller.rb index d15ba1288b..dec7c86784 100644 --- a/app/controllers/schools/low_carbon_hub_installations_controller.rb +++ b/app/controllers/schools/low_carbon_hub_installations_controller.rb @@ -48,6 +48,16 @@ def destroy redirect_to school_solar_feeds_configuration_index_path(@school), notice: 'Low carbon hub deleted' end + def check + @api_ok = Solar::LowCarbonHubInstallationFactory.check(@low_carbon_hub_installation) + respond_to(&:js) + end + + def submit_job + Solar::LowCarbonHubLoaderJob.perform_later(installation: @low_carbon_hub_installation, notify_email: current_user.email) + redirect_to school_solar_feeds_configuration_index_path(@school), notice: "Loading job has been submitted. An email will be sent to #{current_user.email} when complete." + end + private def low_carbon_hub_installation_params diff --git a/app/controllers/schools/rtone_variant_installations_controller.rb b/app/controllers/schools/rtone_variant_installations_controller.rb index 73010c7033..286a3923d5 100644 --- a/app/controllers/schools/rtone_variant_installations_controller.rb +++ b/app/controllers/schools/rtone_variant_installations_controller.rb @@ -34,6 +34,16 @@ def destroy redirect_to school_solar_feeds_configuration_index_path(@school), notice: 'New Rtone Variant API feed deleted.' end + def check + @api_ok = Solar::LowCarbonHubInstallationFactory.check(@rtone_variant_installation) + respond_to(&:js) + end + + def submit_job + Solar::RtoneVariantLoaderJob.perform_later(installation: @rtone_variant_installation, notify_email: current_user.email) + redirect_to school_solar_feeds_configuration_index_path(@school), notice: "Loading job has been submitted. An email will be sent to #{current_user.email} when complete." + end + private def load_non_gas_meters diff --git a/app/jobs/solar/low_carbon_hub_loader_job.rb b/app/jobs/solar/low_carbon_hub_loader_job.rb new file mode 100644 index 0000000000..a0083f8589 --- /dev/null +++ b/app/jobs/solar/low_carbon_hub_loader_job.rb @@ -0,0 +1,13 @@ +module Solar + class LowCarbonHubLoaderJob < BaseSolarLoaderJob + private + + def upserter(start_date, end_date) + Solar::LowCarbonHubDownloadAndUpsert.new(installation: @installation, start_date: start_date, end_date: end_date) + end + + def solar_feed_type + "Rtone" + end + end +end diff --git a/app/jobs/solar/rtone_variant_loader_job.rb b/app/jobs/solar/rtone_variant_loader_job.rb new file mode 100644 index 0000000000..41d6cb0856 --- /dev/null +++ b/app/jobs/solar/rtone_variant_loader_job.rb @@ -0,0 +1,13 @@ +module Solar + class RtoneVariantLoaderJob < BaseSolarLoaderJob + private + + def upserter(start_date, end_date) + Solar::RtoneVariantDownloadAndUpsert.new(installation: @installation, start_date: start_date, end_date: end_date) + end + + def solar_feed_type + "Rtone Variant" + end + end +end diff --git a/app/services/solar/low_carbon_hub_installation_factory.rb b/app/services/solar/low_carbon_hub_installation_factory.rb index 441ddbb695..d3b8d174ef 100644 --- a/app/services/solar/low_carbon_hub_installation_factory.rb +++ b/app/services/solar/low_carbon_hub_installation_factory.rb @@ -33,6 +33,19 @@ def perform installation end + def self.check(installation) + username = installation.username || ENV['ENERGYSPARKSRBEEUSERNAME'] + password = installation.password || ENV['ENERGYSPARKSRBEEPASSWORD'] + begin + LowCarbonHubMeterReadings.new(username, password).full_installation_information(installation.is_a?(LowCarbonHubInstallation) ? installation.rbee_meter_id : installation.rtone_meter_id) + true + rescue => e + puts e.message + puts e.backtrace + false + end + end + private def low_carbon_hub_api diff --git a/app/views/schools/low_carbon_hub_installations/check.js.erb b/app/views/schools/low_carbon_hub_installations/check.js.erb new file mode 100644 index 0000000000..ea4a158a97 --- /dev/null +++ b/app/views/schools/low_carbon_hub_installations/check.js.erb @@ -0,0 +1 @@ +$('#low-carbon-hub-<%= @low_carbon_hub_installation.id %>-test').html(' Check API'); diff --git a/app/views/schools/low_carbon_hub_installations/show.html.erb b/app/views/schools/low_carbon_hub_installations/show.html.erb index 7ec63f57c8..7e78570155 100644 --- a/app/views/schools/low_carbon_hub_installations/show.html.erb +++ b/app/views/schools/low_carbon_hub_installations/show.html.erb @@ -19,4 +19,4 @@ -

<%= link_to 'Delete', school_low_carbon_hub_installation_path(@school, @low_carbon_hub_installation), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' %> +

<%= link_to 'Delete', school_low_carbon_hub_installation_path(@school, @low_carbon_hub_installation), method: :delete, data: { confirm: 'Are you sure? This will delete the meters' }, class: 'btn' %> diff --git a/app/views/schools/rtone_variant_installations/check.js.erb b/app/views/schools/rtone_variant_installations/check.js.erb new file mode 100644 index 0000000000..42bf97b3e8 --- /dev/null +++ b/app/views/schools/rtone_variant_installations/check.js.erb @@ -0,0 +1 @@ +$('#rtone-variant-<%= @rtone_variant_installation.id %>-test').html(' Check API'); diff --git a/app/views/schools/solar_feeds_configuration/_rtone_feeds.html.erb b/app/views/schools/solar_feeds_configuration/_rtone_feeds.html.erb index 3e0c592fe3..2d02461842 100644 --- a/app/views/schools/solar_feeds_configuration/_rtone_feeds.html.erb +++ b/app/views/schools/solar_feeds_configuration/_rtone_feeds.html.erb @@ -2,10 +2,11 @@ - - + + - + + <% rtone_installations.each do |installation| %> @@ -15,11 +16,20 @@ + <% end %> diff --git a/app/views/schools/solar_feeds_configuration/_rtone_variant_feeds.html.erb b/app/views/schools/solar_feeds_configuration/_rtone_variant_feeds.html.erb index 54db09cd97..9bb570d7dd 100644 --- a/app/views/schools/solar_feeds_configuration/_rtone_variant_feeds.html.erb +++ b/app/views/schools/solar_feeds_configuration/_rtone_variant_feeds.html.erb @@ -7,7 +7,8 @@ - + + <% rtone_variant_installations.each do |installation| %> @@ -16,11 +17,19 @@ + <% end %> diff --git a/app/views/schools/solar_feeds_configuration/_solar_edge_feeds.html.erb b/app/views/schools/solar_feeds_configuration/_solar_edge_feeds.html.erb index c2c28acb44..50b9f6c8c6 100644 --- a/app/views/schools/solar_feeds_configuration/_solar_edge_feeds.html.erb +++ b/app/views/schools/solar_feeds_configuration/_solar_edge_feeds.html.erb @@ -18,7 +18,7 @@
<%= link_to 'Edit', edit_school_solar_edge_installation_path(school, installation), class: 'btn' %> <%= link_to 'Delete', school_solar_edge_installation_path(school, installation), method: :delete, data: { confirm: 'Are you sure? This will delete the meters' }, class: 'btn btn-danger' %> - <%= link_to "#{fa_icon('circle-question')} Check API".html_safe, check_school_solar_edge_installation_path(school, installation), id: "solar-edge-#{installation.id}-test", method: :post, remote: true, class: 'btn' %> + <%= link_to "#{fa_icon('circle-question')} Check API".html_safe, check_school_solar_edge_installation_path(school, installation), id: "solar-edge-#{installation.id}-test", method: :post, remote: true, class: 'btn check-button' %> <%= form_tag submit_job_school_solar_edge_installation_path(school, installation), method: :post do %> <%= button_tag(type: 'submit', id: "solar-edge-#{installation.id}-run-load", class: 'btn') do %> diff --git a/config/routes.rb b/config/routes.rb index 528144b001..553395c63c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -302,8 +302,18 @@ post :submit_job end end - resources :low_carbon_hub_installations, only: [:new, :show, :create, :edit, :update, :destroy] - resources :rtone_variant_installations, only: [:new, :create, :edit, :update, :destroy] + resources :low_carbon_hub_installations, only: [:new, :show, :create, :edit, :update, :destroy] do + member do + post :check + post :submit_job + end + end + resources :rtone_variant_installations, only: [:new, :create, :edit, :update, :destroy] do + member do + post :check + post :submit_job + end + end resource :meter_readings_validation, only: [:create] diff --git a/spec/factories/low_carbon_hub_installations_factory.rb b/spec/factories/low_carbon_hub_installations_factory.rb index fc2aa1a8ac..aa64150fbd 100644 --- a/spec/factories/low_carbon_hub_installations_factory.rb +++ b/spec/factories/low_carbon_hub_installations_factory.rb @@ -1,11 +1,11 @@ FactoryBot.define do factory :low_carbon_hub_installation do school - sequence(:rbee_meter_id, (100000..900000).cycle) { |n| n } + sequence(:rbee_meter_id) { |n| n } amr_data_feed_config - username { |n| "username_#{n}" } - password { |n| "password_#{n}" } + sequence(:username) { |n| "username_#{n}" } + sequence(:password) { |n| "password_#{n}" } trait :with_electricity_meter do after(:create) do |low_carbon_hub_installation, _evaluator| diff --git a/spec/factories/rtone_variant_installations.rb b/spec/factories/rtone_variant_installations.rb index 021356e86e..827a83dbf0 100644 --- a/spec/factories/rtone_variant_installations.rb +++ b/spec/factories/rtone_variant_installations.rb @@ -4,10 +4,9 @@ amr_data_feed_config association :meter, factory: :electricity_meter - username { |n| "username_#{n}" } - password { |n| "password_#{n}" } - - sequence(:rtone_meter_id, (100000..900000).cycle) { |n| n } + sequence(:username) { |n| "username_#{n}" } + sequence(:password) { |n| "password_#{n}" } + sequence(:rtone_meter_id) { |n| n } rtone_component_type { 1 } end end diff --git a/spec/jobs/solar/low_carbon_hub_loader_job_spec.rb b/spec/jobs/solar/low_carbon_hub_loader_job_spec.rb new file mode 100644 index 0000000000..8328ad776a --- /dev/null +++ b/spec/jobs/solar/low_carbon_hub_loader_job_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +describe Solar::LowCarbonHubLoaderJob do + include Rails.application.routes.url_helpers + let!(:installation) { create(:solar_edge_installation) } + let(:job) { Solar::LowCarbonHubLoaderJob.new } + + let!(:import_log) { create(:amr_data_feed_import_log, records_updated: 4, records_imported: 100) } + let(:upserter) { instance_double(Solar::LowCarbonHubDownloadAndUpsert, perform: nil, import_log: import_log) } + + include_context "when sending solar loader job emails" + + describe '#perform' do + let(:job_result) { job.perform(installation: installation, start_date: start_date, end_date: end_date, notify_email: admin.email) } + + context 'when the load is successful' do + before do + allow(Solar::LowCarbonHubDownloadAndUpsert).to receive(:new).and_return(upserter) + end + + it 'calls the upserter' do + expect(Solar::LowCarbonHubDownloadAndUpsert).to receive(:new).with(start_date: start_date, end_date: end_date, installation: installation) + job_result + end + + context 'when sending the email' do + before do + job_result + end + + it_behaves_like 'a successful solar loader job', solar_feed_type: 'Rtone' + end + end + + context 'when the load is unsuccessful' do + let!(:import_log) { create(:amr_data_feed_import_log, error_messages: "There are errors here") } + + before do + allow(Solar::LowCarbonHubDownloadAndUpsert).to receive(:new).and_return(upserter) + end + + context 'with a loading error' do + before do + job_result + end + + it_behaves_like 'a solar loader job with loader errors', solar_feed_type: 'Rtone' + end + + context 'with an unexpected exception' do + before do + allow(Solar::LowCarbonHubDownloadAndUpsert).to receive(:new).and_raise("Its broken") + #rubocop:disable RSpec/ExpectInHook + expect(Rollbar).to receive(:error).with(anything, job: :import_solar_edge_readings) + #rubocop:enable RSpec/ExpectInHook + job_result + end + + it_behaves_like 'a solar loader job that had an exception', solar_feed_type: 'Rtone' + end + end + end +end diff --git a/spec/jobs/solar/rtone_variant_loader_job_spec.rb b/spec/jobs/solar/rtone_variant_loader_job_spec.rb new file mode 100644 index 0000000000..eec2646179 --- /dev/null +++ b/spec/jobs/solar/rtone_variant_loader_job_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +describe Solar::RtoneVariantLoaderJob do + include Rails.application.routes.url_helpers + let!(:installation) { create(:solar_edge_installation) } + let(:job) { Solar::RtoneVariantLoaderJob.new } + + let!(:import_log) { create(:amr_data_feed_import_log, records_updated: 4, records_imported: 100) } + let(:upserter) { instance_double(Solar::RtoneVariantDownloadAndUpsert, perform: nil, import_log: import_log) } + + include_context "when sending solar loader job emails" + + describe '#perform' do + let(:job_result) { job.perform(installation: installation, start_date: start_date, end_date: end_date, notify_email: admin.email) } + + context 'when the load is successful' do + before do + allow(Solar::RtoneVariantDownloadAndUpsert).to receive(:new).and_return(upserter) + end + + it 'calls the upserter' do + expect(Solar::RtoneVariantDownloadAndUpsert).to receive(:new).with(start_date: start_date, end_date: end_date, installation: installation) + job_result + end + + context 'when sending the email' do + before do + job_result + end + + it_behaves_like 'a successful solar loader job', solar_feed_type: 'Rtone Variant' + end + end + + context 'when the load is unsuccessful' do + let!(:import_log) { create(:amr_data_feed_import_log, error_messages: "There are errors here") } + + before do + allow(Solar::RtoneVariantDownloadAndUpsert).to receive(:new).and_return(upserter) + end + + context 'with a loading error' do + before do + job_result + end + + it_behaves_like 'a solar loader job with loader errors', solar_feed_type: 'Rtone Variant' + end + + context 'with an unexpected exception' do + before do + allow(Solar::RtoneVariantDownloadAndUpsert).to receive(:new).and_raise("Its broken") + #rubocop:disable RSpec/ExpectInHook + expect(Rollbar).to receive(:error).with(anything, job: :import_solar_edge_readings) + #rubocop:enable RSpec/ExpectInHook + job_result + end + + it_behaves_like 'a solar loader job that had an exception', solar_feed_type: 'Rtone Variant' + end + end + end +end diff --git a/spec/jobs/solar/solar_edge_loader_job_spec.rb b/spec/jobs/solar/solar_edge_loader_job_spec.rb index d162d09ee8..180645baa2 100644 --- a/spec/jobs/solar/solar_edge_loader_job_spec.rb +++ b/spec/jobs/solar/solar_edge_loader_job_spec.rb @@ -2,87 +2,61 @@ describe Solar::SolarEdgeLoaderJob do include Rails.application.routes.url_helpers - - let!(:admin) { create(:admin) } let!(:installation) { create(:solar_edge_installation) } let(:job) { Solar::SolarEdgeLoaderJob.new } - let(:start_date) { nil } - let(:end_date) { nil } - - let(:import_log) { create(:amr_data_feed_import_log, records_updated: 4, records_imported: 100) } - let(:upserter) { instance_double(Solar::SolarEdgeDownloadAndUpsert, perform: nil, import_log: import_log) } - - let(:email) { ActionMailer::Base.deliveries.last } - #access to html might change depending on type of email sent, e.g. mail vs make_bootstrap_mail - #this returns the html body as a string - let(:email_body) { email.html_part.body.decoded } - let(:email_subject) { email.subject } - #parse the html string into something we can match against - let(:html_email) { Capybara::Node::Simple.new(email_body) } + let!(:import_log) { create(:amr_data_feed_import_log, records_updated: 4, records_imported: 100) } + let(:upserter) { instance_double(Solar::SolarEdgeDownloadAndUpsert, perform: nil, import_log: import_log) } - let(:meters_url) { school_meters_url(installation.school, host: 'localhost') } + include_context "when sending solar loader job emails" describe '#perform' do let(:job_result) { job.perform(installation: installation, start_date: start_date, end_date: end_date, notify_email: admin.email) } context 'when the load is successful' do - let(:expected_subject) { "[energy-sparks-unknown] Solar Edge Import for #{installation.school.name} Completed" } - before do allow(Solar::SolarEdgeDownloadAndUpsert).to receive(:new).and_return(upserter) end - it 'reports the success via email' do + it 'calls the upserter' do expect(Solar::SolarEdgeDownloadAndUpsert).to receive(:new).with(start_date: start_date, end_date: end_date, installation: installation) - job_result + end + + context 'when sending the email' do + before do + job_result + end - expect(email_subject).to eq expected_subject - expect(html_email).to have_text("The requested import for Solar Edge installation #{installation.site_id} has completed successfully") - expect(html_email).to have_text("100 records were imported and 4 were updated") - expect(html_email).to have_link("View the school meters", href: meters_url) - expect(html_email).to have_link("View the import logs") + it_behaves_like 'a successful solar loader job', solar_feed_type: 'Solar Edge' end end context 'when the load is unsuccessful' do - let(:expected_subject) { "[energy-sparks-unknown] Solar Edge Import for #{installation.school.name} Completed" } - - let(:import_log) { create(:amr_data_feed_import_log, error_messages: "There are errors here") } + let!(:import_log) { create(:amr_data_feed_import_log, error_messages: "There are errors here") } before do allow(Solar::SolarEdgeDownloadAndUpsert).to receive(:new).and_return(upserter) end context 'with a loading error' do - it 'reports the error messages via email' do - expect(Solar::SolarEdgeDownloadAndUpsert).to receive(:new).with(start_date: start_date, end_date: end_date, installation: installation) + before do job_result - expect(email_subject).to eq expected_subject - expect(html_email).to have_text("The requested import for Solar Edge installation #{installation.site_id} has failed") - expect(html_email).to have_text("The error reported was: There are errors here") - expect(html_email).to have_link("View the school meters", href: meters_url) - expect(html_email).to have_link("View the import logs") end + + it_behaves_like 'a solar loader job with loader errors', solar_feed_type: 'Solar Edge' end context 'with an unexpected exception' do before do allow(Solar::SolarEdgeDownloadAndUpsert).to receive(:new).and_raise("Its broken") - end - - it 'reports the failure via email' do - job_result - expect(html_email).to have_text("The requested import job has failed. An error has been logged") - expect(html_email).to have_text("Its broken") - expect(html_email).to have_link("View the school meters", href: meters_url) - end - - it 'reports to Rollbar' do + #rubocop:disable RSpec/ExpectInHook expect(Rollbar).to receive(:error).with(anything, job: :import_solar_edge_readings) + #rubocop:enable RSpec/ExpectInHook job_result end + + it_behaves_like 'a solar loader job that had an exception', solar_feed_type: 'Solar Edge' end end end diff --git a/spec/support/shared_contexts/solar_loader_job_emails.rb b/spec/support/shared_contexts/solar_loader_job_emails.rb new file mode 100644 index 0000000000..8e21ac9593 --- /dev/null +++ b/spec/support/shared_contexts/solar_loader_job_emails.rb @@ -0,0 +1,15 @@ +RSpec.shared_context "when sending solar loader job emails" do + let!(:admin) { create(:admin) } + let(:start_date) { nil } + let(:end_date) { nil } + + let(:email) { ActionMailer::Base.deliveries.last } + #access to html might change depending on type of email sent, e.g. mail vs make_bootstrap_mail + #this returns the html body as a string + let(:email_body) { email.html_part.body.decoded } + let(:email_subject) { email.subject } + #parse the html string into something we can match against + let(:html_email) { Capybara::Node::Simple.new(email_body) } + + let(:meters_url) { school_meters_url(installation.school, host: 'localhost') } +end diff --git a/spec/support/shared_examples/solar_loader_jobs.rb b/spec/support/shared_examples/solar_loader_jobs.rb new file mode 100644 index 0000000000..f025dc12a5 --- /dev/null +++ b/spec/support/shared_examples/solar_loader_jobs.rb @@ -0,0 +1,52 @@ +RSpec.shared_examples "a successful solar loader job" do |solar_feed_type:| + let(:expected_subject) { "[energy-sparks-unknown] #{solar_feed_type} Import for #{installation.school.name} Completed" } + + it 'sends email with the expected subject' do + expect(email_subject).to eq expected_subject + end + + it 'includes links' do + expect(html_email).to have_link("View the school meters", href: meters_url) + expect(html_email).to have_link("View the import logs") + end + + it 'summarises the import' do + expect(html_email).to have_text("The requested import for #{solar_feed_type} installation #{installation.site_id} has completed successfully") + expect(html_email).to have_text("100 records were imported and 4 were updated") + end +end + +RSpec.shared_examples "a solar loader job with loader errors" do |solar_feed_type:| + let(:expected_subject) { "[energy-sparks-unknown] #{solar_feed_type} Import for #{installation.school.name} Completed" } + + it 'sends email with the expected subject' do + expect(email_subject).to eq expected_subject + end + + it 'summarises the import' do + expect(html_email).to have_text("The requested import for #{solar_feed_type} installation #{installation.site_id} has failed") + expect(html_email).to have_text("The error reported was: There are errors here") + end + + it 'includes links' do + expect(html_email).to have_link("View the school meters", href: meters_url) + expect(html_email).to have_link("View the import logs") + end +end + +RSpec.shared_examples "a solar loader job that had an exception" do |solar_feed_type:| + let(:expected_subject) { "[energy-sparks-unknown] #{solar_feed_type} Import for #{installation.school.name} Failed" } + + it 'sends email with the expected subject' do + expect(email_subject).to eq expected_subject + end + + it 'reports the exception failure' do + expect(html_email).to have_text("The requested import job has failed. An error has been logged") + expect(html_email).to have_text("Its broken") + end + + it 'includes links' do + expect(html_email).to have_link("View the school meters", href: meters_url) + end +end diff --git a/spec/system/low_carbon_hub_installation_spec.rb b/spec/system/low_carbon_hub_installation_spec.rb index 11e4a08a95..a01088ef66 100644 --- a/spec/system/low_carbon_hub_installation_spec.rb +++ b/spec/system/low_carbon_hub_installation_spec.rb @@ -10,89 +10,152 @@ before do sign_in(admin) visit school_meters_path(school) - click_on 'Manage Solar API feeds' end - it 'I can add and delete a low carbon hub installation' do - expect(page).to have_content("This school has no Rtone API feeds") - click_on 'New Rtone API feed' + context 'with no api feeds' do + before do + click_on 'Manage Solar API feeds' + end - allow(LowCarbonHubMeterReadings).to receive(:new).with(username, password).and_return(low_carbon_hub_api) + it 'I can add and delete a low carbon hub installation' do + expect(page).to have_content("This school has no Rtone API feeds") + click_on 'New Rtone API feed' - fill_in(:low_carbon_hub_installation_rbee_meter_id, with: rbee_meter_id) - fill_in(:low_carbon_hub_installation_username, with: username) - fill_in(:low_carbon_hub_installation_password, with: password) + allow(LowCarbonHubMeterReadings).to receive(:new).with(username, password).and_return(low_carbon_hub_api) - expect { click_on 'Submit' }.to change { Meter.count }.by(3).and change { LowCarbonHubInstallation.count }.by(1).and change { AmrDataFeedReading.count }.by(6) + fill_in(:low_carbon_hub_installation_rbee_meter_id, with: rbee_meter_id) + fill_in(:low_carbon_hub_installation_username, with: username) + fill_in(:low_carbon_hub_installation_password, with: password) - expect(page).not_to have_content("This school has no Rtone API feeds") - expect(page).to have_content(rbee_meter_id) - expect(school.low_carbon_hub_installations.count).to be 1 - expect(school.low_carbon_hub_installations.first.username).to eql username - expect(school.low_carbon_hub_installations.first.password).to eql password - expect(school.meters.count).to be 3 + expect { click_on 'Submit' }.to change { Meter.count }.by(3).and change { LowCarbonHubInstallation.count }.by(1).and change { AmrDataFeedReading.count }.by(6) - click_on rbee_meter_id - expect(page).to have_content(info_text) - click_on "All Solar API feeds for #{school.name}" + expect(page).not_to have_content("This school has no Rtone API feeds") + expect(page).to have_content(rbee_meter_id) + expect(school.low_carbon_hub_installations.count).to be 1 + expect(school.low_carbon_hub_installations.first.username).to eql username + expect(school.low_carbon_hub_installations.first.password).to eql password + expect(school.meters.count).to be 3 - expect(page).to have_content("Delete") - expect { click_on 'Delete' }.to change { Meter.count }.by(-3).and change { LowCarbonHubInstallation.count }.by(-1) + click_on rbee_meter_id + expect(page).to have_content(info_text) + click_on "All Solar API feeds for #{school.name}" - expect(page).to have_content("This school has no Rtone API feeds") - end + expect(page).to have_content("Delete") + expect { click_on 'Delete' }.to change { Meter.count }.by(-3).and change { LowCarbonHubInstallation.count }.by(-1) - it 'I can edit an installation' do - expect(page).to have_content("This school has no Rtone API feeds") - click_on 'New Rtone API feed' + expect(page).to have_content("This school has no Rtone API feeds") + end - allow(LowCarbonHubMeterReadings).to receive(:new).with(username, password).and_return(low_carbon_hub_api) + it 'I can edit an installation' do + expect(page).to have_content("This school has no Rtone API feeds") + click_on 'New Rtone API feed' - fill_in(:low_carbon_hub_installation_rbee_meter_id, with: rbee_meter_id) - fill_in(:low_carbon_hub_installation_username, with: username) - fill_in(:low_carbon_hub_installation_password, with: password) + allow(LowCarbonHubMeterReadings).to receive(:new).with(username, password).and_return(low_carbon_hub_api) - expect { click_on 'Submit' }.to change { Meter.count }.by(3).and change { LowCarbonHubInstallation.count }.by(1).and change { AmrDataFeedReading.count }.by(6) + fill_in(:low_carbon_hub_installation_rbee_meter_id, with: rbee_meter_id) + fill_in(:low_carbon_hub_installation_username, with: username) + fill_in(:low_carbon_hub_installation_password, with: password) - expect(page).to have_content(rbee_meter_id) - click_on 'Edit' - expect(page).to have_content("Update Rtone API feed") + expect { click_on 'Submit' }.to change { Meter.count }.by(3).and change { LowCarbonHubInstallation.count }.by(1).and change { AmrDataFeedReading.count }.by(6) - expect(find_field(:low_carbon_hub_installation_username).value).to eql username - expect(find_field(:low_carbon_hub_installation_password).value).to eql password + expect(page).to have_content(rbee_meter_id) + click_on 'Edit' + expect(page).to have_content("Update Rtone API feed") - fill_in(:low_carbon_hub_installation_username, with: "changed-user") - fill_in(:low_carbon_hub_installation_password, with: "changed-pass") + expect(find_field(:low_carbon_hub_installation_username).value).to eql username + expect(find_field(:low_carbon_hub_installation_password).value).to eql password - click_on 'Submit' - expect(page).to have_content("Installation was updated") + fill_in(:low_carbon_hub_installation_username, with: "changed-user") + fill_in(:low_carbon_hub_installation_password, with: "changed-pass") - click_on 'Edit' - expect(find_field(:low_carbon_hub_installation_username).value).to eql "changed-user" - expect(find_field(:low_carbon_hub_installation_password).value).to eql "changed-pass" - end + click_on 'Submit' + expect(page).to have_content("Installation was updated") - it 'handles being run out of hours properly' do - expect(page).to have_content("This school has no Rtone API feeds") - click_on 'New Rtone API feed' + click_on 'Edit' + expect(find_field(:low_carbon_hub_installation_username).value).to eql "changed-user" + expect(find_field(:low_carbon_hub_installation_password).value).to eql "changed-pass" + end - expect(Solar::LowCarbonHubInstallationFactory).to receive(:new).and_raise(EnergySparksUnexpectedStateException) + it 'handles being run out of hours properly' do + expect(page).to have_content("This school has no Rtone API feeds") + click_on 'New Rtone API feed' - click_on 'Submit' - expect(page).to have_content("This school has no Rtone API feeds") - expect(page).to have_content("Rtone API is not available at the moment") - end + expect(Solar::LowCarbonHubInstallationFactory).to receive(:new).and_raise(EnergySparksUnexpectedStateException) - it 'I delete a low carbon hub installation and meter readings get removed' do - expect { create(:low_carbon_hub_installation_with_meters_and_validated_readings, school: school) }.to change { Meter.count }.by(3).and change { AmrValidatedReading.count }.by(3) + click_on 'Submit' + expect(page).to have_content("This school has no Rtone API feeds") + expect(page).to have_content("Rtone API is not available at the moment") + end - visit school_meters_path(school) - click_on 'Manage Solar API feeds' + it 'I delete a low carbon hub installation and meter readings get removed' do + expect { create(:low_carbon_hub_installation_with_meters_and_validated_readings, school: school) }.to change { Meter.count }.by(3).and change { AmrValidatedReading.count }.by(3) - low_carbon_hub_installation = LowCarbonHubInstallation.first + visit school_meters_path(school) + click_on 'Manage Solar API feeds' + + low_carbon_hub_installation = LowCarbonHubInstallation.first + + expect(page).to have_content low_carbon_hub_installation.rbee_meter_id + expect { click_on 'Delete' }.to change { Meter.count }.by(-3).and change { LowCarbonHubInstallation.count }.by(-1).and change { AmrValidatedReading.count }.by(-3) + end + end - expect(page).to have_content low_carbon_hub_installation.rbee_meter_id - expect { click_on 'Delete' }.to change { Meter.count }.by(-3).and change { LowCarbonHubInstallation.count }.by(-1).and change { AmrValidatedReading.count }.by(-3) + context 'with existing installation' do + let!(:installation) { create(:low_carbon_hub_installation, school: school) } + + before do + click_on 'Manage Solar API feeds' + end + + it 'displays the check button with a question mark by default' do + within "#low-carbon-hub-#{installation.id}-test" do + expect(page).to have_content('Check') + expect(page).to have_css("i[class*='fa-circle-question']") + end + end + + context 'when checking an installation', js: true do + before do + allow(Solar::LowCarbonHubInstallationFactory).to receive(:check).and_return(ok) + end + + context 'when check returns true' do + let(:ok) { true } + + it 'updates the button correctly' do + find("#low-carbon-hub-#{installation.id}-test").click + within "#low-carbon-hub-#{installation.id}-test" do + expect(page).to have_css("i[class*='fa-circle-check']") + end + end + end + + context 'when check returns false' do + let(:ok) { false } + + it 'updates the button correctly' do + find("#low-carbon-hub-#{installation.id}-test").click + within "#low-carbon-hub-#{installation.id}-test" do + expect(page).to have_css("i[class*='fa-circle-xmark']") + end + end + end + end + + context 'when submitting a loading job' do + before do + #do nothing + allow(Solar::LowCarbonHubLoaderJob).to receive(:perform_later).and_return(true) + end + + it 'submits the job' do + #...but check the method is called + expect(Solar::LowCarbonHubLoaderJob).to receive(:perform_later).with(installation: installation, notify_email: admin.email) + expect(page).to have_content("Run Loader") + find("#low-carbon-hub-#{installation.id}-run-load").click + expect(page).to have_content("Loading job has been submitted. An email will be sent to #{admin.email} when complete.") + end + end end end end diff --git a/spec/system/rtone_variant_installation_spec.rb b/spec/system/rtone_variant_installation_spec.rb index c29f5b2996..7f230b6202 100644 --- a/spec/system/rtone_variant_installation_spec.rb +++ b/spec/system/rtone_variant_installation_spec.rb @@ -16,10 +16,11 @@ before do sign_in(admin) visit school_meters_path(school) - click_on 'Manage Solar API feeds' end it 'I can add, edit and delete an rtone variant installation' do + click_on 'Manage Solar API feeds' + expect(page).to have_content("This school has no Rtone Variant API feeds") click_on 'New Rtone Variant API feed' @@ -53,5 +54,63 @@ expect(page).to have_content("This school has no Rtone Variant API feeds") end + + context 'with existing installation' do + let!(:installation) { create(:rtone_variant_installation, school: school) } + + before do + click_on 'Manage Solar API feeds' + end + + it 'displays the check button with a question mark by default' do + within "#rtone-variant-#{installation.id}-test" do + expect(page).to have_content('Check') + expect(page).to have_css("i[class*='fa-circle-question']") + end + end + + context 'when checking an installation', js: true do + before do + allow(Solar::LowCarbonHubInstallationFactory).to receive(:check).and_return(ok) + end + + context 'when check returns true' do + let(:ok) { true } + + it 'updates the button correctly' do + find("#rtone-variant-#{installation.id}-test").click + within "#rtone-variant-#{installation.id}-test" do + expect(page).to have_css("i[class*='fa-circle-check']") + end + end + end + + context 'when check returns false' do + let(:ok) { false } + + it 'updates the button correctly' do + find("#rtone-variant-#{installation.id}-test").click + within "#rtone-variant-#{installation.id}-test" do + expect(page).to have_css("i[class*='fa-circle-xmark']") + end + end + end + end + + context 'when submitting a loading job' do + before do + #do nothing + allow(Solar::RtoneVariantLoaderJob).to receive(:perform_later).and_return(true) + end + + it 'submits the job' do + #...but check the method is called + expect(Solar::RtoneVariantLoaderJob).to receive(:perform_later).with(installation: installation, notify_email: admin.email) + expect(page).to have_content("Run Loader") + find("#rtone-variant-#{installation.id}-run-load").click + expect(page).to have_content("Loading job has been submitted. An email will be sent to #{admin.email} when complete.") + end + end + end end end
RBee IdUsernameRBee IdUsername PasswordActionsLast updatedActions
<%= installation.username %> <%= installation.password %><%= nice_date_times(installation.updated_at) %> -

+

<%= link_to 'Edit', edit_school_low_carbon_hub_installation_path(school, installation), class: 'btn' %> - <%= link_to 'Delete', school_low_carbon_hub_installation_path(school, installation), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' %> -

+ <%= link_to 'Delete', school_low_carbon_hub_installation_path(school, installation), method: :delete, data: { confirm: 'Are you sure? This will delete the meters' }, class: 'btn' %> + + <%= link_to "#{fa_icon('circle-question')} Check API".html_safe, check_school_low_carbon_hub_installation_path(school, installation), id: "low-carbon-hub-#{installation.id}-test", method: :post, remote: true, class: 'btn check-button' %> + + <%= form_tag submit_job_school_low_carbon_hub_installation_path(school, installation), method: :post do %> + <%= button_tag(type: 'submit', id: "low-carbon-hub-#{installation.id}-run-load", class: 'btn') do %> + <%= fa_icon('upload') %> Run Loader + <% end %> + <% end %> +
Meter Username PasswordActionsLast updatedActions
<%= installation.meter.mpan_mprn %> <%= installation.username %> <%= installation.password %><%= nice_date_times(installation.updated_at) %> -

+

<%= link_to 'Edit', edit_school_rtone_variant_installation_path(school, installation), class: 'btn' %> - <%= link_to 'Delete', school_rtone_variant_installation_path(school, installation), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' %> -

+ <%= link_to 'Delete', school_rtone_variant_installation_path(school, installation), method: :delete, data: { confirm: 'Are you sure? This will delete the meters' }, class: 'btn' %> + <%= link_to "#{fa_icon('circle-question')} Check API".html_safe, check_school_rtone_variant_installation_path(school, installation), id: "rtone-variant-#{installation.id}-test", method: :post, remote: true, class: 'btn check-button' %> + + <%= form_tag submit_job_school_rtone_variant_installation_path(school, installation), method: :post do %> + <%= button_tag(type: 'submit', id: "rtone-variant-#{installation.id}-run-load", class: 'btn') do %> + <%= fa_icon('upload') %> Run Loader + <% end %> + <% end %> +