kanaui 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: cd2ea6af02abb8c8606e4a716f93ae4174e60281700b637de2f52272aabaa512
4
- data.tar.gz: e046e9ea44c7c2c12bae7d4bc342167ce5664a428ac589648f34909cd7985472
2
+ SHA1:
3
+ metadata.gz: c634cb242e7d9aef0a4bb937451a57c3f10f0c90
4
+ data.tar.gz: '08e4e1e1419a230305488420fa8f2f8b69de57a4'
5
5
  SHA512:
6
- metadata.gz: dbcdcb70318254bc916700840a9fb4ffa040724b59b86005ed121437ea8ff8a2e9d95dd817b74e4a774fd0d66b94ab0a6e6d7dff67816774612dba08ed1861b8
7
- data.tar.gz: b87d87b1981d4626053369b9eacb94c33d85d26f8f8a22532845f296a3068d573e214e3caf3086505b5cea0d689e20ee174529a0755dc541798b874bf71c89ce
6
+ metadata.gz: 4e4bd12458f02a2beeddd6b111e89460245bcc24c8d65be1debd3b261eb88dc55ce6a139e7e550e5110c59cc8d63b287805ec47d74ad803849560b97e55a2eb2
7
+ data.tar.gz: a3d7284429507ddc4b465613407b30ccd3ed118f31b834a7db4846ff1a7b9b416e89f9526e5c2f38a4ee4ed28651f3b3d9d6fe4aa8121a9d2534b18cfe1ae68e
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env rake
2
+ # frozen_string_literal: true
3
+
2
4
  begin
3
5
  require 'bundler/setup'
4
6
  rescue LoadError
@@ -20,11 +22,9 @@ RDoc::Task.new(:rdoc) do |rdoc|
20
22
  rdoc.rdoc_files.include('lib/**/*.rb')
21
23
  end
22
24
 
23
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
25
+ APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
24
26
  load 'rails/tasks/engine.rake'
25
27
 
26
-
27
-
28
28
  Bundler::GemHelper.install_tasks
29
29
 
30
30
  require 'rake/testtask'
@@ -36,5 +36,4 @@ Rake::TestTask.new(:test) do |t|
36
36
  t.verbose = false
37
37
  end
38
38
 
39
-
40
- task :default => :test
39
+ task default: :test
@@ -8,7 +8,7 @@
8
8
  var renderer = new Kiddo.Renderer('#chartAnchor');
9
9
 
10
10
  if (error) {
11
- console.log(error);
11
+ ajaxErrorAlert(error);
12
12
  return renderer.noData();
13
13
  }
14
14
 
@@ -52,6 +52,7 @@ ReportsDataTables.prototype.buildTable = function(data, wrapper) {
52
52
  dataTable.dataTable({
53
53
  "aaData": aaData,
54
54
  "aoColumns": aoColumns,
55
+ "scrollX": true,
55
56
  "sDom": 'C<"clear">lfrtip'
56
57
  });
57
58
 
@@ -1,3 +1,11 @@
1
+ #reports-table th, #reports-table td,
2
+ #dataTable-api_wrapper th, #dataTable-api_wrapper td {
3
+ white-space: nowrap;
4
+ }
5
+
6
+ .sql-query {
7
+ word-break: break-word;
8
+ }
1
9
 
2
10
  .axis path,
3
11
  .axis line {
@@ -138,6 +146,7 @@ button.ColVis_Button:hover, ul.ColVis_collection li:hover {
138
146
  -ms-flex: .5 1 70%;
139
147
  -webkit-flex: .5 1 70%;
140
148
  flex: .5 1 70%;
149
+ overflow: scroll;
141
150
  }
142
151
 
143
152
  #date-picker .form-group {
@@ -146,4 +155,4 @@ button.ColVis_Button:hover, ul.ColVis_collection li:hover {
146
155
 
147
156
  #table-tools {
148
157
  padding-bottom: 10px;
149
- }
158
+ }
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kanaui
2
4
  class DashboardController < Kanaui::EngineController
3
-
4
5
  #
5
6
  # Load the dashboard by rendering the view and executing the javascript that will call
6
7
  # the reports and available_reports endpoints below.
@@ -25,14 +26,14 @@ module Kanaui
25
26
 
26
27
  # Redirect also in case the dates have been updated to avoid any confusion in the view
27
28
  if query.present? || params[:start_date].blank? || params[:end_date].blank?
28
- # TODO Make metrics configurable
29
+ # TODO: Make metrics configurable
29
30
  name = query.present? ? "#{params[:name]}#{query}^metric:count" : params[:name]
30
- query_params = {:start_date => @start_date,
31
- :end_date => @end_date,
32
- :name => name,
33
- :smooth => params[:smooth],
34
- :sql_only => params[:sql_only],
35
- :format => params[:format]}
31
+ query_params = { start_date: @start_date,
32
+ end_date: @end_date,
33
+ name: name,
34
+ smooth: params[:smooth],
35
+ sql_only: params[:sql_only],
36
+ format: params[:format] }
36
37
 
37
38
  # Test only
38
39
  query_params[:fake] = params[:fake] unless params[:fake].blank?
@@ -47,7 +48,7 @@ module Kanaui
47
48
  # Not used anymore as reports are pulled from index
48
49
  def available_reports
49
50
  available_reports = Kanaui::DashboardHelper::DashboardApi.available_reports(options_for_klient)
50
- render :json => available_reports
51
+ render json: available_reports
51
52
  end
