keymaker 0.0.9 → 0.1.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.
Files changed (54) hide show
  1. data/Rakefile +1 -1
  2. data/keymaker.gemspec +5 -37
  3. data/lib/keymaker.rb +8 -5
  4. data/lib/keymaker/node.rb +69 -45
  5. data/lib/keymaker/parsers/cypher_response_parser.rb +25 -0
  6. data/lib/keymaker/serialization.rb +2 -1
  7. data/lib/keymaker/service.rb +4 -17
  8. data/spec/keymaker/node_spec.rb +92 -0
  9. data/spec/keymaker/requests/add_node_to_index_request_spec.rb +13 -13
  10. data/spec/keymaker/requests/batch_request_spec.rb +3 -56
  11. data/spec/keymaker/requests/create_node_request_spec.rb +15 -9
  12. data/spec/keymaker/requests/create_relationship_request_spec.rb +19 -11
  13. data/spec/keymaker/requests/execute_cypher_request_spec.rb +1 -1
  14. data/spec/keymaker/requests/get_relationship_types_request_spec.rb +3 -4
  15. data/spec/keymaker/requests/update_node_properties_request_spec.rb +1 -1
  16. data/spec/keymaker_spec.rb +38 -8
  17. data/spec/support/active_model_lint.rb +17 -0
  18. data/spec/support/keymaker.rb +1 -1
  19. metadata +8 -73
  20. data/spec/cassettes/Keymaker_AddNodeToIndexRequest/with_valid_options/returns_a_201_status_code.yml +0 -203
  21. data/spec/cassettes/Keymaker_AddNodeToIndexRequest/with_valid_options/returns_application/json.yml +0 -203
  22. data/spec/cassettes/Keymaker_AddNodeToIndexRequest/with_valid_options/returns_the_Neo4j_REST_API_starting_point_response_request.yml +0 -203
  23. data/spec/cassettes/Keymaker_BatchRequest/when_a_resource_is_not_found/raises_BatchRequestError.yml +0 -120
  24. data/spec/cassettes/Keymaker_BatchRequest/when_to_and_method_are_not_set/raises_BatchRequestError.yml +0 -106
  25. data/spec/cassettes/Keymaker_BatchRequest/with_valid_options/returns_a_200_status_code.yml +0 -129
  26. data/spec/cassettes/Keymaker_BatchRequest/with_valid_options/runs_the_commands_and_returns_their_respective_results.yml +0 -129
  27. data/spec/cassettes/Keymaker_CreateNodeRequest/returns_a_201_status_code.yml +0 -112
  28. data/spec/cassettes/Keymaker_CreateNodeRequest/returns_application/json.yml +0 -112
  29. data/spec/cassettes/Keymaker_CreateNodeRequest/with_properties/creates_a_node_with_the_given_properties.yml +0 -112
  30. data/spec/cassettes/Keymaker_CreateNodeRequest/without_properties/creates_an_empty_node.yml +0 -112
  31. data/spec/cassettes/Keymaker_CreateRelationshipRequest/with_invalid_options/raises_ClientError.yml +0 -201
  32. data/spec/cassettes/Keymaker_CreateRelationshipRequest/with_properties/creates_a_node_with_the_given_properties.yml +0 -233
  33. data/spec/cassettes/Keymaker_CreateRelationshipRequest/with_properties/returns_a_201_status_code.yml +0 -196
  34. data/spec/cassettes/Keymaker_CreateRelationshipRequest/with_properties/returns_application/json.yml +0 -196
  35. data/spec/cassettes/Keymaker_CreateRelationshipRequest/without_properties/creates_an_empty_relationship_of_type_birthed_.yml +0 -195
  36. data/spec/cassettes/Keymaker_DeleteRelationshipRequest/with_a_non-existent_relationship/raises_ResourceNotFound.yml +0 -191
  37. data/spec/cassettes/Keymaker_DeleteRelationshipRequest/with_an_existing_relationship/deletes_the_relationship.yml +0 -219
  38. data/spec/cassettes/Keymaker_ExecuteCypherRequest/with_a_valid_Cypher_Query/returns_a_200_status_code.yml +0 -111
  39. data/spec/cassettes/Keymaker_ExecuteCypherRequest/with_an_invalid_Cypher_Query/raises_ClientError.yml +0 -108
  40. data/spec/cassettes/Keymaker_ExecuteGremlinRequest/with_a_valid_Gremlin_Script/returns_a_200_status_code.yml +0 -98
  41. data/spec/cassettes/Keymaker_ExecuteGremlinRequest/with_an_invalid_Gremlin_Script/raises_ClientError.yml +0 -107
  42. data/spec/cassettes/Keymaker_GetNodeRequest/with_a_non-existent_node_id/raises_ResourceNotFound.yml +0 -101
  43. data/spec/cassettes/Keymaker_GetNodeRequest/with_an_empty_node_id/raises_ClientError.yml +0 -111
  44. data/spec/cassettes/Keymaker_GetRelationshipTypesRequest/with_existing_relationships/returns_a_unique_array_of_relationship_types.yml +0 -220
  45. data/spec/cassettes/Keymaker_ServiceRootRequest/returns_a_200_status_code.yml +0 -105
  46. data/spec/cassettes/Keymaker_ServiceRootRequest/returns_application/json.yml +0 -105
  47. data/spec/cassettes/Keymaker_ServiceRootRequest/returns_the_Neo4j_REST_API_starting_point_response_request.yml +0 -105
  48. data/spec/cassettes/Keymaker_TraversePathRequest/_traverse_path_properties/with_options/builds_the_query_properties_with_defaults.yml +0 -157
  49. data/spec/cassettes/Keymaker_TraversePathRequest/with_invalid_options/raise_a_ClientError.yml +0 -193
  50. data/spec/cassettes/Keymaker_TraversePathRequest/with_valid_options/returns_status_code_200.yml +0 -269
  51. data/spec/cassettes/Keymaker_UpdateNodePropertiesRequest/_node_properties/excludes_the_node_id.yml +0 -157
  52. data/spec/cassettes/Keymaker_UpdateNodePropertiesRequest/with_invalid_options/raises_a_ClientError.yml +0 -193
  53. data/spec/cassettes/Keymaker_UpdateNodePropertiesRequest/with_valid_options/returns_a_status_of_204.yml +0 -182
  54. data/spec/cassettes/Keymaker_UpdateNodePropertiesRequest/with_valid_options/updates_the_properties.yml +0 -214
