kitestrings 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +10 -0
  4. data/kitestrings.gemspec +0 -2
  5. data/lib/generators/kitestrings/install_generator.rb +26 -6
  6. data/lib/generators/kitestrings/message_templates/default.text.erb +7 -0
  7. data/lib/generators/kitestrings/message_templates/index.html.haml +26 -0
  8. data/lib/generators/kitestrings/{templates → message_templates}/message.rb.erb +19 -2
  9. data/lib/generators/kitestrings/message_templates/message_mailer.rb +19 -0
  10. data/lib/generators/kitestrings/message_templates/message_migration.rb +20 -0
  11. data/lib/generators/kitestrings/message_templates/message_spec.rb +73 -0
  12. data/lib/generators/kitestrings/message_templates/messages.rb +11 -0
  13. data/lib/generators/kitestrings/message_templates/messages_controller.rb +41 -0
  14. data/lib/generators/kitestrings/message_templates/messages_controller_spec.rb +86 -0
  15. data/lib/generators/kitestrings/message_templates/show.html.haml +32 -0
  16. data/lib/generators/kitestrings/messages_generator.rb +64 -1
  17. data/lib/generators/templates/{deploy.rb → config/deploy.rb} +19 -16
  18. data/lib/generators/templates/config/deploy/integ.rb +3 -0
  19. data/lib/generators/templates/config/deploy/production.rb +12 -0
  20. data/lib/generators/templates/config/deploy/uat.rb +3 -0
  21. data/lib/generators/templates/config/environments/integ.rb +21 -0
  22. data/lib/generators/templates/config/environments/uat.rb +21 -0
  23. data/lib/generators/templates/views/public/403.html +30 -0
  24. data/lib/kitestrings/menu.rb +10 -0
  25. data/lib/kitestrings/menu/admin_controller.rb +21 -0
  26. data/lib/kitestrings/menu/controller.rb +24 -0
  27. data/lib/kitestrings/menu/item.rb +94 -0
  28. data/lib/kitestrings/menu/item_collection.rb +29 -0
  29. data/lib/kitestrings/menu/model.rb +29 -0
  30. data/lib/kitestrings/menu/view_helper.rb +68 -0
  31. data/lib/kitestrings/version.rb +1 -1
  32. data/spec/lib/generators/kitestrings/install_generator_spec.rb +17 -13
  33. data/spec/lib/generators/kitestrings/messages_generator_spec.rb +31 -3
  34. data/spec/lib/kitestrings/menu/model_spec.rb +33 -0
  35. data/spec/support/active_record.rb +0 -1
  36. data/spec/support/generator_support.rb +15 -0
  37. metadata +30 -35
  38. data/lib/generators/templates/deploy/integ.rb +0 -21
  39. data/lib/generators/templates/deploy/production.rb +0 -26
  40. data/lib/generators/templates/deploy/uat.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f8cfadafb753d3b207291378f33d28c54544695
4
- data.tar.gz: 353789de7071c765b2a09134199761d43b1b2220
3
+ metadata.gz: e359fb5855cd726d02dd9c2a51508e1d0a3bb848
4
+ data.tar.gz: 2cf04623592f47430d13f1da9c0bf81f3f78c122
5
5
  SHA512:
6
- metadata.gz: 8954419b577c34c1e9cf80930521ee623e01a6cd58aec11e7fd87c3b488e5da53ac8555342b1c52ec0f4a329cd14cb726df826201ed9383240451eec757ba1ce
7
- data.tar.gz: a9f4038bc92af401e244105262d79bb6b138881c08090612eb542db17fb07363d2017ad86ee0c5dd7d5bcecb713521816188b05a56f27917ed483238a8d3253a
6
+ metadata.gz: 9b02af42e038270039c4ce945729900c9c232086708c53988221bc26f3380367c44501b3c5c4b22641df175a2fe8406f631216fc4654d7b2fd6c7602c8c5a8d5
7
+ data.tar.gz: fa7776a4bc5cab3baf5b54cd82f0959b3b3215b70ffad2cbe96a9308f059c03eeee76f21396d0922a2e0ff39e5d3c971f21ecb54d741a2cb772ae7c56e0ca568
data/.gitignore CHANGED
@@ -21,3 +21,4 @@ tmp
21
21
  *.a
22
22
  mkmf.log
23
23
  .idea
24
+ tmp/
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Version history:
2
2
 
3
+ ## Next
4
+
5
+ * Added Kitestrings::Menu classes/modules to assist with rendering menus in web pages.
6
+ * Added generator: kitestrings:messages to add a scaffold model and controller.
7
+
8
+ ## 1.0.3
9
+
10
+ * Added an Access Denied page to be shown when a CanCan::AccessDenied error occurs (except in develop/test)
11
+ * Added UAT and INTEG environments and deploy files to install generator.
12
+
3
13
  ## 1.0.2
