add starred to maps API (#719)
* add starred to maps API and endpoint to create/delete * add token to requests without token param * add minor version number to api version * metacode/user use uri in schema * make code climate happier
This commit is contained in:
parent
40453242fa
commit
d193c9a53c
16 changed files with 92 additions and 13 deletions
29
app/controllers/api/v2/stars_controller.rb
Normal file
29
app/controllers/api/v2/stars_controller.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class StarsController < RestfulController
|
||||
skip_before_action :load_resource
|
||||
|
||||
def create
|
||||
@map = Map.find(params[:id])
|
||||
@star = Star.new(user: current_user, map: @map)
|
||||
authorize @map, :star?
|
||||
create_action
|
||||
|
||||
if @star.errors.empty?
|
||||
render json: @map, scope: default_scope, serializer: MapSerializer, root: serializer_root
|
||||
else
|
||||
respond_with_errors
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@map = Map.find(params[:id])
|
||||
authorize @map, :unstar?
|
||||
@star = @map.stars.find_by(user: current_user)
|
||||
@star.destroy if @star.present?
|
||||
head :no_content
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -39,15 +39,8 @@ class Map < ApplicationRecord
|
|||
Perm.short(permission)
|
||||
end
|
||||
|
||||
# return an array of the contributors to the map
|
||||
def contributors
|
||||
contributors = []
|
||||
|
||||
mappings.each do |m|
|
||||
contributors.push(m.user) unless contributors.include?(m.user)
|
||||
end
|
||||
|
||||
contributors
|
||||
mappings.map(&:user).uniq
|
||||
end
|
||||
|
||||
def editors
|
||||
|
@ -88,6 +81,10 @@ class Map < ApplicationRecord
|
|||
updated_at.strftime('%m/%d/%Y')
|
||||
end
|
||||
|
||||
def starred_by_user?(user)
|
||||
user.stars.where(map: self).exists?
|
||||
end
|
||||
|
||||
def as_json(_options = {})
|
||||
json = super(methods: [:user_name, :user_image, :topic_count, :synapse_count, :contributor_count, :collaborator_ids, :screenshot_url], except: [:screenshot_content_type, :screenshot_file_size, :screenshot_file_name, :screenshot_updated_at])
|
||||
json[:created_at_clean] = created_at_str
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
class Star < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :map
|
||||
validates :map, uniqueness: { scope: :user, message: 'You have already starred this map' }
|
||||
end
|
||||
|
|
|
@ -7,9 +7,14 @@ module Api
|
|||
:desc,
|
||||
:permission,
|
||||
:screenshot,
|
||||
:starred,
|
||||
:created_at,
|
||||
:updated_at
|
||||
|
||||
def starred
|
||||
object.starred_by_user?(scope[:current_user])
|
||||
end
|
||||
|
||||
def self.embeddable
|
||||
{
|
||||
user: {},
|
||||
|
|
|
@ -65,7 +65,10 @@ Metamaps::Application.routes.draw 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 :maps, only: [:index, :create, :show, :update, :destroy] do
|
||||
post :stars, to: 'stars#create', on: :member
|
||||
delete :stars, to: 'stars#destroy', on: :member
|
||||
end
|
||||
resources :synapses, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :tokens, only: [:create, :destroy] do
|
||||
get :my_tokens, on: :collection
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#%RAML 1.0
|
||||
---
|
||||
title: Metamaps
|
||||
version: v2
|
||||
version: v2.0
|
||||
baseUri: https://metamaps.cc/api/v2
|
||||
mediaType: application/json
|
||||
|
||||
|
|
|
@ -94,3 +94,15 @@ post:
|
|||
responses:
|
||||
204:
|
||||
description: No content
|
||||
/stars:
|
||||
post:
|
||||
responses:
|
||||
201:
|
||||
description: Created
|
||||
body:
|
||||
application/json:
|
||||
example: !include ../examples/map.json
|
||||
delete:
|
||||
responses:
|
||||
204:
|
||||
description: No content
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"desc": "Example map for the API",
|
||||
"permission": "commons",
|
||||
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
|
||||
"starred": false,
|
||||
"created_at": "2016-03-26T08:02:05.379Z",
|
||||
"updated_at": "2016-03-27T07:20:18.047Z",
|
||||
"topic_ids": [
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"desc": "Example map for the API",
|
||||
"permission": "commons",
|
||||
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
|
||||
"starred": false,
|
||||
"created_at": "2016-03-26T08:02:05.379Z",
|
||||
"updated_at": "2016-03-27T07:20:18.047Z",
|
||||
"topic_ids": [
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
"format": "uri",
|
||||
"type": "string"
|
||||
},
|
||||
"starred": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"created_at": {
|
||||
"$ref": "_datetimestamp.json"
|
||||
},
|
||||
|
@ -61,6 +64,7 @@
|
|||
"desc",
|
||||
"permission",
|
||||
"screenshot",
|
||||
"starred",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
]
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"format": "uri",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"type": "string"
|
||||
},
|
||||
"avatar": {
|
||||
"format": "uri",
|
||||
"type": "string"
|
||||
},
|
||||
"generation": {
|
||||
|
|
|
@ -16,7 +16,8 @@ RSpec.describe 'mappings API', type: :request do
|
|||
end
|
||||
|
||||
it 'GET /api/v2/mappings/:id' do
|
||||
get "/api/v2/mappings/#{mapping.id}"
|
||||
get "/api/v2/mappings/#{mapping.id}", params: { access_token: token }
|
||||
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:mapping)
|
||||
|
|
|
@ -16,7 +16,7 @@ RSpec.describe 'maps API', type: :request do
|
|||
end
|
||||
|
||||
it 'GET /api/v2/maps/:id' do
|
||||
get "/api/v2/maps/#{map.id}"
|
||||
get "/api/v2/maps/#{map.id}", params: { access_token: token }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:map)
|
||||
|
@ -45,6 +45,23 @@ RSpec.describe 'maps API', type: :request do
|
|||
expect(Map.count).to eq 0
|
||||
end
|
||||
|
||||
it 'POST /api/v2/maps/:id/stars' do
|
||||
post "/api/v2/maps/#{map.id}/stars", params: { access_token: token }
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:map)
|
||||
expect(user.stars.count).to eq 1
|
||||
expect(map.stars.count).to eq 1
|
||||
end
|
||||
|
||||
it 'DELETE /api/v2/maps/:id/stars' do
|
||||
create(:star, map: map, user: user)
|
||||
delete "/api/v2/maps/#{map.id}/stars", params: { access_token: token }
|
||||
|
||||
expect(response).to have_http_status(:no_content)
|
||||
expect(user.stars.count).to eq 0
|
||||
expect(map.stars.count).to eq 0
|
||||
end
|
||||
|
||||
context 'RAML example' do
|
||||
let(:resource) { get_json_example(:map) }
|
||||
let(:collection) { get_json_example(:maps) }
|
||||
|
|
|
@ -16,7 +16,8 @@ RSpec.describe 'topics API', type: :request do
|
|||
end
|
||||
|
||||
it 'GET /api/v2/topics/:id' do
|
||||
get "/api/v2/topics/#{topic.id}"
|
||||
get "/api/v2/topics/#{topic.id}", params: { access_token: token }
|
||||
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:topic)
|
||||
|
|
5
spec/factories/stars.rb
Normal file
5
spec/factories/stars.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
FactoryGirl.define do
|
||||
factory :star do
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue