Skip to content

Commit

Permalink
Make tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
lleirborras committed Apr 17, 2024
1 parent 371eb85 commit 6d69b65
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 61 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ jobs:
continue-on-error: ${{ matrix.channel != 'stable' }}

env:
SP_USERNAME: test
SP_PASSWORD: test
SP_URL: http://localhost:1234/
SP_CLIENT_ID: clientfoo
SP_CLIENT_SECRET: secretfoo
SP_TENANT_ID: tenantfoo
SP_CERT_NAME: certfoo
SP_AUTH_SCOPE: http://localhost:1234/

steps:
- name: Install libmagic-dev
Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ You can instantiate a number of SharePoint clients in your application:

```rb
client = Sharepoint::Client.new({
username: 'username',
password: 'password',
uri: 'https://sharepoint_url'
client_id: "client_id",
client_secret: "client_secret",
tenant_id: "tenant_id",
cert_name: "cert_name",
auth_scope: "auth_scope",
uri: "http://sharepoint_url"
})
```

Expand All @@ -47,3 +50,11 @@ client.upload filename, content, path
```rb
client.update_metadata filename, metadata, path
```

## Testing

Create a .env file based on the `env-example` and run

```bash
$ bundle exec rake
```
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ begin
RSpec::Core::RakeTask.new(:spec)
rescue LoadError
end

task default: :spec
7 changes: 5 additions & 2 deletions env-example
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# SharePoint Access
SP_USERNAME=
SP_PASSWORD=
SP_CLIENT_ID=
SP_CLIENT_SECRET=
SP_TENANT_ID=
SP_CERT_NAME=
SP_AUTH_SCOPE=
SP_URL=
57 changes: 34 additions & 23 deletions lib/sharepoint/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ def to_s
end

def fetch
response = request_new_token

details = response["Token"]
self.fetched_at = Time.now.utc.to_i
self.expires_in = details["expires_in"]
self.access_token = details["access_token"]
end

private

def expired?
return true unless fetched_at && expires_in

(fetched_at + expires_in) < Time.now.utc.to_i
end

def request_new_token
auth_request = {
client_id: config.client_id,
client_secret: config.client_secret,
Expand All @@ -52,20 +69,7 @@ def fetch

raise InvalidTokenError.new(ethon.response_body.to_s) unless ethon.response_code == 200

response = JSON.parse(ethon.response_body)

details = response["Token"]
self.fetched_at = Time.now.utc.to_i
self.expires_in = details["expires_in"]
self.access_token = details["access_token"]
end

private

def expired?
return true unless fetched_at && expires_in

(fetched_at + expires_in) < Time.now.utc.to_i
JSON.parse(ethon.response_body)
end
end # endof Token

Expand All @@ -90,8 +94,11 @@ def bearer_auth
#
# @param [Hash] options The client options:
# - `:uri` The SharePoint server's root url
# - `:username` self-explanatory
# - `:password` self-explanatory
# - `:client_id` self-explanatory
# - `:client_secret` self-explanatory
# - `:tenant_id` self-explanatory
# - `:cert_name` self-explanatory
# - `:auth_scope` self-explanatory
# @return [Sharepoint::Client] client object
def initialize(config = {})
@config = OpenStruct.new(config)
Expand Down Expand Up @@ -661,25 +668,29 @@ def extract_paths(url)

def validate_ouath_config
[:client_id, :client_secret, :tenant_id, :cert_name, :auth_scope].map do |opt|
next if config.send(opt).present?
c = config.send(opt)

next if c.present? && string_not_blank?(c)
opt
end.compact
end

def validate_config!
invalid_oauth_opts = validate_ouath_config
raise Errors::InvalidOauthConfigError.new(invalid_oauth_opts) unless invalid_oauth_opts.empty?
raise Errors::UriConfigurationError.new unless valid_config_uri?
raise Errors::EthonOptionsConfigurationError.new unless ethon_easy_options.is_a?(Hash)

raise Errors::InvalidOauthConfigError.new(invalid_oauth_opts) unless invalid_oauth_opts.empty?
raise Errors::UriConfigurationError.new unless valid_uri?(config.auth_scope)
raise Errors::UriConfigurationError.new unless valid_uri?(config.uri)
raise Errors::EthonOptionsConfigurationError.new unless ethon_easy_options.is_a?(Hash)
end

def string_not_blank?(object)
!object.nil? && object != "" && object.is_a?(String)
end

def valid_config_uri?
if @config.uri and @config.uri.is_a? String
uri = URI.parse(@config.uri)
def valid_uri?(which)
if which and which.is_a? String
uri = URI.parse(which)
uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
else
false
Expand Down
10 changes: 0 additions & 10 deletions lib/sharepoint/errors.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
module Sharepoint
module Errors
class UsernameConfigurationError < StandardError
def initialize
super "Invalid Username Configuration"
end
end
class PasswordConfigurationError < StandardError
def initialize
super "Invalid Password configuration"
end
end
class UriConfigurationError < StandardError
def initialize
super "Invalid Uri configuration"
Expand Down
17 changes: 17 additions & 0 deletions lib/sharepoint/spec_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,29 @@ def value_to_string(value)
end
end

def sp_config
{
uri: ENV['SP_URL'],
client_id: ENV['SP_CLIENT_ID'],
client_secret: ENV['SP_CLIENT_SECRET'],
tenant_id: ENV['SP_TENANT_ID'],
cert_name: ENV['SP_CERT_NAME'],
auth_scope: ENV['SP_AUTH_SCOPE']
}
end

def mock_requests
allow_any_instance_of(Ethon::Easy)
.to receive(:perform)
.and_return(nil)
end

def mock_token_responses
allow_any_instance_of(Sharepoint::Client::Token)
.to receive(:request_new_token)
.and_return({"Token" => { "expires_in" => 3600, "access_token" => "access_token" }})
end

def mock_responses(fixture_file)
allow_any_instance_of(Ethon::Easy)
.to receive(:response_code)
Expand Down
13 changes: 6 additions & 7 deletions spec/lib/sharepoint/client_methods_spec.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
require 'spec_helper'

describe Sharepoint::Client do
before { mock_requests }
let(:config) do
{
username: ENV['SP_USERNAME'],
password: ENV['SP_PASSWORD'],
uri: ENV['SP_URL']
}
before do
mock_requests
mock_token_responses
end

let(:config) { sp_config }

let(:client) { described_class.new(config) }

describe '#documents_for' do
Expand Down
92 changes: 78 additions & 14 deletions spec/lib/sharepoint/client_spec.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
require 'spec_helper'

describe Sharepoint::Client do
let(:config) { { username: ENV['SP_USERNAME'],
password: ENV['SP_PASSWORD'],
uri: ENV['SP_URL'] } }
before { ENV['SP_URL'] = 'https://localhost:8888' }

let(:config) { sp_config }

describe '#initialize' do

Expand All @@ -17,7 +17,7 @@
it 'sets config object' do
client_config = subject.config
expect(client_config).to be_a OpenStruct
[:username, :password, :url].each do |key|
[:client_id, :client_secret, :tenant_id, :cert_name, :auth_scope, :url].each do |key|
value = client_config.send(key)
expect(value).to eq config[key]
end
Expand All @@ -28,11 +28,11 @@
end

it "sets base_api_url in the client" do
expect(subject.send :base_api_url).to eql(ENV['SP_URL']+'/_api/')
expect(subject.send :base_api_url).to eql("#{ENV['SP_URL']}/_api/")
end

it "sets base_api_web_url in the client" do
expect(subject.send :base_api_web_url).to eql(ENV['SP_URL']+'/_api/web/')
expect(subject.send :base_api_web_url).to eql("#{ENV['SP_URL']}/_api/web/")
end
end

Expand Down Expand Up @@ -61,36 +61,100 @@

context 'failure' do

context "bad username" do
context "bad client_id" do
[{ value: nil, name: 'nil' },
{ value: '', name: 'blank' },
{ value: 344, name: 344 } ].each do |ocurrence|

it "should raise username configuration error for #{ ocurrence[:name]} username" do
it "should raise client_id configuration error for #{ ocurrence[:name]} client_id" do
wrong_config = config
wrong_config[:username] = ocurrence[:value]
wrong_config[:client_id] = ocurrence[:value]

expect {
described_class.new(wrong_config)
}.to raise_error(Sharepoint::Errors::UsernameConfigurationError)
}.to raise_error(Sharepoint::Errors::InvalidOauthConfigError)
end
end
end

