exposition 0.0.3.pre.alpha

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 (165) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +25 -0
  4. data/app/assets/images/exposition/twitter.svg +10 -0
  5. data/app/assets/javascripts/exposition/admin/application.js +3 -0
  6. data/app/assets/stylesheets/exposition/_breakpoints.scss +5 -0
  7. data/app/assets/stylesheets/exposition/_code.scss +83 -0
  8. data/app/assets/stylesheets/exposition/_footer.scss +9 -0
  9. data/app/assets/stylesheets/exposition/_header.scss +62 -0
  10. data/app/assets/stylesheets/exposition/_layout.scss +28 -0
  11. data/app/assets/stylesheets/exposition/_mixins.scss +4 -0
  12. data/app/assets/stylesheets/exposition/_normalize.scss +427 -0
  13. data/app/assets/stylesheets/exposition/_pagination.scss +18 -0
  14. data/app/assets/stylesheets/exposition/_posts.scss +96 -0
  15. data/app/assets/stylesheets/exposition/_tags.scss +12 -0
  16. data/app/assets/stylesheets/exposition/_variables.scss +16 -0
  17. data/app/assets/stylesheets/exposition/admin/_layout.scss +58 -0
  18. data/app/assets/stylesheets/exposition/admin/_mixins.scss +3 -0
  19. data/app/assets/stylesheets/exposition/admin/_notifications.scss +46 -0
  20. data/app/assets/stylesheets/exposition/admin/_pagination.scss +12 -0
  21. data/app/assets/stylesheets/exposition/admin/_posts.scss +7 -0
  22. data/app/assets/stylesheets/exposition/admin/application.scss +9 -0
  23. data/app/assets/stylesheets/exposition/admin/base/_base.scss +15 -0
  24. data/app/assets/stylesheets/exposition/admin/base/_buttons.scss +31 -0
  25. data/app/assets/stylesheets/exposition/admin/base/_forms.scss +78 -0
  26. data/app/assets/stylesheets/exposition/admin/base/_grid-settings.scss +14 -0
  27. data/app/assets/stylesheets/exposition/admin/base/_lists.scss +31 -0
  28. data/app/assets/stylesheets/exposition/admin/base/_tables.scss +25 -0
  29. data/app/assets/stylesheets/exposition/admin/base/_typography.scss +55 -0
  30. data/app/assets/stylesheets/exposition/admin/base/_variables.scss +35 -0
  31. data/app/assets/stylesheets/exposition/admin/normalize.scss +427 -0
  32. data/app/assets/stylesheets/exposition/application.scss +17 -0
  33. data/app/controllers/exposition/admin/admin_controller.rb +5 -0
  34. data/app/controllers/exposition/admin/posts_controller.rb +5 -0
  35. data/app/controllers/exposition/admin/sessions_controller.rb +31 -0
  36. data/app/controllers/exposition/admin/tags_controller.rb +5 -0
  37. data/app/controllers/exposition/application_controller.rb +8 -0
  38. data/app/controllers/exposition/posts_controller.rb +5 -0
  39. data/app/controllers/exposition/tags_controller.rb +5 -0
  40. data/app/helpers/exposition/admin/flashes_helper.rb +7 -0
  41. data/app/helpers/exposition/admin/sessions_helper.rb +20 -0
  42. data/app/helpers/exposition/markdown_helper.rb +21 -0
  43. data/app/models/categorical/tag.rb +6 -0
  44. data/app/models/exposition/encryptor.rb +10 -0
  45. data/app/models/exposition/post.rb +5 -0
  46. data/app/models/exposition/user.rb +5 -0
  47. data/app/views/exposition/admin/images/index.html.haml +12 -0
  48. data/app/views/exposition/admin/images/new.html.haml +0 -0
  49. data/app/views/exposition/admin/posts/_error_handler.html.haml +8 -0
  50. data/app/views/exposition/admin/posts/_form_fields.html.haml +23 -0
  51. data/app/views/exposition/admin/posts/edit.html.haml +5 -0
  52. data/app/views/exposition/admin/posts/index.html.haml +23 -0
  53. data/app/views/exposition/admin/posts/new.html.haml +7 -0
  54. data/app/views/exposition/admin/posts/update.html.haml +2 -0
  55. data/app/views/exposition/admin/sessions/new.html.haml +10 -0
  56. data/app/views/exposition/admin/tags/_error_handler.html.haml +8 -0
  57. data/app/views/exposition/admin/tags/edit.html.haml +10 -0
  58. data/app/views/exposition/admin/tags/index.html.haml +18 -0
  59. data/app/views/exposition/admin/tags/new.html.haml +10 -0
  60. data/app/views/exposition/posts/_post.html.haml +8 -0
  61. data/app/views/exposition/posts/_tags.html.haml +6 -0
  62. data/app/views/exposition/posts/index.html.haml +8 -0
  63. data/app/views/exposition/posts/show.html.haml +5 -0
  64. data/app/views/exposition/tags/show.html.haml +6 -0
  65. data/app/views/layouts/exposition/admin.html.haml +22 -0
  66. data/app/views/layouts/exposition/application.html.haml +20 -0
  67. data/config/locales/en.yml +37 -0
  68. data/config/routes.rb +14 -0
  69. data/db/migrate/20160106220615_create_exposition_posters.rb +12 -0
  70. data/db/migrate/20160112194424_add_author_id_to_posts.rb +5 -0
  71. data/db/migrate/20160112200248_create_exposition_users.rb +14 -0
  72. data/db/migrate/20160112202302_add_slug_to_expositon_posts.rb +7 -0
  73. data/db/migrate/20160112204019_add_categorial_tags.rb +17 -0
  74. data/db/migrate/20160225203524_add_summary_to_posts.rb +5 -0
  75. data/db/migrate/20160226035733_convert_published_at_to_datetime.rb +9 -0
  76. data/lib/exposition.rb +19 -0
  77. data/lib/exposition/concerns/controllers/admin/admin_controller.rb +39 -0
  78. data/lib/exposition/concerns/controllers/admin/posts_controller.rb +70 -0
  79. data/lib/exposition/concerns/controllers/admin/tags_controller.rb +63 -0
  80. data/lib/exposition/concerns/controllers/posts_controller.rb +19 -0
  81. data/lib/exposition/concerns/controllers/tags_controller.rb +31 -0
  82. data/lib/exposition/concerns/models/post.rb +52 -0
  83. data/lib/exposition/concerns/models/user.rb +43 -0
  84. data/lib/exposition/engine.rb +14 -0
  85. data/lib/exposition/setup.rb +15 -0
  86. data/lib/exposition/version.rb +3 -0
  87. data/lib/tasks/exposition_tasks.rake +4 -0
  88. data/lib/tasks/setup.rb +17 -0
  89. data/spec/controllers/exposition/admin/admin_controller_spec.rb +88 -0
  90. data/spec/controllers/exposition/admin/posts_controller_spec.rb +153 -0
  91. data/spec/controllers/exposition/admin/sessions_controller_spec.rb +46 -0
  92. data/spec/controllers/exposition/admin/tags_controller_spec.rb +106 -0
  93. data/spec/controllers/exposition/posts_controller_spec.rb +43 -0
  94. data/spec/controllers/exposition/tags_controller_spec.rb +40 -0
  95. data/spec/dummy/Gemfile +5 -0
  96. data/spec/dummy/Gemfile.lock +173 -0
  97. data/spec/dummy/README.rdoc +28 -0
  98. data/spec/dummy/Rakefile +6 -0
  99. data/spec/dummy/Thorfile +1 -0
  100. data/spec/dummy/app/assets/javascripts/application.js +1 -0
  101. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  102. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  103. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  104. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  105. data/spec/dummy/bin/bundle +3 -0
  106. data/spec/dummy/bin/rails +9 -0
  107. data/spec/dummy/bin/rake +9 -0
  108. data/spec/dummy/bin/setup +29 -0
  109. data/spec/dummy/bin/spring +15 -0
  110. data/spec/dummy/bin/thor +16 -0
  111. data/spec/dummy/config.ru +4 -0
  112. data/spec/dummy/config/application.rb +26 -0
  113. data/spec/dummy/config/boot.rb +3 -0
  114. data/spec/dummy/config/database.yml +12 -0
  115. data/spec/dummy/config/environment.rb +5 -0
  116. data/spec/dummy/config/environments/development.rb +41 -0
  117. data/spec/dummy/config/environments/production.rb +79 -0
  118. data/spec/dummy/config/environments/test.rb +42 -0
  119. data/spec/dummy/config/initializers/assets.rb +11 -0
  120. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  121. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  122. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  123. data/spec/dummy/config/initializers/inflections.rb +16 -0
  124. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  125. data/spec/dummy/config/initializers/session_store.rb +3 -0
  126. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  127. data/spec/dummy/config/locales/en.yml +23 -0
  128. data/spec/dummy/config/routes.rb +3 -0
  129. data/spec/dummy/config/secrets.yml +22 -0
  130. data/spec/dummy/db/schema.rb +62 -0
  131. data/spec/dummy/db/seeds.rb +22 -0
  132. data/spec/dummy/public/404.html +67 -0
  133. data/spec/dummy/public/422.html +67 -0
  134. data/spec/dummy/public/500.html +66 -0
  135. data/spec/dummy/public/favicon.ico +0 -0
  136. data/spec/dummy/public/robots.txt +5 -0
  137. data/spec/factories/categorical/tags.rb +5 -0
  138. data/spec/factories/posts.rb +8 -0
  139. data/spec/factories/taggings.rb +7 -0
  140. data/spec/factories/users.rb +7 -0
  141. data/spec/features/admin/post_management_spec.rb +95 -0
  142. data/spec/features/admin/session_management_spec.rb +40 -0
  143. data/spec/features/admin/tags_management_spec.rb +59 -0
  144. data/spec/features/posts_index_spec.rb +28 -0
  145. data/spec/features/viewing_a_post_spec.rb +21 -0
  146. data/spec/features/viewing_posts_by_tag_spec.rb +17 -0
  147. data/spec/helpers/admin/flashes_helper_spec.rb +29 -0
  148. data/spec/helpers/admin/sessions_helper_spec.rb +56 -0
  149. data/spec/helpers/markdown_helper_spec.rb +10 -0
  150. data/spec/models/categorical/tag_spec.rb +35 -0
  151. data/spec/models/exposition/post_spec.rb +123 -0
  152. data/spec/models/exposition/user_spec.rb +15 -0
  153. data/spec/rails_helper.rb +47 -0
  154. data/spec/spec_helper.rb +11 -0
  155. data/spec/support/controllers.rb +6 -0
  156. data/spec/support/controllers/pagination.rb +17 -0
  157. data/spec/support/controllers/session_management.rb +20 -0
  158. data/spec/support/features.rb +6 -0
  159. data/spec/support/features/pagination.rb +22 -0
  160. data/spec/support/features/session_management.rb +17 -0
  161. data/spec/support/models.rb +5 -0
  162. data/spec/support/models/sluggable.rb +11 -0
  163. data/spec/tasks/setup_spec.rb +32 -0
  164. data/spec/views/admin/posts/index.html.haml_spec.rb +16 -0
  165. metadata +619 -0
@@ -0,0 +1,14 @@
1
+ module Exposition
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Exposition
4
+ config.generators do |g|
5
+ g.test_framework :rspec, :fixture => false
6
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
7
+ g.assets false
8
+ g.helper false
9
+ end
10
+ initializer "exposition.assets.precompile" do |app|
11
+ app.config.assets.precompile += %w( exposition/twitter.svg )
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ require 'thor'
2
+
3
+ module Exposition
4
+ class Setup < Thor
5
+ desc 'create_user', 'creates an admin user'
6
+ method_option :attributes,
7
+ type: :hash,
8
+ required: true,
9
+ desc: 'specifies attributes for your user account. eg. name:Johnny email:john@exposition.com password:secret password_confirmation:secret'
10
+ def create_user
11
+ user_attributes = options.fetch('attributes')
12
+ ::Exposition::User.create!(user_attributes)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Exposition
2
+ VERSION = "0.0.3-alpha"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task exposition: :environment do
3
+ # puts Exposition::User.last
4
+ # end
@@ -0,0 +1,17 @@
1
+ # Load associated Rails environment if there is a Rails environment
2
+ # require 'exposition/engine' if defined? ::Rails
3
+ require 'thor'
4
+
5
+ module Exposition
6
+ class Setup < Thor
7
+ desc 'create_user', 'creates an admin user'
8
+ method_option :attributes,
9
+ type: :hash,
10
+ required: true,
11
+ desc: 'specifies attributes for your user account. eg. name:Johnny email:john@exposition.com password:secret password_confirmation:secret'
12
+ def create_user
13
+ user_attributes = options.fetch('attributes')
14
+ ::Exposition::User.create!(user_attributes)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,88 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Exposition::Admin::AdminController, type: :controller do
4
+ routes { Exposition::Engine.routes }
5
+
6
+ describe "#authorize" do
7
+ it { should use_before_action(:authorize) }
8
+
9
+ it "raises a 404 error if there is no logged in user" do
10
+ expect { controller.authorize }.
11
+ to raise_error(ActionController::RoutingError)
12
+ end
13
+
14
+ it "does not raise a 404 error if there is a logged in user" do
15
+ allow(controller).to receive(:logged_in?).and_return(true)
16
+
17
+ expect { controller.authorize }.not_to raise_error()
18
+ end
19
+ end
20
+
21
+ describe "#current_user" do
22
+ context "when logged in via a session" do
23
+ it "returns the logged in user" do
24
+ user = create(:user,
25
+ password: 'password',
26
+ email: 'j@j.com',
27
+ name: 'Josh')
28
+ session_params = {user_id: user.id}
29
+ allow(controller).to receive(:session).and_return(session_params)
30
+
31
+ expect(controller.current_user).to eq(user)
32
+ end
33
+ end
34
+
35
+
36
+ context "when logged in via a cookie" do
37
+ it "returns the logged in user and sets the user_id in the session" do
38
+ user = create(:user,
39
+ password: 'password',
40
+ email: 'j@j.com',
41
+ name: 'Josh')
42
+ user.set_encrypted_remember_token!
43
+ session_params = {}
44
+ signed_cookie_params = {user_id: user.id}
45
+ cookie_params = {remember_token: user.remember_token}
46
+ fake_cookie = FakeCookies.new(
47
+ signed: signed_cookie_params,
48
+ unsigned: cookie_params
49
+ )
50
+ allow(controller).to receive(:cookies).and_return(fake_cookie)
51
+ allow(controller).to receive(:session).and_return(session_params)
52
+
53
+ expect(controller.current_user).to eq(user)
54
+ expect(session_params[:user_id]).to eq(user.id)
55
+ end
56
+ end
57
+
58
+ describe "#logged_in?" do
59
+ it "returns true if current_user is present" do
60
+ user = double("user")
61
+ allow(controller).to receive(:current_user).and_return(user)
62
+
63
+ expect(controller.logged_in?).to be_truthy
64
+ end
65
+
66
+ it "returns false if current_user is not present" do
67
+ allow(controller).to receive(:current_user).and_return(nil)
68
+
69
+ expect(controller.logged_in?).to be_falsey
70
+ end
71
+ end
72
+
73
+ class FakeCookies
74
+ def initialize(unsigned:{}, signed:{})
75
+ @signed = signed
76
+ @unsigned = unsigned
77
+ end
78
+
79
+ def [](key)
80
+ @unsigned[key]
81
+ end
82
+
83
+ def signed
84
+ @signed
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,153 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Exposition::Admin::PostsController, type: :controller do
4
+ routes { Exposition::Engine.routes }
5
+
6
+ before(:each) { build_user_and_login }
7
+
8
+ describe "GET #index" do
9
+ it "finds all the posts" do
10
+ blog_post = create(:post)
11
+
12
+ get :index
13
+
14
+ expect(assigns(:posts).last).to eq(blog_post)
15
+ end
16
+
17
+ it { paginates(factory: :post, increment: 25) { get :index } }
18
+ end
19
+
20
+ describe "GET #new" do
21
+ it "builds a new post" do
22
+ get :new
23
+
24
+ expect(assigns(:post)).to be_a_new(Exposition::Post)
25
+ end
26
+
27
+ it "finds all the users and sets them as authors" do
28
+ author = create(:user)
29
+ get :new
30
+
31
+ expect(assigns(:authors)).to eq([author])
32
+ end
33
+
34
+ it { finds_tags_for { get :new } }
35
+ end
36
+
37
+ describe "POST #create" do
38
+ context "with valid attributes" do
39
+ it "creates a new post" do
40
+ user = create(:user)
41
+ valid_post_attributes = attributes_for(:post,
42
+ title: 'Title',
43
+ body: 'Body',
44
+ author_id: user.id)
45
+
46
+ post :create, post: valid_post_attributes
47
+
48
+ expect(assigns(:post)).to be_persisted
49
+ expect(assigns(:post).title).to eq('Title')
50
+ expect(assigns(:post).body).to eq('Body')
51
+ expect(assigns(:post).author).to eq(user)
52
+ expect(flash[:success]).to eq('Post successfully created.')
53
+ expect(response).to redirect_to(admin_posts_path)
54
+ end
55
+ end
56
+
57
+ context "with invalid attributes" do
58
+ it "re-renders the new action" do
59
+ invalid_post_attributes = attributes_for(:post,
60
+ title: '',
61
+ body: 'Body')
62
+ post :create, post: invalid_post_attributes
63
+
64
+ expect(assigns(:post)).to be_a_new(Exposition::Post)
65
+ expect(assigns(:post).title).to eq('')
66
+ expect(assigns(:post).body).to eq('Body')
67
+ expect(response).to render_template(:new)
68
+ end
69
+ end
70
+
71
+ it "finds all the users and sets them as authors" do
72
+ author = create(:user)
73
+ post_attributes = attributes_for(:post)
74
+
75
+ post :create, post: post_attributes
76
+
77
+ expect(assigns(:authors)).to eq([author])
78
+ end
79
+
80
+ it { finds_tags_for { post :create, post: attributes_for(:post) } }
81
+ end
82
+
83
+ describe "GET #edit" do
84
+ it "finds the post" do
85
+ blog_post = create(:post)
86
+
87
+ get :edit, id: blog_post
88
+
89
+ expect(assigns(:post)).to eq(blog_post)
90
+ end
91
+
92
+ it "finds all the users and sets them as authors" do
93
+ author = create(:user)
94
+ post = create(:post, author: author)
95
+
96
+ get :edit, id: post
97
+
98
+ expect(assigns(:authors)).to eq([author])
99
+ end
100
+
101
+ it { finds_tags_for { get :edit, id: create(:post) } }
102
+ end
103
+
104
+ describe "GET #update" do
105
+ it "finds the post" do
106
+ blog_post = create(:post)
107
+
108
+ patch :update, id: blog_post, post: {title: 'hello'}
109
+
110
+ expect(assigns(:post)).to eq(blog_post)
111
+ end
112
+
113
+ it "finds all the users and sets them as authors" do
114
+ author = create(:user)
115
+ post = create(:post, author: author)
116
+
117
+ patch :update, id: post, post: {title: 'hello'}
118
+
119
+ expect(assigns(:authors)).to eq([author])
120
+ end
121
+
122
+ it "updates the posts attributes when given" do
123
+ user = create(:user)
124
+ blog_post = create(:post)
125
+
126
+ patch :update, id: blog_post, post: {title: "hello!",
127
+ body: "1,2,3,4",
128
+ author_id: user.id}
129
+
130
+ blog_post.reload
131
+
132
+ expect(blog_post.title).to eq("hello!")
133
+ expect(blog_post.body).to eq("1,2,3,4")
134
+ expect(blog_post.author).to eq(user)
135
+ end
136
+
137
+ it do
138
+ finds_tags_for do
139
+ blog_post = create(:post)
140
+ patch :update, id: blog_post, post: {title: 'hello'}
141
+ end
142
+ end
143
+ end
144
+
145
+ def finds_tags_for
146
+ tag = create(:tag)
147
+ post_attributes = attributes_for(:post)
148
+
149
+ yield
150
+
151
+ expect(assigns(:tags)).to eq([tag])
152
+ end
153
+ end
@@ -0,0 +1,46 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Exposition::Admin::SessionsController, type: :controller do
4
+ routes { Exposition::Engine.routes }
5
+
6
+ describe "GET #new" do
7
+ it "returns http success" do
8
+ get :new
9
+ expect(response).to have_http_status(:success)
10
+ end
11
+ end
12
+
13
+ describe "POST #create" do
14
+ it "finds the user by the session email" do
15
+ user = create(:user, email: 'user@user.com', password: 'password')
16
+
17
+ post :create, session: {email: user.email, password: user.password}
18
+ expect(response).to redirect_to(admin_posts_path)
19
+ end
20
+
21
+ it "generates an error message with incorrect login credentials" do
22
+ post :create, session: {email: '', password: ''}
23
+
24
+ expect(flash[:error]).to be_present
25
+
26
+ get :new
27
+
28
+ expect(flash[:error]).to_not be_present
29
+ end
30
+ end
31
+
32
+ describe "DELETE #destroy" do
33
+ it "deletes the sesssion and cookies" do
34
+ build_user_and_login
35
+ session['user_id'] = 1
36
+ request.cookies['user_id'] = 1
37
+ request.cookies['remember_token'] = 'token'
38
+
39
+ delete :destroy
40
+
41
+ expect(session['user_id']).to be_nil
42
+ expect(cookies['user_id']).to be_nil
43
+ expect(cookies['remember_token']).to be_nil
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,106 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Exposition::Admin::TagsController, type: :controller do
4
+ routes { Exposition::Engine.routes }
5
+
6
+ before(:each) { build_user_and_login }
7
+
8
+ describe "GET #index" do
9
+ it "finds all the tags" do
10
+ tag = create(:tag)
11
+
12
+ get :index
13
+
14
+ expect(assigns(:tags)).to eq([tag])
15
+ end
16
+
17
+ it { paginates(factory: :tag, increment: 25) { get :index } }
18
+ end
19
+
20
+ describe "GET #new" do
21
+ it "builds a new tag" do
22
+ get :new
23
+
24
+ expect(assigns(:tag)).to be_a_new(Categorical::Tag)
25
+ end
26
+ end
27
+
28
+ describe "POST #create" do
29
+ context "with valid attributes" do
30
+ it "creates a new tag" do
31
+ user = create(:user)
32
+ valid_tag_attributes = attributes_for(:tag, label: 'Label')
33
+
34
+ post :create, tag: valid_tag_attributes
35
+
36
+ expect(assigns(:tag)).to be_persisted
37
+ expect(assigns(:tag).label).to eq('Label')
38
+ expect(flash[:success]).to eq('Tag successfully created.')
39
+ expect(response).to redirect_to(admin_tags_path)
40
+ end
41
+ end
42
+
43
+ context "with invalid attributes" do
44
+ it "re-renders the new action" do
45
+ invalid_tag_attributes = attributes_for(:tag, label: '')
46
+ post :create, tag: invalid_tag_attributes
47
+
48
+ expect(assigns(:tag)).to be_a_new(Categorical::Tag)
49
+ expect(assigns(:tag).label).to eq('')
50
+ expect(response).to render_template(:new)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "GET #edit" do
56
+ it "finds the tag" do
57
+ tag = create(:tag)
58
+
59
+ get :edit, id: tag
60
+
61
+ expect(assigns(:tag)).to eq(tag)
62
+ end
63
+ end
64
+
65
+ describe "GET #update" do
66
+ it "finds the tag" do
67
+ tag = create(:tag)
68
+
69
+ patch :update, id: tag, tag: {label: 'new label'}
70
+
71
+ expect(assigns(:tag)).to eq(tag)
72
+ end
73
+
74
+ context "when the attributes are valid" do
75
+ it "updates the tags attributes when given" do
76
+ tag = create(:tag, label: 'old label')
77
+
78
+ patch :update, id: tag, tag: {label: "new label"}
79
+ tag.reload
80
+
81
+ expect(tag.label).to eq("new label")
82
+ end
83
+ end
84
+
85
+ context "when the attributes are invalid" do
86
+ it "renders the edit page" do
87
+ tag = create(:tag, label: 'old label')
88
+
89
+ patch :update, id: tag, tag: {label: ""}
90
+
91
+ expect(response).to render_template(:edit)
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "DELETE #destroy" do
97
+ it "deletes the specified tag" do
98
+ tag = create(:tag)
99
+
100
+ delete :destroy, id: tag
101
+
102
+ expect(response).to redirect_to(admin_tags_path)
103
+ expect(Categorical::Tag.all).to eq([])
104
+ end
105
+ end
106
+ end