Forum: Rails France test d'un module avec rspec

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
1e2f73355d6fb2e417e0c38e97c50cf4?d=identicon&s=25 Gilles (Guest)
on 2009-03-10 04:34
(Received via mailing list)
Bonjour à tous,

Voila j'utilise un module pour gérer des sous domaines, placé dans le
dossier lib/ qui me retourne une instance particulière d'un modele
selon le sous sous-domaine. Ce module placé dans application.rb est
utilisable par tous les controleurs. Ceci me sert à scoper les autres
données liées à cet instance. Mon problème est que je n'arrive pas à
le tester avec rspec dans le contexte d'un sous domaine justement. Par
ailleurs j'ai dans application.rb un before_filter qui teste la
validité du sous-domaine demandé

Voici le module :

#
# Inspired by
#
http://dev.rubyonrails.org/svn/rails/plugins/accou...
#
module SubdomainTeams
 def self.included( controller )
   if controller.respond_to? :helper_method
     controller.helper_method
(:team_domain, :team_subdomain, :team_url,
:current_team,:default_team_subdomain, :default_team_url)
   end
 end

 protected

   # TODO: need to handle www as well
   def default_team_subdomain
     '' # 'www' || ''
   end

   def team_url( team_subdomain = default_team_subdomain, use_ssl =
request.ssl? )
     http_protocol(use_ssl) + team_host(team_subdomain)
   end

   def team_host( subdomain )
     team_host = ''
     team_host << subdomain + '.'
     team_host << team_domain
   end

   def team_domain
     team_domain = ''
     team_domain << request.domain + request.port_string
   end

   def team_subdomain
     request.subdomains.first || ''
   end

   def default_team_url( use_ssl = request.ssl? )
     http_protocol(use_ssl) + team_domain
   end

   def current_team
     Team.find_by_subdomain(team_subdomain)
   end

   def http_protocol( use_ssl = request.ssl? )
     (use_ssl ? "https://" : "http://")
   end
end

et voici un un contrôleur l'utilisant :

class PostsController < ApplicationController
 before_filter :find_team

 def index
   if current_team
     @posts = current_team.posts.of_the_week
   elsif @team
     @posts = @team.posts.of_the_week
   end
 end
…

Le before_filter est :

 before_filter :check_team_status

 def check_team_status
   unless team_subdomain == default_team_subdomain
     # TODO : check if the team has a valid subscription
     if !current_team.nil? && current_team.valid_subscription == true
       return true
     end
     redirect_to default_team_url if current_team.nil?
   end
 end

Comment faire pour tester l'action index du controleur Posts ds le
contexte d'un sous-domaine ? C'est à dire avec la variable
current_team à non nil ?

Merci d'avance.

Gilles.
2fd0206c71a1b22a9cc6293f38537461?d=identicon&s=25 Cyril Mougel (shingara)
on 2009-03-10 05:33
(Received via mailing list)
Gilles a écrit :
>
>  end
>      http_protocol(use_ssl) + team_host(team_subdomain)
>      team_domain << request.domain + request.port_string
>    def current_team
> class PostsController < ApplicationController
>
>      redirect_to default_team_url if current_team.nil?
>    end
>  end
>
> Comment faire pour tester l'action index du controleur Posts ds le
> contexte d'un sous-domaine ? C'est à dire avec la variable
> current_team à non nil ?
>

