I'm working on a pure Ruby application where I'm trying to create a Rake task. I have a method in the file src/lambda_function.rb that is as follows:
def self.process(event:, context: nil, box_api: BoxApi.new, form: nil, sns: SNS.new, kms: KMS.new)
begin
# verify request came from fromstack from headers
verify_webhook_req(event)
# parse data
submission = JSON.parse(event["body"])
form_id = submission.fetch("FormID").strip()
submission_id = submission.fetch("UniqueID").strip()
As you can see from the above snippet the function takes in the following parameters:
event:, context:, box_api:, form:, sns:, kms: So in the rake task I pass the following:
require './src/lambda_function.rb'
require 'rake'
require 'pry'
include Rake::DSL
class KMS
def initialize
end
def decrypt(key)
return 'some password'
end
end
class SNS
def initialize
end
end
namespace :test do
namespace :lambda do
desc 'Run the Lambda process function'
task :process do
TEST_FORM_ID=3353951
LambdaFunctions::LambdaHandler.process(box_api: BoxApi.new,
form: TEST_FORM_ID,
sns: SNS.new,
kms: KMS.new)
end
end
end
But calling this rake task throws an error:
rake aborted!
ArgumentError: unknown keywords: box_api, form
How come it doesn't recognize form and box_api. At first, I thought that maybe I was missing a hash to pass in the arguments. {box_api: BoxApi.new, form: ....}` this didn't work either.
Why is throwing the error?
I was calling a method in a different class which had different parameters.
class WebhookHandler
def self.process(event:, context: nil, box_api: BoxApi.new, form: nil, sns: SNS.new, kms: KMS.new)
begin
# verify request came from fromstack from headers
verify_webhook_req(event)
Related
This question probably has a simple answer but I can't find any examples for using Roda with RSpec3, so it is difficult to troubleshoot.
I am using Marston and Dees "Effective Testing w/ RSpec3" book which uses Sinatra instead of Roda. I am having difficulty passing an object to API.new, and, from the book, this is what works with Sinatra but fails with a "wrong number of arguments" error when I substitute Roda.
Depending on whether I pass arguments with super or no arguments with super(), the error switches to indicate that the failure occurs either at the initialize method or in the call to Rack::Test::Methods post in the spec.
I see that in Rack::Test, in the Github repo README, I may have to use Rack::Builder.parse_file("config.ru") but that didn't help.
Here are the two errors that rspec shows when using super without brackets:
Failures:
1) MbrTrak::API POST /users when the user is successfully recorded returns the user id
Failure/Error: post '/users', JSON.generate(user)
ArgumentError:
wrong number of arguments (given 1, expected 0)
# ./spec/unit/app/api_spec.rb:21:in `block (4 levels) in <module:MbrTrak>'
And when using super():
1) MbrTrak::API POST /users when the user is successfully recorded returns the user id
Failure/Error: super()
ArgumentError:
wrong number of arguments (given 0, expected 1)
# ./app/api.rb:8:in `initialize'
# ./spec/unit/app/api_spec.rb:10:in `new'
# ./spec/unit/app/api_spec.rb:10:in `app'
# ./spec/unit/app/api_spec.rb:21:in `block (4 levels) in <module:MbrTrak>'
This is my api_spec.rb:
require_relative '../../../app/api'
require 'rack/test'
module MbrTrak
RecordResult = Struct.new(:success?, :expense_id, :error_message)
RSpec.describe API do
include Rack::Test::Methods
def app
API.new(directory: directory)
end
let(:directory) { instance_double('MbrTrak::Directory')}
describe 'POST /users' do
context 'when the user is successfully recorded' do
it 'returns the user id' do
user = { 'some' => 'user' }
allow(directory).to receive(:record)
.with(user)
.and_return(RecordResult.new(true, 417, nil))
post '/users', JSON.generate(user)
parsed = JSON.parse(last_response.body)
expect(parsed).to include('user_id' => 417)
end
end
end
end
end
And here is my api.rb file:
require 'roda'
require 'json'
module MbrTrak
class API < Roda
def initialize(directory: Directory.new)
#directory = directory
super()
end
plugin :render, escape: true
plugin :json
route do |r|
r.on "users" do
r.is Integer do |id|
r.get do
JSON.generate([])
end
end
r.post do
user = JSON.parse(request.body.read)
result = #directory.record(user)
JSON.generate('user_id' => result.user_id)
end
end
end
end
end
My config.ru is:
require "./app/api"
run MbrTrak::API
Well roda has defined initialize method that receives env as an argument which is being called by the app method of the class. Looks atm like this
def self.app
...
lambda{|env| new(env)._roda_handle_main_route}
...
end
And the constructor of the app looks like this
def initialize(env)
When you run your config.ru with run MbrTrack::API you are actually invoking the call method of the roda class which looks like this
def self.call(env)
app.call(env)
end
Because you have redefined the constructor to accept hash positional argument this no longer works and it throws the error you are receiving
ArgumentError:
wrong number of arguments (given 0, expected 1)
Now what problem are you trying to solve, if you want to make your API class configurable one way to go is to try out dry-configurable which is part of the great dry-ruby gem collection.
If you want to do something else feel free to ask.
It has been a long time since you posted your question so hope you will still find this helpful.
When I run rails c, I can call the following class and the method works:
test = SlackService::BoardGameNotifier
test.create_alert("test")
>>method works
I'm trying to set this up in rspec like this:
require 'spec_helper'
require 'slack-notifier'
RSpec.describe SlackService::BoardGameNotifier do
describe '#notify' do
#notifier = SlackService::BoardGameNotifier
it 'pings Slack' do
error = nil
message = "test"
expect(notifier).to receive(:ping).with(message)
notifier.send_message()
end
end
end
But I keep getting the error:
NameError:
uninitialized constant SlackService
Does this have to do with how I set up the module?
My current setup:
slack_service/board_game_notifier.rb
module SlackService
class BoardGameNotifier < BaseNotifier
WEBHOOK_URL = Rails.configuration.x.slack.url
DEFAULT_OPTIONS = {
channel: "board-games-channel",
text: "board games alert",
username: "bot",
}
def create_alert(message)
message #testing
end
end
end
slack_service/base_notifier.rb
module SlackService
class BaseNotifier
include Singleton
def initialize
webhook_url = self.class::WEBHOOK_URL
options = self.class::DEFAULT_OPTIONS
#notifier = Slack::Notifier.new(webhook_url, options)
end
def self.send_message
message = instance.create_alert("test")
instance.notify(message)
end
def notify(message)
#notifier.post blocks: message
end
end
end
Add this to your spec_helper.rb
# spec_helper.rb
ENV["RAILS_ENV"] ||= "test"
require File.expand_path("../config/environment", __dir__)
When running RSpec, Rails doesn't automatically boot up, and therefore doesn't automatically load all the libraries.
Also, I'd suggest creating a .rspec in your app's root folder with the following lines so that spec_helper is automatically loaded for all your RSpec tests:
# .rspec
--format documentation
--color
--require spec_helper
I would use the described_class from Rspec
require 'spec_helper'
require 'slack-notifier'
RSpec.describe ::SlackService::BoardGameNotifier do
describe '#notify' do
it 'pings Slack' do
error = nil
message = "test"
expect(described_class).to receive(:ping).with(message)
notifier.send_message()
end
end
end
I'm currently trying to run a Rake task in a Ruby project (No Rails). What I am trying to accomplish is to run a method from a file within my Ruby project. However I get the following error:
undefined method `namespace' for main:Object (NoMethodError)
I created a folder task that holds a test.rb file. Before I had it as test.rake but I think this was incorrect. I also created a Rakefile pointing to task/test.rb
For redeability, I'm using namespace: although I'll be honest I'm not sure if I even need it.
#Rakefile
task :default => [:test]
task :test do
ruby 'task/test.rb'
end
Here is the task.test.rb
require './src/lambda_function.rb'
class KMS
def initialize
end
def decrypt(key)
return "some password"
end
end
class SNS
def initialize
end
end
TEST_FORM_ID=123
namespace :test do
namespace :lambda do
desc 'Run the Lambda process function'
task :process do
LambdaFunctions::LambdaHandler.process(box_api: BoxApi.new,
form: TEST_FORM_ID,
sns: SNS.new,
kms: KMS.new)
end
end
end
What I'm I doing wrong?
I have the below Fluentd plugin code:
require 'avro'
module Fluent
module TextFormatter
class Sample
end
class AvroFormatter < Formatter
Fluent::Plugin.register_formatter('avro', self)
config_param :schema_file, :string, :default => nil
config_param :schema_json, :string, :default => nil
def configure(conf)
super
if not (#schema_json.nil? ^ #schema_file.nil?) then
raise Fluent::ConfigError, 'schema_json or schema_file (but not both) is required'
end
if #schema_json.nil? then
#schema_json = File.read(#schema_file)
end
#schema = Avro::Schema.parse(#schema_json)
end
def format(tag, time, record)
handler = Sample.new()
end
end
end
end
And I need to instance the class "Sample" in the def "Format". The problem is that when I try to do a http POST against Fluentd the below error appears:
failed: error_class=NoMethodError error="undefined method `bytesize'
This error only appears when the class "Sample" is instanced. I'm new with ruby, and I don't know where is the problem. Should I create the class "Sample" in another file?
I think you're getting this error because code, that calls format expects string result, but instead it gets an instance of Sample class. Try to return some string instead.
You can also use this example here: http://docs.fluentd.org/articles/plugin-development#text-formatter-plugins.
I am unable to send emails. i have already tried the following:
Converting type of handler from text to long text does'nt work as i am using postgres.
I have also tried restarting my workers and delayed jobs
and my delayed job is version is 3.0.1.
I am having problem on the line:
Notifier.delay.delivery_alert(u)
and my delivery_alert method is
def delivery_alert(user)
#user = user
#deliveries = #user.issues.includes(:copy => [:rentable]).current.by_last_status("to_be_delivered").map(&:copy).map(&:rentable)
#returns = #user.issues.includes(:copy => [:rentable]).current.by_last_status("marked_for_return").map(&:copy).map(&:rentable)
mail(:to => #user.email)
end
While on localhost i am getting the error:
[Worker(host:ubuntu pid:12169)] Class#delivery_alert failed with NoMethodError: undefined method `delivery_alert' for # - 5 failed attempts
for which i have added a patch in my lib folder
require 'yaml'
module Delayed
module Backend
module Base
def payload_object
YAML::ENGINE.yamler = 'psych'
#payload_object ||= YAML.load(self.handler)
rescue TypeError, LoadError, NameError, ArgumentError => e
raise DeserializationError,
"Job failed to load: #{e.message}. Handler: #{handler.inspect}"
end
end
end
class PerformableMailer
def perform
double = object.is_a?( String ) ? object.constantize : object
double.send(method_name, *args).deliver
end
end
end
by taking reference of
https://gist.github.com/oelmekki/2181381
but still my email are not going. Thanks in advance?