marty 1.0.35 → 1.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/components/marty/api_config_view.rb +11 -7
- data/app/controllers/marty/rpc_controller.rb +50 -12
- data/app/models/marty/api_config.rb +2 -1
- data/db/migrate/302_add_api_configs_validate_result.rb +9 -0
- data/lib/marty/version.rb +1 -1
- data/spec/controllers/rpc_controller_spec.rb +223 -19
- data/spec/dummy/public/images/icons +1 -1
- data/spec/dummy/spec/features/javascripts +1 -1
- data/spec/features/log_view_spec.rb +1 -0
- data/spec/lib/logger_spec.rb +2 -1
- metadata +4 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3ee1b4758299664b9d0140ae70dcd1b2c0dddc5e
         | 
| 4 | 
            +
              data.tar.gz: 865b7a125ce0321f3ca674936ab74023daa6c6a9
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 1a3bce72d9bd0f1b5f9aa1f92bfca51385163be1b669fee56ef7faf71e0ea45919b3573f056bfb81ff07d8176e095f1c61c8dd0e067186573004686ad6fb05e1
         | 
| 7 | 
            +
              data.tar.gz: 3ebfdc6cd512712555ad8f329cf2d8d5f3a1655618cc95b5db5f2b75fdec1f8cb2d0e547252410eb7217a0b5eff6b08f81469983094dcd1fee9a8aa0f95f2c4c
         | 
| @@ -13,7 +13,9 @@ class Marty::ApiConfigView < Marty::Grid | |
| 13 13 | 
             
                  :node,
         | 
| 14 14 | 
             
                  :attr,
         | 
| 15 15 | 
             
                  :logged,
         | 
| 16 | 
            -
                  : | 
| 16 | 
            +
                  :input_validated,
         | 
| 17 | 
            +
                  :output_validated,
         | 
| 18 | 
            +
                  :strict_validate,
         | 
| 17 19 | 
             
                  :created_at,
         | 
| 18 20 | 
             
                  :updated_at,
         | 
| 19 21 | 
             
                ]
         | 
| @@ -47,11 +49,11 @@ class Marty::ApiConfigView < Marty::Grid | |
| 47 49 | 
             
                  c.setter = lambda { |r, v| r.send("#{a}=", v.blank? ? nil : v) }
         | 
| 48 50 | 
             
                end
         | 
| 49 51 | 
             
              end
         | 
| 50 | 
            -
               | 
| 51 | 
            -
                 | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
                 | 
| 52 | 
            +
              [:logged, :input_validated, :output_validated, :strict_validate].each do
         | 
| 53 | 
            +
                |a|
         | 
| 54 | 
            +
                attribute a do |c|
         | 
| 55 | 
            +
                  c.width = 110
         | 
| 56 | 
            +
                end
         | 
| 55 57 | 
             
              end
         | 
| 56 58 | 
             
              [:created_at, :updated_at].each do |a|
         | 
| 57 59 | 
             
                attribute a do |c|
         | 
| @@ -64,7 +66,9 @@ class Marty::ApiConfigView < Marty::Grid | |
| 64 66 | 
             
                  :node,
         | 
| 65 67 | 
             
                  :attr,
         | 
| 66 68 | 
             
                  :logged,
         | 
| 67 | 
            -
                  : | 
| 69 | 
            +
                  :input_validated,
         | 
| 70 | 
            +
                  :output_validated,
         | 
| 71 | 
            +
                  :strict_validate,
         | 
| 68 72 | 
             
                ]
         | 
| 69 73 | 
             
              end
         | 
| 70 74 |  | 
| @@ -28,7 +28,7 @@ class Marty::RpcController < ActionController::Base | |
| 28 28 | 
             
                  attrs.zip(result)
         | 
| 29 29 | 
             
                rescue => e
         | 
| 30 30 | 
             
                  use_message = e.message == 'No such script' ?
         | 
| 31 | 
            -
                                'Schema not defined' : 'Problem with schema'
         | 
| 31 | 
            +
                                'Schema not defined' : 'Problem with schema: ' + e.message
         | 
| 32 32 | 
             
                  raise "Schema error for #{sname}/#{node} "\
         | 
| 33 33 | 
             
                        "attrs=#{attrs.join(',')}: #{use_message}"
         | 
| 34 34 | 
             
                end
         | 
| @@ -64,32 +64,36 @@ class Marty::RpcController < ActionController::Base | |
| 64 64 |  | 
| 65 65 | 
             
                return {error: "Malformed params"} unless params.is_a?(Hash)
         | 
| 66 66 |  | 
| 67 | 
            -
                 | 
| 67 | 
            +
                need_input_validate, need_output_validate, strict_validate, need_log =
         | 
| 68 | 
            +
                                                                            [], [], [], []
         | 
| 68 69 | 
             
                Marty::ApiConfig.multi_lookup(sname, node, attrs).each do
         | 
| 69 | 
            -
                  |attr, log,  | 
| 70 | 
            -
                   | 
| 70 | 
            +
                  |attr, log, input_validate, output_validate, strict, id|
         | 
| 71 | 
            +
                  need_input_validate << attr if input_validate
         | 
| 72 | 
            +
                  need_output_validate << attr + "_" if output_validate
         | 
| 73 | 
            +
                  strict_validate << attr if strict
         | 
| 71 74 | 
             
                  need_log << id if log
         | 
| 72 75 | 
             
                end
         | 
| 73 76 |  | 
| 77 | 
            +
                opt = { :validate_schema    => true,
         | 
| 78 | 
            +
                            :errors_as_objects  => true,
         | 
| 79 | 
            +
                            :version            => Marty::JsonSchema::RAW_URI }
         | 
| 80 | 
            +
                to_append = {"\$schema" => Marty::JsonSchema::RAW_URI}
         | 
| 81 | 
            +
             | 
| 74 82 | 
             
                validation_error = {}
         | 
| 75 83 | 
             
                err_count = 0
         | 
| 76 | 
            -
                if  | 
| 84 | 
            +
                if need_input_validate.present?
         | 
| 77 85 | 
             
                  begin
         | 
| 78 | 
            -
                    schemas = get_schemas(tag, sname, node,  | 
| 86 | 
            +
                    schemas = get_schemas(tag, sname, node, need_input_validate)
         | 
| 79 87 | 
             
                  rescue => e
         | 
| 80 88 | 
             
                    return {error: e.message}
         | 
| 81 89 | 
             
                  end
         | 
| 82 | 
            -
                  opt = { :validate_schema    => true,
         | 
| 83 | 
            -
                          :errors_as_objects  => true,
         | 
| 84 | 
            -
                          :version            => Marty::JsonSchema::RAW_URI }
         | 
| 85 | 
            -
                  to_append = {"\$schema" => Marty::JsonSchema::RAW_URI}
         | 
| 86 90 | 
             
                  schemas.each do |attr, sch|
         | 
| 87 91 | 
             
                    begin
         | 
| 88 92 | 
             
                      er = JSON::Validator.fully_validate(sch.merge(to_append), params, opt)
         | 
| 89 93 | 
             
                    rescue NameError
         | 
| 90 94 | 
             
                      return {error: "Unrecognized PgEnum for attribute #{attr}"}
         | 
| 91 95 | 
             
                    rescue => ex
         | 
| 92 | 
            -
                      return {error: ex.message}
         | 
| 96 | 
            +
                      return {error: "#{attr}: #{ex.message}"}
         | 
| 93 97 | 
             
                    end
         | 
| 94 98 | 
             
                    validation_error[attr] = er.map{ |e| e[:message] } if er.size > 0
         | 
| 95 99 | 
             
                    err_count += er.size
         | 
| @@ -116,8 +120,42 @@ class Marty::RpcController < ActionController::Base | |
| 116 120 | 
             
                    result = engine.background_eval(node, params, attrs)
         | 
| 117 121 | 
             
                    return retval = {"job_id" => result.__promise__.id}
         | 
| 118 122 | 
             
                  end
         | 
| 119 | 
            -
             | 
| 120 123 | 
             
                  res = engine.evaluate_attrs(node, attrs, params)
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  validation_error = {}
         | 
| 126 | 
            +
                  err_count = 0
         | 
| 127 | 
            +
                  if need_output_validate.present?
         | 
| 128 | 
            +
                    begin
         | 
| 129 | 
            +
                      schemas = get_schemas(tag, sname, node, need_output_validate)
         | 
| 130 | 
            +
                    rescue => e
         | 
| 131 | 
            +
                      return {error: e.message}
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
                    pairs = attrs.zip(res)
         | 
| 134 | 
            +
                    pairs.zip(schemas).each do |(attr, res), (_, sch)|
         | 
| 135 | 
            +
                      begin
         | 
| 136 | 
            +
                        er = JSON::Validator.fully_validate(sch.merge(to_append), res, opt)
         | 
| 137 | 
            +
                      rescue NameError
         | 
| 138 | 
            +
                        return {error: "Unrecognized PgEnum for attribute #{attr}"}
         | 
| 139 | 
            +
                      rescue => ex
         | 
| 140 | 
            +
                        return {error: "#{attr}: #{ex.message}"}
         | 
| 141 | 
            +
                      end
         | 
| 142 | 
            +
                      validation_error[attr] = er.map{ |e| e[:message] } if er.size > 0
         | 
| 143 | 
            +
                      err_count += er.size
         | 
| 144 | 
            +
                    end
         | 
| 145 | 
            +
                    if err_count > 0
         | 
| 146 | 
            +
                      res = pairs.map do |attr, res|
         | 
| 147 | 
            +
                        is_strict = strict_validate.include?(attr)
         | 
| 148 | 
            +
                        the_error = validation_error[attr]
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                        Marty::Logger.error("API #{sname}:#{node}.#{attr}",
         | 
| 151 | 
            +
                                            {error:  the_error,
         | 
| 152 | 
            +
                                             data: res}) if the_error
         | 
| 153 | 
            +
                        is_strict && the_error ?
         | 
| 154 | 
            +
                          {error: "Error(s) validating: #{the_error}"} : res
         | 
| 155 | 
            +
                      end
         | 
| 156 | 
            +
                    end
         | 
| 157 | 
            +
                  end
         | 
| 158 | 
            +
             | 
| 121 159 | 
             
                  return retval = (attrs_atom ? res.first : res)
         | 
| 122 160 | 
             
                rescue => exc
         | 
| 123 161 | 
             
                  err_msg = Delorean::Engine.grok_runtime_exception(exc).symbolize_keys
         | 
| @@ -6,7 +6,8 @@ class Marty::ApiConfig < Marty::Base | |
| 6 6 | 
             
                       "AND (attr IS NULL OR attr = ?)",
         | 
| 7 7 | 
             
                       script, node, attr]).
         | 
