crowdblog 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +8 -0
- data/Gemfile +5 -2
- data/Gemfile.lock +20 -37
- data/README.md +7 -0
- data/Rakefile +5 -2
- data/app/assets/javascripts/crowdblog/templates/posts/edit.jst.eco +1 -1
- data/app/controllers/crowdblog/application_controller.rb +1 -11
- data/app/controllers/crowdblog/sessions_controller.rb +1 -21
- data/app/models/crowdblog/post.rb +53 -44
- data/app/models/crowdblog/user.rb +9 -13
- data/app/views/layouts/crowdblog/application.html.slim +1 -0
- data/config/cucumber.yml +4 -3
- data/config/routes.rb +1 -2
- data/crowdblog.gemspec +6 -2
- data/features/posts/listing.feature +16 -0
- data/features/posts/manage.feature +31 -0
- data/features/posts/publish.feature +17 -0
- data/features/step_definitions/global_steps.rb +19 -0
- data/features/step_definitions/navigation_steps.rb +45 -0
- data/features/step_definitions/posts_steps.rb +113 -20
- data/features/support/env.rb +18 -0
- data/lib/crowdblog/version.rb +1 -1
- data/script/build +5 -1
- data/spec/dummy/app/models/user.rb +12 -0
- data/spec/dummy/config/application.rb +9 -0
- data/spec/dummy/config/initializers/crowdblog.rb +24 -0
- data/spec/dummy/config/initializers/devise.rb +3 -4
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/fabricators/posts_fabricator.rb +21 -0
- data/spec/fabricators/users_fabricator.rb +19 -0
- data/spec/models/post_spec.rb +152 -56
- data/spec/models/user_spec.rb +57 -0
- metadata +116 -60
- data/README.rdoc +0 -3
- data/app/controllers/crowdblog/users/omniauth_callbacks_controller.rb +0 -21
- data/features/posts/manage_posts.feature +0 -46
- data/features/step_definitions/index_steps.rb +0 -16
- data/features/step_definitions/interaction_steps.rb +0 -26
- data/features/step_definitions/session_steps.rb +0 -15
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    CHANGED
    
    | @@ -12,8 +12,7 @@ gem 'carrierwave' | |
| 12 12 | 
             
            gem 'devise'
         | 
| 13 13 | 
             
            gem 'gravtastic'
         | 
| 14 14 | 
             
            gem 'less-rails-bootstrap'
         | 
| 15 | 
            -
            gem ' | 
| 16 | 
            -
            gem 'omniauth-google-oauth2'
         | 
| 15 | 
            +
            gem 'redcarpet'
         | 
| 17 16 | 
             
            gem 'state_machine'
         | 
| 18 17 | 
             
            gem 'slim_assets'
         | 
| 19 18 | 
             
            gem 'slim-rails'
         | 
| @@ -25,6 +24,10 @@ group :assets do | |
| 25 24 | 
             
              gem 'uglifier'
         | 
| 26 25 | 
             
            end
         | 
| 27 26 |  | 
| 27 | 
            +
            group :development, :test do
         | 
| 28 | 
            +
              gem 'rake' # needed for Travis CI: http://bit.ly/xEgH8j
         | 
| 29 | 
            +
            end
         | 
| 30 | 
            +
             | 
| 28 31 | 
             
            # Declare any dependencies that are still in development here instead of in
         | 
| 29 32 | 
             
            # your gemspec. These might include edge Rails or gems from your path or
         | 
| 30 33 | 
             
            # Git. Remember to move these dependencies to your gemspec before releasing
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -9,7 +9,7 @@ GIT | |
| 9 9 | 
             
            PATH
         | 
| 10 10 | 
             
              remote: .
         | 
| 11 11 | 
             
              specs:
         | 
