Passing BSON directly to MongoDB using the mong-ruby-driver? - ruby

Is there a way to pass a BSON object directly into the .find() in the mongo-ruby-driver?
At the moment I have a basic sinatra app that takes URL encoded JSON and parses it into the .find() but I would ideally like to give it straight BSON:
require 'sinatra'
require 'mongo'
require 'json'
include Mongo
db = MongoClient.new().db('test')
get '/' do
if request[:query]
query = JSON.parse(CGI::unescape(request[:query]))
db.collection('test_collection').find(query).to_a.to_json
end
end
So essentially have something along the lines of BSON.parse(url-encoded-query) and be able to pass that into a .find() returning the result.
Example URL: http://localhost:4567/?query=%7B%20%22name%22%20%3A%20%22john%20doe%22%20%7D
Current query: { "name" : "john doe" }
BSON query: { name: /.*john.*/, interests: [ 'fishing', 'golf' ]} that I'd like to work

The following test script demonstrates how to use the $elemMatch operator as a projection. Please note that the Collection#find method takes arbitrary documents for both the "selector" formal parameter and for the "opts" :fields option.
MongoDB documents are mapped to/from Ruby Hash objects, and these documents can fully incorporate MongoDB operators.
elemmatch_projection.rb
#!/usr/bin/env ruby
# Ruby translation of example from http://docs.mongodb.org/manual/reference/projection/elemMatch/
require 'mongo'
coll = Mongo::MongoClient.new['test']['students']
coll.remove
coll.insert({
zipcode: 63109,
dependents: [
{ name: "john", school: 102, age: 10 },
{ name: "jess", school: 102, age: 11 },
{ name: "jeff", school: 108, age: 15 }
]
})
p coll.find( { zipcode: 63109 }, :fields => { dependents: { '$elemMatch' => { school: 102 } } } ).to_a
ruby elemmatch_projection.rb
[{"_id"=>BSON::ObjectId('50eab29929daeb05ae000001'), "dependents"=>[{"name"=>"john", "school"=>102, "age"=>10}]}]
This is another answer because the question has been significantly clarified by the OP.
Hope that this helps you understand how to use MongoDB documents and operators in Ruby.

Your issue has more to do with parsing JSON or Ruby (Regexp) than with BSON. Your original question causes confusion by jumping directly to BSON. With the current Ruby driver, BSON is not directly exposed to the application writer, but mapped as naturally as possible from and to Ruby objects.
JSON is strictly limited and safe for parsing. Adding parsing for Regexp moves beyond this.
You can do what you want unsafely using Kernel#eval. This will parse your Regexp, but it will also parse exec, system, backticks, etc. For a public application with arbitrary user input, you will have to do something safer.
Also note, the differences between the following lines, which highlights semantics with both Ruby and MongoDB:
{ interests: [ 'fishing', 'golf' ] }
The above exactly matches interests iff they are exactly [ 'fishing', 'golf' ]. no more, no less, no other order.
{ interests: { '$in' => [ 'fishing', 'golf' ] } }
The above matches interests if interests have either 'fishing' or 'golf', any order, any position, any extras. Note that the string key '$in' requires the original => syntax.
Hope that this helps your understanding, and please feel free to followup with clarifying questions.
The following is a working example.
myapp.rb
require 'sinatra'
require 'mongo'
require 'json'
include Mongo
db = MongoClient.new().db('test')
get '/' do
if request[:query]
query = eval CGI::unescape(request[:query])
docs = db.collection('test_collection').find(query).to_a.to_json
"docs=#{docs}"
end
end
myapp_test.rb
require 'myapp'
require 'test/unit'
require 'rack/test'
require 'open-uri'
ENV['RACK_ENV'] = 'test'
class MyAppTest < Test::Unit::TestCase
include Rack::Test::Methods
def setup
#db ||= Mongo::MongoClient.new['test']
#coll ||= #db['test_collection']
#coll.remove
#coll.insert({name: 'john doe', interests: [ 'fishing', 'golf' ]})
end
def app
Sinatra::Application
end
def query_test(query)
uri = "http://localhost:4567/?query=#{URI::encode(query)}"
puts "uri=#{uri}"
get uri
puts last_response.body
assert_match(/^docs=/, last_response.body)
end
def test_john_doe
query_test("{ name: 'john doe'}")
end
def test_regexp
query_test("{ name: /.*john.*/, interests: [ 'fishing', 'golf' ]}")
end
end
ruby -I. myapp_test.rb
Run options:
# Running tests:
uri=http://localhost:4567/?query=%7B%20name:%20/.*john.*/,%20interests:%20[%20'fishing',%20'golf'%20]%7D
docs=[{"_id":{"$oid": "50e9e60029daeb0be1000001"},"name":"john doe","interests":["fishing","golf"]}]
.uri=http://localhost:4567/?query=%7B%20name:%20'john%20doe'%7D
docs=[{"_id":{"$oid": "50e9e60129daeb0be1000002"},"name":"john doe","interests":["fishing","golf"]}]
.
Finished tests in 0.065822s, 30.3850 tests/s, 60.7700 assertions/s.
2 tests, 4 assertions, 0 failures, 0 errors, 0 skips