| 8 8 | 
             
                       order('node nulls last, attr nulls last').
         | 
| 9 | 
            -
                       pluck(:logged, : | 
| 9 | 
            +
                       pluck(:logged, :input_validated, :output_validated, :strict_validate,
         | 
| 10 | 
            +
                             :id)
         | 
| 10 11 | 
             
                res.first
         | 
| 11 12 | 
             
              end
         | 
| 12 13 | 
             
              def self.multi_lookup(script, node, attrs)
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            class AddApiConfigsValidateResult < ActiveRecord::Migration
         | 
| 2 | 
            +
              def change
         | 
| 3 | 
            +
                rename_column :marty_api_configs, :validated, :input_validated
         | 
| 4 | 
            +
                add_column :marty_api_configs, :output_validated, :boolean, null: false,
         | 
| 5 | 
            +
                           default: false
         | 
| 6 | 
            +
                add_column :marty_api_configs, :strict_validate, :boolean, null: false,
         | 
| 7 | 
            +
                           default: false
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
            end
         | 
    
        data/lib/marty/version.rb
    CHANGED
    
    
| @@ -47,7 +47,7 @@ A: M3::A | |
| 47 47 | 
             
                g = e * 5 + f
         | 
| 48 48 | 
             
                h = f + 1
         | 
| 49 49 | 
             
                ptest = p * 10
         | 
| 50 | 
            -
                result = [{"a":  | 
| 50 | 
            +
                result = [{"a": p, "b": 456}, {"a": 789, "b": p}]
         | 
| 51 51 | 
             
            eof
         | 
| 52 52 |  | 
| 53 53 | 
             
            sample_script5 = <<eof
         | 
| @@ -60,6 +60,8 @@ A: | |
| 60 60 | 
             
                    else if f == "Orange"
         | 
| 61 61 | 
             
                    then 2
         | 
| 62 62 | 
             
                    else 9
         | 
| 63 | 
            +
                result =  [{"a": "str", "b": 456}, {"a": 789, "b": "str"}]
         | 
| 64 | 
            +
                result2 = [{"a": "str", "b": 456}, {"a": 789, "b": "str"}]
         | 
| 63 65 | 
             
            eof
         | 
| 64 66 |  | 
| 65 67 | 
             
            sample_script6 = <<eof
         | 
| @@ -80,6 +82,13 @@ A: | |
| 80 82 | 
             
                res = 123
         | 
| 81 83 | 
             
            eof
         | 
| 82 84 |  | 
| 85 | 
            +
            sample_script9 = <<eof
         | 
| 86 | 
            +
            A:
         | 
| 87 | 
            +
                b =?
         | 
| 88 | 
            +
                res = b + 1
         | 
| 89 | 
            +
                result = [{"a": 1, "b": res}, {"a": 789, "b": res}]
         | 
| 90 | 
            +
            eof
         | 
| 91 | 
            +
             | 
| 83 92 | 
             
            script3_schema = <<eof
         | 
| 84 93 | 
             
            A:
         | 
| 85 94 | 
             
                pc = { "properties : {
         | 
| @@ -94,6 +103,7 @@ A: | |
| 94 103 | 
             
                        "p" : { "type" : "integer" },
         | 
| 95 104 | 
             
                            }
         | 
| 96 105 | 
             
                        }
         | 
| 106 | 
            +
                d_ = { "type" : "integer" }
         | 
| 97 107 |  | 
| 98 108 | 
             
                g = { "properties" : {
         | 
| 99 109 | 
             
                              "e" : { "type" : "integer" },
         | 
| @@ -101,10 +111,29 @@ A: | |
| 101 111 | 
             
                            }
         | 
| 102 112 | 
             
                      }
         | 
| 103 113 |  | 
| 114 | 
            +
                g_ = { "type" : "integer" }
         | 
| 115 | 
            +
             | 
| 104 116 | 
             
                lc = { "properties" : {
         | 
| 105 117 | 
             
                              "p" : { "type" : "integer" },
         | 
| 106 118 | 
             
                            }
         | 
| 107 119 | 
             
                        }
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                result = { "properties" : {
         | 
| 122 | 
            +
                        "p" : { "type" : "integer" },
         | 
| 123 | 
            +
                            }
         | 
| 124 | 
            +
                         }
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                result_ = {
         | 
| 127 | 
            +
                             "type": "array",
         | 
| 128 | 
            +
                             "minItems": 1,
         | 
| 129 | 
            +
                             "items": {
         | 
| 130 | 
            +
                               "type": "object",
         | 
| 131 | 
            +
                               "properties": {
         | 
| 132 | 
            +
                                   "a": { "type" : "integer" },
         | 
| 133 | 
            +
                                   "b": { "type" : "integer" }
         | 
| 134 | 
            +
                            }
         | 
| 135 | 
            +
                          }
         | 
| 136 | 
            +
                      }
         | 
| 108 137 | 
             
            eof
         | 
| 109 138 |  | 
| 110 139 | 
             
            script5_schema = <<eof
         | 
| @@ -113,6 +142,39 @@ A: | |
| 113 142 | 
             
                        "f" : { "pg_enum" : "FruitsEnum" },
         | 
| 114 143 | 
             
                            }
         | 
| 115 144 | 
             
                        }
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                result = { "properties" : {
         | 
| 147 | 
            +
                        "f" : { "pg_enum" : "FruitsEnum" },
         | 
| 148 | 
            +
                            }
         | 
| 149 | 
            +
                        }
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                result_ = { "type": "array",
         | 
| 152 | 
            +
                             "minItems": 1,
         | 
| 153 | 
            +
                             "items": {
         | 
| 154 | 
            +
                               "type": "object",
         | 
| 155 | 
            +
                               "properties": {
         | 
| 156 | 
            +
                                   "a": { "type" : "integer" },
         | 
| 157 | 
            +
                                   "b": { "type" : "string" }
         | 
| 158 | 
            +
                               }
         | 
| 159 | 
            +
                            }
         | 
| 160 | 
            +
                         }
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                result2 = { "properties" : {
         | 
| 163 | 
            +
                        "f" : { "pg_enum" : "FruitsEnum" },
         | 
| 164 | 
            +
                            }
         | 
| 165 | 
            +
                        }
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                result2_ = { "type": "array",
         | 
| 168 | 
            +
                             "minItems": 1,
         | 
| 169 | 
            +
                             "items": {
         | 
| 170 | 
            +
                               "type": "object",
         | 
| 171 | 
            +
                               "properties": {
         | 
| 172 | 
            +
                                   "a": { "type" : "integer" },
         | 
| 173 | 
            +
                                   "b": { "type" : "string" }
         | 
| 174 | 
            +
                               }
         | 
| 175 | 
            +
                            }
         | 
| 176 | 
            +
                         }
         | 
| 177 | 
            +
             | 
| 116 178 | 
             
            eof
         | 
| 117 179 |  | 
| 118 180 | 
             
            script6_schema = <<eof
         | 
| @@ -139,6 +201,31 @@ A: | |
| 139 201 | 
             
                        }
         | 
| 140 202 | 
             
            eof
         | 
| 141 203 |  | 
| 204 | 
            +
            script9_schema = <<eof
         | 
| 205 | 
            +
            A:
         | 
| 206 | 
            +
                res = { "properties" : {
         | 
| 207 | 
            +
                        "b" : { "type" : "number" },
         | 
| 208 | 
            +
                            }
         | 
| 209 | 
            +
                        }
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                result = { "properties" : {
         | 
| 212 | 
            +
                        "b" : { "type" : "number" },
         | 
| 213 | 
            +
                            }
         | 
| 214 | 
            +
                        }
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                result_ = {  "type": "array",
         | 
| 217 | 
            +
                             "minItems": 1,
         | 
| 218 | 
            +
                             "items": {
         | 
| 219 | 
            +
                               "type": "object",
         | 
| 220 | 
            +
                               "properties": {
         | 
| 221 | 
            +
                                   "a": { "type" : "integer" },
         | 
| 222 | 
            +
                                   "b": { "type" : "integer" },
         | 
| 223 | 
            +
                                   "c": { "type" : "string" }
         | 
| 224 | 
            +
                               },
         | 
| 225 | 
            +
                               "required" : ["a", "b", "c"]
         | 
| 226 | 
            +
                            }
         | 
| 227 | 
            +
                      }
         | 
| 228 | 
            +
            eof
         | 
| 142 229 |  | 
| 143 230 | 
             
            describe Marty::RpcController do
         | 
| 144 231 | 
             
              before(:each) {
         | 
| @@ -162,12 +249,14 @@ describe Marty::RpcController do | |
| 162 249 | 
             
                                     "M6" => sample_script6,
         | 
| 163 250 | 
             
                                     "M7" => sample_script7,
         | 
| 164 251 | 
             
                                     "M8" => sample_script8,
         | 
| 252 | 
            +
                                     "M9" => sample_script9,
         | 
| 165 253 | 
             
                                     "M3Schemas" => script3_schema,
         | 
| 166 254 | 
             
                                     "M4Schemas" => script4_schema,
         | 
| 167 255 | 
             
                                     "M5Schemas" => script5_schema,
         | 
| 168 256 | 
             
                                     "M6Schemas" => script6_schema,
         | 
| 169 257 | 
             
                                     "M7Schemas" => script7_schema,
         | 
| 170 258 | 
             
                                     "M8Schemas" => script8_schema,
         | 
| 259 | 
            +
                                     "M9Schemas" => script9_schema,
         | 
| 171 260 | 
             
                                   }, Date.today + 1.minute)
         | 
| 172 261 |  | 
| 173 262 | 
             
                @p1 = Marty::Posting.do_create("BASE", Date.today + 2.minute, 'a comment')
         | 
| @@ -415,7 +504,7 @@ describe Marty::RpcController do | |
| 415 504 | 
             
                  attrs: ["result"].to_json,
         | 
| 416 505 | 
             
                }
         | 
| 417 506 | 
             
                # puts 'Z'*40, request.inspect
         | 
| 418 | 
            -
                expect(response.body).to eq("a,b\r\ | 
| 507 | 
            +
                expect(response.body).to eq("a,b\r\n10,456\r\n789,10\r\n")
         | 
| 419 508 | 
             
              end
         | 
| 420 509 |  | 
| 421 510 | 
             
              it "returns an error message on missing schema script (csv)" do
         | 
| @@ -423,7 +512,7 @@ describe Marty::RpcController do | |
| 423 512 | 
             
                                         node: "A",
         | 
| 424 513 | 
             
                                         attr: nil,
         | 
| 425 514 | 
             
                                         logged: false,
         | 
| 426 | 
            -
                                          | 
| 515 | 
            +
                                         input_validated: true)
         | 