4
14
 
5
15
  * Added FormObject#update to behave like persisted active record model objects.
data/kitestrings.gemspec CHANGED
@@ -19,12 +19,10 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_runtime_dependency "rails", ">= 3.2"
22
- spec.add_runtime_dependency "activemodel", ">= 3.2"
23
22
 
24
23
  spec.add_development_dependency "bundler", "~> 1.6"
25
24
  spec.add_development_dependency "rake"
26
25
  spec.add_development_dependency "rspec", "~> 2.14"
27
26
  spec.add_development_dependency "generator_spec"
28
27
  spec.add_development_dependency "sqlite3"
29
- spec.add_development_dependency "activerecord", ">= 3.2"
30
28
  end
@@ -8,12 +8,10 @@ module Kitestrings
8
8
 
9
9
  desc "Copies 2rk relevant templates to the relevant directory"
10
10
 
11
- def copy_deploy
12
- copy_file "deploy.rb", "config/deploy.rb"
13
- end
14
-
15
- def copy_deploy_files
16
- directory "deploy", "config/deploy"
11
+ def copy_config_files
12
+ copy_file "config/deploy.rb", "config/deploy.rb"
13
+ directory "config/deploy", "config/deploy"
14
+ directory "config/environments", "config/environments"
17
15
  end
18
16
 
19
17
  def copy_haml_files
@@ -35,6 +33,28 @@ module Kitestrings
35
33
  def copy_app_view_files
36
34
  copy_file "views/application/_navigation.html.haml", "app/views/application/_navigation.html.haml"
37
35
  copy_file "views/layouts/application.html.haml", "app/views/layouts/application.html.haml"
36
+ copy_file "views/public/403.html", "app/views/public/403.html"
37
+ end
38
+
39
+ def setup_application_controller
40
+ inject_into_file "app/controllers/application_controller.rb", :after => /protect_from_forgery.*$/ do
41
+ <<-EOF
42
+
43
+
44
+ unless Rails.application.config.consider_all_requests_local
45
+ rescue_from CanCan::AccessDenied do |exception|
46
+ # Notify errbit if you would like to:
47
+ # Airbrake.notify(exception)
48
+ render 'public/403', status: 403, layout: 'none'
49
+ end
50
+ end
51
+ EOF
52
+ end
53
+ end
54
+
55
+ def setup_directories
56
+ empty_directory("lib/capistrano")
57
+ create_file("lib/capistrano/.keep")
38
58
  end
39
59
  end
40
60
  end
@@ -0,0 +1,7 @@
1
+ <%- @message.subject = "Message" %>
2
+
3
+ Message link: <%= @message.view_link %>
4
+
5
+
6
+ -----------
7
+ example.com
@@ -0,0 +1,26 @@
1
+ .page-header
2
+ %h1 Listing messages
3
+
4
+ .row
5
+ .col-md-12
6
+ %table.table.table-striped
7
+ %tr
8
+ %th.subject= sortable_title :subject
9
+ %th= sortable_title :sent_at
10
+ %th= sortable_title :user_name
11
+ %th Link
12
+ %th= sortable_title :clicked_at
13
+ %th= sortable_title :id
14
+
15
+ - @messages.each do |message|
16
+ %tr
17
+ %td.subject= message.user && link_to(message.subject || "(none)", user_message_path(message.user_id, message))
18
+ %td= l message.created_at
19
+ %td= message.user && link_to_if(can?(:show, message.user), message.user.try(:full_name), user_path(message.user.id))
20
+ %td= link_to message.link, message_path(message)
21
+ %td= message.clicked_at ? l(message.clicked_at) : nil
22
+ %td= message.id
23
+ %br
24
+
25
+ %p.pagination
26
+ = paginate @messages
@@ -9,7 +9,7 @@ class Message < ActiveRecord::Base
9
9
  <% end %>
10
10
  serialize :options
11
11
 
12
- include Rails.application.routes_url_helpers
12
+ include Rails.application.routes.url_helpers
13
13
 
14
14
  after_create :send_email
15
15
 
@@ -41,7 +41,7 @@ class Message < ActiveRecord::Base
41
41
 
42
42
  # prepare a mail object ready for delivery by email or display on the screen
43
43
  def mail
44
- @mail ||= MessageMailer.prepare_message(self, context)
44
+ @mail ||= MessageMailer.prepare_message(self)
45
45
  end
46
46
 
47
47
  # The "view" link. This is the link to the messages controller that marks the message
@@ -53,4 +53,21 @@ class Message < ActiveRecord::Base
53
53
  def name
54
54
  "Message ID: #{id}"