Related

Prepend/append to cucumber scenario name/feature name or tags at runtime

When running cucumber suite for different viewports desktop/mobile, I'd like to prepend ENV['VIEWPORT'] value to either Feature name or Scenario name at runtime so I can see in the HTML report the viewport for which the scenario failed. I am generating a unified HTML report my merging all viewport reports. Each scenario can run on any platform based on the ENV flag above so tagging scenarios by viewport is not necessary
You need to implement some custom formatters for your custom formats.
https://github.com/cucumber/cucumber/wiki/Custom-Formatters
Then, similar to https://github.com/moredip/timestamped-scenarios, assuming the cucumber 2.4.0 version and bundler are used:
Formatter
# features/support/viewport_aware/adds_viewport.rb
require 'rubygems'
module ViewportAware
module AddsViewport
def self.formatter_with_viewport(formatter_class)
Class.new( formatter_class ){ include AddsViewport }
end
def scenario_name(keyword, name, file_colon_line, source_indent)
super(keyword, with_viewport(name), file_colon_line, source_indent)
end
def feature_name(keyword, name)
super(with_viewport(keyword), name)
end
# for json formatter
def on_finished_testing(event)
#feature_hashes.each do |it|
it[:name] = with_viewport(it[:name])
(it[:elements] || []).each do |el|
el[:name] = with_viewport(el[:name])
end
end
super
end
private
def with_viewport(str)
"#{str} <<#{ENV['VIEWPORT']}>>"
end
end
end
Pretty Formatter
# features/support/viewport_aware/pretty_formatter.rb
require 'cucumber/formatter/pretty'
module ViewportAware
PrettyFormatter = AddsViewport.formatter_with_viewport(Cucumber::Formatter::Pretty)
end
HTML Formatter
# features/support/viewport_aware/html_formatter.rb
require 'cucumber/formatter/html'
module ViewportAware
HtmlFormatter = AddsViewport.formatter_with_viewport(Cucumber::Formatter::Html)
end
JSON Formatter
# features/support/viewport_aware/json_formatter.rb
require 'cucumber/formatter/json'
module ViewportAware
JsonFormatter = AddsViewport.formatter_with_viewport(Cucumber::Formatter::Json)
end
Then run:
VIEWPORT=mobile bundle exec cucumber -f ViewportAware::PrettyFormatter
or
VIEWPORT=mobile bundle exec cucumber -f ViewportAware::HtmlFormatter
or
VIEWPORT=mobile bundle exec cucumber -f ViewportAware::JsonFormatter
As a result of pretty format:
Feature <<mobile>>: Create a boat
In order to avoid mistakes when finding my boat
As a sailor of my boat
I want to be told the details of my boat
Scenario: Creating a new boat <<mobile>>
<skimmed>
or JSON Formatter:
[
{
"uri": "features/add.feature",
"id": "create-a-boat",
"keyword": "Feature",
"name": "Create a boat <<mobile>>",
"description": " In order to avoid mistakes when finding my boat\n As a sailor of my boat\n I want to be told the details of my boat",
"line": 1,
"elements": [
{
"id": "create-a-boat;creating-a-new-boat",
"keyword": "Scenario",
"name": "Creating a new boat <<mobile>>",

Difficulty processing json with ruby

I have the following json...
{
"NumPages":"17",
"Page":"1",
"PageSize":"50",
"Total":"808",
"Start":"1",
"End":"50",
"FirstPageUri":"/v3/results?PAGE=1",
"LastPageUri":"/v3/results?PAGE=17",
"PreviousPageUri":"",
"NextPageUri":"/v3/results?PAGE=2",
"User":[
{
"RowNumber":"1",
"UserId":"86938",
"InternalId":"",
"CompletionPercentage":"100",
"DateTimeTaken":"2014-06-18T01:43:25Z",
"DateTimeLastUpdated":"2014-06-18T01:58:11Z",
"DateTimeCompleted":"2014-06-18T01:58:11Z",
"Account":{
"Id":"655",
"Name":"Technical Community College"
},
"FirstName":"Matthew",
"LastName":"Knice",
"EmailAddress":"knice#gmail.com",
"AssessmentResults":[
{
"Title":"Life Factors",
"Code":"LifeFactors",
"IsComplete":"1",
"AttemptNumber":"1",
"Percent":"58",
"Readiness":"fail",
"DateTimeCompleted":"2014-06-18T01:46:00Z"
},
{
"Title":"Learning Styles",
"Code":"LearnStyles",
"IsComplete":"0"
},
{
"Title":"Personal Attributes",
"Code":"PersonalAttributes",
"IsComplete":"1",
"AttemptNumber":"1",
"Percent":"52.08",
"Readiness":"fail",
"DateTimeCompleted":"2014-06-18T01:49:00Z"
},
{
"Title":"Technical Competency",
"Code":"TechComp",
"IsComplete":"1",
"AttemptNumber":"1",
"Percent":"100",
"Readiness":"pass",
"DateTimeCompleted":"2014-06-18T01:51:00Z"
},
{
"Title":"Technical Knowledge",
"Code":"TechKnowledge",
"IsComplete":"1",
"AttemptNumber":"1",
"Percent":"73.44",
"Readiness":"question",
"DateTimeCompleted":"2014-06-18T01:58:00Z"
},
{
"Title":"Reading Rate & Recall",
"Code":"Reading",
"IsComplete":"0"
},
{
"Title":"Typing Speed & Accuracy",
"Code":"Typing",
"IsComplete":"0"
}
]
},
{
"RowNumber":"2",
"UserId":"8654723",
"InternalId":"",
"CompletionPercentage":"100",
"DateTimeTaken":"2014-06-13T14:37:59Z",
"DateTimeLastUpdated":"2014-06-13T15:00:12Z",
"DateTimeCompleted":"2014-06-13T15:00:12Z",
"Account":{
"Id":"655",
"Name":"Technical Community College"
},
"FirstName":"Virginia",
"LastName":"Bustas",
"EmailAddress":"bigBusta#students.college.edu",
"AssessmentResults":[
{
...
I need to start processing where you see "User:" The stuff at the beginning (numpages, page, ect) I want to ignore. Here is the processing script I am working on...
require 'csv'
require 'json'
CSV.open("your_csv.csv", "w") do |csv| #open new file for write
JSON.parse(File.open("sample.json").read).each do |hash| #open json to parse
csv << hash.values
end
end
Right now this fails with the error:
convert.rb:6:in `block (2 levels) in <main>': undefined method `values' for ["NumPages", "17"]:Array (NoMethodError)
I have ran the json through a parser, and it seems to be valid. What is the best way to only process the "User" data?
You have to look at the structure of the JSON object being created. Here's a very small subset of your document being parsed, which makes it easier to see and understand:
require 'json'
foo = '{"NumPages":17,"User":[{"UserId":12345}]}'
bar = JSON[foo]
# => {"NumPages"=>17, "User"=>[{"UserId"=>12345}]}
bar['User'].first['UserId'] # => 12345
foo contains the JSON for a hash. bar contains the Ruby object created by the JSON parser after it reads foo.
User is the key pointing to an array of hashes. Because it's an array, you have to specify which of the hashes in the array you want to look at, which is what bar['User'].first does.
An alternate way to access that sub-hash is:
bar['User'][0]['UserId'] # => 12345
If there were multiple hashes inside the array, you could access them by using the appropriate index value. For example, if there are two hashes, and I want the second one:
foo = '{"NumPages":17,"User":[{"UserId":12345},{"UserId":12346}]}'
bar = JSON[foo]
# => {"NumPages"=>17, "User"=>[{"UserId"=>12345}, {"UserId"=>12346}]}
bar['User'].first['UserId'] # => 12345
bar['User'][0]['UserId'] # => 12345
bar['User'][1]['UserId'] # => 12346
I'm wondering if I am going down the wrong road with the JSON.parse(File.open("sample.json").read).each do |hash|?
Yes, you are. You need to understand what you're doing, and break your code into digestible pieces so they make sense to you. Consider this:
require 'csv'
require 'json'
json_object = JSON.parse(File.read("sample.json"))
CSV.open("your_csv.csv", "w") do |csv| #open new file for write
csv << %w[RowNumber UserID AccountID AccountName FirstName LastName EmailAddress]
json_object['User'].each do |user_hash|
puts 'RowNumber: %s' % user_hash['RowNumber']
puts 'UserID: %s' % user_hash['UserID']
account = user_hash['UserID']['Account']
puts 'Account->Id: %s' % account['Id']
puts 'Account->Name: %s' % account['Name']
puts 'FirstName: %s' % user_hash['FirstName']
puts 'LastName: %s' % user_hash['LastName']
puts 'EmailAddress: %s' % user_hash['EmailAddress']
csv << [
user_hash['RowNumber'],
user_hash['UserID'],
account['Id'],
account['Name'],
user_hash['FirstName'],
user_hash['LastName'],
user_hash['EmailAddress']
]
end
end
This reads the JSON file and parses it into a Ruby object immediately. There is no special magic or anything else that happens with the file, it's opened, read, closed, and its content is passed to the JSON parser and assigned to json_object.
Once parsed, the CSV file is opened and a header row is written. It could have been written as part of the open statement but this is clearer for explaining what's going on.
json_object is a hash, so to access the 'User' data you have to use a normal hash access json_object['User']. The value for the User key is an array of hashes, so those need to be iterated over, which is what json_object['User'].each does, passing the hash elements of that array into the block as user_hash.
Inside that block it's pretty much the same thing as access the value for 'User', each "element" is a key/value pair, except 'Account' which is an embedded hash.
Read the error message. each called on a hash is giving you a sequence of arrays with two members (the key and value together). There is no values method on an array. And in any case if what you have is a hash there seems little point cycling through it with each; if you want the "User" entry in the hash, why don't you ask for it up front?
Just for posterity and context this is the script I ended up using in its entity. I needed to pull from a url, and process the results and move them to a simple CSV. I needed to wite the student id, first name, last name, and the score from each of 4 assessments to the csv.
require 'csv'
require 'json'
require 'curb'
c = Curl::Easy.new('myURL/m/v3/results')
c.http_auth_types = :basic
c.username = 'myusername'
c.password = 'mypassword'
c.perform
json_object = JSON.parse(c.body_str)
CSV.open("your_csv.csv", "w") do |csv| #open new file for write
csv << %w[UserID FirstName LastName LifeFactors PersonalAttributes TechComp TechKnowledge]
json_object['User'].each do |user_hash|
csv << [
user_hash['UserId'],
user_hash['FirstName'],
user_hash['LastName'],
user_hash['AssessmentResults'][0]['Percent'],
user_hash['AssessmentResults'][2]['Percent'],
user_hash['AssessmentResults'][3]['Percent'],
user_hash['AssessmentResults'][4]['Percent']
]
end
end

Objectify Ruby Hashes from/to JSON API

I just released a ruby gem to use some JSON over HTTP API:
https://github.com/solyaris/blomming_api
My naif ruby code just convert complex/nested JSON data structures returned by API endpoints (json_data) to ruby Hashes ( hash_data), in a flat one-to-one transaltion (JSON to ruby hash and viceversa). Tat's fine, but...
I would like a programming interface more "high level".
Maybe instatiating a class Resource for every endpoint, but I'm confused about a smart implementation.
Let me explain with an abstract code.
Let say I have a complex/nested JSON received by an API,
usually an Array of Hashes, recursively nested as here below (imagination example):
json_data = '[{
"commute": {
"minutes": 0,
"startTime": "Wed May 06 22:14:12 EDT 2014",
"locations": [
{
"latitude": "40.4220061",
"longitude": "40.4220061"
},
{
"latitude": "40.4989909",
"longitude": "40.48989805"
},
{
"latitude": "40.4111169",
"longitude": "40.42222869"
}
]
}
},
{
"commute": {
"minutes": 2,
"startTime": "Wed May 28 20:14:12 EDT 2014",
"locations": [
{
"latitude": "43.4220063",
"longitude": "43.4220063"
}
]
}
}]'
At the moment what I do, when I receive a similar JSON form an API is just:
# from JSON to hash
hash_data = JSON.load json_data
# and to assign values:
coords = hash_data.first["commute"]["locations"].last
coords["longitude"] = "40.00" # was "40.4111169"
coords["latitude"] = "41.00" # was "40.42222869"
that's ok, but with awfull/confusing syntax.
Instead, I probably would enjoy something like:
# create object Resource from hash
res = Resource.create( hash_data )
# ... some processing
# assign a "nested" variables: longitude, latitude of object: res
coords = res.first.commute.locations.last
coords.longitude = "40.00" # was "40.4111169"
coords.latitude = "41.00" # was "40.42222869"
# ... some processing
# convert modified object: res into an hash again:
modified_hash = res.save
# and probably at least I'll recover to to JSON:
modified_json = JSON.dump modified_hash
I read intresting posts:
http://pullmonkey.com/2008/01/06/convert-a-ruby-hash-into-a-class-object/
http://www.goodercode.com/wp/convert-your-hash-keys-to-object-properties-in-ruby/
and copying Kerry Wilson' code, I sketched the implementation here below:
class Resource
def self.create (hash)
new ( hash)
end
def initialize ( hash)
hash.to_obj
end
def save
# or to_hash()
# todo! HELP! (see later)
end
end
class ::Hash
# add keys to hash
def to_obj
self.each do |k,v|
v.to_obj if v.kind_of? Hash
v.to_obj if v.kind_of? Array
k=k.gsub(/\.|\s|-|\/|\'/, '_').downcase.to_sym
## create and initialize an instance variable for this key/value pair
self.instance_variable_set("##{k}", v)
## create the getter that returns the instance variable
self.class.send(:define_method, k, proc{self.instance_variable_get("##{k}")})
## create the setter that sets the instance variable
self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("##{k}", v)})
end
return self
end
end
class ::Array
def to_obj
self.map { |v| v.to_obj }
end
end
#------------------------------------------------------------
BTW, I studied a bit ActiveResource project (was part of Rails if I well understood).
ARes could be great for my scope but the problem is ARes have a bit too "strict" presumption of full REST APIs...
In my case server API are not completely RESTfull in the way ARes would expect...
All in all I would do a lot of work to subclass / modify ARes behaviours
and at the moment I discarded the idea to use ActiveResource
QUESTIONS:
someone could help me to realize the save() method on the above code (I'm really bad with recursive methods... :-( ) ?
Does exist some gem that to the above sketched hash_to_object() and object_to_hash() translation ?
What do you think about that "automatic" objectifying of an "arbitrary" hash coming froma JSON over http APIs ?
I mean: I see the great pro that I do not need to client-side static-wire data structures, allowing to be flexible to possible server side variations.
But on the other hand, doing this automatic objectify, there is a possible cons of a side effect to allow security issues ... like malicious JSON injection (possible untrasted communication net ...)
What do you think about all this ? Any suggestion is welcome!
Sorry for my long post and my ruby language metaprogramming azards :-)
giorgio
UPDATE 2: I'm still interested reading opinions about question point 3:
Pros/Cons to create Resource class for every received JSON
Pros/Cons to create static (preemptive attributes) / automatich/dynamic nested objects
UPDATE 1: long reply to Simone:
thanks, you are right Mash have a sweet .to_hash() method:
require 'json'
require 'hashie'
json_data = '{
"commute": {
"minutes": 0,
"startTime": "Wed May 06 22:14:12 EDT 2014",
"locations": [
{
"latitude": "40.4220061",
"longitude": "40.4220061"
},
{
"latitude": "40.4989909",
"longitude": "40.48989805"
},
{
"latitude": "40.4111169",
"longitude": "40.42222869"
}
]
}
}'
# trasforma in hash
hash = JSON.load json_data
puts hash
res = Hashie::Mash.new hash
# assign a "nested" variables: longitude, latitude of object: res
coords = res.commute.locations.last
coords.longitude = "40.00" # was "40.4111169"
coords.latitude = "41.00" # was "40.42222869"
puts; puts "longitude: #{res.commute.locations.last.longitude}"
puts "latitude: #{res.commute.locations.last.latitude}"
modified_hash = res.to_hash
puts; puts modified_hash
This feature is provided by a few gem. One of the most known is Hashie, specifically the class Hashie::Mash.
Mash is an extended Hash that gives simple pseudo-object functionality that can be built from hashes and easily extended. It is designed to be used in RESTful API libraries to provide easy object-like access to JSON and XML parsed hashes.
Mash also supports multi-level objects.
Depending on your needs and level of nesting, you may get away with an OpenStruct.
I was working with a simple test stub. Hashie would have worked well, but was a bigger tool than I needed (and added dependency).

Rails 3.1 urllib2.quote(json.dumps(var)) Equivalent

In Python I can convert JSON into a useable encoded string eg:
cmd2 = [{'cmd': 'inlinepush',
'params': {'raw': 'score'
}
}]
url = urllib2.quote(json.dumps(cmd2))
print url
This produces:
%5B%7B%22cmd%22%3A%20%22inlinepush%22%2C%20%22params%22%3A%20%7B%22raw%22%3A%20%22score%22%7D%7D%5D
I have searched and searched but not found a Ruby or Rails equivalent, particularly in the NET::HTTP library.
I really have spent a lot of time thrashing to no end and would be grateful of any pointers.
Try this:
require 'cgi'
require 'json'
cmd2 = [{
'cmd' => 'inlinepush',
'params' => {
'raw' => 'score'
}
}]
puts CGI.escape(JSON.dump(cmd2))

How to Send a Multidimensional Array using Rack::Test post

I am sending a multidimensional array using the post method given by the Rack::Test like
post "#{url}.json",:data => [["Company","Website"],["this is the dummy text, with,comma","www.technology.com"],["some company","www.url.com"]]
But in my controller when check my params params[:data] i am receiving it as a single dimensioned array ["Company", "Website", "this is the dummy text, with comma", "www.technology.com", "some company", "www.url.com"]
But i want it to retain it's property as a multi-dimensional array. I need help to do this.
The Rack::Test methods all have the same signature... and the second param is a hash of params
i.e.
post '/path', params={}, rack_env={}
This is because they're just URL params - which are typical key/value structures (i.e. a hash)
Why do you need it to be a multi-dimensional array?
EDIT: oh, I get it - you have a single hash with one key (:data)
If it's still causing you grief you could explicitly call to_param in there
ruby-1.9.2-p180 :003 > h = {:data => [["Company","Website"],["this is the dummy text, with,comma","www.technology.com"],["some company","www.url.com"]]}
=> {:data=>[["Company", "Website"], ["this is the dummy text, with,comma", "www.technology.com"], ["some company", "www.url.com"]]}
ruby-1.9.2-p180 :004 > h.to_param
=> "data[][]=Company&data[][]=Website&data[][]=this+is+the+dummy+text%2C+with%2Ccomma&data[][]=www.technology.com&data[][]=some+company&data[][]=www.url.com"
A workaround if you really need nested arrays is to change the request content type to JSON:
post url, JSON.dump([[1, 2], [3, 4]]), { "CONTENT_TYPE" => "application/json" }
This will correctly send a nested array through to the rack app.
Neither of the above worked too well for me but this did (see my original answer here).
The problem is body is sent as application/x-www-form-urlencoded by default, which doesn't handle multi-dimensional arrays too well. You can send it as application/json, but Sinatra probably won't merge the data into the request params. I use a middleware from rack-contrib which parses a json body from a POST request and merges it for you:
# Gemfile
`gem 'rack-contrib'`
then config.ru:
require 'rack/contrib'
require './app'
use Rack::PostBodyContentTypeParser
run Sinatra::Application
This won't be used in testing by default, but you can specify it:
# spec_helper.rb
OUTER_APP = Rack::Builder.parse_file("config.ru").first
module RSpecMixin
include Rack::Test::Methods
def app
OUTER_APP # typically this might just be Sinatra::Application
end
end
RSpec.configure do |config|
config.include RSpecMixin
end
And example usage:
it 'is ok' do
post '/', { key: 'value' }.to_json, { 'CONTENT_TYPE' => 'application/json' }
expect(last_response).to be_ok
end

Resources