| 12 | 
            -
                crowdblog (0.0. | 
| 12 | 
            +
                crowdblog (0.0.2)
         | 
| 13 13 | 
             
                  backbone-rails
         | 
| 14 14 | 
             
                  carrierwave
         | 
| 15 15 | 
             
                  devise
         | 
| @@ -17,9 +17,8 @@ PATH | |
| 17 17 | 
             
                  gravtastic
         | 
| 18 18 | 
             
                  jquery-rails
         | 
| 19 19 | 
             
                  less-rails-bootstrap
         | 
| 20 | 
            -
                  omniauth-google-apps
         | 
| 21 | 
            -
                  omniauth-google-oauth2
         | 
| 22 20 | 
             
                  rails (~> 3.2)
         | 
| 21 | 
            +
                  redcarpet
         | 
| 23 22 | 
             
                  slim-rails
         | 
| 24 23 | 
             
                  slim_assets
         | 
| 25 24 | 
             
                  state_machine
         | 
| @@ -54,7 +53,6 @@ GEM | |
| 54 53 | 
             
                activesupport (3.2.1)
         | 
| 55 54 | 
             
                  i18n (~> 0.6)
         | 
| 56 55 | 
             
                  multi_json (~> 1.0)
         | 
| 57 | 
            -
                addressable (2.2.7)
         | 
| 58 56 | 
             
                arel (3.0.2)
         | 
| 59 57 | 
             
                backbone-rails (0.9.0)
         | 
| 60 58 | 
             
                  rails (>= 3.0.0)
         | 
| @@ -67,6 +65,9 @@ GEM | |
| 67 65 | 
             
                  rack-test (>= 0.5.4)
         | 
| 68 66 | 
             
                  selenium-webdriver (~> 2.0)
         | 
| 69 67 | 
             
                  xpath (~> 0.1.4)
         | 
| 68 | 
            +
                capybara-webkit (0.10.0)
         | 
| 69 | 
            +
                  capybara (>= 1.0.0, < 1.2)
         | 
| 70 | 
            +
                  json
         | 
| 70 71 | 
             
                carrierwave (0.5.8)
         | 
| 71 72 | 
             
                  activesupport (~> 3.0)
         | 
| 72 73 | 
             
                childprocess (0.3.1)
         | 
| @@ -105,19 +106,21 @@ GEM | |
| 105 106 | 
             
                erubis (2.7.0)
         | 
| 106 107 | 
             
                execjs (1.3.0)
         | 
| 107 108 | 
             
                  multi_json (~> 1.0)
         | 
| 108 | 
            -
                 | 
| 109 | 
            -
             | 
| 110 | 
            -
                   | 
| 111 | 
            -
                  rack (~> 1.1)
         | 
| 109 | 
            +
                fabrication (1.3.1)
         | 
| 110 | 
            +
                faker (1.0.1)
         | 
| 111 | 
            +
                  i18n (~> 0.4)
         | 
| 112 112 | 
             
                ffi (1.0.11)
         | 
| 113 113 | 
             
                fuubar (1.0.0)
         | 
| 114 114 | 
             
                  rspec (~> 2.0)
         | 
| 115 115 | 
             
                  rspec-instafail (~> 0.2.0)
         | 
| 116 116 | 
             
                  ruby-progressbar (~> 0.0.10)
         | 
| 117 | 
            +
                fuubar-cucumber (0.0.15)
         | 
| 118 | 
            +
                  cucumber (>= 1.0.2)
         | 
| 119 | 
            +
                  ruby-progressbar (~> 0.0.10)
         | 
| 117 120 | 
             
                gherkin (2.9.0)
         | 
| 118 121 | 
             
                  json (>= 1.4.6)
         | 
| 119 122 | 
             
                gravtastic (3.2.6)
         | 
| 120 | 
            -
                 | 
| 123 | 
            +
                headless (0.2.2)
         | 
| 121 124 | 
             
                hike (1.2.1)
         | 
| 122 125 | 
             
                i18n (0.6.0)
         | 
| 123 126 | 
             
                journey (1.0.2)
         | 
| @@ -141,35 +144,12 @@ GEM | |
| 141 144 | 
             
                  treetop (~> 1.4.8)
         | 
| 142 145 | 
             
                mime-types (1.17.2)
         | 
| 143 146 | 
             
                multi_json (1.1.0)
         | 
| 144 | 
            -
                multipart-post (1.1.5)
         | 
| 145 147 | 
             
                nokogiri (1.5.0)
         | 
| 146 | 
            -
                oauth2 (0.5.2)
         | 
| 147 | 
            -
                  faraday (~> 0.7)
         | 
| 148 | 
            -
                  multi_json (~> 1.0)
         | 
| 149 | 
            -
                omniauth (1.0.2)
         | 
| 150 | 
            -
                  hashie (~> 1.2)
         | 
| 151 | 
            -
                  rack
         | 
| 152 | 
            -
                omniauth-google-apps (0.0.1)
         | 
| 153 | 
            -
                  omniauth (~> 1.0)
         | 
| 154 | 
            -
                  omniauth-openid (~> 1.0)
         | 
| 155 | 
            -
                  ruby-openid-apps-discovery (~> 1.2.0)
         | 
| 156 | 
            -
                omniauth-google-oauth2 (0.1.9)
         | 
| 157 | 
            -
                  omniauth (~> 1.0)
         | 
| 158 | 
            -
                  omniauth-oauth2
         | 
| 159 | 
            -
                omniauth-oauth2 (1.0.0)
         | 
| 160 | 
            -
                  oauth2 (~> 0.5.0)
         | 
| 161 | 
            -
                  omniauth (~> 1.0)
         | 
| 162 | 
            -
                omniauth-openid (1.0.1)
         | 
| 163 | 
            -
                  omniauth (~> 1.0)
         | 
| 164 | 
            -
                  rack-openid (~> 1.3.1)
         | 
| 165 148 | 
             
                orm_adapter (0.0.6)
         | 
| 166 149 | 
             
                polyglot (0.3.3)
         | 
| 167 150 | 
             
                rack (1.4.1)
         | 
| 168 151 | 
             
                rack-cache (1.1)
         | 
| 169 152 | 
             
                  rack (>= 0.4)
         | 
| 170 | 
            -
                rack-openid (1.3.1)
         | 
| 171 | 
            -
                  rack (>= 1.1.0)
         | 
| 172 | 
            -
                  ruby-openid (>= 2.1.8)
         | 
| 173 153 | 
             
                rack-ssl (1.3.2)
         | 
| 174 154 | 
             
                  rack
         | 
| 175 155 | 
             
                rack-test (0.6.1)
         | 
| @@ -192,6 +172,7 @@ GEM | |
| 192 172 | 
             
                rake (0.9.2.2)
         | 
| 193 173 | 
             
                rdoc (3.12)
         | 
| 194 174 | 
             
                  json (~> 1.4)
         | 
| 175 | 
            +
                redcarpet (2.1.0)
         | 
| 195 176 | 
             
                rspec (2.8.0)
         | 
| 196 177 | 
             
                  rspec-core (~> 2.8.0)
         | 
| 197 178 | 
             
                  rspec-expectations (~> 2.8.0)
         | 
| @@ -206,9 +187,6 @@ GEM | |
| 206 187 | 
             
                  activesupport (>= 3.0)
         | 
| 207 188 | 
             
                  railties (>= 3.0)
         | 
| 208 189 | 
             
                  rspec (~> 2.8.0)
         | 
| 209 | 
            -
                ruby-openid (2.1.8)
         | 
| 210 | 
            -
                ruby-openid-apps-discovery (1.2.0)
         | 
| 211 | 
            -
                  ruby-openid (>= 2.1.7)
         | 
| 212 190 | 
             
                ruby-progressbar (0.0.10)
         | 
| 213 191 | 
             
                rubyzip (0.9.6.1)
         | 
| 214 192 | 
             
                sass (3.1.15)
         | 
| @@ -266,6 +244,7 @@ PLATFORMS | |
| 266 244 |  | 
| 267 245 | 
             
            DEPENDENCIES
         | 
| 268 246 | 
             
              backbone-rails
         | 
| 247 | 
            +
              capybara-webkit
         | 
| 269 248 | 
             
              carrierwave
         | 
| 270 249 | 
             
              coffee-rails
         | 
| 271 250 | 
             
              crowdblog!
         | 
| @@ -273,12 +252,16 @@ DEPENDENCIES | |
| 273 252 | 
             
              database_cleaner
         | 
| 274 253 | 
             
              devise
         | 
| 275 254 | 
             
              eco
         | 
| 255 | 
            +
              fabrication
         | 
| 256 | 
            +
              faker
         | 
| 276 257 | 
             
              fuubar
         | 
| 258 | 
            +
              fuubar-cucumber
         | 
| 277 259 | 
             
              gravtastic
         | 
| 260 | 
            +
              headless
         | 
| 278 261 | 
             
              jquery-rails
         | 
| 279 262 | 
             
              less-rails-bootstrap
         | 
| 280 | 
            -
               | 
| 281 | 
            -
               | 
| 263 | 
            +
              rake
         | 
| 264 | 
            +
              redcarpet
         | 
| 282 265 | 
             
              rspec-rails
         | 
| 283 266 | 
             
              sass-rails
         | 
| 284 267 | 
             
              simplecov
         | 
    
        data/README.md
    ADDED
    
    
    
        data/Rakefile
    CHANGED
    
    | @@ -28,5 +28,8 @@ Bundler::GemHelper.install_tasks | |
| 28 28 | 
             
            require 'rspec/core/rake_task'
         | 
| 29 29 | 
             
            RSpec::Core::RakeTask.new(:spec)
         | 
| 30 30 |  | 
| 31 | 
            -
            #  | 
| 32 | 
            -
            task : | 
| 31 | 
            +
            # Alias for Cucumber
         | 
| 32 | 
            +
            task :cucumber => 'app:cucumber'
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            # RSpec and Cucumber by default
         | 
| 35 | 
            +
            task :default => [:spec, :cucumber]
         | 
| @@ -1,16 +1,6 @@ | |
| 1 1 | 
             
            module Crowdblog
         | 
| 2 2 | 
             
              class ApplicationController < ActionController::Base
         | 
| 3 | 
            +
                include Crowdblog::Devise::Auth
         | 
| 3 4 | 
             
                before_filter :authenticate!
         | 
| 4 | 
            -
             | 
| 5 | 
            -
                def authenticate!
         | 
| 6 | 
            -
                  unless user_signed_in?
         | 
| 7 | 
            -
                    current_user = User.find_by_email('foo@crowdint.com') || User.create!(email: 'foo@crowdint.com', is_publisher: true)
         | 
| 8 | 
            -
                    sign_in current_user
         | 
| 9 | 
            -
                  end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  #TODO: fix OAuth
         | 
| 12 | 
            -
                  #redirect_to user_omniauth_authorize_path(:google_apps) unless current_user
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 5 | 
             
              end
         | 
| 16 6 | 
             
            end
         | 
| @@ -1,25 +1,5 @@ | |
| 1 1 | 
             
            module  Crowdblog
         | 
| 2 2 | 
             
              class SessionsController < ApplicationController
         | 
| 3 | 
            -
             | 
| 4 | 
            -
                def authenticate_user
         | 
| 5 | 
            -
                  auth_hash = request.env['omniauth.auth']
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                  if allowed?
         | 
| 8 | 
            -
                    Rails.logger.info auth_hash.info
         | 
| 9 | 
            -
                    email = auth_hash.info['email']
         | 
| 10 | 
            -
                    user = User.find_by_email(email)
         | 
| 11 | 
            -
                    user ||= User.create!(email: email, name: auth_hash.info['name'])
         | 
| 12 | 
            -
                    sign_in user
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                    redirect_to root_url
         | 
| 15 | 
            -
                  else
         | 
| 16 | 
            -
                    render :text => '401 Unauthorized', :status => 401
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                def allowed?
         | 
| 21 | 
            -
                  true
         | 
| 22 | 
            -
                end
         | 
| 23 | 
            -
             | 
| 3 | 
            +
                include Crowdblog::Devise::Sessions
         | 
| 24 4 | 
             
              end
         | 
| 25 5 | 
             
            end
         | 
| @@ -28,59 +28,66 @@ module  Crowdblog | |
| 28 28 | 
             
                    post.published_at ||= Time.now
         | 
| 29 29 | 
             
                  end
         | 
| 30 30 |  | 
| 31 | 
            -
                  event :publish do
         | 
| 32 | 
            -
                    transition drafted: :published
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
             | 
| 35 31 | 
             
                  event :draft do
         | 
| 36 32 | 
             
                    transition published: :drafted
         | 
| 37 33 | 
             
                  end
         | 
| 38 | 
            -
                end
         | 
| 39 34 |  | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 35 | 
            +
                  event :publish do
         | 
| 36 | 
            +
                    transition drafted: :published
         | 
| 37 | 
            +
                  end
         | 
| 43 38 | 
             
                end
         | 
| 44 39 |  | 
| 45 | 
            -
                 | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 40 | 
            +
                # CLASS METHODS
         | 
| 41 | 
            +
                class << self
         | 
| 42 | 
            +
                  def all_posts_json
         | 
| 43 | 
            +
                    order_by_publish_date.to_json only: [:id, :title, :state, :published_at],
         | 
| 44 | 
            +
                                                  methods: [:author_email, :published?]
         | 
| 45 | 
            +
                  end
         | 
| 48 46 |  | 
| 47 | 
            +
                  def last_published(number)
         | 
| 48 | 
            +
                    published_and_ordered.limit(number)
         | 
| 49 | 
            +
                  end
         | 
| 49 50 |  | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 51 | 
            +
                  def order_by_publish_date
         | 
| 52 | 
            +
                    order('published_at DESC, created_at DESC, id DESC')
         | 
| 53 | 
            +
                  end
         | 
| 53 54 |  | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 55 | 
            +
                  def published
         | 
| 56 | 
            +
                    where(state: 'published')
         | 
| 57 | 
            +
                  end
         | 
| 57 58 |  | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 59 | 
            +
                  def published_and_ordered
         | 
| 60 | 
            +
                    published.order_by_publish_date.includes(:author)
         | 
| 61 | 
            +
                  end
         | 
| 61 62 |  | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 63 | 
            +
                  def scoped_for(user)
         | 
| 64 | 
            +
                    user.is_publisher? ? Post : user.authored_posts
         | 
| 65 | 
            +
                  end
         | 
| 64 66 | 
             
                end
         | 
| 65 67 |  | 
| 66 | 
            -
                 | 
| 67 | 
            -
             | 
| 68 | 
            -
                 | 
| 68 | 
            +
                # Must be after Class methods (otherwise a missing method error will raise)
         | 
| 69 | 
            +
                scope :for_index,     last_published(3)
         | 
| 70 | 
            +
                scope :for_history,   last_published(13)
         | 
| 71 | 
            +
                scope :all_for_feed,  last_published(15)
         | 
| 72 | 
            +
             | 
| 69 73 |  | 
| 74 | 
            +
                # INSTANCE METHODS
         | 
| 70 75 | 
             
                def allowed_to_update_permalink?
         | 
| 71 76 | 
             
                  !self.published?
         | 
| 72 77 | 
             
                end
         | 
| 73 78 |  | 
| 74 | 
            -
                def  | 
| 75 | 
            -
                   | 
| 79 | 
            +
                def day
         | 
| 80 | 
            +
                  "%02d" % published_at.day
         | 
| 76 81 | 
             
                end
         | 
| 77 82 |  | 
| 78 | 
            -
                def  | 
| 79 | 
            -
                  "% | 
| 83 | 
            +
                def formatted_published_date
         | 
| 84 | 
            +
                  published_at.strftime("%b %d, %Y")
         | 
| 80 85 | 
             
                end
         | 
| 81 86 |  | 
| 82 | 
            -
                def  | 
| 83 | 
            -
                   | 
| 87 | 
            +
                def html_body
         | 
| 88 | 
            +
                  @@renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML,
         | 
| 89 | 
            +
                                                         :autolink => true, :space_after_headers => true)
         | 
