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,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Orcid
|
4
|
+
describe Profile do
|
5
|
+
let(:orcid_profile_id) { '0001-0002-0003-0004' }
|
6
|
+
let(:remote_service) { double('Service') }
|
7
|
+
let(:mapper) { double("Mapper") }
|
8
|
+
let(:non_orcid_work) { double("A non-ORCID Work") }
|
9
|
+
let(:orcid_work) { double("Orcid::Work") }
|
10
|
+
let(:xml_renderer) { double("Renderer") }
|
11
|
+
let(:xml_parser) { double("Parser") }
|
12
|
+
let(:xml) { double("XML Payload")}
|
13
|
+
|
14
|
+
subject {
|
15
|
+
described_class.new(
|
16
|
+
orcid_profile_id,
|
17
|
+
mapper: mapper,
|
18
|
+
remote_service: remote_service,
|
19
|
+
xml_renderer: xml_renderer,
|
20
|
+
xml_parser: xml_parser
|
21
|
+
)
|
22
|
+
}
|
23
|
+
|
24
|
+
def should_map(source, target)
|
25
|
+
mapper.should_receive(:map).with(source, target: 'orcid/work').and_return(target)
|
26
|
+
end
|
27
|
+
|
28
|
+
context '#remote_works' do
|
29
|
+
let(:parsed_object) { double("Parsed Object")}
|
30
|
+
let(:response_body) { double("XML Response") }
|
31
|
+
it 'should parse the response body' do
|
32
|
+
xml_parser.should_receive(:call).with(response_body).and_return(parsed_object)
|
33
|
+
remote_service.should_receive(:call).with(orcid_profile_id, request_method: :get).and_return(response_body)
|
34
|
+
|
35
|
+
expect(subject.remote_works).to eq(parsed_object)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
context '#append_new_work' do
|
41
|
+
it 'should transform the input work to xml and deliver to the remote_service' do
|
42
|
+
xml_renderer.should_receive(:call).with([orcid_work]).and_return(xml)
|
43
|
+
remote_service.should_receive(:call).with(orcid_profile_id, body: xml, request_method: :post)
|
44
|
+
|
45
|
+
should_map(non_orcid_work, orcid_work)
|
46
|
+
|
47
|
+
subject.append_new_work(non_orcid_work)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context '#replace_works_with' do
|
52
|
+
it 'should transform the input work to xml and deliver to the remote_service' do
|
53
|
+
xml_renderer.should_receive(:call).with([orcid_work]).and_return(xml)
|
54
|
+
remote_service.should_receive(:call).with(orcid_profile_id, body: xml, request_method: :put)
|
55
|
+
|
56
|
+
should_map(non_orcid_work, orcid_work)
|
57
|
+
|
58
|
+
subject.replace_works_with(non_orcid_work)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context '#verified_authentication' do
|
63
|
+
it 'should not be authorized' do
|
64
|
+
subject.verified_authentication?.should eq false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context '#verified_authentication' do
|
69
|
+
it 'should be authorized' do
|
70
|
+
Orcid.stub(:access_token_for).and_return(Object.new())
|
71
|
+
|
72
|
+
subject.verified_authentication?.should eq true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Orcid
|
4
|
+
describe Work::XmlParser do
|
5
|
+
let(:xml) { fixture_file('orcid_works.xml').read }
|
6
|
+
|
7
|
+
context '.call' do
|
8
|
+
subject { described_class.call(xml) }
|
9
|
+
its(:size) { should eq 2 }
|
10
|
+
its(:first) { should be_an_instance_of Orcid::Work }
|
11
|
+
its(:last) { should be_an_instance_of Orcid::Work }
|
12
|
+
|
13
|
+
context 'first element' do
|
14
|
+
subject { described_class.call(xml).first }
|
15
|
+
|
16
|
+
its(:title) { should eq "Another Test Drive" }
|
17
|
+
its(:put_code) { should eq "303475" }
|
18
|
+
its(:work_type) { should eq "test" }
|
19
|
+
its(:journal_title) { should_not be_present }
|
20
|
+
its(:short_description) { should_not be_present }
|
21
|
+
its(:citation_type) { should_not be_present }
|
22
|
+
its(:citation) { should_not be_present }
|
23
|
+
its(:publication_month) { should_not be_present }
|
24
|
+
its(:publication_year) { should_not be_present }
|
25
|
+
its(:url) { should_not be_present }
|
26
|
+
its(:language_code) { should_not be_present }
|
27
|
+
its(:country) { should_not be_present }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'last element' do
|
31
|
+
subject { described_class.call(xml).last }
|
32
|
+
|
33
|
+
its(:title) { should eq "Test Driven Orcid Integration" }
|
34
|
+
its(:put_code) { should eq "303474" }
|
35
|
+
its(:work_type) { should eq "test" }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Orcid
|
4
|
+
describe Work::XmlRenderer do
|
5
|
+
let(:work) { Work.new(title: 'Hello', work_type: 'journal-article') }
|
6
|
+
subject { described_class.new(work) }
|
7
|
+
|
8
|
+
context '#call' do
|
9
|
+
it 'should return an XML document' do
|
10
|
+
rendered = subject.call
|
11
|
+
expect(rendered).to have_tag('orcid-profile orcid-activities orcid-works orcid-work') do
|
12
|
+
with_tag('work-title title', text: work.title)
|
13
|
+
with_tag('work-type', text: work.work_type)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Orcid
|
4
|
+
describe Work do
|
5
|
+
let(:attributes) {
|
6
|
+
{
|
7
|
+
title: 'Hello',
|
8
|
+
work_type: 'journal-article',
|
9
|
+
put_code: '1234',
|
10
|
+
external_identifiers: [ {type: 'doi', identifier: 'abc-123' }]
|
11
|
+
}
|
12
|
+
}
|
13
|
+
subject { described_class.new(attributes) }
|
14
|
+
|
15
|
+
its(:title) { should eq attributes[:title] }
|
16
|
+
its(:subtitle) { should eq nil }
|
17
|
+
its(:work_type) { should eq attributes[:work_type] }
|
18
|
+
its(:put_code) { should eq attributes[:put_code] }
|
19
|
+
its(:external_identifiers) { should be_an_instance_of(Array) }
|
20
|
+
its(:valid?) { should eq true }
|
21
|
+
|
22
|
+
context '#id' do
|
23
|
+
context 'with put_code' do
|
24
|
+
subject { described_class.new(put_code: '123') }
|
25
|
+
its(:id) { should eq subject.put_code}
|
26
|
+
end
|
27
|
+
context 'with title and work type' do
|
28
|
+
subject { described_class.new(title: 'Title', work_type: 'journal-article') }
|
29
|
+
its(:id) { should eq [subject.title, subject.work_type]}
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'without title, work type, and put_code' do
|
33
|
+
subject { described_class.new }
|
34
|
+
its(:id) { should eq nil }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context '#to_xml' do
|
39
|
+
it 'should return an XML document' do
|
40
|
+
rendered = subject.to_xml
|
41
|
+
expect(rendered).to have_tag('orcid-profile orcid-activities orcid-works orcid-work') do
|
42
|
+
with_tag('work-title title', text: subject.title)
|
43
|
+
with_tag('work-type', text: subject.work_type)
|
44
|
+
with_tag('work-external-identifiers work-external-identifier', count: 1) do
|
45
|
+
with_tag('work-external-identifier-type', text: 'doi')
|
46
|
+
with_tag('work-external-identifier-id', text: 'abc-123')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'fast_helper'
|
2
|
+
require 'orcid/remote/profile_creation_service'
|
3
|
+
|
4
|
+
module Orcid::Remote
|
5
|
+
describe ProfileCreationService do
|
6
|
+
Given(:payload) { %(<?xml version="1.0" encoding="UTF-8"?>) }
|
7
|
+
Given(:config) { {token: token, headers: request_headers, path: 'path/to/somewhere' } }
|
8
|
+
Given(:token) { double("Token", post: response) }
|
9
|
+
Given(:minted_orcid) { '0000-0001-8025-637X' }
|
10
|
+
Given(:request_headers) {
|
11
|
+
{ 'Content-Type' => 'application/vdn.orcid+xml', 'Accept' => 'application/xml' }
|
12
|
+
}
|
13
|
+
Given(:callback) { StubCallback.new }
|
14
|
+
Given(:callback_config) { callback.configure }
|
15
|
+
|
16
|
+
Given(:response) {
|
17
|
+
double("Response", headers: { location: File.join("/", minted_orcid, "orcid-profile") })
|
18
|
+
}
|
19
|
+
|
20
|
+
When(:returned_value) { described_class.call(payload, config, &callback_config) }
|
21
|
+
|
22
|
+
context 'with orcid created' do
|
23
|
+
Given(:response) {
|
24
|
+
double("Response", headers: { location: File.join("/", minted_orcid, "orcid-profile") })
|
25
|
+
}
|
26
|
+
Then { returned_value.should eq(minted_orcid)}
|
27
|
+
And { expect(callback.invoked).to eq [:success, minted_orcid] }
|
28
|
+
And { token.should have_received(:post).with(config.fetch(:path), body: payload, headers: request_headers)}
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with orcid created' do
|
32
|
+
Given(:response) {
|
33
|
+
double("Response", headers: { location: "" })
|
34
|
+
}
|
35
|
+
Then { returned_value.should eq(false)}
|
36
|
+
And { expect(callback.invoked).to eq [:failure] }
|
37
|
+
And { token.should have_received(:post).with(config.fetch(:path), body: payload, headers: request_headers)}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'fast_helper'
|
2
|
+
require 'orcid/remote/profile_query_service/query_parameter_builder'
|
3
|
+
|
4
|
+
module Orcid::Remote
|
5
|
+
|
6
|
+
describe ProfileQueryService::QueryParameterBuilder do
|
7
|
+
When(:response) { described_class.call(input) }
|
8
|
+
context 'single word input' do
|
9
|
+
Given(:input) {
|
10
|
+
{ text: "Hello", email: 'jeremy.n.friesen@gmail.com' }
|
11
|
+
}
|
12
|
+
Then { expect(response).to eq(q: "email:#{input[:email]} AND text:#{input[:text]}") }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'empty string and nil' do
|
16
|
+
Given(:input) {
|
17
|
+
{ text: "" , email: nil}
|
18
|
+
}
|
19
|
+
Then { expect(response).to eq(q: "") }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'multi-word named input' do
|
23
|
+
Given(:input) {
|
24
|
+
{ other_names: %("Tim O'Connor" -"Oak"), email: 'jeremy.n.friesen@gmail.com' }
|
25
|
+
}
|
26
|
+
Then { expect(response).to eq(q: "other-names:#{input[:other_names]} AND email:#{input[:email]}") }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'q is provided along with other params' do
|
30
|
+
Given(:input) {
|
31
|
+
{ q: %("Tim O'Connor" -"Oak"), email: 'jeremy.n.friesen@gmail.com' }
|
32
|
+
}
|
33
|
+
Then { expect(response).to eq(q: "email:#{input[:email]} AND text:#{input[:q]}") }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'q is provided with text params' do
|
37
|
+
Given(:input) {
|
38
|
+
{ q: %("Tim O'Connor" -"Oak"), text: 'jeremy.n.friesen@gmail.com' }
|
39
|
+
}
|
40
|
+
Then { expect(response).to eq(q: "text:((#{input[:q]}) AND (#{input[:text]}))") }
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'orcid/remote/profile_query_service/search_response'
|
3
|
+
|
4
|
+
module Orcid::Remote
|
5
|
+
describe ProfileQueryService::SearchResponse do
|
6
|
+
Given(:attributes) { {id: 'Hello', label: 'World', junk: 'JUNK!', biography: "Extended Biography"} }
|
7
|
+
Given(:search_response) { described_class.new(attributes) }
|
8
|
+
Then { expect(search_response.id).to eq(attributes[:id]) }
|
9
|
+
And { expect(search_response.biography).to eq(attributes[:biography]) }
|
10
|
+
And { expect(search_response.label).to eq(attributes[:label]) }
|
11
|
+
And { expect(search_response.orcid_profile_id).to eq(attributes[:id]) }
|
12
|
+
And { expect{search_response.junk }.to raise_error }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'fast_helper'
|
2
|
+
require 'orcid/remote/profile_query_service'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Orcid::Remote
|
6
|
+
describe ProfileQueryService do
|
7
|
+
Given(:email) { 'corwin@amber.gov' }
|
8
|
+
Given(:biography) { 'King of Amber' }
|
9
|
+
Given(:orcid_profile_id) { '0001-0002' }
|
10
|
+
Given(:config) {
|
11
|
+
{
|
12
|
+
token: token,
|
13
|
+
path: 'somehwere',
|
14
|
+
headers: 'headers',
|
15
|
+
response_builder: OpenStruct,
|
16
|
+
query_parameter_builder: query_parameter_builder
|
17
|
+
}
|
18
|
+
}
|
19
|
+
Given(:query_parameter_builder) { double('Query Builder')}
|
20
|
+
Given(:response) { double("Response", body: response_body)} # See below
|
21
|
+
Given(:token) { double("Token") }
|
22
|
+
Given(:json_response) {
|
23
|
+
[
|
24
|
+
OpenStruct.new({ 'id' => orcid_profile_id, 'label' => "Corwin Amber (#{email}) [ORCID: #{orcid_profile_id}]", 'biography' => biography })
|
25
|
+
]
|
26
|
+
}
|
27
|
+
Given(:parameters) { double("Parameters") }
|
28
|
+
Given(:normalized_parameters) { double("Normalized Parameters") }
|
29
|
+
Given(:callback) { StubCallback.new }
|
30
|
+
Given(:callback_config) { callback.configure(:found, :not_found) }
|
31
|
+
|
32
|
+
context '.call' do
|
33
|
+
before(:each) do
|
34
|
+
query_parameter_builder.should_receive(:call).with(parameters).and_return(normalized_parameters)
|
35
|
+
token.should_receive(:get).with(config[:path], headers: config[:headers], params: normalized_parameters).and_return(response)
|
36
|
+
end
|
37
|
+
When(:result) { described_class.call(parameters, config, &callback_config) }
|
38
|
+
Then { expect(result).to eq(json_response) }
|
39
|
+
And { expect(callback.invoked).to eq [:found, json_response] }
|
40
|
+
end
|
41
|
+
|
42
|
+
Given(:response_body) {
|
43
|
+
%(
|
44
|
+
{
|
45
|
+
"message-version": "1.1",
|
46
|
+
"orcid-search-results": {
|
47
|
+
"orcid-search-result": [
|
48
|
+
{
|
49
|
+
"relevancy-score": {
|
50
|
+
"value": 14.298138
|
51
|
+
},
|
52
|
+
"orcid-profile": {
|
53
|
+
"orcid": null,
|
54
|
+
"orcid-identifier": {
|
55
|
+
"value": null,
|
56
|
+
"uri": "http://orcid.org/#{orcid_profile_id}",
|
57
|
+
"path": "#{orcid_profile_id}",
|
58
|
+
"host": "orcid.org"
|
59
|
+
},
|
60
|
+
"orcid-bio": {
|
61
|
+
"personal-details": {
|
62
|
+
"given-names": {
|
63
|
+
"value": "Corwin"
|
64
|
+
},
|
65
|
+
"family-name": {
|
66
|
+
"value": "Amber"
|
67
|
+
}
|
68
|
+
},
|
69
|
+
"biography": {
|
70
|
+
"value": "#{biography}",
|
71
|
+
"visibility": null
|
72
|
+
},
|
73
|
+
"contact-details": {
|
74
|
+
"email": [
|
75
|
+
{
|
76
|
+
"value": "#{email}",
|
77
|
+
"primary": true,
|
78
|
+
"current": true,
|
79
|
+
"verified": true,
|
80
|
+
"visibility": null,
|
81
|
+
"source": null
|
82
|
+
}
|
83
|
+
],
|
84
|
+
"address": {
|
85
|
+
"country": {
|
86
|
+
"value": "US",
|
87
|
+
"visibility": null
|
88
|
+
}
|
89
|
+
}
|
90
|
+
},
|
91
|
+
"keywords": {
|
92
|
+
"keyword": [
|
93
|
+
{
|
94
|
+
"value": "Lord of Amber"
|
95
|
+
}
|
96
|
+
],
|
97
|
+
"visibility": null
|
98
|
+
},
|
99
|
+
"delegation": null,
|
100
|
+
"applications": null,
|
101
|
+
"scope": null
|
102
|
+
},
|
103
|
+
"orcid-activities": {
|
104
|
+
"affiliations": null
|
105
|
+
},
|
106
|
+
"type": null,
|
107
|
+
"group-type": null,
|
108
|
+
"client-type": null
|
109
|
+
}
|
110
|
+
}
|
111
|
+
],
|
112
|
+
"num-found": 1
|
113
|
+
}
|
114
|
+
}
|
115
|
+
)
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'fast_helper'
|
2
|
+
require 'orcid/remote/service'
|
3
|
+
|
4
|
+
module Orcid::Remote
|
5
|
+
describe Service do
|
6
|
+
Given(:context) { double(invoked: true) }
|
7
|
+
Given(:runner) {
|
8
|
+
described_class.new { |on|
|
9
|
+
on.found {|a,b| context.invoked("FOUND", a,b) }
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "calling defined callback" do
|
14
|
+
When(:result) { runner.callback(:found, :first, :second) }
|
15
|
+
Then { context.should have_received(:invoked).with("FOUND", :first, :second) }
|
16
|
+
Then { result == [:first, :second] }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "calling undefined callback" do
|
20
|
+
When(:result) { runner.callback(:missing, :first, :second) }
|
21
|
+
Then { context.should_not have_received(:invoked) }
|
22
|
+
Then { result == [:first, :second] }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'fast_helper'
|
2
|
+
require 'oauth2/error'
|
3
|
+
require 'orcid/remote/work_service'
|
4
|
+
|
5
|
+
module Orcid::Remote
|
6
|
+
describe WorkService do
|
7
|
+
let(:payload) { %(<?xml version="1.0" encoding="UTF-8"?>) }
|
8
|
+
let(:token) { double("Token") }
|
9
|
+
let(:orcid_profile_id) { '0000-0003-1495-7122' }
|
10
|
+
let(:request_headers) { { 'Content-Type' => 'application/orcid+xml', 'Accept' => 'application/xml' } }
|
11
|
+
let(:response) { double("Response", body: 'Body') }
|
12
|
+
|
13
|
+
context '.call' do
|
14
|
+
let(:token) { double('Token', client: client, token: 'access_token', refresh_token: 'refresh_token')}
|
15
|
+
let(:client) { double('Client', id: '123', site: 'URL', options: {})}
|
16
|
+
it 'raises a more helpful message' do
|
17
|
+
response = double("Response", status: '100', body: 'body')
|
18
|
+
response.stub(:error=)
|
19
|
+
response.stub(:parsed)
|
20
|
+
token.should_receive(:request).and_raise(OAuth2::Error.new(response))
|
21
|
+
|
22
|
+
expect {
|
23
|
+
described_class.call(orcid_profile_id, token: token)
|
24
|
+
}.to raise_error(Orcid::RemoteServiceError)
|
25
|
+
end
|
26
|
+
it 'instantiates and calls underlying instance' do
|
27
|
+
token.should_receive(:request).
|
28
|
+
with(:post, "v1.1/#{orcid_profile_id}/orcid-works/", body: payload, headers: request_headers).
|
29
|
+
and_return(response)
|
30
|
+
|
31
|
+
expect(
|
32
|
+
described_class.call(
|
33
|
+
orcid_profile_id,
|
34
|
+
body: payload,
|
35
|
+
request_method: :post,
|
36
|
+
token: token,
|
37
|
+
headers: request_headers
|
38
|
+
)
|
39
|
+
).to eq(response.body)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|