orcid 0.0.4 → 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.
- 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
|