| 90 | 
            +
                  @@renderer.render(self.body).html_safe
         | 
| 84 91 | 
             
                end
         | 
| 85 92 |  | 
| 86 93 | 
             
                def legacy(string, email)
         | 
| @@ -93,6 +100,21 @@ module  Crowdblog | |
| 93 100 | 
             
                  self.update_attribute(:permalink, results[2])
         | 
| 94 101 | 
             
                end
         | 
| 95 102 |  | 
| 103 | 
            +
                def month
         | 
| 104 | 
            +
                  "%02d" % published_at.month
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                def publish_if_allowed(transition, user)
         | 
| 108 | 
            +
                  if user.is_publisher?
         | 
| 109 | 
            +
                    self.publisher = user
         | 
| 110 | 
            +
                    self.send(transition)
         | 
| 111 | 
            +
                  end
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                def regenerate_permalink
         | 
| 115 | 
            +
                  self.permalink = title.parameterize
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 96 118 | 
             
                #
         | 
| 97 119 | 
             
                # Use this methods to generate the post url
         | 
| 98 120 | 
             
                # always use with the splat
         | 
| @@ -104,18 +126,5 @@ module  Crowdblog | |
| 104 126 | 
             
                def url_params
         | 
| 105 127 | 
             
                  [self.year, self.month, self.day, self.permalink, 'html']
         | 
