Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merged with origin/master

  • Loading branch information...
commit d15893cefec9aabebc24f900b293e8ab766c6644 2 parents 6f7f512 + 1a24b96
@oemera oemera authored
Showing with 851 additions and 23 deletions.
  1. +1 −0  .rspec
  2. +25 −3 Gemfile
  3. +73 −0 Gemfile.lock
  4. +37 −0 Guardfile
  5. BIN  app/assets/images/hackful.png
  6. BIN  app/assets/images/rails.png
  7. BIN  app/assets/images/rss.png
  8. +3 −0  app/assets/javascripts/admin.js.coffee
  9. +3 −0  app/assets/stylesheets/admin.css.scss
  10. +10 −0 app/assets/stylesheets/layout.css.scss
  11. +21 −0 app/controllers/admin_controller.rb
  12. +1 −0  app/controllers/filter_controller.rb
  13. +1 −1  app/controllers/posts_controller.rb
  14. +2 −0  app/helpers/admin_helper.rb
  15. +36 −0 app/mailers/user_mailer.rb
  16. +3 −0  app/models/ability.rb
  17. +3 −0  app/models/admin_auth.rb
  18. +1 −1  app/models/comment.rb
  19. +7 −0 app/models/data_set.rb
  20. +5 −1 app/models/user.rb
  21. +8 −0 app/views/admin/mail.html.erb
  22. +8 −0 app/views/content/stats.html.erb
  23. +5 −0 app/views/devise/registrations/edit.html.erb
  24. +1 −0  app/views/layouts/application.html.erb
  25. +7 −0 app/views/user_mailer/newsletter.html.erb
  26. +7 −0 app/views/user_mailer/newsletter.text.erb
  27. +3 −0  app/views/user_mailer/notify.text.erb
  28. +3 −0  app/views/user_mailer/receive.text.erb
  29. +3 −3 config/cucumber.yml
  30. +11 −0 config/database.yml
  31. +1 −1  config/initializers/devise.rb
  32. +6 −1 config/routes.rb
  33. +11 −0 db/migrate/20120224135606_create_admin_auths.rb
  34. +22 −0 db/migrate/20120226193229_create_delayed_jobs.rb
  35. +16 −0 db/migrate/20120307155241_create_data_sets.rb
  36. +39 −1 db/schema.rb
  37. +11 −0 db/seeds.rb
  38. +30 −0 features/devise.feature
  39. +31 −0 features/posts.feature
  40. +19 −0 features/step_definitions/devise_steps.rb
  41. +3 −0  features/step_definitions/posts_steps.rb
  42. +40 −0 features/step_definitions/shared_steps.rb
  43. +65 −0 features/support/env.rb
  44. +193 −0 spec/controllers/posts_controller_spec.rb
  45. +7 −0 spec/factories/posts.rb
  46. +11 −0 spec/factories/users.rb
  47. +49 −0 spec/spec_helper.rb
  48. +9 −0 spec/support/controller_macros.rb
  49. +0 −11 test/integration/posts_controller_test.rb