data/Rakefile CHANGED
@@ -134,7 +134,7 @@ NEO4J_PORT = ENV['NEO4J_PORT'] || '7477' # Don't clobber standard neo4j ports 74
134
134
 
135
135
  namespace :neo4j do
136
136
 
137
- desc "Install neo4j on localhost:#{NEO4J_PORT}. e.g. rake neo4j:install[community,1.7.M03]"
137
+ desc "Install neo4j on localhost:#{NEO4J_PORT}. e.g. rake neo4j:install[community,1.8.RC1]"
138
138
  task :install, :edition, :version do |t, args|
139
139
  args.with_defaults(:edition => "community", :version => "1.7")
140
140
 
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
5
5
  s.rubygems_version = '1.3.5'
6
6
 
7
7
  s.name = 'keymaker'
8
- s.version = '0.0.9'
9
- s.date = '2012-09-22'
8
+ s.version = '0.1.0'
9
+ s.date = '2012-10-14'
10
10
 
11
11
  s.description = %q{A multi-layer REST API wrapper for neo4j.}
12
12
  s.summary = %q{A multi-layer REST API wrapper for neo4j.}
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
48
48
  lib/keymaker/indexing.rb
49
49
  lib/keymaker/match_method.rb
50
50
  lib/keymaker/node.rb
51
+ lib/keymaker/parsers/cypher_response_parser.rb
51
52
  lib/keymaker/rails_tasks.rb