| 106 128 | 
             
                end
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                def html_body
         | 
| 109 | 
            -
                  @@renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML,
         | 
| 110 | 
            -
                      :autolink => true, :space_after_headers => true)
         | 
| 111 | 
            -
                  @@renderer.render(self.body).html_safe
         | 
| 112 | 
            -
                end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                def publish_if_allowed(transition, user)
         | 
| 115 | 
            -
                  if user.is_publisher?
         | 
| 116 | 
            -
                    self.publisher = user
         | 
| 117 | 
            -
                    self.send(transition)
         | 
| 118 | 
            -
                  end
         | 
| 119 | 
            -
                end
         | 
| 120 129 | 
             
              end
         | 
| 121 130 | 
             
            end
         | 
| @@ -4,28 +4,24 @@ module  Crowdblog | |
| 4 4 | 
             
                include Gravtastic
         | 
| 5 5 |  | 
| 6 6 | 
             
                has_many :authored_posts, inverse_of: :author, foreign_key: 'author_id', class_name: 'Post'
         | 
| 7 | 
            +
                has_one  :last_post, class_name: 'Post', foreign_key: :author_id, conditions: ['state = ?', 'published'], order: 'published_at DESC, created_at DESC, id DESC'
         | 
| 7 8 |  | 
| 8 | 
            -
                 | 
