FIX: all the specs

This commit is contained in:
Régis Hanol 2019-05-22 22:58:53 +02:00
parent ae92a376fb
commit daf377d217
13 changed files with 129 additions and 375 deletions

View File

@ -3,9 +3,11 @@ module DiscourseCalendar
def self.update(post)
calendar = post.calendar || {}
post.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD] = calendar.delete("type") || "dynamic"
previous_type = post.custom_fields[CALENDAR_CUSTOM_FIELD].dup
unless post.custom_fields[DiscourseCalendar::CALENDAR_DETAILS_CUSTOM_FIELD].present?
post.custom_fields[CALENDAR_CUSTOM_FIELD] = calendar.delete("type") || "dynamic"
if previous_type != post.custom_fields[CALENDAR_CUSTOM_FIELD] || post.calendar_details.blank?
post.calendar_details = {}
end

View File

@ -2,18 +2,16 @@ module DiscourseCalendar
class EventValidator
def initialize(post)
@post = post
@calendar = post&.topic&.first_post&.custom_fields
@op = post.topic.first_post
end
def validate_event
dates_count = DiscourseCalendar::Event::count(@post)
calendar_type = @calendar[DiscourseCalendar::CALENDAR_CUSTOM_FIELD] || "dynamic"
calendar_type = @op.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD] || "dynamic"
if calendar_type == "dynamic"
return false if has_too_many_dates?(dates_count)
end
if calendar_type == "static"
elsif calendar_type == "static"
return false if dates_count > 0
end

View File

@ -39,12 +39,14 @@ after_initialize do
register_post_custom_field_type(DiscourseCalendar::CALENDAR_DETAILS_CUSTOM_FIELD, :json)
register_post_custom_field_type(DiscourseCalendar::CALENDAR_CUSTOM_FIELD, :string)
whitelist_staff_user_custom_field(::DiscourseCalendar::HOLIDAY_CUSTOM_FIELD)
whitelist_staff_user_custom_field(DiscourseCalendar::HOLIDAY_CUSTOM_FIELD)
class DiscourseCalendar::Calendar
class << self
def extract(post)
Nokogiri::HTML(post.cooked).css('div.calendar').map do |cooked_calendar|
cooked = PrettyText.cook(post.raw, topic_id: post.topic_id, user_id: post.user_id)
Nokogiri::HTML(cooked).css('div.calendar').map do |cooked_calendar|
calendar = {}
cooked_calendar.attributes.values.each do |attribute|
@ -62,7 +64,9 @@ after_initialize do
class DiscourseCalendar::Event
class << self
def count(post)
Nokogiri::HTML(post.cooked).css('span.discourse-local-date').count
cooked = PrettyText.cook(post.raw, topic_id: post.topic_id, user_id: post.user_id)
Nokogiri::HTML(cooked).css('span.discourse-local-date').count
end
end
end

View File

@ -1,23 +1,15 @@
require 'rails_helper'
require "rails_helper"
describe DiscourseCalendar::EnsuredExpiredEventDestruction do
before do
SiteSetting.queue_jobs = false
raw = <<~MD
[calendar]
[/calendar]
MD
topic = Fabricate(:topic, first_post: create_post(raw: raw))
@op = topic.first_post
Jobs.run_immediately!
SiteSetting.calendar_enabled = true
@op = create_post(raw: "[calendar]\n[/calendar]")
expect(@op.calendar_details).to eq({})
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="11:20:00"]
MD
@post = create_post(raw: raw, topic: topic)
raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="11:20:00"]'
@post = create_post(raw: raw, topic: @op.topic)
CookedPostProcessor.new(@post).post_process
end
@ -27,7 +19,7 @@ describe DiscourseCalendar::EnsuredExpiredEventDestruction do
@op.reload
expect(@op.calendar_details[@post.post_number.to_s]).to eq([
"Rome to", "2018-06-05T10:20:00Z", "2018-06-06T11:20:00Z", @post.user.username_lower
"Rome to", "2018-06-05T10:20:00Z", "2018-06-06T11:20:00Z", @post.user.username_lower, nil
])
freeze_time Time.strptime("2018-06-06 13:21:00 UTC", "%Y-%m-%d %H:%M:%S %Z")
@ -40,9 +32,7 @@ describe DiscourseCalendar::EnsuredExpiredEventDestruction do
it "wont destroy recurring events" do
freeze_time Time.strptime("2018-06-03 09:21:00 UTC", "%Y-%m-%d %H:%M:%S %Z")
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00" recurring="1.weeks"] to [date="2018-06-06" time="11:20:00"]
MD
raw = 'Rome [date="2018-06-05" time="10:20:00" recurring="1.weeks"] to [date="2018-06-06" time="11:20:00"]'
@post = create_post(raw: raw, topic: @op.topic)
CookedPostProcessor.new(@post).post_process