| 427 516 | 
             
                attrs = ["b"].to_json
         | 
| 428 517 | 
             
                params = {"a" => 5}.to_json
         | 
| 429 518 | 
             
                get 'evaluate', {
         | 
| @@ -442,7 +531,7 @@ describe Marty::RpcController do | |
| 442 531 | 
             
                                         node: "A",
         | 
| 443 532 | 
             
                                         attr: nil,
         | 
| 444 533 | 
             
                                         logged: false,
         | 
| 445 | 
            -
                                          | 
| 534 | 
            +
                                         input_validated: true)
         | 
| 446 535 | 
             
                attrs = ["b"].to_json
         | 
| 447 536 | 
             
                params = {"a" => 5}.to_json
         | 
| 448 537 | 
             
                get 'evaluate', {
         | 
| @@ -464,7 +553,7 @@ describe Marty::RpcController do | |
| 464 553 | 
             
                                         node: "A",
         | 
| 465 554 | 
             
                                         attr: nil,
         | 
| 466 555 | 
             
                                         logged: false,
         | 
| 467 | 
            -
                                          | 
| 556 | 
            +
                                         input_validated: true)
         | 
| 468 557 | 
             
                attrs = ["h"].to_json
         | 
| 469 558 | 
             
                params = {"f" => 5}.to_json
         | 
| 470 559 | 
             
                get 'evaluate', {
         | 
| @@ -474,8 +563,8 @@ describe Marty::RpcController do | |
| 474 563 | 
             
                  attrs: attrs,
         | 
| 475 564 | 
             
                  params: params
         | 
| 476 565 | 
             
                }
         | 
| 477 | 
            -
                expect = "Schema error for M4/A attrs=h: Problem with schema | 
| 478 | 
            -
                expect(response.body).to  | 
| 566 | 
            +
                expect = "Schema error for M4/A attrs=h: Problem with schema"
         | 
| 567 | 
            +
                expect(response.body).to include("error,#{expect}")
         | 
| 479 568 | 
             
              end
         | 
| 480 569 |  | 
| 481 570 | 
             
              it "returns an error message on invalid schema" do
         | 
| @@ -483,7 +572,7 @@ describe Marty::RpcController do | |
| 483 572 | 
             
                                         node: "A",
         | 
| 484 573 | 
             
                                         attr: nil,
         | 
| 485 574 | 
             
                                         logged: false,
         | 
| 486 | 
            -
                                          | 
| 575 | 
            +
                                         input_validated: true)
         | 
| 487 576 | 
             
                attrs = ["pc"].to_json
         | 
| 488 577 | 
             
                params = {"p" => 5}.to_json
         | 
| 489 578 | 
             
                get 'evaluate', {
         | 
| @@ -493,7 +582,8 @@ describe Marty::RpcController do | |
| 493 582 | 
             
                  attrs: attrs,
         | 
| 494 583 | 
             
                  params: params
         | 
| 495 584 | 
             
                }
         | 
| 496 | 
            -
                expect = "Schema error for M3/A attrs=pc: Problem with schema\ | 
| 585 | 
            +
                expect = "Schema error for M3/A attrs=pc: Problem with schema: "\
         | 
| 586 | 
            +
                         "syntax error M3Schemas:2\r\n"
         | 
| 497 587 | 
             
                expect(response.body).to eq("error,#{expect}")
         | 
| 498 588 | 
             
              end
         | 
| 499 589 |  | 
| @@ -502,7 +592,7 @@ describe Marty::RpcController do | |
| 502 592 | 
             
                                         node: "A",
         | 
| 503 593 | 
             
                                         attr: nil,
         | 
| 504 594 | 
             
                                         logged: false,
         | 
| 505 | 
            -
                                          | 
| 595 | 
            +
                                         input_validated: true)
         | 
| 506 596 | 
             
                attrs = ["d"].to_json
         | 
| 507 597 | 
             
                params = {"p" => "132"}.to_json
         | 
| 508 598 | 
             
                get 'evaluate', {
         | 
| @@ -522,7 +612,8 @@ describe Marty::RpcController do | |
| 522 612 | 
             
                                         node: "A",
         | 
| 523 613 | 
             
                                         attr: nil,
         | 
| 524 614 | 
             
                                         logged: false,
         | 
| 525 | 
            -
                                          | 
| 615 | 
            +
                                         input_validated: true,
         | 
| 616 | 
            +
                                         output_validated: true)
         | 
| 526 617 | 
             
                attrs = ["d", "g"].to_json
         | 
| 527 618 | 
             
                params = {"p" => "132", "e" => "55", "f"=>"16"}.to_json
         | 
| 528 619 | 
             
                get 'evaluate', {
         | 
| @@ -531,7 +622,7 @@ describe Marty::RpcController do | |
| 531 622 | 
             
                  node: "A",
         | 
| 532 623 | 
             
                  attrs: attrs,
         | 
| 533 624 | 
             
                  params: params
         | 
| 534 | 
            -
             | 
| 625 | 
            +
                    }
         | 
| 535 626 | 
             
                expect = '""d""=>[""The property \'#/p\' of type string did not '\
         | 
| 536 627 | 
             
                         'match the following type: integer'
         | 
| 537 628 | 
             
                expect(response.body).to include(expect)
         | 
| @@ -543,12 +634,125 @@ describe Marty::RpcController do | |
| 543 634 | 
             
                expect(response.body).to include(expect)
         | 
