mirror of
https://github.com/samsonjs/samhuri.net.git
synced 2026-04-27 14:57:40 +00:00
expose drafts via HarpBlog and the API
This commit is contained in:
parent
8f6b3be1eb
commit
c8f543122b
3 changed files with 303 additions and 88 deletions
|
|
@ -19,7 +19,7 @@ class HarpBlog
|
||||||
|
|
||||||
class Post
|
class Post
|
||||||
PERSISTENT_FIELDS = %w[author title date timestamp link url tags].map(&:to_sym)
|
PERSISTENT_FIELDS = %w[author title date timestamp link url tags].map(&:to_sym)
|
||||||
TRANSIENT_FIELDS = %w[time slug body].map(&:to_sym)
|
TRANSIENT_FIELDS = %w[time slug body draft].map(&:to_sym)
|
||||||
FIELDS = PERSISTENT_FIELDS + TRANSIENT_FIELDS
|
FIELDS = PERSISTENT_FIELDS + TRANSIENT_FIELDS
|
||||||
attr_accessor *FIELDS
|
attr_accessor *FIELDS
|
||||||
|
|
||||||
|
|
@ -51,9 +51,8 @@ class HarpBlog
|
||||||
!!link
|
!!link
|
||||||
end
|
end
|
||||||
|
|
||||||
def title=(title)
|
def draft?
|
||||||
@slug = nil
|
@draft
|
||||||
@title = title
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def author
|
def author
|
||||||
|
|
@ -69,7 +68,12 @@ class HarpBlog
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
@url ||= "/posts/#{time.year}/#{padded_month}/#{slug}"
|
@url ||=
|
||||||
|
if draft?
|
||||||
|
"/posts/drafts/#{slug}"
|
||||||
|
else
|
||||||
|
"/posts/#{time.year}/#{padded_month}/#{slug}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def slug
|
def slug
|
||||||
|
|
@ -95,6 +99,14 @@ class HarpBlog
|
||||||
pad(time.month)
|
pad(time.month)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dir
|
||||||
|
if draft?
|
||||||
|
'drafts'
|
||||||
|
else
|
||||||
|
File.join(time.year.to_s, padded_month)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def pad(n)
|
def pad(n)
|
||||||
n.to_i < 10 ? "0#{n}" : "#{n}"
|
n.to_i < 10 ? "0#{n}" : "#{n}"
|
||||||
end
|
end
|
||||||
|
|
@ -149,71 +161,64 @@ class HarpBlog
|
||||||
end
|
end
|
||||||
|
|
||||||
def posts_for_month(year, month)
|
def posts_for_month(year, month)
|
||||||
post_dir = post_path(year, month)
|
read_posts(File.join(year, month))
|
||||||
post_data = read_post_data(post_dir)
|
end
|
||||||
post_data.values.sort_by { |p| p['timestamp'] }.map { |p| Post.new(p) }
|
|
||||||
|
def drafts
|
||||||
|
read_posts('drafts', draft: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_post(year, month, slug)
|
def get_post(year, month, slug)
|
||||||
post_dir = post_path(year, month)
|
read_post(File.join(year, month), slug)
|
||||||
post_filename = File.join(post_dir, "#{slug}.md")
|
|
||||||
post_data = read_post_data(post_dir)
|
|
||||||
if File.exist?(post_filename) && fields = post_data[slug]
|
|
||||||
fields[:body] = File.read(post_filename)
|
|
||||||
Post.new(fields)
|
|
||||||
elsif fields
|
|
||||||
message = "missing post body for #{year}/#{month}/#{slug}: #{post_filename}"
|
|
||||||
$stderr.puts "[HarpBlog#get_post] #{message}"
|
|
||||||
raise InvalidDataError.new(message)
|
|
||||||
elsif File.exist?(post_filename)
|
|
||||||
message = "missing metadata for #{year}/#{month}/#{slug}: #{post_dir}/_data.json"
|
|
||||||
$stderr.puts "[HarpBlog#get_post] #{message}"
|
|
||||||
raise InvalidDataError.new(message)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_post(title, body, link)
|
def get_draft(slug)
|
||||||
|
read_post('drafts', slug, draft: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_post(title, body, link, extra_fields = nil)
|
||||||
if !title || title.strip.length == 0
|
if !title || title.strip.length == 0
|
||||||
title = find_title(link)
|
title = find_title(link)
|
||||||
end
|
end
|
||||||
unless title
|
unless title
|
||||||
raise "cannot find title for #{link}"
|
raise "cannot find title for #{link}"
|
||||||
end
|
end
|
||||||
fields = {
|
extra_fields ||= {}
|
||||||
|
fields = extra_fields.merge({
|
||||||
title: title,
|
title: title,
|
||||||
link: link,
|
link: link,
|
||||||
body: body,
|
body: body,
|
||||||
}
|
})
|
||||||
post = Post.new(fields)
|
post = Post.new(fields)
|
||||||
year, month, slug = post.time.year, post.padded_month, post.slug
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
existing_post = get_post(year.to_s, month, slug)
|
existing_post = read_post(post.dir, post.slug, extra_fields)
|
||||||
rescue InvalidDataError => e
|
rescue InvalidDataError => e
|
||||||
$stderr.puts "[HarpBlog#create_post] deleting post with invalid data: #{e.message}"
|
$stderr.puts "[HarpBlog#create_post] deleting post with invalid data: #{e.message}"
|
||||||
delete_post(year.to_s, month, slug)
|
delete_post_from_dir(post.dir, post.slug)
|
||||||
existing_post = nil
|
existing_post = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if existing_post
|
if existing_post
|
||||||
raise PostExistsError.new("post exists: #{year}/#{month}/#{slug}")
|
raise PostExistsError.new("post exists: #{post.dir}/#{post.slug}")
|
||||||
else
|
else
|
||||||
save_post(post)
|
save_post('create post', post)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_post(post, title, body, link)
|
def update_post(post, title, body, link)
|
||||||
old_slug = post.slug
|
|
||||||
post.title = title
|
post.title = title
|
||||||
post.body = body
|
post.body = body
|
||||||
post.link = link
|
post.link = link
|
||||||
save_post(post, old_slug)
|
save_post('update post', post)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_post(year, month, slug)
|
def delete_post(year, month, slug)
|
||||||
post_dir = post_path(year, month)
|
delete_post_from_dir(File.join(year, month), slug)
|
||||||
delete_post_body(post_dir, slug)
|
end
|
||||||
delete_post_index(post_dir, slug)
|
|
||||||
|
def delete_draft(slug)
|
||||||
|
delete_post_from_dir('drafts', slug)
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish(production = false)
|
def publish(production = false)
|
||||||
|
|
@ -236,37 +241,74 @@ class HarpBlog
|
||||||
path_for('public/posts', *components)
|
path_for('public/posts', *components)
|
||||||
end
|
end
|
||||||
|
|
||||||
def save_post(post, old_slug = nil)
|
def drafts_path(*components)
|
||||||
|
post_path('drafts', *components)
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_posts(post_dir, extra_fields = nil)
|
||||||
|
post_data = read_post_data(post_path(post_dir))
|
||||||
|
post_data.sort_by do |k, v|
|
||||||
|
(v['timestamp'] || Time.now).to_i
|
||||||
|
end.map do |slug, fields|
|
||||||
|
Post.new(fields.merge(extra_fields || {}).merge(slug: slug))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_post(post_dir, slug, extra_fields = nil)
|
||||||
|
post_filename = post_path(post_dir, "#{slug}.md")
|
||||||
|
post_data = read_post_data(post_path(post_dir))
|
||||||
|
if File.exist?(post_filename) && fields = post_data[slug]
|
||||||
|
fields[:body] = File.read(post_filename)
|
||||||
|
Post.new(fields.merge(extra_fields || {}).merge(slug: slug))
|
||||||
|
elsif fields
|
||||||
|
message = "missing post body for #{post_dir}/#{slug}: #{post_filename}"
|
||||||
|
$stderr.puts "[HarpBlog#read_post] #{message}"
|
||||||
|
raise InvalidDataError.new(message)
|
||||||
|
elsif File.exist?(post_filename)
|
||||||
|
message = "missing metadata for #{post_dir}/#{slug}: #{post_dir}/_data.json"
|
||||||
|
$stderr.puts "[HarpBlog#read_post] #{message}"
|
||||||
|
raise InvalidDataError.new(message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_post(action, post)
|
||||||
git_fetch
|
git_fetch
|
||||||
git_reset_hard('origin/master')
|
git_reset_hard('origin/master')
|
||||||
|
|
||||||
begin
|
begin
|
||||||
post_dir = write_post(post, old_slug)
|
write_post(post)
|
||||||
git_commit(post.title, post_dir)
|
git_commit(action, post.title, post_path(post.dir))
|
||||||
git_push
|
git_push
|
||||||
post
|
post
|
||||||
|
|
||||||
rescue => e
|
rescue => e
|
||||||
|
$stderr.puts "#{e.class}: #{e.message}"
|
||||||
|
$stderr.puts e.backtrace
|
||||||
git_reset_hard
|
git_reset_hard
|
||||||
raise PostSaveError.new('failed to save post', e)
|
raise PostSaveError.new('failed to save post', e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_post(post, old_slug = nil)
|
def write_post(post)
|
||||||
post_dir = post_path(post.time.year.to_s, post.padded_month)
|
post_dir = post_path(post.dir)
|
||||||
ensure_post_dir_exists(post_dir)
|
unless post.draft?
|
||||||
if old_slug
|
ensure_post_dir_exists(post_dir)
|
||||||
delete_post_body(post_dir, old_slug)
|
|
||||||
delete_post_index(post_dir, old_slug)
|
|
||||||
end
|
end
|
||||||
write_post_body(post_dir, post.slug, post.body)
|
write_post_body(post_dir, post.slug, post.body)
|
||||||
begin
|
begin
|
||||||
write_post_index(post_dir, post.slug, post.persistent_fields)
|
write_post_index(post_dir, post.slug, post.persistent_fields)
|
||||||
rescue => e
|
rescue => e
|
||||||
|
$stderr.puts "#{e.class}: #{e.message}"
|
||||||
|
$stderr.puts e.backtrace
|
||||||
delete_post_body(post_dir, post.slug)
|
delete_post_body(post_dir, post.slug)
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
post_dir
|
end
|
||||||
|
|
||||||
|
def delete_post_from_dir(post_dir, slug)
|
||||||
|
post_dir = post_path(post_dir)
|
||||||
|
delete_post_body(post_dir, slug)
|
||||||
|
delete_post_index(post_dir, slug)
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_post_body(dir, slug, body)
|
def write_post_body(dir, slug, body)
|
||||||
|
|
@ -287,8 +329,10 @@ class HarpBlog
|
||||||
|
|
||||||
def delete_post_index(dir, slug)
|
def delete_post_index(dir, slug)
|
||||||
post_data = read_post_data(dir)
|
post_data = read_post_data(dir)
|
||||||
post_data.delete(slug)
|
if post_data[slug]
|
||||||
write_post_data(dir, post_data)
|
post_data.delete(slug)
|
||||||
|
write_post_data(dir, post_data)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_post_dir_exists(dir)
|
def ensure_post_dir_exists(dir)
|
||||||
|
|
@ -383,9 +427,9 @@ class HarpBlog
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def git_commit(title, *files)
|
def git_commit(action, title, *files)
|
||||||
quoted_files = files.map { |f| "\"#{quote(f)}\"" }
|
quoted_files = files.map { |f| "\"#{quote(f)}\"" }
|
||||||
message = "linked '#{quote(title)}'"
|
message = "#{action} '#{quote(title)}'"
|
||||||
run("git add -A #{quoted_files.join(' ')} && git commit -m \"#{message}\"")
|
run("git add -A #{quoted_files.join(' ')} && git commit -m \"#{message}\"")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ get '/months' do
|
||||||
JSON.generate(months: blog.months)
|
JSON.generate(months: blog.months)
|
||||||
end
|
end
|
||||||
|
|
||||||
# list posts
|
# list published posts
|
||||||
get '/posts/:year/?:month?' do |year, month|
|
get '/posts/:year/?:month?' do |year, month|
|
||||||
posts =
|
posts =
|
||||||
if month
|
if month
|
||||||
|
|
@ -102,6 +102,15 @@ get '/posts/:year/?:month?' do |year, month|
|
||||||
JSON.generate(posts: posts.map(&:fields))
|
JSON.generate(posts: posts.map(&:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# list drafts
|
||||||
|
get '/drafts' do
|
||||||
|
posts = blog.drafts
|
||||||
|
|
||||||
|
status 200
|
||||||
|
headers 'Content-Type' => 'application/json'
|
||||||
|
JSON.generate(posts: posts.map(&:fields))
|
||||||
|
end
|
||||||
|
|
||||||
# get a post
|
# get a post
|
||||||
get '/posts/:year/:month/:slug' do |year, month, slug|
|
get '/posts/:year/:month/:slug' do |year, month, slug|
|
||||||
begin
|
begin
|
||||||
|
|
@ -130,15 +139,43 @@ get '/posts/:year/:month/:slug' do |year, month, slug|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# make a post
|
# get a draft
|
||||||
post '/posts' do
|
get '/drafts/:slug' do |slug|
|
||||||
|
begin
|
||||||
|
post = blog.get_draft(slug)
|
||||||
|
rescue HarpBlog::InvalidDataError => e
|
||||||
|
status 500
|
||||||
|
return "Failed to get draft, invalid data on disk: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if post
|
||||||
|
if request.accept?('application/json')
|
||||||
|
status 200
|
||||||
|
headers 'Content-Type' => 'application/json'
|
||||||
|
JSON.generate(post: post.fields)
|
||||||
|
elsif request.accept?('text/html')
|
||||||
|
status 200
|
||||||
|
headers 'Content-Type' => 'text/html'
|
||||||
|
blog.render_post(post.fields)
|
||||||
|
else
|
||||||
|
status 400
|
||||||
|
"content not available in an acceptable format: #{request.accept.join(', ')}"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
status 404
|
||||||
|
'not found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# make a draft
|
||||||
|
post '/drafts' do
|
||||||
unless authenticated?(request['Auth'])
|
unless authenticated?(request['Auth'])
|
||||||
status 403
|
status 403
|
||||||
return 'forbidden'
|
return 'forbidden'
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
post = blog.create_post(params[:title], params[:body], params[:link])
|
post = blog.create_post(params[:title], params[:body], params[:link], draft: true)
|
||||||
rescue HarpBlog::PostExistsError => e
|
rescue HarpBlog::PostExistsError => e
|
||||||
post = HarpBlog::Post.new({
|
post = HarpBlog::Post.new({
|
||||||
title: params[:title],
|
title: params[:title],
|
||||||
|
|
@ -146,13 +183,13 @@ post '/posts' do
|
||||||
link: params[:link],
|
link: params[:link],
|
||||||
})
|
})
|
||||||
status 409
|
status 409
|
||||||
return "refusing to clobber existing post, update it instead: #{post.url}"
|
return "refusing to clobber existing draft, update it instead: #{post.url}"
|
||||||
rescue HarpBlog::PostSaveError => e
|
rescue HarpBlog::PostSaveError => e
|
||||||
status 500
|
status 500
|
||||||
if orig_err = e.original_error
|
if orig_err = e.original_error
|
||||||
"#{e.message} -- #{orig_err.class}: #{orig_err.message}"
|
"#{e.message} -- #{orig_err.class}: #{orig_err.message}"
|
||||||
else
|
else
|
||||||
"Failed to create post: #{e.message}"
|
"Failed to create draft: #{e.message}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -190,7 +227,35 @@ put '/posts/:year/:month/:slug' do |year, month, slug|
|
||||||
if orig_err = e.original_error
|
if orig_err = e.original_error
|
||||||
"#{e.message} -- #{orig_err.class}: #{orig_err.message}"
|
"#{e.message} -- #{orig_err.class}: #{orig_err.message}"
|
||||||
else
|
else
|
||||||
"Failed to create post: #{e.message}"
|
"Failed to update post: #{e.message}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# update a draft
|
||||||
|
put '/drafts/:slug' do |slug|
|
||||||
|
unless authenticated?(request['Auth'])
|
||||||
|
status 403
|
||||||
|
return 'forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
if post = blog.get_draft(slug)
|
||||||
|
blog.update_post(post, params[:title], params[:body], params[:link])
|
||||||
|
status 204
|
||||||
|
else
|
||||||
|
status 404
|
||||||
|
'not found'
|
||||||
|
end
|
||||||
|
rescue HarpBlog::InvalidDataError => e
|
||||||
|
status 500
|
||||||
|
"Failed to update draft, invalid data on disk: #{e.message}"
|
||||||
|
rescue HarpBlog::PostSaveError => e
|
||||||
|
status 500
|
||||||
|
if orig_err = e.original_error
|
||||||
|
"#{e.message} -- #{orig_err.class}: #{orig_err.message}"
|
||||||
|
else
|
||||||
|
"Failed to update draft: #{e.message}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -206,6 +271,17 @@ delete '/posts/:year/:month/:slug' do |year, month, slug|
|
||||||
status 204
|
status 204
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# delete a draft
|
||||||
|
delete '/drafts/:slug' do |slug|
|
||||||
|
unless authenticated?(request['Auth'])
|
||||||
|
status 403
|
||||||
|
return 'forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
blog.delete_draft(slug)
|
||||||
|
status 204
|
||||||
|
end
|
||||||
|
|
||||||
# publish
|
# publish
|
||||||
post '/publish' do
|
post '/publish' do
|
||||||
unless authenticated?(request['Auth'])
|
unless authenticated?(request['Auth'])
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,24 @@ RSpec.describe HarpBlog::Post do
|
||||||
describe '#link?' do
|
describe '#link?' do
|
||||||
it "returns true for link posts" do
|
it "returns true for link posts" do
|
||||||
post = HarpBlog::Post.new(link: @default_fields[:link])
|
post = HarpBlog::Post.new(link: @default_fields[:link])
|
||||||
expect(post.link?).to eq(true)
|
expect(post.link?).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false for article posts" do
|
it "returns false for article posts" do
|
||||||
post = HarpBlog::Post.new
|
post = HarpBlog::Post.new
|
||||||
expect(post.link?).to eq(false)
|
expect(post.link?).to be_falsy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#draft?' do
|
||||||
|
it "returns true for draft posts" do
|
||||||
|
post = HarpBlog::Post.new(draft: true)
|
||||||
|
expect(post.draft?).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false for published posts" do
|
||||||
|
post = HarpBlog::Post.new
|
||||||
|
expect(post.draft?).to be_falsy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -124,6 +136,18 @@ RSpec.describe HarpBlog::Post do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#dir' do
|
||||||
|
it "returns the drafts dir for draft posts" do
|
||||||
|
post = HarpBlog::Post.new(draft: true)
|
||||||
|
expect(post.dir).to eq('drafts')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the dated dir for published posts" do
|
||||||
|
post = HarpBlog::Post.new
|
||||||
|
expect(post.dir).to eq("#{post.time.year}/#{post.padded_month}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#pad' do
|
describe '#pad' do
|
||||||
it "should have a leading zero for integers 0 < n < 10" do
|
it "should have a leading zero for integers 0 < n < 10" do
|
||||||
post = HarpBlog::Post.new
|
post = HarpBlog::Post.new
|
||||||
|
|
@ -183,7 +207,6 @@ RSpec.describe HarpBlog do
|
||||||
@blog.create_post('title', 'body', nil)
|
@blog.create_post('title', 'body', nil)
|
||||||
expect(@blog.dirty?).to be_truthy
|
expect(@blog.dirty?).to be_truthy
|
||||||
|
|
||||||
@blog.publish
|
|
||||||
@mock_version_finder.version = @blog.local_version
|
@mock_version_finder.version = @blog.local_version
|
||||||
expect(@blog.dirty?).to be_falsy
|
expect(@blog.dirty?).to be_falsy
|
||||||
end
|
end
|
||||||
|
|
@ -244,6 +267,59 @@ RSpec.describe HarpBlog do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#drafts' do
|
||||||
|
it "returns the correct number of posts" do
|
||||||
|
expect(@blog.drafts.length).to eq(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort the posts by publish time" do
|
||||||
|
timestamps = @blog.drafts.map(&:timestamp)
|
||||||
|
expect(increasing?(timestamps)).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#get_post' do
|
||||||
|
it "should return complete posts" do
|
||||||
|
first_post_path = File.join(TEST_BLOG_PATH, 'public/posts/2006/02/first-post.md')
|
||||||
|
post = @blog.get_post('2006', '02', 'first-post')
|
||||||
|
expect(post).to be_truthy
|
||||||
|
expect(post.author).to eq('Sami Samhuri')
|
||||||
|
expect(post.title).to eq('First Post!')
|
||||||
|
expect(post.slug).to eq('first-post')
|
||||||
|
expect(post.timestamp).to eq(1139368860)
|
||||||
|
expect(post.date).to eq('8th February, 2006')
|
||||||
|
expect(post.url).to eq('/posts/2006/02/first-post')
|
||||||
|
expect(post.link).to eq(nil)
|
||||||
|
expect(post.link?).to be_falsy
|
||||||
|
expect(post.tags).to eq(['life'])
|
||||||
|
expect(post.body).to eq(File.read(first_post_path))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return nil if the post does not exist" do
|
||||||
|
post = @blog.get_post('2005', '01', 'anything')
|
||||||
|
expect(post).to be(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#get_draft' do
|
||||||
|
it "should return complete posts" do
|
||||||
|
title = 'new draft'
|
||||||
|
body = "blah blah blah\n"
|
||||||
|
@blog.create_post(title, body, nil, draft: true)
|
||||||
|
post = @blog.get_draft('new-draft')
|
||||||
|
expect(post).to be_truthy
|
||||||
|
expect(post.title).to eq(title)
|
||||||
|
expect(post.url).to eq('/posts/drafts/new-draft')
|
||||||
|
expect(post.draft?).to be_truthy
|
||||||
|
expect(post.body).to eq(body)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return nil if the post does not exist" do
|
||||||
|
post = @blog.get_draft('does-not-exist')
|
||||||
|
expect(post).to be(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#create_post' do
|
describe '#create_post' do
|
||||||
it "should create a link post when a link is given" do
|
it "should create a link post when a link is given" do
|
||||||
title = 'test post'
|
title = 'test post'
|
||||||
|
|
@ -270,6 +346,15 @@ RSpec.describe HarpBlog do
|
||||||
expect(post.time.to_date).to eq(Date.today)
|
expect(post.time.to_date).to eq(Date.today)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should create a draft post" do
|
||||||
|
title = 'test draft'
|
||||||
|
body = 'check this out'
|
||||||
|
post = @blog.create_post(title, body, nil, draft: true)
|
||||||
|
expect(post).to be_truthy
|
||||||
|
expect(post.draft?).to be_truthy
|
||||||
|
expect(post.dir).to eq('drafts')
|
||||||
|
end
|
||||||
|
|
||||||
it "should create a post that can be fetched immediately" do
|
it "should create a post that can be fetched immediately" do
|
||||||
title = 'fetch now'
|
title = 'fetch now'
|
||||||
body = 'blah blah blah'
|
body = 'blah blah blah'
|
||||||
|
|
@ -280,6 +365,16 @@ RSpec.describe HarpBlog do
|
||||||
year = today.year.to_s
|
year = today.year.to_s
|
||||||
month = post.pad(today.month)
|
month = post.pad(today.month)
|
||||||
fetched_post = @blog.get_post(year, month, post.slug)
|
fetched_post = @blog.get_post(year, month, post.slug)
|
||||||
|
expect(fetched_post.url).to eq(post.url)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should create a draft that can be fetched immediately" do
|
||||||
|
title = 'fetch now'
|
||||||
|
body = 'blah blah blah'
|
||||||
|
post = @blog.create_post(title, body, nil, draft: true)
|
||||||
|
expect(post).to be_truthy
|
||||||
|
|
||||||
|
fetched_post = @blog.get_draft(post.slug)
|
||||||
expect(post.url).to eq(fetched_post.url)
|
expect(post.url).to eq(fetched_post.url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -301,29 +396,6 @@ RSpec.describe HarpBlog do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#get_post' do
|
|
||||||
it "should return complete posts" do
|
|
||||||
first_post_path = File.join(TEST_BLOG_PATH, 'public/posts/2006/02/first-post.md')
|
|
||||||
post = @blog.get_post('2006', '02', 'first-post')
|
|
||||||
expect(post).to be_truthy
|
|
||||||
expect(post.author).to eq('Sami Samhuri')
|
|
||||||
expect(post.title).to eq('First Post!')
|
|
||||||
expect(post.slug).to eq('first-post')
|
|
||||||
expect(post.timestamp).to eq(1139368860)
|
|
||||||
expect(post.date).to eq('8th February, 2006')
|
|
||||||
expect(post.url).to eq('/posts/2006/02/first-post')
|
|
||||||
expect(post.link).to eq(nil)
|
|
||||||
expect(post.link?).to eq(false)
|
|
||||||
expect(post.tags).to eq(['life'])
|
|
||||||
expect(post.body).to eq(File.read(first_post_path))
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should return nil if the post does not exist" do
|
|
||||||
post = @blog.get_post('2005', '01', 'anything')
|
|
||||||
expect(post).to be(nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#update_post' do
|
describe '#update_post' do
|
||||||
it "should immediately reflect changes when fetched" do
|
it "should immediately reflect changes when fetched" do
|
||||||
post = @blog.get_post('2006', '02', 'first-post')
|
post = @blog.get_post('2006', '02', 'first-post')
|
||||||
|
|
@ -333,14 +405,10 @@ RSpec.describe HarpBlog do
|
||||||
@blog.update_post(post, title, body, link)
|
@blog.update_post(post, title, body, link)
|
||||||
|
|
||||||
# new slug, new data
|
# new slug, new data
|
||||||
post = @blog.get_post('2006', '02', 'new-title')
|
post = @blog.get_post('2006', '02', 'first-post')
|
||||||
expect(post.title).to eq(title)
|
expect(post.title).to eq(title)
|
||||||
expect(post.body).to eq(body)
|
expect(post.body).to eq(body)
|
||||||
expect(post.link).to eq(link)
|
expect(post.link).to eq(link)
|
||||||
|
|
||||||
# old post is long gone
|
|
||||||
post = @blog.get_post('2006', '02', 'first-post')
|
|
||||||
expect(post).to eq(nil)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -364,4 +432,31 @@ RSpec.describe HarpBlog do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#delete_draft' do
|
||||||
|
it "should delete existing drafts" do
|
||||||
|
title = 'new draft'
|
||||||
|
body = 'blah blah blah'
|
||||||
|
existing_post = @blog.create_post(title, body, nil, draft: true)
|
||||||
|
post = @blog.get_draft(existing_post.slug)
|
||||||
|
expect(post).to be_truthy
|
||||||
|
|
||||||
|
@blog.delete_draft(post.slug)
|
||||||
|
|
||||||
|
post = @blog.get_draft(post.slug)
|
||||||
|
expect(post).to eq(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should do nothing for non-existent posts" do
|
||||||
|
title = 'new draft'
|
||||||
|
body = 'blah blah blah'
|
||||||
|
existing_post = @blog.create_post(title, body, nil, draft: true)
|
||||||
|
|
||||||
|
post = @blog.get_draft(existing_post.slug)
|
||||||
|
expect(post).to be_truthy
|
||||||
|
|
||||||
|
@blog.delete_draft(post.slug)
|
||||||
|
@blog.delete_draft(post.slug)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue