Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 2 commits
  • 11 files changed
  • 0 commit comments
  • 1 contributor
View
3 config.ru
@@ -10,4 +10,5 @@ map '/assets' do
end
-run Todo::Application
+use Todo::Api
+run Todo::Frontend
View
2 lib/todo.rb
@@ -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
111 lib/todo/api.rb
@@ -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
124 lib/todo/application.rb
@@ -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
9 lib/todo/frontend.rb
@@ -0,0 +1,9 @@
+module Todo
+ class Frontend < Application
+
+ get '/' do
+ haml :index
+ end
+
+ end
+end
View
2 lib/todo/services/session_creator.rb
@@ -28,6 +28,8 @@ def user
end
def create_session
+ fail 'Session could not be destroyed' if @user.session && !@user.session.destroy
+
@session = Models::Session.create user: @user
if @session.saved?
View
22 spec/api/sessions_spec.rb
@@ -10,26 +10,28 @@
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
end
context 'when a session already exists' do
- before do
+ let!(:previous_access_token) do
session_creator = Todo::Services::SessionCreator.new(params)
expect(session_creator.valid?).to be_true
+ session_creator.access_token
end
- xit 'should delete older session and create a new one' do
+ 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 be_nil
- expect(last_response.body).to have_json_path 'errors/user'
- expect(last_response.status).to eq 404
+ 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
end
end
end
@@ -45,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
45 spec/api/todos_spec.rb
@@ -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
View
10 spec/api/users_spec.rb
@@ -9,11 +9,14 @@
params = { user: { email: 'test@test.com', password: '123test123' } }
post '/api/users', params
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
+ expect(last_response).to be_json
+
expect(last_response.body).to have_json_path 'id'
expect(last_response.body).not_to have_json_path 'email'
expect(last_response.body).not_to have_json_path 'password'
+
expect(last_response.status).to eq 200
+
expect(Todo::Models::User.count).to eq 1
end
@@ -23,9 +26,12 @@
params = { user: { email: 'test@test.com' } }
post '/api/users', params
- expect(last_response.headers['Content-Type']).to eq 'application/json;charset=utf-8'
+ expect(last_response).to be_json
+
expect(last_response.body).to have_json_path 'errors/password'
+
expect(last_response.status).to eq 404
+
expect(Todo::Models::User.count).to eq 0
end
View
16 spec/services/session_creator_spec.rb
@@ -9,24 +9,26 @@
it 'should create a session' do
session_creator = Todo::Services::SessionCreator.new params
- expect(session_creator.valid?).to be_true
+ expect(session_creator).to be_valid
expect(session_creator.access_token).not_to be_nil
expect(session_creator.h_errors[:errors]).to be_empty
end
end
context 'when a session already exists' do
- before do
+ let!(:previous_access_token) do
Todo::Models::User.create(params)
session_creator = Todo::Services::SessionCreator.new(params)
- expect(session_creator.valid?).to be_true
+ expect(session_creator).to be_valid
+ session_creator.access_token
end
- it 'should not create a session' do
+ it 'should create a new session' do
session_creator = Todo::Services::SessionCreator.new params
- expect(session_creator.valid?).not_to be_true
- expect(session_creator.access_token).to be_nil
- expect(session_creator.h_errors[:errors]).not_to be_empty
+ expect(session_creator).to be_valid
+ expect(session_creator.access_token).not_to be_nil
+ expect(session_creator.access_token).not_to eq previous_access_token
+ expect(session_creator.h_errors[:errors]).to be_empty
end
end
end
View
14 spec/support/shared_api_context.rb
@@ -4,7 +4,19 @@
include Rack::Test::Methods
def app
- Todo::Application
+ Todo::Api
end
end
+
+RSpec::Matchers.define :be_json do |expected|
+ match do |actual|
+ actual.headers['Content-Type'] == 'application/json;charset=utf-8'
+ end
+end
+
+RSpec::Matchers.define :have_cookie do |name, value|
+ match do |actual|
+ actual.headers['Set-Cookie'] =~ /#{name}=#{value}/
+ end
+end

No commit comments for this range

Something went wrong with that request. Please try again.