Ability to search a subset of log fields on Logs#search. Fixes #1354

pull/1355/head
Rick Carlino 2019-08-07 08:15:08 -05:00
parent f4b90eaea5
commit 0a6bbb4bfb
3 changed files with 93 additions and 54 deletions

View File

@ -2,21 +2,31 @@ module Api
class LogsController < Api::AbstractController
before_action :trim_logs
SEARCH_FIELDS = {
message: :to_s,
type: :to_s,
verbosity: :to_i,
x: :to_i,
y: :to_i,
z: :to_i,
}
def search
conf = current_device.web_app_config
mt = CeleryScriptSettingsBag::ALLOWED_MESSAGE_TYPES
query = mt
.map { |x| "(type = '#{x}' AND verbosity <= ?)" }
.join(" OR ")
conditions = mt.map { |x| "#{x}_log" }.map{|x| conf.send(x) }
args_ = conditions.unshift(query)
limit = current_device.max_log_count || Device::DEFAULT_MAX_LOGS
conf = current_device.web_app_config
mt = CeleryScriptSettingsBag::ALLOWED_MESSAGE_TYPES
query = mt
.map { |x| "(type = '#{x}' AND verbosity <= ?)" }
.join(" OR ")
conditions = mt.map { |x| "#{x}_log" }.map { |x| conf.send(x) }
args_ = conditions.unshift(query)
limit = current_device.max_log_count || Device::DEFAULT_MAX_LOGS
render json: current_device
.logs
.order(created_at: :desc)
.where(*args_)
.limit(limit)
.logs
.order(created_at: :desc)
.where(*args_)
.limit(limit)
.where(search_params)
end
def create
@ -32,7 +42,7 @@ module Api
render json: current_device.logs.destroy_all && ""
end
private
private
def trim_logs
# WARNING: Calls to `destroy_all` rather than
@ -40,5 +50,15 @@ module Api
# a big table! RC
current_device.excess_logs.delete_all
end
def search_params
SEARCH_FIELDS.reduce({}) do |acc, (k, v)|
search_term = params[k]
if search_term
acc[k] = search_term.send(v)
end
acc
end
end
end
end

View File