52
53
  lib/keymaker/railtie.rb
53
54
  lib/keymaker/request.rb
@@ -69,42 +70,8 @@ Gem::Specification.new do |s|
69
70
  lib/keymaker/response.rb
70
71
  lib/keymaker/serialization.rb
71
72
  lib/keymaker/service.rb
72
- spec/cassettes/Keymaker_AddNodeToIndexRequest/with_valid_options/returns_a_201_status_code.yml
73
- spec/cassettes/Keymaker_AddNodeToIndexRequest/with_valid_options/returns_application/json.yml
74
- spec/cassettes/Keymaker_AddNodeToIndexRequest/with_valid_options/returns_the_Neo4j_REST_API_starting_point_response_request.yml
75
- spec/cassettes/Keymaker_BatchRequest/when_a_resource_is_not_found/raises_BatchRequestError.yml
76
- spec/cassettes/Keymaker_BatchRequest/when_to_and_method_are_not_set/raises_BatchRequestError.yml
77
- spec/cassettes/Keymaker_BatchRequest/with_valid_options/returns_a_200_status_code.yml
78
- spec/cassettes/Keymaker_BatchRequest/with_valid_options/runs_the_commands_and_returns_their_respective_results.yml
79
- spec/cassettes/Keymaker_CreateNodeRequest/returns_a_201_status_code.yml
80
- spec/cassettes/Keymaker_CreateNodeRequest/returns_application/json.yml
81
- spec/cassettes/Keymaker_CreateNodeRequest/with_properties/creates_a_node_with_the_given_properties.yml
82
- spec/cassettes/Keymaker_CreateNodeRequest/without_properties/creates_an_empty_node.yml
83
- spec/cassettes/Keymaker_CreateRelationshipRequest/with_invalid_options/raises_ClientError.yml
84
- spec/cassettes/Keymaker_CreateRelationshipRequest/with_properties/creates_a_node_with_the_given_properties.yml
85
- spec/cassettes/Keymaker_CreateRelationshipRequest/with_properties/returns_a_201_status_code.yml
86
- spec/cassettes/Keymaker_CreateRelationshipRequest/with_properties/returns_application/json.yml
87
- spec/cassettes/Keymaker_CreateRelationshipRequest/without_properties/creates_an_empty_relationship_of_type_birthed_.yml
88
- spec/cassettes/Keymaker_DeleteRelationshipRequest/with_a_non-existent_relationship/raises_ResourceNotFound.yml
89
- spec/cassettes/Keymaker_DeleteRelationshipRequest/with_an_existing_relationship/deletes_the_relationship.yml
90
- spec/cassettes/Keymaker_ExecuteCypherRequest/with_a_valid_Cypher_Query/returns_a_200_status_code.yml
91
- spec/cassettes/Keymaker_ExecuteCypherRequest/with_an_invalid_Cypher_Query/raises_ClientError.yml
92
- spec/cassettes/Keymaker_ExecuteGremlinRequest/with_a_valid_Gremlin_Script/returns_a_200_status_code.yml
93
- spec/cassettes/Keymaker_ExecuteGremlinRequest/with_an_invalid_Gremlin_Script/raises_ClientError.yml
94
- spec/cassettes/Keymaker_GetNodeRequest/with_a_non-existent_node_id/raises_ResourceNotFound.yml
95
- spec/cassettes/Keymaker_GetNodeRequest/with_an_empty_node_id/raises_ClientError.yml
96
- spec/cassettes/Keymaker_GetRelationshipTypesRequest/with_existing_relationships/returns_a_unique_array_of_relationship_types.yml
97
- spec/cassettes/Keymaker_ServiceRootRequest/returns_a_200_status_code.yml
98
- spec/cassettes/Keymaker_ServiceRootRequest/returns_application/json.yml
99
- spec/cassettes/Keymaker_ServiceRootRequest/returns_the_Neo4j_REST_API_starting_point_response_request.yml
100
- spec/cassettes/Keymaker_TraversePathRequest/_traverse_path_properties/with_options/builds_the_query_properties_with_defaults.yml
101
- spec/cassettes/Keymaker_TraversePathRequest/with_invalid_options/raise_a_ClientError.yml
102
- spec/cassettes/Keymaker_TraversePathRequest/with_valid_options/returns_status_code_200.yml
103
- spec/cassettes/Keymaker_UpdateNodePropertiesRequest/_node_properties/excludes_the_node_id.yml
104
- spec/cassettes/Keymaker_UpdateNodePropertiesRequest/with_invalid_options/raises_a_ClientError.yml
105
- spec/cassettes/Keymaker_UpdateNodePropertiesRequest/with_valid_options/returns_a_status_of_204.yml
106
- spec/cassettes/Keymaker_UpdateNodePropertiesRequest/with_valid_options/updates_the_properties.yml
107
73
  spec/configuration_spec.rb