55
55
  end
56
+
57
+ def add_attachments(mailer)
58
+ # This is called by the mailer to add any attachments. For example:
59
+ # if context.is_a? CalendarEvent
60
+ # mailer.attachments.inline["calendar.ics"] = context.to_ical
61
+ # end
62
+ end
63
+
64
+ # return the mail body as a string, skipping any attachment parts that may be in the message
65
+ def mail_body
66
+ if mail.multipart?
67
+ part = mail.parts.select { |p| p.text? && !p.attachment? }.first
68
+ part.body.to_s
69
+ else
70
+ mail.body.to_s
71
+ end
72
+ end
56
73
  end
@@ -0,0 +1,19 @@
1
+ class MessageMailer < ActionMailer::Base
2
+ #TODO set default from address
3
+ default from: "noreply@example.com"
4
+
5
+ attr :subject
6
+
7
+ def prepare_message(message)
8
+ @message = message
9
+ @user = message.user
10
+
11
+ # ask the message model if we need any attachments added
12
+ message.add_attachments(self)
13
+
14
+ m = mail(to: message.user.email, subject: message.subject, template_name: message.template || :default)
15
+ # allow template to override subject in the view by doing: <% @message.subject = "new subject" %>
16
+ m.subject = message.subject
17
+ m
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ class CreateMessages < ActiveRecord::Migration
2
+ def change
3
+ create_table :messages do |t|
4
+ t.references :user
5
+ t.string :template
6
+ t.string :context_type
7
+ t.integer :context_id
8
+ t.string :link
9
+ t.string :subject
10
+ t.datetime :clicked_at
11
+ t.datetime :sent_at
12
+ t.text :options
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :messages, :user_id
18
+ add_index :messages, [:context_type, :context_id]
19
+ end
20
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Message do
4
+
5
+ let(:freeze_1) { Time.zone.now.change(:usec => 0) }
6
+
7
+ common_lets
8
+
9
+ context "relationships" do
10
+ it { should belong_to(:user) }
11
+ it { should belong_to(:context) }
12
+ end
13
+
14
+ context "validations" do
15
+ # validate the common_lets generated message instance:
16
+ it { expect(message).to be_valid }
17
+ it { should validate_presence_of(:user) }
18
+ end
19
+
20
+ describe 'latest' do
21
+ before do
22
+ Timecop.freeze(Time.local(1990)) do
23
+ message_other
24
+ message
25
+ end
26
+ end
27
+ it { expect(Message.latest).to match_array([message_other, message]) }
28
+ end
29
+
30
+ describe "#mail" do
31
+ # Example test for mail content:
32
+ # let(:message) { Message.new(template: "report_untag", context: relation, options: {foo: "bar"}, user: user_owner) }
33
+ # context "rendering email" do
34
+ # subject { message.mail }
35
+ # it { expect(subject.subject).to eq("Tag Removed Notification") }
36
+ # it { expect(subject.body).to include("The following tag has just been removed") }
37
+ # end
38
+ end
39
+
40
+ describe "#view_link" do
41
+ subject { message }
42
+ it "production" do
43
+ Rails.application.routes.stub(:default_url_options => {:host => 'example.com'})
44
+ Rails.env.stub(:production? => true)
45
+ expect(subject.view_link).to eq("http://example.com/messages/#{message.id}")
46
+ end
47
+ it "development" do
48
+ expect(subject.view_link).to eq("http://localhost/messages/#{message.id}")
49
+ end
50
+ end
51
+
52
+
53
+ context '#send_email' do
54
+ context 'build only' do
55
+ before do
56
+ message.update_column(:sent_at, nil)
57
+ ActionMailer::Base.deliveries.clear
58
+ message.mail
59
+ end
60
+ it { expect(message.sent_at).to be_nil }
61
+ it { ActionMailer::Base.deliveries.should be_empty }
62
+ end
63
+
64
+ context 'build and send' do
65
+ before do
66
+ Timecop.freeze(freeze_1) { message.send_email }
67
+ end
68
+
69
+ it { ActionMailer::Base.deliveries.last.to.should == [user.email] }
70
+ it { message.sent_at.should == freeze_1 }
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,11 @@
1
+ # Read about factories at https://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :message do
5
+ link "/"
6
+ # clicked_at nil
7
+ # sent_at nil
8
+ template "default"
9
+ # options nil
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ class MessagesController < ApplicationController
2
+
3
+ include PageAndSortHelper
4
+ include PageAndSortHelper::Controller
5
+ helper PageAndSortHelper
6
+
7
+ before_filter do
8
+ authenticate_user!
9
+ load_and_authorize_if_present :user do
10
+ load_and_authorize :message
11
+ end
12
+ load_and_authorize :message
13
+ end
14
+
15
+ def index
16
+ @messages =
17
+ case
18
+ when @user
19
+ @user.messages
20
+ when can?(:index_all, Message)
21
+ Message
22
+ else
23
+ current_user.messages
24
+ end
25
+
26
+ @messages = page_and_sort(@messages, default_sort: :created_at, default_direction: :desc)
27
+ end
28
+
29
+ # this one controller action has two totally different functions:
30
+ #
31
+ # 1. /users/1/messages/3 => show the message content
32
+ # 2. /messages/3 => mark the message clicked at time and redirect to the link in the message.
33
+ def show
34
+ if @user
35
+ # show
36
+ else
37
+ @message.update_column(:clicked_at, Time.now) if current_user == @message.user
38
+ redirect_to @message.link
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe MessagesController do
4
+ render_views
5
+ common_lets
6
+
7
+ before :all do
8
+ Fracture.define_selector :new_message_link
9
+ Fracture.define_selector :cancel_new_message_link
10
+ Fracture.define_selector :edit_message_link
11
+ Fracture.define_selector :cancel_edit_message_link
12
+ end
13
+
14
+ context 'not logged in' do
15
+ {index: :get, show: :get}.each do |v, m|
16
+ it "#{m} #{v} should logout" do
17
+ self.send(m, v, id: message)
18
+ should redirect_to new_user_session_path
19
+ end
20
+ end
21
+ end
22
+
23
+ context "signed in" do
24
+ before do
25
+ sign_in user
26
+ controller.should_receive(:authenticate_user!).and_call_original
27
+ end
28
+
29
+ context "GET index" do
30
+ context "not nested" do
31
+ before do
32
+ controller.should_receive(:authorize!).with(:index, Message)
33
+ message; message_other
34
+ get :index
35
+ end
36
+ it { should assign_to(:messages).with_items([message]) }
37
+ it { should render_template :index }
38
+ it { should have_only_fractures }
39
+ end
40
+
41
+ context "under user" do
42
+ before do
43
+ controller.should_receive(:authorize!).with(:show, user)
44
+ controller.should_receive(:authorize!).with(:index, user => Message)
45
+ controller.should_receive(:authorize!).with(:index, Message)
46
+ message; message_other
47
+ get :index, :user_id => user.id
48
+ end
49
+ it { should assign_to(:messages).with_items([message]) }
50
+ it { should render_template :index }
51
+ it { should have_only_fractures }
52
+ end
53
+ end
54
+
55
+ context "GET show" do
56
+ context "not nested" do # this is the redirect action. This link appears in the email.
57
+ before do
58
+ message.update_column :link, "/some/location"
59
+ Timecop.freeze(freeze_1) do
60
+ get :show, id: message
61
+ end
62
+ end
63
+
64
+ it { should assign_to(:message).with(message) }
65
+ it { should assign_to("message.clicked_at").with(freeze_1) }
66
+ it { should_not render_template :show }
67
+ it { should redirect_to("/some/location") }
68
+ end
69
+
70
+ # context 'not as the owner of the message' do
71
+ # it { expects_access_denied { get :show, id: message_other } }
72
+ # end
73
+
74
+ context "under user" do
75
+ before do
76
+ controller.should_receive(:authorize!).with(:show, user)
77
+ controller.should_receive(:authorize!).with(:show, message)
78
+ get :show, user_id: user, id: message
79
+ end
80
+ it { should assign_to(:message).with(message) }
81
+ it { should render_template :show }
82
+ it { should have_only_fractures }
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,32 @@
1
+ %h1 Message
2
+
3
+ .row.form-horizontal
4
+ .col-md-1
5
+ %label.control-label Subject
6
+ .col-md-9
7
+ %p.form-text
8
+ %b= @message.subject
9
+ .row
10
+ .col-md-1
11
+ %label.control-label Date Sent
12
+ .col-md-9
13
+ %p.form-text
14
+ = @message.sent_at ? l(@message.sent_at) : "(not sent)"
15
+ .row
16
+ .col-md-1
17
+ %label.control-label Body
18
+ .col-md-9
19
+ %p
20
+ = simple_format(@message.mail_body)
21
+ -# or add the `gem "rails_autolink"` to Gemfile to detect links in the message body:
22
+ -#= simple_format(auto_link(@message.mail_body))
23
+
24
+ -#- if @message.mail.attachments.any?
25
+ -# .row
26
+ -# .col-md-1
27
+ -# %label.control-label Attachments
28
+ -# .col-md-9
29
+ -# %ul
30
+ -# - @message.mail.attachments.each_with_index do |attachment, index|
31
+ -# %li
32
+ -# = link_to(attachment.filename, company_user_message_attachment_path(@company, @user, @message, index+1))