Accept published_at in Article API (#20235)

This commit is contained in:
Anna Buianova 2023-10-11 16:12:35 +03:00 committed by GitHub
parent ddf045ac68
commit a14a1e9e7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 1 deletions

View file

@ -147,7 +147,8 @@ module Api
def article_params
allowed_params = [
:title, :body_markdown, :published, :series,
:main_image, :canonical_url, :description, { tags: [] }
:main_image, :canonical_url, :description, { tags: [] },
:published_at
]
allowed_params << :organization_id if params.dig("article", "organization_id") && allowed_to_change_org_id?
params.require(:article).permit(allowed_params)

View file

@ -4,6 +4,20 @@ module Articles
new(...).call
end
# @param user [User]
# @param article_params [Hash]
# @option article_params [NilClass, String] :title
# @option article_params [NilClass, String] :body_markdown
# @option article_params [NilClass, String] :main_image
# @option article_params [Boolean] :published
# @option article_params [NilClass, String] :description
# @option article_params [NilClass, String] :video_thumbnail_url
# @option article_params [NilClass, String] :canonical_url
# @option article_params [NilClass, String] :series series slug
# @option article_params [Integer, NilClass] :collection_id
# @option article_params [Boolean] :archived
# @option article_params [String<Array>] :tags
# @option article_params [NilClass, String, ActiveSupport::TimeWithZone] :published_at
def initialize(user, article_params)
@user = user
@article_params = normalize_params(article_params)

View file

@ -622,6 +622,8 @@ RSpec.describe "Api::V1::Articles" do
describe "when authorized" do
let(:default_params) { { body_markdown: "" } }
let(:tomorrow) { Date.tomorrow }
let(:formatted_date) { tomorrow.strftime("%Y-%m-%d") }
def post_article(**params)
params = default_params.merge params
@ -878,6 +880,33 @@ RSpec.describe "Api::V1::Articles" do
expect(Article.find(response.parsed_body["id"]).description).to eq("#{'yoooo' * 20}y...")
end
it "creates an articles with published_at in the future" do
formatted_published_at = "#{formatted_date} 18:00 MSK"
published_at = DateTime.parse(formatted_published_at)
expect do
post_article(
title: Faker::Book.title,
body_markdown: "yoooo" * 100,
published_at: formatted_published_at,
)
end.to change(Article, :count).by(1)
created_article = Article.find(response.parsed_body["id"])
expect(created_article.published_at).to be_present
expect(created_article.published_at).to be_within(1.minute).of(published_at)
end
it "creates an article when publushed_at in the future without time is passed" do
expect do
post_article(
title: Faker::Book.title,
body_markdown: "yoooo" * 100,
published_at: formatted_date,
)
end.to change(Article, :count).by(1)
created_article = Article.find(response.parsed_body["id"])
expect(created_article.published_at.strftime("%Y-%m-%d")).to eq(formatted_date)
end
it "does not raise an error if article params are missing" do
expect do
post api_articles_path, params: {}.to_json, headers: post_headers
@ -898,6 +927,8 @@ RSpec.describe "Api::V1::Articles" do
let(:article) { create(:article, user: user, published: false, published_at: nil) }
let(:path) { api_article_path(article.id) }
let!(:organization) { create(:organization) }
let(:tomorrow) { Date.tomorrow }
let(:formatted_future_time) { "#{tomorrow.strftime('%Y-%m-%d')} 18:00 UTC" }
describe "when unauthorized" do
it "fails with no api key" do
@ -1151,6 +1182,41 @@ RSpec.describe "Api::V1::Articles" do
expect(article.reload.organization).to eq(organization)
end
it "updates published_at draft => scheduled" do
put_article(published_at: formatted_future_time, published: true)
expect(response).to have_http_status(:ok)
article.reload
expect(article.published_at > Time.current).to be true
end
it "updates published_at sheduled => scheduled" do
article.update_columns(published_at: 2.days.from_now, published: true)
future_time = DateTime.parse(formatted_future_time)
put_article(published_at: formatted_future_time)
expect(response).to have_http_status(:ok)
article.reload
expect(article.published_at).to be_within(1.minute).of(future_time)
end
it "doesn't allow to update published_at of a scheduled article to a past date" do
future = 2.days.from_now
article.update_columns(published_at: future, published: true)
put_article(published_at: "2020-02-02 19:00 UTC")
expect(response).to have_http_status(:unprocessable_entity)
article.reload
expect(article.published_at).to be_within(1.minute).of(future)
end
# published_at is immutable after publishing
it "doesn't update published_at for a published article (but doesn't raise an error)" do
time = 1.day.ago
article.update_columns(published_at: time, published: true)
put_article(published_at: formatted_future_time)
expect(response).to have_http_status(:ok)
article.reload
expect(article.published_at).to be_within(1.minute).of(time)
end
it "fails if params are not a Hash" do
# Not using the nifty put_article helper method because it expects a Hash
string_params = "this_string_is_definitely_not_a_hash"