| 544 635 | 
             
              end
         | 
| 545 636 |  | 
| 637 | 
            +
              context "output_validation" do
         | 
| 638 | 
            +
                before(:all) do
         | 
| 639 | 
            +
                  @db =  SQLite3::Database.new(Marty::Log.logfile)
         | 
| 640 | 
            +
                end
         | 
| 641 | 
            +
                before(:each) do
         | 
| 642 | 
            +
                  @logid = @db.execute('select max(id) from log').first.first || 0 rescue 0
         | 
| 643 | 
            +
                end
         | 
| 644 | 
            +
                after(:all) do
         | 
| 645 | 
            +
                  @db.close
         | 
| 646 | 
            +
                end
         | 
| 647 | 
            +
                it "validates output" do
         | 
| 648 | 
            +
                  Marty::ApiConfig.create!(script: "M4",
         | 
| 649 | 
            +
                                           node: "A",
         | 
| 650 | 
            +
                                           attr: nil,
         | 
| 651 | 
            +
                                           logged: false,
         | 
| 652 | 
            +
                                           input_validated: true,
         | 
| 653 | 
            +
                                           output_validated: true)
         | 
| 654 | 
            +
                  attrs = ["d", "g", "result"].to_json
         | 
| 655 | 
            +
                  params = {"p" => 132, "e" => 55, "f"=>16}.to_json
         | 
| 656 | 
            +
                  get 'evaluate', {
         | 
| 657 | 
            +
                        format: :json,
         | 
| 658 | 
            +
                        script: "M4",
         | 
| 659 | 
            +
                        node: "A",
         | 
| 660 | 
            +
                        attrs: attrs,
         | 
| 661 | 
            +
                        params: params
         | 
| 662 | 
            +
                      }
         | 
| 663 | 
            +
                  res_hash = JSON.parse(response.body)
         | 
| 664 | 
            +
                  expect(res_hash).to eq([135,291,[{"a"=>132,"b"=>456},
         | 
| 665 | 
            +
                                                   {"a"=>789,"b"=>132}]])
         | 
| 666 | 
            +
                  logs = Marty::Log.where("id > #{@logid}").to_a
         | 
| 667 | 
            +
                  expect(logs.count).to eq(0)
         | 
| 668 | 
            +
                end
         | 
| 669 | 
            +
             | 
| 670 | 
            +
                it "validates output (bad type, with strict/non strict errors)" do
         | 
| 671 | 
            +
                  Marty::ApiConfig.create!(script: "M5",
         | 
| 672 | 
            +
                                           node: "A",
         | 
| 673 | 
            +
                                           attr: nil,
         | 
| 674 | 
            +
                                           logged: false,
         | 
| 675 | 
            +
                                           input_validated: true,
         | 
| 676 | 
            +
                                           output_validated: true,
         | 
| 677 | 
            +
                                           strict_validate: true)
         | 
| 678 | 
            +
                  Marty::ApiConfig.create!(script: "M5",
         | 
| 679 | 
            +
                                           node: "A",
         | 
| 680 | 
            +
                                           attr: "result2",
         | 
| 681 | 
            +
                                           logged: false,
         | 
| 682 | 
            +
                                           input_validated: true,
         | 
| 683 | 
            +
                                           output_validated: true,
         | 
| 684 | 
            +
                                           strict_validate: false)
         | 
| 685 | 
            +
                  attrs = ["result", "result2"].to_json
         | 
| 686 | 
            +
                  params = {"f" => "Banana"}.to_json
         | 
| 687 | 
            +
                  get 'evaluate', {
         | 
| 688 | 
            +
                        format: :json,
         | 
| 689 | 
            +
                        script: "M5",
         | 
| 690 | 
            +
                        node: "A",
         | 
| 691 | 
            +
                        attrs: attrs,
         | 
| 692 | 
            +
                        params: params
         | 
| 693 | 
            +
                      }
         | 
| 694 | 
            +
                  res_hash = JSON.parse(response.body)
         | 
| 695 | 
            +
                  expect(res_hash[0]).to include("error")
         | 
| 696 | 
            +
                  expect1 = "The property '#/0/b' of type integer did not match the "\
         | 
| 697 | 
            +
                           "following type: string"
         | 
| 698 | 
            +
                  expect2 = "The property '#/0/a' of type string did not match the "\
         | 
| 699 | 
            +
                            "following type: integer"
         | 
| 700 | 
            +
                  expect(res_hash[0]["error"]).to include(expect1)
         | 
| 701 | 
            +
                  expect(res_hash[0]["error"]).to include(expect2)
         | 
| 702 | 
            +
             | 
| 703 | 
            +
                  logs = Marty::Log.where("id > #{@logid}").to_a
         | 
| 704 | 
            +
                  expect(logs.count).to eq(2)
         | 
| 705 | 
            +
                  expect(logs[0].message).to eq("API M5:A.result")
         | 
| 706 | 
            +
                  expect(logs[1].message).to eq("API M5:A.result2")
         | 
| 707 | 
            +
                  logs.each do |ml|
         | 
| 708 | 
            +
                    expect(ml.details).to include(expect1)
         | 
| 709 | 
            +
                    expect(ml.details).to include(expect2)
         | 
| 710 | 
            +
                    expect(ml.details).to include(
         | 
| 711 | 
            +
                     ":data=>[{\"a\"=>\"str\", \"b\"=>456}, {\"a\"=>789, \"b\"=>\"str\"}]}")
         | 