| 9 | 
            -
                # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
         | 
| 10 | 
            -
                devise :database_authenticatable, :token_authenticatable, :trackable, :omniauthable
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                # Setup accessible (or protected) attributes for your model
         | 
| 13 | 
            -
                attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :is_publisher
         | 
| 9 | 
            +
                devise :database_authenticatable, :token_authenticatable
         | 
| 14 10 |  | 
| 15 11 | 
             
                gravtastic :gravatar_email
         | 
| 16 12 |  | 
| 17 | 
            -
                validate :email, uniqueness: true
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                def publisher!
         | 
| 20 | 
            -
                  update_attribute(:is_publisher, true)
         | 
| 21 | 
            -
                end
         | 
| 22 13 |  | 
| 14 | 
            +
                # INSTANCE METHODS
         | 
| 23 15 | 
             
                def gravatar_email
         | 
| 24 | 
            -
                   | 
| 16 | 
            +
                  gravatar_alias || email
         | 
| 25 17 | 
             
                end
         | 
| 26 18 |  | 
| 27 19 | 
             
                def last_post_at
         | 
| 28 | 
            -
                   | 
| 20 | 
            +
                  last_post.try(:published_at)
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def publisher!
         | 
| 24 | 
            +
                  update_attribute(:is_publisher, true)
         | 
