days 0.2.0 → 1.0.0.rc1
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.
- checksums.yaml +4 -4
- data/.travis.yml +21 -4
- data/app/javascripts/admin/bootstrap.min.js +7 -0
- data/app/javascripts/jquery-2.1.3.min.js +4 -0
- data/app/stylesheets/admin/bootstrap-theme.min.css +5 -0
- data/app/stylesheets/admin/bootstrap.min.css +5 -0
- data/app/stylesheets/admin/login.scss +3 -5
- data/app/stylesheets/admin.scss +4 -0
- data/app/views/admin/categories.haml +3 -3
- data/app/views/admin/entries/form.haml +22 -17
- data/app/views/admin/entries/index.haml +46 -28
- data/app/views/admin/login.haml +11 -8
- data/app/views/admin/setup.haml +16 -9
- data/app/views/admin.haml +31 -21
- data/days.gemspec +14 -11
- data/lib/days/app/admin/entries.rb +11 -5
- data/lib/days/app/entries.rb +24 -13
- data/lib/days/app.rb +2 -3
- data/lib/days/command.rb +1 -1
- data/lib/days/config.rb +18 -5
- data/lib/days/helpers.rb +13 -11
- data/lib/days/models/base.rb +11 -0
- data/lib/days/models/category.rb +2 -2
- data/lib/days/models/entry.rb +41 -8
- data/lib/days/models/user.rb +2 -2
- data/lib/days/version.rb +1 -1
- data/scripts/tumblr_export.rb +1 -1
- data/spec/controllers/admin/categories_spec.rb +22 -22
- data/spec/controllers/admin/entries_spec.rb +155 -44
- data/spec/controllers/admin/session_spec.rb +16 -25
- data/spec/controllers/admin/setup_spec.rb +22 -25
- data/spec/controllers/admin/users_spec.rb +39 -40
- data/spec/controllers/entries_spec.rb +71 -42
- data/spec/helpers_spec.rb +18 -29
- data/spec/models/entry_spec.rb +117 -47
- data/spec/shared/admin.rb +2 -2
- data/spec/spec_helper.rb +25 -25
- metadata +111 -86
- data/app/javascripts/bootstrap.js +0 -2159
- data/app/javascripts/bootstrap.min.js +0 -6
- data/app/javascripts/jquery-1.8.3.min.js +0 -2
- data/app/stylesheets/bootstrap-responsive.css +0 -1092
- data/app/stylesheets/bootstrap-responsive.min.css +0 -9
- data/app/stylesheets/bootstrap.css +0 -6039
- data/app/stylesheets/bootstrap.min.css +0 -9
data/spec/models/entry_spec.rb
CHANGED
@@ -1,59 +1,129 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Days::Entry do
|
4
|
-
before do
|
5
|
-
described_class.destroy_all
|
6
|
-
end
|
7
|
-
|
8
|
-
after do
|
9
|
-
described_class.destroy_all
|
10
|
-
end
|
11
|
-
|
12
4
|
subject do
|
13
5
|
described_class.new(title: 'title', body: 'a')
|
14
6
|
end
|
15
7
|
|
8
|
+
describe "#render!" do
|
9
|
+
def generate_pipeline(rendered_text)
|
10
|
+
double("pipeline(#{rendered_text.inspect})").tap do |d|
|
11
|
+
allow(d).to receive(:call) do |text|
|
12
|
+
expect(text).to eq 'text'
|
13
|
+
{output: rendered_text}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:pipeline) do
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
subject do
|
23
|
+
described_class.new(title: 'title', body: 'text')
|
24
|
+
end
|
25
|
+
|
26
|
+
before do
|
27
|
+
allow(described_class).to receive(:default_pipeline).and_return(generate_pipeline('default'))
|
28
|
+
end
|
29
|
+
|
30
|
+
context "without pipeline, @pipeline" do
|
31
|
+
it "uses default_pipeline" do
|
32
|
+
expect {
|
33
|
+
subject.render!
|
34
|
+
}.to change {
|
35
|
+
subject.rendered
|
36
|
+
}.from(nil).to('default')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with @pipeline" do
|
41
|
+
before do
|
42
|
+
subject.pipeline = generate_pipeline('instance')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "uses @pipeline" do
|
46
|
+
expect {
|
47
|
+
subject.render!
|
48
|
+
}.to change {
|
49
|
+
subject.rendered
|
50
|
+
}.from(nil).to('instance')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "with pipeline" do
|
55
|
+
it "uses passed argument" do
|
56
|
+
expect {
|
57
|
+
subject.render!(pipeline: generate_pipeline('arg'))
|
58
|
+
}.to change {
|
59
|
+
subject.rendered
|
60
|
+
}.from(nil).to('arg')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
16
64
|
|
17
|
-
describe "rendering" do
|
65
|
+
describe "auto-rendering" do
|
18
66
|
subject do
|
19
67
|
described_class.new(title: 'title', body: 'a')
|
20
68
|
end
|
21
69
|
|
22
70
|
before do
|
23
|
-
|
24
|
-
|
71
|
+
allow(subject).to receive(:render!) do
|
72
|
+
subject.rendered = 'rendered'
|
73
|
+
end
|
25
74
|
end
|
26
75
|
|
27
|
-
|
76
|
+
context "normal" do
|
77
|
+
before do
|
78
|
+
subject.save
|
79
|
+
end
|
80
|
+
|
81
|
+
it { is_expected.to be_valid }
|
28
82
|
|
29
|
-
|
30
|
-
|
83
|
+
specify do
|
84
|
+
expect(subject.rendered).to eq('rendered')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "modified body" do
|
89
|
+
before do
|
90
|
+
subject.save!
|
91
|
+
subject.rendered = ''
|
92
|
+
subject.body = 'b'
|
93
|
+
subject.save
|
94
|
+
end
|
95
|
+
|
96
|
+
it { is_expected.to be_valid }
|
97
|
+
|
98
|
+
specify do
|
99
|
+
expect(subject.rendered).to eq('rendered')
|
100
|
+
end
|
31
101
|
end
|
32
102
|
end
|
33
103
|
|
34
104
|
describe "slug" do
|
35
105
|
before do
|
36
|
-
String.
|
106
|
+
allow_any_instance_of(String).to receive_messages(to_url: "slug")
|
37
107
|
subject.save
|
38
108
|
end
|
39
109
|
|
40
|
-
it {
|
110
|
+
it { is_expected.to be_valid }
|
41
111
|
|
42
112
|
it "generates slug"do
|
43
|
-
subject.slug.
|
113
|
+
expect(subject.slug).to eq('slug')
|
44
114
|
end
|
45
115
|
|
46
116
|
context "with empty slug" do
|
47
117
|
before do
|
48
|
-
String.
|
118
|
+
allow_any_instance_of(String).to receive_messages(to_url: "slug")
|
49
119
|
subject.slug = ""
|
50
120
|
subject.save
|
51
121
|
end
|
52
122
|
|
53
|
-
it {
|
123
|
+
it { is_expected.to be_valid }
|
54
124
|
|
55
125
|
it "generates slug"do
|
56
|
-
subject.slug.
|
126
|
+
expect(subject.slug).to eq('slug')
|
57
127
|
end
|
58
128
|
end
|
59
129
|
end
|
@@ -65,59 +135,59 @@ describe Days::Entry do
|
|
65
135
|
end
|
66
136
|
|
67
137
|
specify do
|
68
|
-
subject.
|
138
|
+
expect(subject).not_to be_published
|
69
139
|
end
|
70
140
|
|
71
141
|
specify do
|
72
|
-
subject.
|
142
|
+
expect(subject).not_to be_scheduled
|
73
143
|
end
|
74
144
|
end
|
75
145
|
|
76
146
|
context "when after published_at" do
|
77
147
|
before do
|
78
148
|
base = Time.now
|
79
|
-
Time.
|
149
|
+
allow(Time).to receive_messages(now: base)
|
80
150
|
subject.published_at = base - 1
|
81
151
|
end
|
82
152
|
|
83
153
|
specify do
|
84
|
-
subject.
|
154
|
+
expect(subject).to be_published
|
85
155
|
end
|
86
156
|
|
87
157
|
specify do
|
88
|
-
subject.
|
158
|
+
expect(subject).not_to be_scheduled
|
89
159
|
end
|
90
160
|
end
|
91
161
|
|
92
162
|
context "when just published_at" do
|
93
163
|
before do
|
94
164
|
base = Time.now
|
95
|
-
Time.
|
165
|
+
allow(Time).to receive_messages(now: base)
|
96
166
|
subject.published_at = base
|
97
167
|
end
|
98
168
|
|
99
169
|
specify do
|
100
|
-
subject.
|
170
|
+
expect(subject).to be_published
|
101
171
|
end
|
102
172
|
|
103
173
|
specify do
|
104
|
-
subject.
|
174
|
+
expect(subject).not_to be_scheduled
|
105
175
|
end
|
106
176
|
end
|
107
177
|
|
108
178
|
context "when before published_at" do
|
109
179
|
before do
|
110
180
|
base = Time.now
|
111
|
-
Time.
|
181
|
+
allow(Time).to receive_messages(now: base)
|
112
182
|
subject.published_at = base + 1
|
113
183
|
end
|
114
184
|
|
115
185
|
specify do
|
116
|
-
subject.
|
186
|
+
expect(subject).not_to be_published
|
117
187
|
end
|
118
188
|
|
119
189
|
specify do
|
120
|
-
subject.
|
190
|
+
expect(subject).to be_scheduled
|
121
191
|
end
|
122
192
|
end
|
123
193
|
end
|
@@ -128,7 +198,7 @@ describe Days::Entry do
|
|
128
198
|
described_class.create(title: 'B', body: 'b', published_at: Time.local(2012,12,30,11,0,0))
|
129
199
|
described_class.create(title: 'C', body: 'c', published_at: Time.local(2012,12,30, 9,0,0))
|
130
200
|
described_class.create(title: 'D', body: 'd', published_at: Time.local(2013, 1, 1, 9,0,0))
|
131
|
-
Time.
|
201
|
+
allow(Time).to receive_messages(now: Time.local(2012,12,30, 14,0,0))
|
132
202
|
end
|
133
203
|
|
134
204
|
subject do
|
@@ -136,26 +206,26 @@ describe Days::Entry do
|
|
136
206
|
end
|
137
207
|
|
138
208
|
it "orders by published_at" do
|
139
|
-
subject.map(&:title).
|
209
|
+
expect(subject.map(&:title)).to eq(['B', 'C'])
|
140
210
|
end
|
141
211
|
|
142
212
|
it "rejects not published entries" do
|
143
|
-
subject.map(&:title).
|
144
|
-
subject.map(&:title).
|
213
|
+
expect(subject.map(&:title)).not_to include('A')
|
214
|
+
expect(subject.map(&:title)).not_to include('D')
|
145
215
|
end
|
146
216
|
|
147
217
|
context "all published" do
|
148
218
|
before do
|
149
|
-
Time.
|
219
|
+
allow(Time).to receive_messages(now: Time.local(2013,1,1,14,0,0))
|
150
220
|
end
|
151
221
|
|
152
222
|
it "orders by published_at" do
|
153
|
-
subject.map(&:title).
|
223
|
+
expect(subject.map(&:title)).to eq(['D', 'B', 'C'])
|
154
224
|
end
|
155
225
|
|
156
226
|
it "rejects not published entries" do
|
157
|
-
subject.map(&:title).
|
158
|
-
subject.map(&:title).
|
227
|
+
expect(subject.map(&:title)).not_to include('A')
|
228
|
+
expect(subject.map(&:title)).to include('D')
|
159
229
|
end
|
160
230
|
end
|
161
231
|
end
|
@@ -169,7 +239,7 @@ describe Days::Entry do
|
|
169
239
|
end
|
170
240
|
|
171
241
|
it "nullifies published_at" do
|
172
|
-
subject.published_at.
|
242
|
+
expect(subject.published_at).to be_nil
|
173
243
|
end
|
174
244
|
end
|
175
245
|
|
@@ -182,25 +252,25 @@ describe Days::Entry do
|
|
182
252
|
|
183
253
|
context "when published_at is nil" do
|
184
254
|
before do
|
185
|
-
Time.
|
255
|
+
allow(Time).to receive_messages(now: base)
|
186
256
|
subject.published_at = nil
|
187
257
|
subject.valid?
|
188
258
|
end
|
189
259
|
|
190
260
|
it "fills published_at" do
|
191
|
-
subject.published_at.
|
261
|
+
expect(subject.published_at).to eq(base)
|
192
262
|
end
|
193
263
|
end
|
194
264
|
|
195
265
|
context "when published_at is not nil" do
|
196
266
|
before do
|
197
|
-
Time.
|
267
|
+
allow(Time).to receive_messages(now: base + 1)
|
198
268
|
subject.published_at = base
|
199
269
|
subject.valid?
|
200
270
|
end
|
201
271
|
|
202
272
|
it "keeps published_at" do
|
203
|
-
subject.published_at.
|
273
|
+
expect(subject.published_at).to eq(base)
|
204
274
|
end
|
205
275
|
end
|
206
276
|
end
|
@@ -218,20 +288,20 @@ describe Days::Entry do
|
|
218
288
|
let(:body) { "a\n\n<!--more-->\n\nb" }
|
219
289
|
|
220
290
|
it "deletes after <!--more-->" do
|
221
|
-
subject.short_rendered.
|
291
|
+
expect(subject.short_rendered).to eq("<p>a</p>\n\n")
|
222
292
|
end
|
223
293
|
|
224
294
|
context "without <!--more--> in body" do
|
225
295
|
let(:body) { "a\n\nb" }
|
226
296
|
|
227
297
|
it "returns entire rendered body" do
|
228
|
-
subject.short_rendered.
|
298
|
+
expect(subject.short_rendered).to eq(subject.rendered)
|
229
299
|
end
|
230
300
|
end
|
231
301
|
|
232
302
|
context "with block" do
|
233
303
|
it "replaces by block evaluation result" do
|
234
|
-
subject.short_rendered { "hi!" }.
|
304
|
+
expect(subject.short_rendered { "hi!" }).to eq("<p>a</p>\n\nhi!")
|
235
305
|
end
|
236
306
|
end
|
237
307
|
end
|
data/spec/shared/admin.rb
CHANGED
@@ -2,7 +2,7 @@ shared_examples "an admin page" do
|
|
2
2
|
before { env.delete 'rack.session' }
|
3
3
|
|
4
4
|
it "redirects to /admin/login" do
|
5
|
-
subject.
|
6
|
-
URI.parse(subject.location).path.
|
5
|
+
expect(subject).to be_redirect
|
6
|
+
expect(URI.parse(subject.location).path).to eq('/admin/login')
|
7
7
|
end
|
8
8
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
ENV["RACK_ENV"] ||= 'test'
|
2
|
+
require 'active_record'
|
3
|
+
require 'database_rewinder'
|
2
4
|
require 'days'
|
3
5
|
require 'days/models'
|
4
6
|
require 'days/migrator'
|
5
7
|
require 'rack/test'
|
6
|
-
|
7
|
-
require 'active_record/fixtures'
|
8
|
-
require 'active_support/test_case'
|
8
|
+
|
9
9
|
require 'pry'
|
10
10
|
|
11
11
|
Days::App.set :environment, :test
|
12
|
+
Days::App.set :raise_errors, true
|
12
13
|
|
13
14
|
module AppSpecHelper
|
14
15
|
include Rack::Test::Methods
|
@@ -49,10 +50,10 @@ module AppSpecHelper
|
|
49
50
|
ActiveRecord::Base.logger = nil
|
50
51
|
end
|
51
52
|
|
52
|
-
before(:
|
53
|
+
before(:example) do |example|
|
53
54
|
@renders = []
|
54
|
-
unless
|
55
|
-
Days::App.
|
55
|
+
unless example.metadata[:render]
|
56
|
+
allow_any_instance_of(Days::App).to receive(:render) do |instance, *args, &block|
|
56
57
|
@renders << {engine: args[0], data: args[1], options: args[2] || {}, locals: args[3] || {}, ivars: args[4] || {}}
|
57
58
|
""
|
58
59
|
end
|
@@ -90,24 +91,7 @@ module SetupAndTeardown
|
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
93
|
-
module FixturesAdapter
|
94
|
-
extend ActiveSupport::Concern
|
95
|
-
include SetupAndTeardown
|
96
|
-
include ActiveRecord::TestFixtures
|
97
|
-
|
98
|
-
included do
|
99
|
-
self.fixture_path = "#{File.dirname(__FILE__)}/fixtures"
|
100
|
-
self.use_transactional_fixtures = false
|
101
|
-
self.use_instantiated_fixtures = true
|
102
|
-
|
103
|
-
self.fixture_class_names = Hash.new do |h, table_name|
|
104
|
-
h[table_name] = "Days::#{ActiveRecord::Fixtures.find_table_name(table_name)}"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
94
|
RSpec.configure do |config|
|
110
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
111
95
|
config.run_all_when_everything_filtered = true
|
112
96
|
config.filter_run :focus
|
113
97
|
# config.order = 'random'
|
@@ -119,16 +103,32 @@ RSpec.configure do |config|
|
|
119
103
|
config.before(:suite) do
|
120
104
|
Days::App.environment = ENV["RACK_ENV"] || :test
|
121
105
|
config.days_config.establish_db_connection()
|
122
|
-
Days::Migrator.start(config.days_config, verbose: true)
|
123
106
|
ActiveRecord::Base.configurations = {'test' => Hash[config.days_config.database]}
|
107
|
+
|
108
|
+
Days::Migrator.start(config.days_config, verbose: true)
|
124
109
|
ActiveRecord::Base.logger = nil
|
110
|
+
|
111
|
+
DatabaseRewinder.clean_all
|
125
112
|
end
|
126
113
|
|
114
|
+
config.after(:each) do
|
115
|
+
DatabaseRewinder.clean
|
116
|
+
end
|
127
117
|
|
128
118
|
config.include AppSpecHelper, type: :controller
|
129
|
-
config.include FixturesAdapter
|
130
119
|
|
131
120
|
config.tty = true
|
121
|
+
|
122
|
+
config.mock_with :rspec do |mocks|
|
123
|
+
# In RSpec 3, `any_instance` implementation blocks will be yielded the receiving
|
124
|
+
# instance as the first block argument to allow the implementation block to use
|
125
|
+
# the state of the receiver.
|
126
|
+
# In RSpec 2.99, to maintain compatibility with RSpec 3 you need to either set
|
127
|
+
# this config option to `false` OR set this to `true` and update your
|
128
|
+
# `any_instance` implementation blocks to account for the first block argument
|
129
|
+
# being the receiving instance.
|
130
|
+
mocks.yield_receiver_to_any_instance_implementation_blocks = true
|
131
|
+
end
|
132
132
|
end
|
133
133
|
|
134
134
|
require_relative "./shared/admin"
|