stormpath-sdk 0.4.0 → 1.0.0.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.
- data/.gitignore +6 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +27 -0
- data/CHANGES.md +21 -1
- data/Gemfile +1 -2
- data/README.md +457 -11
- data/Rakefile +15 -1
- data/lib/stormpath-sdk.rb +52 -33
- data/lib/stormpath-sdk/{resource/group_list.rb → api_key.rb} +5 -9
- data/lib/stormpath-sdk/auth/authentication_result.rb +3 -13
- data/lib/stormpath-sdk/auth/basic_authenticator.rb +5 -11
- data/lib/stormpath-sdk/auth/basic_login_attempt.rb +6 -8
- data/lib/stormpath-sdk/auth/username_password_request.rb +2 -5
- data/lib/stormpath-sdk/cache/cache.rb +54 -0
- data/lib/stormpath-sdk/cache/cache_entry.rb +33 -0
- data/lib/stormpath-sdk/cache/cache_manager.rb +22 -0
- data/lib/stormpath-sdk/cache/cache_stats.rb +35 -0
- data/lib/stormpath-sdk/cache/memory_store.rb +29 -0
- data/lib/stormpath-sdk/cache/redis_store.rb +32 -0
- data/lib/stormpath-sdk/client.rb +111 -0
- data/lib/stormpath-sdk/data_store.rb +241 -0
- data/lib/stormpath-sdk/{client/api_key.rb → error.rb} +16 -10
- data/lib/stormpath-sdk/{util → ext}/hash.rb +1 -2
- data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +8 -4
- data/lib/stormpath-sdk/http/http_client_request_executor.rb +8 -7
- data/lib/stormpath-sdk/http/request.rb +4 -8
- data/lib/stormpath-sdk/{util/request_utils.rb → http/utils.rb} +17 -38
- data/lib/stormpath-sdk/resource/account.rb +12 -108
- data/lib/stormpath-sdk/resource/application.rb +35 -171
- data/lib/stormpath-sdk/resource/associations.rb +97 -0
- data/lib/stormpath-sdk/resource/base.rb +256 -0
- data/lib/stormpath-sdk/resource/collection.rb +94 -0
- data/lib/stormpath-sdk/resource/directory.rb +11 -68
- data/lib/stormpath-sdk/resource/email_verification_token.rb +3 -9
- data/lib/stormpath-sdk/resource/error.rb +4 -38
- data/lib/stormpath-sdk/resource/expansion.rb +28 -0
- data/lib/stormpath-sdk/resource/group.rb +8 -66
- data/lib/stormpath-sdk/resource/group_membership.rb +4 -55
- data/lib/stormpath-sdk/resource/{application_list.rb → instance.rb} +7 -13
- data/lib/stormpath-sdk/resource/password_reset_token.rb +5 -23
- data/lib/stormpath-sdk/resource/status.rb +22 -28
- data/lib/stormpath-sdk/resource/tenant.rb +5 -52
- data/lib/stormpath-sdk/resource/utils.rb +43 -13
- data/lib/stormpath-sdk/util/assert.rb +5 -15
- data/lib/stormpath-sdk/version.rb +3 -3
- data/spec/api_key_spec.rb +19 -0
- data/spec/auth/basic_authenticator_spec.rb +25 -0
- data/spec/auth/sauthc1_signer_spec.rb +42 -0
- data/spec/cache/cache_entry_spec.rb +157 -0
- data/spec/cache/cache_spec.rb +89 -0
- data/spec/cache/cache_stats_spec.rb +106 -0
- data/spec/client_spec.rb +538 -0
- data/spec/data_store_spec.rb +130 -0
- data/spec/resource/account_spec.rb +74 -0
- data/spec/resource/application_spec.rb +148 -0
- data/spec/resource/base_spec.rb +114 -0
- data/spec/resource/collection_spec.rb +169 -0
- data/spec/resource/directory_spec.rb +30 -0
- data/spec/resource/expansion_spec.rb +100 -0
- data/spec/resource/group_spec.rb +49 -0
- data/spec/spec_helper.rb +135 -0
- data/spec/support/resource_factory.rb +48 -0
- data/spec/support/resource_matchers.rb +27 -0
- data/spec/support/test_cache_stores.rb +9 -0
- data/spec/support/test_request_executor.rb +11 -0
- data/stormpath-sdk.gemspec +14 -4
- data/support/api.rb +55 -0
- metadata +214 -44
- data/lib/stormpath-sdk/client/client.rb +0 -38
- data/lib/stormpath-sdk/client/client_application.rb +0 -38
- data/lib/stormpath-sdk/client/client_application_builder.rb +0 -351
- data/lib/stormpath-sdk/client/client_builder.rb +0 -305
- data/lib/stormpath-sdk/ds/data_store.rb +0 -210
- data/lib/stormpath-sdk/ds/resource_factory.rb +0 -37
- data/lib/stormpath-sdk/resource/account_list.rb +0 -32
- data/lib/stormpath-sdk/resource/collection_resource.rb +0 -91
- data/lib/stormpath-sdk/resource/directory_list.rb +0 -30
- data/lib/stormpath-sdk/resource/group_membership_list.rb +0 -32
- data/lib/stormpath-sdk/resource/instance_resource.rb +0 -28
- data/lib/stormpath-sdk/resource/resource.rb +0 -327
- data/lib/stormpath-sdk/resource/resource_error.rb +0 -47
- data/test/client/client.yml +0 -16
- data/test/client/client_application_builder_spec.rb +0 -114
- data/test/client/client_builder_spec.rb +0 -176
- data/test/client/read_spec.rb +0 -254
- data/test/client/write_spec.rb +0 -420
- data/test/resource/resource_spec.rb +0 -41
- data/test/resource/test_resource.rb +0 -28
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stormpath::DataStore do
|
4
|
+
let(:factory) { Stormpath::Test::ResourceFactory.new }
|
5
|
+
let(:request_executor) { Stormpath::Test::TestRequestExecutor.new }
|
6
|
+
let(:store) { Stormpath::Cache::RedisStore }
|
7
|
+
let(:data_store) { Stormpath::DataStore.new request_executor, {store: store}, nil, nil }
|
8
|
+
let(:application_cache) { data_store.cache_manager.get_cache 'applications' }
|
9
|
+
let(:tenant_cache) { data_store.cache_manager.get_cache 'tenants' }
|
10
|
+
let(:group_cache) { data_store.cache_manager.get_cache 'groups' }
|
11
|
+
|
12
|
+
after do
|
13
|
+
application_cache.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.region_for' do
|
17
|
+
let(:region) { data_store.send(:region_for, 'https://api.stormpath.com/v1/directories/4NykYrYH0OBiOOVOg8LXQ5') }
|
18
|
+
it 'pulls resource name from href' do
|
19
|
+
expect(region).to eq('directories')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#delete' do
|
24
|
+
before do
|
25
|
+
resource = factory.resource 'application', 1, %w(tenant groups)
|
26
|
+
href = resource['href']
|
27
|
+
request_executor.response = MultiJson.dump resource
|
28
|
+
application = data_store.get_resource href, Stormpath::Resource::Application
|
29
|
+
expect(application_cache.size).to eq(1)
|
30
|
+
data_store.delete application
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'removes the resource from the cache' do
|
34
|
+
expect(application_cache.size).to be(0)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#get_resource' do
|
39
|
+
context 'shallow resource' do
|
40
|
+
before do
|
41
|
+
resource = factory.resource 'application', 1, %w(tenant groups)
|
42
|
+
href = resource['href']
|
43
|
+
request_executor.response = MultiJson.dump resource
|
44
|
+
data_store.get_resource href, Stormpath::Resource::Application
|
45
|
+
@cached = application_cache.get href
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'caches a shallow resource' do
|
49
|
+
expect(@cached).to be
|
50
|
+
expect(@cached).to be_resource
|
51
|
+
expect(@cached['tenant']).to be_link
|
52
|
+
expect(@cached['groups']).to be_link_collection
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'caches no associations' do
|
56
|
+
expect(tenant_cache.size).to eq(0)
|
57
|
+
expect(group_cache.size).to eq(0)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'misses the cache on the get' do
|
61
|
+
expect(application_cache.stats.hits).to eq(1) # this hit is when we grab @cached
|
62
|
+
expect(application_cache.stats.misses).to eq(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'retrieved twice' do
|
66
|
+
before do
|
67
|
+
data_store.get_resource @cached['href'], Stormpath::Resource::Application
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'hits the cache on the get' do
|
71
|
+
expect(application_cache.stats.hits).to eq(2)
|
72
|
+
expect(application_cache.stats.misses).to eq(1)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'deep resource' do
|
78
|
+
before do
|
79
|
+
resource = factory.resource 'application', 2, %w(tenant groups)
|
80
|
+
href = resource['href']
|
81
|
+
request_executor.response = MultiJson.dump resource
|
82
|
+
data_store.get_resource href, Stormpath::Resource::Application
|
83
|
+
@cached = application_cache.get href
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'caches a shallow resource' do
|
87
|
+
expect(@cached).to be
|
88
|
+
expect(@cached).to be_resource
|
89
|
+
expect(@cached['tenant']).to be_link
|
90
|
+
expect(@cached['groups']).to be_link_collection
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'caches shallow associations' do
|
94
|
+
expect(tenant_cache.size).to eq(1)
|
95
|
+
expect(group_cache.size).to eq(2)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'shallow collection' do
|
100
|
+
before do
|
101
|
+
resource = factory.collection 'tenant', 'application', 1, %w(tenant groups)
|
102
|
+
href = resource['href']
|
103
|
+
request_executor.response = MultiJson.dump resource
|
104
|
+
data_store.get_resource href, Stormpath::Resource::Application
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'caches collection resources only' do
|
108
|
+
expect(application_cache.size).to eq(2)
|
109
|
+
expect(tenant_cache.size).to eq(0)
|
110
|
+
expect(group_cache.size).to eq(0)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'deep collection' do
|
115
|
+
before do
|
116
|
+
resource = factory.collection 'tenant', 'application', 2, %w(tenant groups)
|
117
|
+
href = resource['href']
|
118
|
+
request_executor.response = MultiJson.dump resource
|
119
|
+
data_store.get_resource href, Stormpath::Resource::Application
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'caches collection resources and associations' do
|
123
|
+
expect(application_cache.size).to eq(2)
|
124
|
+
expect(tenant_cache.size).to eq(2)
|
125
|
+
expect(group_cache.size).to eq(4)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stormpath::Resource::Account, :vcr do
|
4
|
+
describe "#add_group" do
|
5
|
+
context "given a group" do
|
6
|
+
let(:directory) do
|
7
|
+
test_api_client.directories.create name: 'testDirectory'
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:group) do
|
11
|
+
directory.groups.create name: 'testGroup'
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:account) do
|
15
|
+
directory.accounts.create email: 'test@example.com',
|
16
|
+
givenName: 'Ruby SDK',
|
17
|
+
password: 'P@$$w0rd',
|
18
|
+
surname: 'SDK',
|
19
|
+
username: 'rubysdk'
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:reloaded_account) do
|
23
|
+
test_api_client.accounts.get account.href
|
24
|
+
end
|
25
|
+
|
26
|
+
before do
|
27
|
+
account.add_group group
|
28
|
+
end
|
29
|
+
|
30
|
+
after do
|
31
|
+
account.delete if account
|
32
|
+
group.delete if group
|
33
|
+
directory.delete if directory
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'adds the group to the account' do
|
37
|
+
group_added = false
|
38
|
+
reloaded_account.groups.each do |g|
|
39
|
+
group_added = true if g.href == group.href
|
40
|
+
end
|
41
|
+
expect(group_added).to be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#save' do
|
47
|
+
context 'when property values have changed' do
|
48
|
+
let(:account) do
|
49
|
+
test_directory.accounts.create build_account
|
50
|
+
end
|
51
|
+
let(:account_uri) do
|
52
|
+
account.href
|
53
|
+
end
|
54
|
+
let(:new_surname) do
|
55
|
+
"NewSurname"
|
56
|
+
end
|
57
|
+
let(:reloaded_account) { test_api_client.accounts.get account_uri }
|
58
|
+
|
59
|
+
before do
|
60
|
+
account = test_api_client.accounts.get account_uri
|
61
|
+
account.surname = new_surname
|
62
|
+
account.save
|
63
|
+
end
|
64
|
+
|
65
|
+
after do
|
66
|
+
account.delete if account
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'saves changes to the account' do
|
70
|
+
expect(reloaded_account.surname).to eq(new_surname)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stormpath::Resource::Application, :vcr do
|
4
|
+
let(:application) { test_application }
|
5
|
+
let(:directory) { test_directory }
|
6
|
+
|
7
|
+
describe '.load' do
|
8
|
+
let(:url) do
|
9
|
+
uri = URI(application.href)
|
10
|
+
credentialed_uri = URI::HTTPS.new(
|
11
|
+
uri.scheme, "#{test_api_key_id}:#{test_api_key_secret}", uri.host,
|
12
|
+
uri.port, uri.registry, uri.path, uri.query, uri.opaque, uri.fragment
|
13
|
+
)
|
14
|
+
credentialed_uri.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
it "raises a LoadError with an invalid url" do
|
18
|
+
expect {
|
19
|
+
Stormpath::Resource::Application.load 'this is an invalid url'
|
20
|
+
}.to raise_error(Stormpath::Resource::Application::LoadError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "instantiates client and application objects from a composite URL" do
|
24
|
+
loaded_application = Stormpath::Resource::Application.load(url)
|
25
|
+
expect(loaded_application).to eq(application)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#authenticate_account' do
|
30
|
+
let(:account) do
|
31
|
+
directory.accounts.create build_account(password: 'P@$$w0rd')
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:login_request) do
|
35
|
+
Stormpath::Authentication::UsernamePasswordRequest.new account.username, password
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:authentication_result) do
|
39
|
+
application.authenticate_account login_request
|
40
|
+
end
|
41
|
+
|
42
|
+
after do
|
43
|
+
account.delete if account
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'given a valid username and password' do
|
47
|
+
let(:password) {'P@$$w0rd' }
|
48
|
+
|
49
|
+
it 'returns an authentication result' do
|
50
|
+
expect(authentication_result).to be
|
51
|
+
expect(authentication_result.account).to be
|
52
|
+
expect(authentication_result.account).to be_kind_of Stormpath::Resource::Account
|
53
|
+
expect(authentication_result.account.email).to eq(account.email)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'given an invalid username and password' do
|
58
|
+
let(:password) { 'b@dP@$$w0rd' }
|
59
|
+
|
60
|
+
it 'raises an error' do
|
61
|
+
expect { authentication_result }.to raise_error Stormpath::Error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#send_password_reset_email' do
|
67
|
+
context 'given an email' do
|
68
|
+
context 'of an exisiting account on the application' do
|
69
|
+
let(:account) { directory.accounts.create build_account }
|
70
|
+
|
71
|
+
let(:sent_to_account) { application.send_password_reset_email account.email }
|
72
|
+
|
73
|
+
after do
|
74
|
+
account.delete if account
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'sends a password reset request of the account' do
|
78
|
+
expect(sent_to_account).to be
|
79
|
+
expect(sent_to_account).to be_kind_of Stormpath::Resource::Account
|
80
|
+
expect(sent_to_account.email).to eq(account.email)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'of a non exisitng account' do
|
85
|
+
it 'raises an exception' do
|
86
|
+
expect do
|
87
|
+
application.send_password_reset_email "test@example.com"
|
88
|
+
end.to raise_error Stormpath::Error
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#verify_password_reset_token' do
|
95
|
+
let(:account) do
|
96
|
+
directory.accounts.create({
|
97
|
+
email: 'test@example.com',
|
98
|
+
given_name: 'Ruby SDK',
|
99
|
+
password: 'P@$$w0rd',
|
100
|
+
surname: 'SDK',
|
101
|
+
username: 'rubysdk'
|
102
|
+
})
|
103
|
+
end
|
104
|
+
|
105
|
+
let(:password_reset_token) do
|
106
|
+
application.password_reset_tokens.create(email: account.email).token
|
107
|
+
end
|
108
|
+
|
109
|
+
let(:reset_password_account) do
|
110
|
+
application.verify_password_reset_token password_reset_token
|
111
|
+
end
|
112
|
+
|
113
|
+
after do
|
114
|
+
account.delete if account
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'retrieves the account with the reset password' do
|
118
|
+
expect(reset_password_account).to be
|
119
|
+
expect(reset_password_account.email).to eq(account.email)
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'and if the password is changed' do
|
123
|
+
let(:new_password) { 'N3wP@$$w0rd' }
|
124
|
+
|
125
|
+
let(:login_request) do
|
126
|
+
Stormpath::Authentication::UsernamePasswordRequest.new account.username, new_password
|
127
|
+
end
|
128
|
+
|
129
|
+
let(:expected_email) { 'test2@example.com' }
|
130
|
+
|
131
|
+
let(:authentication_result) do
|
132
|
+
application.authenticate_account login_request
|
133
|
+
end
|
134
|
+
|
135
|
+
before do
|
136
|
+
reset_password_account.password = new_password
|
137
|
+
reset_password_account.save
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'can be successfully authenticated' do
|
141
|
+
expect(authentication_result).to be
|
142
|
+
expect(authentication_result.account).to be
|
143
|
+
expect(authentication_result.account).to be_kind_of Stormpath::Resource::Account
|
144
|
+
expect(authentication_result.account.email).to eq(account.email)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stormpath::Resource::Base do
|
4
|
+
describe '.prop_accessor' do
|
5
|
+
context 'given property names' do
|
6
|
+
class TestResource < Stormpath::Resource::Base
|
7
|
+
prop_accessor :username, :given_name
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:resource) do
|
11
|
+
TestResource.new({
|
12
|
+
'username' => 'bar',
|
13
|
+
'givenName' => 'foo'
|
14
|
+
}, nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'generates a getter method for each property' do
|
18
|
+
expect(resource.username).to eq('bar')
|
19
|
+
expect(resource.given_name).to eq('foo')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'generates a setter for each property' do
|
23
|
+
resource.username = 'foo'
|
24
|
+
resource.given_name = 'bar'
|
25
|
+
expect(resource.properties).to include('username' => 'foo')
|
26
|
+
expect(resource.properties).to include('givenName' => 'bar')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.non_printable' do
|
32
|
+
context 'given property names' do
|
33
|
+
class TestResource < Stormpath::Resource::Base
|
34
|
+
prop_non_printable :password
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:resource) do
|
38
|
+
TestResource.new({
|
39
|
+
'username' => 'bar',
|
40
|
+
'password' => 'P@$$w0rd'
|
41
|
+
}, nil)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'marks that property as not being printable' do
|
45
|
+
expect(resource.inspect).to include('username')
|
46
|
+
expect(resource.inspect).to_not include('password')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '.get_property' do
|
52
|
+
context 'given the name of a dirty property' do
|
53
|
+
class TestResource < Stormpath::Resource::Base
|
54
|
+
prop_accessor :username
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:resource) do
|
58
|
+
TestResource.new('http://foo.com/test/123', nil).tap do |resource|
|
59
|
+
resource.username = 'foo'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does NOT attempt to materialize the entire resource' do
|
64
|
+
expect(resource.username).to eq('foo')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#==' do
|
70
|
+
class TestResource < Stormpath::Resource::Base; end
|
71
|
+
|
72
|
+
context 'compared against an object of the same class' do
|
73
|
+
let(:resource) do
|
74
|
+
TestResource.new('http://foo.com/test/123')
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'href matches' do
|
78
|
+
let(:other) do
|
79
|
+
TestResource.new('http://foo.com/test/123')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'passes' do
|
83
|
+
expect(resource).to eq(other)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'href does not match' do
|
88
|
+
let(:other) do
|
89
|
+
TestResource.new('http://foo.com/test/456')
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'fails' do
|
93
|
+
expect(resource).to_not eq(other)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'compared against an object of another class' do
|
99
|
+
class NotAResource; end
|
100
|
+
|
101
|
+
let(:resource) do
|
102
|
+
TestResource.new('http://foo.com/test/123')
|
103
|
+
end
|
104
|
+
|
105
|
+
let(:other) do
|
106
|
+
NotAResource.new
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'fails' do
|
110
|
+
expect(resource).to_not eq(other)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|