52
53
 
53
54
  def reports
@@ -66,7 +67,7 @@ module Kanaui
66
67
  else
67
68
  reports = raw_reports
68
69
  end
69
- render :json => reports
70
+ render json: reports
70
71
  end
71
72
 
72
73
  private
@@ -117,6 +118,7 @@ module Kanaui
117
118
  filter_query = ''
118
119
  filters.each do |k, v|
119
120
  next if v.blank?
121
+
120
122
  filter_query << '%26' unless filter_query.blank?
121
123
  filter_query << "(#{k}=#{v.join("|#{k}=")})"
122
124
  end
@@ -124,7 +126,8 @@ module Kanaui
124
126
 
125
127
  groups.each do |k, v|
126
128
  next if v.blank?
127
- # TODO Make "no other" configurable
129
+
130
+ # TODO: Make "no other" configurable
128
131
  query << "^dimension:#{k}(#{v.join('|')}|-)"
129
132
  end
130
133
 
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kanaui
2
4
  class EngineController < ApplicationController
3
-
4
5
  layout :get_layout
5
6
 
6
7
  def get_layout
@@ -17,12 +18,46 @@ module Kanaui
17
18
  def options_for_klient
18
19
  user = current_tenant_user
19
20
  {
20
- :username => user[:username],
21
- :password => user[:password],
22
- :session_id => user[:session_id],
23
- :api_key => user[:api_key],
24
- :api_secret => user[:api_secret]
21
+ username: user[:username],
22
+ password: user[:password],
23
+ session_id: user[:session_id],
24
+ api_key: user[:api_key],
25
+ api_secret: user[:api_secret]
25
26
  }
26
27
  end
28
+
29
+ rescue_from(KillBillClient::API::ResponseError) do |killbill_exception|
30
+ flash[:error] = "Error while communicating with the Kill Bill server: #{as_string(killbill_exception)}"
31
+ redirect_to dashboard_index_path
32
+ end
33
+
34
+ def as_string(e)
35
+ if e.is_a?(KillBillClient::API::ResponseError)
36
+ "Error #{e.response.code}: #{as_string_from_response(e.response.body)}"
37
+ else
38
+ log_rescue_error(e)
39
+ e.message
40
+ end
41
+ end
42
+
43
+ def log_rescue_error(error)
44
+ Rails.logger.warn "#{error.class} #{error}. #{error.backtrace.join("\n")}"
45
+ end
46
+
47
+ def as_string_from_response(response)
48
+ error_message = response
49
+ begin
50
+ # BillingExceptionJson?
51
+ error_message = JSON.parse response
52
+ rescue StandardError => _e
53
+ end
54
+
55
+ if error_message.respond_to?(:[]) && error_message['message'].present?
56
+ # Likely BillingExceptionJson
57
+ error_message = error_message['message']
58
+ end
59
+ # Limit the error size to avoid ActionDispatch::Cookies::CookieOverflow
60
+ error_message[0..1000]
61
+ end
27
62
  end
28
63
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kanaui
2
4
  class ReportsController < Kanaui::EngineController
3
-
4
5
  def index
5
6
  @reports = JSON.parse(Kanaui::DashboardHelper::DashboardApi.available_reports(options_for_klient)).map(&:deep_symbolize_keys)
6
7
  end
@@ -13,7 +14,7 @@ module Kanaui
13
14
  Kanaui::DashboardHelper::DashboardApi.create_report(report_from_params.to_json, options_for_klient)
14
15
 
15
16
  flash[:notice] = 'Report successfully created'
16
- redirect_to :action => :index
17
+ redirect_to action: :index
17
18
  end
18
19
 
19
20
  def edit
@@ -26,34 +27,36 @@ module Kanaui
26
27
  Kanaui::DashboardHelper::DashboardApi.update_report(params.require(:id), report_from_params.to_json, options_for_klient)
27
28
 
28
29
  flash[:notice] = 'Report successfully updated'
29
- redirect_to :action => :index
30
+ redirect_to action: :index
30
31
  end
31
32
 
32
33
  def refresh
33
34
  Kanaui::DashboardHelper::DashboardApi.refresh_report(params.require(:id), options_for_klient)
34
35
 
35
36
  flash[:notice] = 'Report refresh successfully scheduled'
36
- redirect_to :action => :index
37
+ redirect_to action: :index
37
38
  end
38
39
 
39
40
  def destroy
40
41
  Kanaui::DashboardHelper::DashboardApi.delete_report(params.require(:id), options_for_klient)
41
42
 
42
43
  flash[:notice] = 'Report successfully deleted'
43
- redirect_to :action => :index
44
+ redirect_to action: :index
44
45
  end
45
46
 
46
47
  private
47
48
 
48
49
  def report_from_params
49
50
  {
50
- :reportName => params[:report_name],
51
- :reportPrettyName => params[:report_pretty_name],
52
- :reportType => params[:report_type],
53
- :sourceTableName => params[:source_table_name],
54
- :refreshProcedureName => params[:refresh_procedure_name],
55
- :refreshFrequency => params[:refresh_frequency],
56
- :refreshHourOfDayGmt => params[:refresh_hour_of_day_gmt]
51
+ reportName: params[:report_name],
52
+ reportPrettyName: params[:report_pretty_name],
53
+ reportType: params[:report_type],
54
+ sourceTableName: params[:source_table_name],
55
+ sourceName: params[:source_name],
56
+ sourceQuery: params[:source_query],
57
+ refreshProcedureName: params[:refresh_procedure_name],
58
+ refreshFrequency: params[:refresh_frequency].presence,
59
+ refreshHourOfDayGmt: params[:refresh_hour_of_day_gmt]
57
60
  }
