# frozen_string_literal: true
require 'rack'
module Coverband
module Reporters
# TODO: move to reports and drop need for S3 allow reading from adapters?
class Web
attr_reader :request
def initialize
full_path = Gem::Specification.find_by_name('coverband').full_gem_path
@static = Rack::Static.new(self,
root: File.expand_path('public', full_path),
urls: [/.*\.css/, /.*\.js/, /.*\.gif/, /.*\.png/])
end
def call(env)
@request = Rack::Request.new(env)
if request.post?
case request.path_info
when %r{\/collect_update_and_view}
collect_update_and_view
when %r{\/clear}
clear
when %r{\/update_report}
update_report
when %r{\/collect_coverage}
collect_coverage
when %r{\/reload_files}
reload_files
else
[404, { 'Content-Type' => 'text/html' }, ['404 error!']]
end
else
case request.path_info
when /.*\.(css|js|gif|png)/
@static.call(env)
when %r{\/show}
[200, { 'Content-Type' => 'text/html' }, [show]]
when %r{\/}
[200, { 'Content-Type' => 'text/html' }, [index]]
else
[404, { 'Content-Type' => 'text/html' }, ['404 error!']]
end
end
end
# TODO: move to file or template
def index
notice = "Notice: #{Rack::Utils.escape_html(request.params['notice'])}
"
notice = request.params['notice'] ? notice : ''
%(
#{notice}
- Coverband Web Admin Index
- #{button("#{base_path}collect_update_and_view", 'collect data, update report, & view')}
- view coverage report
- #{button("#{base_path}collect_coverage", 'update coverage data (collect coverage)')}
- #{button("#{base_path}update_report", 'update coverage report (rebuild report)')}
- #{button("#{base_path}clear", 'clear coverage report')}
- #{button("#{base_path}reload_files", 'reload Coverband files')}
version: #{Coverband::VERSION}
Coverband
)
end
def show
html = Coverband::Reporters::HTMLReport.report(Coverband.configuration.store,
html: true, open_report: false)
fix_html_paths(html)
end
def collect_update_and_view
collect_coverage
update_report
[301, { 'Location' => "#{base_path}show" }, []]
end
def update_report
Coverband::Reporters::HTMLReport.report(Coverband.configuration.store, open_report: false)
notice = 'coverband coverage updated'
[301, { 'Location' => "#{base_path}?notice=#{notice}" }, []]
end
def collect_coverage
Coverband::Collectors::Coverage.instance.report_coverage(true)
notice = 'coverband coverage collected'
[301, { 'Location' => "#{base_path}?notice=#{notice}" }, []]
end
def clear
Coverband.configuration.store.clear!
notice = 'coverband coverage cleared'
[301, { 'Location' => "#{base_path}?notice=#{notice}" }, []]
end
def reload_files
Coverband.configuration&.safe_reload_files&.each do |safe_file|
load safe_file
end
# force reload
Coverband.configure
notice = 'coverband files reloaded'
[301, { 'Location' => "#{base_path}?notice=#{notice}" }, []]
end
private
def fix_html_paths(html)
# HACK: the static HTML assets to link to the path where this was mounted
html = html.gsub("src='", "src='#{base_path}")
html = html.gsub("href='", "href='#{base_path}")
html = html.gsub('loading.gif', "#{base_path}loading.gif")
html = html.gsub('/images/', "#{base_path}images/")
html.gsub("./assets/#{Coverband::VERSION}/", '')
end
def button(url, title)
button = "'
end
# This method should get the root mounted endpoint
# for example if the app is mounted like so:
# mount Coverband::Web, at: '/coverage'
# "/coverage/collect_coverage?" become:
# /coverage/
def base_path
request.path.match("\/.*\/") ? request.path.match("\/.*\/")[0] : '/'
end
end
end
end