74
+ spec/keymaker/node_spec.rb
108
75
  spec/keymaker/requests/add_node_to_index_request_spec.rb
109
76
  spec/keymaker/requests/batch_get_nodes_request_spec.rb
110
77
  spec/keymaker/requests/batch_request_spec.rb
@@ -123,6 +90,7 @@ Gem::Specification.new do |s|
123
90
  spec/keymaker_spec.rb
124
91
  spec/service_spec.rb
125
92
  spec/spec_helper.rb
93
+ spec/support/active_model_lint.rb
126
94
  spec/support/keymaker.rb
127
95
  spec/support/vcr.rb
128
96
  ]
@@ -2,11 +2,18 @@ require 'faraday'
2
2
  require 'faraday_middleware'
3
3
  require 'hashie'
4
4
  require 'active_model'
5
+ require 'active_model/validations'
6
+ require 'active_model/callbacks'
5
7
  require 'active_support/core_ext/string/inflections'
8
+ require 'active_support/core_ext/object/blank'
9
+ require 'active_support/core_ext/class/attribute'
10
+ require 'active_support/core_ext/string/conversions'
11
+ require 'active_support/hash_with_indifferent_access'
6
12
 
7
13
  require 'keymaker/match_method'
8
14
  require 'keymaker/errors'
9
15
  require 'keymaker/response'
16
+ require 'keymaker/parsers/cypher_response_parser'
10
17
  require 'keymaker/configuration'
11
18
  require 'keymaker/service'
12
19
 
@@ -14,19 +21,15 @@ require 'keymaker/request'
14
21
 
15
22
  require 'keymaker/requests/batch_request'
16
23
  require 'keymaker/requests/batch_get_nodes_request'
17
-
18
24
  require 'keymaker/requests/create_node_request'
19
25
  require 'keymaker/requests/delete_node_request'
20
26
  require 'keymaker/requests/get_node_request'
21
-
22
27
  require 'keymaker/requests/add_node_to_index_request'
23
28
  require 'keymaker/requests/remove_node_from_index_request'
24
29
  require 'keymaker/requests/update_node_properties_request'
25
-
26
30
  require 'keymaker/requests/create_relationship_request'
27
31
  require 'keymaker/requests/delete_relationship_request'
28
32
  require 'keymaker/requests/get_relationship_types_request'
29
-
30
33
  require 'keymaker/requests/execute_cypher_request'
31
34
  require 'keymaker/requests/execute_gremlin_request'
32
35
  require 'keymaker/requests/traverse_path_request'
@@ -40,7 +43,7 @@ require 'keymaker/railtie' if defined? Rails::Railtie
40
43
 
41
44
  module Keymaker
42
45
 
43
- VERSION = "0.0.9"
46
+ VERSION = "0.1.0"
44
47
 
45
48
  def self.service
46
49
  @service ||= Keymaker::Service.new(Keymaker::Configuration.new)
@@ -5,16 +5,21 @@ module Keymaker
5
5
  module Node
6
6
 
7
7
  def self.included(base)