View File

@ -2,21 +2,16 @@ require 'rails_helper'
describe DiscourseCalendar::UpdateHolidayUsernames do
before do
SiteSetting.queue_jobs = false
Jobs.run_immediately!
SiteSetting.calendar_enabled = true
raw = <<~MD
[calendar]
[/calendar]
MD
@topic = Fabricate(:topic, first_post: create_post(raw: raw))
SiteSetting.holiday_calendar_topic_id = @topic.id
@op = create_post(raw: "[calendar]\n[/calendar]")
SiteSetting.holiday_calendar_topic_id = @op.topic_id
end
it "should update users on holiday list" do
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]
MD
post = create_post(raw: raw, topic: @topic)
raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]'
post = create_post(raw: raw, topic: @op.topic)
CookedPostProcessor.new(post).post_process
freeze_time Time.strptime("2018-06-05 18:40:00 UTC", "%Y-%m-%d %H:%M:%S %Z")
@ -26,10 +21,8 @@ describe DiscourseCalendar::UpdateHolidayUsernames do
end
it "should have empty users on holiday list" do
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]
MD
post = create_post(raw: raw, topic: @topic)
raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]'
post = create_post(raw: raw, topic: @op.topic)
CookedPostProcessor.new(post).post_process
freeze_time Time.strptime("2018-06-07 18:40:00 UTC", "%Y-%m-%d %H:%M:%S %Z")

View File

@ -1,24 +0,0 @@
require 'rails_helper'
describe DiscourseCalendar::CalendarUpdater do
before do
SiteSetting.queue_jobs = false
end
it "will correctly update the calendar" do
post = create_post
expect(post.custom_fields).to eq({})
DiscourseCalendar::CalendarUpdater.update(post)
expect(post.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD]).to eq("dynamic")
expect(post.calendar_details).to eq({})
post.calendar = { "type" => "static" }
DiscourseCalendar::CalendarUpdater.update(post)
expect(post.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD]).to eq("static")
end
end

View File

