Merge branch 'api' into api-tag-updates
This commit is contained in:
commit
6fa99072d1
6 changed files with 413 additions and 4 deletions
72
app/controllers/api/v1/aspects_controller.rb
Normal file
72
app/controllers/api/v1/aspects_controller.rb
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Api
|
||||||
|
module V1
|
||||||
|
class AspectsController < Api::V1::BaseController
|
||||||
|
before_action only: %i[index show] do
|
||||||
|
require_access_token %w[read]
|
||||||
|
end
|
||||||
|
|
||||||
|
before_action only: %i[create update destroy] do
|
||||||
|
require_access_token %w[read write]
|
||||||
|
end
|
||||||
|
|
||||||
|
def index
|
||||||
|
aspects = current_user.aspects.map {|a| AspectPresenter.new(a).as_api_json(false) }
|
||||||
|
render json: aspects
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
aspect = current_user.aspects.where(id: params[:id]).first
|
||||||
|
if aspect
|
||||||
|
render json: AspectPresenter.new(aspect).as_api_json(true)
|
||||||
|
else
|
||||||
|
render json: I18n.t("api.endpoint_errors.aspects.not_found"), status: :not_found
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
params.require(%i[name chat_enabled])
|
||||||
|
aspect = current_user.aspects.build(name: params[:name], chat_enabled: params[:chat_enabled])
|
||||||
|
if aspect&.save
|
||||||
|
render json: AspectPresenter.new(aspect).as_api_json(true)
|
||||||
|
else
|
||||||
|
render json: I18n.t("api.endpoint_errors.aspects.cant_create"), status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
rescue ActionController::ParameterMissing
|
||||||
|
render json: I18n.t("api.endpoint_errors.aspects.cant_create"), status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
aspect = current_user.aspects.where(id: params[:id]).first
|
||||||
|
|
||||||
|
if !aspect
|
||||||
|
render json: I18n.t("api.endpoint_errors.aspects.cant_update"), status: :not_found
|
||||||
|
elsif aspect.update!(aspect_params(true))
|
||||||
|
render json: AspectPresenter.new(aspect).as_api_json(true)
|
||||||
|
else
|
||||||
|
render json: I18n.t("api.endpoint_errors.aspects.cant_update"), status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
rescue ActionController::ParameterMissing, ActiveRecord::RecordInvalid
|
||||||
|
render json: I18n.t("api.endpoint_errors.aspects.cant_update"), status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
aspect = current_user.aspects.where(id: params[:id]).first
|
||||||
|
if aspect&.destroy
|
||||||
|
head :no_content
|
||||||
|
else
|
||||||
|
render json: I18n.t("api.endpoint_errors.aspects.cant_delete"), status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def aspect_params(allow_order=false)
|
||||||
|
parameters = params.permit(:name, :chat_enabled)
|
||||||
|
parameters[:order_id] = params[:order] if params.has_key?(:order) && allow_order
|
||||||
|
parameters
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -11,7 +11,18 @@ class AspectPresenter < BasePresenter
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_json(options = {})
|
def as_api_json(full=false)
|
||||||
|
values = {
|
||||||
|
id: @aspect.id,
|
||||||
|
name: @aspect.name,
|
||||||
|
order: @aspect.order_id
|
||||||
|
}
|
||||||
|
|
||||||
|
values[:chat_enabled] = @aspect.chat_enabled if full
|
||||||
|
values
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_json(options={})
|
||||||
as_json.to_json(options)
|
as_json.to_json(options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -951,6 +951,11 @@ en:
|
||||||
login_required: "You must first login before you can authorize this application"
|
login_required: "You must first login before you can authorize this application"
|
||||||
could_not_authorize: "The application could not be authorized"
|
could_not_authorize: "The application could not be authorized"
|
||||||
endpoint_errors:
|
endpoint_errors:
|
||||||
|
aspects:
|
||||||
|
cant_create: "Failed to create the aspect"
|
||||||
|
cant_delete: "Failed to delete the aspect"
|
||||||
|
cant_update: "Failed to update the aspect"
|
||||||
|
not_found: "Aspect with provided ID could not be found"
|
||||||
conversations:
|
conversations:
|
||||||
not_found: "Conversation with provided guid could not be found"
|
not_found: "Conversation with provided guid could not be found"
|
||||||
cant_process: "Couldn’t accept or process the conversation"
|
cant_process: "Couldn’t accept or process the conversation"
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,7 @@ Rails.application.routes.draw do
|
||||||
get "podmin", to: "home#podmin"
|
get "podmin", to: "home#podmin"
|
||||||
|
|
||||||
api_version(module: "Api::V1", path: {value: "api/v1"}) do
|
api_version(module: "Api::V1", path: {value: "api/v1"}) do
|
||||||
|
resources :aspects, only: %i[show index create destroy update]
|
||||||
resources :posts, only: %i[show create destroy] do
|
resources :posts, only: %i[show create destroy] do
|
||||||
resources :comments, only: %i[create index destroy] do
|
resources :comments, only: %i[create index destroy] do
|
||||||
post "report" => "comments#report"
|
post "report" => "comments#report"
|
||||||
|
|
|
||||||
302
spec/integration/api/aspects_controller_spec.rb
Normal file
302
spec/integration/api/aspects_controller_spec.rb
Normal file
|
|
@ -0,0 +1,302 @@
|
||||||
|
# frozen_sTring_literal: true
|
||||||
|
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
describe Api::V1::AspectsController do
|
||||||
|
let(:auth) { FactoryGirl.create(:auth_with_read_and_write) }
|
||||||
|
let(:auth_read_only) { FactoryGirl.create(:auth_with_read) }
|
||||||
|
let!(:access_token) { auth.create_access_token.to_s }
|
||||||
|
let!(:access_token_read_only) { auth_read_only.create_access_token.to_s }
|
||||||
|
|
||||||
|
before do
|
||||||
|
@aspect1 = auth.user.aspects.where(name: "generic").first
|
||||||
|
@aspect2 = auth.user.aspects.create(name: "another aspect")
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#index" do
|
||||||
|
it "returns list of aspects" do
|
||||||
|
get(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {access_token: access_token}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspects = JSON.parse(response.body)
|
||||||
|
expect(aspects.length).to eq(auth.user.aspects.length)
|
||||||
|
aspects.each do |aspect|
|
||||||
|
found_aspect = auth.user.aspects.find_by(id: aspect["id"])
|
||||||
|
expect(aspect["name"]).to eq(found_aspect.name)
|
||||||
|
expect(aspect["order"]).to eq(found_aspect.order_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails if invalid token" do
|
||||||
|
get(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {access_token: "999_999_999"}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(401)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
context "with correct id" do
|
||||||
|
it "returns aspect" do
|
||||||
|
get(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: access_token}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspect = JSON.parse(response.body)
|
||||||
|
expect(aspect["id"]).to eq(@aspect2.id)
|
||||||
|
expect(aspect["name"]).to eq(@aspect2.name)
|
||||||
|
expect(aspect["order"]).to eq(@aspect2.order_id)
|
||||||
|
expect(aspect["chat_enabled"]).to eq(@aspect2.chat_enabled)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with incorrect id" do
|
||||||
|
it "fails to return with error" do
|
||||||
|
get(
|
||||||
|
api_v1_aspect_path("-1"),
|
||||||
|
params: {access_token: access_token}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.aspects.not_found"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when not logged in" do
|
||||||
|
it "fails to return with error" do
|
||||||
|
get(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: "999_999_999"}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(401)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
context "with full aspect settings" do
|
||||||
|
it "creates aspect" do
|
||||||
|
new_name = "diaspora developers"
|
||||||
|
post(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {name: new_name, chat_enabled: true, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspect = JSON.parse(response.body)
|
||||||
|
expect(aspect["name"]).to eq(new_name)
|
||||||
|
expect(aspect["chat_enabled"]).to be_truthy
|
||||||
|
expect(aspect.has_key?("id")).to be_truthy
|
||||||
|
expect(aspect.has_key?("order")).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails to create duplicate aspect" do
|
||||||
|
post(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {name: @aspect1.name, chat_enabled: true, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.aspects.cant_create"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with malformed settings" do
|
||||||
|
it "fails when missing name" do
|
||||||
|
post(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {chat_enabled: true, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.aspects.cant_create"))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails when missing chat" do
|
||||||
|
post(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {name: "new_aspect", access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.aspects.cant_create"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "improper credentials" do
|
||||||
|
it "fails when not logged in" do
|
||||||
|
post(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {name: "new_name", chat_enabled: true, access_token: "999_999_999"}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(401)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails when logged in read only" do
|
||||||
|
post(
|
||||||
|
api_v1_aspects_path,
|
||||||
|
params: {name: "new_name", chat_enabled: true, access_token: access_token_read_only}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(403)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
context "with aspect settings" do
|
||||||
|
it "updates full aspect" do
|
||||||
|
new_name = "NewAspectName"
|
||||||
|
new_chat = @aspect2.chat_enabled
|
||||||
|
order = @aspect2.order_id + 1
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {name: new_name, chat_enabled: new_chat, order: order, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspect = JSON.parse(response.body)
|
||||||
|
expect(aspect["name"]).to eq(new_name)
|
||||||
|
expect(aspect["chat_enabled"]).to eq(new_chat)
|
||||||
|
expect(aspect["order"]).to eq(order)
|
||||||
|
expect(aspect["id"]).to eq(@aspect2.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates name only aspect" do
|
||||||
|
new_name = "NewAspectName"
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {name: new_name, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspect = JSON.parse(response.body)
|
||||||
|
expect(aspect["name"]).to eq(new_name)
|
||||||
|
expect(aspect["id"]).to eq(@aspect2.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates chat only" do
|
||||||
|
new_chat = @aspect2.chat_enabled
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {chat_enabled: new_chat, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspect = JSON.parse(response.body)
|
||||||
|
expect(aspect["chat_enabled"]).to eq(new_chat)
|
||||||
|
expect(aspect["id"]).to eq(@aspect2.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates order only" do
|
||||||
|
order = @aspect2.order_id + 1
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {order: order, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspect = JSON.parse(response.body)
|
||||||
|
expect(aspect["order"]).to eq(order)
|
||||||
|
expect(aspect["id"]).to eq(@aspect2.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "succeds with no arguments" do
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
aspect = JSON.parse(response.body)
|
||||||
|
expect(aspect["name"]).to eq(@aspect2.name)
|
||||||
|
expect(aspect["chat_enabled"]).to eq(@aspect2.chat_enabled)
|
||||||
|
expect(aspect["id"]).to eq(@aspect2.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with bad parameters" do
|
||||||
|
it "fails with reused name" do
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {name: @aspect1.name, access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.aspects.cant_update"))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails with bad id" do
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path("-1"),
|
||||||
|
params: {name: "NewAspectName", access_token: access_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.aspects.cant_update"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "improper credentials" do
|
||||||
|
it "fails when not logged in" do
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: "999_999_999"}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(401)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails when logged in read only" do
|
||||||
|
patch(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: access_token_read_only}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(403)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#delete" do
|
||||||
|
context "with correct ID" do
|
||||||
|
it "deletes aspect" do
|
||||||
|
delete(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: access_token}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(204)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with bad ID" do
|
||||||
|
it "fails to delete with error" do
|
||||||
|
delete(
|
||||||
|
api_v1_aspect_path("-1"),
|
||||||
|
params: {access_token: access_token}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.aspects.cant_delete"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "improper credentials" do
|
||||||
|
it "fails when not logged in" do
|
||||||
|
delete(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: "999_999_999"}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(401)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails when logged in read only" do
|
||||||
|
delete(
|
||||||
|
api_v1_aspect_path(@aspect2.id),
|
||||||
|
params: {access_token: access_token_read_only}
|
||||||
|
)
|
||||||
|
expect(response.status).to eq(403)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
describe AspectPresenter do
|
describe AspectPresenter do
|
||||||
before do
|
before do
|
||||||
@presenter = AspectPresenter.new(bob.aspects.first)
|
@aspect = bob.aspects.first
|
||||||
|
@presenter = AspectPresenter.new(@aspect)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#to_json' do
|
describe '#to_json' do
|
||||||
|
|
@ -10,4 +11,21 @@ describe AspectPresenter do
|
||||||
expect(@presenter.to_json).to be_present
|
expect(@presenter.to_json).to be_present
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
describe "#to_api_json" do
|
||||||
|
it "creates simple JSON" do
|
||||||
|
aspect_json = @presenter.as_api_json(false)
|
||||||
|
expect(aspect_json[:id]).to eq(@aspect.id)
|
||||||
|
expect(aspect_json[:name]).to eq(@aspect.name)
|
||||||
|
expect(aspect_json[:order]).to eq(@aspect.order_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "produces full JSON" do
|
||||||
|
aspect_json = @presenter.as_api_json(true)
|
||||||
|
expect(aspect_json[:id]).to eq(@aspect.id)
|
||||||
|
expect(aspect_json[:name]).to eq(@aspect.name)
|
||||||
|
expect(aspect_json[:order]).to eq(@aspect.order_id)
|
||||||
|
expect(aspect_json[:chat_enabled]).to eq(@aspect.chat_enabled)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue