kanaui 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
- ----------------------