| 712 | 
            +
                  end
         | 
| 713 | 
            +
                end
         | 
| 714 | 
            +
             | 
| 715 | 
            +
                it "validates output (missing item)" do
         | 
| 716 | 
            +
                  logid = @db.execute('select max(id) from log').first.first rescue 0
         | 
| 717 | 
            +
                  Marty::ApiConfig.create!(script: "M9",
         | 
| 718 | 
            +
                                           node: "A",
         | 
| 719 | 
            +
                                           attr: nil,
         | 
| 720 | 
            +
                                           logged: false,
         | 
| 721 | 
            +
                                           input_validated: true,
         | 
| 722 | 
            +
                                           output_validated: true,
         | 
| 723 | 
            +
                                           strict_validate: true)
         | 
| 724 | 
            +
                  attrs = ["result"].to_json
         | 
| 725 | 
            +
                  params = {"b" => 122}.to_json
         | 
| 726 | 
            +
                  get 'evaluate', {
         | 
| 727 | 
            +
                        format: :json,
         | 
| 728 | 
            +
                        script: "M9",
         | 
| 729 | 
            +
                        node: "A",
         | 
| 730 | 
            +
                        attrs: attrs,
         | 
| 731 | 
            +
                        params: params
         | 
| 732 | 
            +
                      }
         | 
| 733 | 
            +
                  res_hash = JSON.parse(response.body)
         | 
| 734 | 
            +
                  expect(res_hash[0]).to include("error")
         | 
| 735 | 
            +
                  expect1 = "The property '#/0' did not contain a required property of 'c'"
         | 
| 736 | 
            +
                  expect2 = "The property '#/1' did not contain a required property of 'c'"
         | 
| 737 | 
            +
                  expect(res_hash[0]["error"]).to include(expect1)
         | 
| 738 | 
            +
                  expect(res_hash[0]["error"]).to include(expect2)
         | 
| 739 | 
            +
             | 
| 740 | 
            +
                  logs = Marty::Log.where("id > #{@logid}").to_a
         | 
| 741 | 
            +
                  expect(logs.count).to eq(1)
         | 
| 742 | 
            +
                  expect(logs[0].message).to eq("API M9:A.result")
         | 
| 743 | 
            +
                  expect(logs[0].details).to include(expect1)
         | 
| 744 | 
            +
                  expect(logs[0].details).to include(expect2)
         | 
| 745 | 
            +
                  expect(logs[0].details).to include(
         | 
| 746 | 
            +
                     ":data=>[{\"a\"=>1, \"b\"=>123}, {\"a\"=>789, \"b\"=>123}]")
         | 
| 747 | 
            +
                end
         | 
| 748 | 
            +
              end
         | 
| 749 | 
            +
             | 
| 546 750 | 
             
              it "validates schema" do
         | 
| 547 751 | 
             
                Marty::ApiConfig.create!(script: "M4",
         | 
| 548 752 | 
             
                                         node: "A",
         | 
| 549 753 | 
             
                                         attr: nil,
         | 
| 550 754 | 
             
                                         logged: false,
         | 
| 551 | 
            -
                                          | 
| 755 | 
            +
                                         input_validated: true)
         | 
| 552 756 | 
             
                attrs = ["lc"].to_json
         | 
| 553 757 | 
             
                params = {"p" => 5}.to_json
         | 
| 554 758 | 
             
                get 'evaluate', {
         | 
| @@ -566,7 +770,7 @@ describe Marty::RpcController do | |
| 566 770 | 
             
                                         node: "A",
         | 
| 567 771 | 
             
                                         attr: nil,
         | 
| 568 772 | 
             
                                         logged: false,
         | 
| 569 | 
            -
                                          | 
| 773 | 
            +
                                         input_validated: true)
         | 
| 570 774 | 
             
                attrs = ["res"].to_json
         | 
| 571 775 | 
             
                params = {"b" => 5.22}.to_json
         | 
| 572 776 | 
             
                get 'evaluate', {
         | 
| @@ -576,7 +780,7 @@ describe Marty::RpcController do | |
| 576 780 | 
             
                  attrs: attrs,
         | 
| 577 781 | 
             
                  params: params
         | 
| 578 782 | 
             
                }
         | 
| 579 | 
            -
                expect = 'The property \'#/properties/b/type\' of type string '\
         | 
| 783 | 
            +
                expect = 'res: The property \'#/properties/b/type\' of type string '\
         | 
| 580 784 | 
             
                         'did not match one or more of the required schemas'
         | 
| 581 785 | 
             
                res_hsh = JSON.parse(response.body)
         | 
| 582 786 | 
             
                expect(res_hsh.keys.size).to eq(1)
         | 
| @@ -594,7 +798,7 @@ describe Marty::RpcController do | |
| 594 798 | 
             
                                         node: "A",
         | 
| 595 799 | 
             
                                         attr: nil,
         | 
| 596 800 | 
             
                                         logged: false,
         | 
| 597 | 
            -
                                          | 
| 801 | 
            +
                                         input_validated: true)
         | 
| 598 802 | 
             
                attrs = ["res"].to_json
         | 
| 599 803 | 
             
                params = {"f" => "Banana"}.to_json
         | 
| 600 804 | 
             
                get 'evaluate', {
         | 
| @@ -612,7 +816,7 @@ describe Marty::RpcController do | |
| 612 816 | 
             
                                         node: "A",
         | 
| 613 817 | 
             
                                         attr: nil,
         | 
| 614 818 | 
             
                                         logged: false,
         | 
| 615 | 
            -
                                          | 
| 819 | 
            +
                                         input_validated: true)
         | 
