users and metacodes api endpoints

This commit is contained in:
Devin Howard 2016-10-04 22:24:47 +08:00
parent c90460802e
commit 2eae89a6b7
23 changed files with 405 additions and 10 deletions

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
module Api
module V2
class MetacodesController < RestfulController
def searchable_columns
[:name]
end
end
end
end

View file

@ -70,7 +70,8 @@ module Api
def default_scope
{
embeds: embeds
embeds: embeds,
current_user: current_user
}
end

View file

@ -0,0 +1,24 @@
# frozen_string_literal: true
module Api
module V2
class UsersController < RestfulController
def current
@user = current_user
authorize @user
return show
end
private
def searchable_columns
[:name]
end
# only ask serializer to return is_admin field if we're on the
# current_user action
def default_scope
super.merge(show_is_admin: action_name == 'current')
end
end
end
end

View file

@ -0,0 +1,27 @@
class MetacodePolicy < ApplicationPolicy
def index?
true
end
def show?
true
end
def create?
user.is_admin
end
def update?
user.is_admin
end
def destroy?
false
end
class Scope < Scope
def resolve
scope.all
end
end
end

View file

@ -0,0 +1,41 @@
class UserPolicy < ApplicationPolicy
def index?
user.present?
end
def show?
user.present?
end
def create?
fail 'Create should be handled by Devise'
end
def update?
user == record
end
def destroy?
false
end
def details?
show?
end
def updatemetacodes?
update?
end
# API action
def current?
user == record
end
class Scope < Scope
def resolve
return scope.all if user.present?
scope.none
end
end
end

View file

@ -4,9 +4,8 @@ module Api
class MetacodeSerializer < ApplicationSerializer
attributes :id,
:name,
:manual_icon,
:color,
:aws_icon
:icon
end
end
end

View file

@ -5,9 +5,11 @@ module Api
attributes :id,
:name,
:avatar,
:is_admin,
:generation
attribute :is_admin,
if: -> { scope[:show_is_admin] && scope[:current_user] == object }
def avatar
object.image.url(:sixtyfour)
end

View file

@ -63,13 +63,17 @@ Metamaps::Application.routes.draw do
namespace :api, path: '/api', default: { format: :json } do
namespace :v2, path: '/v2' do
resources :metacodes, only: [:index, :show]
resources :mappings, only: [:index, :create, :show, :update, :destroy]
resources :maps, only: [:index, :create, :show, :update, :destroy]
resources :synapses, only: [:index, :create, :show, :update, :destroy]
resources :topics, only: [:index, :create, :show, :update, :destroy]
resources :mappings, only: [:index, :create, :show, :update, :destroy]
resources :tokens, only: [:create, :destroy] do
get :my_tokens, on: :collection
end
resources :topics, only: [:index, :create, :show, :update, :destroy]
resources :users, only: [:index, :show] do
get :current, on: :collection
end
end
namespace :v1, path: '/v1' do
# api v1 routes all lead to a deprecation error method

View file

@ -16,19 +16,23 @@ traits:
searchable: !include traits/searchable.raml
schemas:
topic: !include schemas/_topic.json
synapse: !include schemas/_synapse.json
map: !include schemas/_map.json
mapping: !include schemas/_mapping.json
metacode: !include schemas/_metacode.json
synapse: !include schemas/_synapse.json
token: !include schemas/_token.json
topic: !include schemas/_topic.json
user: !include schemas/_user.json
#resourceTypes:
# base: !include resourceTypes/base.raml
# item: !include resourceTypes/item.raml
# collection: !include resourceTypes/collection.raml
/topics: !include apis/topics.raml
/synapses: !include apis/synapses.raml
/maps: !include apis/maps.raml
/mappings: !include apis/mappings.raml
/metacodes: !include api/metacodes.raml
/synapses: !include apis/synapses.raml
/tokens: !include apis/tokens.raml
/topics: !include apis/topics.raml
/users: !include apis/users.raml

View file

@ -0,0 +1,16 @@
#type: collection
get:
is: [ searchable: { searchFields: "name" }, orderable, pageable ]
responses:
200:
body:
application/json:
example: !include ../examples/metacodes.json
/{id}:
#type: item
get:
responses:
200:
body:
application/json:
example: !include ../examples/metacode.json

24
doc/api/apis/users.raml Normal file
View file

@ -0,0 +1,24 @@
#type: collection
get:
is: [ searchable: { searchFields: "name" }, orderable, pageable ]
responses:
200:
body:
application/json:
example: !include ../examples/users.json
/current:
#type: item
get:
responses:
200:
body:
application/json:
example: !include ../examples/current_user.json
/{id}:
#type: item
get:
responses:
200:
body:
application/json:
example: !include ../examples/user.json

View file

