Skip to content

Commit

Permalink
refactor(enmeshed): leave the validation of the userdata to the `User…
Browse files Browse the repository at this point in the history
…` model

Part of XI-6523
  • Loading branch information
nenock committed Feb 12, 2025
1 parent 39ab4f6 commit 18755f2
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 76 deletions.
8 changes: 5 additions & 3 deletions lib/enmeshed/relationship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ def pending_for(nbp_uid)
private

def parse_userdata # rubocop:disable Metrics/AbcSize
return if response_items.blank?

user_provided_attributes = response_items.select do |item|
item[:@type] == 'ReadAttributeAcceptResponseItem'
end
Expand All @@ -91,13 +93,13 @@ def parse_userdata # rubocop:disable Metrics/AbcSize
email: enmeshed_user_attributes['EMailAddress'],
first_name: enmeshed_user_attributes['GivenName'],
last_name: enmeshed_user_attributes['Surname'],
status_group: parse_status_group(enmeshed_user_attributes['AffiliationRole'].downcase),
status_group: parse_status_group(enmeshed_user_attributes['AffiliationRole']&.downcase),
}
rescue NoMethodError
raise ConnectorError.new("Could not parse userdata in the response items: #{response_items}")
end

def parse_status_group(affiliation_role)
return if affiliation_role.blank?

if STATUS_GROUP_SYNONYMS['learner'].any? {|synonym| synonym.downcase.include? affiliation_role }
:learner
elsif STATUS_GROUP_SYNONYMS['educator'].any? {|synonym| synonym.downcase.include? affiliation_role }
Expand Down
57 changes: 42 additions & 15 deletions spec/lib/enmeshed/relationship_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,48 +89,75 @@
describe '#userdata' do
subject(:userdata) { described_class.new(json:, template:, response_items:).userdata }

it 'returns the requested data' do
expect(userdata).to eq({email: '[email protected]', first_name: 'John', last_name: 'Oliver',
status_group: :educator})
shared_examples 'parsed userdata' do
it 'passes' do
expect { userdata }.not_to raise_error
end

it 'returns the requested data' do
expect(userdata).to eq parsed_userdata
end
end

it_behaves_like 'parsed userdata' do
let(:parsed_userdata) do
{email: '[email protected]', first_name: 'John', last_name: 'Oliver', status_group: :educator}
end
end

context 'with a synonym of "learner" as status group' do
before do
response_items.last[:attribute][:value][:value] = 'Schüler'
end

it 'returns the requested data' do
expect(userdata).to eq({email: '[email protected]', first_name: 'John', last_name: 'Oliver',
status_group: :learner})
it_behaves_like 'parsed userdata' do
let(:parsed_userdata) do
{email: '[email protected]', first_name: 'John', last_name: 'Oliver', status_group: :learner}
end
end
end

context 'with a blank attribute' do
context 'with gibberish as status group' do
before do
response_items.last[:attribute][:value][:value] = 'gibberish'
end

it_behaves_like 'parsed userdata' do
let(:parsed_userdata) do
{email: '[email protected]', first_name: 'John', last_name: 'Oliver', status_group: nil}
end
end
end

context 'with a blank status group' do
before do
response_items.last[:attribute][:value][:value] = ' '
end

# The validations of the User model will take care
it 'passes' do
expect { userdata }.not_to raise_error
it_behaves_like 'parsed userdata' do
let(:parsed_userdata) do
{email: '[email protected]', first_name: 'John', last_name: 'Oliver', status_group: nil}
end
end
end

context 'with a missing attribute' do
before do
response_items.pop
response_items.slice!(3)
end

it 'raises an error' do
expect { userdata }.to raise_error(Enmeshed::ConnectorError, 'AffiliationRole must not be empty')
it_behaves_like 'parsed userdata' do
let(:parsed_userdata) do
{email: nil, first_name: 'John', last_name: 'Oliver', status_group: :educator}
end
end
end

context 'without any provided attributes' do
let(:response_items) { nil }

it 'raises an error' do
expect { userdata }.to raise_error(Enmeshed::ConnectorError, 'Could not parse userdata in the response items: ')
it_behaves_like 'parsed userdata' do
let(:parsed_userdata) { nil }
end
end
end
Expand Down
97 changes: 39 additions & 58 deletions spec/requests/users/nbp_wallet/finalize_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,17 @@

let(:uid) { 'example-uid' }
let(:session_params) { {saml_uid: uid, omniauth_provider: 'nbp'} }
let(:relationship) { instance_double(Enmeshed::Relationship) }

before do
set_session(session_params)
end

context 'without any errors' do
let(:relationship) do
instance_double(Enmeshed::Relationship,
accept!: true,
userdata: {
email: '[email protected]',
first_name: 'john',
last_name: 'oliver',
status_group: 'learner',
})
end

before do
allow(Enmeshed::Relationship).to receive(:pending_for).with(uid).and_return(relationship)
allow(relationship).to receive(:peer).and_return('id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp')
allow(relationship).to receive_messages(peer: 'id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp', accept!: true,
userdata: {email: '[email protected]', first_name: 'john', last_name: 'oliver', status_group: :learner})
end

it 'creates a user' do
Expand Down Expand Up @@ -112,79 +103,69 @@
end

context 'when an attribute is missing' do
# `Enmeshed::ConnectorError` is unknown until 'lib/enmeshed/connector.rb' is loaded, because it's defined there
require 'enmeshed/connector'

let(:relationship) do
instance_double(Enmeshed::Relationship, accept!: false, reject!: true)
end

before do
allow(Enmeshed::Relationship).to receive(:pending_for).with(uid).and_return(relationship)
allow(relationship).to receive(:userdata).and_raise(Enmeshed::ConnectorError, 'EMailAddress must not be empty')
allow(relationship).to receive_messages(
userdata: {first_name: 'john', last_name: 'oliver', status_group: :learner},
peer: 'id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp',
reject!: true
)
end

it_behaves_like 'a handled erroneous request', I18n.t('common.errors.generic')
it_behaves_like 'a documented erroneous request', Enmeshed::ConnectorError
it_behaves_like 'a handled erroneous request', "Could not create User: Email can't be blank"
end

context 'with an invalid status group' do
let(:relationship) do
instance_double(Enmeshed::Relationship,
reject!: true,
userdata: {
email: '[email protected]',
first_name: 'john',
last_name: 'oliver',
status_group: nil,
})
end

before do
allow(Enmeshed::Relationship).to receive(:pending_for).with(uid).and_return(relationship)
allow(relationship).to receive_messages(reject!: true, userdata: {
email: '[email protected]',
first_name: 'john',
last_name: 'oliver',
status_group: nil,
})
end

it_behaves_like 'a handled erroneous request', 'Could not create User: Unknown role. Please select either ' \
'"Teacher" or "Student" as your role.'
end

context 'when the User cannot be saved' do
let(:relationship) do
instance_double(Enmeshed::Relationship,
reject!: true,
userdata: {
email: '[email protected]',
first_name: 'john',
last_name: 'oliver',
status_group: 'learner',
})
context 'with a blank name' do
before do
allow(Enmeshed::Relationship).to receive(:pending_for).with(uid).and_return(relationship)
allow(relationship).to receive_messages(
userdata: {email: '[email protected]', first_name: ' ', last_name: 'oliver', status_group: :learner},
peer: 'id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp',
reject!: true
)
end

it_behaves_like 'a handled erroneous request', "Could not create User: First Name can't be blank"
end

context 'when email address already has been taken' do
before do
create(:user, email: relationship.userdata[:email])
create(:user, email: '[email protected]')
allow(Enmeshed::Relationship).to receive(:pending_for).with(uid).and_return(relationship)
allow(relationship).to receive(:peer).and_return('id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp')
allow(relationship).to receive_messages(
userdata: {email: '[email protected]', first_name: 'john', last_name: 'oliver', status_group: :learner},
peer: 'id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp',
reject!: true
)
end

it_behaves_like 'a handled erroneous request', 'Could not create User: Email has already been taken'
end

context 'when the RelationshipChange cannot be accepted' do
let(:relationship) do
instance_double(Enmeshed::Relationship,
accept!: false,
reject!: true,
userdata: {
email: '[email protected]',
first_name: 'john',
last_name: 'oliver',
status_group: 'learner',
})
end

before do
allow(Enmeshed::Relationship).to receive(:pending_for).with(uid).and_return(relationship)
allow(relationship).to receive(:peer).and_return('id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp')
allow(relationship).to receive_messages(
userdata: {email: '[email protected]', first_name: 'john', last_name: 'oliver', status_group: :learner},
peer: 'id1EvvJ68x6wdHBwYrFTR31XtALHko9fnbyp',
accept!: false,
reject!: true
)
end

it_behaves_like 'a handled erroneous request', I18n.t('common.errors.generic')
Expand Down

0 comments on commit 18755f2

Please sign in to comment.