logical_model 0.4.10 → 0.5.0

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.
@@ -0,0 +1,61 @@
1
+ require 'logger'
2
+
3
+ class LogicalModel
4
+ module SafeLog
5
+
6
+ def self.included(base)
7
+ base.send(:include, InstanceMethods)
8
+ base.send(:extend, ClassMethods)
9
+ end
10
+
11
+ module InstanceMethods
12
+ def log_ok(response)
13
+ self.class.log_ok(response)
14
+ end
15
+
16
+ def log_failed(response)
17
+ self.class.log_failed(response)
18
+ end
19
+
20
+ end
21
+
22
+ module ClassMethods
23
+ attr_accessor :log_path
24
+
25
+ def log_path
26
+ @log_path ||= "log/logical_model.log"
27
+ end
28
+
29
+ def log_ok(response)
30
+ self.logger.info("LogicalModel Log: #{response.code} #{mask_api_key(response.effective_url)} in #{response.time}s")
31
+ self.logger.debug("LogicalModel Log RESPONSE: #{response.body}")
32
+ end
33
+
34
+ def log_failed(response)
35
+ begin
36
+ error_message = ActiveSupport::JSON.decode(response.body)["message"]
37
+ rescue => e
38
+ error_message = "error"
39
+ end
40
+ msg = "LogicalModel Log: #{response.code} #{mask_api_key(response.effective_url)} in #{response.time}s FAILED: #{error_message}"
41
+ self.logger.warn(msg)
42
+ self.logger.debug("LogicalModel Log RESPONSE: #{response.body}")
43
+ end
44
+
45
+ def logger
46
+ Logger.new(self.log_path || "log/logical_model.log")
47
+ end
48
+
49
+ # Filters api_key
50
+ # @return [String]
51
+ def mask_api_key(str)
52
+ if use_api_key && str
53
+ str = str.gsub(api_key,'[SECRET]')
54
+ end
55
+ str
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,78 @@
1
+ class LogicalModel
2
+ module UrlHelper
3
+
4
+ def self.included(base)
5
+ base.send(:extend, ClassMethods)
6
+ end
7
+
8
+ # adds following setters
9
+ # - force_ssl
10
+ # - set_resource_host
11
+ # - set_resource_path
12
+ #
13
+ # add reader
14
+ # - resource_uri
15
+ module ClassMethods
16
+
17
+ attr_accessor :host,
18
+ :resource_path,
19
+ :use_ssl
20
+
21
+ # Will return path to resource
22
+ # @param id [String] (nil)
23
+ def resource_uri(id=nil)
24
+ sufix = (id.nil?)? "" : "/#{id}"
25
+ "#{url_protocol_prefix}#{host}#{resource_path}#{sufix}"
26
+ end
27
+
28
+ # If called in class, will make al request through SSL.
29
+ # @example
30
+ # class Client < LogicalModel
31
+ # force_ssl
32
+ # ...
33
+ # end
34
+ def force_ssl
35
+ @use_ssl = true
36
+ end
37
+
38
+ # @param new_host [String] resource host. Should NOT include protocol (http)
39
+ # @param new_path [String] resource path in host
40
+ def set_resource_url(new_host,new_path)
41
+ @host = new_host
42
+ @resource_path = new_path
43
+ end
44
+
45
+ def set_resource_host(new_host)
46
+ @host = new_host
47
+ end
48
+
49
+ def set_resource_path(new_path)
50
+ @resource_path = new_path
51
+ end
52
+
53
+ ##
54
+ # Default use_ssl to ssl_recommend?
55
+ # @return [Boolean]
56
+ def use_ssl?
57
+ @use_ssl ||= ssl_recommended?
58
+ end
59
+
60
+ # @return [String]
61
+ def url_protocol_prefix
62
+ (use_ssl?)? "https://" : "http://"
63
+ end
64
+
65
+ # Returns true if ssl is recommended according to environment.
66
+ #
67
+ # - production, staging -> true
68
+ # - other -> false
69
+ #
70
+ # @return [Boolean]
71
+ def ssl_recommended?
72
+ ssl_recommended_environments = %W(production staging)
73
+ ssl_recommended_environments.include?(defined?(Rails)? Rails.env : ENV['RACK_ENV'] )
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "logical_model"
8
- s.version = "0.4.10"
8
+ s.version = "0.5.0"
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 = "2013-04-23"
12
+ s.date = "2013-05-01"
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 = [
@@ -32,9 +32,12 @@ Gem::Specification.new do |s|
32
32
  "db/development.sqlite3",
33
33
  "db/migrate/001_create_users.rb",
34
34
  "lib/logical_model.rb",
35
+ "lib/logical_model/api_key.rb",
36
+ "lib/logical_model/attributes.rb",
35
37
  "lib/logical_model/has_many_keys.rb",
36
- "lib/safe_log.rb",
37
- "lib/ssl_support.rb",
38
+ "lib/logical_model/rest_actions.rb",
39
+ "lib/logical_model/safe_log.rb",
40
+ "lib/logical_model/url_helper.rb",
38
41
  "lib/typhoeus_fix/array_decoder.rb",
39
42
  "logical_model.gemspec",
40
43
  "models/user.rb",
@@ -5,6 +5,135 @@ include TyphoeusMocks
5
5
 
6
6
  describe "LogicalModel User client" do
7
7
 
8
+ subject{User}
9
+
10
+ describe "Attributes" do
11
+ subject{User.new}
12
+ %W(id name email password bio).each do |attribute|
13
+ it { should respond_to attribute }
14
+ it { should respond_to "#{attribute}="}
15
+ end
16
+ describe "attribute definer" do
17
+ it "should add attribute" do
18
+ User.new.attributes.should_not include :this_is_a_new_attribute
19
+ User.new.attributes.should_not include :another_new_attribute
20
+ class User < LogicalModel
21
+ attribute :this_is_a_new_attribute
22
+ attribute :another_new_attribute
23
+ end
24
+ User.new.attributes.should include :this_is_a_new_attribute
25
+ User.new.attributes.should include :another_new_attribute
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "RESTActions" do
31
+ %W(find async_find paginate async_paginate delete delete_multiple).each do |class_action|
32
+ it { should respond_to class_action }
33
+ end
34
+ end
35
+
36
+ describe "has_many_keys" do
37
+ it { should respond_to 'has_many_keys=' }
38
+ it { should respond_to 'has_many_keys'}
39
+ end
40
+
41
+ describe "url_helper" do
42
+ it { should respond_to 'use_ssl=' }
43
+ it { should respond_to 'use_ssl?' }
44
+ it { should respond_to 'url_protocol_prefix' }
45
+ it { should respond_to 'ssl_recommended?' }
46
+ describe "force_ssl" do
47
+ it { should respond_to 'force_ssl' }
48
+ it "sets use_ssl to true" do
49
+ User.use_ssl?.should be_false
50
+ class User; force_ssl; end;
51
+ User.use_ssl?.should be_true
52
+ end
53
+ end
54
+ describe "set_resource_host" do
55
+ it { should respond_to 'set_resource_host' }
56
+ it "sets resource_path" do
57
+ User.resource_path.should == "/api/v1/users"
58
+ class User; set_resource_path("new_path"); end;
59
+ User.resource_path.should == "new_path"
60
+ end
61
+ end
62
+ describe "set_resource_path" do
63
+ it { should respond_to 'set_resource_path'}
64
+ it "sets resource_host" do
65
+ User.host.should == "localhost:3000"
66
+ class User; set_resource_host("new_host"); end;
67
+ User.host.should == "new_host"
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "safe_log" do
73
+ it { should respond_to 'log_ok' }
74
+ it { should respond_to 'log_failed' }
75
+ it { should respond_to 'logger' }
76
+ it { should respond_to 'mask_api_key' }
77
+ describe ".log_path" do
78
+ it { should respond_to 'log_path' }
79
+ its(:log_path){ should == "logs/development.log"}
80
+ end
81
+ end
82
+
83
+ describe "api_key" do
84
+ describe "set_api_key" do
85
+ it { should respond_to 'set_api_key'}
86
+ it "sets api_key" do
87
+ class User < LogicalModel
88
+ set_api_key(:key_name, 'secret_api_key')
89
+ end
90
+ User.use_api_key.should be_true
91
+ User.api_key.should == 'secret_api_key'
92
+ User.api_key_name.should == :key_name
93
+ end
94
+ end
95
+ describe "use_api_key" do
96
+ it { should respond_to 'use_api_key' }
97
+ context "when true" do
98
+ before(:each) do
99
+ class User < LogicalModel; self.use_api_key=true; self.api_key_name='keyname'; self.api_key="secret_api_key"; end
100
+ end
101
+ it "should send api key in requests" do
102
+ Typhoeus::Request.should_receive(:new).with(User.resource_uri(1),{:params=>{'keyname'=>'secret_api_key'}})
103
+ begin
104
+ User.find(1)
105
+ rescue
106
+ end
107
+ end
108
+ it "should mask api key in logs" do
109
+ response = mock(
110
+ code: 200,
111
+ body: {}.to_json,
112
+ effective_url: "server?keyname=secret_api_key",
113
+ time: 1234
114
+ )
115
+ Logger.any_instance.should_receive(:info).with(/\[SECRET\]/)
116
+ User.log_ok(response)
117
+ Logger.any_instance.should_receive(:warn).with(/\[SECRET\]/)
118
+ User.log_failed(response)
119
+ end
120
+ end
121
+ context "when false" do
122
+ before(:each) do
123
+ class User < LogicalModel; self.use_api_key=false; self.api_key_name='keyname'; self.api_key="secret_api_key"; end
124
+ end
125
+ it "should not send api key in requests" do
126
+ Typhoeus::Request.should_not_receive(:new).with(User.resource_uri(1),{:params=>{'keyname'=>'secret_api_key'}})
127
+ begin
128
+ User.find(1)
129
+ rescue
130
+ end
131
+ end
132
+ end
133
+ end
134
+ it { should respond_to 'merge_key'}
135
+ end
136
+
8
137
  describe "#create" do
9
138
  context "with valid attributes" do
10
139
  context "if response is code 201" do
@@ -131,45 +260,6 @@ describe "LogicalModel User client" do
131
260
  end
132
261
  end
133
262
 
134
- describe "use_api_key" do
135
- context "when true" do
136
- before(:each) do
137
- class User < LogicalModel; self.use_api_key=true; self.api_key_name='keyname'; self.api_key="secret_api_key"; end
138
- end
139
- it "should send api key in requests" do
140
- Typhoeus::Request.should_receive(:new).with(User.resource_uri(1),{:params=>{'keyname'=>'secret_api_key'}})
141
- begin
142
- User.find(1)
143
- rescue
144
- end
145
- end
146
- it "should mask api key in logs" do
147
- response = mock(
148
- code: 200,
149
- body: {}.to_json,
150
- effective_url: "server?keyname=secret_api_key",
151
- time: 1234
152
- )
153
- Logger.any_instance.should_receive(:info).with(/\[SECRET\]/)
154
- User.log_ok(response)
155
- Logger.any_instance.should_receive(:warn).with(/\[SECRET\]/)
156
- User.log_failed(response)
157
- end
158
- end
159
- context "when false" do
160
- before(:each) do
161
- class User < LogicalModel; self.use_api_key=false; self.api_key_name='keyname'; self.api_key="secret_api_key"; end
162
- end
163
- it "should not send api key in requests" do
164
- Typhoeus::Request.should_not_receive(:new).with(User.resource_uri(1),{:params=>{'keyname'=>'secret_api_key'}})
165
- begin
166
- User.find(1)
167
- rescue
168
- end
169
- end
170
- end
171
- end
172
-
173
263
  describe "#https" do
174
264
  context "when use_ssl is tue" do
175
265
  before(:each) do
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.4.10
4
+ version: 0.5.0
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: 2013-04-23 00:00:00.000000000 Z
12
+ date: 2013-05-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -323,9 +323,12 @@ files:
323
323
  - db/development.sqlite3
324
324
  - db/migrate/001_create_users.rb
325
325
  - lib/logical_model.rb
326
+ - lib/logical_model/api_key.rb
327
+ - lib/logical_model/attributes.rb
326
328
  - lib/logical_model/has_many_keys.rb
327
- - lib/safe_log.rb
328
- - lib/ssl_support.rb
329
+ - lib/logical_model/rest_actions.rb
330
+ - lib/logical_model/safe_log.rb
331
+ - lib/logical_model/url_helper.rb
329
332
  - lib/typhoeus_fix/array_decoder.rb
330
333
  - logical_model.gemspec
331
334
  - models/user.rb
@@ -348,7 +351,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
348
351
  version: '0'
349
352
  segments:
350
353
  - 0
351
- hash: -711400131
354
+ hash: 863618749
352
355
  required_rubygems_version: !ruby/object:Gem::Requirement
353
356
  none: false
354
357
  requirements:
@@ -1,11 +0,0 @@
1
- module SafeLog
2
-
3
- # Filters api_key
4
- # @return [String]
5
- def mask_api_key(str)
6
- if use_api_key && str
7
- str = str.gsub(api_key,'[SECRET]')
8
- end
9
- str
10
- end
11
- end
@@ -1,39 +0,0 @@
1
- module SslSupport
2
-
3
- def self.included(base)
4
- base.class.send(:attr_accessor, :use_ssl)
5
- base.send(:include, InstanceMethods)
6
- base.send(:extend, ClassMethods)
7
- end
8
-
9
- module InstanceMethods
10
-
11
- end
12
-
13
- module ClassMethods
14
- ##
15
- # Default use_ssl to ssl_recommend?
16
- # @return [Boolean]
17
- def use_ssl?
18
- @use_ssl ||= ssl_recommended?
19
- end
20
-
21
- # @return [String]
22
- def url_protocol_prefix
23
- (use_ssl?)? "https://" : "http://"
24
- end
25
-
26
- # Returns true if ssl is recommended according to environment.
27
- #
28
- # - production, staging -> true
29
- # - other -> false
30
- #
31
- # @return [Boolean]
32
- def ssl_recommended?
33
- ssl_recommended_environments = %W(production staging)
34
- ssl_recommended_environments.include?(defined?(Rails)? Rails.env : ENV['RACK_ENV'] )
35
- end
36
- end
37
-
38
-
39
- end