add starred to maps API and endpoint to create/delete
This commit is contained in:
parent
e3db00f229
commit
7edaeb7c4e
11 changed files with 84 additions and 2 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
|
|
@ -88,6 +88,10 @@ class Map < ApplicationRecord
|
||||||
updated_at.strftime('%m/%d/%Y')
|
updated_at.strftime('%m/%d/%Y')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def starred_by_user?(user)
|
||||||
|
user.stars.where(map: self).exists?
|
||||||
|
end
|
||||||
|
|
||||||
def as_json(_options = {})
|
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 = 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
|
json[:created_at_clean] = created_at_str
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
class Star < ActiveRecord::Base
|
class Star < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :map
|
belongs_to :map
|
||||||
|
validates :map, uniqueness: { scope: :user, message: 'You have already starred this map' }
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,9 +7,14 @@ module Api
|
||||||
:desc,
|
:desc,
|
||||||
:permission,
|
:permission,
|
||||||
:screenshot,
|
:screenshot,
|
||||||
|
:starred,
|
||||||
:created_at,
|
:created_at,
|
||||||
:updated_at
|
:updated_at
|
||||||
|
|
||||||
|
def starred
|
||||||
|
object.starred_by_user?(scope[:current_user])
|
||||||
|
end
|
||||||
|
|
||||||
def self.embeddable
|
def self.embeddable
|
||||||
{
|
{
|
||||||
user: {},
|
user: {},
|
||||||
|
|
|
@ -65,7 +65,10 @@ Metamaps::Application.routes.draw do
|
||||||
namespace :v2, path: '/v2' do
|
namespace :v2, path: '/v2' do
|
||||||
resources :metacodes, only: [:index, :show]
|
resources :metacodes, only: [:index, :show]
|
||||||
resources :mappings, only: [:index, :create, :show, :update, :destroy]
|
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 :synapses, only: [:index, :create, :show, :update, :destroy]
|
||||||
resources :tokens, only: [:create, :destroy] do
|
resources :tokens, only: [:create, :destroy] do
|
||||||
get :my_tokens, on: :collection
|
get :my_tokens, on: :collection
|
||||||
|
|
|
@ -94,3 +94,15 @@ post:
|
||||||
responses:
|
responses:
|
||||||
204:
|
204:
|
||||||
description: No content
|
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",
|
"desc": "Example map for the API",
|
||||||
"permission": "commons",
|
"permission": "commons",
|
||||||
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
|
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
|
||||||
|
"starred": false,
|
||||||
"created_at": "2016-03-26T08:02:05.379Z",
|
"created_at": "2016-03-26T08:02:05.379Z",
|
||||||
"updated_at": "2016-03-27T07:20:18.047Z",
|
"updated_at": "2016-03-27T07:20:18.047Z",
|
||||||
"topic_ids": [
|
"topic_ids": [
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"desc": "Example map for the API",
|
"desc": "Example map for the API",
|
||||||
"permission": "commons",
|
"permission": "commons",
|
||||||
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
|
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
|
||||||
|
"starred": false,
|
||||||
"created_at": "2016-03-26T08:02:05.379Z",
|
"created_at": "2016-03-26T08:02:05.379Z",
|
||||||
"updated_at": "2016-03-27T07:20:18.047Z",
|
"updated_at": "2016-03-27T07:20:18.047Z",
|
||||||
"topic_ids": [
|
"topic_ids": [
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
"format": "uri",
|
"format": "uri",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"starred": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
"$ref": "_datetimestamp.json"
|
"$ref": "_datetimestamp.json"
|
||||||
},
|
},
|
||||||
|
@ -61,6 +64,7 @@
|
||||||
"desc",
|
"desc",
|
||||||
"permission",
|
"permission",
|
||||||
"screenshot",
|
"screenshot",
|
||||||
|
"starred",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at"
|
"updated_at"
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,7 +16,7 @@ RSpec.describe 'maps API', type: :request do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'GET /api/v2/maps/:id' do
|
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 have_http_status(:success)
|
||||||
expect(response).to match_json_schema(:map)
|
expect(response).to match_json_schema(:map)
|
||||||
|
@ -45,6 +45,23 @@ RSpec.describe 'maps API', type: :request do
|
||||||
expect(Map.count).to eq 0
|
expect(Map.count).to eq 0
|
||||||
end
|
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
|
context 'RAML example' do
|
||||||
let(:resource) { get_json_example(:map) }
|
let(:resource) { get_json_example(:map) }
|
||||||
let(:collection) { get_json_example(:maps) }
|
let(:collection) { get_json_example(:maps) }
|
||||||
|
|
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…
Add table
Reference in a new issue