8
- base.extend ActiveModel::Callbacks
9
- base.extend ClassMethods
10
8
 
11
9
  base.class_eval do
12
- attr_writer :new_node
10
+ extend ActiveModel::Callbacks
11
+ extend ActiveModel::Naming
13
12
  include ActiveModel::MassAssignmentSecurity
13
+ include ActiveModel::Validations
14
+ include ActiveModel::Conversion
14
15
 
15
16
  include Keymaker::Indexing
16
17
  include Keymaker::Serialization
17
18
 
19
+ extend Keymaker::Node::ClassMethods
20
+ include Keymaker::Node::InstanceMethods
21
+
22
+ attr_writer :new_node
18
23
  attr_protected :created_at, :updated_at
19
24
  end
20
25
 
@@ -30,10 +35,10 @@ module Keymaker
30
35
  base.property :node_id, Integer
31
36
  base.property :created_at, DateTime
32
37
  base.property :updated_at, DateTime
38
+
33
39
  end
34
40
 
35
41
  module ClassMethods
36
-
37
42
  extend Forwardable
38
43
 
39
44
  def_delegator :Keymaker, :service, :neo_service
@@ -47,63 +52,82 @@ module Keymaker
47
52
  attr_accessor attribute
48
53
  end
49
54
 
50
- def execute_cypher(query, params={}, return_type=:results_only)
51
- executed_query = neo_service.execute_query(query, params)
52
- if executed_query.present?
53
- case return_type
54
- when :results_only
55
- executed_query["data"].flatten
56
- # TODO: Make this less specific
57
- when :full_user
58
- {"user" => executed_query["data"].flatten[0]["data"], "neo_id" => executed_query["data"].flatten[1]}
55
+ def create(attributes)
56
+ new(attributes).save
57
+ end
58
+
59
+ def find_by_cypher(query, params={})
60
+ find_all_by_cypher(query, params).first
61
+ end
62
+
63
+ def find_all_by_cypher(query, params={})
64
+ neo_service.execute_cypher(query, params)
65
+ end
66
+
67
+ def find(node_id)
68
+ node = neo_service.get_node(node_id)
69
+ if node.present?
70
+ new(node.slice(*properties)).tap do |neo_node|
71
+ neo_node.node_id = node.neo4j_id
72
+ neo_node.new_node = false
59
73
  end
60
- else
61
- return []
62
74
  end
63
75
  end
64
76
 
65
77
  end
66
78
 
67
- def initialize(attrs)
68
- @new_node = true
69
- process_attrs(attrs) if attrs.present?
70
- end
79
+ module InstanceMethods
71
80
 
72
- def neo_service
73
- self.class.neo_service
74
- end
81
+ def initialize(attrs = {})
82
+ @new_node = true
83
+ process_attrs(attrs) if attrs.present?
84
+ end
75
85
 
76
- def new?
77
- @new_node
78
- end
86
+ def neo_service
87
+ self.class.neo_service
88
+ end
79
89
 
80
- def sanitize(attrs)
81
- serializable_hash(except: :node_id).merge(attrs.except('node_id')).reject {|k,v| v.blank?}
82
- end
90
+ def new?
91
+ @new_node
92
+ end
83
93
 
84
- def save
85
- create_or_update
86
- end
94
+ def sanitize(attrs)
95
+ serializable_hash(except: :node_id).merge(attrs.except('node_id')).reject {|k,v| v.blank?}
96
+ end
87
97
 
88
- def create_or_update
89
- run_callbacks :save do
90
- new? ? create : update(attributes)
98
+ def save
99
+ create_or_update
91
100
  end
92
- end
93
101
 
94
- def create
95
- run_callbacks :create do
96
- neo_service.create_node(sanitize(attributes)).on_success do |response|
97
- self.node_id = response.neo4j_id
98
- self.new_node = false
102
+ def create_or_update
103
+ run_callbacks :save do
104
+ new? ? create : update(attributes)
99
105
  end
100
- self
101
106
  end
102
- end
103
107
 
