kitestrings 1.0.2 → 1.0.3

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.
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))