@ -0,0 +1,8 @@
{
"data": {
"id": 1,
"name": "Action",
"color": "#BD6C85",
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_action.png"
}
}

View file

@ -0,0 +1,30 @@
{
"data": [
{
"id": 1,
"name": "Action",
"color": "#BD6C85",
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_action.png"
},
{
"id": 2,
"name": "Activity",
"color": "#6EBF65",
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_activity.png"
},
{
"id": 3,
"name": "Catalyst",
"color": "#EF8964",
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_catalyst.png"
}
],
"page": {
"current_page": 1,
"next_page": 2,
"prev_page": 0,
"total_pages": 16,
"total_count": 47,
"per": 3
}
}

View file

@ -0,0 +1,9 @@
{
"data": {
"id": 1,
"name": "user",
"avatar": "https://s3.amazonaws.com/metamaps-assets/site/user.png",
"generation": 0,
"is_admin": false
}
}

View file

@ -0,0 +1,24 @@
{
"data": [
{
"id": 1,
"name": "user",
"avatar": "https://s3.amazonaws.com/metamaps-assets/site/user.png",
"generation": 0
},
{
"id": 2,
"name": "admin",
"avatar": "https://s3.amazonaws.com/metamaps-assets/site/user.png",
"generation": 0
}
],
"page": {
"current_page": 1,
"next_page": 0,
"prev_page": 0,
"total_pages": 1,
"total_count": 2,
"per": 25
}
}

View file

@ -0,0 +1,24 @@
{
"name": "Metacode",
"type": "object",
"properties": {
"id": {
"$ref": "_id.json"
},
"name": {
"type": "string"
},
"color": {
"type": "string"
},
"icon": {
"type": "string"
}
},
"required": [
"id",
"name",
"color",
"icon"
]
}

View file

@ -0,0 +1,28 @@
{
"name": "User",
"type": "object",
"properties": {
"id": {
"$ref": "_id.json"
},
"name": {
"type": "string"
},
"avatar": {
"type": "string"
},
"generation": {
"type": "integer",
"minimum": 0
},
"is_admin": {
"type": "boolean"
}
},
"required": [
"id",
"name",
"avatar",
"generation"
]
}

View file

@ -0,0 +1,12 @@
{
"name": "Metacode Envelope",
"type": "object",
"properties": {
"data": {
"$ref": "_metacode.json"
}
},
"required": [
"data"
]
}

View file

@ -0,0 +1,19 @@
{
"name": "Metacodes",
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "_metacode.json"
}
},
"page": {
"$ref": "_page.json"
}
},
"required": [
"data",
"page"
]
}

12
doc/api/schemas/user.json Normal file
View file

@ -0,0 +1,12 @@
{
"name": "User Envelope",
"type": "object",
"properties": {
"data": {
"$ref": "_user.json"
}
},
"required": [
"data"
]
}

View file

@ -0,0 +1,19 @@
{
"name": "Users",
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "_user.json"
}
},
"page": {
"$ref": "_page.json"
}
},
"required": [
"data",
"page"
]
}

View file

@ -0,0 +1,25 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'metacodes API', type: :request do
let(:user) { create(:user, admin: true) }
let(:token) { create(:token, user: user).token }
let(:metacode) { create(:metacode) }
it 'GET /api/v2/metacodes' do
create_list(:metacode, 5)
get '/api/v2/metacodes', params: { access_token: token }
expect(response).to have_http_status(:success)
expect(response).to match_json_schema(:metacodes)
expect(JSON.parse(response.body)['data'].count).to eq 5
end
it 'GET /api/v2/metacodes/:id' do
get "/api/v2/metacodes/#{metacode.id}", params: { access_token: token }
expect(response).to have_http_status(:success)
expect(response).to match_json_schema(:metacode)
expect(JSON.parse(response.body)['data']['id']).to eq metacode.id
end
end

View file

@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'users API', type: :request do
let(:user) { create(:user, admin: true) }
let(:token) { create(:token, user: user).token }
let(:record) { create(:user) }
it 'GET /api/v2/users' do
create_list(:user, 5)
get '/api/v2/users', params: { access_token: token }
expect(response).to have_http_status(:success)
expect(response).to match_json_schema(:users)
expect(JSON.parse(response.body)['data'].count).to eq 6
end
it 'GET /api/v2/users/:id' do
get "/api/v2/users/#{record.id}", params: { access_token: token }
expect(response).to have_http_status(:success)
expect(response).to match_json_schema(:user)
expect(JSON.parse(response.body)['data']['id']).to eq record.id
end
it 'GET /api/v2/users/current' do
get '/api/v2/users/current', params: { access_token: token }
expect(response).to have_http_status(:success)
expect(response).to match_json_schema(:user)
expect(JSON.parse(response.body)['data']['id']).to eq user.id
end
end