logical_model 0.2.18 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/logical_model.rb +17 -9
- data/logical_model.gemspec +2 -4
- data/spec/client_spec.rb +29 -21
- data/test/typhoeus_mocks.rb +5 -5
- metadata +3 -5
- data/service.rb +0 -83
- data/spec/service_spec.rb +0 -139
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.19
|
data/lib/logical_model.rb
CHANGED
@@ -68,13 +68,16 @@ class LogicalModel
|
|
68
68
|
end
|
69
69
|
|
70
70
|
DEFAULT_TIMEOUT = 10000
|
71
|
+
DEFAULT_RETRIES = 3
|
71
72
|
|
72
73
|
class << self
|
73
|
-
attr_accessor :host, :hydra, :resource_path, :api_key, :api_key_name,
|
74
|
+
attr_accessor :host, :hydra, :resource_path, :api_key, :api_key_name,
|
75
|
+
:timeout, :retries,
|
74
76
|
:use_ssl, :use_api_key, :enable_delete_multiple,
|
75
77
|
:json_root, :log_path
|
76
78
|
|
77
79
|
def timeout; @timeout ||= DEFAULT_TIMEOUT; end
|
80
|
+
def retries; @retries ||= DEFAULT_RETRIES; end
|
78
81
|
def use_ssl; @use_ssl ||= false; end
|
79
82
|
def log_path; @log_path ||= "log/logical_model.log"; end
|
80
83
|
def use_api_key; @use_api_key ||= false; end
|
@@ -324,14 +327,19 @@ class LogicalModel
|
|
324
327
|
#synchronic pagination
|
325
328
|
def self.paginate(options={})
|
326
329
|
result = nil
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
+
self.retries.times do
|
331
|
+
begin
|
332
|
+
async_paginate(options){|i| result = i}
|
333
|
+
Timeout::timeout(self.timeout/1000) do
|
334
|
+
self.hydra.run
|
335
|
+
end
|
336
|
+
break unless result.nil?
|
337
|
+
rescue Timeout::Error
|
338
|
+
self.logger.warn("timeout")
|
339
|
+
result = nil
|
340
|
+
end
|
330
341
|
end
|
331
342
|
result
|
332
|
-
rescue Timeout::Error
|
333
|
-
self.logger.warn("timeout")
|
334
|
-
return nil
|
335
343
|
end
|
336
344
|
|
337
345
|
# Asynchronic Count
|
@@ -437,9 +445,9 @@ class LogicalModel
|
|
437
445
|
params = self.class.merge_key(params)
|
438
446
|
|
439
447
|
response = nil
|
440
|
-
Timeout::timeout(self.class.timeout/1000) do
|
448
|
+
#Timeout::timeout(self.class.timeout/1000) do
|
441
449
|
response = Typhoeus::Request.post( self.class.resource_uri, :params => params, :timeout => self.class.timeout )
|
442
|
-
end
|
450
|
+
#end
|
443
451
|
if response.code == 201
|
444
452
|
log_ok(response)
|
445
453
|
self.id = ActiveSupport::JSON.decode(response.body)["id"]
|
data/logical_model.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "logical_model"
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.19"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Dwayne Macgowan"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-08-19"
|
13
13
|
s.description = "LogicalModel allows to use a resource as a model. It is based on web presentation http://www.slideshare.net/ihower/serviceoriented-design-and-implement-with-rails3"
|
14
14
|
s.email = "dwaynemac@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -35,9 +35,7 @@ Gem::Specification.new do |s|
|
|
35
35
|
"lib/safe_log.rb",
|
36
36
|
"logical_model.gemspec",
|
37
37
|
"models/user.rb",
|
38
|
-
"service.rb",
|
39
38
|
"spec/client_spec.rb",
|
40
|
-
"spec/service_spec.rb",
|
41
39
|
"test/helper.rb",
|
42
40
|
"test/test_logical_model.rb",
|
43
41
|
"test/typhoeus_mocks.rb"
|
data/spec/client_spec.rb
CHANGED
@@ -3,18 +3,13 @@ require File.dirname(__FILE__) + '/../client'
|
|
3
3
|
require File.dirname(__FILE__) + '/../test/typhoeus_mocks.rb'
|
4
4
|
include TyphoeusMocks
|
5
5
|
|
6
|
-
# NOTE: to run these specs you must have the service running locally. Do like this:
|
7
|
-
# ruby service.rb -p 3000 -e test
|
8
|
-
|
9
|
-
# Also note that after a single run of the tests the server must be restarted to reset
|
10
|
-
# the database. We could change this by deleting all users in the test setup.
|
11
6
|
describe "LogicalModel User client" do
|
12
7
|
|
13
8
|
describe "#create" do
|
14
9
|
context "with valid attributes" do
|
15
10
|
before(:each) do
|
16
|
-
|
17
|
-
@user = User.new({:name => "paul",
|
11
|
+
mock_post_with(code: 201, body: {'id' => 3}.to_json)
|
12
|
+
@user = User.new({:name => "paul",
|
18
13
|
:email => "paul@pauldix.net",
|
19
14
|
:password => "strongpass",
|
20
15
|
:bio => "rubyist"})
|
@@ -34,21 +29,34 @@ describe "LogicalModel User client" do
|
|
34
29
|
end
|
35
30
|
|
36
31
|
describe "#paginate" do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
32
|
+
context "when successfull" do
|
33
|
+
before do
|
34
|
+
mock_index(
|
35
|
+
collection: [{name:'a',email:'a@m'},
|
36
|
+
{name:'b',email:'b@m'},
|
37
|
+
{name:'c',email:'c@m'}],
|
38
|
+
total: 6
|
39
|
+
)
|
40
|
+
@users = User.paginate(page:1, per_page:1)
|
41
|
+
end
|
42
|
+
it "should return a Kaminari::PaginatableArray" do
|
43
|
+
@users.should be_a(Kaminari::PaginatableArray)
|
44
|
+
end
|
45
|
+
it "should set total_count" do
|
46
|
+
@users.total_count.should == 6
|
47
|
+
end
|
49
48
|
end
|
50
|
-
|
51
|
-
|
49
|
+
context "when it fails" do
|
50
|
+
before do
|
51
|
+
req = Typhoeus::Request.any_instance
|
52
|
+
response = mock( code: 500, body: "error", request: "mockedurl", time: 1234 )
|
53
|
+
req.stub(:on_complete).and_yield(response)
|
54
|
+
end
|
55
|
+
it "should retry LogicalModel#retries times (default: 3)" do
|
56
|
+
User.retries= 2
|
57
|
+
LogicalModel.should_receive(:async_paginate).exactly(2)
|
58
|
+
User.paginate(page:1,per_page:1).should be_nil
|
59
|
+
end
|
52
60
|
end
|
53
61
|
end
|
54
62
|
|
data/test/typhoeus_mocks.rb
CHANGED
@@ -45,11 +45,11 @@ module TyphoeusMocks
|
|
45
45
|
# @option [String] url - requested url
|
46
46
|
# @return [Typhoeus::Response]
|
47
47
|
def mock_response(options={})
|
48
|
-
mock_response = Typhoeus::Response.new(
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
mock_response = Typhoeus::Response.new()
|
49
|
+
mock_response.stub(:code).and_return(options[:code]||200)
|
50
|
+
mock_response.stub(:headers).and_return('whatever')
|
51
|
+
mock_response.stub(:time).and_return(0.1)
|
52
|
+
mock_response.stub(:body).and_return options[:body]
|
53
53
|
mock_response.stub!(:request).and_return(mock(:url => options[:url] || "mocked-url"))
|
54
54
|
mock_response
|
55
55
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logical_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.19
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -310,9 +310,7 @@ files:
|
|
310
310
|
- lib/safe_log.rb
|
311
311
|
- logical_model.gemspec
|
312
312
|
- models/user.rb
|
313
|
-
- service.rb
|
314
313
|
- spec/client_spec.rb
|
315
|
-
- spec/service_spec.rb
|
316
314
|
- test/helper.rb
|
317
315
|
- test/test_logical_model.rb
|
318
316
|
- test/typhoeus_mocks.rb
|
@@ -331,7 +329,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
331
329
|
version: '0'
|
332
330
|
segments:
|
333
331
|
- 0
|
334
|
-
hash:
|
332
|
+
hash: 430038925
|
335
333
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
336
334
|
none: false
|
337
335
|
requirements:
|
data/service.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler/setup'
|
3
|
-
require 'active_record'
|
4
|
-
require 'sinatra'
|
5
|
-
require './models/user'
|
6
|
-
|
7
|
-
# setting up the environment
|
8
|
-
env_index = ARGV.index("-e")
|
9
|
-
env_arg = ARGV[env_index + 1] if env_index
|
10
|
-
env = env_arg || ENV["SINATRA_ENV"] || "development"
|
11
|
-
databases = YAML.load_file("config/database.yml")
|
12
|
-
ActiveRecord::Base.establish_connection(databases[env])
|
13
|
-
|
14
|
-
if env == "test"
|
15
|
-
puts "starting in test mode"
|
16
|
-
User.destroy_all
|
17
|
-
User.create(:name => "paul", :email => "paul@pauldix.net", :bio => "rubyist")
|
18
|
-
end
|
19
|
-
|
20
|
-
# Simple RESTfull Service
|
21
|
-
# for LogicalModel Testing
|
22
|
-
|
23
|
-
# index
|
24
|
-
# Responds { collection, total }
|
25
|
-
get 'api/v1/users' do
|
26
|
-
users = User.all
|
27
|
-
|
28
|
-
{ collection: users, total: users.count}.to_json
|
29
|
-
end
|
30
|
-
|
31
|
-
# HTTP entry points
|
32
|
-
# get a user by name
|
33
|
-
get '/api/v1/users/:name' do
|
34
|
-
user = User.find_by_name(params[:name])
|
35
|
-
if user
|
36
|
-
user.to_json
|
37
|
-
else
|
38
|
-
error 404, {:error => "user not found"}.to_json
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# create a new user
|
43
|
-
post '/api/v1/users' do
|
44
|
-
begin
|
45
|
-
user = User.new(params[:user])
|
46
|
-
if user.save
|
47
|
-
[201, {id: user.id}.to_json]
|
48
|
-
else
|
49
|
-
error 400, {:errors => user.errors}.to_json
|
50
|
-
end
|
51
|
-
rescue => e
|
52
|
-
error 500, {:errors => e.message}.to_json
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# update an existing user
|
57
|
-
put '/api/v1/users/:name' do
|
58
|
-
user = User.find_by_name(params[:name])
|
59
|
-
if user
|
60
|
-
begin
|
61
|
-
if user.update_attributes(params[:user])
|
62
|
-
user.to_json
|
63
|
-
else
|
64
|
-
error 400, user.errors.to_json
|
65
|
-
end
|
66
|
-
rescue => e
|
67
|
-
error 400, e.message.to_json
|
68
|
-
end
|
69
|
-
else
|
70
|
-
error 404, {:error => "user not found"}.to_json
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# destroy an existing user
|
75
|
-
delete '/api/v1/users/:name' do
|
76
|
-
user = User.find_by_name(params[:name])
|
77
|
-
if user
|
78
|
-
user.destroy
|
79
|
-
user.to_json
|
80
|
-
else
|
81
|
-
error 404, {:error => "user not found"}.to_json
|
82
|
-
end
|
83
|
-
end
|
data/spec/service_spec.rb
DELETED
@@ -1,139 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../service'
|
2
|
-
|
3
|
-
require 'rspec'
|
4
|
-
require 'rack/test'
|
5
|
-
require 'test/unit'
|
6
|
-
require 'sinatra'
|
7
|
-
require 'json'
|
8
|
-
#require 'rspec/interop/test'
|
9
|
-
|
10
|
-
set :environment, :test
|
11
|
-
Test::Unit::TestCase.send :include, Rack::Test::Methods
|
12
|
-
|
13
|
-
def app
|
14
|
-
Sinatra::Application
|
15
|
-
end
|
16
|
-
|
17
|
-
RSpec.configure do |conf| #from Jason
|
18
|
-
conf.include Rack::Test::Methods
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "v1 service: " do
|
22
|
-
before(:each) do
|
23
|
-
User.delete_all
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "get /api/v1/users" do
|
27
|
-
before do
|
28
|
-
User.create(name: "dwayne", email: "dwaynemac@gmail.com", password: "asdf", bio: "test")
|
29
|
-
User.create(name: "2dwayne", email: "dw2aynemac@gmail.com", password: "a2sdf", bio: "te2st")
|
30
|
-
get '/api/v1/users'
|
31
|
-
end
|
32
|
-
it { should respond_with :success }
|
33
|
-
it "should send collection" do
|
34
|
-
ActiveSupport::JSON.decode(last_response.body)['collection'].should_not be_nil
|
35
|
-
end
|
36
|
-
it "should send total items number" do
|
37
|
-
AcriveSupport::JSON.decode(last_response.body)['total'].should == 2
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "RESTfull GET (on /api/v1/users/:id)" do
|
42
|
-
context "for existing user" do
|
43
|
-
before(:each) do
|
44
|
-
User.create(
|
45
|
-
:name => "paul",
|
46
|
-
:email => "paul@pauldix.net",
|
47
|
-
:password => "strongpass",
|
48
|
-
:bio => "rubyist")
|
49
|
-
get '/api/v1/users/paul'
|
50
|
-
end
|
51
|
-
it "should respond with 200" do
|
52
|
-
last_response.status.should == 200
|
53
|
-
end
|
54
|
-
it "should return user with id paul" do
|
55
|
-
attributes = JSON.parse(last_response.body)["user"]
|
56
|
-
attributes["name"].should == "paul"
|
57
|
-
end
|
58
|
-
it "should return users email" do
|
59
|
-
attributes = JSON.parse(last_response.body)["user"]
|
60
|
-
attributes["email"].should == "paul@pauldix.net"
|
61
|
-
end
|
62
|
-
it "should not return a user's password" do
|
63
|
-
attributes = JSON.parse(last_response.body)["user"]
|
64
|
-
attributes.should_not have_key("password")
|
65
|
-
end
|
66
|
-
it "should return user's bio" do
|
67
|
-
attributes = JSON.parse(last_response.body)["user"]
|
68
|
-
attributes["bio"].should == "rubyist"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
context "for un-existing user" do
|
72
|
-
before do
|
73
|
-
get '/api/v1/users/foo'
|
74
|
-
end
|
75
|
-
it "should return not found" do
|
76
|
-
last_response.status.should == 404
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
describe "RESTfull POST (on /api/v1/users) with attributes under resource name" do
|
82
|
-
it "should create a user" do
|
83
|
-
expect{post '/api/v1/users', :user => { :name => "trotter",
|
84
|
-
:email => "no spam",
|
85
|
-
:password => "whatever",
|
86
|
-
:bio => "southern belle" }}.to change{User.count}.by 1
|
87
|
-
last_response.should be_ok
|
88
|
-
|
89
|
-
get '/api/v1/users/trotter'
|
90
|
-
attributes = JSON.parse(last_response.body)["user"]
|
91
|
-
attributes["name"].should == "trotter"
|
92
|
-
attributes["email"].should == "no spam"
|
93
|
-
attributes["bio"].should == "southern belle"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe "RESTfull PUT (on /api/v1/users/:id) with params under resourcename" do
|
98
|
-
it "should update a user" do
|
99
|
-
User.create(
|
100
|
-
:name => "bryan",
|
101
|
-
:email => "no spam",
|
102
|
-
:password => "whatever",
|
103
|
-
:bio => "rspec master")
|
104
|
-
|
105
|
-
put '/api/v1/users/bryan', :user => {:bio => "testing freak"}
|
106
|
-
|
107
|
-
last_response.status.should == 200
|
108
|
-
|
109
|
-
get '/api/v1/users/bryan'
|
110
|
-
attributes = JSON.parse(last_response.body)["user"]
|
111
|
-
attributes["bio"].should == "testing freak"
|
112
|
-
end
|
113
|
-
context "when called with unexisting id" do
|
114
|
-
before do
|
115
|
-
put "/api/v1/users/no-existo"
|
116
|
-
end
|
117
|
-
it "should return not found" do
|
118
|
-
last_response.status.should == 404
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe "RESTfull DELETE (on /api/v1/users/:id)" do
|
124
|
-
it "should delete a user" do
|
125
|
-
User.create(
|
126
|
-
:name => "francis",
|
127
|
-
:email => "no spam",
|
128
|
-
:password => "whatever",
|
129
|
-
:bio => "williamsburg hipster")
|
130
|
-
|
131
|
-
expect{delete '/api/v1/users/francis'}.to change{User.count}.by -1
|
132
|
-
|
133
|
-
last_response.should be_ok
|
134
|
-
|
135
|
-
get '/api/v1/users/francis'
|
136
|
-
last_response.status.should == 404
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|