context "bad client_secret" do
[{ value: nil, name: 'nil' },
{ value: '', name: 'blank' },
{ value: 344, name: 344 } ].each do |ocurrence|

it "should raise client_secret configuration error for #{ocurrence[:name]} client_secret" do
wrong_config = config
wrong_config[:client_secret] = ocurrence[:value]

expect {
described_class.new(wrong_config)
}.to raise_error(Sharepoint::Errors::InvalidOauthConfigError)
end
end
end

context "bad tenant_id" do
[{ value: nil, name: 'nil' },
{ value: '', name: 'blank' },
{ value: 344, name: 344 } ].each do |ocurrence|

it "should raise tenant_id configuration error for #{ocurrence[:name]} tenant_id" do
wrong_config = config
wrong_config[:tenant_id] = ocurrence[:value]

expect {
described_class.new(wrong_config)
}.to raise_error(Sharepoint::Errors::InvalidOauthConfigError)
end
end
end

context "bad password" do
context "bad cert_name" do
[{ value: nil, name: 'nil' },
{ value: '', name: 'blank' },
{ value: 344, name: 344 } ].each do |ocurrence|

it "should raise password configuration error for #{ocurrence[:name]} password" do
it "should raise cert_name configuration error for #{ocurrence[:name]} cert_name" do
wrong_config = config
wrong_config[:cert_name] = ocurrence[:value]

expect {
described_class.new(wrong_config)
}.to raise_error(Sharepoint::Errors::InvalidOauthConfigError)
end
end
end

context "bad auth_scope" do
[{ value: nil, name: 'nil' },
{ value: '', name: 'blank' },
{ value: 344, name: 344 }].each do |ocurrence|

it "should raise auth_scope configuration error for #{ocurrence[:name]} auth_scope" do
wrong_config = config
wrong_config[:password] = ocurrence[:value]
wrong_config[:auth_scope] = ocurrence[:value]

expect {
described_class.new(wrong_config)
}.to raise_error(Sharepoint::Errors::PasswordConfigurationError)
}.to raise_error(Sharepoint::Errors::InvalidOauthConfigError)
end
end

end

context "bad auth_scope" do
[{ value: 'ftp://www.test.com', name: "invalid auth_scope" }].each do |ocurrence|

it "should raise auth_scope configuration error for #{ocurrence[:name]} auth_scope" do
wrong_config = config
wrong_config[:auth_scope] = ocurrence[:value]

expect {
described_class.new(wrong_config)
}.to raise_error(Sharepoint::Errors::UriConfigurationError)
end
end

end

context "bad uri" do
Expand Down

0 comments on commit 6d69b65

Please sign in to comment.