58
61
  end
59
62
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kanaui
4
+ class SettingsController < Kanaui::EngineController
5
+ def index; end
6
+
7
+ # update would have been nicer, but it's hard to pass the id in the url
8
+ def create
9
+ Kanaui::DashboardHelper::DashboardApi.refresh(params.require(:account_id), options_for_klient)
10
+ redirect_to({ action: :index }, notice: 'Account successfully refreshed')
11
+ end
12
+ end
13
+ end
@@ -1,6 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kanaui
2
4
  module ApplicationHelper
3
-
4
-
5
5
  end
6
6
  end
@@ -1,11 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kanaui
2
4
  module DashboardHelper
3
-
4
5
  class DashboardApi < KillBillClient::Model::Resource
5
-
6
- KILLBILL_ANALYTICS_PREFIX = "/plugins/killbill-analytics"
6
+ KILLBILL_ANALYTICS_PREFIX = '/plugins/killbill-analytics'
7
7
 
8
8
  class << self
9
+ def refresh(account_id, options = {})
10
+ path = "#{KILLBILL_ANALYTICS_PREFIX}/#{account_id}"
11
+ KillBillClient::API.put path, {}, {}, options
12
+ end
9
13
 
10
14
  def available_reports(options = {})
11
15
  path = "#{KILLBILL_ANALYTICS_PREFIX}/reports"
@@ -48,7 +52,5 @@ module Kanaui
48
52
  end
49
53
  end
50
54
  end
51
-
52
55
  end
53
56
  end
54
-
@@ -2,33 +2,47 @@
2
2
  <!-- MENU -->
3
3
  <div class="reports-options flex-inner-left-panel">
4
4
  <div class="row">
5
- <% if params[:name] && @report['reportType'] == 'TIMELINE' %>
6
- <div id="date-picker" class="col-md-12">
7
- <h4>End date</h4>
8
- <%= form_tag kanaui_engine.dashboard_index_path, :html => {:class => 'form-horizontal'}, :method => :get do %>
9
- <input name="name" type="hidden" value="<%= @raw_name %>">
10
- <input name="smooth" type="hidden" value="<%= params[:smooth] %>">
11
- <input name="sql_only" type="hidden" value="<%= params[:sql_only] %>">
12
- <input name="format" type="hidden" value="<%= params[:format] %>">
13
- <input name="delta_days" type="hidden" value="<%= (@end_date.to_date - @start_date.to_date).to_i %>">
5
+ <% if params[:name] %>
6
+ <div class="info-wrapper">
7
+ <div class="tag-bar tag-bar-breathe">
8
+ <div class="tag-select" onclick="void(0);">
9
+ <span><i class="fa fa-calendar"></i><i class="fa fa-caret-down"></i></span>
14
10
 
15
- <div class="form-group">
16
- <div class="col-md-12">
17
- <input class="form-control" name="end_date" type="text" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-today-highlight="true" value="<%= @end_date %>">
18
- </div>
19
- </div>
20
- <div class="form-group">
21
- <div class="col-sm-12">
22
- <%= submit_tag 'Refresh', :class => 'btn btn-default' %>
23
- </div>
24
- </div>
25
- <% end %>
26
- </div>
11
+ <div class="tag-select-box">
12
+ <%= form_tag kanaui_engine.dashboard_index_path, :class => 'form-horizontal', :method => :get do %>
13
+ <input name="name" type="hidden" value="<%= @raw_name %>">
14
+ <input name="smooth" type="hidden" value="<%= params[:smooth] %>">
15
+ <input name="sql_only" type="hidden" value="<%= params[:sql_only] %>">
16
+ <input name="format" type="hidden" value="<%= params[:format] %>">
17
+ <input name="delta_days" type="hidden" value="<%= (@end_date.to_date - @start_date.to_date).to_i %>">
18
+
19
+ <div class="form-group">
20
+ <div class="col-md-7">
21
+ <% # TODO datepicker breaks :hover %>
22
+ From:<input class="form-control" name="start_date" type="text" data-provide="datepicker-BROKEN" data-date-format="yyyy-mm-dd" data-date-today-highlight="true" value="<%= @start_date %>">
23
+ </div>
24
+ </div>
25
+ <div class="form-group">
26
+ <div class="col-md-7">
27
+ <% # TODO datepicker breaks :hover %>
28
+ To:<input class="form-control" name="end_date" type="text" data-provide="datepicker-BROKEN" data-date-format="yyyy-mm-dd" data-date-today-highlight="true" value="<%= @end_date %>">
29
+ </div>
30
+ </div>
31
+ <div class="form-group">
32
+ <div class="col-sm-12">
33
+ <%= submit_tag 'Refresh', :class => 'btn btn-default' %>
34
+ </div>
35
+ </div>
36
+ <% end %>
37
+ </div><!-- /.tag-select-box -->
38
+ </div><!-- /.tag-select -->
39
+ </div><!-- /.tag-bar -->
40
+ </div><!-- /.info-wrapper -->
27
41
  <% end %>
28
42
  <div class="col-md-12 col-sm-8">
29
43
  <h4><%= link_to 'Available Reports', kanaui_engine.url_for(:controller => :reports) %></h4>
