How to test kohana model, controller - tdd

I have been working with php for more than 5 years. Lately I have worked in rubyonrails. I have done a few projects in this very nice framework. What I like best from rails and ruby: they both promote automate test and there are so many rich libs. Rspec and TestUnit are very easy to learn comparing to PhpUnit.
I have to develop a very big project in the next coming month. I am a big fan in cakephp but I realize that cakephp will not meet my project requirement. I am a quick learner. After reading doc from Kohana official website, I will use Kohana for this project.
After having done some search on Kohana, I still have a few topics to concern about
The test module is lack of doc. I am not clear how to test model, controller, functional test. Could anyone provide me ideas, tutorials, examples, resources ?
The application environment is not quite clear. Sorry because I am pretty family with rubyonrails . I feel like environment in rails make more sense to me. I can have one gem in a specific environment. for example I have rspec gem (for automate test ) for test environment only and I have unicorn gem for production only. For those who are new to ruby, gem is something similar to "module" in kohana. Could anyone tell me how to tell kohana to just load "unittest" in test environment only ? because I don't want to load unittest in production env.
In Rails there is an app console mode called rails console. with rails console we can interact with models via console mode . Is there anything similar to this in Kohana ?

I can answer only 2 of your questions, still better then nothing ;)
AD2. You can set Kohana::$environment variable based on the .htaccess (setenv and getenv) / $_SERVER setting:
if (Arr::get($_SERVER, 'SERVER_NAME') !== 'localhost')
{
// We are live!
Kohana::$environment = Kohana::PRODUCTION;
// Turn off notices and strict errors
error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT);
}
else
{
Kohana::$environment = Kohana::DEVELOPMENT;
error_reporting(E_ALL | E_STRICT);
}
Then you can setup Kohana::init like this:
Kohana::init(array(
'base_url' => '/',
'caching' => Kohana::$environment === Kohana::PRODUCTION,
'profile' => Kohana::$environment !== Kohana::PRODUCTION,
'index_file' => FALSE,
'errors' => TRUE
));
so your production application will have caching enabled and profiling disabled.
For the modules it's pretty much the same:
if (Kohana::$environment !== Kohana::PRODUCTION)
{
Kohana::modules(array(
'unittest' => MODPATH . 'unittest',
));
}
AD3. Sorry for being laconic - no, there isn't one.

Related

Padrino framework I18n routes translation