| 29 25 | 
             
                end
         | 
| 30 26 | 
             
              end
         | 
| 31 27 | 
             
            end
         | 
    
        data/config/cucumber.yml
    CHANGED
    
    | @@ -1,8 +1,9 @@ | |
| 1 1 | 
             
            <%
         | 
| 2 | 
            +
            require 'fuubar-cucumber'
         | 
| 2 3 | 
             
            rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
         | 
| 3 4 | 
             
            rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
         | 
| 4 | 
            -
            std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || ' | 
| 5 | 
            +
            std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'fuubar'} --color --strict --tags ~@wip -r features/"
         | 
| 5 6 | 
             
            %>
         | 
| 6 7 | 
             
            default: <%= std_opts %> features
         | 
| 7 | 
            -
            wip: --color --tags @wip:3 --wip features
         | 
| 8 | 
            -
            rerun: <%= rerun_opts %> --color --format rerun --out rerun.txt --strict --tags ~@wip
         | 
| 8 | 
            +
            wip: --color -r features/ --tags @wip:3 --wip features
         | 
| 9 | 
            +
            rerun: <%= rerun_opts %> --color -r features/ --format rerun --out rerun.txt --strict --tags ~@wip
         | 
    
        data/config/routes.rb
    CHANGED
    
    
    
        data/crowdblog.gemspec
    CHANGED
    
    | @@ -29,15 +29,19 @@ Gem::Specification.new do |s| | |