30
44
  <ul class="nav nav-tabs nav-stacked">
31
- <% if Rails.env.development? %>
45
+ <% if Rails.env.development? && @reports.empty? %>
32
46
  <li class="nav-element">
33
47
  <%= link_to "Fake pie", kanaui_engine.dashboard_index_path(:fake => 1, :name => 'fake_pie', :type => 'pie') %>
34
48
  </li>
@@ -45,6 +59,11 @@
45
59
  </ul>
46
60
  </div>
47
61
  </div>
62
+ <div class="row">
63
+ <div class="col-md-12 col-sm-8">
64
+ <h5><%= link_to 'Settings', kanaui_engine.url_for(:controller => :settings) %></h5>
65
+ </div>
66
+ </div>
48
67
  </div>
49
68
 
50
69
  <!-- DASHBOARD -->
@@ -55,16 +74,6 @@
55
74
  <h2 class="chart-title">
56
75
  <%= @raw_name.titleize %>
57
76
  </h2>
58
- <% if @report['reportType'] == 'TABLE' %>
59
- <input type="hidden" id="visible-table-columns" value="<%= @visible_columns %>">
60
-
61
- <div id="table-tools" class="row">
62
- <div class="col-sm-2">
63
- <a class="btn btn-default" id="copy-url" data-reports-path="<%= kanaui_engine.dashboard_index_path(params.to_h) %>">Copy URL</a>
64
- <input id="url-placeholder" class="form-control hidden">
65
- </div>
66
- </div>
67
- <% end %>
68
77
  <div id="loading-spinner"></div>
69
78
  <div id="chartAnchor" data-reports-path="<%= kanaui_engine.reports_path(params.to_h) %>"></div>
70
79
  <div id="date-controls" style="display: none;">
@@ -76,6 +85,11 @@
76
85
  </div>
77
86
  <hr>
78
87
  <div class="pull-right">
88
+ <% if @report['reportType'] == 'TABLE' %>
89
+ <input type="hidden" id="visible-table-columns" value="<%= @visible_columns %>">
90
+ <a class="btn btn-default" id="copy-url" data-reports-path="<%= kanaui_engine.dashboard_index_path(params.to_h) %>">Copy URL</a>
91
+ <input id="url-placeholder" class="form-control hidden">
92
+ <% end %>
79
93
  <%= link_to 'Download raw data', kanaui_engine.reports_path(params.to_h.merge(:format => 'csv')), class: 'btn btn-default' %>
80
94
  </div>
81
95
  <a class="btn btn-default" role="button" data-toggle="collapse" href="#advanced-controls" aria-expanded="false" aria-controls="advanced-controls">
@@ -1,48 +1,62 @@
1
1
  <%= form_tag @report[:reportName].blank? ? url_for(:controller => :reports, :action => :create) : report_path(@report[:reportName]), :method => (@report[:reportName].blank? ? :post : :put), :class => 'form-horizontal' do %>
2
2
  <div class="form-group">
3
- <%= label_tag :report_name, 'Report name', :class => 'col-sm-2 control-label' %>
4
- <div class="col-sm-10">
3
+ <%= label_tag :report_name, 'Report name', :class => 'col-sm-3 control-label' %>
4
+ <div class="col-sm-9">
5
5
  <%= text_field_tag :report_name, @report[:reportName], :class => 'form-control', :disabled => !@report[:reportName].blank?, :read_only => !@report[:reportName].blank? %>
6
6
  </div>
7
7
  </div>
8
8
  <div class="form-group">
9
- <%= label_tag :report_pretty_name, 'Pretty name', :class => 'col-sm-2 control-label' %>
10
- <div class="col-sm-10">
9
+ <%= label_tag :report_pretty_name, 'Pretty name', :class => 'col-sm-3 control-label' %>
10
+ <div class="col-sm-9">
11
11
  <%= text_field_tag :report_pretty_name, @report[:reportPrettyName], :class => 'form-control' %>
12
12
  </div>
13
13
  </div>
14
14
  <div class="form-group">
15
- <%= label_tag :report_type, 'Type', :class => 'col-sm-2 control-label' %>
16
- <div class="col-sm-10">
15
+ <%= label_tag :report_type, 'Type', :class => 'col-sm-3 control-label' %>
16
+ <div class="col-sm-9">
17
17
  <%= select_tag :report_type, options_for_select(%w(TIMELINE COUNTERS TABLE), @report[:reportType] || 'TABLE'), :class => 'form-control' %>
18
18
  </div>
19
19
  </div>
20
20
  <div class="form-group">
21
- <%= label_tag :source_table_name, 'Source', :class => 'col-sm-2 control-label' %>
22
- <div class="col-sm-10">
21
+ <%= label_tag :source_table_name, 'Source', :class => 'col-sm-3 control-label' %>
22
+ <div class="col-sm-9">
23
23
  <%= text_field_tag :source_table_name, @report[:sourceTableName], :class => 'form-control' %>
24
24
  </div>
25
25
  </div>
26
26
  <div class="form-group">
