Merge branch 'staging' of github.com:FarmBot/Farmbot-Web-App into telemetry3
commit
a501decb1c
4
Gemfile
4
Gemfile
|
@ -1,6 +1,7 @@
|
|||
source "https://rubygems.org"
|
||||
ruby "~> 2.6.5"
|
||||
|
||||
gem "rails"
|
||||
gem "active_model_serializers"
|
||||
gem "bunny"
|
||||
gem "delayed_job_active_record" # TODO: Get off of SQL backed jobs. Use Redis
|
||||
|
@ -16,7 +17,6 @@ gem "rabbitmq_http_api_client"
|
|||
gem "rack-attack"
|
||||
gem "rack-cors"
|
||||
gem "rails_12factor"
|
||||
gem "rails", "5.2.3" # TODO: Upgrade to Rails 6
|
||||
gem "redis", "~> 4.0"
|
||||
gem "request_store"
|
||||
gem "rollbar"
|
||||
|
@ -35,7 +35,7 @@ group :development, :test do
|
|||
gem "hashdiff"
|
||||
gem "pry-rails"
|
||||
gem "pry"
|
||||
gem "rspec-rails"
|
||||
gem "rspec-rails", "4.0.0.beta3"
|
||||
gem "rspec"
|
||||
gem "simplecov"
|
||||
gem "smarf_doc", git: "https://github.com/RickCarlino/smarf_doc.git"
|
||||
|
|
124
Gemfile.lock
124
Gemfile.lock
|
@ -7,56 +7,69 @@ GIT
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (5.2.3)
|
||||
actionpack (= 5.2.3)
|
||||
actioncable (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailer (5.2.3)
|
||||
actionpack (= 5.2.3)
|
||||
actionview (= 5.2.3)
|
||||
activejob (= 5.2.3)
|
||||
actionmailbox (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
activestorage (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
mail (>= 2.7.1)
|
||||
actionmailer (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
actionview (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.2.3)
|
||||
actionview (= 5.2.3)
|
||||
activesupport (= 5.2.3)
|
||||
actionpack (6.0.0)
|
||||
actionview (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
rack (~> 2.0)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (5.2.3)
|
||||
activesupport (= 5.2.3)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actiontext (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
activestorage (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
active_model_serializers (0.10.10)
|
||||
actionpack (>= 4.1, < 6.1)
|
||||
activemodel (>= 4.1, < 6.1)
|
||||
case_transform (>= 0.2)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||
activejob (5.2.3)
|
||||
activesupport (= 5.2.3)
|
||||
activejob (6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (5.2.3)
|
||||
activesupport (= 5.2.3)
|
||||
activerecord (5.2.3)
|
||||
activemodel (= 5.2.3)
|
||||
activesupport (= 5.2.3)
|
||||
arel (>= 9.0)
|
||||
activestorage (5.2.3)
|
||||
actionpack (= 5.2.3)
|
||||
activerecord (= 5.2.3)
|
||||
activemodel (6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
activerecord (6.0.0)
|
||||
activemodel (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
activestorage (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
marcel (~> 0.3.1)
|
||||
activesupport (5.2.3)
|
||||
activesupport (6.0.0)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.1, >= 2.1.8)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
amq-protocol (2.3.0)
|
||||
arel (9.0.0)
|
||||
bcrypt (3.1.13)
|
||||
builder (3.2.3)
|
||||
bunny (2.14.3)
|
||||
|
@ -106,7 +119,7 @@ GEM
|
|||
railties (>= 3.2, < 6.1)
|
||||
globalid (0.4.2)
|
||||
activesupport (>= 4.2.0)
|
||||
google-api-client (0.33.1)
|
||||
google-api-client (0.33.2)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (~> 0.9)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
|
@ -114,9 +127,9 @@ GEM
|
|||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.12)
|
||||
google-cloud-core (1.3.2)
|
||||
google-cloud-core (1.4.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-env (1.2.1)
|
||||
google-cloud-env (1.3.0)
|
||||
faraday (~> 0.11)
|
||||
google-cloud-storage (1.21.1)
|
||||
addressable (~> 2.5)
|
||||
|
@ -183,18 +196,20 @@ GEM
|
|||
rack-cors (1.0.3)
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (5.2.3)
|
||||
actioncable (= 5.2.3)
|
||||
actionmailer (= 5.2.3)
|
||||
actionpack (= 5.2.3)
|
||||
actionview (= 5.2.3)
|
||||
activejob (= 5.2.3)
|
||||
activemodel (= 5.2.3)
|
||||
activerecord (= 5.2.3)
|
||||
activestorage (= 5.2.3)
|
||||
activesupport (= 5.2.3)
|
||||
rails (6.0.0)
|
||||
actioncable (= 6.0.0)
|
||||
actionmailbox (= 6.0.0)
|
||||
actionmailer (= 6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
actiontext (= 6.0.0)
|
||||
actionview (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
activemodel (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
activestorage (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.2.3)
|
||||
railties (= 6.0.0)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
|
@ -206,12 +221,12 @@ GEM
|
|||
rails_stdout_logging
|
||||
rails_serve_static_assets (0.0.5)
|
||||
rails_stdout_logging (0.0.5)
|
||||
railties (5.2.3)
|
||||
actionpack (= 5.2.3)
|
||||
activesupport (= 5.2.3)
|
||||
railties (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.19.0, < 2.0)
|
||||
thor (>= 0.20.3, < 2.0)
|
||||
rake (13.0.0)
|
||||
redis (4.1.3)
|
||||
representable (3.0.4)
|
||||
|
@ -237,14 +252,14 @@ GEM
|
|||
rspec-mocks (3.9.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-rails (3.9.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.9.0)
|
||||
rspec-expectations (~> 3.9.0)
|
||||
rspec-mocks (~> 3.9.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-rails (4.0.0.beta3)
|
||||
actionpack (>= 4.2)
|
||||
activesupport (>= 4.2)
|
||||
railties (>= 4.2)
|
||||
rspec-core (~> 3.8)
|
||||
rspec-expectations (~> 3.8)
|
||||
rspec-mocks (~> 3.8)
|
||||
rspec-support (~> 3.8)
|
||||
rspec-support (3.9.0)
|
||||
scenic (1.5.1)
|
||||
activerecord (>= 4.0.0)
|
||||
|
@ -281,6 +296,7 @@ GEM
|
|||
websocket-driver (0.7.1)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.4)
|
||||
zeitwerk (2.2.0)
|
||||
zero_downtime_migrations (0.0.7)
|
||||
activerecord
|
||||
|
||||
|
@ -311,13 +327,13 @@ DEPENDENCIES
|
|||
rabbitmq_http_api_client
|
||||
rack-attack
|
||||
rack-cors
|
||||
rails (= 5.2.3)
|
||||
rails
|
||||
rails_12factor
|
||||
redis (~> 4.0)
|
||||
request_store
|
||||
rollbar
|
||||
rspec
|
||||
rspec-rails
|
||||
rspec-rails (= 4.0.0.beta3)
|
||||
scenic
|
||||
secure_headers
|
||||
simplecov
|
||||
|
|
|
@ -136,7 +136,7 @@ module Api
|
|||
strategy = Auth::DetermineAuthStrategy.run!(context)
|
||||
case strategy
|
||||
when :jwt
|
||||
sign_in(Auth::FromJWT.run!(context).require_consent!)
|
||||
sign_in(Auth::FromJwt.run!(context).require_consent!)
|
||||
when :already_connected
|
||||
# Probably provided a cookie.
|
||||
# 9 times out of 10, it's a unit test.
|
||||
|
|
|
@ -44,7 +44,7 @@ module Api
|
|||
end
|
||||
|
||||
def update_fields
|
||||
user.update_attributes!(confirmed_at: Time.now)
|
||||
user.update!(confirmed_at: Time.now)
|
||||
end
|
||||
|
||||
def seed_user
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require_relative "../../lib/hstore_filter"
|
||||
# require_relative "../../lib/mutations/hstore_filter"
|
||||
|
||||
module Api
|
||||
class PointsController < Api::AbstractController
|
||||
|
|
|
@ -273,7 +273,7 @@ module Api
|
|||
end
|
||||
|
||||
def current_device
|
||||
@current_device ||= Auth::FromJWT.run!(jwt: password_param).device
|
||||
@current_device ||= Auth::FromJwt.run!(jwt: password_param).device
|
||||
rescue Mutations::ValidationException => e
|
||||
raise JWT::VerificationError, "RMQ Provided bad token"
|
||||
end
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
# * You need to create "traces" of where you are in a sequence (using numbers)
|
||||
# MORE INFO: https://github.com/FarmBot-Labs/Celery-Slicer
|
||||
module CeleryScript
|
||||
# Supporting class for CSHeap (below this class)
|
||||
# PROBLEM: CSHeap uses numbers to address sibling/parent nodes.
|
||||
# Supporting class for CsHeap (below this class)
|
||||
# PROBLEM: CsHeap uses numbers to address sibling/parent nodes.
|
||||
# PROBLEM: Numbers are very easy to mix up. Is it an array index? A SQL
|
||||
# primary key? A primitive value? It's not always easy to say.
|
||||
# SOLUTION: Create a `HeapAddress` value type to remove ambiguity.
|
||||
|
@ -60,21 +60,22 @@ module CeleryScript
|
|||
end
|
||||
end
|
||||
|
||||
class CSHeap
|
||||
class BadAddress < Exception; end;
|
||||
class CsHeap
|
||||
class BadAddress < Exception; end
|
||||
|
||||
BAD_ADDR = "Bad node address: "
|
||||
# Nodes that point to other nodes rather than primitive data types (eg:
|
||||
# `locals` and friends) will be prepended with a LINK.
|
||||
LINK = "__"
|
||||
LINK = "__"
|
||||
# Points to the originator (parent) of an `arg` or `body` node.
|
||||
PARENT = (LINK + "parent").to_sym
|
||||
PARENT = (LINK + "parent").to_sym
|
||||
# Points to the first element in the `body``
|
||||
BODY = (LINK + "body").to_sym
|
||||
BODY = (LINK + "body").to_sym
|
||||
# Points to the next node in the body chain. Pointing to NOTHING indicates
|
||||
# the end of the body linked list.
|
||||
NEXT = (LINK + "next").to_sym
|
||||
NEXT = (LINK + "next").to_sym
|
||||
# Unique key name. See `celery_script_settings_bag.rb`
|
||||
KIND = :__KIND__
|
||||
KIND = :__KIND__
|
||||
COMMENT = :__COMMENT__
|
||||
|
||||
# Keys that primary nodes must have
|
||||
|
@ -82,17 +83,16 @@ module CeleryScript
|
|||
|
||||
# Index 0 of the heap represents a null pointer of sorts.
|
||||
# If a field points to this address, it is considered empty.
|
||||
NULL = HeapAddress[0]
|
||||
NULL = HeapAddress[0]
|
||||
|
||||
# What you will find at index 0 of the heap:
|
||||
NOTHING = {
|
||||
KIND => "nothing",
|
||||
KIND => "nothing",
|
||||
PARENT => NULL,
|
||||
BODY => NULL,
|
||||
NEXT => NULL
|
||||
BODY => NULL,
|
||||
NEXT => NULL,
|
||||
}
|
||||
|
||||
|
||||
# A dictionary of nodes in the CeleryScript tree, as stored in the heap.
|
||||
# Nodes will have:
|
||||
# * A `KIND` field - What kind of node is it?
|
||||
|
@ -113,7 +113,7 @@ module CeleryScript
|
|||
|
||||
# Set "here" to "null". Prepopulates "here" with an empty entry.
|
||||
def initialize
|
||||
@here = NULL
|
||||
@here = NULL
|
||||
@entries = { @here => NOTHING }
|
||||
end
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
require_relative "./csheap"
|
||||
require_relative "./cs_heap"
|
||||
|
||||
# Service object that:
|
||||
# 1. Pulls out all PrimaryNodes and EdgeNodes for a sequence node (AST Flat IR form)
|
||||
|
@ -8,7 +8,7 @@ require_relative "./csheap"
|
|||
# DEFAULT.
|
||||
module CeleryScript
|
||||
class FetchCelery < Mutations::Command
|
||||
private # = = = = = = =
|
||||
private # = = = = = = =
|
||||
# This class is too CPU intensive to make multiple SQL requests.
|
||||
# To speed up querying, we create an in-memory index for frequently
|
||||
# looked up attributes such as :id, :kind, :parent_id, :primary_node_id
|
||||
|
@ -60,7 +60,7 @@ module CeleryScript
|
|||
# that node's children (or an empty array, since body is always optional).
|
||||
def get_body_elements(origin)
|
||||
next_node = find_by_id_in_memory(origin.body_id)
|
||||
results = []
|
||||
results = []
|
||||
until next_node.kind == "nothing"
|
||||
results.push(next_node)
|
||||
next_node = find_by_id_in_memory(next_node[:next_id])
|
||||
|
@ -71,7 +71,7 @@ module CeleryScript
|
|||
# Top level function call for converting a single EdgeNode into a JSON
|
||||
# document. Returns Ruby hash that conforms to CeleryScript semantics.
|
||||
def recurse_into_node(node)
|
||||
out = { kind: node.kind, args: recurse_into_args(node) }
|
||||
out = { kind: node.kind, args: recurse_into_args(node) }
|
||||
body = get_body_elements(node)
|
||||
if body.empty?
|
||||
# Legacy sequences *must* have body on sequence. Others are fine.
|
||||
|
@ -87,16 +87,17 @@ module CeleryScript
|
|||
# Eg: color, id, etc.
|
||||
def misc_fields
|
||||
return {
|
||||
id: sequence.id,
|
||||
created_at: sequence.created_at,
|
||||
updated_at: sequence.updated_at,
|
||||
args: Sequence::DEFAULT_ARGS,
|
||||
color: sequence.color,
|
||||
name: sequence.name
|
||||
}
|
||||
id: sequence.id,
|
||||
created_at: sequence.created_at,
|
||||
updated_at: sequence.updated_at,
|
||||
args: Sequence::DEFAULT_ARGS,
|
||||
color: sequence.color,
|
||||
name: sequence.name,
|
||||
}
|
||||
end
|
||||
|
||||
public # = = = = = = =
|
||||
public # = = = = = = =
|
||||
|
||||
NO_SEQUENCE = "You must have a root node `sequence` at a minimum."
|
||||
|
||||
required do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require_relative "./csheap"
|
||||
require_relative "./cs_heap"
|
||||
|
||||
# ABOUT THIS CLASS:
|
||||
# CSHeap creates an in memory representation of a Flat IR tree using array
|
||||
# CsHeap creates an in memory representation of a Flat IR tree using array
|
||||
# indexes (HeapAddress instances, really). This class takes a flat IR tree
|
||||
# from memory and converts `HeapAddress`es to SQL primary/foreign keys.
|
||||
module CeleryScript
|
||||
|
@ -10,14 +10,14 @@ module CeleryScript
|
|||
# The following constants are abbreviations of the full name, since the
|
||||
# full name is quite long and they are referenced frequently in the code.
|
||||
# Just remember that "B" is "BODY", "K" is "KIND", etc...
|
||||
B = CeleryScript::CSHeap::BODY
|
||||
C = CeleryScript::CSHeap::COMMENT
|
||||
K = CeleryScript::CSHeap::KIND
|
||||
L = CeleryScript::CSHeap::LINK
|
||||
N = CeleryScript::CSHeap::NEXT
|
||||
P = CeleryScript::CSHeap::PARENT
|
||||
NULL = CeleryScript::CSHeap::NULL
|
||||
I = :instance
|
||||
B = CeleryScript::CsHeap::BODY
|
||||
C = CeleryScript::CsHeap::COMMENT
|
||||
K = CeleryScript::CsHeap::KIND
|
||||
L = CeleryScript::CsHeap::LINK
|
||||
N = CeleryScript::CsHeap::NEXT
|
||||
P = CeleryScript::CsHeap::PARENT
|
||||
NULL = CeleryScript::CsHeap::NULL
|
||||
I = :instance
|
||||
|
||||
required do
|
||||
model :sequence, class: Sequence
|
||||
|
@ -28,7 +28,7 @@ module CeleryScript
|
|||
def validate
|
||||
# IF YOU REMOVE THIS BAD STUFF WILL HAPPEN:
|
||||
# version is never user definable!
|
||||
sequence_hash[:args] = \
|
||||
sequence_hash[:args] =
|
||||
Sequence::DEFAULT_ARGS.merge(sequence_hash[:args] || {})
|
||||
# See comment above ^ TODO: Investigate removal now that EdgeNodes exist.
|
||||
end
|
||||
|
@ -37,67 +37,67 @@ module CeleryScript
|
|||
Sequence.transaction do
|
||||
flat_ir
|
||||
.each do |node|
|
||||
# Step 1- instantiate records.
|
||||
node[I] = PrimaryNode.create!(kind: node[K],
|
||||
sequence: sequence,
|
||||
comment: node[C] || nil)
|
||||
end
|
||||
# Step 1- instantiate records.
|
||||
node[I] = PrimaryNode.create!(kind: node[K],
|
||||
sequence: sequence,
|
||||
comment: node[C] || nil)
|
||||
end
|
||||
.each_with_index do |node, index|
|
||||
# Step 2- Assign SQL ids (not to be confused with array index IDs or
|
||||
# instances of HeapAddress), also sets parent_arg_name
|
||||
model = node[I]
|
||||
model.parent_arg_name = parent_arg_name_for(node, index)
|
||||
model.body_id = fetch_sql_id_for(B, node)
|
||||
model.parent_id = fetch_sql_id_for(P, node)
|
||||
model.next_id = fetch_sql_id_for(N, node)
|
||||
node
|
||||
end
|
||||
# Step 2- Assign SQL ids (not to be confused with array index IDs or
|
||||
# instances of HeapAddress), also sets parent_arg_name
|
||||
model = node[I]
|
||||
model.parent_arg_name = parent_arg_name_for(node, index)
|
||||
model.body_id = fetch_sql_id_for(B, node)
|
||||
model.parent_id = fetch_sql_id_for(P, node)
|
||||
model.next_id = fetch_sql_id_for(N, node)
|
||||
node
|
||||
end
|
||||
.map do |node|
|
||||
# Step 3- Set edge nodes
|
||||
pairs = node
|
||||
.to_a
|
||||
.select do |x|
|
||||
key = x.first.to_s
|
||||
(x.first != I) && !key.starts_with?(L)
|
||||
end
|
||||
.map do |(key, value)|
|
||||
EdgeNode.create!(kind: key,
|
||||
value: value,
|
||||
sequence_id: sequence.id,
|
||||
primary_node_id: node[:instance].id)
|
||||
end
|
||||
node[:instance]
|
||||
# Step 3- Set edge nodes
|
||||
pairs = node
|
||||
.to_a
|
||||
.select do |x|
|
||||
key = x.first.to_s
|
||||
(x.first != I) && !key.starts_with?(L)
|
||||
end
|
||||
.tap { |x| sequence.update_attributes(migrated_nodes: true) unless sequence.migrated_nodes }
|
||||
.map do |(key, value)|
|
||||
EdgeNode.create!(kind: key,
|
||||
value: value,
|
||||
sequence_id: sequence.id,
|
||||
primary_node_id: node[:instance].id)
|
||||
end
|
||||
node[:instance]
|
||||
end
|
||||
.tap { |x| sequence.update(migrated_nodes: true) unless sequence.migrated_nodes }
|
||||
.map { |x|
|
||||
x.save! if x.changed?
|
||||
x
|
||||
}
|
||||
x.save! if x.changed?
|
||||
x
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
# Index every primary node in memory by its `HeapAddress`.
|
||||
# We need this info in order to fill out the `parent_arg_name` of a node.
|
||||
def every_primary_link
|
||||
@every_primary_link ||= flat_ir
|
||||
.map do |x|
|
||||
x
|
||||
.except(B,C,I,K,L,N,P)
|
||||
.invert
|
||||
.to_a
|
||||
.select{|(k,v)| k.is_a?(HeapAddress)}
|
||||
end
|
||||
x
|
||||
.except(B, C, I, K, L, N, P)
|
||||
.invert
|
||||
.to_a
|
||||
.select { |(k, v)| k.is_a?(HeapAddress) }
|
||||
end
|
||||
.map(&:to_h)
|
||||
.reduce({}, :merge)
|
||||
end
|
||||
|
||||
def parent_arg_name_for(node, index)
|
||||
resides_in_args = (node[N] == NULL) && (node[P] != NULL)
|
||||
link_symbol = every_primary_link[HeapAddress[index]]
|
||||
resides_in_args = (node[N] == NULL) && (node[P] != NULL)
|
||||
link_symbol = every_primary_link[HeapAddress[index]]
|
||||
needs_p_arg_name = (resides_in_args && link_symbol)
|
||||
parent_arg_name = (needs_p_arg_name ? link_symbol.to_s.gsub(L, "") : nil)
|
||||
parent_arg_name = (needs_p_arg_name ? link_symbol.to_s.gsub(L, "") : nil)
|
||||
return parent_arg_name
|
||||
end
|
||||
|
||||
|
@ -107,7 +107,7 @@ private
|
|||
end
|
||||
|
||||
def sequence_hash
|
||||
@sequence_hash ||= \
|
||||
@sequence_hash ||=
|
||||
HashWithIndifferentAccess.new(kind: "sequence", args: args, body: body)
|
||||
end
|
||||
|
||||
|
|
|
@ -2,18 +2,18 @@ module CeleryScript
|
|||
# THIS IS A MORE MINIMAL VERSION OF CeleryScript::TreeClimber.
|
||||
# It is a NON-VALIDATING tree climber.
|
||||
# Don't use this on unverified data structures.
|
||||
class JSONClimber
|
||||
class JsonClimber
|
||||
HASH_ONLY = "Expected a Hash."
|
||||
NOT_NODE = "Expected hash with at least a `kind` and `args` prop."
|
||||
NOT_NODE = "Expected hash with at least a `kind` and `args` prop."
|
||||
|
||||
def self.climb(thing, &callable)
|
||||
raise HASH_ONLY unless thing.is_a?(Hash)
|
||||
raise NOT_NODE unless is_node?(thing)
|
||||
raise NOT_NODE unless is_node?(thing)
|
||||
go(thing, callable)
|
||||
thing
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def self.is_node?(maybe)
|
||||
maybe.is_a?(Hash) &&
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require_relative "./csheap.rb"
|
||||
require_relative "./cs_heap.rb"
|
||||
# ORIGINAL IMPLEMENTATION HERE: https://github.com/FarmBot-Labs/Celery-Slicer
|
||||
# Take a nested ("canonical") representation of a CeleryScript sequence and
|
||||
# transforms it to a flat/homogenous intermediate representation which is better
|
||||
|
@ -11,12 +11,12 @@ module CeleryScript
|
|||
raise "Not a hash" unless node.is_a?(Hash)
|
||||
@nesting_level = 0
|
||||
@root_node = node
|
||||
heap = CSHeap.new()
|
||||
allocate(heap, node, CSHeap::NULL)
|
||||
heap = CsHeap.new()
|
||||
allocate(heap, node, CsHeap::NULL)
|
||||
@heap_values = heap.values
|
||||
@heap_values.map do |x|
|
||||
x[CSHeap::BODY] ||= CSHeap::NULL
|
||||
x[CSHeap::NEXT] ||= CSHeap::NULL
|
||||
x[CsHeap::BODY] ||= CsHeap::NULL
|
||||
x[CsHeap::NEXT] ||= CsHeap::NULL
|
||||
end
|
||||
heap.dump()
|
||||
end
|
||||
|
@ -31,8 +31,8 @@ module CeleryScript
|
|||
|
||||
def allocate(h, s, parentAddr)
|
||||
addr = h.allot(s[:kind])
|
||||
h.put(addr, CSHeap::PARENT, parentAddr)
|
||||
h.put(addr, CSHeap::COMMENT, s[:comment]) if s[:comment]
|
||||
h.put(addr, CsHeap::PARENT, parentAddr)
|
||||
h.put(addr, CsHeap::COMMENT, s[:comment]) if s[:comment]
|
||||
iterate_over_body(h, s, addr)
|
||||
iterate_over_args(h, s, addr)
|
||||
addr
|
||||
|
@ -44,7 +44,7 @@ module CeleryScript
|
|||
.map do |key|
|
||||
v = s[:args][key]
|
||||
if (is_celery_script(v))
|
||||
k = CSHeap::LINK + key.to_s
|
||||
k = CsHeap::LINK + key.to_s
|
||||
h.put(parentAddr, k, allocate(h, v, parentAddr))
|
||||
else
|
||||
h.put(parentAddr, key, v)
|
||||
|
@ -64,12 +64,12 @@ module CeleryScript
|
|||
is_head = index == 0
|
||||
# BE CAREFUL EDITING THIS LINE, YOU MIGHT BREAK `BODY` NODES:
|
||||
heap # See note above!
|
||||
.put(previous_address, CSHeap::BODY, previous_address + 1) if is_head
|
||||
.put(previous_address, CsHeap::BODY, previous_address + 1) if is_head
|
||||
|
||||
my_heap_address = allocate(heap, canonical_list[index], previous_address)
|
||||
|
||||
prev_next_key = is_head ? CSHeap::NULL : my_heap_address
|
||||
heap.put(previous_address, CSHeap::NEXT, prev_next_key)
|
||||
prev_next_key = is_head ? CsHeap::NULL : my_heap_address
|
||||
heap.put(previous_address, CsHeap::NEXT, prev_next_key)
|
||||
|
||||
recurse_into_body(heap, canonical_list, my_heap_address, index + 1)
|
||||
end
|
||||
|
|
|
@ -24,7 +24,10 @@ class LogService < AbstractServiceRunner
|
|||
end
|
||||
|
||||
def maybe_deliver(data)
|
||||
return unless data.valid?
|
||||
|
||||
violation = THROTTLE_POLICY.is_throttled(data.device_id)
|
||||
|
||||
if violation
|
||||
return warn_user(data, violation)
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
after_save :maybe_broadcast, on: [:create, :update]
|
||||
after_create :maybe_broadcast
|
||||
after_update :maybe_broadcast
|
||||
after_destroy :maybe_broadcast
|
||||
|
||||
class << self
|
||||
|
@ -37,7 +38,7 @@ class ApplicationRecord < ActiveRecord::Base
|
|||
def self.auto_sync_debounce
|
||||
@auto_sync_paused = true
|
||||
result = yield
|
||||
result.update_attributes!(updated_at: Time.now)
|
||||
result.update!(updated_at: Time.now)
|
||||
@auto_sync_paused = false
|
||||
result.broadcast!
|
||||
result
|
||||
|
@ -94,7 +95,7 @@ class ApplicationRecord < ActiveRecord::Base
|
|||
|
||||
def manually_sync!
|
||||
device && (device.auto_sync_transaction do
|
||||
update_attributes!(updated_at: Time.now)
|
||||
update!(updated_at: Time.now)
|
||||
end)
|
||||
self
|
||||
end
|
||||
|
|
|
@ -118,8 +118,8 @@ class Device < ApplicationRecord
|
|||
end_t = violation.ends_at
|
||||
# Some log validation errors will result in until_time being `nil`.
|
||||
if (throttled_until.nil? || end_t > throttled_until)
|
||||
reload.update_attributes!(throttled_until: end_t,
|
||||
throttled_at: Time.now)
|
||||
reload.update!(throttled_until: end_t,
|
||||
throttled_at: Time.now)
|
||||
refresh_cache
|
||||
cooldown = end_t.in_time_zone(self.timezone || "UTC").strftime("%I:%M%p")
|
||||
info = [violation.explanation, cooldown]
|
||||
|
@ -131,7 +131,7 @@ class Device < ApplicationRecord
|
|||
if throttled_until.present?
|
||||
old_time = throttled_until
|
||||
reload # <= WHY!?! TODO: Find out why it crashes without this.
|
||||
.update_attributes!(throttled_until: nil, throttled_at: nil)
|
||||
.update!(throttled_until: nil, throttled_at: nil)
|
||||
refresh_cache
|
||||
cooldown_notice(THROTTLE_OFF, old_time, "info")
|
||||
end
|
||||
|
@ -203,7 +203,7 @@ class Device < ApplicationRecord
|
|||
|
||||
last_sent_at = device.mqtt_rate_limit_email_sent_at || 4.years.ago
|
||||
if last_sent_at < 1.day.ago
|
||||
device.update_attributes!(mqtt_rate_limit_email_sent_at: Time.now)
|
||||
device.update!(mqtt_rate_limit_email_sent_at: Time.now)
|
||||
device.tell(TOO_MANY_CONNECTIONS, ["fatal_email"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,7 +40,7 @@ class FarmwareInstallation < ApplicationRecord
|
|||
known_error = KNOWN_PROBLEMS[error.class]
|
||||
description = \
|
||||
known_error || (OTHER_PROBLEM % error.class)
|
||||
update_attributes!(package_error: description,
|
||||
update!(package_error: description,
|
||||
package: nil)
|
||||
unless known_error.present?
|
||||
raise error
|
||||
|
@ -54,7 +54,7 @@ class FarmwareInstallation < ApplicationRecord
|
|||
string = string_io.read(MAX_JSON_SIZE)
|
||||
json = JSON.parse(string)
|
||||
pkg_name = json.fetch("package")
|
||||
update_attributes!(package: pkg_name, package_error: nil)
|
||||
update!(package: pkg_name, package_error: nil)
|
||||
rescue => error
|
||||
maybe_recover_from_fetch_error(error)
|
||||
end
|
||||
|
|
|
@ -3,7 +3,8 @@ class FbosConfig < ApplicationRecord
|
|||
class MissingSerial < StandardError; end
|
||||
|
||||
belongs_to :device
|
||||
after_save :maybe_sync_nerves, on: [:create, :update]
|
||||
after_create :maybe_sync_nerves
|
||||
after_update :maybe_sync_nerves
|
||||
|
||||
FIRMWARE_HARDWARE = [
|
||||
NOT_SET = nil,
|
||||
|
|
|
@ -28,7 +28,7 @@ class GlobalConfig < ApplicationRecord
|
|||
# Remove it if the demo tour does not require it.
|
||||
"MQTT_WS" => SessionToken::MQTT_WS,
|
||||
}.map do |(key, value)|
|
||||
self.find_or_create_by(key: key).update_attributes(key: key, value: value)
|
||||
self.find_or_create_by(key: key).update(key: key, value: value)
|
||||
end
|
||||
|
||||
# Memoized version of every GlobalConfig, with key/values layed out in a hash.
|
||||
|
|
|
@ -40,16 +40,9 @@ class Image < ApplicationRecord
|
|||
# Worst case scenario for 1280x1280 BMP.
|
||||
GCS_BUCKET_NAME = ENV["GCS_BUCKET"]
|
||||
|
||||
# ========= DEPRECATED PAPERCLIP STUFF =========
|
||||
# has_attached_file :attachment, CONFIG
|
||||
# validates_attachment_content_type :attachment,
|
||||
# content_type: CONTENT_TYPES
|
||||
# ========= /DEPRECATED PAPERCLIP STUFF ========
|
||||
has_one_attached :attachment
|
||||
|
||||
def set_attachment_by_url(url)
|
||||
# File
|
||||
# URI::HTTPS
|
||||
attachment.attach(io: open(url), filename: "image_#{self.id}")
|
||||
self.attachment_processed_at = Time.now
|
||||
self
|
||||
|
|
|
@ -11,7 +11,9 @@ class ToolSlot < Point
|
|||
MIN_PULLOUT = PULLOUT_DIRECTIONS.min
|
||||
PULLOUT_ERR = "must be a value between #{MIN_PULLOUT} and #{MAX_PULLOUT}. "\
|
||||
"%{value} is not valid."
|
||||
IN_USE = "already in use by another tool slot"
|
||||
IN_USE = "already in use by another tool slot. "\
|
||||
"Please un-assign the tool from its current slot"\
|
||||
" before reassigning."
|
||||
|
||||
belongs_to :tool
|
||||
validates_uniqueness_of :tool,
|
||||
|
|
|
@ -26,7 +26,7 @@ module Auth
|
|||
end
|
||||
|
||||
def execute
|
||||
@user.update_attributes(agreed_to_terms_at: Time.now) if agree_to_terms
|
||||
@user.update(agreed_to_terms_at: Time.now) if agree_to_terms
|
||||
SessionToken.as_json(@user, aud, fbos_version)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module Auth
|
||||
# The API supports a number of authentication strategies (Cookies, Bot token,
|
||||
# JWT). This service helps determine which auth strategy to use.
|
||||
class FromJWT < Mutations::Command
|
||||
class FromJwt < Mutations::Command
|
||||
required { string :jwt }
|
||||
|
||||
def execute
|
||||
|
|
|
@ -5,7 +5,7 @@ module Configs
|
|||
GOOD = 5556
|
||||
|
||||
required do
|
||||
duck :target, methods: [:update_attributes!]
|
||||
duck :target, methods: [:update!]
|
||||
duck :update_attrs, methods: [:deep_symbolize_keys]
|
||||
end
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ module DeviceCerts
|
|||
SendNervesHubInfoJob.perform_later(device_id: device.id,
|
||||
serial_number: serial_number,
|
||||
tags: tags)
|
||||
return device.update_attributes!(serial_number: serial_number) && device
|
||||
return device.update!(serial_number: serial_number) && device
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ module Devices
|
|||
# when we were using MongoDB. This can be
|
||||
# safely removed now. - RC 11-APR-19
|
||||
old_device = user.device
|
||||
user.update_attributes!(device_id: device.id) # Detach from old one.
|
||||
user.update!(device_id: device.id) # Detach from old one.
|
||||
# Remove userless devices.
|
||||
old_device.destroy! if old_device && device.users.count < 1
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ module Devices
|
|||
|
||||
def execute
|
||||
ActiveRecord::Base.transaction do
|
||||
user.update_attributes!(device: Devices::Create.run!(user: user))
|
||||
user.update!(device: Devices::Create.run!(user: user))
|
||||
device.destroy! if device.reload.users.count < 1
|
||||
end
|
||||
true
|
||||
|
|
|
@ -20,7 +20,7 @@ module Devices
|
|||
|
||||
def run_it
|
||||
ActiveRecord::Base.transaction do
|
||||
device.update_attributes!(name: "FarmBot")
|
||||
device.update!(name: "FarmBot")
|
||||
Device::SINGULAR_RESOURCES.keys.map do |resource|
|
||||
device.send(resource).destroy!
|
||||
end
|
||||
|
|
|
@ -2,14 +2,14 @@ module Devices
|
|||
module Seeders
|
||||
class AbstractExpress < AbstractGenesis
|
||||
def settings_device_name
|
||||
device.update_attributes!(name: "FarmBot Express")
|
||||
device.update!(name: "FarmBot Express")
|
||||
end
|
||||
|
||||
def sensors_soil_sensor; end
|
||||
def sensors_tool_verification; end
|
||||
|
||||
def settings_enable_encoders
|
||||
device.firmware_config.update_attributes!(encoder_enabled_x: 0,
|
||||
device.firmware_config.update!(encoder_enabled_x: 0,
|
||||
encoder_enabled_y: 0,
|
||||
encoder_enabled_z: 0)
|
||||
end
|
||||
|
@ -17,7 +17,7 @@ module Devices
|
|||
def settings_firmware
|
||||
device
|
||||
.fbos_config
|
||||
.update_attributes!(firmware_hardware: FbosConfig::EXPRESS_K10)
|
||||
.update!(firmware_hardware: FbosConfig::EXPRESS_K10)
|
||||
end
|
||||
|
||||
def tool_slots_slot_1
|
||||
|
@ -91,11 +91,11 @@ module Devices
|
|||
def sequences_unmount_tool; end
|
||||
|
||||
def settings_default_map_size_y
|
||||
device.web_app_config.update_attributes!(map_size_y: 1_200)
|
||||
device.web_app_config.update!(map_size_y: 1_200)
|
||||
end
|
||||
|
||||
def settings_hide_sensors
|
||||
device.web_app_config.update_attributes!(hide_sensors: true)
|
||||
device.web_app_config.update!(hide_sensors: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -18,11 +18,11 @@ module Devices
|
|||
end
|
||||
|
||||
def settings_device_name
|
||||
device.update_attributes!(name: "FarmBot Genesis")
|
||||
device.update!(name: "FarmBot Genesis")
|
||||
end
|
||||
|
||||
def settings_enable_encoders
|
||||
device.firmware_config.update_attributes!(encoder_enabled_x: 1,
|
||||
device.firmware_config.update!(encoder_enabled_x: 1,
|
||||
encoder_enabled_y: 1,
|
||||
encoder_enabled_z: 1)
|
||||
end
|
||||
|
@ -146,15 +146,15 @@ module Devices
|
|||
def settings_firmware
|
||||
device
|
||||
.fbos_config
|
||||
.update_attributes!(firmware_hardware: FbosConfig::FARMDUINO)
|
||||
.update!(firmware_hardware: FbosConfig::FARMDUINO)
|
||||
end
|
||||
|
||||
def settings_default_map_size_x
|
||||
device.web_app_config.update_attributes!(map_size_x: 2_900)
|
||||
device.web_app_config.update!(map_size_x: 2_900)
|
||||
end
|
||||
|
||||
def settings_default_map_size_y
|
||||
device.web_app_config.update_attributes!(map_size_y: 1_400)
|
||||
device.web_app_config.update!(map_size_y: 1_400)
|
||||
end
|
||||
|
||||
def pin_bindings_button_1
|
||||
|
|
|
@ -72,7 +72,7 @@ module Devices
|
|||
end
|
||||
|
||||
def settings_hide_sensors
|
||||
device.web_app_config.update_attributes!(hide_sensors: false)
|
||||
device.web_app_config.update!(hide_sensors: false)
|
||||
end
|
||||
|
||||
def plants
|
||||
|
|
|
@ -55,10 +55,10 @@ module Devices
|
|||
.map { |p| p.merge(device: device) }
|
||||
.map { |p| Alerts::Create.run!(p) }
|
||||
device
|
||||
.update_attributes!(fbos_version: READ_COMMENT_ABOVE)
|
||||
.update!(fbos_version: READ_COMMENT_ABOVE)
|
||||
device
|
||||
.web_app_config
|
||||
.update_attributes!(discard_unsaved: true)
|
||||
.update!(discard_unsaved: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,15 +2,15 @@ module Devices
|
|||
module Seeders
|
||||
class ExpressXlOneZero < AbstractExpress
|
||||
def settings_device_name
|
||||
device.update_attributes!(name: "FarmBot Express XL")
|
||||
device.update!(name: "FarmBot Express XL")
|
||||
end
|
||||
|
||||
def settings_default_map_size_x
|
||||
device.web_app_config.update_attributes!(map_size_x: 6_000)
|
||||
device.web_app_config.update!(map_size_x: 6_000)
|
||||
end
|
||||
|
||||
def settings_default_map_size_y
|
||||
device.web_app_config.update_attributes!(map_size_y: 2_400)
|
||||
device.web_app_config.update!(map_size_y: 2_400)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ module Devices
|
|||
def settings_firmware
|
||||
device
|
||||
.fbos_config
|
||||
.update_attributes!(firmware_hardware: FbosConfig::FARMDUINO_K14)
|
||||
.update!(firmware_hardware: FbosConfig::FARMDUINO_K14)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ module Devices
|
|||
def settings_firmware
|
||||
device
|
||||
.fbos_config
|
||||
.update_attributes!(firmware_hardware: FbosConfig::ARDUINO)
|
||||
.update!(firmware_hardware: FbosConfig::ARDUINO)
|
||||
end
|
||||
|
||||
def peripherals_lighting; end
|
||||
|
|
|
@ -4,19 +4,19 @@ module Devices
|
|||
def settings_firmware
|
||||
device
|
||||
.fbos_config
|
||||
.update_attributes!(firmware_hardware: FbosConfig::FARMDUINO_K14)
|
||||
.update!(firmware_hardware: FbosConfig::FARMDUINO_K14)
|
||||
end
|
||||
|
||||
def settings_device_name
|
||||
device.update_attributes!(name: "FarmBot Genesis XL")
|
||||
device.update!(name: "FarmBot Genesis XL")
|
||||
end
|
||||
|
||||
def settings_default_map_size_x
|
||||
device.web_app_config.update_attributes!(map_size_x: 5_900)
|
||||
device.web_app_config.update!(map_size_x: 5_900)
|
||||
end
|
||||
|
||||
def settings_default_map_size_y
|
||||
device.web_app_config.update_attributes!(map_size_y: 2_900)
|
||||
device.web_app_config.update!(map_size_y: 2_900)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ module Devices
|
|||
class Sync < Mutations::Command
|
||||
SEL = "SELECT id, updated_at FROM"
|
||||
WHERE = "WHERE device_id = "
|
||||
FORMAT = "%Y-%m-%d %H:%M:%S.%5N"
|
||||
|
||||
def self.basic_query(plural_resource, where = WHERE)
|
||||
[SEL, plural_resource, where].join(" ")
|
||||
|
|
|
@ -21,7 +21,7 @@ module Devices
|
|||
|
||||
def execute
|
||||
p = inputs.except(:device).merge(mounted_tool_data)
|
||||
device.update_attributes!(p)
|
||||
device.update!(p)
|
||||
device
|
||||
end
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ module FarmEvents
|
|||
FarmEvents => ->() { farm_event },
|
||||
Regimens => ->() { regimen },
|
||||
}
|
||||
options.fetch(self.class.parent).call()
|
||||
options.fetch(self.class.module_parent).call()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,7 +33,7 @@ module FarmEvents
|
|||
FarmEvent.auto_sync_debounce do
|
||||
FarmEvent.transaction do
|
||||
handle_body_field
|
||||
farm_event.update_attributes!(p)
|
||||
farm_event.update!(p)
|
||||
farm_event
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module FarmwareEnvs
|
|||
end
|
||||
|
||||
def execute
|
||||
farmware_env.update_attributes!(inputs.except(:farmware_env)) && farmware_env
|
||||
farmware_env.update!(inputs.except(:farmware_env)) && farmware_env
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ module PasswordResets
|
|||
end
|
||||
|
||||
def execute
|
||||
user.update_attributes!(password: password,
|
||||
user.update!(password: password,
|
||||
password_confirmation: password_confirmation)
|
||||
Auth::CreateToken.run!(email: user.email,
|
||||
password: password,
|
||||
|
|
|
@ -11,7 +11,7 @@ module Peripherals
|
|||
end
|
||||
|
||||
def execute
|
||||
peripheral.update_attributes!(inputs.except(:peripheral, :device))
|
||||
peripheral.update!(inputs.except(:peripheral, :device))
|
||||
peripheral
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ module PinBindings
|
|||
|
||||
def execute
|
||||
x = inputs.except(:pin_binding, :device)
|
||||
pin_binding.update_attributes!(x) && pin_binding
|
||||
pin_binding.update!(x) && pin_binding
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ module PlantTemplates
|
|||
end
|
||||
|
||||
def execute
|
||||
plant_template.update_attributes!(update_params)
|
||||
plant_template.update!(update_params)
|
||||
plant_template
|
||||
end
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ module PointGroups
|
|||
PointGroup.transaction do
|
||||
PointGroupItem.transaction do
|
||||
maybe_reconcile_points
|
||||
point_group.update_attributes!(update_attributes)
|
||||
point_group.update!(update_attributes)
|
||||
point_group.reload # <= Because PointGroupItem caching?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require_relative "../../lib/hstore_filter"
|
||||
# require_relative "../../lib/hstore_filter"
|
||||
# WHY??? ^
|
||||
module Points
|
||||
class Create < Mutations::Command
|
||||
|
|
|
@ -73,7 +73,7 @@ module Points
|
|||
# a fresh session_id, the frontend will
|
||||
# think it is an "echo" and cancel it out.
|
||||
# """ - Rick
|
||||
x.update_attributes!(updated_at: Time.now)
|
||||
x.update!(updated_at: Time.now)
|
||||
x.broadcast!(SecureRandom.uuid)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
require_relative "../../lib/hstore_filter"
|
||||
# require_relative "../../lib/hstore_filter"
|
||||
# WHY??? ^
|
||||
module Points
|
||||
class Query < Mutations::Command
|
||||
H_QUERY = "meta -> :key = :value"
|
||||
class Query < Mutations::Command
|
||||
H_QUERY = "meta -> :key = :value"
|
||||
|
||||
required do
|
||||
duck :points, method: [:where]
|
||||
end
|
||||
required do
|
||||
duck :points, method: [:where]
|
||||
end
|
||||
|
||||
optional do
|
||||
float :radius
|
||||
float :x
|
||||
float :y
|
||||
float :z
|
||||
hstore :meta
|
||||
string :name
|
||||
string :pointer_type, in: Point::POINTER_KINDS
|
||||
string :plant_stage, in: CeleryScriptSettingsBag::PLANT_STAGES
|
||||
string :openfarm_slug
|
||||
end
|
||||
optional do
|
||||
float :radius
|
||||
float :x
|
||||
float :y
|
||||
float :z
|
||||
hstore :meta
|
||||
string :name
|
||||
string :pointer_type, in: Point::POINTER_KINDS
|
||||
string :plant_stage, in: CeleryScriptSettingsBag::PLANT_STAGES
|
||||
string :openfarm_slug
|
||||
end
|
||||
|
||||
def execute
|
||||
search_results
|
||||
end
|
||||
def execute
|
||||
search_results
|
||||
end
|
||||
|
||||
def search_results
|
||||
@search_results ||= conditions.reduce(points) do |collection, query|
|
||||
collection.where(query)
|
||||
end
|
||||
end
|
||||
|
||||
def conditions
|
||||
@conditions ||= regular_conditions + meta_conditions
|
||||
end
|
||||
|
||||
def meta_conditions
|
||||
@meta_conditions ||= (meta || {}).map do |(k,v)|
|
||||
[H_QUERY, {key: k, value: v}]
|
||||
end
|
||||
end
|
||||
|
||||
def regular_conditions
|
||||
@regular_conditions ||= [inputs.except(:points, :meta)]
|
||||
def search_results
|
||||
@search_results ||= conditions.reduce(points) do |collection, query|
|
||||
collection.where(query)
|
||||
end
|
||||
end
|
||||
|
||||
def conditions
|
||||
@conditions ||= regular_conditions + meta_conditions
|
||||
end
|
||||
|
||||
def meta_conditions
|
||||
@meta_conditions ||= (meta || {}).map do |(k, v)|
|
||||
[H_QUERY, { key: k, value: v }]
|
||||
end
|
||||
end
|
||||
|
||||
def regular_conditions
|
||||
@regular_conditions ||= [inputs.except(:points, :meta)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
require_relative "../../lib/hstore_filter"
|
||||
# require_relative "../../lib/hstore_filter"
|
||||
|
||||
module Points
|
||||
class Update < Mutations::Command
|
||||
required do
|
||||
model :device, class: Device
|
||||
model :point, class: Point
|
||||
model :point, class: Point
|
||||
end
|
||||
|
||||
optional do
|
||||
integer :tool_id, nils: true, empty_is_nil: true
|
||||
float :x
|
||||
float :y
|
||||
float :z
|
||||
float :radius
|
||||
string :name
|
||||
string :openfarm_slug
|
||||
float :x
|
||||
float :y
|
||||
float :z
|
||||
float :radius
|
||||
string :name
|
||||
string :openfarm_slug
|
||||
integer :pullout_direction, in: ToolSlot::PULLOUT_DIRECTIONS
|
||||
string :plant_stage, in: CeleryScriptSettingsBag::PLANT_STAGES
|
||||
time :planted_at
|
||||
hstore :meta
|
||||
string :plant_stage, in: CeleryScriptSettingsBag::PLANT_STAGES
|
||||
time :planted_at
|
||||
hstore :meta
|
||||
boolean :gantry_mounted
|
||||
end
|
||||
|
||||
|
@ -27,10 +27,10 @@ module Points
|
|||
end
|
||||
|
||||
def execute
|
||||
Point.transaction { point.update_attributes!(inputs.except(:point)) && point }
|
||||
Point.transaction { point.update!(inputs.except(:point)) && point }
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def new_tool_id?
|
||||
raw_inputs.key?("tool_id")
|
||||
|
|
|
@ -27,7 +27,7 @@ module Regimens
|
|||
RegimenItem.new(ri).tap { |r| r.validate! }
|
||||
end
|
||||
handle_body_field
|
||||
regimen.update_attributes!(inputs.slice(:name, :color, :regimen_items))
|
||||
regimen.update!(inputs.slice(:name, :color, :regimen_items))
|
||||
regimen
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module SavedGardens
|
|||
end
|
||||
|
||||
def execute
|
||||
saved_garden.update_attributes!(inputs.except(:saved_garden))
|
||||
saved_garden.update!(inputs.except(:saved_garden))
|
||||
saved_garden
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module Sensors
|
|||
end
|
||||
|
||||
def execute
|
||||
sensor.update_attributes!(inputs.except(:sensor))
|
||||
sensor.update!(inputs.except(:sensor))
|
||||
sensor
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,7 +40,7 @@ module Sequences
|
|||
Sequence.auto_sync_debounce do
|
||||
ActiveRecord::Base.transaction do
|
||||
sequence.migrated_nodes = true
|
||||
sequence.update_attributes!(inputs.except(*BLACKLIST))
|
||||
sequence.update!(inputs.except(*BLACKLIST))
|
||||
CeleryScript::StoreCelery.run!(sequence: sequence,
|
||||
args: args,
|
||||
body: body)
|
||||
|
|
|
@ -9,7 +9,7 @@ module Tools
|
|||
end
|
||||
|
||||
def execute
|
||||
tool.update_attributes!(inputs.except(:tool)) && tool
|
||||
tool.update!(inputs.except(:tool)) && tool
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ module Users
|
|||
required { model :user, class: User }
|
||||
|
||||
def execute
|
||||
user.update_attributes!(confirmed_at: Time.now,
|
||||
user.update!(confirmed_at: Time.now,
|
||||
email: user.unconfirmed_email,
|
||||
unconfirmed_email: nil)
|
||||
fbos_vers = Gem::Version.new("99.9.9") # Not relevant here, stubbing out.
|
||||
|
|
|
@ -21,7 +21,7 @@ module Users
|
|||
|
||||
def execute
|
||||
maybe_perform_password_reset
|
||||
user.update_attributes!(calculated_update)
|
||||
user.update!(calculated_update)
|
||||
user.reload
|
||||
end
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ module WebcamFeeds
|
|||
end
|
||||
|
||||
def execute
|
||||
webcam_feed.update_attributes!(inputs.except(:webcam_feed)) && webcam_feed
|
||||
webcam_feed.update!(inputs.except(:webcam_feed)) && webcam_feed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require_relative "../app/models/transport.rb"
|
||||
require File.expand_path("../boot", __FILE__)
|
||||
require_relative "../app/lib/celery_script/csheap"
|
||||
require_relative "../app/lib/celery_script/cs_heap"
|
||||
require "rails/all"
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
|
@ -14,11 +14,13 @@ module FarmBot
|
|||
REDIS_URL = ENV.fetch(REDIS_ENV_KEY, "redis://redis:6379/0")
|
||||
gcs_enabled =
|
||||
%w[ GOOGLE_CLOUD_KEYFILE_JSON GCS_PROJECT GCS_BUCKET ].all? { |s| ENV.key? s }
|
||||
config.load_defaults 6.0
|
||||
config.active_storage.service = gcs_enabled ?
|
||||
:google : :local
|
||||
config.cache_store = :redis_cache_store, { url: REDIS_URL }
|
||||
config.middleware.use Rack::Attack
|
||||
config.active_record.schema_format = :sql
|
||||
config.active_record.belongs_to_required_by_default = false
|
||||
config.active_job.queue_adapter = :delayed_job
|
||||
config.action_dispatch.perform_deep_munge = false
|
||||
I18n.enforce_available_locales = false
|
||||
|
|
|
@ -10,7 +10,7 @@ class DeprecateDeviceSerialNumberTable < ActiveRecord::Migration[5.2]
|
|||
|
||||
def change
|
||||
DeviceSerialNumber.preload(:devices) do |x|
|
||||
x.device.update_attributes!(serial_number: x.serial_number)
|
||||
x.device.update!(serial_number: x.serial_number)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ if Rails.env == "development"
|
|||
User.update_all(confirmed_at: Time.now,
|
||||
agreed_to_terms_at: Time.now)
|
||||
u = User.last
|
||||
u.update_attributes(device: Devices::Create.run!(user: u))
|
||||
u.update(device: Devices::Create.run!(user: u))
|
||||
# === Parameterized Sequence stuff
|
||||
json = JSON.parse(File.read("spec/lib/celery_script/ast_fixture5.json"), symbolize_names: true)
|
||||
Sequences::Create.run!(json, device: u.device)
|
||||
|
|
|
@ -17,7 +17,7 @@ export function Apology(_: {}) {
|
|||
<h1>Page Error</h1>
|
||||
<span>
|
||||
We can't render this part of the page due to an unrecoverable error.
|
||||
Here are some thing you can try:
|
||||
Here are some things you can try:
|
||||
</span>
|
||||
<ol>
|
||||
<li>
|
||||
|
|
|
@ -141,7 +141,7 @@ namespace :api do
|
|||
puts "Setting new support target to #{data.to_s}"
|
||||
GlobalConfig # Set the new oldest support version.
|
||||
.find_by(key: "FBOS_END_OF_LIFE_VERSION")
|
||||
.update_attributes!(value: data.to_s)
|
||||
.update!(value: data.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -86,7 +86,7 @@ describe Api::FbosConfigsController do
|
|||
it 'resets everything to the defaults' do
|
||||
sign_in user
|
||||
old_conf = device.fbos_config
|
||||
old_conf.update_attributes(arduino_debug_messages: 23)
|
||||
old_conf.update(arduino_debug_messages: 23)
|
||||
delete :destroy, params: {}
|
||||
expect(response.status).to eq(200)
|
||||
new_conf = device.reload.fbos_config
|
||||
|
|
|
@ -138,7 +138,7 @@ describe Api::FirmwareConfigsController do
|
|||
it 'resets everything to the defaults' do
|
||||
sign_in user
|
||||
old_conf = device.firmware_config
|
||||
old_conf.update_attributes(pin_guard_5_pin_nr: 23)
|
||||
old_conf.update(pin_guard_5_pin_nr: 23)
|
||||
delete :destroy, params: {}
|
||||
expect(response.status).to eq(200)
|
||||
new_conf = device.reload.firmware_config
|
||||
|
|
|
@ -90,7 +90,7 @@ describe Api::WebAppConfigsController do
|
|||
it "resets everything to the defaults" do
|
||||
sign_in user
|
||||
old_conf = device.web_app_config
|
||||
old_conf.update_attributes(zoom_level: 23)
|
||||
old_conf.update(zoom_level: 23)
|
||||
delete :destroy, params: {}
|
||||
expect(response.status).to eq(200)
|
||||
new_conf = device.reload.web_app_config
|
||||
|
|
|
@ -22,7 +22,7 @@ describe Api::DevicesController do
|
|||
expect(device.send(resource.pluralize).reload.count).to be > 0
|
||||
end
|
||||
|
||||
device.update_attributes(name: "#{SecureRandom.hex(10)}")
|
||||
device.update(name: "#{SecureRandom.hex(10)}")
|
||||
|
||||
run_jobs_now { post :reset, body: { password: password }.to_json }
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ describe Api::DevicesController do
|
|||
|
||||
describe '#show' do
|
||||
it 'handles deviceless requests' do
|
||||
user.update_attributes(device: nil)
|
||||
user.update(device: nil)
|
||||
sign_in user
|
||||
get :show, params: {}, session: { format: :json }
|
||||
expect(response.status).to eq(422)
|
||||
|
@ -27,7 +27,7 @@ describe Api::DevicesController do
|
|||
it 'reminds users to agree to TOS' do
|
||||
b4 = User::ENFORCE_TOS
|
||||
const_reassign(User, :ENFORCE_TOS, "http://farm.bot/tos")
|
||||
user.update_attributes!(agreed_to_terms_at: nil)
|
||||
user.update!(agreed_to_terms_at: nil)
|
||||
sign_in user
|
||||
get :show, params: {}, session: { format: :json }
|
||||
const_reassign(User, :ENFORCE_TOS, b4)
|
||||
|
|
|
@ -36,7 +36,8 @@ describe Api::DevicesController do
|
|||
pair = json[:devices].first
|
||||
expect(pair.first).to eq(device.id)
|
||||
real_time = device.updated_at.strftime(FORMAT).sub(/0+$/, "")
|
||||
expect(pair.last).to include(real_time)
|
||||
diff = (device.updated_at - DateTime.parse(pair.last))
|
||||
expect(diff).to be < 1
|
||||
expect(pair.last.first(8)).to eq(device.updated_at.as_json.first(8))
|
||||
json.keys.without(*EDGE_CASES).map do |key|
|
||||
array = json[key]
|
||||
|
@ -56,7 +57,10 @@ describe Api::DevicesController do
|
|||
json[key].each_with_index do |item, index|
|
||||
comparison = expected[index]
|
||||
expect(item.first).to eq(comparison.first)
|
||||
expect(Time.parse(item.last)).to eq(comparison.last.to_time)
|
||||
left = Time.parse(item.last)
|
||||
right = comparison.last.to_time.utc
|
||||
expect((right - left).seconds).to be < 1
|
||||
expect((right - left).seconds).to be >= 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -75,7 +75,7 @@ describe Api::DevicesController do
|
|||
|
||||
it "dismounts a tool" do
|
||||
sign_in user
|
||||
device.update_attributes!(mounted_tool_id: tool.id)
|
||||
device.update!(mounted_tool_id: tool.id)
|
||||
expect(device.mounted_tool_id).to be
|
||||
put :update,
|
||||
body: { id: user.device.id, mounted_tool_id: 0 }.to_json,
|
||||
|
|
|
@ -15,7 +15,7 @@ describe Api::GlobalConfigController do
|
|||
|
||||
it 'changes configs dynamically' do
|
||||
value = SecureRandom.hex
|
||||
conf.update_attributes!(value: value)
|
||||
conf.update!(value: value)
|
||||
GlobalConfig.reload_
|
||||
get :show
|
||||
expect(json[:PING]).to eq(value)
|
||||
|
|
|
@ -39,7 +39,7 @@ describe Api::ImagesController do
|
|||
sign_in user
|
||||
device = user.device
|
||||
# Using the *real* value (10) was super slow (~30 seconds)
|
||||
device.update_attributes!(max_images_count: 1)
|
||||
device.update!(max_images_count: 1)
|
||||
FactoryBot.create_list(:image, 2, device: user.device)
|
||||
get :index
|
||||
expect(response.status).to eq(200)
|
||||
|
|
|
@ -109,7 +109,7 @@ describe Api::LogsController do
|
|||
Log.destroy_all
|
||||
100.times { Log.create!(device: user.device) }
|
||||
sign_in user
|
||||
user.device.update_attributes!(max_log_count: 15)
|
||||
user.device.update!(max_log_count: 15)
|
||||
get :index, params: { format: :json }
|
||||
expect(response.status).to eq(200)
|
||||
expect(json.length).to eq(user.device.max_log_count)
|
||||
|
@ -187,7 +187,7 @@ describe Api::LogsController do
|
|||
verbosity: verbosity,
|
||||
type: type)
|
||||
end
|
||||
conf.update_attributes(success_log: 3,
|
||||
conf.update(success_log: 3,
|
||||
busy_log: 3,
|
||||
warn_log: 3,
|
||||
error_log: 3,
|
||||
|
@ -208,7 +208,7 @@ describe Api::LogsController do
|
|||
verbosity: verbosity,
|
||||
type: type)
|
||||
end
|
||||
conf.update_attributes(success_log: 0,
|
||||
conf.update(success_log: 0,
|
||||
busy_log: 0,
|
||||
warn_log: 0,
|
||||
error_log: 0,
|
||||
|
|
|
@ -93,7 +93,7 @@ describe Api::SequencesController do
|
|||
it 'updates existing sequences' do
|
||||
sign_in user
|
||||
sequence = FakeSequence.create(device: user.device)
|
||||
sequence.update_attributes!(updated_at: 2.days.ago)
|
||||
sequence.update!(updated_at: 2.days.ago)
|
||||
updated_at_before = sequence.updated_at.to_i
|
||||
input = { sequence: { name: "Scare Birds", args: {}, body: [] } }
|
||||
params = { id: sequence.id }
|
||||
|
|
|
@ -14,7 +14,7 @@ describe Api::ToolsController do
|
|||
it 'destroy a tool' do
|
||||
sign_in user
|
||||
before = Tool.count
|
||||
tool.tool_slot.update_attributes(tool: nil)
|
||||
tool.tool_slot.update(tool: nil)
|
||||
delete :destroy, params: { id: tool.id }
|
||||
after = Tool.count
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -44,7 +44,7 @@ describe Api::ToolsController do
|
|||
sign_in user
|
||||
# If we dont do this, it will trigger the wrong error.
|
||||
# We test this elsewhere - RC
|
||||
tool.tool_slot.update_attributes(tool: nil)
|
||||
tool.tool_slot.update(tool: nil)
|
||||
|
||||
before = Tool.count
|
||||
delete :destroy, params: { id: tool.id }
|
||||
|
|
|
@ -4,7 +4,7 @@ describe DashboardController do
|
|||
render_views
|
||||
|
||||
it 'can not re-verify' do
|
||||
user.update_attributes(confirmed_at: Time.now)
|
||||
user.update(confirmed_at: Time.now)
|
||||
sign_in user
|
||||
get :confirmation_page, params: { token: user.confirmation_token }
|
||||
expect(response.status).to eq(409)
|
||||
|
|
|
@ -43,7 +43,7 @@ describe DashboardController do
|
|||
|
||||
it "verifies email changes" do
|
||||
email = "foo@bar.com"
|
||||
user.update_attributes!(unconfirmed_email: "foo@bar.com")
|
||||
user.update!(unconfirmed_email: "foo@bar.com")
|
||||
params = { token: user.confirmation_token }
|
||||
get :confirmation_page, params: params
|
||||
expect(user.reload.unconfirmed_email).to be nil
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
FactoryBot.define do
|
||||
factory :image do
|
||||
attachment { StringIO.new(File.open("./spec/fixture.jpg").read) }
|
||||
meta {({x: 1, y: 2, z: 3})}
|
||||
meta { ({ x: 1, y: 2, z: 3 }) }
|
||||
device
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,15 +4,15 @@ fixture = {
|
|||
body: [
|
||||
{
|
||||
kind: "child",
|
||||
args: { grandchild: { kind: "grandchild", args: {} } }
|
||||
}
|
||||
]
|
||||
args: { grandchild: { kind: "grandchild", args: {} } },
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
describe "JSONClimber" do
|
||||
it 'Climbs JSON' do
|
||||
describe "JsonClimber" do
|
||||
it "Climbs JSON" do
|
||||
results = []
|
||||
CeleryScript::JSONClimber.climb(fixture) do |hmm|
|
||||
CeleryScript::JsonClimber.climb(fixture) do |hmm|
|
||||
results.push(hmm[:kind])
|
||||
end
|
||||
expect(results).to eq(["parent", "child", "grandchild"])
|
||||
|
|
|
@ -2,16 +2,20 @@ require "spec_helper"
|
|||
# require_relative "../../lib/log_service"
|
||||
|
||||
describe LogService do
|
||||
normal_payl = {
|
||||
z: 0,
|
||||
y: 0,
|
||||
x: 0,
|
||||
type: "info",
|
||||
major_version: 6,
|
||||
message: "HQ FarmBot TEST 123 Pin 13 is 0",
|
||||
created_at: 1512585641,
|
||||
channels: [],
|
||||
}.to_json
|
||||
normal_hash = ->() do
|
||||
return {
|
||||
z: 0,
|
||||
y: 0,
|
||||
x: 0,
|
||||
type: "info",
|
||||
major_version: 8,
|
||||
message: "HQ FarmBot TEST 123 Pin 13 is 0",
|
||||
created_at: 1512585641,
|
||||
channels: [],
|
||||
}
|
||||
end
|
||||
|
||||
normal_payl = normal_hash[].to_json
|
||||
|
||||
let!(:device) { FactoryBot.create(:device) }
|
||||
let!(:device_id) { device.id }
|
||||
|
@ -83,4 +87,18 @@ describe LogService do
|
|||
LogService.new.process(fake_delivery_info, "}}{{")
|
||||
end.to raise_error(Mutations::ValidationException)
|
||||
end
|
||||
|
||||
it "does not save `fun`, `debug` or `nil` logs" do
|
||||
["fun", "debug", nil].map do |type|
|
||||
Log.destroy_all
|
||||
j = normal_hash[].merge(type: type).to_json
|
||||
LogService.new.process(fake_delivery_info, j)
|
||||
if Log.count != 0
|
||||
opps = "Expected there to be no #{type.inspect} logs. " \
|
||||
"There are, though. -RC"
|
||||
fail(opps)
|
||||
end
|
||||
expect(Log.count).to be 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,19 +38,19 @@ describe SessionToken do
|
|||
end
|
||||
|
||||
it "doesn't honor expired tokens" do
|
||||
user.update_attributes!(confirmed_at: Time.now)
|
||||
user.update!(confirmed_at: Time.now)
|
||||
token = SessionToken.issue_to(user, iat: 000,
|
||||
exp: 1,
|
||||
iss: "//lycos.com:9867",
|
||||
fbos_version: Gem::Version.new("9.9.9"))
|
||||
result = Auth::FromJWT.run(jwt: token.encoded)
|
||||
result = Auth::FromJwt.run(jwt: token.encoded)
|
||||
expect(result.success?).to be(false)
|
||||
expect(result.errors.values.first.message).to eq(Auth::ReloadToken::BAD_SUB)
|
||||
end
|
||||
|
||||
unless ENV["NO_EMAILS"]
|
||||
it "doesn't mint tokens for unverified users" do
|
||||
user.update_attributes!(confirmed_at: nil)
|
||||
user.update!(confirmed_at: nil)
|
||||
expect {
|
||||
SessionToken.issue_to(user, iat: 000,
|
||||
exp: 1,
|
||||
|
|
|
@ -68,7 +68,7 @@ describe Device do
|
|||
|
||||
it "throttles a device that sends too many logs" do
|
||||
expect(device).to receive(:tell).and_return(Log.new)
|
||||
device.update_attributes!(throttled_until: nil)
|
||||
device.update!(throttled_until: nil)
|
||||
expect(device.throttled_until).to be(nil)
|
||||
five_minutes = ThrottlePolicy::TimePeriod.new(5.minutes, Time.now + 1.minute)
|
||||
rule = ThrottlePolicy::Rule.new("X", five_minutes, 500)
|
||||
|
@ -80,7 +80,7 @@ describe Device do
|
|||
it "increases a device throttle time period" do
|
||||
expect(device).to receive(:tell).and_return(Log.new)
|
||||
previous_throttle = Time.now - 1.minute
|
||||
device.update_attributes!(throttled_until: previous_throttle)
|
||||
device.update!(throttled_until: previous_throttle)
|
||||
expect(device.throttled_until).to eq(previous_throttle)
|
||||
five_minutes = ThrottlePolicy::TimePeriod.new(5.minutes, Time.now + 1.minute)
|
||||
rule = ThrottlePolicy::Rule.new("X", five_minutes, 500)
|
||||
|
@ -92,7 +92,7 @@ describe Device do
|
|||
it "unthrottles a runaway device" do
|
||||
expect(device).to receive(:tell).and_return(Log.new)
|
||||
example = Time.now - 1.minute
|
||||
device.update_attributes!(throttled_until: example)
|
||||
device.update!(throttled_until: example)
|
||||
expect(device.throttled_until).to eq(example)
|
||||
device.maybe_unthrottle
|
||||
expect(device.throttled_until).to eq(nil)
|
||||
|
@ -114,7 +114,7 @@ describe Device do
|
|||
end
|
||||
|
||||
it "throttled emails about MQTT rate limiting" do
|
||||
device.update_attributes!(mqtt_rate_limit_email_sent_at: 2.days.ago)
|
||||
device.update!(mqtt_rate_limit_email_sent_at: 2.days.ago)
|
||||
Device.connection_warning("device_#{device.id.to_s}")
|
||||
time = device.reload.mqtt_rate_limit_email_sent_at
|
||||
expect(time).to be > 1.minute.ago
|
||||
|
|
|
@ -16,7 +16,7 @@ describe FbosConfig do
|
|||
|
||||
it "notifies us of broken production data" do
|
||||
# Remove this test by May 2019.
|
||||
config.device.update_attributes!(serial_number: nil)
|
||||
config.device.update!(serial_number: nil)
|
||||
conn = fake_conn("Report broke data")
|
||||
NervesHub.set_conn(conn)
|
||||
problem = "Device #{device.id} missing serial"
|
||||
|
@ -37,7 +37,7 @@ describe FbosConfig do
|
|||
expect(NervesHub.conn).to(receive(:put).with(*params).and_return(resp2))
|
||||
|
||||
run_jobs_now do
|
||||
config.update_attributes!(update_channel: "beta")
|
||||
config.update!(update_channel: "beta")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ describe PointGroup do
|
|||
end
|
||||
|
||||
fit "refuses to delete groups in-use by regimens" do
|
||||
point_group.update_attributes!(name: "@@@")
|
||||
point_group.update!(name: "@@@")
|
||||
Regimens::Create.run!(name: "Wrapper 26",
|
||||
device: device,
|
||||
color: "red",
|
||||
|
|
|
@ -4,7 +4,7 @@ describe WebcamFeed do
|
|||
let(:feed) { FactoryBot.create(:webcam_feed) }
|
||||
|
||||
it "requires a URL" do
|
||||
result = feed.update_attributes(url: nil)
|
||||
result = feed.update(url: nil)
|
||||
expect(result).to be(false)
|
||||
expect(result).to be(false)
|
||||
expect(feed.errors.messages[:url]).to include("can't be blank")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe Auth::FromJWT do
|
||||
describe Auth::FromJwt do
|
||||
let(:user) { FactoryBot.create(:user) }
|
||||
|
||||
def fake_credentials(email, password)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe Auth::FromJWT do
|
||||
describe Auth::FromJwt do
|
||||
FAKE_VERS = Gem::Version.new("99.9.9")
|
||||
let(:user) { FactoryBot.create(:user) }
|
||||
let(:token) do
|
||||
|
@ -19,7 +19,7 @@ describe Auth::FromJWT do
|
|||
}
|
||||
|
||||
it "gets user from jwt" do
|
||||
result = Auth::FromJWT.run!(jwt: token)
|
||||
result = Auth::FromJwt.run!(jwt: token)
|
||||
expect(result).to eq(user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ describe Devices::Dump do
|
|||
.points
|
||||
.where(pointer_type: "ToolSlot")
|
||||
.last
|
||||
.update_attributes(tool_id: tools.last.id)
|
||||
.update(tool_id: tools.last.id)
|
||||
plant = device
|
||||
.points
|
||||
.where(pointer_type: "Plant")
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe CeleryScript::CSHeap do
|
||||
describe CeleryScript::CsHeap do
|
||||
it "raises if address is bad" do
|
||||
expect do
|
||||
CeleryScript::CSHeap.new.put(CeleryScript::HeapAddress[99], "no", "no")
|
||||
end.to raise_error(CeleryScript::CSHeap::BadAddress)
|
||||
CeleryScript::CsHeap.new.put(CeleryScript::HeapAddress[99], "no", "no")
|
||||
end.to raise_error(CeleryScript::CsHeap::BadAddress)
|
||||
end
|
||||
end
|
|
@ -11,10 +11,10 @@ describe CeleryScript::FirstPass do
|
|||
CeleryScript::FlatIrHelpers.fake_first_pass.primary_nodes
|
||||
end
|
||||
|
||||
kind = CeleryScript::CSHeap::KIND
|
||||
parent = CeleryScript::CSHeap::PARENT
|
||||
next_ = CeleryScript::CSHeap::NEXT
|
||||
body = CeleryScript::CSHeap::BODY
|
||||
kind = CeleryScript::CsHeap::KIND
|
||||
parent = CeleryScript::CsHeap::PARENT
|
||||
next_ = CeleryScript::CsHeap::NEXT
|
||||
body = CeleryScript::CsHeap::BODY
|
||||
|
||||
EXPECTATIONS = { # Came from the JS implementation which is known good.
|
||||
0 => { kind => "nothing", parent => 0, next_ => 0 },
|
||||
|
|
|
@ -2,11 +2,11 @@ require "spec_helper"
|
|||
require_relative "./flat_ir_helpers"
|
||||
|
||||
describe CeleryScript::Slicer do
|
||||
kind = CeleryScript::CSHeap::KIND
|
||||
parent = CeleryScript::CSHeap::PARENT
|
||||
next_ = CeleryScript::CSHeap::NEXT
|
||||
body = CeleryScript::CSHeap::BODY
|
||||
comment = CeleryScript::CSHeap::COMMENT
|
||||
kind = CeleryScript::CsHeap::KIND
|
||||
parent = CeleryScript::CsHeap::PARENT
|
||||
next_ = CeleryScript::CsHeap::NEXT
|
||||
body = CeleryScript::CsHeap::BODY
|
||||
comment = CeleryScript::CsHeap::COMMENT
|
||||
|
||||
n = "nothing"
|
||||
|
||||
|
|
Loading…
Reference in New Issue