104
- def update(attrs)
105
- process_attrs(sanitize(attrs.merge(updated_at: Time.now.utc.to_i)))
106
- neo_service.update_node_properties(node_id, sanitize(attributes))
108
+ def create
109
+ run_callbacks :create do
110
+ neo_service.create_node(sanitize(attributes)).on_success do |response|
111
+ self.node_id = response.neo4j_id
112
+ self.new_node = false
113
+ end
114
+ self
115
+ end
116
+ end
117
+
118
+ def update(attrs)
119
+ process_attrs(sanitize(attrs.merge(updated_at: Time.now.utc.to_i)))
120
+ neo_service.update_node_properties(node_id, sanitize(attributes))
121
+ end
122
+
123
+ def persisted?
124
+ node_id.present?
125
+ end
126
+
127
+ def to_key
128
+ persisted? ? [node_id] : nil
129
+ end
130
+
107
131
  end
108
132
 
109
133
  end
@@ -0,0 +1,25 @@
1
+ module Keymaker
2
+ class CypherResponseParser
3
+
4
+ def self.parse(response_body)
5
+ response_body.data.map do |result|
6
+ if response_body.columns.one? && result.first.kind_of?(Hashie::Mash)
7
+ result.first.data
8
+ else
9
+ translate_response(response_body, result)
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.translate_response(response_body, result)
15
+ Hashie::Mash.new(Hash[sanitized_column_names(response_body).zip(result)])
16
+ end
17
+
18
+ def self.sanitized_column_names(response_body)
19
+ response_body.columns.map do |column|
20
+ column[/[^\.]+$/]
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -12,7 +12,7 @@ module Keymaker::Serialization
12
12
  when Time
13
13
  Time.at(v)
14
14
  when String
15
- DateTime.strptime(v).to_time
15
+ v.to_time
16
16
  else
17
17
  Time.now.utc
18
18
  end
@@ -43,4 +43,5 @@ module Keymaker::Serialization
43
43
  self.class.properties.each{|property| hash[property.to_s] }
44
44
  end
45
45
  end
46
+
46
47
  end
@@ -18,8 +18,8 @@ module Keymaker
18
18
 
19
19
  def connection
20
20
  @connection ||= Faraday.new(url: config.connection_service_root_url) do |conn|
21
- conn.use FaradayMiddleware::Mashify
22
21
  conn.request :json
22
+ conn.response :mashify
23
23
  conn.response :json, :content_type => /\bjson$/
24
24
  conn.adapter :net_http
25
25
  end
@@ -36,8 +36,6 @@ module Keymaker
36
36
  super
37
37
  end
38
38
 
39
- ## Nodes
40
- # Create Node
41
39
  def create_node(attrs)
42
40
  # TODO: parse response into manageable Ruby objects
43
41
  create_node_request(attrs)
@@ -49,58 +47,47 @@ module Keymaker
49
47
  data.merge!("neo4j_id" => response.neo4j_id, "__raw_response__" => response)
50
48
  end
51
49
 
52
- # Update Node properties
53
50
  def update_node_properties(node_id, attrs)
54
51
  update_node_properties_request({node_id: node_id}.merge(attrs))
55
52
  end
56
53
 
57
- # Delete Node
58
54
  def delete_node(node_id)
59
55
  delete_node_request(node_id: node_id)
60
56
  end
61
57
 
62
- # Create Relationship
63
58
  def create_relationship(rel_type, start_node_id, end_node_id, data={})
64
59
  create_relationship_request({node_id: start_node_id, rel_type: rel_type, end_node_id: end_node_id, data: data})
65
60
  end
66
61
 
67
- # Delete Relationship
68
62
  def delete_relationship(relationship_id)
69
63
  delete_relationship_request(relationship_id: relationship_id)
70
64
  end
71
65
 
72
- # Add Node to Index
73
66
  def add_node_to_index(index_name, key, value, node_id)
74
67
  add_node_to_index_request(index_name: index_name, key: key, value: value, node_id: node_id)