| 29 29 | 
             
              s.add_dependency 'eco'
         | 
| 30 30 | 
             
              s.add_dependency 'gravtastic'
         | 
| 31 31 | 
             
              s.add_dependency 'less-rails-bootstrap'
         | 
| 32 | 
            -
              s.add_dependency ' | 
| 33 | 
            -
              s.add_dependency 'omniauth-google-oauth2'
         | 
| 32 | 
            +
              s.add_dependency 'redcarpet'
         | 
| 34 33 | 
             
              s.add_dependency 'slim_assets'
         | 
| 35 34 | 
             
              s.add_dependency 'slim-rails'
         | 
| 36 35 | 
             
              s.add_dependency 'state_machine'
         | 
| 37 36 |  | 
| 37 | 
            +
              s.add_development_dependency 'capybara-webkit'
         | 
| 38 38 | 
             
              s.add_development_dependency 'cucumber-rails'
         | 
| 39 39 | 
             
              s.add_development_dependency 'database_cleaner'
         | 
| 40 | 
            +
              s.add_development_dependency 'fabrication'
         | 
| 41 | 
            +
              s.add_development_dependency 'faker'
         | 
| 40 42 | 
             
              s.add_development_dependency 'fuubar'
         | 
| 43 | 
            +
              s.add_development_dependency 'fuubar-cucumber'
         | 
| 44 | 
            +
              s.add_development_dependency 'headless'
         | 
| 41 45 | 
             
              s.add_development_dependency 'rspec-rails'
         | 
| 42 46 | 
             
              s.add_development_dependency 'simplecov'
         | 
| 43 47 | 
             
              s.add_development_dependency 'simplecov-rcov-text'
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            @javascript
         | 
| 2 | 
            +
            Feature: Posts Listing
         | 
| 3 | 
            +
              As a User
         | 
| 4 | 
            +
              I should only see my own posts
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              Background:
         | 
| 7 | 
            +
                Given the Test Post exists
         | 
| 8 | 
            +
                  And a Post from other User exists
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              Scenario: Show only User Posts
         | 
| 11 | 
            +
                When I am signed in as Test User
         | 
| 12 | 
            +
                Then I should only see my Posts
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              Scenario: Publishers can see all Posts
         | 
| 15 | 
            +
                When I am signed in as Publisher User
         | 
| 16 | 
            +
                Then I should see Posts for all Users
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            @javascript
         | 
| 2 | 
            +
            Feature: Manage Posts
         | 
| 3 | 
            +
              As a User
         | 
| 4 | 
            +
              I want to be able to manage Posts (CRUD)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              Background:
         | 
| 7 | 
            +
                Given the Test User exists
         | 
| 8 | 
            +
                  And the Test Post exists
         | 
| 9 | 
            +
                  And I am signed in as Test User
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              Scenario: New Post
         | 
| 12 | 
            +
                Given I am on the New Post page
         | 
| 13 | 
            +
                When I write a Post
         | 
| 14 | 
            +
                Then I should see my New Post
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              Scenario: Edit Post
         | 
| 17 | 
            +
                Given I am on the Edit Post page
         | 
| 18 | 
            +
                When I edit the Test Post
         | 