View
1  .rspec
@@ -0,0 +1 @@
+--colour
View
28 Gemfile
@@ -7,16 +7,36 @@ gem 'sqlite3'
gem 'json'
group :assets do
- gem 'sass-rails', '~> 3.1.5'
+ gem 'sass-rails', '~> 3.1.5'
gem 'coffee-rails', '~> 3.1.1'
gem 'uglifier', '>= 1.0.3'
end
-group :test do
+group :test, :development do
gem 'cucumber-rails'
+ gem 'database_cleaner'
+ gem 'rspec-rails'
+ gem 'cucumber-rails', require: false
+ gem "factory_girl_rails"
gem 'capybara'
+ gem "capybara-webkit"
+ gem 'fakeweb'
+ gem "launchy"
gem 'database_cleaner', :group => :test
+ gem 'faker'
+ gem 'pry'
gem 'rest-client'
+
+ if RUBY_PLATFORM.downcase.include?("darwin")
+ gem "guard"
+ gem "guard-rspec"
+ gem "guard-cucumber"
+ gem "guard-bundler"
+ gem "guard-spork"
+ gem 'spork'
+ gem 'rb-fsevent'
+ gem 'growl' # also install growlnotify from the Extras/growlnotify/growlnotify.pkg in Growl disk image
+ end
end
gem 'execjs'
@@ -28,4 +48,6 @@ gem 'cancan'
gem 'make_voteable'
gem 'mysql2'
gem 'rails_autolink'
-gem 'rdiscount'
+gem 'rdiscount'
+gem 'delayed_job'
+gem 'delayed_job_active_record'
View
73 Gemfile.lock
@@ -36,6 +36,7 @@ GEM
activesupport (= 3.1.3)
activesupport (3.1.3)
multi_json (~> 1.0)
+ addressable (2.2.7)
arel (2.2.1)
bcrypt-ruby (3.0.1)
builder (3.0.0)
@@ -47,8 +48,12 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
+ capybara-webkit (0.10.1)
+ capybara (>= 1.0.0, < 1.2)
+ json
childprocess (0.3.0)
ffi (~> 1.0.6)
+ coderay (1.0.5)
coffee-rails (3.1.1)
coffee-script (>= 2.2.0)
railties (~> 3.1.0)
@@ -67,6 +72,11 @@ GEM
cucumber (>= 1.1.3)
nokogiri (>= 1.5.0)
database_cleaner (0.7.1)
+ delayed_job (3.0.0)
+ activesupport (~> 3.0)
+ delayed_job_active_record (0.3.1)
+ activerecord (> 2.1.0)
+ delayed_job (~> 3.0.0)
devise (2.0.0)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
@@ -76,15 +86,40 @@ GEM
erubis (2.7.0)
execjs (1.3.0)
multi_json (~> 1.0)
+ factory_girl (2.6.3)
+ activesupport (>= 2.3.9)
+ factory_girl_rails (1.7.0)
+ factory_girl (~> 2.6.0)
+ railties (>= 3.0.0)
+ faker (1.0.1)
+ i18n (~> 0.4)
+ fakeweb (1.3.0)
ffi (1.0.11)
gherkin (2.7.6)
json (>= 1.4.6)
+ growl (1.0.3)
+ guard (1.0.1)
+ ffi (>= 0.5.0)
+ thor (~> 0.14.6)
+ guard-bundler (0.1.3)
+ bundler (>= 1.0.0)
+ guard (>= 0.2.2)
+ guard-cucumber (0.7.5)
+ cucumber (>= 0.10)
+ guard (>= 0.8.3)
+ guard-rspec (0.6.0)
+ guard (>= 0.10.0)
+ guard-spork (0.5.2)
+ guard (>= 0.10.0)
+ spork (>= 0.8.4)
hike (1.2.1)
i18n (0.6.0)
jquery-rails (1.0.19)
railties (~> 3.0)
thor (~> 0.14)
json (1.6.5)
+ launchy (2.0.5)
+ addressable (~> 2.2.6)
libv8 (3.3.10.4)
mail (2.3.0)
i18n (>= 0.4.0)
@@ -92,12 +127,17 @@ GEM
treetop (~> 1.4.8)
make_voteable (0.1.1)
activerecord (~> 3.0)
+ method_source (0.7.1)
mime-types (1.17.2)
multi_json (1.0.4)
mysql2 (0.3.11)
nokogiri (1.5.0)
orm_adapter (0.0.6)
polyglot (0.3.3)
+ pry (0.9.8.4)
+ coderay (~> 1.0.5)
+ method_source (~> 0.7.1)
+ slop (>= 2.4.4, < 3)
rack (1.3.6)
rack-cache (1.1)
rack (>= 0.4)
@@ -125,11 +165,25 @@ GEM
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2.2)
+ rb-fsevent (0.9.0)
rdiscount (1.6.8)
rdoc (3.12)
json (~> 1.4)
rest-client (1.6.7)
mime-types (>= 1.16)
+ rspec (2.8.0)
+ rspec-core (~> 2.8.0)
+ rspec-expectations (~> 2.8.0)
+ rspec-mocks (~> 2.8.0)
+ rspec-core (2.8.0)
+ rspec-expectations (2.8.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.8.0)
+ rspec-rails (2.8.1)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec (~> 2.8.0)
rubyzip (0.9.5)
sass (3.1.12)
sass-rails (3.1.5)
@@ -142,6 +196,8 @@ GEM
ffi (~> 1.0.9)
multi_json (~> 1.0.4)
rubyzip
+ slop (2.4.4)
+ spork (0.9.0)
sprockets (2.0.3)
hike (~> 1.2)
rack (~> 1.0)
@@ -170,21 +226,38 @@ PLATFORMS
DEPENDENCIES
cancan
capybara
+ capybara-webkit
coffee-rails (~> 3.1.1)
cucumber-rails
database_cleaner
+ delayed_job
+ delayed_job_active_record
devise
execjs
+ factory_girl_rails
+ faker
+ fakeweb
+ growl
+ guard
+ guard-bundler
+ guard-cucumber
+ guard-rspec
+ guard-spork
jquery-rails
json
+ launchy
make_voteable
mysql2
nested_form!
+ pry
rails (= 3.1.3)
rails_autolink
+ rb-fsevent
rdiscount
rest-client
+ rspec-rails
sass-rails (~> 3.1.5)
+ spork
sqlite3
therubyracer
uglifier (>= 1.0.3)
View
37 Guardfile
@@ -0,0 +1,37 @@
+# A sample Guardfile
+# More info at https://github.com/guard/guard#readme
+
+guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
+ watch('config/application.rb')
+ watch('config/environment.rb')
+ watch(%r{^config/environments/.+\.rb$})
+ watch(%r{^config/initializers/.+\.rb$})
+ watch('Gemfile')
+ watch('Gemfile.lock')
+ watch('spec/spec_helper.rb') { :rspec }
+ watch('test/test_helper.rb') { :test_unit }
+ watch(%r{features/support/}) { :cucumber }
+end
+
+guard 'rspec', :version => 2 do
+ watch(%r{^spec/.+_spec\.rb$})
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
+ watch('spec/spec_helper.rb') { "spec" }
+
+ # Rails example
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
+ watch('config/routes.rb') { "spec/routing" }
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
+ # Capybara request specs
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
+end
+
+
+guard 'cucumber' do
+ watch(%r{^features/.+\.feature$})
+ watch(%r{^features/support/.+$}) { 'features' }
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
+end
View
BIN  app/assets/images/hackful.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  app/assets/images/rails.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  app/assets/images/rss.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
3  app/assets/javascripts/admin.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
View
3  app/assets/stylesheets/admin.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Admin controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
View
10 app/assets/stylesheets/layout.css.scss
@@ -25,6 +25,16 @@ a:visited {
text-decoration: none;
}
+.notice {
+ font-size: 10pt;
+ padding: {
+ left: 13%;
+ right: 10%;
+ }
+ line-height: 20px;
+ color: #797979;
+}
+
.header {
background: {
color: #EBEBEB;
View
21 app/controllers/admin_controller.rb
@@ -0,0 +1,21 @@
+class AdminController < ApplicationController
+ authorize_resource :class => false
+
+ def mail
+
+ end
+
+ def send_newsletter
+ if user_signed_in?
+ unless params[:test]
+ User.all.each do |user|
+ UserMailer.delay.newsletter(user, params[:subject], params[:text])
+ end
+ else
+ UserMailer.delay.newsletter(current_user, params[:subject], params[:text])
+ end
+ redirect_to "/admin/mail", notice: "Mail sent"
+ end
+ end
+
+end
View
1  app/controllers/filter_controller.rb
@@ -4,6 +4,7 @@ class FilterController < ApplicationController
rescue_from CanCan::AccessDenied do |exception|
flash[:error] = exception.message
+ session[:user_return_to] = request.url
redirect_to new_user_session_path
end
end
View
2  app/controllers/posts_controller.rb
@@ -22,7 +22,7 @@ def show
# GET /posts/new
# GET /posts/new.json
def new
- @post = Post.new
+ @post = Post.new(:link => params[:link], :title => params[:title])
respond_to do |format|
format.html # new.html.erb
View
2  app/helpers/admin_helper.rb
@@ -0,0 +1,2 @@
+module AdminHelper
+end
View
36 app/mailers/user_mailer.rb
@@ -0,0 +1,36 @@
+class UserMailer < ActionMailer::Base
+ helper :application
+
+ default from: "mail@hackful.com"
+
+ def receive(email)
+ commentable_string = email.subject.scan(/\(\w{1,} #\d*\)/mi)[0]
+ commentable_type = commentable_string.scan(/[a-zA-Z]+/mi)[0]
+ commentable_id = commentable_string.scan(/[0-9]{1,}/)[0].to_i
+ text = email.body.decoded.gsub(/(^>.*)|((\w*\s*)[0-9]{1,}.*:$)/mi, "")
+ Comment.new(commentable_type: commentable_type, commentable_id: commentable_id, text: text, user_id: User.find_by_email(email.from.first).id).save! unless User.find_by_email(email.from.first).nil?
+ end
+
+ # Subject can be set in your I18n file at config/locales/en.yml
+ # with the following lookup:
+ #
+ # en.user_mailer.newsletter.subject
+ #
+ def newsletter(user, subject, text)
+ @user = user
+ @text = text
+
+ mail(to: user.email, subject: subject)
+ end
+
+ # Subject can be set in your I18n file at config/locales/en.yml
+ # with the following lookup:
+ #
+ # en.user_mailer.notify.subject
+ #
+ def notify
+ @greeting = "Hi"
+
+ mail to: "to@example.org"
+ end
+end
View
3  app/models/ability.rb
@@ -6,6 +6,9 @@ def initialize(user)
unless user.id.nil?
can [:read, :create, :vote_up, :vote_down], [Post, Comment]
can [:update, :destroy], [Post, Comment], :user_id => user.id
+ user.admin_auths.each do |auth|
+ (defined?(auth.resource.upcase) == "constant") ? (can auth.action.to_sym, auth.resource.constantize) : (can auth.action.to_sym, auth.resource.to_sym)
+ end
end
can [:read], :all
can :create, User
View
3  app/models/admin_auth.rb
@@ -0,0 +1,3 @@
+class AdminAuth < ActiveRecord::Base
+ belongs_to :user
+end
View
2  app/models/comment.rb
@@ -6,7 +6,7 @@ class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
belongs_to :user
- attr_accessible :commentable_type, :commentable_id, :text
+ attr_accessible :commentable_type, :commentable_id, :text, :user_id
has_many :comments, :as => :commentable
View
7 app/models/data_set.rb
@@ -0,0 +1,7 @@
+class DataSet < ActiveRecord::Base
+ #Initial table structure, could be changed in favor of more dynamic structure
+
+ attr_accessible :contact_me, :user_id
+
+ belongs_to :user
+end
View
6 app/models/user.rb
@@ -8,12 +8,16 @@ class User < ActiveRecord::Base
cattr_accessor :current_user
# Setup accessible (or protected) attributes for your model
- attr_accessible :email, :password, :password_confirmation, :remember_me, :name
+ attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :data_set_attributes
has_many :votes, :as => :voteable
has_many :comments
has_many :posts
has_many :notifications, :order => "created_at DESC"
+ has_many :admin_auths
+
+ has_one :data_set
+ accepts_nested_attributes_for :data_set
validates_uniqueness_of :name
validates_format_of :name, :with => /\A[a-zA-Z0-9]+\z/i,
View
8 app/views/admin/mail.html.erb
@@ -0,0 +1,8 @@
+<h1>Mails</h1>
+
+<%= form_tag "/admin/send_newsletter" do %>
+ Test run <%= check_box_tag "test" %><br />
+ <%= text_field_tag :subject %><br />
+ <%= text_area_tag :text %><br /><br />
+ <%= submit_tag "Send" %><br />
+<% end %>
View
8 app/views/content/stats.html.erb
@@ -0,0 +1,8 @@
+<h2>Statistics</h2>
+
+<h3>Comments per day</h3>
+
+<h3>Posts per day</h3>
+
+<h3>Average Comments per post</h3>
+
View
5 app/views/devise/registrations/edit.html.erb
@@ -18,6 +18,11 @@
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></div>
+ <div><%= f.fields_for :data_set do |data_set_form| %>
+ <%= data_set_form.label :contact_me, "Send email notifications" %>
+ <%= data_set_form.check_box :contact_me %>
+ <% end %></div>
+
<div><%= f.submit "Update" %></div>
<% end %>
View
1  app/views/layouts/application.html.erb
@@ -34,6 +34,7 @@
<% end %>
</span>
</div>
+<div class="notice"><%= notice %></div>
<div class="body">
<%= yield %>
</div>
View
7 app/views/user_mailer/newsletter.html.erb
@@ -0,0 +1,7 @@
+Hi <%= @user.name %>.
+
+<%= markdown(@text) %>
+
+------------<br />
+Hackful Europe<br />
+http://hackful.com
View
7 app/views/user_mailer/newsletter.text.erb
@@ -0,0 +1,7 @@
+Hi <%= @user.name %>.
+
+<%= @text %>
+
+------------
+Hackful Europe
+http://hackful.com
View
3  app/views/user_mailer/notify.text.erb
@@ -0,0 +1,3 @@
+UserMailer#notify
+
+<%= @greeting %>, find me in app/views/app/views/user_mailer/notify.text.erb
View
3  app/views/user_mailer/receive.text.erb
@@ -0,0 +1,3 @@
+UserMailer#receive
+
+<%= @greeting %>, find me in app/views/app/views/user_mailer/receive.text.erb
View
6 config/cucumber.yml
@@ -3,6 +3,6 @@ rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
%>
-default: <%= std_opts %> features
-wip: --tags @wip:3 --wip features
-rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
+default: --drb <%= std_opts %> features
+wip: --drb --tags @wip:3 --wip features
+rerun: --drb <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
View
11 config/database.yml
@@ -6,3 +6,14 @@ development:
username: root
password:
socket: /var/run/mysqld/mysqld.sock
+
+test: &test
+ adapter: mysql2
+ encoding: utf8
+ database: hackful_test
+ username: root
+ password:
+ socket: /var/run/mysqld/mysqld.sock
+
+cucumber:
+ <<: *test
View
2  config/initializers/devise.rb
@@ -4,7 +4,7 @@
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
- config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
+ config.mailer_sender = "mail@hackful.com"
# Configure the class responsible to send e-mails.
# config.mailer = "Devise::Mailer"
View
7 config/routes.rb
@@ -1,5 +1,9 @@
Hackful::Application.routes.draw do
- match "/about" => "content#about"
+ get "admin/mail"
+ post "admin/send_newsletter"
+
+ match "/about" => "content#about"
+
match "/user/:name" => "users#show", :as => 'user'
#Voting routes
@@ -16,6 +20,7 @@
resources :posts
devise_for :users
+ resources :users, has_one: :data_set
# /api/<request>
scope 'api' do
View
11 db/migrate/20120224135606_create_admin_auths.rb
@@ -0,0 +1,11 @@
+class CreateAdminAuths < ActiveRecord::Migration
+ def change
+ create_table :admin_auths do |t|
+ t.integer :user_id
+ t.string :resource
+ t.string :action
+
+ t.timestamps
+ end
+ end
+end
View
22 db/migrate/20120226193229_create_delayed_jobs.rb
@@ -0,0 +1,22 @@
+class CreateDelayedJobs < ActiveRecord::Migration
+ def self.up
+ create_table :delayed_jobs, :force => true do |table|
+ table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
+ table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
+ table.text :handler # YAML-encoded string of the object that will do work
+ table.text :last_error # reason for last failure (See Note below)
+ table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
+ table.datetime :locked_at # Set when a client is working on this object
+ table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
+ table.string :locked_by # Who is working on this object (if locked)
+ table.string :queue # The name of the queue this job is in
+ table.timestamps
+ end
+
+ add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
+ end
+
+ def self.down
+ drop_table :delayed_jobs
+ end
+end
View
16 db/migrate/20120307155241_create_data_sets.rb
@@ -0,0 +1,16 @@
+class CreateDataSets < ActiveRecord::Migration
+ def change
+ create_table :data_sets do |t|
+ t.integer :user_id
+ t.boolean :contact_me, default: true
+ t.string :twitter
+ t.string :github
+ t.string :linkedin
+ t.string :url
+ t.string :blog
+ t.text :about_me
+
+ t.timestamps
+ end
+ end
+end
View
40 db/schema.rb
@@ -11,7 +11,15 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120219131606) do
+ActiveRecord::Schema.define(:version => 20120307155241) do
+
+ create_table "admin_auths", :force => true do |t|
+ t.integer "user_id"
+ t.string "resource"
+ t.string "action"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
create_table "comments", :force => true do |t|
t.integer "user_id"
@@ -24,6 +32,36 @@
t.datetime "updated_at"
end
+ create_table "data_sets", :force => true do |t|
+ t.integer "user_id"
+ t.boolean "contact_me", :default => true
+ t.string "twitter"
+ t.string "github"
+ t.string "linkedin"
+ t.string "url"
+ t.string "blog"
+ t.text "about_me"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+>>>>>>> 1a24b96f2e8555e79cf7dc79ddc48efd70ca40fe
+
+ create_table "delayed_jobs", :force => true do |t|
+ t.integer "priority", :default => 0
+ t.integer "attempts", :default => 0
+ t.text "handler"
+ t.text "last_error"
+ t.datetime "run_at"
+ t.datetime "locked_at"
+ t.datetime "failed_at"
+ t.string "locked_by"
+ t.string "queue"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority"
+
create_table "notifications", :force => true do |t|
t.integer "user_id"
t.boolean "unread", :default => true
View
11 db/seeds.rb
@@ -0,0 +1,11 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+#
+# Examples:
+#
+# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
+# Mayor.create(:name => 'Emanuel', :city => cities.first)
+
+User.all.each do |user|
+ DataSet.create(user_id: user.id)
+end
View
30 features/devise.feature
@@ -0,0 +1,30 @@
+Feature: User authentication
+
+ As a user
+ To submit, vote and post news items
+ I want to be able to sign in
+
+ Scenario: Sign up
+ #Issue :
+ #Given I am not authenticated
+ Given I am on the startpage
+ When I click "Sign in"
+ And I click "Sign up"
+ And I fill in new user details
+ Then I should see "Welcome! You have signed up successfully."
+
+ Scenario: Sign in
+ Given I am a new authenticated user
+ Then I should see "Signed in"
+
+ #Issue :
+ #Scenario: Sign out
+ # Given I am a new authenticated user
+ # When I click "Sign out"
+ # Then I should see "Signed out successfully."
+
+ Scenario: Sign out
+ Given I am a new authenticated user
+ When I click "Sign out"
+ Then I should see "Signed out successfully."
+
View
31 features/posts.feature
@@ -0,0 +1,31 @@
+Feature: Submitting news items
+
+ To share news about startup related news in europe
+ As a user
+ I want to be able to submit stories
+
+ Scenario: Submitting
+ Given I am a new authenticated user
+ When I click "submit"
+ And I fill in "Title" with "Hackful integration tests pull request submitted"
+ And I fill in "Text" with "Check out the github issues list to see the pull request"
+ And I fill in "Link" with "https://github.com/8bitpal/hackful/issues"
+ And I click the button "Create Post"
+ Then I should see "Post was successfully created."
+
+ Scenario: Editing
+ Given I am a new authenticated user
+ And I am on the page for a submitted post
+ When I click "Edit"
+ And I fill in "Title" with "Hackful integration tests pull request declined"
+ And I fill in "Text" with "See this example of how not to submit pull requests"
+ And I fill in "Link" with "https://github.com/8bitpal/hackful/pull/41"
+ And I click the button "Update Post"
+ Then I should see "Post was successfully updated."
+
+ Scenario: Editing a post where the user has deleted his account
+ Given I am a new authenticated user
+ And I am on the page for a submitted post
+ And the user has deleted his account
+ When I am on the startpage
+ Then I should see "[Deleted]"
View
19 features/step_definitions/devise_steps.rb
@@ -0,0 +1,19 @@
+When /^I fill in new user details$/ do
+ within(".body") do
+ fill_in 'User Name', with: 'pbjorklund'
+ fill_in 'Email', with: 'p.bjorklund@gmail.com'
+ fill_in 'Password', :with => 'password'
+ fill_in 'Password confirmation', :with => 'password'
+ end
+ click_button "Sign up"
+end
+
+When /^I fill in my user details$/ do
+ within(".body") do
+ fill_in 'User Name', with: 'pbjorklund'
+ fill_in 'Email', with: 'p.bjorklund@gmail.com'
+ fill_in 'Password', :with => 'password'
+ fill_in 'Password confirmation', :with => 'password'
+ end
+ click_button "Sign up"
+end
View
3  features/step_definitions/posts_steps.rb
@@ -0,0 +1,3 @@
+When /^I fill in "([^"]*)" with "([^"]*)"$/ do |field, text|
+ fill_in field, with: text
+end
View
40 features/step_definitions/shared_steps.rb
@@ -0,0 +1,40 @@
+Given /^I am on the startpage$/ do
+ visit "/"
+end
+
+Given /^I am a new authenticated user$/ do
+ email = 'testing@man.net'
+ password = 'secretpass'
+ @user = FactoryGirl.create(:user, email: email, password: password, password_confirmation: password)
+
+ visit '/users/sign_in'
+ fill_in "user_email", :with=>email
+ fill_in "user_password", :with=>password
+ click_button "Sign in"
+end
+
+Given /^I am not authenticated$/ do
+ visit('/users/sign_out')
+end
+
+Given /^I am on the page for a submitted post$/ do
+ post = @user.posts.create(FactoryGirl.build(:post).attributes)
+ visit "/posts/#{post.id}"
+end
+
+
+Given /^the user has deleted his account$/ do
+ User.delete_all
+end
+
+When /^I click "([^"]*)"$/ do |link|
+ click_link link
+end
+
+When /^I click the button "([^"]*)"$/ do |button|
+ click_button button
+end
+
+Then /^I should see "([^"]*)"$/ do |text|
+ page.should have_content(text)
+end
View
65 features/support/env.rb
@@ -0,0 +1,65 @@
+# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
+# It is recommended to regenerate this file in the future when you upgrade to a
+# newer version of cucumber-rails. Consider adding your own code to a new file
+# instead of editing this one. Cucumber will automatically load all features/**/*.rb
+# files.
+
+require 'rubygems'
+require 'spork'
+
+Spork.prefork do
+ require 'cucumber/rails'
+
+
+ # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
+ # order to ease the transition to Capybara we set the default here. If you'd
+ # prefer to use XPath just remove this line and adjust any selectors in your
+ # steps to use the XPath syntax.
+ Capybara.default_selector = :css
+
+end
+
+Spork.each_run do
+ # By default, any exception happening in your Rails application will bubble up
+ # to Cucumber so that your scenario will fail. This is a different from how
+ # your application behaves in the production environment, where an error page will
+ # be rendered instead.
+ #
+ # Sometimes we want to override this default behaviour and allow Rails to rescue
+ # exceptions and display an error page (just like when the app is running in production).
+ # Typical scenarios where you want to do this is when you test your error pages.
+ # There are two ways to allow Rails to rescue exceptions:
+ #
+ # 1) Tag your scenario (or feature) with @allow-rescue
+ #
+ # 2) Set the value below to true. Beware that doing this globally is not
+ # recommended as it will mask a lot of errors for you!
+ #
+ ActionController::Base.allow_rescue = false
+
+ # Remove/comment out the lines below if your app doesn't have a database.
+ # For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
+ begin
+ DatabaseCleaner.strategy = :transaction
+ rescue NameError
+ raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
+ end
+
+ # You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
+ # See the DatabaseCleaner documentation for details. Example:
+ #
+ # Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
+ # DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
+ # end
+ #
+ # Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
+ # DatabaseCleaner.strategy = :transaction
+ # end
+ #
+
+ # Possible values are :truncation and :transaction
+ # The :transaction strategy is faster, but might give you threading problems.
+ # See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature
+ Cucumber::Rails::Database.javascript_strategy = :truncation
+
+end
View
193 spec/controllers/posts_controller_spec.rb
@@ -0,0 +1,193 @@
+require 'spec_helper'
+
+describe PostsController do
+ login_user
+ let(:new_post) { FactoryGirl.create :post, user_id: subject.current_user.id }
+
+ before(:each) do
+ Post.stub(:find).and_return(new_post)
+ end
+
+ describe "GET 'index'" do
+ it "returns http sucess" do
+ get 'index'
+ response.should redirect_to root_path
+ end
+ end
+
+ describe "GET 'show'" do
+ it "gets posts for id" do
+ get 'show', id: "1"
+ response.should be_success
+ end
+
+ it "gets posts for id as JSON" do
+ get 'show', id: "1", format: :json
+ response.should be_success
+ end
+ end
+
+ describe "GET 'new'" do
+ context "when signed in" do
+
+ it "returns http success" do
+ get 'new'
+ response.should be_success
+ end
+
+ it "gets posts for id as JSON" do
+ get 'new'
+ response.should be_success
+ end
+ end
+ context "when not signed in" do
+ it "redirects to signin when requesting html" do
+ controller.stub(:current_user).and_return(nil)
+ get 'new'
+ response.should redirect_to new_user_session_path
+ end
+
+ it "redirects to signin when requesting JSON" do
+ controller.stub(:current_user).and_return(nil)
+ get 'new'
+ response.should redirect_to new_user_session_path
+ end
+ end
+ end
+
+ describe "GET 'edit'" do
+ context "when signed in" do
+ login_user
+
+ it "creates a new post" do
+ get 'edit', id: new_post.id
+ response.should be_success
+ end
+ end
+ context "when not signed in" do
+ it "redirects to signin when requesting html" do
+ controller.stub(:current_user).and_return(nil)
+ get 'edit', id: new_post.id
+ response.should redirect_to new_user_session_path
+ end
+ end
+ end
+
+ describe "POST 'create'" do
+ context "when signed in" do
+ it "sends http success" do
+ post 'create', post: new_post.attributes
+ flash[:notice].should match('Post was successfully created.')
+ response.should redirect_to post_path(assigns[:post])
+ end
+
+ context "on successful save" do
+ it "makes the user upvote the post" do
+ Post.stub(:new).and_return(new_post)
+ subject.current_user.should_receive(:up_vote!).with(new_post)
+ post 'create', post: new_post.attributes
+ end
+
+ it "renders json for post" do
+ post 'create', post: new_post.attributes, format: :json
+ json = JSON.parse(response.body)
+ json["text"].length.should > 0
+ response.status.should == 201
+ end
+ end
+
+ context "on unsuccessful save" do
+ it "renders the new template" do
+ Post.any_instance.stub(:save).and_return(false)
+ post 'create', post: new_post.attributes
+ response.should render_template("new")
+ end
+
+ it "renders json with post.errors" do
+ post 'create', post: { title: "" }, format: :json
+ response.body.should match("too short")
+ response.status.should == 422
+ end
+ end
+ end
+
+ context "when not signed in" do
+ it "redirects to singin_path" do
+ controller.stub(:current_user).and_return(nil)
+ post 'create', post: new_post.attributes
+ response.should redirect_to new_user_session_path
+ end
+ end
+ end
+
+ describe "PUT 'update'" do
+ context "when signed in" do
+ it "sends http success" do
+ put 'update', id: new_post.id
+ flash[:notice].should match('Post was successfully updated.')
+ response.should redirect_to post_path(assigns[:post])
+ end
+
+ context "on successful update" do
+ it "renders json for post" do
+ put 'update', id: new_post.id, format: :json
+ response.body.should == " "
+ response.should be_success
+ end
+ end
+
+ context "on unsuccessful save" do
+ it "renders the edit template" do
+ Post.any_instance.stub(:save).and_return(false)
+ put 'update', id: new_post.id
+ response.should render_template("edit")
+ end
+
+ it "renders json with post.errors" do
+ put 'update', id: new_post.id, post: { link: "none" }, format: :json
+ response.body.should match("is invalid")
+ response.status.should == 422
+ end
+ end
+ end
+
+ context "when not signed in" do
+ it "redirects to singin_path" do
+ controller.stub(:current_user).and_return(nil)
+ put 'update', id: new_post.id
+ response.should redirect_to new_user_session_path
+ end
+ end
+ end
+
+ describe "DELETE 'destroy'" do
+ it "should destroy model and redirect to index action" do
+ delete :destroy, id: new_post.id
+ response.should redirect_to(posts_url)
+ Post.exists?(new_post.id).should be_false
+ end
+
+ it "should redirect to index action when trying to delete non-existant post" do
+ delete :destroy, id: "9999"
+ response.should redirect_to(posts_url)
+ Post.exists?(new_post.id).should be_false
+ end
+ end
+
+ #TODO FIX This is broken. No template to render
+ #describe "#vote_up" do
+ # it "sends vote up message to User" do
+ # get 'vote_up', id: "1", format: :json
+ # subject.current_user.should_receive(:vote_down).once
+ # end
+ #end
+ #
+ ##TODO FIX This is broken. No template to render
+ #describe "#vote_down" do
+ # it "sends vote down message to User" do
+ # get 'vote_down', id: "1", format: :json
+ # subject.current_user.should_receive(:vote_up).once
+ # end
+ # it "does not vote up if the user has already voted"
+ #end
+end
View
7 spec/factories/posts.rb
@@ -0,0 +1,7 @@
+FactoryGirl.define do
+ factory :post do
+ title { FactoryGirl.generate :unique_user_name }
+ text { Faker::Internet.email }
+ link { "http://#{Faker::Internet.domain_name}/#{Faker::Internet.domain_word}" }
+ end
+end
View
11 spec/factories/users.rb
@@ -0,0 +1,11 @@
+FactoryGirl.define do
+ sequence :unique_user_name do |n|
+ Faker::Internet.user_name.delete('^a-zA-Z') + "#{n}"
+ end
+ factory :user do
+ name { FactoryGirl.generate :unique_user_name }
+ email { Faker::Internet.email }
+ password "testing"
+ password_confirmation "testing"
+ end
+end
View
49 spec/spec_helper.rb
@@ -0,0 +1,49 @@
+require 'rubygems'
+require 'spork'
+#uncomment the following line to use spork with the debugger
+#require 'spork/ext/ruby-debug'
+
+Spork.prefork do
+ # Loading more in this block will cause your tests to run faster. However,
+ # if you change any configuration or code from libraries loaded here, you'll
+ # need to restart spork for it take effect.
+
+ ENV["RAILS_ENV"] ||= 'test'
+ require File.expand_path("../../config/environment", __FILE__)
+ require 'rspec/rails'
+ require 'rspec/autorun'
+
+ # Requires supporting ruby files with custom matchers and macros, etc,
+ # in spec/support/ and its subdirectories.
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+
+ RSpec.configure do |config|
+ # ## Mock Framework
+ #
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
+ #
+ # config.mock_with :mocha
+ # config.mock_with :flexmock
+ # config.mock_with :rr
+
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
+ # examples within a transaction, remove the following line or assign false
+ # instead of true.
+ config.use_transactional_fixtures = true
+
+ # If true, the base class of anonymous controllers will be inferred
+ # automatically. This will be the default behavior in future versions of
+ # rspec-rails.
+ config.infer_base_class_for_anonymous_controllers = false
+ config.include Devise::TestHelpers, :type => :controller
+ config.extend ControllerMacros, :type => :controller
+ end
+end
+
+Spork.each_run do
+ # This code will be run each time you run your specs.
+
+end
View
9 spec/support/controller_macros.rb
@@ -0,0 +1,9 @@
+module ControllerMacros
+ def login_user
+ before(:each) do
+ @request.env["devise.mapping"] = Devise.mappings[:user]
+ user = Factory.create(:user)
+ sign_in user
+ end
+ end
+end
View
11 test/integration/posts_controller_test.rb
@@ -1,11 +0,0 @@
-require 'test_helper'
-
-class PostsControllerTest < ActionDispatch::IntegrationTest
- fixtures :all
-
- test "the truth" do
- #user = RestClient.get "/users/TestUser"
- #assert user.name.eql? "TestUser"
- assert true
- end
-end
Please sign in to comment.
Something went wrong with that request. Please try again.