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/app/views/admin.haml
CHANGED
@@ -3,35 +3,45 @@
|
|
3
3
|
%head
|
4
4
|
%meta{charset: 'UTF-8'}
|
5
5
|
%meta{name: "viewport", content: "width=device-width, initial-scale=1.0"}
|
6
|
-
%link{href: "/assets/bootstrap.min.css", rel: "stylesheet"}
|
6
|
+
%link{href: "/assets/admin/bootstrap.min.css", rel: "stylesheet"}
|
7
7
|
%link{href: "/assets/admin.css", rel: "stylesheet", media: "screen"}
|
8
|
-
%
|
9
|
-
%script{src: '/assets/
|
10
|
-
%script{src: '/assets/bootstrap.min.js'}
|
8
|
+
%script{src: '/assets/jquery-2.1.3.min.js'}
|
9
|
+
%script{src: '/assets/admin/bootstrap.min.js'}
|
11
10
|
- if @title
|
12
11
|
%title #{@title} - Days Admin
|
13
12
|
- else
|
14
13
|
%title Days Admin
|
15
14
|
%body
|
16
|
-
.navbar.navbar-
|
17
|
-
.
|
18
|
-
.
|
19
|
-
%
|
15
|
+
%nav.navbar.navbar-default.navbar-fixed-top
|
16
|
+
.container
|
17
|
+
.navbar-header
|
18
|
+
%button.navbar-toggle.collapsed{type: 'button', data: {toggle: 'collapse', target: '#navbar-collapse-1'}}
|
19
|
+
%span.sr-only Toggle navigation
|
20
20
|
%span.icon-bar
|
21
21
|
%span.icon-bar
|
22
22
|
%span.icon-bar
|
23
|
-
%a.brand{href: '/admin/'} Days
|
24
|
-
%form.navbar-form.pull-right{action: "/admin/logout", method: "POST"}
|
25
|
-
!= csrf_tag
|
26
|
-
%button.btn.btn-link{type: 'submit'} Log out
|
27
|
-
%a.btn.btn-primary{href: '/admin/entries/new'} New Entry
|
28
23
|
|
29
|
-
%
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
24
|
+
%a.navbar-brand{href: '/admin/'} Days
|
25
|
+
|
26
|
+
%form.navbar-form.navbar-right.hidden-xs{action: "/admin/logout", method: "POST"}
|
27
|
+
!= csrf_tag
|
28
|
+
%button.btn.btn-link{type: 'submit'} Log out
|
29
|
+
%a.btn.btn-default{href: '/admin/entries/new'} New Entry
|
30
|
+
|
31
|
+
%div.collapse.navbar-collapse#navbar-collapse-1
|
32
|
+
%ul.nav.navbar-nav
|
33
|
+
%li.visible-xs
|
34
|
+
%form
|
35
|
+
%a.btn.btn-default.visible-xs{href: '/admin/entries/new'} New Entry
|
36
|
+
%li
|
37
|
+
%a{href: '/admin/entries'} Entries
|
38
|
+
%li
|
39
|
+
%a{href: '/admin/categories'} Categories
|
40
|
+
%li
|
41
|
+
%a{href: '/admin/users'} Users
|
42
|
+
%li.visible-xs
|
43
|
+
%form.form-inline{action: "/admin/logout", method: "POST"}
|
44
|
+
!= csrf_tag
|
45
|
+
%button.btn.btn-link{type: 'submit'} Log out
|
46
|
+
|
37
47
|
!= yield
|
data/days.gemspec
CHANGED
@@ -17,31 +17,34 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
-
gem.add_dependency "sinatra", '
|
20
|
+
gem.add_dependency "sinatra", '>= 1.4.5'
|
21
21
|
gem.add_dependency "thor", '~> 0.16.0'
|
22
|
-
gem.add_dependency "rack_csrf", '~> 2.
|
22
|
+
gem.add_dependency "rack_csrf", '~> 2.5.0'
|
23
23
|
|
24
24
|
gem.add_dependency "settingslogic", '~> 2.0.9'
|
25
25
|
|
26
|
-
gem.add_dependency "sprockets", '~> 2.
|
27
|
-
gem.add_dependency "
|
26
|
+
gem.add_dependency "sprockets", '~> 2.12.3'
|
27
|
+
gem.add_dependency "faml", '>= 0.2.4'
|
28
28
|
gem.add_dependency "sass", '~> 3.2.5'
|
29
29
|
|
30
|
-
gem.add_dependency "
|
31
|
-
gem.add_dependency "builder", '~> 3.0.0'
|
30
|
+
gem.add_dependency "builder", '~> 3.1'
|
32
31
|
|
33
|
-
gem.add_dependency "activerecord", "~>
|
34
|
-
gem.add_dependency "
|
32
|
+
gem.add_dependency "activerecord", "~> 4.2.0"
|
33
|
+
gem.add_dependency "protected_attributes"
|
34
|
+
gem.add_dependency "kaminari", "~> 0.16.1"
|
35
35
|
gem.add_dependency "padrino-helpers", '~> 0.9.21'
|
36
36
|
gem.add_dependency "stringex", '~> 1.5.1'
|
37
|
-
gem.add_dependency "bcrypt
|
37
|
+
gem.add_dependency "bcrypt", '~> 3.1.9'
|
38
|
+
|
39
|
+
gem.add_dependency "html-pipeline", '>= 1.11.0'
|
40
|
+
gem.add_dependency "github-markdown"
|
38
41
|
|
39
42
|
gem.add_development_dependency "sqlite3"
|
40
43
|
|
41
|
-
gem.add_development_dependency "rspec"
|
44
|
+
gem.add_development_dependency "rspec", '~> 3.2.0'
|
42
45
|
gem.add_development_dependency "rack-test"
|
43
46
|
gem.add_development_dependency "fuubar"
|
47
|
+
gem.add_development_dependency "database_rewinder"
|
44
48
|
|
45
49
|
gem.add_dependency "pry"
|
46
|
-
gem.add_development_dependency "pry-nav"
|
47
50
|
end
|
@@ -1,7 +1,11 @@
|
|
1
1
|
module Days
|
2
2
|
class App < Sinatra::Base
|
3
3
|
get "/admin/entries", :admin_only => true do
|
4
|
-
@entries = Entry.order(
|
4
|
+
@entries = Entry.order(id: :desc)
|
5
|
+
@entries = @entries.draft if params[:draft] && !params[:draft].empty?
|
6
|
+
@entries = @entries.scheduled if params[:scheduled] && !params[:scheduled].empty?
|
7
|
+
@entries = @entries.published if params[:published] && !params[:published].empty?
|
8
|
+
@entries = @entries.page(params[:page] || 1)
|
5
9
|
haml :'admin/entries/index', layout: :admin
|
6
10
|
end
|
7
11
|
|
@@ -22,6 +26,7 @@ module Days
|
|
22
26
|
|
23
27
|
@entry = Entry.new(entry)
|
24
28
|
@entry.user = current_user
|
29
|
+
@entry.pipeline = config.html_pipeline if config.html_pipeline
|
25
30
|
|
26
31
|
if @entry.save
|
27
32
|
redirect "/admin/entries/#{@entry.id}" # FIXME: Permalink
|
@@ -36,19 +41,20 @@ module Days
|
|
36
41
|
end
|
37
42
|
|
38
43
|
get "/admin/entries/:id", :admin_only => true do
|
39
|
-
@entry = Entry.
|
44
|
+
@entry = Entry.find_by(id: params[:id]) || halt(404)
|
40
45
|
@categories = Category.all
|
41
46
|
haml :'admin/entries/form', layout: :admin
|
42
47
|
end
|
43
48
|
|
44
49
|
put "/admin/entries/:id", :admin_only => true do
|
45
50
|
entry = params[:entry] || halt(400)
|
46
|
-
@entry = Entry.
|
51
|
+
@entry = Entry.find_by(id: params[:id]) || halt(404)
|
52
|
+
@entry.pipeline = config.html_pipeline if config.html_pipeline
|
47
53
|
|
48
54
|
entry[:categories] = Category.where(
|
49
55
|
id: (entry[:categories] || {}).keys.map(&:to_i)
|
50
56
|
)
|
51
|
-
@entry.
|
57
|
+
@entry.assign_attributes(entry)
|
52
58
|
|
53
59
|
if @entry.save
|
54
60
|
redirect "/admin/entries/#{@entry.id}"
|
@@ -60,7 +66,7 @@ module Days
|
|
60
66
|
end
|
61
67
|
|
62
68
|
delete "/admin/entries/:id", :admin_only => true do
|
63
|
-
@entry = Entry.
|
69
|
+
@entry = Entry.find_by(id: params[:id]) || halt(404)
|
64
70
|
@entry.destroy
|
65
71
|
|
66
72
|
redirect "/admin/entries"
|
data/lib/days/app/entries.rb
CHANGED
@@ -20,7 +20,7 @@ module Days
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
entry = Entry.
|
23
|
+
entry = Entry.find_by(old_path: request.path)
|
24
24
|
if entry
|
25
25
|
return [301, {'Location' => entry_path(entry)}, ""]
|
26
26
|
end
|
@@ -32,7 +32,7 @@ module Days
|
|
32
32
|
end
|
33
33
|
|
34
34
|
get '/category/:name' do
|
35
|
-
category = Category.
|
35
|
+
category = Category.find_by(name: params[:name]) || halt(404)
|
36
36
|
@entries = category.entries.published.page(params[:page] || 1)
|
37
37
|
haml :entries
|
38
38
|
end
|
@@ -50,20 +50,15 @@ module Days
|
|
50
50
|
haml :entries
|
51
51
|
end
|
52
52
|
|
53
|
-
|
54
|
-
content_type 'application/atom+xml'
|
55
|
-
entries = Entry.published.first(50)
|
56
|
-
|
53
|
+
private def generate_atom_feed(entries, title: config.title, html_path: '/feed')
|
57
54
|
xml = Builder::XmlMarkup.new
|
58
|
-
|
59
55
|
xml.instruct!
|
60
|
-
|
61
56
|
xml.feed("xmlns" => 'http://www.w3.org/2005/Atom') do
|
62
57
|
xml.id("tag:#{request.host},2005:#{request.fullpath.split(".")[0]}")
|
63
58
|
|
64
|
-
xml.link(:rel => 'alternate', :type => 'text/html', :href => request.
|
59
|
+
xml.link(:rel => 'alternate', :type => 'text/html', :href => [request.base_url, config.base_path, html_path].join.gsub(%r{//}, '/'))
|
65
60
|
xml.link(:rel => 'self', :type => 'application/atom+xml', :href => request.url)
|
66
|
-
xml.title
|
61
|
+
xml.title title
|
67
62
|
|
68
63
|
xml.updated(entries.map(&:updated_at).max)
|
69
64
|
|
@@ -74,14 +69,30 @@ module Days
|
|
74
69
|
xml.published entry.published_at.xmlschema
|
75
70
|
xml.updated entry.updated_at.xmlschema
|
76
71
|
|
77
|
-
xml.link(rel: 'alternate', type: 'text/html', href: "#{request.url.gsub(/\/feed$/,'')}#{entry_path(entry)}")
|
78
|
-
|
79
72
|
xml.title entry.title
|
80
73
|
|
81
|
-
|
74
|
+
href = [request.base_url, config.base_path, entry_path(entry)].join.gsub(%r{//}, '/')
|
75
|
+
xml.link(rel: 'alternate', type: 'text/html', href: href)
|
76
|
+
xml.content(entry.short_rendered { '... <a href="'+href+'">Continue Reading</a>' }, type: 'html')
|
82
77
|
end
|
83
78
|
end
|
84
79
|
end
|
85
80
|
end
|
81
|
+
|
82
|
+
get '/feed' do
|
83
|
+
entries = Entry.published.page(params[:page])
|
84
|
+
|
85
|
+
content_type 'application/atom+xml'
|
86
|
+
generate_atom_feed(entries)
|
87
|
+
end
|
88
|
+
|
89
|
+
get '/feed/category/:name' do
|
90
|
+
category = Category.find_by(name: params[:name]) || halt(404)
|
91
|
+
entries = category.entries.published.page(params[:page])
|
92
|
+
|
93
|
+
content_type 'application/atom+xml'
|
94
|
+
generate_atom_feed(entries, title: "#{config.title} (Category: #{category.name})", html_path: "/category/#{category.name}")
|
95
|
+
end
|
96
|
+
|
86
97
|
end
|
87
98
|
end
|
data/lib/days/app.rb
CHANGED
@@ -5,7 +5,7 @@ require 'rack/csrf'
|
|
5
5
|
require_relative 'config'
|
6
6
|
require_relative 'models'
|
7
7
|
require_relative 'helpers'
|
8
|
-
require '
|
8
|
+
require 'faml'
|
9
9
|
require 'sass'
|
10
10
|
|
11
11
|
I18n.load_path.reject! {|_| _.match(/padrino/) }
|
@@ -48,8 +48,6 @@ module Days
|
|
48
48
|
set(:config, nil)
|
49
49
|
set :method_override, true
|
50
50
|
|
51
|
-
set :haml, :escape_html => true
|
52
|
-
|
53
51
|
helpers Helpers
|
54
52
|
helpers Kaminari::Helpers::SinatraHelpers
|
55
53
|
|
@@ -106,6 +104,7 @@ module Days
|
|
106
104
|
env.append_path "#{self.root}/images"
|
107
105
|
})
|
108
106
|
config.establish_db_connection()
|
107
|
+
config.run_scripts()
|
109
108
|
x
|
110
109
|
end
|
111
110
|
end
|
data/lib/days/command.rb
CHANGED
@@ -55,7 +55,7 @@ module Days
|
|
55
55
|
desc "server", "Starts the server"
|
56
56
|
method_option :config, :type => :string, :aliases => "-c"
|
57
57
|
method_option :port, :type => :numeric, :aliases => "-p", :default => 3162
|
58
|
-
method_option :bind, :type => :string, :aliases => "-b", :default =>
|
58
|
+
method_option :bind, :type => :string, :aliases => "-b", :default => 'localhost'
|
59
59
|
method_option :environment, :type => :string, :aliases => "-e", :default => "development"
|
60
60
|
method_option :pid, :type => :string, :aliases => "-c"
|
61
61
|
def server
|
data/lib/days/config.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'app'
|
2
|
-
require '
|
2
|
+
require 'days/models/base'
|
3
|
+
require 'html/pipeline'
|
3
4
|
require 'logger'
|
4
5
|
require 'settingslogic'
|
5
6
|
|
@@ -33,17 +34,29 @@ module Days
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
37
|
+
attr_accessor :html_pipeline
|
36
38
|
|
37
|
-
def
|
39
|
+
def run_scripts
|
40
|
+
instance_eval (self[:script_lines] || []).join("\n")
|
41
|
+
|
42
|
+
(self[:scripts] || []).each do |_|
|
43
|
+
path = File.expand_path(_, self[:root])
|
44
|
+
instance_eval File.read(path), path, 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def establish_db_connection(force=false, base: ActiveRecord::Base)
|
38
49
|
if Days::App.environment.to_sym == :development && (self.has_key?(:activerecord_log) ? self.activerecord_log == true : true)
|
39
|
-
|
50
|
+
base.logger = Logger.new($stdout)
|
40
51
|
end
|
41
52
|
|
53
|
+
base.default_timezone = self['database_timezone'] ? self['database_timezone'].to_sym : :local
|
54
|
+
|
42
55
|
begin
|
43
56
|
raise ActiveRecord::ConnectionNotEstablished if force
|
44
|
-
return
|
57
|
+
return base.connection
|
45
58
|
rescue ActiveRecord::ConnectionNotEstablished
|
46
|
-
|
59
|
+
base.establish_connection(self['database'] ? Hash[self.database] : ENV["DATABASE_URL"])
|
47
60
|
retry
|
48
61
|
end
|
49
62
|
end
|
data/lib/days/helpers.rb
CHANGED
@@ -38,8 +38,12 @@ module Days
|
|
38
38
|
config.permalink.gsub(/{(\w+?)}/) { hash[$1.to_sym] }
|
39
39
|
end
|
40
40
|
|
41
|
+
def self.lookup_entry_regexp_for(permalink_format)
|
42
|
+
(@lookup_entry_regexp_cache ||= {})[permalink_format] ||= Regexp.compile(Regexp.escape(permalink_format).gsub(/\\{(\w+?)\\}/) { "(?<#{$1}>.+?)" } + "$")
|
43
|
+
end
|
44
|
+
|
41
45
|
def lookup_entry(path)
|
42
|
-
regexp =
|
46
|
+
regexp = Helpers.lookup_entry_regexp_for(config.permalink)
|
43
47
|
m = regexp.match(path)
|
44
48
|
return nil unless m
|
45
49
|
|
@@ -48,27 +52,25 @@ module Days
|
|
48
52
|
hash
|
49
53
|
end
|
50
54
|
|
51
|
-
|
52
55
|
if match[:id] || match[:slug]
|
53
56
|
if match[:id]
|
54
|
-
|
57
|
+
entry = Entry.find(match[:id])
|
55
58
|
else
|
56
|
-
|
59
|
+
entry = Entry.find_by(slug: match[:slug])
|
57
60
|
end
|
58
61
|
|
59
|
-
entry = query.first
|
60
62
|
return nil unless entry
|
61
63
|
published_at = entry.published_at
|
62
64
|
return nil unless published_at
|
63
65
|
|
64
66
|
return nil if match[:slug] && match[:slug] != entry.slug
|
65
67
|
return nil if match[:id] && match[:id].to_i != entry.id
|
66
|
-
return nil if match[:year] && match[:year].to_i != published_at.year
|
67
|
-
return nil if match[:month] && match[:month].to_i != published_at.month
|
68
|
-
return nil if match[:day] && match[:day].to_i != published_at.day
|
69
|
-
return nil if match[:hour] && match[:hour].to_i != published_at.hour
|
70
|
-
return nil if match[:minute] && match[:minute].to_i != published_at.min
|
71
|
-
return nil if match[:second] && match[:second].to_i != published_at.sec
|
68
|
+
return nil if match[:year] && match[:year].to_i != published_at.localtime.year
|
69
|
+
return nil if match[:month] && match[:month].to_i != published_at.localtime.month
|
70
|
+
return nil if match[:day] && match[:day].to_i != published_at.localtime.day
|
71
|
+
return nil if match[:hour] && match[:hour].to_i != published_at.localtime.hour
|
72
|
+
return nil if match[:minute] && match[:minute].to_i != published_at.localtime.min
|
73
|
+
return nil if match[:second] && match[:second].to_i != published_at.localtime.sec
|
72
74
|
|
73
75
|
return entry
|
74
76
|
else
|
data/lib/days/models/category.rb
CHANGED
data/lib/days/models/entry.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'days/models/base'
|
2
|
+
require 'html/pipeline'
|
2
3
|
require 'stringex'
|
3
|
-
require 'redcarpet'
|
4
4
|
|
5
5
|
module Days
|
6
|
-
class Entry <
|
6
|
+
class Entry < Days::Models::Base
|
7
7
|
attr_accessible :title, :body, :slug, :published_at, :categories, :user, :draft, :old_path
|
8
8
|
|
9
9
|
validates_uniqueness_of :slug
|
@@ -18,6 +18,16 @@ module Days
|
|
18
18
|
order('published_at DESC')
|
19
19
|
end
|
20
20
|
|
21
|
+
scope :draft, -> do
|
22
|
+
where(published_at: nil)
|
23
|
+
end
|
24
|
+
|
25
|
+
scope :scheduled, -> do
|
26
|
+
includes(:categories).
|
27
|
+
where('published_at IS NOT NULL AND published_at >= ?', Time.now).
|
28
|
+
order('published_at DESC')
|
29
|
+
end
|
30
|
+
|
21
31
|
paginates_per 12
|
22
32
|
|
23
33
|
def draft=(x)
|
@@ -45,6 +55,32 @@ module Days
|
|
45
55
|
self.rendered.gsub(/<!-- *more *-->.+\z/m, block_given? ? yield(self) : '')
|
46
56
|
end
|
47
57
|
|
58
|
+
def body=(*)
|
59
|
+
@need_rendering = true
|
60
|
+
super
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.default_pipeline
|
64
|
+
HTML::Pipeline.new([
|
65
|
+
HTML::Pipeline::MarkdownFilter,
|
66
|
+
])
|
67
|
+
end
|
68
|
+
|
69
|
+
def pipeline=(other)
|
70
|
+
@pipeline = other
|
71
|
+
end
|
72
|
+
|
73
|
+
def pipeline
|
74
|
+
@pipeline ||= self.class.default_pipeline
|
75
|
+
end
|
76
|
+
|
77
|
+
def render!(pipeline: self.pipeline)
|
78
|
+
result = pipeline.call(self.body)
|
79
|
+
self.rendered = result[:output].to_s
|
80
|
+
@need_rendering = false
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
48
84
|
before_validation do
|
49
85
|
if draft?
|
50
86
|
self.published_at = nil
|
@@ -55,11 +91,8 @@ module Days
|
|
55
91
|
if self.title && (!self.slug || self.slug.empty?)
|
56
92
|
self.slug = self.title.to_url
|
57
93
|
end
|
58
|
-
|
59
|
-
|
60
|
-
:no_intra_emphasis => true, :fenced_code_blocks => true,
|
61
|
-
:tables => true, :superscript => true)
|
62
|
-
self.rendered = markdown.render(self.body)
|
94
|
+
|
95
|
+
self.render! if @need_rendering
|
63
96
|
end
|
64
97
|
end
|
65
98
|
end
|
data/lib/days/models/user.rb
CHANGED
data/lib/days/version.rb
CHANGED
data/scripts/tumblr_export.rb
CHANGED
@@ -2,9 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Days::App, type: :controller do
|
4
4
|
describe "admin: categories" do
|
5
|
-
|
6
|
-
let(:
|
7
|
-
let(:category) { categories(:daily) }
|
5
|
+
let(:user) { Days::User.create!(login_name: 'blogger', name: 'blogger', password: 'x', password_confirmation: 'x') }
|
6
|
+
let!(:category) { Days::Category.create!(name: 'daily') }
|
8
7
|
|
9
8
|
before { login(user) }
|
10
9
|
|
@@ -13,13 +12,13 @@ describe Days::App, type: :controller do
|
|
13
12
|
|
14
13
|
it_behaves_like 'an admin page'
|
15
14
|
|
16
|
-
it {
|
15
|
+
it { is_expected.to be_ok }
|
17
16
|
|
18
17
|
it "lists up categories" do
|
19
|
-
render[:data].
|
18
|
+
expect(render[:data]).to eq(:'admin/categories')
|
20
19
|
|
21
20
|
categories = render[:ivars][:@categories]
|
22
|
-
categories.
|
21
|
+
expect(categories.to_a).to eq([category])
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
@@ -30,20 +29,21 @@ describe Days::App, type: :controller do
|
|
30
29
|
it_behaves_like 'an admin page'
|
31
30
|
|
32
31
|
it "creates category" do
|
33
|
-
subject.
|
32
|
+
expect(subject).to be_redirect
|
34
33
|
|
35
|
-
Days::Category.last.name.
|
34
|
+
expect(Days::Category.last.name).to eq(params[:category][:name])
|
36
35
|
end
|
37
36
|
|
38
37
|
context "when category is invalid" do
|
39
38
|
before do
|
40
|
-
Days::Category.
|
39
|
+
allow_any_instance_of(Days::Category).to receive(:valid?).and_return(false)
|
40
|
+
allow_any_instance_of(Days::Category).to receive(:save).and_return(false)
|
41
41
|
end
|
42
42
|
|
43
|
-
specify { subject.status.
|
43
|
+
specify { expect(subject.status).to eq(406) } # not acceptable
|
44
44
|
|
45
45
|
it "renders form" do
|
46
|
-
render[:data].
|
46
|
+
expect(render[:data]).to eq(:'admin/categories')
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -55,27 +55,27 @@ describe Days::App, type: :controller do
|
|
55
55
|
it_behaves_like 'an admin page'
|
56
56
|
|
57
57
|
it "updates category" do
|
58
|
-
subject.
|
59
|
-
URI.parse(subject['Location']).path.
|
58
|
+
expect(subject).to be_redirect
|
59
|
+
expect(URI.parse(subject['Location']).path).to eq('/admin/categories')
|
60
60
|
|
61
61
|
category.reload
|
62
|
-
category.name.
|
62
|
+
expect(category.name).to eq('Storm')
|
63
63
|
end
|
64
64
|
|
65
65
|
context "when invalid" do
|
66
66
|
before do
|
67
|
-
Days::Category.
|
67
|
+
allow_any_instance_of(Days::Category).to receive_messages(:valid? => false, :save => false)
|
68
68
|
end
|
69
69
|
|
70
70
|
it "renders form" do
|
71
|
-
render[:data].
|
71
|
+
expect(render[:data]).to eq(:'admin/categories')
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
75
|
context "with invalid category" do
|
76
|
-
|
76
|
+
before { category.destroy }
|
77
77
|
|
78
|
-
it {
|
78
|
+
it { is_expected.to be_not_found }
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -86,14 +86,14 @@ describe Days::App, type: :controller do
|
|
86
86
|
|
87
87
|
it "destroys category" do
|
88
88
|
expect { subject }.to change { Days::Category.where(id: category.id).count }.from(1).to(0)
|
89
|
-
subject.
|
90
|
-
URI.parse(subject.location).path.
|
89
|
+
expect(subject).to be_redirect
|
90
|
+
expect(URI.parse(subject.location).path).to eq("/admin/categories")
|
91
91
|
end
|
92
92
|
|
93
93
|
context "with invalid category" do
|
94
|
-
|
94
|
+
before { category.destroy }
|
95
95
|
|
96
|
-
it {
|
96
|
+
it { is_expected.to be_not_found }
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|