mirror of
https://github.com/samsonjs/samhuri.net.git
synced 2026-03-25 09:05:47 +00:00
use IDs instead of slugs for posts
Drafts don’t have reliable slugs until they’re published so give them UUIDs, and lookup posts by ID instead of slug.
This commit is contained in:
parent
d9731944c2
commit
c905f5c414
3 changed files with 230 additions and 146 deletions
|
|
@ -1,5 +1,6 @@
|
|||
require 'fileutils'
|
||||
require 'json'
|
||||
require 'securerandom'
|
||||
require './web_title_finder'
|
||||
require './web_version_finder'
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ class HarpBlog
|
|||
end
|
||||
|
||||
class Post
|
||||
PERSISTENT_FIELDS = %w[author title date timestamp link url tags].map(&:to_sym)
|
||||
PERSISTENT_FIELDS = %w[id author title date timestamp link url tags].map(&:to_sym)
|
||||
TRANSIENT_FIELDS = %w[time slug body draft].map(&:to_sym)
|
||||
FIELDS = PERSISTENT_FIELDS + TRANSIENT_FIELDS
|
||||
FIELDS.each { |f| attr_accessor f }
|
||||
|
|
@ -83,10 +84,19 @@ class HarpBlog
|
|||
@timestamp = timestamp
|
||||
end
|
||||
|
||||
def id
|
||||
@id ||=
|
||||
if draft?
|
||||
SecureRandom.uuid
|
||||
else
|
||||
slug
|
||||
end
|
||||
end
|
||||
|
||||
def url
|
||||
@url ||=
|
||||
if draft?
|
||||
"/posts/drafts/#{slug}"
|
||||
"/posts/drafts/#{id}"
|
||||
else
|
||||
"/posts/#{time.year}/#{padded_month}/#{slug}"
|
||||
end
|
||||
|
|
@ -94,7 +104,7 @@ class HarpBlog
|
|||
|
||||
def slug
|
||||
# TODO: be intelligent about unicode ... \p{Word} might help. negated char class with it?
|
||||
if title
|
||||
if !draft? && title
|
||||
@slug ||= title.downcase.
|
||||
gsub(/'/, '').
|
||||
gsub(/[^[:alpha:]\d_]/, '-').
|
||||
|
|
@ -184,12 +194,12 @@ class HarpBlog
|
|||
read_posts('drafts', draft: true)
|
||||
end
|
||||
|
||||
def get_post(year, month, slug)
|
||||
read_post(File.join(year, month), slug)
|
||||
def get_post(year, month, id)
|
||||
read_post(File.join(year, month), id)
|
||||
end
|
||||
|
||||
def get_draft(slug)
|
||||
read_post('drafts', slug, draft: true)
|
||||
def get_draft(id)
|
||||
read_post('drafts', id, draft: true)
|
||||
end
|
||||
|
||||
def create_post(title, body, url, extra_fields = nil)
|
||||
|
|
@ -208,15 +218,15 @@ class HarpBlog
|
|||
post = Post.new(fields)
|
||||
|
||||
begin
|
||||
existing_post = read_post(post.dir, post.slug, extra_fields)
|
||||
existing_post = read_post(post.dir, post.id, extra_fields)
|
||||
rescue InvalidDataError => e
|
||||
$stderr.puts "[HarpBlog#create_post] deleting post with invalid data: #{e.message}"
|
||||
delete_post_from_dir(post.dir, post.slug)
|
||||
delete_post_from_dir(post.dir, post.id)
|
||||
existing_post = nil
|
||||
end
|
||||
|
||||
if existing_post
|
||||
raise PostExistsError.new("post exists: #{post.dir}/#{post.slug}")
|
||||
raise PostExistsError.new("post exists: #{post.dir}/#{post.id}")
|
||||
else
|
||||
save_post('create post', post)
|
||||
end
|
||||
|
|
@ -229,36 +239,36 @@ class HarpBlog
|
|||
save_post('update post', post)
|
||||
end
|
||||
|
||||
def delete_post(year, month, slug)
|
||||
delete_post_from_dir(File.join(year, month), slug)
|
||||
def delete_post(year, month, id)
|
||||
delete_post_from_dir(File.join(year, month), id)
|
||||
end
|
||||
|
||||
def delete_draft(slug)
|
||||
delete_post_from_dir('drafts', slug)
|
||||
def delete_draft(id)
|
||||
delete_post_from_dir('drafts', id)
|
||||
end
|
||||
|
||||
def publish_post(post)
|
||||
if post.draft?
|
||||
new_post = create_post(post.title, post.body, post.link)
|
||||
delete_post_from_dir('drafts', post.slug)
|
||||
delete_post_from_dir('drafts', post.id)
|
||||
new_post
|
||||
else
|
||||
raise PostAlreadyPublishedError.new("post is already published: #{post.dir}/#{post.slug}")
|
||||
raise PostAlreadyPublishedError.new("post is already published: #{post.dir}/#{post.id}")
|
||||
end
|
||||
end
|
||||
|
||||
def unpublish_post(post)
|
||||
if post.draft?
|
||||
raise PostNotPublishedError.new("post is not published: #{post.dir}/#{post.slug}")
|
||||
raise PostNotPublishedError.new("post is not published: #{post.dir}/#{post.id}")
|
||||
else
|
||||
new_post = create_post(post.title, post.body, post.link, draft: true)
|
||||
delete_post_from_dir(post.dir, post.slug)
|
||||
delete_post_from_dir(post.dir, post.id)
|
||||
new_post
|
||||
end
|
||||
end
|
||||
|
||||
def publish(production = false)
|
||||
target = production ? 'publish' : 'publish_beta'
|
||||
def publish(env)
|
||||
target = env.to_s == 'production' ? 'publish' : 'publish_beta'
|
||||
run("make #{target}")
|
||||
end
|
||||
|
||||
|
|
@ -282,26 +292,40 @@ class HarpBlog
|
|||
end
|
||||
|
||||
def read_posts(post_dir, extra_fields = nil)
|
||||
extra_fields ||= {}
|
||||
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.map do |id, fields|
|
||||
fields[:id] = id
|
||||
unless extra_fields[:draft]
|
||||
fields[:slug] = id
|
||||
end
|
||||
post_filename = post_path(post_dir, "#{id}.md")
|
||||
fields[:body] = File.read(post_filename)
|
||||
Post.new(fields.merge(extra_fields))
|
||||
end
|
||||
end
|
||||
|
||||
def read_post(post_dir, slug, extra_fields = nil)
|
||||
post_filename = post_path(post_dir, "#{slug}.md")
|
||||
def read_post(post_dir, id, extra_fields = nil)
|
||||
post_filename = post_path(post_dir, "#{id}.md")
|
||||
post_data = read_post_data(post_path(post_dir))
|
||||
if File.exist?(post_filename) && fields = post_data[slug]
|
||||
if File.exist?(post_filename) && fields = post_data[id]
|
||||
fields[:body] = File.read(post_filename)
|
||||
Post.new(fields.merge(extra_fields || {}).merge(slug: slug))
|
||||
if extra_fields
|
||||
fields.merge!(extra_fields)
|
||||
end
|
||||
fields[:id] = id
|
||||
unless fields[:draft]
|
||||
fields[:slug] = id
|
||||
end
|
||||
Post.new(fields)
|
||||
elsif fields
|
||||
message = "missing post body for #{post_dir}/#{slug}: #{post_filename}"
|
||||
message = "missing post body for #{post_dir}/#{id}: #{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"
|
||||
message = "missing metadata for #{post_dir}/#{id}: #{post_dir}/_data.json"
|
||||
$stderr.puts "[HarpBlog#read_post] #{message}"
|
||||
raise InvalidDataError.new(message)
|
||||
end
|
||||
|
|
@ -330,43 +354,43 @@ class HarpBlog
|
|||
unless post.draft?
|
||||
ensure_post_dir_exists(post_dir)
|
||||
end
|
||||
write_post_body(post_dir, post.slug, post.body)
|
||||
write_post_body(post_dir, post.id, post.body)
|
||||
begin
|
||||
write_post_index(post_dir, post.slug, post.persistent_fields)
|
||||
write_post_index(post_dir, post.id, post.persistent_fields)
|
||||
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.id)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
def delete_post_from_dir(post_dir, slug)
|
||||
def delete_post_from_dir(post_dir, id)
|
||||
post_dir = post_path(post_dir)
|
||||
delete_post_body(post_dir, slug)
|
||||
delete_post_index(post_dir, slug)
|
||||
delete_post_body(post_dir, id)
|
||||
delete_post_index(post_dir, id)
|
||||
end
|
||||
|
||||
def write_post_body(dir, slug, body)
|
||||
post_filename = File.join(dir, "#{slug}.md")
|
||||
def write_post_body(dir, id, body)
|
||||
post_filename = File.join(dir, "#{id}.md")
|
||||
write_file(post_filename, body)
|
||||
end
|
||||
|
||||
def delete_post_body(dir, slug)
|
||||
post_filename = File.join(dir, "#{slug}.md")
|
||||
def delete_post_body(dir, id)
|
||||
post_filename = File.join(dir, "#{id}.md")
|
||||
delete_file(post_filename)
|
||||
end
|
||||
|
||||
def write_post_index(dir, slug, fields)
|
||||
def write_post_index(dir, id, fields)
|
||||
post_data = read_post_data(dir)
|
||||
post_data[slug] = fields
|
||||
post_data[id] = fields
|
||||
write_post_data(dir, post_data)
|
||||
end
|
||||
|
||||
def delete_post_index(dir, slug)
|
||||
def delete_post_index(dir, id)
|
||||
post_data = read_post_data(dir)
|
||||
if post_data[slug]
|
||||
post_data.delete(slug)
|
||||
if post_data[id]
|
||||
post_data.delete(id)
|
||||
write_post_data(dir, post_data)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
117
server/server.rb
117
server/server.rb
|
|
@ -67,11 +67,36 @@ set :port, $config[:port]
|
|||
|
||||
blog = HarpBlog.new($config[:path], $config[:dry_run])
|
||||
|
||||
before do
|
||||
if request.body.size > 0
|
||||
type = request['HTTP_CONTENT_TYPE']
|
||||
@fields =
|
||||
case
|
||||
when type =~ /^application\/json\b/
|
||||
request.body.rewind
|
||||
JSON.parse(request.body.read)
|
||||
else
|
||||
params
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# status
|
||||
get '/status' do
|
||||
status 200
|
||||
headers 'Content-Type' => 'application/json'
|
||||
JSON.generate(blog.status)
|
||||
JSON.generate(status: blog.status)
|
||||
end
|
||||
|
||||
# publish the site
|
||||
post '/publish' do
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
blog.publish(@fields['env'])
|
||||
status 204
|
||||
end
|
||||
|
||||
# list years
|
||||
|
|
@ -102,6 +127,17 @@ get '/posts/:year/?:month?' do |year, month|
|
|||
JSON.generate(posts: posts.map(&:fields))
|
||||
end
|
||||
|
||||
# list all published posts
|
||||
get '/posts' do
|
||||
posts = blog.months.map do |year, month|
|
||||
blog.posts_for_month(year, month)
|
||||
end.flatten
|
||||
|
||||
status 200
|
||||
headers 'Content-Type' => 'application/json'
|
||||
JSON.generate(posts: posts.map(&:fields))
|
||||
end
|
||||
|
||||
# list drafts
|
||||
get '/drafts' do
|
||||
posts = blog.drafts
|
||||
|
|
@ -112,9 +148,9 @@ get '/drafts' do
|
|||
end
|
||||
|
||||
# get a post
|
||||
get '/posts/:year/:month/:slug' do |year, month, slug|
|
||||
get '/posts/:year/:month/:id' do |year, month, id|
|
||||
begin
|
||||
post = blog.get_post(year, month, slug)
|
||||
post = blog.get_post(year, month, id)
|
||||
rescue HarpBlog::InvalidDataError => e
|
||||
status 500
|
||||
return "Failed to get post, invalid data on disk: #{e.message}"
|
||||
|
|
@ -140,9 +176,9 @@ get '/posts/:year/:month/:slug' do |year, month, slug|
|
|||
end
|
||||
|
||||
# get a draft
|
||||
get '/drafts/:slug' do |slug|
|
||||
get '/drafts/:id' do |id|
|
||||
begin
|
||||
post = blog.get_draft(slug)
|
||||
post = blog.get_draft(id)
|
||||
rescue HarpBlog::InvalidDataError => e
|
||||
status 500
|
||||
return "Failed to get draft, invalid data on disk: #{e.message}"
|
||||
|
|
@ -174,16 +210,25 @@ post '/drafts' do
|
|||
return 'forbidden'
|
||||
end
|
||||
|
||||
id, title, body, link = @fields.values_at('id', 'title', 'body', 'link')
|
||||
begin
|
||||
post = blog.create_post(params[:title], params[:body], params[:link], draft: true)
|
||||
if post = blog.create_post(title, body, link, id: id, draft: true)
|
||||
url = url_for(post.url)
|
||||
status 201
|
||||
headers 'Location' => url, 'Content-Type' => 'application/json'
|
||||
JSON.generate(post: post.fields)
|
||||
else
|
||||
status 500
|
||||
'failed to create post'
|
||||
end
|
||||
rescue HarpBlog::PostExistsError => e
|
||||
post = HarpBlog::Post.new({
|
||||
title: params[:title],
|
||||
body: params[:body],
|
||||
link: params[:link],
|
||||
title: title,
|
||||
body: body,
|
||||
link: link,
|
||||
})
|
||||
status 409
|
||||
return "refusing to clobber existing draft, update it instead: #{post.url}"
|
||||
"refusing to clobber existing draft, update it instead: #{post.url}"
|
||||
rescue HarpBlog::PostSaveError => e
|
||||
status 500
|
||||
if orig_err = e.original_error
|
||||
|
|
@ -192,28 +237,19 @@ post '/drafts' do
|
|||
"Failed to create draft: #{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
if post
|
||||
url = url_for(post.url)
|
||||
status 201
|
||||
headers 'Location' => url, 'Content-Type' => 'application/json'
|
||||
JSON.generate(post: post.fields)
|
||||
else
|
||||
status 500
|
||||
'failed to create post'
|
||||
end
|
||||
end
|
||||
|
||||
# update a post
|
||||
put '/posts/:year/:month/:slug' do |year, month, slug|
|
||||
put '/posts/:year/:month/:id' do |year, month, id|
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
title, body, link = @field.values_at('title', 'body', 'link')
|
||||
begin
|
||||
if post = blog.get_post(year, month, slug)
|
||||
blog.update_post(post, params[:title], params[:body], params[:link])
|
||||
if post = blog.get_post(year, month, id)
|
||||
blog.update_post(post, title, body, link)
|
||||
status 204
|
||||
else
|
||||
status 404
|
||||
|
|
@ -233,15 +269,16 @@ put '/posts/:year/:month/:slug' do |year, month, slug|
|
|||
end
|
||||
|
||||
# update a draft
|
||||
put '/drafts/:slug' do |slug|
|
||||
put '/drafts/:id' do |id|
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
title, body, link = @field.values_at('title', 'body', 'link')
|
||||
begin
|
||||
if post = blog.get_draft(slug)
|
||||
blog.update_post(post, params[:title], params[:body], params[:link])
|
||||
if post = blog.get_draft(id)
|
||||
blog.update_post(post, title, body, link)
|
||||
status 204
|
||||
else
|
||||
status 404
|
||||
|
|
@ -261,35 +298,35 @@ put '/drafts/:slug' do |slug|
|
|||
end
|
||||
|
||||
# delete a post
|
||||
delete '/posts/:year/:month/:slug' do |year, month, slug|
|
||||
delete '/posts/:year/:month/:id' do |year, month, id|
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
blog.delete_post(year, month, slug)
|
||||
blog.delete_post(year, month, id)
|
||||
status 204
|
||||
end
|
||||
|
||||
# delete a draft
|
||||
delete '/drafts/:slug' do |slug|
|
||||
delete '/drafts/:id' do |id|
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
blog.delete_draft(slug)
|
||||
blog.delete_draft(id)
|
||||
status 204
|
||||
end
|
||||
|
||||
# publish a post
|
||||
post '/drafts/:slug/publish' do |slug|
|
||||
post '/drafts/:id/publish' do |id|
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
if post = blog.get_draft(slug)
|
||||
if post = blog.get_draft(id)
|
||||
new_post = blog.publish_post(post)
|
||||
status 201
|
||||
headers 'Location' => url_for(new_post.url), 'Content-Type' => 'application/json'
|
||||
|
|
@ -301,13 +338,13 @@ post '/drafts/:slug/publish' do |slug|
|
|||
end
|
||||
|
||||
# unpublish a post
|
||||
post '/posts/:year/:month/:slug/unpublish' do |year, month, slug|
|
||||
post '/posts/:year/:month/:id/unpublish' do |year, month, id|
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
if post = blog.get_post(year, month, slug)
|
||||
if post = blog.get_post(year, month, id)
|
||||
new_post = blog.unpublish_post(post)
|
||||
status 201
|
||||
headers 'Location' => url_for(new_post.url), 'Content-Type' => 'application/json'
|
||||
|
|
@ -317,15 +354,3 @@ post '/posts/:year/:month/:slug/unpublish' do |year, month, slug|
|
|||
'not found'
|
||||
end
|
||||
end
|
||||
|
||||
# publish the site
|
||||
post '/publish' do
|
||||
unless authenticated?(request['Auth'])
|
||||
status 403
|
||||
return 'forbidden'
|
||||
end
|
||||
|
||||
production = params[:env] == 'production'
|
||||
blog.publish(production)
|
||||
status 204
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,21 +11,28 @@ end
|
|||
|
||||
RSpec.describe HarpBlog::Post do
|
||||
|
||||
# Persistent fields: author, title, date, timestamp, link, url, tags
|
||||
# Persistent fields: id, author, title, date, timestamp, link, url, tags
|
||||
# Transient fields: time, slug, body
|
||||
|
||||
before :all do
|
||||
@default_fields = {
|
||||
@post_fields = {
|
||||
title: 'samhuri.net',
|
||||
link: 'http://samhuri.net',
|
||||
body: 'this site is sick',
|
||||
}
|
||||
@default_slug = 'samhuri-net'
|
||||
@post_slug = 'samhuri-net'
|
||||
@draft_fields = {
|
||||
title: 'reddit.com',
|
||||
link: 'http://reddit.com',
|
||||
body: 'hi reddit',
|
||||
draft: true,
|
||||
id: 'dummy-draft-id',
|
||||
}
|
||||
end
|
||||
|
||||
describe '#new' do
|
||||
it "takes a Hash of fields" do
|
||||
fields = @default_fields
|
||||
fields = @post_fields
|
||||
post = HarpBlog::Post.new(fields)
|
||||
expect(post.title).to eq(fields[:title])
|
||||
expect(post.link).to eq(fields[:link])
|
||||
|
|
@ -61,7 +68,7 @@ RSpec.describe HarpBlog::Post do
|
|||
|
||||
describe '#link?' do
|
||||
it "returns true for link posts" do
|
||||
post = HarpBlog::Post.new(link: @default_fields[:link])
|
||||
post = HarpBlog::Post.new(link: @post_fields[:link])
|
||||
expect(post.link?).to be_truthy
|
||||
end
|
||||
|
||||
|
|
@ -101,18 +108,38 @@ RSpec.describe HarpBlog::Post do
|
|||
|
||||
describe '#url' do
|
||||
it "should be derived from the time and slug if necessary" do
|
||||
post = HarpBlog::Post.new(@default_fields)
|
||||
post = HarpBlog::Post.new(@post_fields)
|
||||
year = post.time.year.to_s
|
||||
month = post.time.month
|
||||
padded_month = month < 10 ? " #{month}" : "#{month}"
|
||||
expect(post.url).to eq("/posts/#{year}/#{padded_month}/#{@default_slug}")
|
||||
padded_month = month < 10 ? "0#{month}" : "#{month}"
|
||||
expect(post.url).to eq("/posts/#{year}/#{padded_month}/#{@post_slug}")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#id' do
|
||||
it "should be generated for drafts if necessary" do
|
||||
draft = HarpBlog::Post.new(@draft_fields)
|
||||
expect(draft.id).to eq(@draft_fields[:id])
|
||||
|
||||
draft = HarpBlog::Post.new(@draft_fields.merge(id: nil))
|
||||
expect(draft.id).to_not eq(@draft_fields[:id])
|
||||
end
|
||||
|
||||
it "should be the slug for posts" do
|
||||
post = HarpBlog::Post.new(@post_fields)
|
||||
expect(post.id).to eq(post.slug)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#slug' do
|
||||
it "should be derived from the title if necessary" do
|
||||
post = HarpBlog::Post.new(@default_fields)
|
||||
expect(post.slug).to eq(@default_slug)
|
||||
post = HarpBlog::Post.new(@post_fields)
|
||||
expect(post.slug).to eq(@post_slug)
|
||||
end
|
||||
|
||||
it "should be nil for drafts" do
|
||||
draft = HarpBlog::Post.new(@draft_fields)
|
||||
expect(draft.slug).to be_nil
|
||||
end
|
||||
|
||||
it "should strip apostrophes" do
|
||||
|
|
@ -303,20 +330,21 @@ RSpec.describe HarpBlog do
|
|||
|
||||
describe '#get_draft' do
|
||||
it "should return complete posts" do
|
||||
id = 'some-draft-id'
|
||||
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)
|
||||
@blog.create_post(title, body, nil, id: id, draft: true)
|
||||
draft = @blog.get_draft(id)
|
||||
expect(draft).to be_truthy
|
||||
expect(draft.title).to eq(title)
|
||||
expect(draft.url).to eq("/posts/drafts/#{id}")
|
||||
expect(draft.draft?).to be_truthy
|
||||
expect(draft.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)
|
||||
draft = @blog.get_draft('does-not-exist')
|
||||
expect(draft).to be(nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -369,13 +397,14 @@ RSpec.describe HarpBlog do
|
|||
end
|
||||
|
||||
it "should create a draft that can be fetched immediately" do
|
||||
id = 'another-draft-id'
|
||||
title = 'fetch now'
|
||||
body = 'blah blah blah'
|
||||
post = @blog.create_post(title, body, nil, draft: true)
|
||||
expect(post).to be_truthy
|
||||
draft = @blog.create_post(title, body, nil, id: id, draft: true)
|
||||
expect(draft).to be_truthy
|
||||
|
||||
fetched_post = @blog.get_draft(post.slug)
|
||||
expect(post.url).to eq(fetched_post.url)
|
||||
fetched_draft = @blog.get_draft(draft.id)
|
||||
expect(draft.url).to eq(fetched_draft.url)
|
||||
end
|
||||
|
||||
it "should fetch titles if necessary" do
|
||||
|
|
@ -434,49 +463,54 @@ RSpec.describe HarpBlog do
|
|||
|
||||
describe '#delete_draft' do
|
||||
it "should delete existing drafts" do
|
||||
id = 'bunk-draft-id'
|
||||
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
|
||||
existing_draft = @blog.create_post(title, body, nil, id: id, draft: true)
|
||||
draft = @blog.get_draft(existing_draft.id)
|
||||
expect(draft).to be_truthy
|
||||
|
||||
@blog.delete_draft(post.slug)
|
||||
@blog.delete_draft(draft.id)
|
||||
|
||||
post = @blog.get_draft(post.slug)
|
||||
expect(post).to eq(nil)
|
||||
draft = @blog.get_draft(draft.id)
|
||||
expect(draft).to eq(nil)
|
||||
end
|
||||
|
||||
it "should do nothing for non-existent posts" do
|
||||
id = 'missing-draft-id'
|
||||
title = 'new draft'
|
||||
body = 'blah blah blah'
|
||||
existing_post = @blog.create_post(title, body, nil, draft: true)
|
||||
existing_draft = @blog.create_post(title, body, nil, id: id, draft: true)
|
||||
|
||||
post = @blog.get_draft(existing_post.slug)
|
||||
expect(post).to be_truthy
|
||||
draft = @blog.get_draft(existing_draft.id)
|
||||
expect(draft).to be_truthy
|
||||
|
||||
@blog.delete_draft(post.slug)
|
||||
@blog.delete_draft(post.slug)
|
||||
@blog.delete_draft(draft.id)
|
||||
expect(@blog.get_draft(existing_draft.id)).to be_nil
|
||||
@blog.delete_draft(draft.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#publish_post' do
|
||||
it "should publish drafts" do
|
||||
id = 'this-draft-is-a-keeper'
|
||||
title = 'a-shiny-new-post'
|
||||
body = 'blah blah blah'
|
||||
link = 'http://samhuri.net'
|
||||
post = @blog.create_post(title, body, link, draft: true)
|
||||
new_post = @blog.publish_post(post)
|
||||
expect(new_post).to be_truthy
|
||||
expect(new_post.draft?).to be_falsy
|
||||
expect(new_post.title).to eq(title)
|
||||
expect(new_post.body).to eq(body)
|
||||
expect(new_post.link).to eq(link)
|
||||
|
||||
draft = @blog.get_draft(post.slug)
|
||||
expect(draft).to eq(nil)
|
||||
|
||||
post = @blog.get_post(post.time.year.to_s, post.padded_month, post.slug)
|
||||
draft = @blog.create_post(title, body, link, id: id, draft: true)
|
||||
post = @blog.publish_post(draft)
|
||||
expect(post).to be_truthy
|
||||
expect(post.id).to eq(post.slug)
|
||||
expect(post.draft?).to be_falsy
|
||||
expect(post.title).to eq(title)
|
||||
expect(post.body).to eq(body)
|
||||
expect(post.link).to eq(link)
|
||||
|
||||
missing_draft = @blog.get_draft(draft.id)
|
||||
expect(missing_draft).to eq(nil)
|
||||
|
||||
fetched_post = @blog.get_post(post.time.year.to_s, post.padded_month, post.slug)
|
||||
expect(fetched_post).to be_truthy
|
||||
end
|
||||
|
||||
it "should raise an error for published posts" do
|
||||
|
|
@ -488,18 +522,19 @@ RSpec.describe HarpBlog do
|
|||
describe '#unpublish_post' do
|
||||
it "should unpublish posts" do
|
||||
post = @blog.get_post('2006', '02', 'first-post')
|
||||
new_post = @blog.unpublish_post(post)
|
||||
expect(new_post).to be_truthy
|
||||
expect(new_post.draft?).to be_truthy
|
||||
expect(new_post.title).to eq(post.title)
|
||||
expect(new_post.body).to eq(post.body)
|
||||
expect(new_post.link).to eq(post.link)
|
||||
|
||||
post = @blog.get_post(post.time.year.to_s, post.padded_month, post.slug)
|
||||
expect(post).to eq(nil)
|
||||
|
||||
draft = @blog.get_draft(new_post.slug)
|
||||
draft = @blog.unpublish_post(post)
|
||||
expect(draft).to be_truthy
|
||||
expect(draft.id).to be_truthy
|
||||
expect(draft.draft?).to be_truthy
|
||||
expect(draft.title).to eq(post.title)
|
||||
expect(draft.body).to eq(post.body)
|
||||
expect(draft.link).to eq(post.link)
|
||||
|
||||
missing_post = @blog.get_post(post.time.year.to_s, post.padded_month, post.slug)
|
||||
expect(missing_post).to eq(nil)
|
||||
|
||||
fetched_draft = @blog.get_draft(draft.id)
|
||||
expect(fetched_draft).to be_truthy
|
||||
end
|
||||
|
||||
it "should raise an error for drafts" do
|
||||
|
|
|
|||
Loading…
Reference in a new issue