describe PostsController do
  before(:each) do
    @controller.stub!(:domain).and_return('my_domain')
    @controller.stub!(:port_string).and_return('80')
    @controller.stub!(:subdomains).and_return(['my_first_subdomain',
'next', 'othernext']
  end
end

un truc comme ca devrait être une piste.

--
Cyril Mougel
http://blog.shingara.fr
140f1cb88275f7c391504de6e99edc78?d=identicon&s=25 Sébastien Gruhier (Guest)
on 2009-03-10 07:15
(Received via mailing list)
ou bien un truc comme ça devrais le faire (je crois que c'est le
referer qui est utilisé, sinon faut setter la bonne clé)

before(:each) do
  @request.env['HTTP_REFERER']  = 'subdomain.domain.com'
end


-----------------------------------------------------------------------
http://xilinus.com    Web Application Development, Consulting, Training
http://mapeed.com     Markers fusion plugin for your online maps
1e2f73355d6fb2e417e0c38e97c50cf4?d=identicon&s=25 Gilles (Guest)
on 2009-03-10 14:03
(Received via mailing list)
Merci du coup de main, j'ai intégré ces quelques lignes et mes specs
passent maintenant. Mais je ne comprends pas entièrement ce qui se
passe … c'est frustrant …
1e2f73355d6fb2e417e0c38e97c50cf4?d=identicon&s=25 Gilles (Guest)
on 2009-03-10 14:08
(Received via mailing list)
Oups ! j'ai parlé trop vite …
Les specs échouent toujours … dommage, je ne comprends pas encore ce
qui se passe …
les @controller.stub! n'ont pas l'air d'apporter quelquechose …
1e2f73355d6fb2e417e0c38e97c50cf4?d=identicon&s=25 Gilles (Guest)
on 2009-03-10 14:34
(Received via mailing list)
hé bien après quelques investigations, c'est toujours l'impasse en
quelque sorte. je réussie à faire passer les specs mais sans utiliser
aucune des suggestions, mais tous simplement en affectant la variable
@current_team à un fixture ds le bef…each

    context "without a team_id but a current_team by subdomain" do

      fixtures :teams

      before(:each) do
        # @controller.stub!(:domain).and_return('basketballstat.dev')
        # @controller.stub!(:port_string).and_return('80')
        # @controller.stub!(:subdomains).and_return(['myteam',
        #       'next', 'othernext'])
        # @request.env['HTTP_REFERER'] = 'myteam.basketballstat.dev:
3000'
        @current_team = teams('myteam')
        @posts_proxy = mock('posts')
        @post = mock_model(Post)
      end

      def do_get
        get :show, :id => "1"
      end

      it "should find the requested current_team's post and assigns it
to the show view" do
        @current_team.should_receive(:posts).and_return(@posts_proxy)
        @posts_proxy.should_receive(:find).with("1").and_return(@post)
        do_get
        assigns[:post].should equal(@post)
        response.should render_template('show')
      end

    end
91eb330fb36d1e03c856574dfb77d2bc?d=identicon&s=25 Thibaut Barrère (thbar)
on 2009-03-11 12:30
(Received via mailing list)
Hello,

ce que je fais d'habitude:
- une première série de tests portant sur le before filter (vérifier
qu'il fonctionne, empêche les gens sans souscription de rentrer,
laisse passer ceux qui en ont une...)
- une deuxième série de tests portant sur la fonctionnalité elle-même,
en supposant que le before filter est passé

Ça revient à appliquer la "separation of concerns" comme ils disent
dans les livres anglais.

Là j'ai l'impression que tu cherches plutôt à réaliser la deuxième
série de tests. Dans ce cas je te conseille de "stubber plus haut".
Peut-être que quelque chose comme suit te conviendrait (c'est ce que
j'ai tendance à faire):

  before(:each) do
    controller.stub!(:find_team).and_return(true)
    controller.stub!(:current_team).and_return(my_mock_team)
  end

à côté de ça j'ai généralement une spec qui se concentre sur le
before_filter (1ère série de tests). Ex ici, où le before filter fait
un Customer.find_by_access_token pour authentifier le client:

describe CustomersController, "authentication" do

  before(:each) do
    controller.use_rails_error_handling!
  end

  it "denies access if a valid access token hasn't been provided" do
    Customer.should_receive(:find_by_access_token).with("wrong-
token").and_return(nil)
    get :index, :access_token => "wrong-token"
    response.response_code.should eql(403)
    session[:customer].should be_nil
  end

  it "grants access if a valid access token has been provided" do
    customer = mock("customer", :id => 44)
    Customer.should_receive(:find_by_access_token).with("good-
token").and_return(customer)
    get :index, :access_token => "good-token"
    response.should be_success
    session[:customer].should == 44
  end

end

voilà j'espère que ça t'aidera dans ta quête de la "spec qui va bien".

Thibaut
--
http://learnivore.com
http://blog.logeek.fr
1e2f73355d6fb2e417e0c38e97c50cf4?d=identicon&s=25 Gilles (Guest)
on 2009-03-12 14:24
(Received via mailing list)
Merci,

Cela a fonctionné. rSpec comporte des subtilités qui poussent à mieux
comprendre ce que l'on code et c'est tout l'intérêt. Ce n'est pas
toujours évident mais on ce sent mieux après avoir compris, alors
merci pour ces explications claires, j'ai encore un peu progressé
grace à toi.

Gilles.
This topic is locked and can not be replied to.