75
68
  end
76
69
 
77
- # Remove Node from Index
78
70
  def remove_node_from_index(index_name, key, value, node_id)
79
71
  remove_node_from_index_request(index_name: index_name, key: key, value: value, node_id: node_id)
80
72
  end
81
73
 
82
- # Path Traverse
83
74
  def path_traverse(start_node_id, data={})
84
75
  traverse_path_request({node_id: start_node_id}.merge(data))
85
76
  end
86
77
 
87
- # Batch
88
- ## GET Nodes
89
78
  def batch_get_nodes(node_ids)
90
79
  batch_get_nodes_request(node_ids)
91
80
  end
92
81
 
93
- # Cypher Query
94
- def execute_query(query, params)
95
- execute_cypher_request({query: query, params: params}).body
82
+ def execute_cypher(query, params)
83
+ response = execute_cypher_request({query: query, params: params})
84
+ Keymaker::CypherResponseParser.parse(response.body)
96
85
  end
97
86
 
98
- # Gremlin Script
99
87
  def execute_script(script, params={})
100
88
  execute_gremlin_request({script: script, params: params})
101
89
  end
102
90
 
103
- # HTTP Verbs
104
91
  def get(url, body)
105
92
  faraday_response = connection.get(parse_url(url), body)
106
93
  Keymaker::Response.new(self, faraday_response)
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ class Terminator
4
+ include Keymaker::Node
5
+ property :name
6
+ end
7
+
8
+ describe Keymaker::Node do
9
+
10
+ let(:terminator) { Terminator.create(name: 'T1000') }
11
+
12
+ subject { terminator }
13
+
14
+ it_behaves_like "ActiveModel"
15
+
16
+ describe ".create" do
17
+ subject { terminator }
18
+ its(:node_id) { should be_present }
19
+ its(:name) { should == 'T1000' }
20
+ it { should_not be_new }
21
+ it { should be_a(Terminator) }
22
+ end
23
+
24
+ describe ".find(node_id)" do
25
+
26
+ subject { Terminator.find(node_id) }
27
+
28
+ context "when terminator is present" do
29
+ let(:node_id) { terminator.node_id }
30
+
31
+ its(:node_id) { should be_present }
32
+ its(:name) { should == 'T1000' }
33
+ it { should be_present }
34
+ it { should_not be_new }
35
+ it { should be_a(Terminator) }
36
+ end
37
+
38
+ context "when terminator is not present" do
39
+ let(:node_id) { 9001 }
40
+ it "raises an Keymaker::ResourceNotFound error" do
41
+ expect { subject }.to raise_error(Keymaker::ResourceNotFound)
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ describe "#persisted?" do
48
+ let(:new_node) { Terminator.new(name: "T1000") }
49
+ subject { node.persisted? }
50
+
51
+ context "when persisted" do
52
+ let(:node) { new_node.save }
53
+ it { subject.should be_true }
54
+ end
55
+
56
+ context "when not persisted" do
57
+ let(:node) { new_node }
58
+ it { subject.should be_false }
59
+ end
60
+
61
+ end
62
+
63
+ describe "#to_key" do
64
+
65
+ context "when persisted" do
66
+ subject { terminator.to_key }
67
+ it { subject.first.should be_a(Integer) }
68
+ it { subject.should include(terminator.node_id) }
69
+ end
70
+
71
+ context "when not persisted" do
72
+ subject { Terminator.new(name: "T1000").to_key }
73
+ it { subject.should be_blank }
74
+ end
75
+
76
+ end
77
+
78
+ describe "#to_param" do
79
+
80
+ context "when persisted" do
81
+ subject { terminator.to_param }
82
+ it { subject.should == terminator.node_id.to_s }
83
+ end
84
+
85
+ context "when not persisted" do
86
+ subject { Terminator.new(name: "T1000").to_param }
87
+ it { subject.should be_nil }
88
+ end
89
+
90
+ end
91
+
92
+ end