days 0.0.1.earlier → 0.1.0

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 (76) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +9 -0
  4. data/README.md +2 -0
  5. data/app/images/glyphicons-halflings-white.png +0 -0
  6. data/app/images/glyphicons-halflings.png +0 -0
  7. data/app/javascripts/bootstrap.js +2159 -0
  8. data/app/javascripts/bootstrap.min.js +6 -0
  9. data/app/javascripts/jquery-1.8.3.min.js +2 -0
  10. data/app/stylesheets/admin/login.scss +26 -0
  11. data/app/stylesheets/admin.scss +28 -0
  12. data/app/stylesheets/bootstrap-responsive.css +1092 -0
  13. data/app/stylesheets/bootstrap-responsive.min.css +9 -0
  14. data/app/stylesheets/bootstrap.css +6039 -0
  15. data/app/stylesheets/bootstrap.min.css +9 -0
  16. data/app/stylesheets/style.scss +132 -0
  17. data/app/views/admin/categories.haml +53 -0
  18. data/app/views/admin/entries/form.haml +55 -0
  19. data/app/views/admin/entries/index.haml +31 -0
  20. data/app/views/admin/index.haml +0 -0
  21. data/app/views/admin/login.haml +19 -0
  22. data/app/views/admin/setup.haml +22 -0
  23. data/app/views/admin/users/form.haml +25 -0
  24. data/app/views/admin/users/index.haml +23 -0
  25. data/app/views/admin.haml +37 -0
  26. data/app/views/entries.haml +4 -0
  27. data/app/views/entry.haml +32 -0
  28. data/app/views/layout.haml +32 -0
  29. data/bin/days +5 -0
  30. data/bootstrap.sh +41 -0
  31. data/days.gemspec +25 -2
  32. data/lib/days/app/admin/categories.rb +43 -0
  33. data/lib/days/app/admin/entries.rb +72 -0
  34. data/lib/days/app/admin/session.rb +28 -0
  35. data/lib/days/app/admin/setup.rb +20 -0
  36. data/lib/days/app/admin/users.rb +59 -0
  37. data/lib/days/app/admin.rb +11 -0
  38. data/lib/days/app/entries.rb +84 -0
  39. data/lib/days/app.rb +110 -0
  40. data/lib/days/command.rb +158 -0
  41. data/lib/days/config.rb +42 -0
  42. data/lib/days/helpers.rb +101 -0
  43. data/lib/days/migrate/20121221000000_create_entries.rb +18 -0
  44. data/lib/days/migrate/20121221001000_create_users.rb +12 -0
  45. data/lib/days/migrate/20121221002000_create_categories.rb +17 -0
  46. data/lib/days/migrator.rb +33 -0
  47. data/lib/days/models/category.rb +12 -0
  48. data/lib/days/models/entry.rb +63 -0
  49. data/lib/days/models/user.rb +14 -0
  50. data/lib/days/models.rb +7 -0
  51. data/lib/days/version.rb +1 -1
  52. data/lib/days.rb +3 -1
  53. data/scripts/lokka_export.rb +45 -0
  54. data/skeleton/days/Gemfile +11 -0
  55. data/skeleton/days/config.ru +6 -0
  56. data/skeleton/days/config.yml +33 -0
  57. data/skeleton/days/db/.gitkeep +0 -0
  58. data/spec/controllers/admin/categories_spec.rb +100 -0
  59. data/spec/controllers/admin/entries_spec.rb +185 -0
  60. data/spec/controllers/admin/session_spec.rb +112 -0
  61. data/spec/controllers/admin/setup_spec.rb +85 -0
  62. data/spec/controllers/admin/users_spec.rb +163 -0
  63. data/spec/controllers/entries_spec.rb +129 -0
  64. data/spec/environment/Gemfile +11 -0
  65. data/spec/environment/config.ru +6 -0
  66. data/spec/environment/config.yml +32 -0
  67. data/spec/environment/db/.gitkeep +0 -0
  68. data/spec/fixtures/categories.yml +5 -0
  69. data/spec/fixtures/entries.yml +25 -0
  70. data/spec/fixtures/users.yml +6 -0
  71. data/spec/helpers_spec.rb +117 -0
  72. data/spec/models/entry_spec.rb +238 -0
  73. data/spec/shared/admin.rb +8 -0
  74. data/spec/spec_helper.rb +134 -0
  75. data/tasks +9 -0
  76. metadata +353 -9
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Days::App, type: :controller do
4
+ describe "admin: categories" do
5
+ fixtures :users, :categories
6
+ let(:user) { users(:blogger) }
7
+ let(:category) { categories(:daily) }
8
+
9
+ before { login(user) }
10
+
11
+ describe "GET /admin/categories" do
12
+ subject { get '/admin/categories', {}, env }
13
+
14
+ it_behaves_like 'an admin page'
15
+
16
+ it { should be_ok }
17
+
18
+ it "lists up categories" do
19
+ render[:data].should == :'admin/categories'
20
+
21
+ categories = render[:ivars][:@categories]
22
+ categories.should == Days::Category.all
23
+ end
24
+ end
25
+
26
+ describe "POST /admin/categories" do
27
+ subject { post '/admin/categories', params, env }
28
+ let(:params) { {category: {name: "Snowy"}} }
29
+
30
+ it_behaves_like 'an admin page'
31
+
32
+ it "creates category" do
33
+ subject.should be_redirect
34
+
35
+ Days::Category.last.name.should == params[:category][:name]
36
+ end
37
+
38
+ context "when category is invalid" do
39
+ before do
40
+ Days::Category.any_instance.stub(:valid? => false, :save => false)
41
+ end
42
+
43
+ specify { subject.status.should == 406 } # not acceptable
44
+
45
+ it "renders form" do
46
+ render[:data].should == :'admin/categories'
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "PUT /admin/categories/:id" do
52
+ subject { put "/admin/categories/#{category.id}", params, env }
53
+ let(:params) { {category: {name: 'Storm'}} }
54
+
55
+ it_behaves_like 'an admin page'
56
+
57
+ it "updates category" do
58
+ subject.should be_redirect
59
+ URI.parse(subject['Location']).path.should == '/admin/categories'
60
+
61
+ category.reload
62
+ category.name.should == 'Storm'
63
+ end
64
+
65
+ context "when invalid" do
66
+ before do
67
+ Days::Category.any_instance.stub(:valid? => false, :save => false)
68
+ end
69
+
70
+ it "renders form" do
71
+ render[:data].should == :'admin/categories'
72
+ end
73
+ end
74
+
75
+ context "with invalid category" do
76
+ let(:category) { double.tap { |_| _.stub(id: Days::Category.last.id.succ) } }
77
+
78
+ it { should be_not_found }
79
+ end
80
+ end
81
+
82
+ describe "DELETE /admin/categories/:id" do
83
+ subject { delete "/admin/categories/#{category.id}", {}, env }
84
+
85
+ it_behaves_like 'an admin page'
86
+
87
+ it "destroys category" do
88
+ expect { subject }.to change { Days::Category.where(id: category.id).count }.from(1).to(0)
89
+ subject.should be_redirect
90
+ URI.parse(subject.location).path.should == "/admin/categories"
91
+ end
92
+
93
+ context "with invalid category" do
94
+ let(:category) { double.tap { |_| _.stub(id: Days::Category.last.id.succ) } }
95
+
96
+ it { should be_not_found }
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,185 @@
1
+ require 'spec_helper'
2
+
3
+ describe Days::App, type: :controller do
4
+ describe "admin: entries" do
5
+ fixtures :users, :categories, :entries
6
+ let(:entry) { entries(:entry_one) }
7
+ let(:user) { users(:blogger) }
8
+
9
+ before { login(user) }
10
+
11
+ describe "GET /admin/entries" do
12
+ subject { get '/admin/entries', {}, env }
13
+
14
+ it_behaves_like 'an admin page'
15
+
16
+ it { should be_ok }
17
+
18
+ it "lists up entries" do
19
+ render[:data].should == :'admin/entries/index'
20
+
21
+ entries = render[:ivars][:@entries]
22
+ entries.should == Days::Entry.order('id DESC').all
23
+ end
24
+ end
25
+
26
+ describe "GET /admin/entries/new" do
27
+ subject { get '/admin/entries/new', {}, env }
28
+
29
+ it_behaves_like 'an admin page'
30
+
31
+ it { should be_ok }
32
+
33
+ it "renders form page" do
34
+ render[:data].should == :'admin/entries/form'
35
+ entry = render[:ivars][:@entry]
36
+ entry.should be_a(Days::Entry)
37
+ entry.should be_new_record
38
+ end
39
+ end
40
+
41
+ describe "POST /admin/entries" do
42
+ subject { post '/admin/entries', params, env }
43
+ let(:entry) { Days::Entry.last }
44
+ let(:entry_params) { {title: "Hello", body: "World"} }
45
+ let(:params) { {entry: entry_params} }
46
+
47
+ it_behaves_like 'an admin page'
48
+
49
+ it "creates entry" do
50
+ subject.should be_redirect
51
+
52
+ entry.title.should == "Hello"
53
+ entry.body.should == "World"
54
+ entry.user.should == user
55
+ end
56
+
57
+ context "when entry is invalid" do
58
+ before do
59
+ Days::Entry.any_instance.stub(:valid? => false, :save => false)
60
+ end
61
+
62
+ specify { subject.status.should == 406 } # not acceptable
63
+
64
+ it "renders form" do
65
+ render[:data].should == :'admin/entries/form'
66
+ ientry = render[:ivars][:@entry]
67
+ ientry.should be_a_new_record
68
+ ientry.title.should == 'Hello'
69
+ ientry.body.should == 'World'
70
+ end
71
+ end
72
+
73
+ context "with category" do
74
+ let(:categories) do
75
+ Hash[Days::Category.pluck(:id).map{ |_| [_, '1'] }]
76
+ end
77
+
78
+ let(:params) do
79
+ {entry: entry_params.merge(categories: categories)}
80
+ end
81
+
82
+ it { should be_redirect }
83
+
84
+ it "creates entry with categories" do
85
+ subject
86
+ entry.categories.reload.map(&:id).should == Days::Category.pluck(:id)
87
+ end
88
+ end
89
+ end
90
+
91
+ describe "GET /admin/entries/:id" do
92
+ subject { get "/admin/entries/#{entry.id}", {}, env }
93
+
94
+ it_behaves_like 'an admin page'
95
+
96
+ it "renders form page" do
97
+ render[:data].should == :'admin/entries/form'
98
+ render[:ivars][:@entry].should == entry
99
+ end
100
+
101
+ context "with invalid entry" do
102
+ let(:entry) { double.tap { |_| _.stub(id: Days::Entry.last.id.succ) } }
103
+
104
+ it { should be_not_found }
105
+ end
106
+ end
107
+
108
+ describe "PUT /admin/entries/:id" do
109
+ subject { put path, params, env }
110
+ let(:path) { "/admin/entries/#{entry.id}" }
111
+ let(:valid_params) { {entry: {title: 'New'}} }
112
+ let(:params) { valid_params }
113
+
114
+ it_behaves_like 'an admin page'
115
+
116
+ it "updates entry" do
117
+ subject.should be_redirect
118
+ URI.parse(subject['Location']).path.should == path
119
+
120
+ entry.reload
121
+ entry.title.should == 'New'
122
+ entry.body.should == 'a rainy day'
123
+ end
124
+
125
+ context "when invalid" do
126
+ before do
127
+ Days::Entry.any_instance.stub(:valid? => false, :save => false)
128
+ end
129
+
130
+ it "renders form" do
131
+ render[:data].should == :'admin/entries/form'
132
+ ientry = render[:ivars][:@entry]
133
+ ientry.id.should == entry.id
134
+ ientry.title.should == 'New'
135
+ entry.title.should == 'Today was'
136
+ end
137
+ end
138
+
139
+ context "with category" do
140
+ let(:params) do
141
+ {entry: {categories: {categories(:rainy).id.to_s => '1'}}}
142
+ end
143
+
144
+ it "creates entry with categories" do
145
+ subject.should be_redirect
146
+ entry.categories.reload.map(&:id).should == [categories(:rainy).id]
147
+ end
148
+ end
149
+
150
+ context "with invalid entry" do
151
+ let(:entry) { double.tap { |_| _.stub(id: Days::Entry.last.id.succ) } }
152
+
153
+ it { should be_not_found }
154
+ end
155
+ end
156
+
157
+ describe "DELETE /admin/entries/:id" do
158
+ subject { delete "/admin/entries/#{entry.id}", {}, env }
159
+
160
+ it_behaves_like 'an admin page'
161
+
162
+ it "destroys entry" do
163
+ expect { subject }.to change { Days::Entry.where(id: entry.id).count }.from(1).to(0)
164
+ subject.should be_redirect
165
+ URI.parse(subject.location).path.should == "/admin/entries"
166
+ end
167
+
168
+ context "with invalid entry" do
169
+ let(:entry) { double.tap { |_| _.stub(id: Days::Entry.last.id.succ) } }
170
+
171
+ it { should be_not_found }
172
+ end
173
+ end
174
+
175
+ describe "POST /admin/entries/preview" do
176
+ subject { post "/admin/entries/preview", params, env }
177
+ let(:valid_params) { {} }
178
+ let(:params) { valid_params }
179
+
180
+ it_behaves_like 'an admin page'
181
+
182
+ it "renders body for preview"
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,112 @@
1
+ require 'spec_helper'
2
+
3
+ describe Days::App, type: :controller do
4
+ describe "admin: sessions" do
5
+ let(:user) do
6
+ Days::User.create(
7
+ name: 'Blogger', login_name: 'blogger',
8
+ password: 'password', password_confirmation: 'password'
9
+ )
10
+ end
11
+
12
+ before do
13
+ Days::User.destroy_all
14
+ user
15
+ end
16
+
17
+ after do
18
+ user.destroy
19
+ end
20
+
21
+ describe "GET /admin/login" do
22
+ subject { get '/admin/login' }
23
+
24
+ it "renders login page" do
25
+ render[:data].should == :'admin/login'
26
+ end
27
+ end
28
+
29
+ describe "POST /admin/login" do
30
+ subject { post '/admin/login', params, env }
31
+ let(:params) { {login_name: 'blogger', password: 'password'} }
32
+
33
+ it "logs in" do
34
+ expect { subject }.to \
35
+ change { session[:user_id] }.from(nil).to(user.id)
36
+ end
37
+
38
+ it "redirects to /admin" do
39
+ subject.should be_redirect
40
+ URI.parse(subject.location).path.should == '/admin'
41
+ end
42
+
43
+ context "without login name" do
44
+ let(:params) { {password: 'password'} }
45
+
46
+ specify do
47
+ subject.status.should == 400
48
+ end
49
+ end
50
+
51
+ context "without password" do
52
+ let(:params) { {login_name: 'blogger'} }
53
+
54
+ specify do
55
+ subject.status.should == 400
56
+ end
57
+ end
58
+
59
+ context "with wrong login name" do
60
+ let(:params) { {login_name: 'not exists', password: 'password'} }
61
+
62
+ it "doesn't log in" do
63
+ subject
64
+ session[:user_id].should be_nil
65
+ end
66
+
67
+ it "returns login page" do
68
+ subject.status.should == 401
69
+ render[:data].should == :'admin/login'
70
+ end
71
+ end
72
+
73
+ context "with wrong password" do
74
+ let(:params) { {login_name: 'blogger', password: 'passw0rd'} }
75
+
76
+ it "doesn't log in" do
77
+ subject
78
+ session[:user_id].should be_nil
79
+ end
80
+
81
+ it "returns login page" do
82
+ subject.status.should == 401
83
+ render[:data].should == :'admin/login'
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "POST /admin/logout" do
89
+ subject { post '/admin/logout', {}, env }
90
+ context "when logged in" do
91
+ before { login(user) }
92
+
93
+ it "redirects to /admin/login" do
94
+ subject.should be_redirect
95
+ URI.parse(subject.location).path.should == '/admin/login'
96
+ end
97
+
98
+ specify do
99
+ expect { subject }.to change { session[:user_id] }.to(nil)
100
+ end
101
+ end
102
+
103
+ context "when not logged in" do
104
+ it "redirects to /admin/login" do
105
+ subject.should be_redirect
106
+ URI.parse(subject.location).path.should == '/admin/login'
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Days::App, type: :controller do
4
+ shared_examples "an setup page" do
5
+ context "when user exists" do
6
+ fixtures :users
7
+
8
+ it "denies access" do
9
+ subject.status.should == 403
10
+ end
11
+ end
12
+ end
13
+
14
+ describe "admin: setup" do
15
+ describe "GET /admin/setup" do
16
+ subject { get '/admin/setup', {}, env }
17
+
18
+ it_behaves_like 'an setup page'
19
+
20
+ context "when user not exists" do
21
+ before do
22
+ Days::User.destroy_all
23
+ end
24
+
25
+ it { should be_ok }
26
+
27
+ it "renders form page" do
28
+ render[:data].should == :'admin/setup'
29
+ user = render[:ivars][:@user]
30
+ user.should be_a(Days::User)
31
+ user.should be_new_record
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "POST /admin/setup" do
37
+ subject { post '/admin/setup', {user: user_params}, env }
38
+ let(:user_params) do
39
+ {login_name: 'newbie', name: 'Newbie',
40
+ password: 'a', password_confirmation: 'a'}
41
+ end
42
+
43
+ it_behaves_like 'an setup page'
44
+
45
+ context "when user not exists" do
46
+ before do
47
+ Days::User.destroy_all
48
+ end
49
+
50
+ it "creates user" do
51
+ expect { subject }.to change { Days::User.count }.from(0).to(1)
52
+ user = Days::User.last
53
+ user.name.should == "Newbie"
54
+ end
55
+
56
+ it "logs in" do
57
+ session[:user_id].should be_nil
58
+ subject
59
+ session[:user_id].should == Days::User.last.id
60
+ end
61
+
62
+ it "redirects to /admin" do
63
+ subject.should be_redirect
64
+ URI.parse(subject.location).path.should == '/admin'
65
+ end
66
+
67
+ context "when user is invalid" do
68
+ before do
69
+ Days::User.any_instance.stub(:valid? => false, :save => false)
70
+ end
71
+
72
+ specify { subject.status.should == 406 } # not acceptable
73
+
74
+ it "renders form" do
75
+ render[:data].should == :'admin/setup'
76
+ iuser = render[:ivars][:@user]
77
+ iuser.should be_a_new_record
78
+ iuser.name.should == 'Newbie'
79
+ iuser.login_name.should == 'newbie'
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,163 @@
1
+ require 'spec_helper'
2
+
3
+ describe Days::App, type: :controller do
4
+ describe "admin: users" do
5
+ fixtures :users
6
+ let(:user) { users(:blogger) }
7
+
8
+ before { login(user) }
9
+
10
+ describe "GET /admin/users" do
11
+ subject { get '/admin/users', {}, env }
12
+
13
+ it_behaves_like 'an admin page'
14
+
15
+ it { should be_ok }
16
+
17
+ it "lists up users" do
18
+ render[:data].should == :'admin/users/index'
19
+
20
+ users = render[:ivars][:@users]
21
+ users.should == Days::User.all
22
+ end
23
+ end
24
+
25
+ describe "GET /admin/users/new" do
26
+ subject { get '/admin/users/new', {}, env }
27
+
28
+ it_behaves_like 'an admin page'
29
+
30
+ it { should be_ok }
31
+
32
+ it "renders form page" do
33
+ render[:data].should == :'admin/users/form'
34
+ user = render[:ivars][:@user]
35
+ user.should be_a(Days::User)
36
+ user.should be_new_record
37
+ end
38
+ end
39
+
40
+ describe "POST /admin/users" do
41
+ subject { post '/admin/users', params, env }
42
+ let(:user) { Days::User.last }
43
+ let(:user_params) do
44
+ {
45
+ name: "Writer", login_name: "writer",
46
+ password: "pass", password_confirmation: "pass"
47
+ }
48
+ end
49
+ let(:params) { {user: user_params} }
50
+
51
+ it_behaves_like 'an admin page'
52
+
53
+ it "creates user" do
54
+ subject.should be_redirect
55
+
56
+ user = Days::User.last
57
+ user.name.should == "Writer"
58
+ user.login_name.should == "writer"
59
+ end
60
+
61
+ context "when user is invalid" do
62
+ before do
63
+ Days::User.any_instance.stub(:valid? => false, :save => false)
64
+ end
65
+
66
+ specify { subject.status.should == 406 } # not acceptable
67
+
68
+ it "renders form" do
69
+ render[:data].should == :'admin/users/form'
70
+ iuser = render[:ivars][:@user]
71
+ iuser.should be_a_new_record
72
+ iuser.name.should == 'Writer'
73
+ iuser.login_name.should == 'writer'
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "GET /admin/users/:id" do
79
+ subject { get "/admin/users/#{user.id}", {}, env }
80
+
81
+ it_behaves_like 'an admin page'
82
+
83
+ it "renders form page" do
84
+ render[:data].should == :'admin/users/form'
85
+ render[:ivars][:@user].should == user
86
+ end
87
+
88
+ context "with invalid user" do
89
+ let(:user) { double.tap { |_| _.stub(id: Days::User.last.id.succ) } }
90
+
91
+ it { should be_not_found }
92
+ end
93
+ end
94
+
95
+ describe "PUT /admin/users/:id" do
96
+ subject { put path, params, env }
97
+ let(:path) { "/admin/users/#{user.id}" }
98
+ let(:valid_params) { {user: {name: 'Newbie', password: 'a', password_confirmation: 'a'}} }
99
+ let(:params) { valid_params }
100
+
101
+ it_behaves_like 'an admin page'
102
+
103
+ it "updates user" do
104
+ subject.should be_redirect
105
+ URI.parse(subject['Location']).path.should == path
106
+
107
+ user.reload
108
+ user.name.should == 'Newbie'
109
+ end
110
+
111
+ context "when invalid" do
112
+ before do
113
+ Days::User.any_instance.stub(:valid? => false, :save => false)
114
+ end
115
+
116
+ it "renders form" do
117
+ render[:data].should == :'admin/users/form'
118
+ iuser = render[:ivars][:@user]
119
+ iuser.id.should == user.id
120
+ iuser.name.should == 'Newbie'
121
+ end
122
+ end
123
+
124
+ context "with invalid user" do
125
+ let(:user) { double.tap { |_| _.stub(id: Days::User.last.id.succ) } }
126
+
127
+ it { should be_not_found }
128
+ end
129
+ end
130
+
131
+ describe "DELETE /admin/users/:id" do
132
+ let(:another_user) { users(:writer) }
133
+ subject { delete "/admin/users/#{another_user.id}", {}, env }
134
+
135
+ it_behaves_like 'an admin page'
136
+
137
+ it "destroys user" do
138
+ expect { subject }.to change { Days::User.count }.by(-1)
139
+ Days::User.where(id: another_user.id).count.should be_zero
140
+
141
+ subject.should be_redirect
142
+ URI.parse(subject.location).path.should == "/admin/users"
143
+ end
144
+
145
+ context "when tried to delete myself" do
146
+ subject { delete "/admin/users/#{user.id}", {}, env }
147
+
148
+ it "doesn't destroy" do
149
+ expect { subject }.to_not change { Days::User.count }
150
+
151
+ subject.status.should == 400
152
+ end
153
+ end
154
+
155
+ context "with invalid user" do
156
+ subject { delete "/admin/users/#{user.id}", {}, env }
157
+ let(:user) { users(:blogger).tap(&:destroy) }
158
+
159
+ it { should be_not_found }
160
+ end
161
+ end
162
+ end
163
+ end