27
- <%= label_tag :refresh_procedure_name, 'Refresh procedure', :class => 'col-sm-2 control-label' %>
28
- <div class="col-sm-10">
27
+ <%= label_tag :source_name, 'Source name', :class => 'col-sm-3 control-label' %>
28
+ <div class="col-sm-9">
29
+ <%= text_field_tag :source_name, @report[:sourceName], :class => 'form-control' %>
30
+ <span>Must match a database configuration entry in the Analytics plugin</span>
31
+ </div>
32
+ </div>
33
+ <div class="form-group">
34
+ <%= label_tag :source_query, 'SQL query', :class => 'col-sm-3 control-label' %>
35
+ <div class="col-sm-9">
36
+ <%= text_area_tag :source_query, @report[:sourceQuery], rows: 10, cols: 25, :class => 'form-control' %>
37
+ <span>Don't add a trailing ;</span>
38
+ </div>
39
+ </div>
40
+ <div class="form-group">
41
+ <%= label_tag :refresh_procedure_name, 'Refresh procedure', :class => 'col-sm-3 control-label' %>
42
+ <div class="col-sm-9">
29
43
  <%= text_field_tag :refresh_procedure_name, @report[:refreshProcedureName], :class => 'form-control' %>
30
44
  </div>
31
45
  </div>
32
46
  <div class="form-group">
33
- <%= label_tag :refresh_frequency, 'Refresh frequency', :class => 'col-sm-2 control-label' %>
34
- <div class="col-sm-10">
35
- <%= select_tag :refresh_frequency, options_for_select(%w(HOURLY DAILY), @report[:refreshFrequency] || 'HOURLY'), :class => 'form-control' %>
47
+ <%= label_tag :refresh_frequency, 'Refresh frequency', :class => 'col-sm-3 control-label' %>
48
+ <div class="col-sm-9">
49
+ <%= select_tag :refresh_frequency, options_for_select(%w(HOURLY DAILY), @report[:refreshFrequency]), :class => 'form-control', :include_blank => true %>
36
50
  </div>
37
51
  </div>
38
52
  <div class="form-group">
39
- <%= label_tag :refresh_hour_of_day_gmt, 'Refresh hour (GMT)', :class => 'col-sm-2 control-label' %>
40
- <div class="col-sm-10">
53
+ <%= label_tag :refresh_hour_of_day_gmt, 'Refresh hour (GMT)', :class => 'col-sm-3 control-label' %>
54
+ <div class="col-sm-9">
41
55
  <%= number_field_tag :refresh_hour_of_day_gmt, @report[:refreshHourOfDayGmt], {:min => 1, :max => 23, :class => 'form-control'} %>
42
56
  </div>
43
57
  </div>
44
58
  <div class="form-group">
45
- <div class="col-sm-offset-2 col-sm-10">
59
+ <div class="col-sm-offset-3 col-sm-9">
46
60
  <%= submit_tag 'Save', :class => 'btn btn-default' %>
47
61
  </div>
48
62
  </div>
@@ -5,6 +5,8 @@
5
5
  <th>Pretty name</th>
6
6
  <th>Type</th>
7
7
  <th>Source</th>
8
+ <th>Source Name</th>
9
+ <th>Source Query</th>
8
10
  <th>Refresh procedure</th>
9
11
  <th>Refresh frequency</th>
10
12
  <th>Refresh hour (GMT)</th>
@@ -19,6 +21,23 @@
19
21
  <td><%= report[:reportPrettyName] %></td>
20
22
  <td><%= report[:reportType] %></td>
21
23
  <td><%= report[:sourceTableName] %></td>
24
+ <td><%= report[:sourceName] %></td>
25
+ <td>
26
+ <% unless report[:sourceQuery].blank? %>
27
+ <a href="" data-toggle="modal" data-target="#<%= report[:reportName] %>-query-modal">
28
+ Show SQL
29
+ </a>
30
+ <div class="modal fade" id="<%= report[:reportName] %>-query-modal" tabindex="-1" role="dialog">
31
+ <div class="modal-dialog" role="document">
32
+ <div class="modal-content column-block">
33
+ <div class="modal-body">
34
+ <p><pre class="sql-query"><code><%= report[:sourceQuery] %></code></pre></p>
35
+ </div>
36
+ </div><!-- /.modal-content -->
37
+ </div><!-- /.modal-dialog -->
38
+ </div><!-- /.modal -->
39
+ <% end %>
40
+ </td>
22
41
  <td><%= report[:refreshProcedureName] %></td>
23
42
  <td><%= report[:refreshFrequency] %></td>
24
43
  <td><%= report[:refreshHourOfDayGmt] %></td>
@@ -42,6 +61,7 @@
42
61
  <%= javascript_tag do %>
