I have to tag a separation by -
Example:
require 'nokogiri'
teste = Nokogiri::XML::DocumentFragment.parse("")
Nokogiri::XML::Builder.with(teste) do |x|
x.root('xmlns:ns3' => 'Example namespace') do
x['ns3'].example "Example Test"
end
end
puts teste.to_xml
Output
<exemplo>teste xml</exemplo>
Required output
<ns3:exemplo-teste>teste</ns3:exemplo-teste>
Try this:
Nokogiri::XML::Builder.with(teste) do |x|
x.root('xmlns:ns3' => 'Example namespace') do
x['ns3'].send('example-test', 'Example Test')
end
end
Output will be:
</root><root xmlns:ns3="Example namespace">
<ns3:example-test>Example Test</ns3:example-test>
</root>
Related
How can I check the content of a bounced email?
require "rails_helper"
RSpec.describe EventsMailbox do
it "requires a current user" do
expect(mail_processed).to have_bounced
# here I would like to check the content of the bounced email
end
def mail
Mail.new(
from: "dorian#dorianmarie.fr",
subject: "Some subject",
body: "Some body"
)
end
def mail_processed
#mail_processed ||= process(mail)
end
end
Here is how I did it, the key was that perform_enqueued_jobs that allows emails to be retrieved from ActionMailer::Base.deliveries:
require "rails_helper"
RSpec.describe EventsMailbox do
include ActiveJob::TestHelper
around(:each) { |example| perform_enqueued_jobs { example.run } }
it "requires a current user", focus: true do
expect(mail_processed).to have_bounced
expect(last_delivery.from).to eq(["contact#socializus.app"])
expect(last_delivery.to).to eq(["dorian#dorianmarie.fr"])
expect(last_delivery_text).to(
include("You need to be registered on Socializus")
)
end
def mail
Mail.new(
from: "dorian#dorianmarie.fr",
to: "party#events.socializus.app",
subject: "Some subject",
body: "Some body"
)
end
def mail_processed
#mail_processed ||= process(mail)
end
def last_delivery
ActionMailer::Base.deliveries.last
end
def last_delivery_text
return unless last_delivery
text_part = last_delivery.parts.detect { _1.mime_type == "text/plain" }
return unless text_part
text_part.body.to_s
end
end
In rails I am writing a test for a controller method search_backups with Rspec:
def elastic_mongo_lookup(search_term)
devices_ids_from_elastic = ConfigTextSearch.search search_term
puts devices_ids_from_elastic
device_ids = devices_ids_from_elastic.map { |device| device._source.device_id }
csv_string = CSV.generate do |csv|
Device.where(:_id.in => device_ids).each do |device|
csv << [device.logical_name, device.primary_ip]
end
end
return csv_string
end
def search_backups
authorize! :read, :custom_report
csv_string = elastic_mongo_lookup params[:search_term]
if csv_string.blank?
flash[:notice] = "No results were found"
redirect_to reports_path
else
render text: "DeviceID, primary_ip\n" + csv_string
end
end#search_backups
describe "try controller method" do
let(:reports_controller) { ReportsController.new }
before do
allow(CSV).to receive(:generate).and_return("1234", "blah")
allow(ConfigTextSearch).to receive(:search).and_return(['"hits": [ {"_source":{"device_id":"54afe167b3000006"}]'])
allow(:devices_ids_from_elastic).to receive(:map).and_return('54afe167b3000006')
stub_request(:get, "http://localhost:9200/mongo_index/config_files/_search?q=").
with(:headers => {'Expect'=>'', 'User-Agent'=>'Faraday v0.9.1'}).
to_return(:status => 200, :body => '', :headers => {})
end
it "allows people to search backups" do
reports = double(ReportsController)
post 'search_backups'
end
end
The issue is that ConfigTextSearch.search search_term returns a elasticsearch ORM object.. which means I can't stub it because the .map() method on devices_ids_from_elastic.map is unique with it's nested _source method.
How could I bypass elastic_mongo_lookup entirely and just return a mocked csv_string to search_backups?
In an RSpec controller test, controller is defined as the controller under test. You can therefore achieve what you're asking about with the following:
allow(controller).to receive(:elastic_mongo_lookup).and_return('whatever string you choose')
I want to testing page, and I have some problem. The select matcher does not work.
rspec
let!(:hotel1) { create(:hotel) }
let!(:hotel2) { create(:hotel, status: 'rejected') }
it 'with params: status column and existing value' do
login_admin
visit admin_hotels_path
expect(page).to have_content hotel1.title
expect(page).to have_content hotel2.title
fill_in :search, with: 'rejected'
select 'status', from: :search_column
click_button 'Search'
expect(page).to have_content hotel2.title
expect(page).to_not have_content hotel1.title
end
index
=form_tag admin_hotels_path, method: 'get' do
=text_field_tag :search, params[:search]
=select_tag :search_column, options_for_select(Hotel.searchable_columns, params[:search_column])
=submit_tag 'Search'
controller
def index
#hotels = Hotel.search(params[:search], params[:search_column]).order(sort_column + ' ' + sort_direction)
end
The result of testing:
Failures:
1) hotels page check the Search with params: status column and existing value
Failure/Error: expect(page).to_not have_content hotel1.title
expected #has_content?("Hotel1") to return false, got true
But the search from status with this params return one object, because in the factories the status have approved value.
UPDATE
factory :hotel do
sequence(:title) { |i| "Hotel#{i}" }
description 'This is a some description for hotel'
breakfast true
price 20500
address { create(:address) }
user { create(:user) }
avatar { fixture_file_upload(Rails.root + 'spec/fixtures/images/example.jpg', "image/jpg") }
status 'approved'
end
UPDATE 2.0
hotel.rb
def self.search(keyword, column_name)
if self.column_names.include?(column_name.to_s)
where("#{column_name} LIKE ?", "#{keyword}")
else
scoped
end
end
def self.searchable_columns
wanted_columns = ['title', 'status' ]
self.column_names.select{ |column| wanted_columns.include?(column) }
end
end
Maybe your factory generates hotels with the same name.
Your select statement should be in the format of:
select(value, options = {})
e.g.,
select 'rejected', from: :search_column
Ref. this doc
I have created a FormBuilder extension:
form.div_field_with_label(:email)
Which outputs:
<div class="field email">
<label for="user_email">Email</label>
<input class="input" id="user_email" name="user[email]" type="email" value="">
</div>
How do i create or mock the template object in my rspec test?
app/helper/form_helper.rb
module FormHelper
class GroundedFormBuilder < ActionView::Helpers::FormBuilder
def div_field_with_label(key, &block)
if block_given?
content = self.label(key)
content << block.call(key)
end
classes = ['field']
classes << key.to_s
if #object.errors[key].size != 0
classes << 'warning'
msg = #object.errors.full_message(key, #object.errors[key].join(', '))
content << #template.content_tag(:p, msg, :class => "error-message warning alert" )
end
#template.content_tag(:div, content, :class => classes.join(' ').html_safe)
end
end
end
spec/helper/form_helper_spec.rb
require 'spec_helper'
describe FormHelper do
describe FormHelper::GroundedFormBuilder do
describe 'div_field_with_label' do
# how do i create or mock template?
# template = ?
let(:resource) { FactoryGirl.create :user }
let(:helper) { FormHelper::GroundedFormBuilder.new(:user, resource, template, {})}
let(:output) { helper.div_field_with_label :email }
it 'wraps input and label' do
expect(output).to match /<div class="field">/
end
it 'creates a label' do
expect(output).to match /<label for="user[email]">Email/
end
end
end
end
Update for rails 3 or higher.
This how it should looks like now:
require 'spec_helper'
class TestHelper < ActionView::Base; end
describe LabeledFormBuilder do
describe '#upload_tag' do
let(:helper) { TestHelper.new }
let(:resource) { FactoryGirl.build :user }
let(:builder) { LabeledFormBuilder.new :user, resource, helper, {}, nil }
let(:output) do
builder.upload_tag :avatar, title: "Test upload"
end
before { expect(helper).to receive(:render) { "render partial "} }
it { expect(output).to include "Upload file via new solution" }
end
end
I haven't tried this, but looking at how your GroundedFormBuilder uses #template, maybe all you need is an object that extends ActionView::Helpers::TagHelper:
# ...
template = Object.new.extend ActionView::Helpers::TagHelper
# ...
Any of the TagHelper methods such as content_tag should generate the same content as they would when included in a real template.
actually it was as easy as using self since FormBuilder has TagHelper somewhere in the inheritance chain.
# spec/helper/form_helper_spec.rb
require 'spec_helper'
describe FormHelper do
describe FormHelper::GroundedFormBuilder do
describe 'div_field_with_label' do
# how do i create or mock template?
# template = ?
let(:resource) { FactoryGirl.create :user }
let(:helper) { FormHelper::GroundedFormBuilder.new(:user, resource, self, {})}
let(:output) {
helper.div_field_with_label :email do
helper.email_field(:email, :class => 'input')
end
}
it 'wraps input and label' do
expect(output).to include '<div class="field email">'
end
it 'creates a label' do
expect(output).to include '<label'
end
end
end
end
I am trying to parse XML using rexml Xpath, but facing error as const_missing: XPath in rhomobile application. can anyone give me the solution.
Below is the sample code:
file = File.new(file_name)
begin
require 'rexml/document'
xmldoc = REXML::Document.new(file)
names = XPath.match(xmldoc, "//MP_HOST_NAME" )
in your build.yml file:
extensions:
- rexml
if using blackberry, replace rexml with rhoxml
Assuming you've done this, replace your XPath with:
REXML::XPath.match(xmldoc, "//MP_HOST_NAME" )
Here is a sample controller I knocked to test xml parsing
I can use the get_names method in the view then to get an array of names
require 'rho/rhocontroller'
require 'rexml/document'
class WebServiceTestController < Rho::RhoController
def index
##get_result = ""
Rho::AsyncHttp.get(
:url => 'http://www.somesite.com/some_names.xml',
#:authorization => {:type => :basic, :username => 'user', :password => 'none'},
:callback => (url_for :action => :httpget_callback),
:authentication => {
:type => :basic,
:username => "xxxx",
:password => "xxxx"
},
:callback_param => "" )
render :action => :wait
end
def get_res
##get_result
end
def get_error
##error_params
end
def httpget_callback
if #params["status"] != "ok"
##error_params = #params
WebView.navigate( url_for(:action => :show_error) )
else
##get_result = #params["body"]
begin
# require "rexml/document"
##doc = REXML::Document.new(##get_result)
# puts "doc : #{doc}"
rescue Exception => e
# puts "Error: #{e}"
##get_result = "Error: #{e}"
end
WebView.navigate( url_for(:action => :show_result) )
end
end
def show_error
render :action => :error, :back => '/app'
end
def show_result
render :action => :index, :back => "/app"
end
def get_doc
##doc
end
def get_names
names = []
REXML::XPath.each( get_doc, "//name_or_whatever_you_are_looking_for") do |element|
names << element.text
end
names
end
end
ensure that rhoxml is set in the build.yml file rather than rexml this works fine and it's a little faster