| 19 | 
            +
                Then I should see the Test Post changed
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              Scenario: Delete Posts
         | 
| 22 | 
            +
                When I delete the Test Post
         | 
| 23 | 
            +
                Then I should not see the Test Post
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              Scenario: Navigate to New Post
         | 
| 26 | 
            +
                When I navigate to New Post
         | 
| 27 | 
            +
                Then I should see the New Post page
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              Scenario: Navigate to Edit Post
         | 
| 30 | 
            +
                When I navigate to Edit Post
         | 
| 31 | 
            +
                Then I should see the Edit Post page
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            @javascript
         | 
| 2 | 
            +
            Feature: Posts Publication
         | 
| 3 | 
            +
              As a Publisher
         | 
| 4 | 
            +
              I want to be able to publish drafted Posts
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              Background:
         | 
| 7 | 
            +
                Given the Test Post exists
         | 
| 8 | 
            +
                  And the Published Post exists
         | 
| 9 | 
            +
                  And I am signed in as Publisher User
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              Scenario: Publish a Post
         | 
| 12 | 
            +
                When I Publish a drafted Post
         | 
| 13 | 
            +
                Then I should see the Post as Published
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              Scenario: Un-Publish a Post
         | 
| 16 | 
            +
                When I Draft a published Post
         | 
| 17 | 
            +
                Then I should see the Post as Drafted
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            Given /^(?:|I )am signed in as (Test|Publisher) User$/ do |user_type|
         | 
| 2 | 
            +
              step "#{user_type} User exists"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              @current_user.authentication_token.should be_present
         | 
| 5 | 
            +
              visit crowdblog_path + "?auth_token=#{@current_user.authentication_token}"
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            Given /^(?:|the )Test User exists$/ do
         | 
| 9 | 
            +
              @current_user = Crowdblog::User.find_by_email('test@crowdint.com')
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              @current_user = Fabricate(:user_test) unless @current_user
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Given /^(?:|the )Publisher User exists$/ do
         | 
| 15 | 
            +
              @current_user = Crowdblog::User.find_by_email('publisher@crowdint.com')
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              @current_user = Fabricate(:user_publisher) unless @current_user
         | 
| 18 | 
            +
              @publisher_user = @current_user
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            #*****************
         | 
| 2 | 
            +
            #   GIVEN steps
         | 
| 3 | 
            +
            #-----------------
         | 
| 4 | 
            +
            Given /^(?:|I )(?:go to|am on) the posts page$/ do
         | 
| 5 | 
            +
              visit posts_path
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            Given /^(?:|I )am on the Edit Post page$/ do
         | 
| 9 | 
            +
              @post.should_not be_nil
         | 
| 10 | 
            +
              visit posts_path + "#edit/#{@post.id}"
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            Given /^(?:|I )am on the New Post page$/ do
         | 
| 14 | 
            +
              visit posts_path + '#new'
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
             | 
| 18 | 
            +
            #*****************
         | 
| 19 | 
            +
            #   WHEN steps
         | 
| 20 | 
            +
            #-----------------
         | 
| 21 | 
            +
            When /^(?:|I )confirm the popup dialog$/ do
         | 
| 22 | 
            +
              if Capybara.javascript_driver == :selenium
         | 
| 23 | 
            +
                page.driver.browser.switch_to.alert.accept
         | 
| 24 | 
            +
              else
         | 
| 25 | 
            +
                page.execute_script 'window.confirm = function() { return true }'
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            When /^(?:|I )navigate to Edit Post$/ do
         | 
| 30 | 
            +
              post = page.find('#posts table tr', text: 'This is a Test Post')
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              post.click_link 'Edit'
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            When /^(?:|I )navigate to New Post$/ do
         | 
| 36 | 
            +
              click_link 'New Post'
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
             | 
| 40 | 
            +
            #*****************
         | 
| 41 | 
            +
            #   THEN steps
         | 
| 42 | 
            +
            #-----------------
         | 
| 43 | 
            +
            #Then /^show me the page$/ do
         | 
| 44 | 
            +
            #  save_and_open_page
         | 
| 45 | 
            +
            #end
         |