| 616 820 | 
             
                attrs = ["res"].to_json
         | 
| 617 821 | 
             
                params = {"f" => "Beans"}.to_json
         | 
| 618 822 | 
             
                get 'evaluate', {
         | 
| @@ -631,7 +835,7 @@ describe Marty::RpcController do | |
| 631 835 | 
             
                                         node: "A",
         | 
| 632 836 | 
             
                                         attr: nil,
         | 
| 633 837 | 
             
                                         logged: false,
         | 
| 634 | 
            -
                                          | 
| 838 | 
            +
                                         input_validated: true)
         | 
| 635 839 | 
             
                attrs = ["res"].to_json
         | 
| 636 840 | 
             
                params = {"b" => "MemberOfANonExistantEnum"}.to_json
         | 
| 637 841 | 
             
                get 'evaluate', {
         | 
| @@ -653,7 +857,7 @@ describe Marty::RpcController do | |
| 653 857 | 
             
                                         node: "A",
         | 
| 654 858 | 
             
                                         attr: nil,
         | 
| 655 859 | 
             
                                         logged: false,
         | 
| 656 | 
            -
                                          | 
| 860 | 
            +
                                         input_validated: true)
         | 
| 657 861 | 
             
                skip "pending until a solution is found that handles "\
         | 
| 658 862 | 
             
                     "autoload issues involving constantize"
         | 
| 659 863 | 
             
                attrs = ["res"].to_json
         | 
| @@ -1 +1 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            spec/dummy/public/images/../extjs/icons/
         | 
| @@ -1 +1 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            spec/dummy/spec/features/../../../features/javascripts/
         | 
| @@ -18,6 +18,7 @@ feature 'logger view', js: true, capybara: true do | |
| 18 18 | 
             
              before(:all) do
         | 
| 19 19 | 
             
                self.use_transactional_fixtures = false
         | 
| 20 20 | 
             
                @db =  SQLite3::Database.new(Marty::Log.logfile)
         | 
| 21 | 
            +
                @db.execute("delete from log")
         | 
| 21 22 |  | 
| 22 23 | 
             
                info_s = { info: 'message' }
         | 
| 23 24 | 
             
                error_s = [1, 2, 3, { error: 'message' }]
         | 
    
        data/spec/lib/logger_spec.rb
    CHANGED
    
    | @@ -8,9 +8,9 @@ module Marty | |
| 8 8 | 
             
                end
         | 
| 9 9 | 
             
                before(:each) do
         | 
| 10 10 | 
             
                  @db =  SQLite3::Database.new(Marty::Log.logfile)
         | 
| 11 | 
            +
                  @db.execute "delete from log"
         | 
| 11 12 | 
             
                end
         | 
| 12 13 | 
             
                after(:each) do
         | 
| 13 | 
            -
                  @db.execute "delete from log"
         | 
| 14 14 | 
             
                  @db.close
         | 
| 15 15 | 
             
                end
         | 
| 16 16 | 
             
                after(:all) do
         | 
| @@ -104,6 +104,7 @@ module Marty | |
| 104 104 | 
             
                  save_clean_db(@clean_file)
         | 
| 105 105 | 
             
                  # transactional fixtures interfere with queueing jobs
         | 
| 106 106 | 
             
                  self.use_transactional_fixtures = false
         | 
| 107 | 
            +
                  Marty::Log.cleanup(0)
         | 
| 107 108 |  | 
| 108 109 | 
             
                  # Needed here because shutting transactional fixtures off
         | 
| 109 110 | 
             
                  # means we lose the globally set user
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: marty
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0. | 
| 4 | 
            +
              version: 1.0.36
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Arman Bostani
         | 
| @@ -14,7 +14,7 @@ authors: | |
| 14 14 | 
             
            autorequire: 
         | 
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 | 
            -
            date: 2017- | 
| 17 | 
            +
            date: 2017-09-11 00:00:00.000000000 Z
         | 
| 18 18 | 
             
            dependencies:
         | 
| 19 19 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 20 20 | 
             
              name: pg
         | 
| @@ -475,6 +475,7 @@ files: | |
| 475 475 | 
             
            - db/migrate/202_add_completion_status_to_event.rb
         | 
| 476 476 | 
             
            - db/migrate/300_create_marty_api_configs.rb
         | 
| 477 477 | 
             
            - db/migrate/301_create_marty_api_log.rb
         | 
| 478 | 
            +
            - db/migrate/302_add_api_configs_validate_result.rb
         | 
| 478 479 | 
             
            - db/seeds.rb
         | 
| 479 480 | 
             
            - delorean/script_report.dl
         | 
| 480 481 | 
             
            - gemini_deprecations.md
         | 
| @@ -1650,7 +1651,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 1650 1651 | 
             
                  version: '0'
         | 
| 1651 1652 | 
             
            requirements: []
         | 
| 1652 1653 | 
             
            rubyforge_project: 
         | 
| 1653 | 
            -
            rubygems_version: 2. | 
| 1654 | 
            +
            rubygems_version: 2.6.13
         | 
| 1654 1655 | 
             
            signing_key: 
         | 
| 1655 1656 | 
             
            specification_version: 4
         | 
| 1656 1657 | 
             
            summary: A framework for working with versioned data
         |