Browse Source

RPG systems API controller

Refs #28
feature/29
Martin Bober 4 months ago
parent
commit
e88cbdbfa7
  1. 106
      app/controllers/api_systems_controller.rb
  2. 2
      config/application.rb
  3. 4
      config/routes.rb
  4. 10
      public/openapi.yaml
  5. 114
      test/controllers/api_systems_controller_test.rb

106
app/controllers/api_systems_controller.rb

@ -0,0 +1,106 @@
class ApiSystemsController < ApplicationController
include ApiHelper
before_action :get_system, except: [:index]
before_action :check_admin, except: [:index]
protect_from_forgery with: :null_session
def index
limit = 10
limit = params[:limit] if params.key? :limit
offset = 0
offset = params[:offset] if params.key? :offset
json = {
limit: limit,
offset: offset,
systems: []
}
if params.key? :q
json[:query] = params[:q]
res = RpgSystem.where("name LIKE :name", name: "%#{params[:q]}%").order(name: :asc).limit(limit).offset(offset)
else
res = RpgSystem.order(name: :asc).limit(limit).offset(offset)
end
systems = []
res.each do |s|
systems << {
name: s.name,
interested_players: s.interested_players.count,
experienced_players: s.experienced_players.count,
campaigns: s.campaigns.count,
characters: s.characters.count
}
end
json[:systems] = systems
render json: json
end
def update
unless params.key? :new_name
render status: :bad_request, json: {
error: "missing_field",
error_description: "Missing field: new_name"
}
return
end
@rpg_system.name = params[:new_name]
if @rpg_system.save
render json: {
name: @rpg_system.name
}
else
render status: :bad_request, json: {
error: "field_error",
error_fields: [{
field: 'new_name',
error: 'Error saving name'
}]
}
end
end
def destroy
@rpg_system.destroy
render json: {
name: @rpg_system.name
}
end
private
def get_system
unless params.key? :name
render status: :bad_request, json: {
error: "invalid_id",
error_description: "Missing parameter: name"
}
return
end
@rpg_system = RpgSystem.where(name: params[:name]).first
unless @rpg_system.present?
render status: :not_found, json: {
error: "not_found",
error_description: "No system found with name '#{params[:name]}'"
}
end
end
def check_admin
unless logged_in?
render status: :unauthorized, json: {
error: "invalid_token",
error_description: "You are not logged in"
}
return
end
unless is_admin?
render status: :forbidden, json: {
error: "invalid_token",
error_description: "You are not an admin"
}
end
end
end

2
config/application.rb

@ -40,7 +40,7 @@ module Charxchange
config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :options, :patch]
resource '*', :headers => :any, :methods => [:get, :post, :options, :patch, :delete]
end
end
end

4
config/routes.rb

@ -163,6 +163,10 @@ Rails.application.routes.draw do
get 'history', controller: :api_character, action: :get_history
delete 'history/:revision', controller: :api_character, action: :destroy_revision
end
get 'systems', controller: :api_systems, action: :index
patch 'systems/:name', controller: :api_systems, action: :update
delete 'systems/:name', controller: :api_systems, action: :destroy
end
end
end

10
public/openapi.yaml

@ -1058,7 +1058,7 @@ paths:
type: integer
description: Number of characters using this system
/1.0/systems/{name}:
post:
patch:
tags:
- "RPG Systems"
- "Admin"
@ -1074,7 +1074,7 @@ paths:
schema:
type: object
properties:
name:
new_name:
type: string
description: "New name for the system"
example: "Shadowrun 6"
@ -1087,6 +1087,12 @@ paths:
type: string
description: New name
example: "Shadowrun 6"
400:
description: Missing new_name parameter
content:
'application/json':
schema:
$ref: '#/components/schemas/Error'
401:
description: You are not logged in.
content:

114
test/controllers/api_systems_controller_test.rb

@ -0,0 +1,114 @@
require 'test_helper'
class ApiSystemsControllerTest < ActionController::TestCase
def setup
@rpg_system = RpgSystem.first
@player = players(:alice)
@admin = players(:admin)
end
test 'anon can get index without query' do
get :index, as: :json
assert_response :success
body = JSON.parse response.body
assert body.key?("offset")
assert body.key?("limit")
body["systems"].each do |s|
assert s.key?("name")
assert s.key?("interested_players")
assert s.key?("experienced_players")
assert s.key?("campaigns")
assert s.key?("characters")
end
end
test 'anon can get index with query' do
get :index, as: :json, params: {
q: "q"
}
assert_response :success
body = JSON.parse response.body
assert body.key?("offset")
assert body.key?("limit")
assert body.key?("query")
body["systems"].each do |s|
assert s.key?("name")
assert s.key?("interested_players")
assert s.key?("experienced_players")
assert s.key?("campaigns")
assert s.key?("characters")
end
end
test 'anon cannot rename system' do
name = @rpg_system.name
new_name = name + 'a'
patch :update, as: :json, params: {
name: name,
new_name: new_name
}
assert_response :unauthorized
@rpg_system.reload
assert_equal name, @rpg_system.name
end
test 'player cannot rename system' do
log_in_as @player
name = @rpg_system.name
new_name = name + 'a'
patch :update, as: :json, params: {
name: name,
new_name: new_name
}
assert_response :forbidden
@rpg_system.reload
assert_equal name, @rpg_system.name
end
test 'admin can rename system' do
log_in_as @admin
name = @rpg_system.name
new_name = name + 'a'
patch :update, as: :json, params: {
name: name,
new_name: new_name
}
assert_response :success
@rpg_system.reload
assert_equal new_name, @rpg_system.name
body = JSON.parse response.body
assert_equal new_name, body["name"]
end
test 'anon cannot delete system' do
assert_no_difference 'RpgSystem.count' do
delete :destroy, as: :json, params: {
name: @rpg_system.name
}
assert_response :unauthorized
end
end
test 'player cannot delete system' do
log_in_as @player
assert_no_difference 'RpgSystem.count' do
delete :destroy, as: :json, params: {
name: @rpg_system.name
}
assert_response :forbidden
end
end
test 'admin can delete system' do
log_in_as @admin
assert_difference 'RpgSystem.count', -1 do
delete :destroy, as: :json, params: {
name: @rpg_system.name
}
assert_response :success
end
body = JSON.parse response.body
assert_equal @rpg_system.name, body["name"]
end
end
Loading…
Cancel
Save