@ -1,106 +1,75 @@
require 'rails_helper'
require "rails_helper"
describe 'Dynamic calendar' do
raw = <<~MD
[calendar]
[/calendar]
MD
let(:op) { create_post(raw: raw) }
let(:topic) { op.topic }
describe "Dynamic calendar" do
before do
SiteSetting.queue_jobs = false
Jobs.run_immediately!
SiteSetting.calendar_enabled = true
end
def create_calendar_post(topic, raw)
post = create_post(raw: raw, topic: topic)
topic.reload
post.reload
post
let(:raw) { "[calendar]\n[/calendar]" }
let(:op) { create_post(raw: raw) }
it "defaults to dynamic" do
expect(op.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD]).to eq("dynamic")
end
describe 'single date events' do
it 'creates an entry in the calendar' do
raw = <<~MD
Rome [date="2018-06-05" timezone="Europe/Paris"]
MD
it "adds an entry with a single date event" do
p = create_post(topic: op.topic, raw: 'Rome [date="2018-06-05" timezone="Europe/Paris"]')
post = create_calendar_post(topic, raw)
expect(topic.first_post.custom_fields["calendar-details"][post.post_number.to_s]).to eq([
"Rome", "2018-06-05T00:00:00+02:00", nil, post.user.username
])
end
describe 'with time' do
it 'creates an entry in the calendar' do
raw = <<~MD
Rome [date="2018-06-05" time="10:00:00" timezone="Europe/Paris"]
MD
post = create_calendar_post(topic, raw)
expect(topic.first_post.custom_fields["calendar-details"][post.post_number.to_s]).to eq([
"Rome", "2018-06-05T10:00:00+02:00", nil, post.user.username
])
end
end
op.reload
expect(op.calendar_details[p.post_number.to_s]).to eq([
"Rome", "2018-06-05T00:00:00+02:00", nil, p.user.username, nil
])
end
describe 'range date events' do
it 'creates an entry in the calendar' do
raw = <<~MD
Rome [date="2018-06-05" timezone="Europe/Paris"] [date="2018-06-08" timezone="Europe/Paris"]
MD
it "adds an entry with a single date/time event" do
p = create_post(topic: op.topic, raw: 'Rome [date="2018-06-05" time="12:34:56"]')
post = create_calendar_post(topic, raw)
expect(topic.first_post.custom_fields["calendar-details"][post.post_number.to_s]).to eq([
"Rome", "2018-06-05T00:00:00+02:00", "2018-06-08T23:59:59+02:00", post.user.username
])
end
op.reload
expect(op.calendar_details[p.post_number.to_s]).to eq([
"Rome", "2018-06-05T12:34:56Z", nil, p.user.username, nil
])
end
describe 'more than two dates' do
it 'raises an error' do
raw = <<~MD
Rome [date="2018-06-05" timezone="Europe/Paris"] [date="2018-06-08" timezone="Europe/Paris"] [date="2018-06-09" timezone="Europe/Paris"]
MD
it "adds an entry with a range event" do
p = create_post(topic: op.topic, raw: 'Rome [date="2018-06-05" timezone="Europe/Paris"] → [date="2018-06-08" timezone="Europe/Paris"]')
expect { create_calendar_post(topic, raw) }.to raise_error(StandardError, I18n.t("discourse_calendar.more_than_two_dates"))
end
op.reload
expect(op.calendar_details[p.post_number.to_s]).to eq([
"Rome", "2018-06-05T00:00:00+02:00", "2018-06-08T23:59:59+02:00", p.user.username, nil
])
end
describe 'a calendar not in first post' do
it 'raises an error' do
raw = <<~MD
Another calendar
[calendar]
[/calendar]
MD
expect { create_calendar_post(topic, raw) }.to raise_error(StandardError, I18n.t("discourse_calendar.calendar_must_be_in_first_post"))
end
it "raises an error when there are more than 2 dates" do
expect {
create_post(topic: op.topic, raw: 'Rome [date="2018-06-05"] → [date="2018-06-08"] [date="2018-06-09"]')
}.to raise_error(StandardError, I18n.t("discourse_calendar.more_than_two_dates"))
end
describe 'going from dynamic to static' do
it 'cleans up everything' do
raw = <<~MD
Rome [date="2018-06-05" timezone="Europe/Paris"]
MD
post = create_calendar_post(topic, raw)
expect(topic.first_post.custom_fields["calendar-details"][post.post_number.to_s]).to be_present
raw = <<~MD
[calendar type="static"]
[/calendar]
MD
op.revise(op.user, raw: raw)
op.reload
expect(op.custom_fields['calendar']).to eq('static')
expect(op.custom_fields['calendar-details']).to be_empty
end
it "raises an error when the calendar is not in first post" do
expect {
create_post(topic: op.topic, raw: raw)
}.to raise_error(StandardError, I18n.t("discourse_calendar.calendar_must_be_in_first_post"))
end
it "raises an error when there are more than 1 calendar" do
expect {
create_post(raw: "#{raw}\n#{raw}")
}.to raise_error(StandardError, I18n.t("discourse_calendar.more_than_one_calendar"))
end
it "empties details when going from dynamic to static" do
p = create_post(topic: op.topic, raw: 'Rome [date="2018-06-05"]')
op.reload
expect(op.calendar_details[p.post_number.to_s]).to be_present
op.revise(op.user, raw: '[calendar type="static"]\n[/calendar]')
op.reload
expect(op.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD]).to eq("static")
expect(op.calendar_details).to be_empty
end
end

View File

@ -1,37 +0,0 @@
require 'rails_helper'
describe DiscourseCalendar::EventUpdater do
before do
SiteSetting.queue_jobs = false
end
it "will correctly remove the event and destroy the associated post" do
freeze_time
raw = <<~MD
[calendar]
[/calendar]
MD
topic = Fabricate(:topic, first_post: create_post(raw: raw))
op = topic.first_post
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00"]
MD
post = create_post(raw: raw, topic: topic)
op.reload
post_number = post.post_number.to_s
expect(post.deleted_at).to be_nil
expect(op.calendar_details[post_number]).to be_present
DiscourseCalendar::EnsuredExpiredEventDestruction.new.execute(nil)
post.reload
op.reload
expect(post.deleted_at).to be_present
expect(op.calendar_details[post_number]).to be_nil
end
end

View File

@ -2,24 +2,15 @@ require 'rails_helper'
describe DiscourseCalendar::EventUpdater do
before do
SiteSetting.queue_jobs = false
SiteSetting.calendar_enabled = true
end
it "will correctly update the associated first post calendar details" do
raw = <<~MD
[calendar]
[/calendar]
MD
topic = Fabricate(:topic, first_post: create_post(raw: raw))
op = topic.first_post
op = create_post(raw: "[calendar]\n[/calendar]")
expect(op.calendar_details).to eq({})
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00"]
MD
post = create_post(raw: raw, topic: topic)
raw = %{Rome [date="2018-06-05" time="10:20:00"]}
post = create_post(raw: raw, topic: op.topic)
CookedPostProcessor.new(post).post_process
op.reload
@ -27,24 +18,16 @@ describe DiscourseCalendar::EventUpdater do
expect(op.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD]).to eq("dynamic")
expect(op.calendar_details).to eq(
post.post_number.to_s => [
"Rome", "2018-06-05T10:20:00Z", nil, post.user.username_lower
"Rome", "2018-06-05T10:20:00Z", nil, post.user.username_lower, nil
]
)
end
it "will correctly remove the event if post doesnt contain dates anymore" do
raw = <<~MD
[calendar]
[/calendar]
MD
topic = Fabricate(:topic, first_post: create_post(raw: raw))
op = create_post(raw: "[calendar]\n[/calendar]")
op = topic.first_post
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00"]
MD
post = create_post(raw: raw, topic: topic)
raw = %{Rome [date="2018-06-05" time="10:20:00"]}
post = create_post(raw: raw, topic: op.topic)
CookedPostProcessor.new(post).post_process
op.reload
@ -61,18 +44,10 @@ describe DiscourseCalendar::EventUpdater do
end
it "will work with no time date" do
raw = <<~MD
[calendar]
[/calendar]
MD
topic = Fabricate(:topic, first_post: create_post(raw: raw))
op = create_post(raw: "[calendar]\n[/calendar]")
op = topic.first_post
raw = <<~MD
Rome [date="2018-06-05"] [date="2018-06-11"]
MD
post = create_post(raw: raw, topic: topic)
raw = %{Rome [date="2018-06-05"] [date="2018-06-11"]}
post = create_post(raw: raw, topic: op.topic)
CookedPostProcessor.new(post).post_process
op.reload
@ -83,18 +58,10 @@ describe DiscourseCalendar::EventUpdater do
end
it "will work with timezone" do
raw = <<~MD
[calendar]
[/calendar]
MD
topic = Fabricate(:topic, first_post: create_post(raw: raw))
op = create_post(raw: "[calendar]\n[/calendar]")
op = topic.first_post
raw = <<~MD
Rome [date="2018-06-05" timezone="Europe/Paris"] [date="2018-06-11" time="13:45:33" timezone="America/Los_Angeles"]
MD
post = create_post(raw: raw, topic: topic)
raw = %{Rome [date="2018-06-05" timezone="Europe/Paris"] [date="2018-06-11" time="13:45:33" timezone="America/Los_Angeles"]}
post = create_post(raw: raw, topic: op.topic)
CookedPostProcessor.new(post).post_process
op.reload

View File

@ -1,29 +0,0 @@
require 'rails_helper'
describe 'No calendar' do
before do
SiteSetting.queue_jobs = false
end
describe 'creating topics and posts' do
it 'works' do
expect {
raw = <<~MD
An op with no calendar in raw
MD
op = create_post(raw: raw)
topic = op.topic
raw = <<~MD
This is a post with no event
MD
post = create_post(topic: topic, raw: raw)
raw = <<~MD
This is a post revision with no event
MD
post.revise(post.user, raw: raw)
}.to_not raise_error
end
end
end

View File

@ -1,33 +0,0 @@
require 'rails_helper'
describe 'markdown' do
before do
SiteSetting.queue_jobs = false
end
it "can properly decorate dynamic calendars" do
raw = <<~MD
[calendar]
[/calendar]
MD
cooked = (<<~HTML).strip
<div class="calendar" data-calendar-type="dynamic"></div>
HTML
expect(PrettyText.cook raw).to eq(cooked)
end
it "can properly decorate static calendars" do
raw = <<~MD
[calendar type="static"]
[/calendar]
MD
cooked = (<<~HTML).strip
<div class="calendar" data-calendar-type="static"></div>
HTML
expect(PrettyText.cook raw).to eq(cooked)
end
end

View File

@ -1,69 +1,30 @@
require 'rails_helper'
require "rails_helper"
describe 'Dynamic calendar' do
raw = <<~MD
[calendar type="static"]
[/calendar]
MD
let(:op) { create_post(raw: raw) }
let(:topic) { op.topic }
describe "Static calendar" do
before do
SiteSetting.queue_jobs = false
Jobs.run_immediately!
SiteSetting.calendar_enabled = true
end
def create_calendar_post(topic, raw)
post = create_post(raw: raw, topic: topic)
topic.reload
post.reload
post
let(:raw) { '[calendar type="static"]\n[/calendar]' }
let(:op) { create_post(raw: raw) }
it "is static" do
expect(op.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD]).to eq("static")
end
describe 'multiple calendars in one post' do
it 'raises an error' do
expect {
raw = <<~MD
[calendar type="static"]
[/calendar]
[calendar type="static"]
[/calendar]
MD
post = create_post(raw: raw)
Fabricate(:topic, first_post: post)
}.to raise_error(StandardError, I18n.t("discourse_calendar.more_than_one_calendar"))
end
it "empties details when going from static to dynamic" do
p = create_post(topic: op.topic, raw: 'Rome [date="2018-06-05"]')
op.reload
expect(op.calendar_details[p.post_number.to_s]).to be_present
op.revise(op.user, raw: "[calendar]\n[/calendar]")
op.reload
expect(op.custom_fields[DiscourseCalendar::CALENDAR_CUSTOM_FIELD]).to eq("dynamic")
expect(op.calendar_details).to be_empty
end
describe 'going from static to dynamic' do
it 'cleans up everything' do
raw = <<~MD
Rome [date="2018-06-05" timezone="Europe/Paris"]
MD
post = create_calendar_post(topic, raw)
expect(topic.first_post.custom_fields["calendar-details"][post.post_number.to_s]).to be_present
raw = <<~MD
[calendar]
[/calendar]
MD
op.revise(op.user, raw: raw)
op.reload
expect(op.custom_fields['calendar']).to eq('dynamic')
expect(op.custom_fields['calendar-details']).to be_empty
end
end
describe 'a calendar not in first post' do
it 'raises an error' do
raw = <<~MD
Another calendar
[calendar]
[/calendar]
MD
expect { create_calendar_post(topic, raw) }.to raise_error(StandardError, I18n.t("discourse_calendar.calendar_must_be_in_first_post"))
end
end
end

View File

@ -1,29 +1,22 @@
require 'rails_helper'
require "rails_helper"
describe "post serializer" do
describe 'post serializer' do
before do
SiteSetting.queue_jobs = false
Jobs.run_immediately!
SiteSetting.calendar_enabled = true
end
it 'includes calendar details in the serializer' do
raw = <<~MD
[calendar]
[/calendar]
MD
topic = Fabricate(:topic, first_post: create_post(raw: raw))
it "includes calendar details" do
op = create_post(raw: "[calendar]\n[/calendar]")
op = topic.first_post
raw = <<~MD
Rome [date="2018-06-05" time="10:20:00"]
MD
post = create_post(raw: raw, topic: topic)
post = create_post(topic: op.topic, raw: 'Rome [date="2018-06-05" time="10:20:00"]')
op.reload
json = PostSerializer.new(op, scope: Guardian.new).as_json
accepted = json[:post][:calendar_details]
expect(accepted.length).to eq(1)
expect(json[:post][:calendar_details].size).to eq(1)
end
end