logical_model 0.2.8 → 0.2.9
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/Gemfile +17 -2
- data/Gemfile.lock +38 -1
- data/Guardfile +14 -0
- data/Rakefile +23 -0
- data/VERSION +1 -1
- data/client.rb +68 -0
- data/config.ru +0 -0
- data/config/application.rb +33 -0
- data/config/database.yml +11 -0
- data/db/development.sqlite3 +0 -0
- data/db/migrate/001_create_users.rb +15 -0
- data/db/test.sqlite3 +0 -0
- data/lib/logical_model.rb +12 -17
- data/logical_model.gemspec +39 -5
- data/logs/development.log +144 -0
- data/models/user.rb +7 -0
- data/service.rb +79 -0
- data/spec/client_spec.rb +130 -0
- data/spec/service_spec.rb +124 -0
- metadata +110 -20
data/Gemfile
CHANGED
@@ -6,9 +6,24 @@ gem "activesupport"
|
|
6
6
|
gem "typhoeus", "~> 0.2.4"
|
7
7
|
gem "kaminari"
|
8
8
|
|
9
|
-
group :development do
|
9
|
+
group :development, :test do
|
10
10
|
gem "shoulda"
|
11
|
-
gem "bundler", "~> 1.0.
|
11
|
+
gem "bundler", "~> 1.0.10"
|
12
12
|
gem "jeweler", "~> 1.6.4"
|
13
13
|
gem "rcov"
|
14
|
+
gem "sqlite3-ruby"
|
15
|
+
gem "sinatra", " ~> 1.2.6"
|
16
|
+
gem "json"
|
17
|
+
|
18
|
+
gem "rspec-rails"
|
19
|
+
|
20
|
+
gem "guard-rspec"
|
21
|
+
|
22
|
+
# guard notifications on Mac OS X
|
23
|
+
gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
|
24
|
+
gem 'growl', :require => false if RUBY_PLATFORM =~ /darwin/i
|
25
|
+
|
26
|
+
# guard notifications on Linux
|
27
|
+
gem 'rb-inotify', :require => false if RUBY_PLATFORM =~ /linux/i
|
28
|
+
gem 'libnotify', :require => false if RUBY_PLATFORM =~ /linux/i
|
14
29
|
end
|
data/Gemfile.lock
CHANGED
@@ -30,16 +30,24 @@ GEM
|
|
30
30
|
activesupport (3.0.7)
|
31
31
|
arel (2.0.10)
|
32
32
|
builder (2.1.2)
|
33
|
+
diff-lcs (1.1.3)
|
33
34
|
erubis (2.6.6)
|
34
35
|
abstract (>= 1.0.0)
|
36
|
+
ffi (1.0.9)
|
35
37
|
git (1.2.5)
|
38
|
+
guard (0.8.4)
|
39
|
+
thor (~> 0.14.6)
|
40
|
+
guard-rspec (0.5.0)
|
41
|
+
guard (>= 0.8.4)
|
36
42
|
i18n (0.5.0)
|
37
43
|
jeweler (1.6.4)
|
38
44
|
bundler (~> 1.0)
|
39
45
|
git (>= 1.2.5)
|
40
46
|
rake
|
47
|
+
json (1.5.3)
|
41
48
|
kaminari (0.12.4)
|
42
49
|
rails (>= 3.0.0)
|
50
|
+
libnotify (0.5.7)
|
43
51
|
mail (2.2.19)
|
44
52
|
activesupport (>= 2.3.6)
|
45
53
|
i18n (>= 0.4.0)
|
@@ -66,9 +74,31 @@ GEM
|
|
66
74
|
rake (>= 0.8.7)
|
67
75
|
thor (~> 0.14.4)
|
68
76
|
rake (0.9.2)
|
77
|
+
rb-inotify (0.8.8)
|
78
|
+
ffi (>= 0.5.0)
|
69
79
|
rcov (0.9.9)
|
80
|
+
rspec (2.6.0)
|
81
|
+
rspec-core (~> 2.6.0)
|
82
|
+
rspec-expectations (~> 2.6.0)
|
83
|
+
rspec-mocks (~> 2.6.0)
|
84
|
+
rspec-core (2.6.4)
|
85
|
+
rspec-expectations (2.6.0)
|
86
|
+
diff-lcs (~> 1.1.2)
|
87
|
+
rspec-mocks (2.6.0)
|
88
|
+
rspec-rails (2.6.1)
|
89
|
+
actionpack (~> 3.0)
|
90
|
+
activesupport (~> 3.0)
|
91
|
+
railties (~> 3.0)
|
92
|
+
rspec (~> 2.6.0)
|
70
93
|
shoulda (2.11.3)
|
94
|
+
sinatra (1.2.7)
|
95
|
+
rack (~> 1.1)
|
96
|
+
tilt (>= 1.2.2, < 2.0)
|
97
|
+
sqlite3 (1.3.4)
|
98
|
+
sqlite3-ruby (1.3.3)
|
99
|
+
sqlite3 (>= 1.3.3)
|
71
100
|
thor (0.14.6)
|
101
|
+
tilt (1.3.3)
|
72
102
|
treetop (1.4.10)
|
73
103
|
polyglot
|
74
104
|
polyglot (>= 0.3.1)
|
@@ -83,9 +113,16 @@ PLATFORMS
|
|
83
113
|
DEPENDENCIES
|
84
114
|
activemodel
|
85
115
|
activesupport
|
86
|
-
bundler (~> 1.0.
|
116
|
+
bundler (~> 1.0.10)
|
117
|
+
guard-rspec
|
87
118
|
jeweler (~> 1.6.4)
|
119
|
+
json
|
88
120
|
kaminari
|
121
|
+
libnotify
|
122
|
+
rb-inotify
|
89
123
|
rcov
|
124
|
+
rspec-rails
|
90
125
|
shoulda
|
126
|
+
sinatra (~> 1.2.6)
|
127
|
+
sqlite3-ruby
|
91
128
|
typhoeus (~> 0.2.4)
|
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
guard 'rspec', :version => 2 do
|
4
|
+
watch(%r{^spec/.+_spec\.rb})
|
5
|
+
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
6
|
+
watch('spec/spec_helper.rb') { "spec" }
|
7
|
+
watch('spec/blueprints.rb') { "spec" }
|
8
|
+
watch('config/routes.rb') { "spec/routing" }
|
9
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
10
|
+
watch(%r{^spec/.+_spec\.rb})
|
11
|
+
watch(%r{^app/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
+
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
13
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
14
|
+
end
|
data/Rakefile
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
+
gem 'activerecord', "=3.0.7"
|
5
|
+
require 'active_record'
|
6
|
+
require 'logger'
|
4
7
|
require 'bundler'
|
8
|
+
gem 'sqlite3'
|
9
|
+
require 'sqlite3'
|
10
|
+
require 'yaml'
|
11
|
+
#require 'active_support'
|
12
|
+
|
5
13
|
begin
|
6
14
|
Bundler.setup(:default, :development)
|
7
15
|
rescue Bundler::BundlerError => e
|
@@ -51,3 +59,18 @@ Rake::RDocTask.new do |rdoc|
|
|
51
59
|
rdoc.rdoc_files.include('README*')
|
52
60
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
61
|
end
|
62
|
+
|
63
|
+
desc "Load the environment"
|
64
|
+
task :environment do
|
65
|
+
env = ENV["SINATRA_ENV"] || "development"
|
66
|
+
databases = YAML.load_file("config/database.yml")
|
67
|
+
ActiveRecord::Base.establish_connection(databases[env])
|
68
|
+
end
|
69
|
+
namespace :db do
|
70
|
+
desc "Migrate the database"
|
71
|
+
task(:migrate => :environment) do
|
72
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
73
|
+
ActiveRecord::Migration.verbose = true
|
74
|
+
ActiveRecord::Migrator.migrate("db/migrate")
|
75
|
+
end
|
76
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.9
|
data/client.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'typhoeus'
|
4
|
+
require 'json'
|
5
|
+
require 'lib/logical_model'
|
6
|
+
|
7
|
+
class User < LogicalModel
|
8
|
+
#class << self; attr_accessor :base_uri end
|
9
|
+
|
10
|
+
#self.hydra = Typhoeus::Hydra.new
|
11
|
+
self.use_ssl = false #(Rails.env=="production")
|
12
|
+
|
13
|
+
self.resource_path = "/api/v1/users"
|
14
|
+
self.attribute_keys = [:name, :email, :password, :bio]
|
15
|
+
self.use_api_key = false
|
16
|
+
#self.api_key_name = "token"
|
17
|
+
#self.api_key = "8c330b5d70f86ebfa6497c901b299b79afc6d68c60df6df0bda0180d3777eb4a5528924ac96cf58a25e599b4110da3c4b690fa29263714ec6604b6cb2d943656"
|
18
|
+
self.host = "localhost:3000"
|
19
|
+
self.log_path = "logs/development.log"
|
20
|
+
|
21
|
+
TIMEOUT = 5500 # miliseconds
|
22
|
+
PER_PAGE = 9999
|
23
|
+
|
24
|
+
# def self.find_by_name(name)
|
25
|
+
# response = Typhoeus::Request.get("#{base_uri}/api/v1/users/#{name}")
|
26
|
+
# if response.code == 200
|
27
|
+
# JSON.parse(response.body)["user"]
|
28
|
+
# elsif response.code == 404
|
29
|
+
# nil
|
30
|
+
# else
|
31
|
+
# raise response.body
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
|
35
|
+
# def self.create(attributes = {})
|
36
|
+
# response = Typhoeus::Request.post("#{base_uri}/api/v1/users", :body => attributes.to_json)
|
37
|
+
# if response.success?
|
38
|
+
# JSON.parse(response.body)["user"]
|
39
|
+
# else
|
40
|
+
# raise response.body
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
|
44
|
+
# def self.update(name, attributes)
|
45
|
+
# response = Typhoeus::Request.put("#{base_uri}/api/v1/users/#{name}", :body => attributes.to_json)
|
46
|
+
# if response.success?
|
47
|
+
# JSON.parse(response.body)["user"]
|
48
|
+
# else
|
49
|
+
# raise response.body
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
|
53
|
+
# def self.destroy(name)
|
54
|
+
# response = Typhoeus::Request.delete("#{base_uri}/api/v1/users/#{name}")
|
55
|
+
# response.success?
|
56
|
+
# end
|
57
|
+
|
58
|
+
# def self.login(name, password)
|
59
|
+
# response = Typhoeus::Request.post("#{base_uri}/api/v1/users/#{name}/sessions", :body => {:password => password}.to_json)
|
60
|
+
# if response.success?
|
61
|
+
# JSON.parse(response.body)["user"]
|
62
|
+
# elsif response.code == 400
|
63
|
+
# nil
|
64
|
+
# else
|
65
|
+
# raise response.body
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
end
|
data/config.ru
ADDED
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rails"
|
2
|
+
gem 'sqlite3-ruby'
|
3
|
+
# %w(
|
4
|
+
# active_record
|
5
|
+
# action_controller
|
6
|
+
# action_mailer
|
7
|
+
# ).each do |framework|
|
8
|
+
# begin
|
9
|
+
# require "#{framework}/railtie"
|
10
|
+
# rescue LoadError
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# [
|
15
|
+
# Rack::Sendfile,
|
16
|
+
# ActionDispatch::Flash,
|
17
|
+
# ActionDispatch::Session::CookieStore,
|
18
|
+
# ActionDispatch::Cookies,
|
19
|
+
# ActionDispatch::BestStandardsSupport,
|
20
|
+
# Rack::MethodOverride,
|
21
|
+
# ActionDispatch::ShowExceptions,
|
22
|
+
# ActionDispatch::Static,
|
23
|
+
# ActionDispatch::RemoteIp,
|
24
|
+
# ActionDispatch::ParamsParser,
|
25
|
+
# Rack::Lock,
|
26
|
+
# ActionDispatch::Head
|
27
|
+
# ].each do |klass|
|
28
|
+
# config.middleware.delete klass
|
29
|
+
# end
|
30
|
+
|
31
|
+
# config/environments/production.rb
|
32
|
+
config.middleware.delete
|
33
|
+
ActiveRecord::ConnectionAdapters::ConnectionManagement
|
data/config/database.yml
ADDED
Binary file
|
data/db/test.sqlite3
ADDED
Binary file
|
data/lib/logical_model.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'timeout'
|
2
2
|
require 'active_model'
|
3
3
|
require 'typhoeus'
|
4
|
-
require 'active_support' # todo migrate to yajl
|
4
|
+
require 'active_support/all' # todo migrate to yajl
|
5
5
|
require 'logger'
|
6
6
|
require 'kaminari'
|
7
7
|
|
@@ -109,11 +109,11 @@ class LogicalModel
|
|
109
109
|
|
110
110
|
unless self.class.has_many_keys.blank?
|
111
111
|
self.class.has_many_keys.inject(attrs) do |result,key|
|
112
|
-
result[key] = send(key).map {|a| a.attributes}
|
112
|
+
result["#{key}_attributes"] = send(key).map {|a| a.attributes}
|
113
113
|
result
|
114
114
|
end
|
115
115
|
end
|
116
|
-
attrs
|
116
|
+
attrs.reject {|key, value| key == "_id" && value.blank?}
|
117
117
|
end
|
118
118
|
|
119
119
|
def attributes=(attrs)
|
@@ -152,11 +152,7 @@ class LogicalModel
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def self.logger
|
155
|
-
|
156
|
-
Rails.logger
|
157
|
-
else
|
158
|
-
Logger.new(self.log_path)
|
159
|
-
end
|
155
|
+
Logger.new(self.log_path || "log/logical_model.log")
|
160
156
|
end
|
161
157
|
|
162
158
|
# if needed willmerge api_key into given hash
|
@@ -174,6 +170,8 @@ class LogicalModel
|
|
174
170
|
# They assume we are using a RESTfull API.
|
175
171
|
# for get, put, delete :id is expected
|
176
172
|
# for post, put attributes are excepted under class_name directly. eg. put( {:id => 1, :class_name => {:attr => "new value for attr"}} )
|
173
|
+
#
|
174
|
+
# On error (400) a "errors" is expected.
|
177
175
|
# ============================================================================================================
|
178
176
|
|
179
177
|
# Asynchronic Pagination
|
@@ -313,20 +311,17 @@ class LogicalModel
|
|
313
311
|
#
|
314
312
|
# Usage:
|
315
313
|
# @person.update(params[:person])
|
316
|
-
def update(
|
317
|
-
self.attributes = attributes
|
314
|
+
def update(attribute_params)
|
318
315
|
|
319
|
-
|
316
|
+
self.attributes = attribute_params[self.json_root]
|
320
317
|
|
321
|
-
|
322
|
-
sending_params.delete(:id)
|
323
|
-
|
324
|
-
params = { self.json_root => sending_params }
|
325
|
-
params = self.class.merge_key(params)
|
318
|
+
return false unless valid?
|
326
319
|
|
320
|
+
params = self.class.merge_key(attribute_params)
|
327
321
|
|
328
322
|
e = Typhoeus::Easy.new
|
329
|
-
|
323
|
+
|
324
|
+
e.url = self.class.resource_uri(_id)
|
330
325
|
e.method = :put
|
331
326
|
e.params = params
|
332
327
|
|
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.9"
|
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 = "2011-
|
12
|
+
s.date = "2011-11-24"
|
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 = [
|
@@ -20,12 +20,25 @@ Gem::Specification.new do |s|
|
|
20
20
|
".document",
|
21
21
|
"Gemfile",
|
22
22
|
"Gemfile.lock",
|
23
|
+
"Guardfile",
|
23
24
|
"LICENSE.txt",
|
24
25
|
"README.rdoc",
|
25
26
|
"Rakefile",
|
26
27
|
"VERSION",
|
28
|
+
"client.rb",
|
29
|
+
"config.ru",
|
30
|
+
"config/application.rb",
|
31
|
+
"config/database.yml",
|
32
|
+
"db/development.sqlite3",
|
33
|
+
"db/migrate/001_create_users.rb",
|
34
|
+
"db/test.sqlite3",
|
27
35
|
"lib/logical_model.rb",
|
28
36
|
"logical_model.gemspec",
|
37
|
+
"logs/development.log",
|
38
|
+
"models/user.rb",
|
39
|
+
"service.rb",
|
40
|
+
"spec/client_spec.rb",
|
41
|
+
"spec/service_spec.rb",
|
29
42
|
"test/helper.rb",
|
30
43
|
"test/test_logical_model.rb",
|
31
44
|
"test/typhoeus_mocks.rb"
|
@@ -45,18 +58,32 @@ Gem::Specification.new do |s|
|
|
45
58
|
s.add_runtime_dependency(%q<typhoeus>, ["~> 0.2.4"])
|
46
59
|
s.add_runtime_dependency(%q<kaminari>, [">= 0"])
|
47
60
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
48
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.
|
61
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.10"])
|
49
62
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
50
63
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
64
|
+
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
65
|
+
s.add_development_dependency(%q<sinatra>, ["~> 1.2.6"])
|
66
|
+
s.add_development_dependency(%q<json>, [">= 0"])
|
67
|
+
s.add_development_dependency(%q<rspec-rails>, [">= 0"])
|
68
|
+
s.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
69
|
+
s.add_development_dependency(%q<rb-inotify>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<libnotify>, [">= 0"])
|
51
71
|
else
|
52
72
|
s.add_dependency(%q<activemodel>, [">= 0"])
|
53
73
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
54
74
|
s.add_dependency(%q<typhoeus>, ["~> 0.2.4"])
|
55
75
|
s.add_dependency(%q<kaminari>, [">= 0"])
|
56
76
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
57
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.
|
77
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.10"])
|
58
78
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
59
79
|
s.add_dependency(%q<rcov>, [">= 0"])
|
80
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
81
|
+
s.add_dependency(%q<sinatra>, ["~> 1.2.6"])
|
82
|
+
s.add_dependency(%q<json>, [">= 0"])
|
83
|
+
s.add_dependency(%q<rspec-rails>, [">= 0"])
|
84
|
+
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
85
|
+
s.add_dependency(%q<rb-inotify>, [">= 0"])
|
86
|
+
s.add_dependency(%q<libnotify>, [">= 0"])
|
60
87
|
end
|
61
88
|
else
|
62
89
|
s.add_dependency(%q<activemodel>, [">= 0"])
|
@@ -64,9 +91,16 @@ Gem::Specification.new do |s|
|
|
64
91
|
s.add_dependency(%q<typhoeus>, ["~> 0.2.4"])
|
65
92
|
s.add_dependency(%q<kaminari>, [">= 0"])
|
66
93
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
67
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.
|
94
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.10"])
|
68
95
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
69
96
|
s.add_dependency(%q<rcov>, [">= 0"])
|
97
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
98
|
+
s.add_dependency(%q<sinatra>, ["~> 1.2.6"])
|
99
|
+
s.add_dependency(%q<json>, [">= 0"])
|
100
|
+
s.add_dependency(%q<rspec-rails>, [">= 0"])
|
101
|
+
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
102
|
+
s.add_dependency(%q<rb-inotify>, [">= 0"])
|
103
|
+
s.add_dependency(%q<libnotify>, [">= 0"])
|
70
104
|
end
|
71
105
|
end
|
72
106
|
|
@@ -0,0 +1,144 @@
|
|
1
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.004691s FAILED:
|
2
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
3
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.00462s FAILED:
|
4
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
5
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.004597s FAILED:
|
6
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
7
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.00463s FAILED:
|
8
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
9
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.004576s FAILED:
|
10
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
11
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.00471s FAILED:
|
12
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
13
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.004598s FAILED:
|
14
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
15
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.021388s FAILED:
|
16
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
17
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.004659s FAILED:
|
18
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
19
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.005105s FAILED:
|
20
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
21
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.004775s FAILED:
|
22
|
+
LogicalModel Log RESPONSE: "745: unexpected token at 'user%5Bbio%5D=rubyist&user%5Bemail%5D=paul%40pauldix.net&user%5Bname%5D=paul&user%5Bpassword%5D=strongpass'"
|
23
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.145529s FAILED:
|
24
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
25
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.0216s FAILED:
|
26
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
27
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.018887s FAILED:
|
28
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
29
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.127662s FAILED:
|
30
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
31
|
+
LogicalModel Log: 0 https://localhost:3000/api/v1/users in 0.044237s FAILED: error
|
32
|
+
LogicalModel Log RESPONSE:
|
33
|
+
LogicalModel Log: 0 https://localhost:3000/api/v1/users in 0.000878s FAILED: error
|
34
|
+
LogicalModel Log RESPONSE:
|
35
|
+
LogicalModel Log: 0 https://localhost:3000/api/v1/users in 0.001611s FAILED: error
|
36
|
+
LogicalModel Log RESPONSE:
|
37
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.233063s FAILED:
|
38
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
39
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.157818s FAILED:
|
40
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
41
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.067717s FAILED:
|
42
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
43
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.011295s FAILED:
|
44
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
45
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.019577s FAILED:
|
46
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
47
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.047789s FAILED:
|
48
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
49
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.021546s FAILED:
|
50
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
51
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.049893s FAILED:
|
52
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
53
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 5.021058s FAILED:
|
54
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
55
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.047952s FAILED:
|
56
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
57
|
+
LogicalModel Log: 0 http://localhost:3000/api/v1/users in 0.001093s FAILED: error
|
58
|
+
LogicalModel Log RESPONSE:
|
59
|
+
LogicalModel Log: 0 http://localhost:3000/api/v1/users in 0.000394s FAILED: error
|
60
|
+
LogicalModel Log RESPONSE:
|
61
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.136481s FAILED:
|
62
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
63
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.050792s FAILED:
|
64
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
65
|
+
LogicalModel Log: 200 http://localhost:3000/api/v1/users in 0.141034s FAILED:
|
66
|
+
LogicalModel Log RESPONSE: {"user":{"name":"bryan","created_at":"2011-11-03T14:37:44-03:00","updated_at":"2011-11-03T14:37:44-03:00","id":24,"bio":"another rubyist","email":"bryan@pauldix.net"}}
|
67
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.050582s FAILED:
|
68
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
69
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.035647s FAILED:
|
70
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
71
|
+
LogicalModel Log: 200 http://localhost:3000/api/v1/users in 0.201605s FAILED:
|
72
|
+
LogicalModel Log RESPONSE: {"user":{"name":"bryan","created_at":"2011-11-03T14:39:18-03:00","updated_at":"2011-11-03T14:39:18-03:00","id":26,"bio":"another rubyist","email":"bryan@pauldix.net"}}
|
73
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.038625s FAILED:
|
74
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
75
|
+
LogicalModel Log: 200 http://localhost:3000/api/v1/users in 0.191726s FAILED:
|
76
|
+
LogicalModel Log RESPONSE: {"user":{"name":"bryan","created_at":"2011-11-03T14:41:10-03:00","updated_at":"2011-11-03T14:41:10-03:00","id":28,"bio":"another rubyist","email":"bryan@pauldix.net"}}
|
77
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.018539s FAILED:
|
78
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
79
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.049956s FAILED:
|
80
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
81
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.018731s FAILED:
|
82
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
83
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.048094s FAILED:
|
84
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
85
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.02157s FAILED:
|
86
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
87
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.051048s FAILED:
|
88
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
89
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 5.02165s FAILED:
|
90
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
91
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.050986s FAILED:
|
92
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
93
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.013325s FAILED:
|
94
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
95
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.11644s FAILED:
|
96
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
97
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.014655s FAILED:
|
98
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
99
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.050812s FAILED:
|
100
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
101
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.015264s FAILED:
|
102
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
103
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.048666s FAILED:
|
104
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
105
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 5.023148s FAILED:
|
106
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
107
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.047819s FAILED:
|
108
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
109
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.014254s FAILED:
|
110
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
111
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.048866s FAILED:
|
112
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
113
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.01741s FAILED:
|
114
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
115
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.051693s FAILED:
|
116
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
117
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.035599s FAILED:
|
118
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
119
|
+
LogicalModel Log: 200 http://localhost:3000/api/v1/users in 0.187376s FAILED:
|
120
|
+
LogicalModel Log RESPONSE: {"user":{"name":"bryan","created_at":"2011-11-03T14:58:14-03:00","updated_at":"2011-11-03T14:58:14-03:00","id":30,"bio":"another rubyist","email":"bryan@pauldix.net"}}
|
121
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.02095s FAILED:
|
122
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
123
|
+
LogicalModel Log: 0 https://localhost:3000/api/v1/users in 0.000257s FAILED: error
|
124
|
+
LogicalModel Log RESPONSE:
|
125
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.023091s FAILED:
|
126
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
127
|
+
LogicalModel Log: 0 https://localhost:3000/api/v1/users in 0.000932s FAILED: error
|
128
|
+
LogicalModel Log RESPONSE:
|
129
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.019534s FAILED:
|
130
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
131
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 5.0228s FAILED:
|
132
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
133
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.012712s FAILED:
|
134
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
135
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.050448s FAILED:
|
136
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
137
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.058483s FAILED:
|
138
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
139
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.01427s FAILED:
|
140
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
141
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.051569s FAILED:
|
142
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
143
|
+
LogicalModel Log: 400 http://localhost:3000/api/v1/users in 0.116518s FAILED:
|
144
|
+
LogicalModel Log RESPONSE: {"errors":{"name":["has already been taken"],"email":["has already been taken"]}}
|
data/models/user.rb
ADDED
data/service.rb
ADDED
@@ -0,0 +1,79 @@
|
|
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
|
+
|
21
|
+
|
22
|
+
# Simple RESTfull Service
|
23
|
+
# for LogicalModel Testing
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
# HTTP entry points
|
28
|
+
# get a user by name
|
29
|
+
get '/api/v1/users/:name' do
|
30
|
+
user = User.find_by_name(params[:name])
|
31
|
+
if user
|
32
|
+
user.to_json
|
33
|
+
else
|
34
|
+
error 404, {:error => "user not found"}.to_json
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# create a new user
|
39
|
+
post '/api/v1/users' do
|
40
|
+
begin
|
41
|
+
user = User.new(params[:user])
|
42
|
+
if user.save
|
43
|
+
user.to_json
|
44
|
+
else
|
45
|
+
error 400, {:errors => user.errors}.to_json
|
46
|
+
end
|
47
|
+
rescue => e
|
48
|
+
error 500, {:errors => e.message}.to_json
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# update an existing user
|
53
|
+
put '/api/v1/users/:name' do
|
54
|
+
user = User.find_by_name(params[:name])
|
55
|
+
if user
|
56
|
+
begin
|
57
|
+
if user.update_attributes(params[:user])
|
58
|
+
user.to_json
|
59
|
+
else
|
60
|
+
error 400, user.errors.to_json
|
61
|
+
end
|
62
|
+
rescue => e
|
63
|
+
error 400, e.message.to_json
|
64
|
+
end
|
65
|
+
else
|
66
|
+
error 404, {:error => "user not found"}.to_json
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# destroy an existing user
|
71
|
+
delete '/api/v1/users/:name' do
|
72
|
+
user = User.find_by_name(params[:name])
|
73
|
+
if user
|
74
|
+
user.destroy
|
75
|
+
user.to_json
|
76
|
+
else
|
77
|
+
error 404, {:error => "user not found"}.to_json
|
78
|
+
end
|
79
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../client'
|
2
|
+
|
3
|
+
# NOTE: to run these specs you must have the service running locally. Do like this:
|
4
|
+
# ruby service.rb -p 3000 -e test
|
5
|
+
|
6
|
+
# Also note that after a single run of the tests the server must be restarted to reset
|
7
|
+
# the database. We could change this by deleting all users in the test setup.
|
8
|
+
|
9
|
+
# TODO testing in these specs should be focus on LogicalModel behaviour.
|
10
|
+
describe "LogicalModel User client" do
|
11
|
+
before(:each) do
|
12
|
+
# User.destroy_all
|
13
|
+
# User.base_uri = "http://localhost:3000"
|
14
|
+
|
15
|
+
# @user = User.find_by_name(:name => "paul")
|
16
|
+
# User.delete(@user.id)
|
17
|
+
# User.destroy("trotter")
|
18
|
+
|
19
|
+
# @user = User.new({:name => "bryan",
|
20
|
+
# :email => "bryan@spamtown.usa",
|
21
|
+
# :password => "strongpass",
|
22
|
+
# :bio => "rubyist"})
|
23
|
+
# @user.create
|
24
|
+
# User.create(
|
25
|
+
# :name => "paul",
|
26
|
+
# :email => "paul@pauldix.net",
|
27
|
+
# :password => "strongpass",
|
28
|
+
# :bio => "rubyist")
|
29
|
+
# User.create(
|
30
|
+
# :name => "bryan",
|
31
|
+
# :email => "bryan@spamtown.usa",
|
32
|
+
# :password => "strongpass",
|
33
|
+
# :bio => "rubyist")
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#create" do
|
37
|
+
context "with valid attributes" do
|
38
|
+
before(:each) do
|
39
|
+
@user = User.new({:name => "paul",
|
40
|
+
:email => "paul@pauldix.net",
|
41
|
+
:password => "strongpass",
|
42
|
+
:bio => "rubyist"})
|
43
|
+
@user.create
|
44
|
+
end
|
45
|
+
it "should create a user" do
|
46
|
+
@user.should_not be_nil
|
47
|
+
end
|
48
|
+
it "should set an id" do
|
49
|
+
@user.id.should_not be_nil
|
50
|
+
end
|
51
|
+
it "should hace the same attributes as passed" do
|
52
|
+
@user.name.should == "paul"
|
53
|
+
@user.email == "paul@pauldix.net"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# describe "#find" do
|
59
|
+
# it "should GET resource by id" do
|
60
|
+
# pending "on it to work"
|
61
|
+
#user = User.find(@user.id)
|
62
|
+
#user["name"].should == "paul"
|
63
|
+
#user["email"].should == "paul@pauldix.net"
|
64
|
+
#user["bio"].should == "rubyist"
|
65
|
+
# end
|
66
|
+
# it "should return nil for a user not found" do
|
67
|
+
# pending "on it to work"
|
68
|
+
#User.find_by_name("gosling").should be_nil
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
|
72
|
+
# describe "#paginate" do
|
73
|
+
|
74
|
+
# end
|
75
|
+
|
76
|
+
# describe "#update" do
|
77
|
+
|
78
|
+
# end
|
79
|
+
|
80
|
+
describe "#https" do
|
81
|
+
context "when use_ssl is tue" do
|
82
|
+
before(:each) do
|
83
|
+
class User < LogicalModel;self.use_ssl = true;end
|
84
|
+
end
|
85
|
+
it "should use https://" do
|
86
|
+
User.resource_uri.should match /https/
|
87
|
+
end
|
88
|
+
end
|
89
|
+
context "when use_ssl is false" do
|
90
|
+
before(:each) do
|
91
|
+
class User < LogicalModel;self.use_ssl = false;end
|
92
|
+
end
|
93
|
+
it "should use http://" do
|
94
|
+
User.resource_uri.should match /http/
|
95
|
+
User.resource_uri.should_not match /https/
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
# it "should create a user" do
|
103
|
+
# user = User.create({
|
104
|
+
# :name => "trotter",
|
105
|
+
# :email => "trotter@spamtown.usa",
|
106
|
+
# :password => "whatev"})
|
107
|
+
# User.find_by_name("trotter")["email"].should == "trotter@spamtown.usa"
|
108
|
+
# end
|
109
|
+
|
110
|
+
# it "should update a user" do
|
111
|
+
# user = User.update("paul", :bio => "rubyist and author")
|
112
|
+
# user["name"].should == "paul"
|
113
|
+
# user["bio"].should == "rubyist and author"
|
114
|
+
# User.find_by_name("paul")["bio"] == "rubyist and author"
|
115
|
+
# end
|
116
|
+
|
117
|
+
# it "should destroy a user" do
|
118
|
+
# User.destroy("bryan").should == true
|
119
|
+
# User.find_by_name("bryan").should be_nil
|
120
|
+
# end
|
121
|
+
|
122
|
+
# it "should verify login credentials" do
|
123
|
+
# user = User.login("paul", "strongpass")
|
124
|
+
# user["name"].should == "paul"
|
125
|
+
# end
|
126
|
+
|
127
|
+
# it "should return nil with invalid credentials" do
|
128
|
+
# User.login("paul", "wrongpassword").should be_nil
|
129
|
+
# end
|
130
|
+
end
|
@@ -0,0 +1,124 @@
|
|
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 "RESTfull GET (on /api/v1/users/:id)" do
|
27
|
+
context "for existing user" do
|
28
|
+
before(:each) do
|
29
|
+
User.create(
|
30
|
+
:name => "paul",
|
31
|
+
:email => "paul@pauldix.net",
|
32
|
+
:password => "strongpass",
|
33
|
+
:bio => "rubyist")
|
34
|
+
get '/api/v1/users/paul'
|
35
|
+
end
|
36
|
+
it "should respond with 200" do
|
37
|
+
last_response.status.should == 200
|
38
|
+
end
|
39
|
+
it "should return user with id paul" do
|
40
|
+
attributes = JSON.parse(last_response.body)["user"]
|
41
|
+
attributes["name"].should == "paul"
|
42
|
+
end
|
43
|
+
it "should return users email" do
|
44
|
+
attributes = JSON.parse(last_response.body)["user"]
|
45
|
+
attributes["email"].should == "paul@pauldix.net"
|
46
|
+
end
|
47
|
+
it "should not return a user's password" do
|
48
|
+
attributes = JSON.parse(last_response.body)["user"]
|
49
|
+
attributes.should_not have_key("password")
|
50
|
+
end
|
51
|
+
it "should return user's bio" do
|
52
|
+
attributes = JSON.parse(last_response.body)["user"]
|
53
|
+
attributes["bio"].should == "rubyist"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
context "for un-existing user" do
|
57
|
+
before do
|
58
|
+
get '/api/v1/users/foo'
|
59
|
+
end
|
60
|
+
it "should return not found" do
|
61
|
+
last_response.status.should == 404
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "RESTfull POST (on /api/v1/users) with attributes under resource name" do
|
67
|
+
it "should create a user" do
|
68
|
+
expect{post '/api/v1/users', :user => { :name => "trotter",
|
69
|
+
:email => "no spam",
|
70
|
+
:password => "whatever",
|
71
|
+
:bio => "southern belle" }}.to change{User.count}.by 1
|
72
|
+
last_response.should be_ok
|
73
|
+
|
74
|
+
get '/api/v1/users/trotter'
|
75
|
+
attributes = JSON.parse(last_response.body)["user"]
|
76
|
+
attributes["name"].should == "trotter"
|
77
|
+
attributes["email"].should == "no spam"
|
78
|
+
attributes["bio"].should == "southern belle"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "RESTfull PUT (on /api/v1/users/:id) with params under resourcename" do
|
83
|
+
it "should update a user" do
|
84
|
+
User.create(
|
85
|
+
:name => "bryan",
|
86
|
+
:email => "no spam",
|
87
|
+
:password => "whatever",
|
88
|
+
:bio => "rspec master")
|
89
|
+
|
90
|
+
put '/api/v1/users/bryan', :user => {:bio => "testing freak"}
|
91
|
+
|
92
|
+
last_response.status.should == 200
|
93
|
+
|
94
|
+
get '/api/v1/users/bryan'
|
95
|
+
attributes = JSON.parse(last_response.body)["user"]
|
96
|
+
attributes["bio"].should == "testing freak"
|
97
|
+
end
|
98
|
+
context "when called with unexisting id" do
|
99
|
+
before do
|
100
|
+
put "/api/v1/users/no-existo"
|
101
|
+
end
|
102
|
+
it "should return not found" do
|
103
|
+
last_response.status.should == 404
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "RESTfull DELETE (on /api/v1/users/:id)" do
|
109
|
+
it "should delete a user" do
|
110
|
+
User.create(
|
111
|
+
:name => "francis",
|
112
|
+
:email => "no spam",
|
113
|
+
:password => "whatever",
|
114
|
+
:bio => "williamsburg hipster")
|
115
|
+
|
116
|
+
expect{delete '/api/v1/users/francis'}.to change{User.count}.by -1
|
117
|
+
|
118
|
+
last_response.should be_ok
|
119
|
+
|
120
|
+
get '/api/v1/users/francis'
|
121
|
+
last_response.status.should == 404
|
122
|
+
end
|
123
|
+
end
|
124
|
+
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.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-24 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
16
|
-
requirement: &
|
16
|
+
requirement: &79786070 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *79786070
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
requirement: &
|
27
|
+
requirement: &79785440 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *79785440
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: typhoeus
|
38
|
-
requirement: &
|
38
|
+
requirement: &79784950 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.2.4
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *79784950
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: kaminari
|
49
|
-
requirement: &
|
49
|
+
requirement: &79784280 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *79784280
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: shoulda
|
60
|
-
requirement: &
|
60
|
+
requirement: &79783710 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,21 +65,21 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *79783710
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
|
-
requirement: &
|
71
|
+
requirement: &79767980 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: 1.0.
|
76
|
+
version: 1.0.10
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *79767980
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: jeweler
|
82
|
-
requirement: &
|
82
|
+
requirement: &79767170 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: 1.6.4
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *79767170
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: rcov
|
93
|
-
requirement: &
|
93
|
+
requirement: &79765920 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,7 +98,84 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *79765920
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: sqlite3-ruby
|
104
|
+
requirement: &79765210 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *79765210
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: sinatra
|
115
|
+
requirement: &79764410 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ~>
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: 1.2.6
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *79764410
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: json
|
126
|
+
requirement: &79763810 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *79763810
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: rspec-rails
|
137
|
+
requirement: &79763190 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: *79763190
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: guard-rspec
|
148
|
+
requirement: &79762800 !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
type: :development
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: *79762800
|
157
|
+
- !ruby/object:Gem::Dependency
|
158
|
+
name: rb-inotify
|
159
|
+
requirement: &79762320 !ruby/object:Gem::Requirement
|
160
|
+
none: false
|
161
|
+
requirements:
|
162
|
+
- - ! '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
type: :development
|
166
|
+
prerelease: false
|
167
|
+
version_requirements: *79762320
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: libnotify
|
170
|
+
requirement: &79761520 !ruby/object:Gem::Requirement
|
171
|
+
none: false
|
172
|
+
requirements:
|
173
|
+
- - ! '>='
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: *79761520
|
102
179
|
description: LogicalModel allows to use a resource as a model. It is based on web
|
103
180
|
presentation http://www.slideshare.net/ihower/serviceoriented-design-and-implement-with-rails3
|
104
181
|
email: dwaynemac@gmail.com
|
@@ -111,12 +188,25 @@ files:
|
|
111
188
|
- .document
|
112
189
|
- Gemfile
|
113
190
|
- Gemfile.lock
|
191
|
+
- Guardfile
|
114
192
|
- LICENSE.txt
|
115
193
|
- README.rdoc
|
116
194
|
- Rakefile
|
117
195
|
- VERSION
|
196
|
+
- client.rb
|
197
|
+
- config.ru
|
198
|
+
- config/application.rb
|
199
|
+
- config/database.yml
|
200
|
+
- db/development.sqlite3
|
201
|
+
- db/migrate/001_create_users.rb
|
202
|
+
- db/test.sqlite3
|
118
203
|
- lib/logical_model.rb
|
119
204
|
- logical_model.gemspec
|
205
|
+
- logs/development.log
|
206
|
+
- models/user.rb
|
207
|
+
- service.rb
|
208
|
+
- spec/client_spec.rb
|
209
|
+
- spec/service_spec.rb
|
120
210
|
- test/helper.rb
|
121
211
|
- test/test_logical_model.rb
|
122
212
|
- test/typhoeus_mocks.rb
|
@@ -135,7 +225,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
225
|
version: '0'
|
136
226
|
segments:
|
137
227
|
- 0
|
138
|
-
hash: -
|
228
|
+
hash: -873629389
|
139
229
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
230
|
none: false
|
141
231
|
requirements:
|