43
62
  $(document).ready(function() {
44
63
  $('#reports-table').dataTable({
64
+ "scrollX": true,
45
65
  "dom": "t",
46
66
  "paging": false,
47
67
  "columns": [
@@ -52,6 +72,8 @@
52
72
  null,
53
73
  null,
54
74
  null,
75
+ null,
76
+ null,
55
77
  { "orderable": false },
56
78
  { "orderable": false }
57
79
  ]
@@ -0,0 +1,19 @@
1
+ <div class="column-block">
2
+ <h1>Analytics settings</h1>
3
+
4
+ <div>
5
+ <%= form_tag kanaui_engine.settings_path, :method => :post, :class => 'form-horizontal' do %>
6
+ <div class='form-group'>
7
+ <%= label_tag :account_id, 'Account id', :class => 'col-sm-2 control-label' %>
8
+ <div class="col-sm-4">
9
+ <%= text_field_tag :account_id, nil, :class => 'form-control' %>
10
+ </div>
11
+ </div>
12
+ <div class="form-group">
13
+ <div class="col-sm-offset-2 col-sm-10">
14
+ <%= submit_tag 'Refresh', :class => 'btn btn-default' %>
15
+ </div>
16
+ </div>
17
+ <% end %>
18
+ </div>
19
+ </div>
data/config/routes.rb CHANGED
@@ -1,14 +1,17 @@
1
- Kanaui::Engine.routes.draw do
1
+ # frozen_string_literal: true
2
2
 
3
+ Kanaui::Engine.routes.draw do
3
4
  root to: 'dashboard#index'
4
- resources :dashboard, :only => [:index]
5
- scope "/dashboard" do
6
- match "/available_reports" => "dashboard#available_reports", :via => :get, :as => "available_reports"
7
- match "/reports" => "dashboard#reports", :via => :get, :as => "reports"
5
+ resources :dashboard, only: [:index]
6
+ scope '/dashboard' do
7
+ match '/available_reports' => 'dashboard#available_reports', :via => :get, :as => 'available_reports'
8
+ match '/reports' => 'dashboard#reports', :via => :get, :as => 'reports'
8
9
  end
9
10
 
10
- resources :reports, :only => [:index, :new, :create, :edit, :update, :destroy]
11
- scope "/reports" do
12
- match "/refresh/:id" => "reports#refresh", :via => :put, :as => "refresh_report"
11
+ resources :reports, only: %i[index new create edit update destroy]
12
+ scope '/reports' do
13
+ match '/refresh/:id' => 'reports#refresh', :via => :put, :as => 'refresh_report'
13
14
  end
15
+
16
+ resources :settings, only: %i[index create]
14
17
  end
data/lib/kanaui.rb CHANGED
@@ -1,21 +1,22 @@
1
- require "kanaui/engine"
1
+ # frozen_string_literal: true
2
2
 
3
- module Kanaui
3
+ require 'kanaui/engine'
4
4
 
5
+ module Kanaui
5
6
  mattr_accessor :current_tenant_user
6
7
  mattr_accessor :layout
7
8
 
8
- self.current_tenant_user = lambda { |session, user|
9
- {:username => 'admin',
10
- :password => 'password',
11
- :session_id => nil,
12
- :api_key => KillBillClient.api_key,
13
- :api_secret => KillBillClient.api_secret}
9
+ self.current_tenant_user = lambda { |_session, _user|
10
+ { username: 'admin',
11
+ password: 'password',
12
+ session_id: nil,
13
+ api_key: KillBillClient.api_key,
14
+ api_secret: KillBillClient.api_secret }
14
15
  }
15
16
 
16
- def self.config(&block)
17
+ def self.config
17
18
  {
18
- :layout => layout || 'kanaui/layouts/kanaui_application',
19
+ layout: layout || 'kanaui/layouts/kanaui_application'
19
20
  }
20
21
  end
21
22
  end
data/lib/kanaui/engine.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Dependencies
2
4
  #
3
5
  # Sigh. Rails autoloads the gems specified in the Gemfile and nothing else.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kanaui
2
- VERSION = "2.0.0"
4
+ VERSION = '2.1.0'
3
5
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # desc "Explaining what the task does"
2
3
  # task :kanaui do
3
4
  # # Task goes here
@@ -0,0 +1 @@
1
+ {}
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module Kanaui
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class NavigationTest < ActionDispatch::IntegrationTest
4
-
5
6
  include Kanaui::Engine.routes.url_helpers
6
7
 
7
8
  test 'can see the dashboard page' do
@@ -9,4 +10,3 @@ class NavigationTest < ActionDispatch::IntegrationTest
9
10
  assert_response :redirect
10
11
  end
11
12
  end
12
-
data/test/kanaui_test.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class KanauiTest < ActiveSupport::TestCase
4
- test "truth" do
6
+ test 'truth' do
5
7
  assert_kind_of Module, Kanaui
6
8
  end
7
9
  end
data/test/test_helper.rb CHANGED
@@ -1,15 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Configure Rails Environment
2
- ENV["RAILS_ENV"] = "test"
4
+ ENV['RAILS_ENV'] = 'test'
3
5
 
4
- require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
- require "rails/test_help"
6
+ require File.expand_path('dummy/config/environment.rb', __dir__)
7
+ require 'rails/test_help'
6
8
 
7
9
  Rails.backtrace_cleaner.remove_silencers!
8
10
 
9
11
  # Load support files
10
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
12
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
11
13
 
12
14
  # Load fixtures from the engine
13
- if ActiveSupport::TestCase.method_defined?(:fixture_path=)
14
- ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
15
- end
15
+ ActiveSupport::TestCase.fixture_path = File.expand_path('fixtures', __dir__) if ActiveSupport::TestCase.method_defined?(:fixture_path=)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module Kanaui
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kanaui
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kill Bill core team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-21 00:00:00.000000000 Z
11
+ date: 2021-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: d3_rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '5.1'
19
+ version: 3.2.8
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '5.1'
26
+ version: 3.2.8
27
27
  - !ruby/object:Gem::Dependency
28
- name: js-routes
28
+ name: jquery-datatables-rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.1'
33
+ version: '3.3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.1'
40
+ version: '3.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: jquery-rails
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,47 +53,47 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.3'
55
55
  - !ruby/object:Gem::Dependency
56
- name: jquery-datatables-rails
56
+ name: js-routes
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.3'
61
+ version: '1.1'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.3'
68
+ version: '1.1'
69
69
  - !ruby/object:Gem::Dependency
70
- name: d3_rails
70
+ name: rails
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 3.2.8
75
+ version: '5.1'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 3.2.8
82
+ version: '5.1'
83
83
  - !ruby/object:Gem::Dependency
84
- name: twitter-bootstrap-rails
84
+ name: bootstrap-datepicker-rails
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '1.6'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '1.6'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: font-awesome-rails
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '4.7'
111
+ - !ruby/object:Gem::Dependency
112
+ name: killbill-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.2'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.2'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: spinjs-rails
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -123,49 +137,49 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '1.4'
125
139
  - !ruby/object:Gem::Dependency
126
- name: bootstrap-datepicker-rails
140
+ name: twitter-bootstrap-rails
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - "~>"
143
+ - - ">="
130
144
  - !ruby/object:Gem::Version
131
- version: '1.6'
145
+ version: '0'
132
146
  type: :runtime
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - "~>"
150
+ - - ">="
137
151
  - !ruby/object:Gem::Version
138
- version: '1.6'
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
- name: killbill-client
154
+ name: gem-release
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '3.2'
146
- type: :runtime
159
+ version: '2.2'
160
+ type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '3.2'
166
+ version: '2.2'
153
167
  - !ruby/object:Gem::Dependency
154
- name: rake
168
+ name: json
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - ">="
158
172
  - !ruby/object:Gem::Version
159
- version: '0'
173
+ version: 1.8.6
160
174
  type: :development
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
178
  - - ">="
165
179
  - !ruby/object:Gem::Version
166
- version: '0'
180
+ version: 1.8.6
167
181
  - !ruby/object:Gem::Dependency
168
- name: simplecov
182
+ name: listen
169
183
  requirement: !ruby/object:Gem::Requirement
170
184
  requirements:
171
185
  - - ">="
@@ -179,7 +193,7 @@ dependencies:
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0'
181
195
  - !ruby/object:Gem::Dependency
182
- name: listen
196
+ name: rake
183
197
  requirement: !ruby/object:Gem::Requirement
184
198
  requirements:
185
199
  - - ">="
@@ -193,19 +207,33 @@ dependencies:
193
207
  - !ruby/object:Gem::Version
194
208
  version: '0'
195
209
  - !ruby/object:Gem::Dependency
196
- name: json
210
+ name: rubocop
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: 0.88.0
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: 0.88.0
223
+ - !ruby/object:Gem::Dependency
224
+ name: simplecov
197
225
  requirement: !ruby/object:Gem::Requirement
198
226
  requirements:
199
227
  - - ">="
200
228
  - !ruby/object:Gem::Version
201
- version: 1.8.6
229
+ version: '0'
202
230
  type: :development
203
231
  prerelease: false
204
232
  version_requirements: !ruby/object:Gem::Requirement
205
233
  requirements:
206
234
  - - ">="
207
235
  - !ruby/object:Gem::Version
208
- version: 1.8.6
236
+ version: '0'
209
237
  description: Rails UI plugin for the Analytics plugin.
210
238
  email: killbilling-users@googlegroups.com
211
239
  executables: []
@@ -246,6 +274,7 @@ files:
246
274
  - app/controllers/kanaui/dashboard_controller.rb
247
275
  - app/controllers/kanaui/engine_controller.rb
248
276
  - app/controllers/kanaui/reports_controller.rb
277
+ - app/controllers/kanaui/settings_controller.rb
249
278
  - app/helpers/kanaui/application_helper.rb
250
279
  - app/helpers/kanaui/dashboard_helper.rb
251
280
  - app/views/kanaui/dashboard/index.html.erb
@@ -255,6 +284,7 @@ files:
255
284
  - app/views/kanaui/reports/edit.html.erb
256
285
  - app/views/kanaui/reports/index.html.erb
257
286
  - app/views/kanaui/reports/new.html.erb
287
+ - app/views/kanaui/settings/index.html.erb
258
288
  - config/locales/en.bootstrap.yml
259
289
  - config/routes.rb
260
290
  - lib/kanaui.rb
@@ -265,6 +295,7 @@ files:
265
295
  - lib/tasks/kanaui_tasks.rake
266
296
  - test/dummy/README.rdoc
267
297
  - test/dummy/Rakefile
298
+ - test/dummy/app/assets/config/manifest.js
268
299
  - test/dummy/app/controllers/application_controller.rb
269
300
  - test/dummy/app/helpers/application_helper.rb
270
301
  - test/dummy/bin/bundle
@@ -295,7 +326,6 @@ files:
295
326
  - test/dummy/config/locales/en.yml
296
327
  - test/dummy/config/routes.rb
297
328
  - test/dummy/config/secrets.yml
298
- - test/dummy/log/test.log
299
329
  - test/dummy/public/404.html
300
330
  - test/dummy/public/422.html
301
331
  - test/dummy/public/500.html
@@ -326,52 +356,53 @@ required_rubygems_version: !ruby/object:Gem::Requirement
326
356
  - !ruby/object:Gem::Version
327
357
  version: '0'
328
358
  requirements: []
329
- rubygems_version: 3.0.6
359
+ rubyforge_project:
360
+ rubygems_version: 2.6.13
330
361
  signing_key:
331
362
  specification_version: 4
332
363
  summary: Kill Bill Analytics UI mountable engine
333
364
  test_files:
334
- - test/kanaui_test.rb
335
- - test/fixtures/kanaui/dashboards.yml
336
- - test/unit/helpers/kanaui/tests_helper_test.rb
337
365
  - test/test_helper.rb
338
366
  - test/integration/navigation_test.rb
339
- - test/dummy/log/test.log
340
- - test/dummy/public/404.html
341
- - test/dummy/public/422.html
342
- - test/dummy/public/500.html
343
- - test/dummy/public/favicon.ico
344
- - test/dummy/config/secrets.yml
345
- - test/dummy/config/locales/en.yml
346
- - test/dummy/config/environment.rb
367
+ - test/fixtures/kanaui/dashboards.yml
368
+ - test/dummy/script/rails
369
+ - test/dummy/config.ru
370
+ - test/dummy/bin/yarn
371
+ - test/dummy/bin/update
372
+ - test/dummy/bin/rake
373
+ - test/dummy/bin/setup
374
+ - test/dummy/bin/bundle
375
+ - test/dummy/bin/rails
347
376
  - test/dummy/config/routes.rb
348
- - test/dummy/config/environments/test.rb
349
- - test/dummy/config/environments/production.rb
350
- - test/dummy/config/environments/development.rb
351
- - test/dummy/config/initializers/new_framework_defaults_5_1.rb
352
- - test/dummy/config/initializers/inflections.rb
353
- - test/dummy/config/initializers/assets.rb
354
- - test/dummy/config/initializers/backtrace_silencers.rb
355
- - test/dummy/config/initializers/killbill_client.rb
356
- - test/dummy/config/initializers/filter_parameter_logging.rb
377
+ - test/dummy/config/boot.rb
357
378
  - test/dummy/config/initializers/mime_types.rb
358
379
  - test/dummy/config/initializers/application_controller_renderer.rb
359
- - test/dummy/config/initializers/secret_token.rb
360
- - test/dummy/config/initializers/cookies_serializer.rb
380
+ - test/dummy/config/initializers/killbill_client.rb
381
+ - test/dummy/config/initializers/assets.rb
361
382
  - test/dummy/config/initializers/session_store.rb
362
383
  - test/dummy/config/initializers/wrap_parameters.rb
363
- - test/dummy/config/boot.rb
384
+ - test/dummy/config/initializers/secret_token.rb
385
+ - test/dummy/config/initializers/filter_parameter_logging.rb
386
+ - test/dummy/config/initializers/cookies_serializer.rb
387
+ - test/dummy/config/initializers/new_framework_defaults_5_1.rb
388
+ - test/dummy/config/initializers/backtrace_silencers.rb
389
+ - test/dummy/config/initializers/inflections.rb
390
+ - test/dummy/config/locales/en.yml
391
+ - test/dummy/config/secrets.yml
392
+ - test/dummy/config/environment.rb
393
+ - test/dummy/config/environments/production.rb
394
+ - test/dummy/config/environments/development.rb
395
+ - test/dummy/config/environments/test.rb
364
396
  - test/dummy/config/application.rb
365
- - test/dummy/Rakefile
366
- - test/dummy/script/rails
367
397
  - test/dummy/README.rdoc
398
+ - test/dummy/Rakefile
399
+ - test/dummy/public/favicon.ico
400
+ - test/dummy/public/404.html
401
+ - test/dummy/public/422.html
402
+ - test/dummy/public/500.html
368
403
  - test/dummy/app/controllers/application_controller.rb
369
404
  - test/dummy/app/helpers/application_helper.rb
370
- - test/dummy/config.ru
371
- - test/dummy/bin/rake
372
- - test/dummy/bin/bundle
373
- - test/dummy/bin/update
374
- - test/dummy/bin/setup
375
- - test/dummy/bin/yarn
376
- - test/dummy/bin/rails
405
+ - test/dummy/app/assets/config/manifest.js
406
+ - test/kanaui_test.rb
377
407
  - test/functional/kanaui/tests_controller_test.rb
408
+ - test/unit/helpers/kanaui/tests_helper_test.rb
@@ -1,22 +0,0 @@
1
- ----------------------
2
- KanauiTest: test_truth
3
- ----------------------
4
- -----------------------------------------------
5
- NavigationTest: test_can_see_the_dashboard_page
6
- -----------------------------------------------
7
- Started GET "/kanaui" for 127.0.0.1 at 2018-04-12 15:30:51 +0000
8
- Processing by Kanaui::DashboardController#index as HTML
9
- Request method='GET', uri='http://127.0.0.1:8080/plugins/killbill-analytics/reports'
10
- accept='application/json', user-agent='killbill/2.2.2; ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]', accept-encoding='gzip;q=1.0,deflate;q=0.6,identity;q=0.3', x-killbill-apikey='bob', x-killbill-apisecret='lazar', authorization='Basic [FILTERED]'
11
- Completed 500 Internal Server Error in 1ms
12
- -----------------------------------------------
13
- NavigationTest: test_can_see_the_dashboard_page
14
- -----------------------------------------------
15
- Started GET "/kanaui" for 127.0.0.1 at 2018-05-18 09:28:21 +0000
16
- Processing by Kanaui::DashboardController#index as HTML
17
- Request method='GET', uri='http://127.0.0.1:8080/plugins/killbill-analytics/reports'
18
- accept='application/json', user-agent='killbill/2.2.3; ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]', accept-encoding='gzip;q=1.0,deflate;q=0.6,identity;q=0.3', x-killbill-apikey='bob', x-killbill-apisecret='lazar', authorization='Basic [FILTERED]'
19
- Completed 500 Internal Server Error in 1ms
20
- ----------------------
21
- KanauiTest: test_truth
22
- ----------------------