Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an Api Resource Controller #319

Merged
merged 1 commit into from
Sep 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions api/app/controllers/spree/api/resource_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
class Spree::Api::ResourceController < Spree::Api::BaseController
before_action :load_resource, only: [:show, :update, :destroy]

def index
@collection = model_class.accessible_by(current_ability, :read).ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
instance_variable_set("@#{controller_name}", @collection)

respond_with(@collection)
end

def show
respond_with(@object)
end

def new
authorize! :new, model_class
respond_with(model_class.new)
end

def create
authorize! :create, model_class

@object = model_class.new(permitted_resource_params)
instance_variable_set("@#{object_name}", @object)

if @object.save
respond_with(@object, status: 201, default_template: :show)
else
invalid_resource!(@object)
end
end

def update
authorize! :update, @object

if @object.update_attributes(permitted_resource_params)
respond_with(@object, status: 200, default_template: :show)
else
invalid_resource!(@object)
end
end

def destroy
authorize! :destroy, @object

if @object.destroy
respond_with(@object, status: 204)
else
invalid_resource!(@object)
end
end

protected

def load_resource
@object = model_class.accessible_by(current_ability, :read).find(params[:id])
instance_variable_set("@#{object_name}", @object)
end

def permitted_resource_params
params.require(object_name).permit(permitted_resource_attributes)
end

def permitted_resource_attributes
send("permitted_#{object_name}_attributes")
end

def model_class
"Spree::#{controller_name.classify}".constantize
end

def object_name
controller_name.singularize
end
end
58 changes: 7 additions & 51 deletions api/app/controllers/spree/api/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,56 +1,12 @@
module Spree
module Api
class UsersController < Spree::Api::BaseController
class Spree::Api::UsersController < Spree::Api::ResourceController

def index
@users = Spree.user_class.accessible_by(current_ability,:read).ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
respond_with(@users)
end
protected

def show
respond_with(user)
end

def new
end

def create
authorize! :create, Spree.user_class
@user = Spree.user_class.new(user_params)
if @user.save
respond_with(@user, :status => 201, :default_template => :show)
else
invalid_resource!(@user)
end
end

def update
authorize! :update, user
if user.update_attributes(user_params)
respond_with(user, :status => 200, :default_template => :show)
else
invalid_resource!(user)
end
end

def destroy
authorize! :destroy, user
user.destroy
respond_with(user, :status => 204)
end

private

def user
@user ||= Spree.user_class.accessible_by(current_ability, :read).find(params[:id])
end

def user_params
params.require(:user).permit(permitted_user_attributes |
[bill_address_attributes: permitted_address_attributes,
ship_address_attributes: permitted_address_attributes])
end
def model_class
Spree.user_class
end

end
def permitted_resource_attributes
super | [bill_address_attributes: permitted_address_attributes, ship_address_attributes: permitted_address_attributes]
end
end
157 changes: 157 additions & 0 deletions api/spec/controllers/spree/api/resource_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
require 'spec_helper'

module Spree
module Api
class WidgetsController < Spree::Api::ResourceController
prepend_view_path('spec/test_views')

def model_class
Widget
end

def permitted_widget_attributes
[:name]
end
end
end

describe Api::WidgetsController, type: :controller do
render_views

after(:all) do
Rails.application.reload_routes!
end

with_model 'Widget' do
table do |t|
t.string :name
t.integer :position
t.timestamps null: false
end

model do
acts_as_list
validates :name, presence: true
end
end

before do
Spree::Core::Engine.routes.draw do
namespace :api do
resources :widgets
end
end
end

let(:user) { create(:user, :with_api_key) }
let(:admin_user) { create(:admin_user, :with_api_key) }

describe "#index" do
let!(:widget) { Widget.create!(name: "a widget") }

it "returns no widgets" do
api_get :index, token: user.spree_api_key
expect(response).to be_success
expect(json_response['widgets']).to be_blank
end

context "it has authorization to read widgets" do
it "returns widgets" do
api_get :index, token: admin_user.spree_api_key
expect(response).to be_success
expect(json_response['widgets']).to include(
'name' => 'a widget',
'position' => 1
)
end
end
end

describe "#show" do
let(:widget) { Widget.create!(name: "a widget") }

it "returns not found" do
api_get :show, id: widget.to_param, token: user.spree_api_key
assert_not_found!
end

context "it has authorization read widgets" do
it "returns widget details" do
api_get :show, id: widget.to_param, token: admin_user.spree_api_key
expect(response).to be_success
expect(json_response['name']).to eq 'a widget'
end
end
end

describe "#new" do
it "returns unauthorized" do
api_get :new, token: user.spree_api_key
expect(response).to be_unauthorized
end

context "it is allowed to view a new widget" do
it "can learn how to create a new widget" do
api_get :new, token: admin_user.spree_api_key
expect(response).to be_success
expect(json_response["attributes"]).to eq(['name'])
end
end
end

describe "#create" do
it "returns unauthorized" do
expect {
api_post :create, widget: { name: "a widget" }, token: user.spree_api_key
}.not_to change(Widget, :count)
expect(response).to be_unauthorized
end

context "it is authorized to create widgets" do
it "can create a widget" do
expect {
api_post :create, widget: { name: "a widget" }, token: admin_user.spree_api_key
}.to change(Widget, :count).by(1)
expect(response).to be_created
expect(json_response['name']).to eq 'a widget'
expect(Widget.last.name).to eq 'a widget'
end
end
end

describe "#update" do
let!(:widget) { Widget.create!(name: "a widget") }
it "returns unauthorized" do
api_put :update, id: widget.to_param, widget: { name: "another widget" }, token: user.spree_api_key
assert_not_found!
expect(widget.reload.name).to eq 'a widget'
end

context "it is authorized to update widgets" do
it "can update a widget" do
api_put :update, id: widget.to_param, widget: { name: "another widget" }, token: admin_user.spree_api_key
expect(response).to be_success
expect(json_response['name']).to eq 'another widget'
expect(widget.reload.name).to eq 'another widget'
end
end
end

describe "#destroy" do
let!(:widget) { Widget.create!(name: "a widget") }
it "returns unauthorized" do
api_delete :destroy, id: widget.to_param, token: user.spree_api_key
assert_not_found!
expect { widget.reload }.not_to raise_error
end

context "it is authorized to destroy widgets" do
it "can destroy a widget" do
api_delete :destroy, id: widget.to_param, token: admin_user.spree_api_key
expect(response.status).to eq 204
expect { widget.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
end
end
2 changes: 2 additions & 0 deletions api/spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
config.include Spree::TestingSupport::Preferences
config.include Spree::TestingSupport::Mail

config.extend WithModel

config.fail_fast = ENV['FAIL_FAST'] || false

config.before(:each) do
Expand Down
7 changes: 7 additions & 0 deletions api/spec/test_views/spree/api/widgets/index.v1.rabl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object false
child(@collection => :widgets) do
extends "spree/api/widgets/show"
end
node(:count) { @collection.count }
node(:current_page) { params[:page] || 1 }
node(:pages) { @collection.num_pages }
2 changes: 2 additions & 0 deletions api/spec/test_views/spree/api/widgets/new.v1.rabl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
object false
node(:attributes) { [:name] }
2 changes: 2 additions & 0 deletions api/spec/test_views/spree/api/widgets/show.v1.rabl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
object @object
attributes :name, :position