API: /api/articles/me defaults to published articles (#3937)

* /api/articles/me defaults to published articles

We want to make it explicit to retrieve unpublished articles, this change defaults `/api/articles/me` to only published articles, also adds `/api/articles/me/published`, `/api/articles/me/unpublished` and `/api/articles/me/all` to make requests more explicit.

* Refactor /me logic into a case switch
This commit is contained in:
rhymes 2019-09-04 20:02:13 +02:00 committed by Ben Halpern
parent f5e61fdae2
commit 2e5a847ab8
5 changed files with 192 additions and 13 deletions

View file

@ -47,7 +47,19 @@ module Api
def me
per_page = (params[:per_page] || 30).to_i
num = [per_page, 1000].min
@articles = @user.articles.
@articles = case params[:status]
when "published"
@user.articles.published
when "unpublished"
@user.articles.unpublished
when "all"
@user.articles
else
@user.articles.published
end
@articles = @articles.
includes(:organization).
order(published_at: :desc, created_at: :desc).
page(params[:page]).

View file

@ -75,6 +75,7 @@ class Article < ApplicationRecord
serialize :cached_organization
scope :published, -> { where(published: true) }
scope :unpublished, -> { where(published: false) }
scope :cached_tagged_with, ->(tag) { where("cached_tag_list ~* ?", "^#{tag},| #{tag},|, #{tag}$|^#{tag}$") }

View file

@ -79,7 +79,7 @@ Rails.application.routes.draw do
constraints: ApiConstraints.new(version: 0, default: true) do
resources :articles, only: %i[index show create update] do
collection do
get :me
get "me(/:status)", to: "articles#me", as: :me, constraints: { status: /published|unpublished|all/ }
end
end
resources :comments, only: %i[index show]

View file

@ -2,7 +2,7 @@ openapi: "3.0.2"
info:
title: DEV API
description: Access DEV articles, comments and other resources via API
version: "0.5.3"
version: "0.5.4"
termsOfService: https://dev.to/terms
contact:
name: DEV Team
@ -983,6 +983,153 @@ paths:
/articles/me:
get:
summary: Authenticated user's articles
description: |
This endpoint allows the client to retrieve a list of its published articles.
"Articles" are all the posts that users create on DEV that typically
show up in the feed. They can be a blog post, a discussion question,
a help thread etc. but is referred to as article within the code.
Published articles will be in reverse chronological publication order.
It will return published articles with pagination.
By default a page will contain `30` articles.
tags:
- articles
parameters:
- name: page
in: query
description: Pagination page.
schema:
type: integer
format: int32
example: 1
- name: per_page
in: query
description: Page size (defaults to 30 with a maximum of 1000).
schema:
type: integer
format: int32
example: 30
responses:
200:
description: A list of published articles
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ArticleMe"
security:
- api_key: []
- oauth2: []
x-code-samples: # https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#x-code-samples
- lang: Shell
label: curl
source: |
curl https://dev.to/api/articles/me
/articles/me/published:
get:
summary: Authenticated user's published articles
description: |
This endpoint allows the client to retrieve a list of its published articles.
"Articles" are all the posts that users create on DEV that typically
show up in the feed. They can be a blog post, a discussion question,
a help thread etc. but is referred to as article within the code.
Published articles will be in reverse chronological publication order.
It will return published articles with pagination.
By default a page will contain `30` articles.
tags:
- articles
parameters:
- name: page
in: query
description: Pagination page.
schema:
type: integer
format: int32
example: 1
- name: per_page
in: query
description: Page size (defaults to 30 with a maximum of 1000).
schema:
type: integer
format: int32
example: 30
responses:
200:
description: A list of published articles
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ArticleMe"
security:
- api_key: []
- oauth2: []
x-code-samples: # https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#x-code-samples
- lang: Shell
label: curl
source: |
curl https://dev.to/api/articles/me/published
/articles/me/unpublished:
get:
summary: Authenticated user's unpublished articles
description: |
This endpoint allows the client to retrieve a list of its unpublished articles.
"Articles" are all the posts that users create on DEV that typically
show up in the feed. They can be a blog post, a discussion question,
a help thread etc. but is referred to as article within the code.
Unpublished articles will be in reverse chronological creation order.
It will return unpublished articles with pagination.
By default a page will contain `30` articles.
tags:
- articles
parameters:
- name: page
in: query
description: Pagination page.
schema:
type: integer
format: int32
example: 1
- name: per_page
in: query
description: Page size (defaults to 30 with a maximum of 1000).
schema:
type: integer
format: int32
example: 30
responses:
200:
description: A list of articles
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ArticleMe"
security:
- api_key: []
- oauth2: []
x-code-samples: # https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#x-code-samples
- lang: Shell
label: curl
source: |
curl https://dev.to/api/articles/me/unpublished
/articles/me/all:
get:
summary: Authenticated user's all articles
description: |
This endpoint allows the client to retrieve a list of its articles.
@ -990,8 +1137,9 @@ paths:
show up in the feed. They can be a blog post, a discussion question,
a help thread etc. but is referred to as article within the code.
It will return both published and draft articles with pagination.
Draft articles will be at the top of the list in reverse chronological creation order.
It will return both published and unpublished articles with pagination.
Unpublished articles will be at the top of the list in reverse chronological creation order.
Published articles will follow in reverse chronological publication order.
By default a page will contain `30` articles.
@ -1028,7 +1176,7 @@ paths:
- lang: Shell
label: curl
source: |
curl https://dev.to/api/articles/me
curl https://dev.to/api/articles/me/all
/webhooks:
post:

View file

@ -112,7 +112,7 @@ RSpec.describe "Api::V0::Articles", type: :request do
end
end
describe "GET /api/articles/me" do
describe "GET /api/articles/me(/:status)" do
context "when request is unauthenticated" do
it "return unauthorized" do
get me_api_articles_path
@ -152,24 +152,42 @@ RSpec.describe "Api::V0::Articles", type: :request do
expect(json_response.length).to eq(1)
end
it "puts unpublished articles at the top" do
create(:article, user: user)
it "only includes published articles by default" do
create(:article, published: false, published_at: nil, user: user)
get me_api_articles_path, params: { access_token: access_token.token }
expected_order = json_response.map { |resp| resp["published"] }
expect(expected_order).to eq([false, true])
expect(json_response.length).to eq(0)
end
it "orders unpublished articles by reverse order" do
it "only includes published articles when asking for published articles" do
create(:article, published: false, published_at: nil, user: user)
get me_api_articles_path(status: :published), params: { access_token: access_token.token }
expect(json_response.length).to eq(0)
end
it "only includes unpublished articles when asking for unpublished articles" do
create(:article, published: false, published_at: nil, user: user)
get me_api_articles_path(status: :unpublished), params: { access_token: access_token.token }
expect(json_response.length).to eq(1)
end
it "orders unpublished articles by reverse order when asking for unpublished articles" do
older = create(:article, published: false, published_at: nil, user: user)
newer = nil
Timecop.travel(1.day.from_now) do
newer = create(:article, published: false, published_at: nil, user: user)
end
get me_api_articles_path, params: { access_token: access_token.token }
get me_api_articles_path(status: :unpublished), params: { access_token: access_token.token }
expected_order = json_response.map { |resp| resp["id"] }
expect(expected_order).to eq([newer.id, older.id])
end
it "puts unpublished articles at the top when asking for all articles" do
create(:article, user: user)
create(:article, published: false, published_at: nil, user: user)
get me_api_articles_path(status: :all), params: { access_token: access_token.token }
expected_order = json_response.map { |resp| resp["published"] }
expect(expected_order).to eq([false, true])
end
end
end