@ -20,17 +20,18 @@ describe Api::LogsController do
it "creates one log (legacy format)" do
sign_in user
before_count = Log.count
now = DateTime.now - 37.3.hours
created_at = now.utc.to_i
now = DateTime.now - 37.3.hours
created_at = now.utc.to_i
post :create, body: {
created_at: created_at,
meta: { x: 1,
y: 2,
z: 3,
type: "info" },
channels: ["toast"],
message: "Hello, world!" }.to_json,
params: { format: :json }
created_at: created_at,
meta: { x: 1,
y: 2,
z: 3,
type: "info" },
channels: ["toast"],
message: "Hello, world!",
}.to_json,
params: { format: :json }
expect(response.status).to eq(200)
expect(Log.count).to be > before_count
expect(Log.last.message).to eq("Hello, world!")
@ -42,7 +43,7 @@ describe Api::LogsController do
sign_in user
before_count = Log.count
body = {
channels: [ ],
channels: [],
major_version: 6,
message: "HELLO",
minor_version: 4,
@ -52,12 +53,12 @@ describe Api::LogsController do
y: 0,
z: 0,
}
post :create, body: body.to_json, params: {format: :json}
post :create, body: body.to_json, params: { format: :json }
expect(response.status).to eq(200)
expect(Log.count).to be > before_count
expect(json[:created_at]).to be_kind_of(Integer)
body.keys.map do |key|
actual = json[key]
actual = json[key]
expected = body[key]
expect(actual).to eq(expected)
@ -68,7 +69,7 @@ describe Api::LogsController do
sign_in user
before_count = Log.count
body = { message: "HELLO" }
post :create, body: body.to_json, params: {format: :json}
post :create, body: body.to_json, params: { format: :json }
expect(response.status).to eq(200)
expect(Log.count).to be > before_count
expect(json[:message]).to eq("HELLO")
@ -80,7 +81,7 @@ describe Api::LogsController do
channels: ["toast"],
message: "my password is foo123!" }
sign_in user
post :create, body: stub.to_json, params: {format: :json}
post :create, body: stub.to_json, params: { format: :json }
expect(json[:log]).to include(Logs::Create::BAD_WORDS)
expect(response.status).to eq(422)
expect(Log.count).to eq(0)
@ -91,7 +92,7 @@ describe Api::LogsController do
100.times { Log.create!(device: user.device) }
sign_in user
user.device.update_attributes!(max_log_count: 15)
get :index, params: {format: :json}
get :index, params: { format: :json }
expect(response.status).to eq(200)
expect(json.length).to eq(user.device.max_log_count)
end
@ -107,7 +108,7 @@ describe Api::LogsController do
it "delivers emails for logs marked as `email`" do
log = Log.create!(device: user.device, channels: ["email"])
b4 = Log.where(sent_at: nil).count
b4 = Log.where(sent_at: nil).count
ldm = LogDeliveryMailer.new
allow(ldm).to receive(:mail)
ldm.log_digest(log.device)
@ -118,11 +119,11 @@ describe Api::LogsController do
message = "KABOOOOMM - SYSTEM ERROR!"
sign_in user
empty_mail_bag
body = { meta: { x: 1, y: 2, z: 3, type: "info" },
channels: ["fatal_email"],
message: message }.to_json
body = { meta: { x: 1, y: 2, z: 3, type: "info" },
channels: ["fatal_email"],
message: message }.to_json
run_jobs_now do
post :create, body: body, params: {format: :json}
post :create, body: body, params: { format: :json }
expect(response.status).to eq(200)
expect(last_email).to be
expect(last_email.body.to_s).to include(message)
@ -162,19 +163,19 @@ describe Api::LogsController do
it "filters ALL logs based on log filtering settings in `WebAppConfig` " do
sign_in user
Log.destroy_all
conf = user.device.web_app_config
conf = user.device.web_app_config
EXAMPLES.map do |(verbosity, type)|
FactoryBot.create(:log, device: user.device,
FactoryBot.create(:log, device: user.device,
verbosity: verbosity,
type: type)
type: type)
end
conf.update_attributes(success_log: 3,
busy_log: 3,
warn_log: 3,
error_log: 3,
info_log: 3,
fun_log: 3,
debug_log: 3)
busy_log: 3,
warn_log: 3,
error_log: 3,
info_log: 3,
fun_log: 3,
debug_log: 3)
get :search
expect(response.status).to eq(200)
expect(json.length).to eq(EXAMPLES.length)
@ -183,22 +184,37 @@ describe Api::LogsController do
it "filters NO logs based on log filtering settings in `WebAppConfig` " do
sign_in user
Log.destroy_all
conf = user.device.web_app_config
conf = user.device.web_app_config
EXAMPLES.map do |(verbosity, type)|
FactoryBot.create(:log, device: user.device,
FactoryBot.create(:log, device: user.device,
verbosity: verbosity,
type: type)
type: type)
end
conf.update_attributes(success_log: 0,
busy_log: 0,
warn_log: 0,
error_log: 0,
info_log: 0,
fun_log: 0,
debug_log: 0)
busy_log: 0,
warn_log: 0,
error_log: 0,
info_log: 0,
fun_log: 0,
debug_log: 0)
get :search
expect(response.status).to eq(200)
expect(json.length).to eq(0)
end
it "filters logs based on criteria" do
sign_in user
Log.destroy_all
[-10, 0, 10, 20].map do |x|
FactoryBot.create(:log,
device: user.device,
x: x,
message: "This is #{x}")
end
get :search, params: { x: -10 }
expect(response.status).to eq(200)
expect(json.length).to eq(1)
expect(json.dig(0, :message)).to eq("This is -10")
end
end
end

View File

@ -2,8 +2,11 @@ FactoryBot.define do
factory :log do
device
sequence(:created_at) { |n| n.minutes.ago.utc }
message { Faker::Company.bs }
type { Log::TYPES.sample }
message { Faker::Company.bs }
type { Log::TYPES.sample }
channels { ["toast"] }
x { rand(-1000...1000) }
y { rand(-1000...1000) }
z { rand(-1000...1000) }
end
end