zoukankan      html  css  js  c++  java
  • 使用Cucumber+Rspec玩转BDD(5)——安全退出


    ### 温故知新 ###


    为了保护用户的隐私,限制特定资料的访问,前面我们给系统增加了登录功能;紧接着,又为了方便用户在一段时间之内不必重复登录操作,我们实现了用户的持久登录状态,即“记住我”功能。如果浏览器未关闭,或者用户一直处于在线状态,而用户自己并没有使用这台设备,很显然,这对用户的帐号是非常危险的;基于此,系统应该提供一个给用户手工注销在线状态退出站点的功能。

    为了获得更好的阅读体验,读者朋友们可以在这里下载源码:http://github.com/404/bdd_user_demo/tree/master


    ### 新建工作分支 ###

    $ git checkout -b user_logout


    ### 用户注销退出功能 ###

      1.提供一个“退出”链接,用户登录后点击该链接可以注销在线状态;
      2.用户登录并勾选记住我后,点击“退出”链接可以注销在线状态,下次访问的时候将不再自动登录。

    下面来编写对应于以上功能的故事场景。


    ### 故事用例之用户注销退出 ###

    $ gedit features/user_logout.feature

    功能: 用户安全退出
      为了保护我的帐号不被他人非法使用
      作为一名已经登录的在线用户
      我希望能够安全退出
      
      场景: 用户注销在线状态
        假如 我已经使用<404/xuliicom@gmail.com/password>注册过且已经激活了帐号
        当 我以<xuliicom@gmail.com/password>这个身份登录
        那么 我应该成功登录网站
        当 我退出网站
        那么 我应该看到<您已经安全退出>的提示信息
        而且 我应该尚未登录

      场景: 用户在持久在线状态下退出
        假如 我已经使用<404/xuliicom@gmail.com/password>注册过且已经激活了帐号
        当 我以<xuliicom@gmail.com/password>这个身份登录并勾选<记住我>
        那么 我应该成功登录网站
        当 我退出网站
        那么 我应该看到<您已经安全退出>的提示信息
        而且 我应该尚未登录
        当 我关闭网页下次再来访问的时候
        那么 我应该尚未登录


    可以把一个feature文件当作一份书面需求的电子版,如果你觉得文件开头几句没什么用(为了...作为...我希望...),那直接在那里罗列出功能简要咯,故事场景就当作详尽的需求来写。例如:

    功能: 用户安全退出
      1.提供一个“退出”链接,用户登录后点击该链接可以注销在线状态;
      2.用户登录并勾选记住我后,点击“退出”链接可以注销在线状态,下次访问的时候将不再自动登录。

      
      场景1
        ...

      场景2
        ...

    若真那样,说不定可以节约不少会议时间,因为用于测试的故事文本(feature文件)完全可以替代现实中的功能需求书,而且更加灵活。再向前一步,就可以直接把客户说的需求整理到测试中去,完了发动测试引擎一直在那转动着,开发人员和测试引擎凑到一块儿玩结对编程……敏捷开发,我们还需要文档么?

    回头干正事儿,保存 user_logout.feature。运行测试看看它能告诉我们应该做些什么,

    $ ruby script/cucumber -l zh-CN features/user_logout.feature




    ### 编写测试脚本 ###

    如上图所示,我们需要为“当 我退出网站”定义所需的运行脚本。

    $ gedit features/step_definitions/user_steps.rb

    # user logout

    When /^我退出网站$/ do
      visit '/logout', :delete
    end


    保存user_steps.rb。运行测试,

    $ ruby script/cucumber -l zh-CN features/user_logout.feature




    ### 配置登出路由(logout_path) ###

    没有找到"/logout"这一访问路径,因为我们还没有在 routes.rb 配置文件中定义"/logout"。修改 routes.rb 文件,添加这条路由信息,

    $ gedit config/routes.rb

    为了sessions资源看起来有紧凑的结构,我们稍微变换了login_path的定义,与logout_path整合到了一起。

      map.with_options :controller => 'sessions' do |page|
        page.login '/login', :action => 'new'
        page.logout '/logout', :action => 'destroy'
      end



    ### 实现用户注销退出 ###

    既然 "/logout" 路由指向了 SessionsController 类的 destroy 方法,那么我们还需要编写 destroy 方法的具体实现。

    $ gedit app/controllers/sessions_controller.rb

    添加 destroy 方法,

      def destroy
        forget(current_user)
        reset_session
        flash[:notice] = "您已经安全退出!"
        redirect_to login_path
      end


    在 private 之后添加 forget 方法,

      def forget(user)
        user.forget_me! if user
        cookies.delete :remember_token
      end



    ### 删除服务端的remember_token ###

    在forget方法中,程序调用了User实例对象的forget_me!方法;然后清除了当前客户端与服务端会话的cookies;仅仅清除客户端的cookies还不够,服务器上的也应该一并删除。

    $ gedit app/models/user.rb

    添加forget_me!方法,

      # 删除数据库里边的remember_token
      def forget_me!
        self.remember_token_expires_at = nil
        self.remember_token            = nil
        save(false)
      end


    保存 user.rb。运行测试,

    $ ruby script/cucumber -l zh-CN features/user_logout.feature



    测试通过!


    ### 亲临现场 ###

    为了方便登录用户能够以鼠标点击的方式退出站点,也为了方便开发人员自己手工测试,此时还需要给登录用户提供一个用于注销退出的链接。在之前设置的访问控制中,用户资料显示页面只能在用户登录以后才可见,我们可以将此退出链接加到这个页面中。

    $ gedit app/views/users/show.html.erb

    在该模板文件末尾加上如下一段代码,

    <p>
      <%= link_to "安全退出", logout_path %>
    </p>


    保存 show.html.erb。打开 Web Server 手工测试看看,

    $ ruby script/server

    打开浏览器,登录到用户资料查看页面;



    点击“安全退出”链接,我们看到系统将我们带到了用户登录页面;



    再次刷新刚才那个用户资料显示页面,系统给我们呈现的是一张登录表单;事实说明我们已经成功登出了。




    ### 下节预告 ###

    接下来的一章里,我们将会回到发送邮件的操作上,与之前发送激活邮件不同的是,下一次将会给忘记密码的用户发送一封用于找回密码的邮件。所以,我们下一章的主题就是找回密码。


    ### 提交工作成果到GIT仓库 ###

    $ git status
    $ git add .
    $ git commit -m "A user can be logout."
    $ git checkout master
    $ git merge user_logout
    $ git branch -d user_logout
    $ git tag v5


    (注意,真正的开发中可不是到功能开发完毕了才commit,而是边开发边add和commit。为了方便演示编码过程,文章中没有一一列举。)

    标签: CucumberRailsRspecTDD

    作者: fandyst
    出处: http://www.cnblogs.com/todototry/
    关注语言: python、javascript(node.js)、objective-C、java、R、C++
    兴趣点: 互联网、大数据技术、大数据IO瓶颈、col-oriented DB、Key-Value DB、数据挖掘、模式识别、deep learning、开发与成本管理
    产品:
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    <p>1、查询端口号占用,根据端口查看进程信息</p>
    CentOS查询端口占用和清除端口占用的程序
    Spring Boot Maven 打包可执行Jar文件!
    linux下运行jar
    maven 工程mybatis自动生成实体类
    java反射教程
    SQL Server 文件和文件组
    Angular CLI 使用教程指南参考
    mac osx 下 浏览器 开启 java
    es 查询分词字段为空的数据
  • 原文地址:https://www.cnblogs.com/ToDoToTry/p/2173385.html
Copyright © 2011-2022 走看看