syncano 3.1.1.beta
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.
- checksums.yaml +7 -0
- data/.gitignore +25 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +304 -0
- data/Rakefile +7 -0
- data/lib/generators/syncano/install_generator.rb +17 -0
- data/lib/generators/syncano/templates/initializers/syncano.rb +4 -0
- data/lib/syncano.rb +92 -0
- data/lib/syncano/batch_queue.rb +58 -0
- data/lib/syncano/batch_queue_element.rb +33 -0
- data/lib/syncano/clients/base.rb +115 -0
- data/lib/syncano/clients/rest.rb +69 -0
- data/lib/syncano/clients/sync.rb +132 -0
- data/lib/syncano/errors.rb +13 -0
- data/lib/syncano/jimson_client.rb +34 -0
- data/lib/syncano/packets/auth.rb +7 -0
- data/lib/syncano/packets/base.rb +64 -0
- data/lib/syncano/packets/call.rb +34 -0
- data/lib/syncano/packets/call_response.rb +33 -0
- data/lib/syncano/packets/error.rb +19 -0
- data/lib/syncano/packets/message.rb +30 -0
- data/lib/syncano/packets/notification.rb +39 -0
- data/lib/syncano/packets/ping.rb +12 -0
- data/lib/syncano/query_builder.rb +144 -0
- data/lib/syncano/resources/admin.rb +26 -0
- data/lib/syncano/resources/api_key.rb +46 -0
- data/lib/syncano/resources/base.rb +375 -0
- data/lib/syncano/resources/collection.rb +186 -0
- data/lib/syncano/resources/data_object.rb +304 -0
- data/lib/syncano/resources/folder.rb +34 -0
- data/lib/syncano/resources/notifications/base.rb +103 -0
- data/lib/syncano/resources/notifications/create.rb +20 -0
- data/lib/syncano/resources/notifications/destroy.rb +20 -0
- data/lib/syncano/resources/notifications/message.rb +9 -0
- data/lib/syncano/resources/notifications/update.rb +24 -0
- data/lib/syncano/resources/project.rb +42 -0
- data/lib/syncano/resources/role.rb +11 -0
- data/lib/syncano/resources/subscription.rb +12 -0
- data/lib/syncano/resources/user.rb +47 -0
- data/lib/syncano/response.rb +22 -0
- data/lib/syncano/sync_connection.rb +110 -0
- data/lib/syncano/version.rb +4 -0
- data/spec/admins_spec.rb +16 -0
- data/spec/api_keys_spec.rb +34 -0
- data/spec/collections_spec.rb +67 -0
- data/spec/data_objects_spec.rb +113 -0
- data/spec/folders_spec.rb +39 -0
- data/spec/notifications_spec.rb +43 -0
- data/spec/projects_spec.rb +35 -0
- data/spec/roles_spec.rb +13 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/sync_resources_spec.rb +35 -0
- data/spec/syncano_spec.rb +9 -0
- data/syncano.gemspec +32 -0
- metadata +250 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class Syncano
|
|
2
|
+
module Resources
|
|
3
|
+
module Notifications
|
|
4
|
+
# Notification resource about destroying data object - represents notification with type "delete"
|
|
5
|
+
class Destroy < Syncano::Resources::Notifications::Base
|
|
6
|
+
|
|
7
|
+
# Constructor for Syncano::Notifications::Create object
|
|
8
|
+
# @param [Syncano::Clients::Base] client
|
|
9
|
+
# @param [Hash] attributes
|
|
10
|
+
def initialize(client, attributes)
|
|
11
|
+
super(client, attributes)
|
|
12
|
+
|
|
13
|
+
if attributes.is_a?(::Syncano::Packets::Base)
|
|
14
|
+
self[:target] = attributes.target
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Syncano
|
|
2
|
+
module Resources
|
|
3
|
+
module Notifications
|
|
4
|
+
# Notification resource about updating data object - represents notification with type "change"
|
|
5
|
+
class Update < Syncano::Resources::Notifications::Base
|
|
6
|
+
# Constructor for Syncano::Notifications::Update object
|
|
7
|
+
# @param [Syncano::Clients::Base] client
|
|
8
|
+
# @param [Hash] attributes
|
|
9
|
+
def initialize(client, attributes)
|
|
10
|
+
super(client, attributes)
|
|
11
|
+
|
|
12
|
+
if attributes.is_a?(::Syncano::Packets::Base)
|
|
13
|
+
self.attributes = {
|
|
14
|
+
added: attributes.data[:added],
|
|
15
|
+
updated: attributes.data[:updated],
|
|
16
|
+
deleted: attributes.data[:deleted],
|
|
17
|
+
target: attributes.target
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
class Syncano
|
|
2
|
+
module Resources
|
|
3
|
+
# Project resource
|
|
4
|
+
class Project < ::Syncano::Resources::Base
|
|
5
|
+
# Association has_many :collections
|
|
6
|
+
# @return [Syncano::QueryBuilder] query builder for resource Syncano::Resources::Collection
|
|
7
|
+
def collections
|
|
8
|
+
::Syncano::QueryBuilder.new(client, ::Syncano::Resources::Collection, project_id: id)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Wrapper for api "subscription.subscribe_project" method
|
|
12
|
+
# @return [Syncano::Resource::Project]
|
|
13
|
+
def subscribe
|
|
14
|
+
perform_subscribe
|
|
15
|
+
reload!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Wrapper for api "subscription.unsubscribe_project" method
|
|
19
|
+
# @return [Syncano::Resource::Project]
|
|
20
|
+
def unsubscribe
|
|
21
|
+
perform_unsubscribe
|
|
22
|
+
reload!
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# Executes proper subscribe request
|
|
28
|
+
# @return [Syncano::Response]
|
|
29
|
+
def perform_subscribe
|
|
30
|
+
check_if_sync_client!
|
|
31
|
+
client.make_request(:subscription, :subscribe_project, { project_id: id })
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Executes proper unsubscribe request
|
|
35
|
+
# @return [Syncano::Response]
|
|
36
|
+
def perform_unsubscribe
|
|
37
|
+
check_if_sync_client!
|
|
38
|
+
client.make_request(:subscription, :unsubscribe_project, { project_id: id })
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
class Syncano
|
|
2
|
+
module Resources
|
|
3
|
+
# User resource
|
|
4
|
+
class User < ::Syncano::Resources::Base
|
|
5
|
+
# Wrapper for api "count" method
|
|
6
|
+
# @param [Syncano::Clients::Base] client
|
|
7
|
+
# @param [Hash] scope_parameters
|
|
8
|
+
# @param [Hash] conditions
|
|
9
|
+
# @return [Integer]
|
|
10
|
+
def self.count(client, scope_parameters = {}, conditions = {})
|
|
11
|
+
response = perform_count(client, scope_parameters, conditions)
|
|
12
|
+
response.data if response.status
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
self.scope_parameters = [:project_id, :collection_id]
|
|
18
|
+
|
|
19
|
+
# Prepares hash with attributes used in synchronization with Syncano
|
|
20
|
+
# @return [Hash]
|
|
21
|
+
def self.attributes_to_sync(attributes)
|
|
22
|
+
attributes = attributes.dup
|
|
23
|
+
|
|
24
|
+
if attributes.keys.map(&:to_sym).include?(:avatar)
|
|
25
|
+
if attributes[:avatar].blank?
|
|
26
|
+
attributes[:avatar] = ''
|
|
27
|
+
elsif attributes[:avatar].is_a?(String)
|
|
28
|
+
attributes[:avatar] = Base64.encode64(File.read(attributes[:avatar]))
|
|
29
|
+
else
|
|
30
|
+
attributes.delete(:image)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
attributes
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Executes proper count request
|
|
38
|
+
# @param [Syncano::Clients::Base] client
|
|
39
|
+
# @param [Hash] scope_parameters
|
|
40
|
+
# @param [Hash] conditions
|
|
41
|
+
# @return [Syncano::Response]
|
|
42
|
+
def self.perform_count(client, scope_parameters, conditions)
|
|
43
|
+
make_request(client, nil, :count, conditions.merge(scope_parameters))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class Syncano
|
|
2
|
+
# Represents response from Syncano API
|
|
3
|
+
class Response
|
|
4
|
+
attr_reader :status, :data, :errors
|
|
5
|
+
|
|
6
|
+
# Constructor for Syncano::Response
|
|
7
|
+
# @param [Boolean] status
|
|
8
|
+
# @param [Hash] data
|
|
9
|
+
# @param [Array] errors
|
|
10
|
+
def initialize(status = false, data = nil, errors = [])
|
|
11
|
+
super()
|
|
12
|
+
|
|
13
|
+
self.status = status
|
|
14
|
+
self.data = data
|
|
15
|
+
self.errors = errors
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_writer :status, :data, :errors
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
class Syncano
|
|
2
|
+
# Represents connection with Sync Server
|
|
3
|
+
class SyncConnection < EventMachine::Connection
|
|
4
|
+
attr_reader :client
|
|
5
|
+
|
|
6
|
+
# Constructor for Syncano::SyncConnection object
|
|
7
|
+
def initialize
|
|
8
|
+
super
|
|
9
|
+
|
|
10
|
+
self.callbacks = ::ActiveSupport::HashWithIndifferentAccess.new
|
|
11
|
+
self.callbacks_queue = []
|
|
12
|
+
|
|
13
|
+
self.responses = ::ActiveSupport::HashWithIndifferentAccess.new
|
|
14
|
+
self.responses_queue = []
|
|
15
|
+
|
|
16
|
+
self.client = ::Syncano::Clients::Sync.instance
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Eventmachine callback invoked after completing connection
|
|
20
|
+
def connection_completed
|
|
21
|
+
start_tls
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Eventmachine callback invoked completing ssl handshake
|
|
25
|
+
def ssl_handshake_completed
|
|
26
|
+
auth_data = {
|
|
27
|
+
api_key: client.api_key,
|
|
28
|
+
instance: client.instance_name
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
client.connection = self
|
|
32
|
+
|
|
33
|
+
send_data "#{auth_data.to_json}\n"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Eventmachine callback invoked after receiving data from socket
|
|
37
|
+
# Data are parsed here and processed by callbacks chain
|
|
38
|
+
def receive_data(data)
|
|
39
|
+
data = ::ActiveSupport::HashWithIndifferentAccess.new(JSON.parse(data))
|
|
40
|
+
packet = ::Syncano::Packets::Base.instantize_packet(data)
|
|
41
|
+
|
|
42
|
+
if packet.notification?
|
|
43
|
+
notification = ::Syncano::Resources::Notifications::Base.instantize_notification(client, packet)
|
|
44
|
+
|
|
45
|
+
callbacks_queue.each do |callback_name|
|
|
46
|
+
callbacks[callback_name].call(notification)
|
|
47
|
+
end
|
|
48
|
+
elsif packet.call_response?
|
|
49
|
+
queue_response(packet)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Appends callback method to the end of callbacks chain
|
|
54
|
+
# @param [Symbol, String] callback_name
|
|
55
|
+
# @param [Block] callback
|
|
56
|
+
def append_callback(callback_name, callback)
|
|
57
|
+
callbacks[callback_name] = callback
|
|
58
|
+
callbacks_queue << callback_name
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Prepends callback method to the beginning of callbacks chain
|
|
62
|
+
# @param [Symbol, String] callback_name
|
|
63
|
+
# @param [Block] callback
|
|
64
|
+
def prepend_callback(callback_name, callback)
|
|
65
|
+
callbacks[callback_name] = callback
|
|
66
|
+
callbacks_queue.unshift(callback_name)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Removes callback from callbacks chain
|
|
70
|
+
# @param [Symbol, String] callback_name
|
|
71
|
+
def remove_callback(callback_name)
|
|
72
|
+
callbacks.delete(callback_name)
|
|
73
|
+
callbacks_queue.delete(callback_name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Gets call response packet from the responses queue
|
|
77
|
+
# @param [Integer, String] message_id
|
|
78
|
+
# @return [Syncano::Packets::CallResponse]
|
|
79
|
+
def get_response(message_id)
|
|
80
|
+
responses.delete(message_id)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
attr_accessor :client, :callbacks, :callbacks_queue, :responses, :responses_queue
|
|
86
|
+
|
|
87
|
+
# Adds call response packet to the responses queue
|
|
88
|
+
# @param [Syncano::Packets::CallResponse] packet
|
|
89
|
+
def queue_response(packet)
|
|
90
|
+
prune_responses_queue
|
|
91
|
+
message_id = packet.message_id.to_i
|
|
92
|
+
responses[message_id] = packet
|
|
93
|
+
responses_queue << message_id
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Removes old call response packets from the responses queue
|
|
97
|
+
def prune_responses_queue
|
|
98
|
+
while !responses_queue.empty?
|
|
99
|
+
message_id = responses_queue.first
|
|
100
|
+
|
|
101
|
+
if responses_queue[message_id].nil? || Time.now - responses[message_id].timestamp.to_time > 2.minutes
|
|
102
|
+
responses_queue.shift
|
|
103
|
+
responses.delete(message_id)
|
|
104
|
+
else
|
|
105
|
+
break
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
data/spec/admins_spec.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Syncano::Resource::Admin' do
|
|
4
|
+
it 'should get admins' do
|
|
5
|
+
@client.admins.all.each do |admin|
|
|
6
|
+
admin.id.should_not be_nil
|
|
7
|
+
admin[:email].should_not be_nil
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'should get one admin' do
|
|
12
|
+
admins = @client.admins.all
|
|
13
|
+
|
|
14
|
+
@client.admins.find(admins.last.id)[:name].should == admins.last[:name]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Syncano::Resource::ApiKey' do
|
|
4
|
+
it 'should create new api key in Syncano' do
|
|
5
|
+
count_before = @client.api_keys.count
|
|
6
|
+
api_key = @client.api_keys.create(role_id: '2', description: 'Just testing')
|
|
7
|
+
count_after = @client.api_keys.count
|
|
8
|
+
|
|
9
|
+
(count_after - count_before).should == 1
|
|
10
|
+
@client.api_keys.last[:description].should == 'Just testing'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should get api keys' do
|
|
14
|
+
@client.api_keys.all.each do |api_key|
|
|
15
|
+
api_key.id.should_not be_nil
|
|
16
|
+
api_key[:description].should_not be_nil
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should get one project' do
|
|
21
|
+
api_keys = @client.api_keys.all
|
|
22
|
+
|
|
23
|
+
api_key = @client.api_keys.find(api_keys.last.id)
|
|
24
|
+
api_key[:description].should == api_keys.last[:description]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should destroy project' do
|
|
28
|
+
count_before = @client.api_keys.count
|
|
29
|
+
@client.api_keys.last.destroy
|
|
30
|
+
count_after = @client.api_keys.count
|
|
31
|
+
|
|
32
|
+
(count_before - count_after).should == 1
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Syncano::Resource::Collection' do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@project = @client.projects.last || @client.projects.create(name: 'Test project')
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'should create a new collection in Syncano' do
|
|
9
|
+
count_before = @project.collections.count
|
|
10
|
+
|
|
11
|
+
collection = @project.collections.create(name: 'Test collection', description: 'Just testing')
|
|
12
|
+
collection.id.should_not be_nil
|
|
13
|
+
|
|
14
|
+
count_after = @project.collections.count
|
|
15
|
+
|
|
16
|
+
(count_after - count_before).should == 1
|
|
17
|
+
@project.collections.last[:name].should == 'Test collection'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should get all collections' do
|
|
21
|
+
@project.collections.all.each do |collection|
|
|
22
|
+
collection.id.should_not be_nil
|
|
23
|
+
collection[:name].should_not be_nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should get a one collection' do
|
|
28
|
+
collection = @project.collections.last
|
|
29
|
+
@project.collections.find(collection.id)[:name].should == collection[:name]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should activate inactive collection' do
|
|
33
|
+
collection = @project.collections.last
|
|
34
|
+
|
|
35
|
+
if collection[:status] == 'active'
|
|
36
|
+
collection.deactivate
|
|
37
|
+
collection.reload!
|
|
38
|
+
end
|
|
39
|
+
collection[:status].should == 'inactive'
|
|
40
|
+
|
|
41
|
+
collection.activate
|
|
42
|
+
collection.reload!
|
|
43
|
+
collection['status'].should == 'active'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'should deactivate active collection' do
|
|
47
|
+
collection = @project.collections.last
|
|
48
|
+
|
|
49
|
+
if collection[:status] == 'inactive'
|
|
50
|
+
collection.activate
|
|
51
|
+
collection.reload!
|
|
52
|
+
end
|
|
53
|
+
collection[:status].should == 'active'
|
|
54
|
+
|
|
55
|
+
collection.deactivate
|
|
56
|
+
collection.reload!
|
|
57
|
+
collection[:status].should == 'inactive'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'should destroy a collection' do
|
|
61
|
+
count_before = @project.collections.count
|
|
62
|
+
@project.collections.last.destroy
|
|
63
|
+
count_after = @project.collections.count
|
|
64
|
+
|
|
65
|
+
(count_before - count_after).should == 1
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Syncano::Resource::DataObject' do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@project = @client.projects.last || @client.projects.create(name: 'Test project')
|
|
6
|
+
@collection = @project.collections.last || @project.collections.create(name: 'Test collection')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
after(:all) do
|
|
10
|
+
@client.batch do |q|
|
|
11
|
+
@collection.data_objects.all.each do |data_object|
|
|
12
|
+
q << data_object.batch.destroy
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should create new data object in Syncano' do
|
|
18
|
+
count_before = @collection.data_objects.count
|
|
19
|
+
@collection.data_objects.create(title: 'Test data object', test_attribute: 'test_value')
|
|
20
|
+
count_after = @collection.data_objects.count
|
|
21
|
+
|
|
22
|
+
(count_after - count_before).should == 1
|
|
23
|
+
data_object = @collection.data_objects.last
|
|
24
|
+
data_object[:title].should == 'Test data object'
|
|
25
|
+
data_object[:test_attribute].should == 'test_value'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should copy data object in Syncano' do
|
|
29
|
+
count_before = @collection.data_objects.count
|
|
30
|
+
data_object = @collection.data_objects.last
|
|
31
|
+
data_object.copy
|
|
32
|
+
data_object_copy = @collection.data_objects.last
|
|
33
|
+
count_after = @collection.data_objects.count
|
|
34
|
+
|
|
35
|
+
(count_after - count_before).should == 1
|
|
36
|
+
data_object_copy[:title].should == data_object[:title]
|
|
37
|
+
data_object_copy.id.should_not == data_object.id
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'should get data objects' do
|
|
41
|
+
@collection.data_objects.all.each do |data_object|
|
|
42
|
+
data_object.id.should_not be_nil
|
|
43
|
+
data_object[:state].should_not be_nil
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'should check amount of objects' do
|
|
48
|
+
@collection.data_objects.count.should == @collection.data_objects.all.count
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should get one data object' do
|
|
52
|
+
data_objects = @collection.data_objects.all
|
|
53
|
+
|
|
54
|
+
data_object = @collection.data_objects.find(data_objects.last.id)
|
|
55
|
+
data_object[:title].should == data_objects.last[:title]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'managing parents and children' do
|
|
59
|
+
before(:all) do
|
|
60
|
+
@parent = @collection.data_objects.first(include_children: true)
|
|
61
|
+
@parent = @collection.data_objects.create(title: "Parent object")
|
|
62
|
+
@child = @collection.data_objects.last
|
|
63
|
+
@child = @collection.data_objects.create(title: 'Child object') if @child.id == @parent.id
|
|
64
|
+
@parent.id.should_not == @child.id
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'should add parent to the data object' do
|
|
68
|
+
@parent.remove_child(@child.id) if @parent[:children].present? && @parent[:children].map(&:id).include?(@child.id)
|
|
69
|
+
|
|
70
|
+
@child.add_parent(@parent.id)
|
|
71
|
+
@parent.reload!(include_children: true)
|
|
72
|
+
|
|
73
|
+
@parent[:children].should_not be_nil
|
|
74
|
+
@parent[:children].select{ |c| c.id == @child.id }.first.should_not be_nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'should remove parent from the data object' do
|
|
78
|
+
@parent.add_child(@child.id) unless @parent[:children].present? && @parent[:children].map(&:id).include?(@child.id)
|
|
79
|
+
|
|
80
|
+
@child.remove_parent(@parent.id)
|
|
81
|
+
@parent.reload!(include_children: true)
|
|
82
|
+
|
|
83
|
+
@parent[:children].should be_nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'should add child to the data object' do
|
|
87
|
+
@parent.remove_child(@child.id) if @parent[:children].present? && @parent[:children].map(&:id).include?(@child.id)
|
|
88
|
+
|
|
89
|
+
@parent.add_child(@child.id)
|
|
90
|
+
@parent.reload!(include_children: true)
|
|
91
|
+
|
|
92
|
+
@parent[:children].should_not be_nil
|
|
93
|
+
@parent[:children].select{ |c| c.id == @child.id }.first.should_not be_nil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'should remove child from the data object' do
|
|
97
|
+
@parent.add_child(@child.id) unless @parent[:children].present? && @parent[:children].map(&:id).include?(@child.id)
|
|
98
|
+
|
|
99
|
+
@parent.remove_child(@child.id)
|
|
100
|
+
@parent.reload!(include_children: true)
|
|
101
|
+
|
|
102
|
+
@parent[:children].should be_nil
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'should destroy data object' do
|
|
107
|
+
count_before = @collection.data_objects.count
|
|
108
|
+
@collection.data_objects.last.destroy
|
|
109
|
+
count_after = @collection.data_objects.count
|
|
110
|
+
|
|
111
|
+
(count_before - count_after).should == 1
|
|
112
|
+
end
|
|
113
|
+
end
|