I have a question about localization, I am trying to do multilingual routes, using I18n.
I am using translations in my project, but, I would like to do this
get "/#{I18n.t('routes.kategorie')}" do ...
but, loading crashes on
! Unable to load application: Mustermann::CompileError: capture name can't be empty: "/translation missing: cs.routes.kategorie"
bundler: failed to load command: puma (/usr/local/bin/puma)
Mustermann::CompileError: capture name can't be empty: "/translation missing: cs.routes.kategorie"
but when I start my app (without that route) with pry, I can use this translation
[3] pry(#<Osadababa::App>)> t('routes.kategorie')
=> "kategorie"
[4] pry(#<Osadababa::App>)> I18n.locale = :en
=> :en
[5] pry(#<Osadababa::App>)> t('routes.kategorie')
=> "category"
For both languages.
I am working in toplevel app.
Please any suggestions?
Thanks
I will answer myself, better way is to handle multiple routes, by Padrino or Sinatra style, I am trying to do according the documentation, but still not working

Add support for rendering views to a rails api only application

I built an api only rails app, but since i'm using a 3rd party email service, I need to be able to render the email template into a string to pass it to the mailing service wrapper gem. So far any attempt to render templates into a string returns an empty string, and i suspect it is because the application is configured to be API only. Ho do I add support to rendering templates into a string?
If this is not the case, please let me know. I'm using postmark mail service. postmark-rails gem, which integrates into standard rails mailers didn't work at all, and plain postmark gem (which uses postmark API instead of postmark SMTP server) works fine, but now my problem is producing the proper html for the email.
this is what I'm trying:
html = render_to_string(
partial: "transfer_mailer/transfer.html.erb",
locals: {
:#body => #body,
:#campaign => #campaign,
:#chat => #chat
}
)
but it returns empty string.
My setup involves Rails 5.0.1, ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux], Sidekiq 4.2.7, and in production im using nginx/1.10.2 and Phusion Passenger 5.1.1. Production environment is deployed in an azure virtual machine, and I added both inbound and outbound rules for allowing traffic through ports 25, 465, 2525, and 587.
Any help would be really appreciated.
Looking at the docs for render_to_string, it looks like the path doesn't need to include .html.erb, so maybe removing that will fix it.
You can see here for some example code:
In your case, it would be:
render_to_string(
partial: '/transfer_mailer/transfer',
locals: {
:#body => #body,
:#campaign => #campaign,
:#chat => #chat
},
layout: false
)
Also make sure the partial filename starts with an underscore, even though you don't include it with render_to_string or render calls.
There is the other way to use render_to_string for resolving your issue. Please see the code below.
#body = XXX
#campaign = YYY
#chat = ZZZ
html = render_to_string(
file: 'transfer_mailer/transfer.html.erb'
)
Hope it helps.

EncryptedCookie gem causes TypeError in Sinatra

I'm trying to make my Sinatra app's sessions more secure, and to do that I'd like to use the EncryptedCookie gem. Unfortunately, when I visit any page in my app, I get this error:
TypeError at /
no _dump_data is defined for class UnboundMethod
file: encrypted_cookie.rb location: dump line: 68
Here's my code:
configure do
use Rack::Session::EncryptedCookie,
:key => 'myapp.session',
:domain => 'myapp.com',
:path => '/',
:expire_after => 1200,
:secret => 'bigcrazysecretstringhere'
end
I tried using the EncryptedCookie gem with the same settings as shown above in a simple Sinatra app I made to test the gem, and it worked fine. There must be some other setting in my app that's interfering with the app, but I can't figure out what it might be. Has anyone out there experienced a similar issue?
(I've also tried starting the app with 'thin start', 'rackup config.ru', and 'ruby myapp.rb'- none of these made a difference.)
After banging my head against the wall for well over a week, I discovered the contractor who worked on the project before me had put
use Rack::Session::Pool
200 lines below the original
use Rack::Session::Cookie
I removed that and Encrypted Cookie worked fine. Lesson learned: Immediately abstract away everything you can when handed a 500 line Sinatra app. Then things can't hide from you.

Bad Request/Bad URI on production (Heroku) but not locally

Let me preface this by saying most of this application is a giant hack put together in a short window of time under pressure so I may have deeper issues. This question will likely have some bad code in it.
I've built a Sinatra application to handle some tasks with purchase and sales orders in-house. Part of that is to send a few parameters to one of the routes in the app which will then push those off to an API that does useful things with them.
Right now, I'm generating the links with paramaters from within a pretty ugly loop in HAML:
%td
- opts = JSON.generate({ "key" => d[d.keys.first]["key"], "sa_id" => d.keys.first, "site" => d[d.keys.first]["site"], "name" => d[d.keys.first]["name"], "recipient" => d[d.keys.first]["email"], "items" => d[d.keys.first]["descriptions"], "date" => d[d.keys.first]["ship_date"]})
-if (d[d.keys.first]["email"]) && (d[d.keys.first]["site"] != "")
%a{:href => "/notify?options=#{opts}", :title => "Deliver"} Deliver
-else
Deliver
%a{:href => "/destroy?key=#{d.keys.first}", :title => "Destroy"} Destroy
When clicking hte "deliver" link (%a{:href => "/notify?options=#{opts}", :title => "Deliver"} Deliver) locally, everything behaves as expected. My /notify route is called, it hands the parameters off to the desired API, and everything is rainbows and unicorns. When I click that same link on Heroku, it throws a "Bad Request" stating "Bad URI". The only difference between the two URLs generated is the hostname (localhost:3000 vs. myapp.herokuapp.com) and vimdiff confirms this.
Everything else being even, why would Heroku (using Webrick) kick back my URI when my local instance (Thin) doesn't seem to care?
Switching from Webrick to Thin on Heroku resolved this issue, though I'm not sure about the specifics as to why.
We've had some issues where development and production environments that were seemingly identical behaved differently once deployed on heroku. A quick sanity check I like to do is to diff the local gemfile.lock to the one on heroku after the deploy process is complete. I know - we should lock our gem versions down more tightly and we will do, so don't consider this a best practice - but it unearthed some hard to track down issues, some of which were related to the fact that we have some devs on Windows and some on Mac and the gemfile.lock often had Windows specific gems which causes issues on heroku. Just something to consider.

Multiple Sinatra apps using rack-mount

I have a question regarding using rack-mount with Sinatra. I've got two classic-style Sinatra apps. Let's call one App defined in app.rb and the other API defined in api.rb.
I would like it so that api.rb handles all routes beginning with '/api' and app.rb handles all other requests including the root ('/').
How would I set this up with rack-mount? Or is there a better solution than that?
I think you'll prefer Rack::URLMap - it will probably look something like this:
run Rack::URLMap.new("/" => App.new,
"/api" => Api.new)
That should go in your config.ru file.
I had a similar issue and I am not very familiar with Rack. I could not figure out what to do based on the answers above. My final solution was to have the following in config.ru.
This works perfectly for me.
# Main Ramaze site
map "/" do
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
require ::File.expand_path('../app', __FILE__)
Ramaze.start(:root => __DIR__, :started => true)
run Ramaze
end
# Sinatra & Grape API
map "/api" do
use Rack::Static, :urls => ["/stylesheets", "/images", "/javascripts"], :root => "public"
use Rack::Session::Cookie
run Rack::Cascade.new([
MySinatraApp::Application,
MySinatraApp::API])
end
In config.ru you could also take advantage of Sinatra's middleware feature. If you have several Sinatra apps, each with its own routes, and want to run them simultaneously, you can arrange them in the order you want them found, e.g.
# config.ru
...
use MyAppA
use MyAppB
use MyAppC
run MyAppD
I had the same problem once and so I came up with this template: sinatra-rspec-bundler-template which is layed out for multiple apps.
It may have more features than you need but it should help you when you need something "a bit more" complex.

Resources