From 0e0caf4d17c28b6b0f3488b25efa265ce2804cc4 Mon Sep 17 00:00:00 2001
From: DJ Mountney <david@twkie.net>
Date: Tue, 10 May 2016 16:19:16 -0700
Subject: [PATCH] Add tests for the health check feature

---
 app/views/admin/health_check/show.html.haml   |  3 +
 .../health_check_controller_spec.rb           | 90 +++++++++++++++++++
 .../features/admin/admin_health_check_spec.rb | 55 ++++++++++++
 spec/routing/admin_routing_spec.rb            |  7 ++
 spec/routing/routing_spec.rb                  | 10 +++
 5 files changed, 165 insertions(+)
 create mode 100644 spec/controllers/health_check_controller_spec.rb
 create mode 100644 spec/features/admin/admin_health_check_spec.rb

diff --git a/app/views/admin/health_check/show.html.haml b/app/views/admin/health_check/show.html.haml
index 70e5d04e356..23a931995ab 100644
--- a/app/views/admin/health_check/show.html.haml
+++ b/app/views/admin/health_check/show.html.haml
@@ -2,6 +2,9 @@
 
 %h3.page-title
   Health Check
+%p.light
+  Access token is
+  %code{ id:'health-check-token' }= "#{current_application_settings.health_check_access_token}"
 %p.light
   Health information can be reteived as plain text, json, or xml using:
   %ul
diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb
new file mode 100644
index 00000000000..3b9cc5c98f5
--- /dev/null
+++ b/spec/controllers/health_check_controller_spec.rb
@@ -0,0 +1,90 @@
+require 'spec_helper'
+
+describe HealthCheckController do
+  let(:token) { current_application_settings.health_check_access_token }
+  let(:json_response) { JSON.parse(response.body) }
+  let(:xml_response) { Hash.from_xml(response.body)['hash'] }
+
+  describe 'GET #index' do
+    context 'when services are up but NO access token' do
+      it 'returns a not found page' do
+        get :index
+        expect(response).to be_not_found
+      end
+    end
+
+    context 'when services are up and an access token is provided' do
+      it 'supports successful plaintest response' do
+        get :index, token: token
+        expect(response).to be_success
+        expect(response.content_type).to eq 'text/plain'
+      end
+
+      it 'supports successful json response' do
+        get :index, token: token, format: :json
+        expect(response).to be_success
+        expect(response.content_type).to eq 'application/json'
+        expect(json_response['healthy']).to be true
+      end
+
+      it 'supports successful xml response' do
+        get :index, token: token, format: :xml
+        expect(response).to be_success
+        expect(response.content_type).to eq 'application/xml'
+        expect(xml_response['healthy']).to be true
+      end
+
+      it 'supports successful responses for specific checks' do
+        get :index, token: token, checks: 'email', format: :json
+        expect(response).to be_success
+        expect(response.content_type).to eq 'application/json'
+        expect(json_response['healthy']).to be true
+      end
+    end
+
+    context 'when a service is down but NO access token' do
+      it 'returns a not found page' do
+        get :index
+        expect(response).to be_not_found
+      end
+    end
+
+    context 'when a service is down and an access token is provided' do
+      before do
+        allow(HealthCheck::Utils).to receive(:process_checks).with('standard').and_return('The server is on fire')
+        allow(HealthCheck::Utils).to receive(:process_checks).with('email').and_return('Email is on fire')
+      end
+
+      it 'supports failure plaintest response' do
+        get :index, token: token
+        expect(response.status).to eq(500)
+        expect(response.content_type).to eq 'text/plain'
+        expect(response.body).to include('The server is on fire')
+      end
+
+      it 'supports failure json response' do
+        get :index, token: token, format: :json
+        expect(response.status).to eq(500)
+        expect(response.content_type).to eq 'application/json'
+        expect(json_response['healthy']).to be false
+        expect(json_response['message']).to include('The server is on fire')
+      end
+
+      it 'supports failure xml response' do
+        get :index, token: token, format: :xml
+        expect(response.status).to eq(500)
+        expect(response.content_type).to eq 'application/xml'
+        expect(xml_response['healthy']).to be false
+        expect(xml_response['message']).to include('The server is on fire')
+      end
+
+      it 'supports failure responses for specific checks' do
+        get :index, token: token, checks: 'email', format: :json
+        expect(response.status).to eq(500)
+        expect(response.content_type).to eq 'application/json'
+        expect(json_response['healthy']).to be false
+        expect(json_response['message']).to include('Email is on fire')
+      end
+    end
+  end
+end
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
new file mode 100644
index 00000000000..4fde04b609b
--- /dev/null
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+
+feature "Admin Health Check", feature: true do
+  include WaitForAjax
+
+  before do
+    login_as :admin
+  end
+
+  describe '#show' do
+    before do
+      visit admin_health_check_path
+    end
+
+    it { page.has_text? 'Health Check' }
+    it { page.has_text? 'Health information can be reteived' }
+
+    it 'has a health check access token' do
+      token = current_application_settings.health_check_access_token
+      expect(page).to have_content("Access token is #{token}")
+      expect(page).to have_selector('#health-check-token', text: token)
+    end
+
+    describe 'reload access token', js: true do
+      it 'changes the access token' do
+        orig_token = current_application_settings.health_check_access_token
+        click_button 'Reset health check access token'
+        wait_for_ajax
+        expect(find('#health-check-token').text).not_to eq orig_token
+      end
+    end
+  end
+
+  context 'when services are up' do
+    before do
+      visit admin_health_check_path
+    end
+
+    it 'shows healthy status' do
+      expect(page).to have_content('Current Status: Healthy')
+    end
+  end
+
+  context 'when a service is down' do
+    before do
+      allow(HealthCheck::Utils).to receive(:process_checks).and_return('The server is on fire')
+      visit admin_health_check_path
+    end
+
+    it 'shows unhealthy status' do
+      expect(page).to have_content('Current Status: Unhealthy')
+      expect(page).to have_content('The server is on fire')
+    end
+  end
+end
diff --git a/spec/routing/admin_routing_spec.rb b/spec/routing/admin_routing_spec.rb
index cd16a8e6322..b5ed8584c8a 100644
--- a/spec/routing/admin_routing_spec.rb
+++ b/spec/routing/admin_routing_spec.rb
@@ -118,3 +118,10 @@ describe Admin::DashboardController, "routing" do
     expect(get("/admin")).to route_to('admin/dashboard#index')
   end
 end
+
+# admin_health_check GET    /admin/health_check(.:format) admin/health_check#show
+describe Admin::HealthCheckController, "routing" do
+  it "to #show" do
+    expect(get("/admin/health_check")).to route_to('admin/health_check#show')
+  end
+end
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index 1527eddfa48..e4dfd4bca35 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -243,3 +243,13 @@ describe "Groups", "routing" do
     expect(get('/1')).to route_to('namespaces#show', id: '1')
   end
 end
+
+describe HealthCheckController, 'routing' do
+  it 'to #index' do
+    expect(get('/health_check')).to route_to('health_check#index')
+  end
+
+  it 'also supports passing checks in the url' do
+    expect(get('/health_check/email')).to route_to('health_check#index', checks: 'email')
+  end
+end
-- 
2.30.9