orcid 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +10 -0
- data/.hound.yml +793 -0
- data/.travis.yml +14 -0
- data/Gemfile +14 -0
- data/README.md +107 -6
- data/Rakefile +17 -9
- data/app/assets/images/orcid/.keep +0 -0
- data/app/controllers/orcid/application_controller.rb +13 -4
- data/app/controllers/orcid/profile_connections_controller.rb +34 -6
- data/app/controllers/orcid/profile_requests_controller.rb +18 -15
- data/app/models/orcid/profile.rb +15 -5
- data/app/models/orcid/profile_connection.rb +20 -20
- data/app/models/orcid/profile_request.rb +39 -20
- data/app/models/orcid/work.rb +45 -55
- data/app/models/orcid/work/xml_parser.rb +45 -0
- data/app/models/orcid/work/xml_renderer.rb +29 -0
- data/app/services/orcid/remote/profile_creation_service.rb +40 -32
- data/app/services/orcid/remote/profile_query_service.rb +82 -0
- data/app/services/orcid/remote/profile_query_service/query_parameter_builder.rb +43 -0
- data/app/services/orcid/remote/profile_query_service/search_response.rb +31 -0
- data/app/services/orcid/remote/service.rb +16 -13
- data/app/services/orcid/remote/work_service.rb +58 -43
- data/app/templates/orcid/work.template.v1.1.xml.erb +32 -1
- data/app/views/orcid/profile_connections/_orcid_connector.html.erb +14 -0
- data/app/views/orcid/profile_connections/new.html.erb +4 -4
- data/bin/rails +8 -0
- data/config/{application.yml → application.yml.example} +3 -13
- data/config/locales/orcid.en.yml +5 -1
- data/config/routes.rb +4 -2
- data/lib/generators/orcid/install/install_generator.rb +46 -7
- data/lib/orcid.rb +23 -11
- data/lib/orcid/configuration.rb +32 -13
- data/lib/orcid/configuration/provider.rb +27 -13
- data/lib/orcid/engine.rb +20 -4
- data/lib/orcid/exceptions.rb +33 -4
- data/lib/orcid/named_callbacks.rb +3 -1
- data/lib/orcid/spec_support.rb +19 -9
- data/lib/orcid/version.rb +1 -1
- data/lib/tasks/orcid_tasks.rake +3 -3
- data/orcid.gemspec +51 -0
- data/rubocop.txt +1164 -0
- data/script/fast_specs +22 -0
- data/spec/controllers/orcid/profile_connections_controller_spec.rb +101 -0
- data/spec/controllers/orcid/profile_requests_controller_spec.rb +116 -0
- data/spec/factories/orcid_profile_requests.rb +11 -0
- data/spec/factories/users.rb +9 -0
- data/spec/fast_helper.rb +12 -0
- data/spec/features/batch_profile_spec.rb +31 -0
- data/spec/features/non_ui_based_interactions_spec.rb +117 -0
- data/spec/features/profile_connection_feature_spec.rb +19 -0
- data/spec/features/public_api_query_spec.rb +36 -0
- data/spec/fixtures/orcid_works.xml +55 -0
- data/spec/lib/orcid/configuration/provider_spec.rb +40 -0
- data/spec/lib/orcid/configuration_spec.rb +38 -0
- data/spec/lib/orcid/named_callbacks_spec.rb +28 -0
- data/spec/lib/orcid_spec.rb +97 -0
- data/spec/models/orcid/profile_connection_spec.rb +81 -0
- data/spec/models/orcid/profile_request_spec.rb +131 -0
- data/spec/models/orcid/profile_spec.rb +76 -0
- data/spec/models/orcid/work/xml_parser_spec.rb +40 -0
- data/spec/models/orcid/work/xml_renderer_spec.rb +18 -0
- data/spec/models/orcid/work_spec.rb +53 -0
- data/spec/services/orcid/remote/profile_creation_service_spec.rb +40 -0
- data/spec/services/orcid/remote/profile_query_service/query_parameter_builder_spec.rb +44 -0
- data/spec/services/orcid/remote/profile_query_service/search_response_spec.rb +14 -0
- data/spec/services/orcid/remote/profile_query_service_spec.rb +118 -0
- data/spec/services/orcid/remote/service_spec.rb +26 -0
- data/spec/services/orcid/remote/work_service_spec.rb +44 -0
- data/spec/spec_helper.rb +99 -0
- data/spec/support/non_orcid_models.rb +11 -0
- data/spec/support/stub_callback.rb +25 -0
- data/spec/test_app_templates/Gemfile.extra +3 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +36 -0
- data/spec/views/orcid/profile_connections/new.html.erb_spec.rb +25 -0
- data/spec/views/orcid/profile_requests/new.html.erb_spec.rb +23 -0
- metadata +119 -29
- data/app/runners/orcid/profile_lookup_runner.rb +0 -33
- data/app/runners/orcid/runner.rb +0 -15
- data/app/services/orcid/remote/profile_lookup_service.rb +0 -56
- data/app/services/orcid/remote/profile_lookup_service/search_response.rb +0 -23
- data/lib/orcid/query_parameter_builder.rb +0 -38
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'public api query', requires_net_connect: true do
|
4
|
+
around(:each) do |example|
|
5
|
+
WebMock.allow_net_connect!
|
6
|
+
example.run
|
7
|
+
WebMock.disable_net_connect!
|
8
|
+
end
|
9
|
+
|
10
|
+
Given(:runner) {
|
11
|
+
Orcid::Remote::ProfileQueryService.new
|
12
|
+
}
|
13
|
+
context 'with simple query' do
|
14
|
+
Given(:parameters) { { email: 'jeremy.n.friesen@gmail.com' } }
|
15
|
+
When(:result) { runner.call(parameters) }
|
16
|
+
Then { expect(result.size).to eq(1) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with bad query' do
|
20
|
+
Given(:parameters) { { hobomancer: 'jeremy.n.friesen@gmail.com' } }
|
21
|
+
When(:result) { runner.call(parameters) }
|
22
|
+
Then { expect(result).to have_failed(OAuth2::Error) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with a text query' do
|
26
|
+
Given(:parameters) { { text: '"Jeremy Friesen"' } }
|
27
|
+
When(:result) { runner.call(parameters) }
|
28
|
+
Then { expect(result.size).to be > 0 }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with a compound text query' do
|
32
|
+
Given(:parameters) { { email: "nobody@gmail.com", text: '"Jeremy+Friesen"' } }
|
33
|
+
When(:result) { runner.call(parameters) }
|
34
|
+
Then { expect(result.size).to eq 0 }
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
2
|
+
<orcid-message xmlns="http://www.orcid.org/ns/orcid">
|
3
|
+
<message-version>1.1</message-version>
|
4
|
+
<orcid-profile type="user">
|
5
|
+
<orcid-identifier>
|
6
|
+
<uri>http://sandbox.orcid.org/0000-0002-1117-8571</uri>
|
7
|
+
<path>0000-0002-1117-8571</path>
|
8
|
+
<host>sandbox.orcid.org</host>
|
9
|
+
</orcid-identifier>
|
10
|
+
<orcid-preferences>
|
11
|
+
<locale>en</locale>
|
12
|
+
</orcid-preferences>
|
13
|
+
<orcid-history>
|
14
|
+
<creation-method>API</creation-method>
|
15
|
+
<completion-date>2014-02-14T15:32:15.453Z</completion-date>
|
16
|
+
<submission-date>2014-02-14T15:31:12.816Z</submission-date>
|
17
|
+
<last-modified-date>2014-02-18T20:23:40.472Z</last-modified-date>
|
18
|
+
<claimed>true</claimed>
|
19
|
+
<source>
|
20
|
+
<source-orcid>
|
21
|
+
<uri>http://sandbox.orcid.org/0000-0002-6683-6607</uri>
|
22
|
+
<path>0000-0002-6683-6607</path>
|
23
|
+
<host>sandbox.orcid.org</host>
|
24
|
+
</source-orcid>
|
25
|
+
<source-name>Hydra ORCID Integrator</source-name>
|
26
|
+
</source>
|
27
|
+
</orcid-history>
|
28
|
+
<orcid-activities>
|
29
|
+
<orcid-works>
|
30
|
+
<orcid-work put-code="303475" visibility="public">
|
31
|
+
<work-title>
|
32
|
+
<title>Another Test Drive</title>
|
33
|
+
</work-title>
|
34
|
+
<work-type>test</work-type>
|
35
|
+
<work-source>
|
36
|
+
<uri>http://sandbox.orcid.org/0000-0002-6683-6607</uri>
|
37
|
+
<path>0000-0002-6683-6607</path>
|
38
|
+
<host>sandbox.orcid.org</host>
|
39
|
+
</work-source>
|
40
|
+
</orcid-work>
|
41
|
+
<orcid-work put-code="303474" visibility="public">
|
42
|
+
<work-title>
|
43
|
+
<title>Test Driven Orcid Integration</title>
|
44
|
+
</work-title>
|
45
|
+
<work-type>test</work-type>
|
46
|
+
<work-source>
|
47
|
+
<uri>http://sandbox.orcid.org/0000-0002-6683-6607</uri>
|
48
|
+
<path>0000-0002-6683-6607</path>
|
49
|
+
<host>sandbox.orcid.org</host>
|
50
|
+
</work-source>
|
51
|
+
</orcid-work>
|
52
|
+
</orcid-works>
|
53
|
+
</orcid-activities>
|
54
|
+
</orcid-profile>
|
55
|
+
</orcid-message>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'fast_helper'
|
2
|
+
require 'orcid/configuration/provider'
|
3
|
+
|
4
|
+
module Orcid
|
5
|
+
describe Configuration::Provider do
|
6
|
+
|
7
|
+
let(:storage) {
|
8
|
+
{
|
9
|
+
'ORCID_APP_AUTHENTICATION_SCOPE' => '_APP_AUTHENTICATION_SCOPE',
|
10
|
+
'ORCID_SITE_URL' => '_SITE_URL',
|
11
|
+
'ORCID_TOKEN_URL' => '_TOKEN_URL',
|
12
|
+
'ORCID_REMOTE_SIGNIN_URL' => '_REMOTE_SIGNIN_URL',
|
13
|
+
'ORCID_AUTHORIZE_URL' => '_AUTHORIZE_URL',
|
14
|
+
'ORCID_APP_ID' => '_APP_ID',
|
15
|
+
'ORCID_APP_SECRET' => '_APP_SECRET',
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
subject { described_class.new(storage) }
|
20
|
+
|
21
|
+
its(:authentication_scope) { should eq storage.fetch('ORCID_APP_AUTHENTICATION_SCOPE') }
|
22
|
+
its(:site_url) { should eq storage.fetch('ORCID_SITE_URL') }
|
23
|
+
its(:token_url) { should eq storage.fetch('ORCID_TOKEN_URL') }
|
24
|
+
its(:signin_via_json_url) { should eq storage.fetch('ORCID_REMOTE_SIGNIN_URL') }
|
25
|
+
its(:authorize_url) { should eq storage.fetch('ORCID_AUTHORIZE_URL') }
|
26
|
+
its(:id) { should eq storage.fetch('ORCID_APP_ID') }
|
27
|
+
its(:secret) { should eq storage.fetch('ORCID_APP_SECRET') }
|
28
|
+
|
29
|
+
context 'with an empty ENV' do
|
30
|
+
Given(:provider) { described_class.new({}) }
|
31
|
+
Then { expect(provider.authentication_scope).to be_an_instance_of(String) }
|
32
|
+
And { expect(provider.site_url).to be_an_instance_of(String) }
|
33
|
+
And { expect(provider.token_url).to be_an_instance_of(String) }
|
34
|
+
And { expect(provider.signin_via_json_url).to be_an_instance_of(String) }
|
35
|
+
And { expect(provider.authorize_url).to be_an_instance_of(String) }
|
36
|
+
And { expect { provider.id }.to raise_error Orcid::ConfigurationError }
|
37
|
+
And { expect { provider.secret }.to raise_error Orcid::ConfigurationError }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Orcid
|
4
|
+
describe Configuration do
|
5
|
+
|
6
|
+
subject { described_class.new }
|
7
|
+
|
8
|
+
its(:parent_controller) { should be_an_instance_of String }
|
9
|
+
its(:provider) { should be_an_instance_of Configuration::Provider }
|
10
|
+
its(:authentication_model) { should eq Devise::MultiAuth::Authentication }
|
11
|
+
|
12
|
+
its(:mapper) { should respond_to :map }
|
13
|
+
its(:mapper) { should respond_to :configure }
|
14
|
+
|
15
|
+
context 'mapping to an Orcid::Work' do
|
16
|
+
let(:legend) {
|
17
|
+
[
|
18
|
+
[:title, :title],
|
19
|
+
[lambda{|*| 'spaghetti'}, :work_type]
|
20
|
+
]
|
21
|
+
}
|
22
|
+
let(:title) { 'Hello World' }
|
23
|
+
let(:article) { NonOrcid::Article.new(title: title)}
|
24
|
+
before(:each) do
|
25
|
+
subject.register_mapping_to_orcid_work('non_orcid/article', legend)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should configure the mapper' do
|
29
|
+
orcid_work = subject.mapper.map(article, target: 'orcid/work')
|
30
|
+
expect(orcid_work.work_type).to eq('spaghetti')
|
31
|
+
expect(orcid_work.title).to eq(title)
|
32
|
+
expect(orcid_work).to be_an_instance_of(Orcid::Work)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'fast_helper'
|
2
|
+
require './lib/orcid/named_callbacks'
|
3
|
+
|
4
|
+
module Orcid
|
5
|
+
describe NamedCallbacks do
|
6
|
+
Given(:named_callback) { NamedCallbacks.new }
|
7
|
+
Given(:context) { [ ] }
|
8
|
+
Given { named_callback.my_named_callback { |*a| context.replace(a) } }
|
9
|
+
|
10
|
+
describe "with a named callback" do
|
11
|
+
Given(:callback_name) { :my_named_callback }
|
12
|
+
When { named_callback.call(callback_name, 'a',:hello) }
|
13
|
+
Then { context == ['a', :hello] }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with a named callback called by a string" do
|
17
|
+
Given(:callback_name) { 'my_named_callback' }
|
18
|
+
When { named_callback.call(callback_name, 'a',:hello) }
|
19
|
+
Then { context == ['a', :hello] }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "with a undeclared callback" do
|
23
|
+
When(:result) { named_callback.call(:undeclared_callback, 1, 2, 3) }
|
24
|
+
Then { result }
|
25
|
+
Then { context == [] }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Orcid do
|
4
|
+
let(:user) { FactoryGirl.build_stubbed(:user) }
|
5
|
+
let(:orcid_profile_id) { '0001-0002-0003-0004' }
|
6
|
+
subject { described_class }
|
7
|
+
its(:provider) { should respond_to :id }
|
8
|
+
its(:provider) { should respond_to :secret }
|
9
|
+
its(:mapper) { should respond_to :map }
|
10
|
+
its(:use_relative_model_naming?) { should eq true }
|
11
|
+
|
12
|
+
context '.authentication_model' do
|
13
|
+
subject { Orcid.authentication_model }
|
14
|
+
it { should respond_to :to_access_token }
|
15
|
+
it { should respond_to :create! }
|
16
|
+
it { should respond_to :count }
|
17
|
+
it { should respond_to :where }
|
18
|
+
end
|
19
|
+
|
20
|
+
context '.oauth_client' do
|
21
|
+
subject { Orcid.oauth_client }
|
22
|
+
its(:client_credentials) { should respond_to :get_token }
|
23
|
+
end
|
24
|
+
|
25
|
+
context '.configure' do
|
26
|
+
it 'should yield a configuration' do
|
27
|
+
expect{|b| Orcid.configure(&b) }.to yield_with_args(Orcid::Configuration)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context '.profile_for' do
|
32
|
+
it 'should return nil if none is found' do
|
33
|
+
expect(Orcid.profile_for(user)).to eq(nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should return an Orcid::Profile if the user has an orcid authentication' do
|
37
|
+
Orcid.connect_user_and_orcid_profile(user,orcid_profile_id)
|
38
|
+
expect(Orcid.profile_for(user).orcid_profile_id).to eq(orcid_profile_id)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context '.client_credentials_token' do
|
43
|
+
let(:tokenizer) { double('Tokenizer') }
|
44
|
+
let(:scope) { '/my-scope' }
|
45
|
+
let(:token) { double('Token') }
|
46
|
+
|
47
|
+
it 'should request the scoped token from the tokenizer' do
|
48
|
+
tokenizer.should_receive(:get_token).with(scope: scope).and_return(token)
|
49
|
+
expect(Orcid.client_credentials_token(scope, tokenizer: tokenizer)).to eq(token)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context '.connect_user_and_orcid_profile' do
|
54
|
+
|
55
|
+
it 'changes the authentication count' do
|
56
|
+
expect {
|
57
|
+
Orcid.connect_user_and_orcid_profile(user, orcid_profile_id)
|
58
|
+
}.to change(Orcid.authentication_model, :count).by(1)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context '.access_token_for' do
|
63
|
+
let(:client) { double("Client")}
|
64
|
+
let(:token) { double('Token') }
|
65
|
+
let(:tokenizer) { double("Tokenizer") }
|
66
|
+
|
67
|
+
it 'delegates to .authentication' do
|
68
|
+
tokenizer.should_receive(:to_access_token).with(provider: 'orcid', uid: orcid_profile_id, client: client).and_return(token)
|
69
|
+
expect(Orcid.access_token_for(orcid_profile_id, client: client, tokenizer: tokenizer)).to eq(token)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context '.enqueue' do
|
74
|
+
let(:object) { double }
|
75
|
+
|
76
|
+
it 'should #run the object' do
|
77
|
+
object.should_receive(:run)
|
78
|
+
Orcid.enqueue(object)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context '#authenticated_orcid' do
|
83
|
+
it 'should not be authenticated' do
|
84
|
+
Orcid.authenticated_orcid?(orcid_profile_id).should eq false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
=begin
|
89
|
+
context '#authenticated_orcid' do
|
90
|
+
it 'should be authenticated' do
|
91
|
+
Orcid.should_receive(:authenticated_orcid).with(orcid_profile_id).and_return(true)
|
92
|
+
Orcid.authenticated_orcid?(orcid_profile_id).should eq true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
=end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Orcid
|
4
|
+
describe ProfileConnection do
|
5
|
+
let(:email) { 'test@hello.com'}
|
6
|
+
let(:user) { FactoryGirl.build_stubbed(:user) }
|
7
|
+
let(:profile_query_service) { double("Profile Lookup Service") }
|
8
|
+
|
9
|
+
subject {
|
10
|
+
Orcid::ProfileConnection.new(email: email, user: user).tap { |pc|
|
11
|
+
pc.profile_query_service = profile_query_service
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
its(:email) { should eq email }
|
16
|
+
its(:user) { should eq user }
|
17
|
+
its(:persisted?) { should eq false }
|
18
|
+
its(:orcid_profile_id) { should be_nil }
|
19
|
+
|
20
|
+
context '.available_query_attribute_names' do
|
21
|
+
subject { Orcid::ProfileConnection.new.available_query_attribute_names }
|
22
|
+
it { should include(:email) }
|
23
|
+
it { should include(:text) }
|
24
|
+
end
|
25
|
+
|
26
|
+
context '#query_attributes' do
|
27
|
+
subject { Orcid::ProfileConnection.new(email: email, user: user)}
|
28
|
+
its(:query_attributes) { should eq(email: email, text: nil) }
|
29
|
+
end
|
30
|
+
|
31
|
+
context '#query_requested?' do
|
32
|
+
context 'with no attributes' do
|
33
|
+
subject { Orcid::ProfileConnection.new }
|
34
|
+
its(:query_requested?) { should eq false }
|
35
|
+
end
|
36
|
+
context 'with attribute set' do
|
37
|
+
subject { Orcid::ProfileConnection.new(email: email, user: user)}
|
38
|
+
its(:query_requested?) { should eq true }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context '#save' do
|
43
|
+
let(:orcid_profile_id) { '1234-5678' }
|
44
|
+
let(:persister) { double("Persister") }
|
45
|
+
|
46
|
+
it 'should call the persister when valid' do
|
47
|
+
subject.orcid_profile_id = orcid_profile_id
|
48
|
+
persister.should_receive(:call).with(user, orcid_profile_id).and_return(:persisted)
|
49
|
+
expect(subject.save(persister: persister)).to eq(:persisted)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should NOT call the persister and add errors when not valid' do
|
53
|
+
subject.user = nil
|
54
|
+
subject.orcid_profile_id = nil
|
55
|
+
expect {
|
56
|
+
subject.save(persister: persister)
|
57
|
+
}.to change { subject.errors.count }.by(2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context '#with_orcid_profile_candidates' do
|
62
|
+
context 'with an email' do
|
63
|
+
|
64
|
+
it 'should yield the query response' do
|
65
|
+
subject.email = email
|
66
|
+
profile_query_service.should_receive(:call).with(subject.query_attributes).and_return(:query_response)
|
67
|
+
expect {|b| subject.with_orcid_profile_candidates(&b) }.to yield_with_args(:query_response)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'without an email' do
|
72
|
+
it 'should not yield' do
|
73
|
+
subject.email = nil
|
74
|
+
profile_query_service.stub(:call).and_return(:query_response)
|
75
|
+
expect {|b| subject.with_orcid_profile_candidates(&b) }.to_not yield_control
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Orcid
|
4
|
+
describe ProfileRequest do
|
5
|
+
let(:orcid_profile_id) { '0000-0001-8025-637X'}
|
6
|
+
let(:user) { mock_model('User') }
|
7
|
+
let(:attributes) {
|
8
|
+
{
|
9
|
+
user: user,
|
10
|
+
given_names: 'Daffy',
|
11
|
+
family_name: 'Duck',
|
12
|
+
primary_email: 'daffy@duck.com'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
subject { described_class.new(attributes) }
|
16
|
+
|
17
|
+
context '#find_by_user' do
|
18
|
+
let!(:profile_request) { FactoryGirl.create(:orcid_profile_request) }
|
19
|
+
it 'returns the profile request' do
|
20
|
+
expect(described_class.find_by_user(profile_request.user)).to eq(profile_request)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'to return nil' do
|
24
|
+
other_user = FactoryGirl.build_stubbed(:user)
|
25
|
+
expect(described_class.find_by_user(other_user)).to be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#handle_profile_creation_response' do
|
31
|
+
it 'should update local' do
|
32
|
+
# Don't want to hit the database
|
33
|
+
subject.should_receive(:update_column).with(:orcid_profile_id, orcid_profile_id)
|
34
|
+
Orcid.should_receive(:connect_user_and_orcid_profile).with(user, orcid_profile_id)
|
35
|
+
|
36
|
+
subject.handle_profile_creation_response(orcid_profile_id)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context '#xml_payload' do
|
41
|
+
it 'should be a parsable XML document' do
|
42
|
+
expect {
|
43
|
+
ActiveSupport::XmlMini.parse(subject.xml_payload)
|
44
|
+
}.to_not raise_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context '#validate_before_run' do
|
49
|
+
let(:orcid_profile) { double('Orcid Profile', to_param: orcid_profile_id) }
|
50
|
+
|
51
|
+
context 'when no orcid profile has been assigned' do
|
52
|
+
before { Orcid.should_receive(:profile_for).with(user).and_return(nil) }
|
53
|
+
it 'should return true' do
|
54
|
+
expect(subject.validate_before_run).to eq(true)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'orcid_profile_id is set' do
|
59
|
+
before { subject.orcid_profile_id = orcid_profile_id }
|
60
|
+
|
61
|
+
it 'should return false' do
|
62
|
+
expect(subject.validate_before_run).to eq(false)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should set an error' do
|
66
|
+
expect {
|
67
|
+
subject.validate_before_run
|
68
|
+
}.to change { subject.errors.full_messages.count }.by(1)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'user has an orcid_profile' do
|
74
|
+
before { Orcid.should_receive(:profile_for).with(user).and_return(orcid_profile) }
|
75
|
+
|
76
|
+
it 'should return false' do
|
77
|
+
expect(subject.validate_before_run).to eq(false)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should set an error' do
|
81
|
+
expect {
|
82
|
+
subject.validate_before_run
|
83
|
+
}.to change { subject.errors.full_messages.count }.by(1)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context '#run' do
|
90
|
+
let(:profile_creation_service) { double('Profile Creation Service') }
|
91
|
+
let(:payload_xml_builder) { double('Payload Xml Builder') }
|
92
|
+
let(:validator) { double('Submission Guardian') }
|
93
|
+
let(:xml_payload) { double('Xml Payload') }
|
94
|
+
|
95
|
+
context 'with the submission guardian permitting the request' do
|
96
|
+
before(:each) do
|
97
|
+
validator.should_receive(:call).with(subject).
|
98
|
+
and_return(true)
|
99
|
+
payload_xml_builder.should_receive(:call).with(subject.attributes).
|
100
|
+
and_return(xml_payload)
|
101
|
+
profile_creation_service.should_receive(:call).with(xml_payload).
|
102
|
+
and_return(orcid_profile_id)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should run a request and handle the response' do
|
106
|
+
subject.run(
|
107
|
+
payload_xml_builder: payload_xml_builder,
|
108
|
+
profile_creation_service: profile_creation_service,
|
109
|
+
validator: validator
|
110
|
+
)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'with the submission guardian returning false' do
|
115
|
+
before(:each) do
|
116
|
+
validator.should_receive(:call).with(subject).
|
117
|
+
and_return(false)
|
118
|
+
payload_xml_builder.should_not_receive(:call)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should raise an exception' do
|
122
|
+
subject.run(
|
123
|
+
payload_xml_builder: payload_xml_builder,
|
124
|
+
profile_creation_service: profile_creation_service,
|
125
|
+
validator: validator
|
126
|
+
)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|