Permalink
Browse files

Split frontend and api applications, add custom matchers to clean api

specs a little bit
  • Loading branch information...
1 parent 28772b8 commit 2aa449637059704f04b185708aa94afe74052e0d @chischaschos committed Feb 22, 2014
Showing with 184 additions and 146 deletions.
  1. +2 −1 config.ru
  2. +2 −0 lib/todo.rb
  3. +111 −0 lib/todo/api.rb
  4. +0 −124 lib/todo/application.rb
  5. +9 −0 lib/todo/frontend.rb
  6. +6 −6 spec/api/sessions_spec.rb
  7. +33 −12 spec/api/todos_spec.rb
  8. +8 −2 spec/api/users_spec.rb
  9. +13 −1 spec/support/shared_api_context.rb
View
@@ -10,4 +10,5 @@ map '/assets' do
end
-run Todo::Application
+use Todo::Api
+run Todo::Frontend
View
@@ -3,6 +3,8 @@
Bundler.require :default
module Todo
+ autoload :Api, 'todo/api'
+ autoload :Frontend, 'todo/frontend'
autoload :Application, 'todo/application'
autoload :Models, 'todo/models'
autoload :Services, 'todo/services'
View
@@ -0,0 +1,111 @@
+module Todo
+ class Api < Application
+
+ before '/api/*' do
+ content_type :json
+ end
+
+ set(:auth_required) do |required|
+ if required
+ condition do
+ @session = Models::Session.first(access_token: request.cookies['access_token'])
+ unless @session
+ halt 501, { errors: { default: 'Invalid access token' } }.to_json
+ end
+ end
+ end
+ end
+
+ post '/api/users', auth_required: false do
+ user = Models::User.new(params[:user])
+
+ if user.valid?
+ user.save!
+ user.to_json
+
+ else
+ status 404
+ user.h_errors.to_json
+ end
+ end
+
+ post '/api/session', auth_required: false do
+ session = Services::SessionCreator.new(params[:user])
+
+ if session.valid?
+ cookie_params = {
+ value: session.access_token,
+ httponly: true,
+ secure: true
+ }
+ response.set_cookie 'access_token', cookie_params
+
+ else
+ status 404
+ session.h_errors.to_json
+ end
+ end
+
+ post '/api/session', auth_required: false do
+ session = Services::SessionCreator.new(params[:user])
+
+ if session.valid?
+ cookie_params = {
+ value: session.access_token,
+ httponly: true,
+ secure: true
+ }
+ response.set_cookie 'access_token', cookie_params
+
+ else
+ status 404
+ session.h_errors.to_json
+ end
+ end
+
+ delete '/api/session', auth_required: true do
+ if !@session || @session && !@session.destroy
+ status 404
+ @session.h_errors.to_json
+ end
+ end
+
+ get '/api/list_item', auth_required: true do
+ @session.user.list_items.to_json
+ end
+
+ post '/api/list_item', auth_required: true do
+ list_item = @session.user.list_items.create(params[:list_item])
+
+ if list_item.saved?
+ list_item.to_json
+ else
+ status 404
+ list_item.h_errors.to_json
+ end
+ end
+
+ put '/api/list_item/:list_item_id', auth_required: true do |list_item_id|
+ list_item = @session.user.list_items.get(list_item_id)
+ list_item.attributes = list_item.attributes.merge(params[:list_item])
+
+ if list_item.save
+ list_item.to_json
+ else
+ status 404
+ list_item.h_errors.to_json
+ end
+ end
+
+ delete '/api/list_item/:list_item_id', auth_required: true do |list_item_id|
+ list_item = @session.user.list_items.get(list_item_id)
+
+ if !list_item || !list_item.destroy
+ status 404
+ list_item.h_errors.to_json
+ end
+
+ end
+
+ end
+end
View
@@ -18,129 +18,5 @@ class Application < Sinatra::Base
use Rack::CommonLogger, settings.logger
use Middlewares::ExceptionHandling
- get '/' do
- haml :index
- end
-
- post '/api/users' do
- content_type :json
- user = Models::User.new(params[:user])
-
- if user.valid?
- user.save!
- user.to_json
-
- else
- status 404
- user.h_errors.to_json
- end
- end
-
- post '/api/session' do
- content_type :json
-
- session = Services::SessionCreator.new(params[:user])
-
- if session.valid?
- cookie_params = {
- value: session.access_token,
- httponly: true,
- secure: true
- }
- response.set_cookie 'access_token', cookie_params
-
- else
- status 404
- session.h_errors.to_json
- end
- end
-
- post '/api/session' do
- content_type :json
-
- session = Services::SessionCreator.new(params[:user])
-
- if session.valid?
- cookie_params = {
- value: session.access_token,
- httponly: true,
- secure: true
- }
- response.set_cookie 'access_token', cookie_params
-
- else
- status 404
- session.h_errors.to_json
- end
- end
-
- delete '/api/session' do
- content_type :json
- session = Models::Session.first(access_token: request.cookies['access_token'])
- if !session || session && !session.destroy
- status 404
- session.h_errors.to_json
- end
- end
-
- post '/api/list_item' do
- content_type :json
- session = Models::Session.first(access_token: request.cookies['access_token'])
-
- if session
- list_item = session.user.list_items.create(params[:list_item])
-
- if list_item.saved?
- list_item.to_json
- else
- status 404
- list_item.h_errors.to_json
- end
-
- else
- status 501
- { errors: { default: 'Invalid access token' } }.to_json
- end
- end
-
- put '/api/list_item/:list_item_id' do |list_item_id|
- content_type :json
- session = Models::Session.first(access_token: request.cookies['access_token'])
-
- if session
- list_item = session.user.list_items.get(list_item_id)
- list_item.attributes = list_item.attributes.merge(params[:list_item])
-
- if list_item.save
- list_item.to_json
- else
- status 404
- list_item.h_errors.to_json
- end
-
- else
- status 501
- { errors: { default: 'Invalid access token' } }.to_json
- end
- end
-
- delete '/api/list_item/:list_item_id' do |list_item_id|
- content_type :json
- session = Models::Session.first(access_token: request.cookies['access_token'])
-
- if session
- list_item = session.user.list_items.get(list_item_id)
-
- if !list_item || !list_item.destroy
- status 404
- list_item.h_errors.to_json
- end
-
- else
- status 501
- { errors: { default: 'Invalid access token' } }.to_json
- end
- end
-
end
end
View
@@ -0,0 +1,9 @@
+module Todo
+ class Frontend < Application
+
+ get '/' do
+ haml :index
+ end
+
+ end
+end
View
@@ -10,8 +10,8 @@
it 'should allow a client to create a user session' do
post '/api/session', { user: params }
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to match /access_token=#{user.session.access_token}/
+ expect(last_response).to be_json
+ expect(last_response).to have_cookie 'access_token', user.session.access_token
expect(last_response.body).to eq ''
expect(last_response.status).to eq 200
end
@@ -27,8 +27,8 @@
it 'should delete older session and create a new one' do
post '/api/session', { user: params }
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to match /access_token=#{user.session.access_token}/
+ expect(last_response).to be_json
+ expect(last_response).to have_cookie 'access_token', user.session.access_token
expect(user.session.access_token).not_to eq previous_access_token
expect(last_response.body).to eq ''
expect(last_response.status).to eq 200
@@ -47,8 +47,8 @@
delete "/api/session"
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to be_nil
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
expect(last_response.body).to eq ''
expect(last_response.status).to eq 200
end
View
@@ -28,11 +28,21 @@
end
context 'when passing an invalid access token' do
+
+ it 'should not allow retrieving a list of my items' do
+ get '/api/list_item'
+
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
+ expect(last_response.body).to have_json_path 'errors/default'
+ expect(last_response.status).to eq 501
+ end
+
it 'should not allow to create' do
post '/api/list_item', { list_item: list_item_params }
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to be_nil
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
expect(last_response.body).to have_json_path 'errors/default'
expect(last_response.status).to eq 501
end
@@ -41,17 +51,17 @@
edit_params = { list_item: { description: 'Buy wine bottles' } }
put "/api/list_item/#{list_item.id}", edit_params
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to be_nil
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
expect(last_response.body).to have_json_path 'errors/default'
expect(last_response.status).to eq 501
end
it 'should not allow to destroy' do
delete "/api/list_item/#{list_item.id}"
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to be_nil
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
expect(last_response.body).to have_json_path 'errors/default'
expect(last_response.status).to eq 501
end
@@ -62,11 +72,22 @@
set_cookie "access_token=#{access_token}"
end
+ it 'should retrieve a list of my items' do
+ list_item
+
+ get '/api/list_item'
+
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
+ expect(last_response.body).to have_json_size(1).at_path '/'
+ expect(last_response.status).to eq 200
+ end
+
it 'should create a list item' do
post '/api/list_item', { list_item: list_item_params }
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to be_nil
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
last_response.body.tap do |body|
expect(body).to have_json_path 'id'
expect(body).to have_json_path 'description'
@@ -81,8 +102,8 @@
edit_params = { list_item: { description: 'Buy wine bottles' } }
put "/api/list_item/#{list_item.id}", edit_params
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to be_nil
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
last_response.body.tap do |body|
expect(body).to have_json_path 'id'
expect(body).to have_json_path 'description'
@@ -98,8 +119,8 @@
it 'should destroy a list item owned by you' do
delete "/api/list_item/#{list_item.id}"
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
- expect(last_response.headers['Set-Cookie']).to be_nil
+ expect(last_response).to be_json
+ expect(last_response).not_to have_cookie 'access_token'
expect(last_response.body).to eq ''
expect(last_response.status).to eq 200
end
Oops, something went wrong.

0 comments on commit 2aa4496

Please sign in to comment.