school21_api_sdk 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f53a4ed9751f4ad38c62dff08811e164694e1b84903847ce98392aa39ae9234
4
- data.tar.gz: 46344c76969f24f6cd33d4b7ef9e1983e36e133c6bb258162b94dcb7ded7cc88
3
+ metadata.gz: c977aa4a81ec303760a605cfa0bc0cb4508cf1cc8fe930419681cbdad2f76365
4
+ data.tar.gz: 540db30ea6fb420599b0d54b8f6236fcc7ccda97bb6fc29a2a65d2b8ae9b78d9
5
5
  SHA512:
6
- metadata.gz: d7bf6101d76b1a93a5510335e0f69a39eac1b8643eb0bbebd716a9b1dace589a1443bc4ef7ee6576c4b1b8e721746bf0b01eaf2888e21c541804bf7b58cfc43e
7
- data.tar.gz: fb4698307bc50ef4b896bda5277f556b5146e293042e9dbfec3a52b3a773792514d558c9f2235975813adace83d2ab3e426a250a9bcd1e1d7025b308c4e4ec59
6
+ metadata.gz: d9ce8af9eaae1316e4e77f62448efb983d14a8c36bb281021fd9ef4dfa1c1ed92a3362be512410fdf62bb9f33095c76990bb944e054888e82c4218613bd055a4
7
+ data.tar.gz: 874a6d4bc32e73deb6324bd57831650cea4f070c2c25d4cdf7dc7f699baff4df123a67e3f22e05081e5580155f4bb24dde9caa17cf5d1ec62e35ddc9fc053180
data/README.md CHANGED
@@ -1,22 +1,28 @@
1
1
  # School21 API SDK
2
2
 
3
- ![](https://github.com/ikael21/school21_api_sdk/actions/workflows/test.yml/badge.svg)
3
+ ![test](https://github.com/ikael21/school21_api_sdk/actions/workflows/test.yml/badge.svg)
4
4
  [![codecov](https://codecov.io/github/ikael21/school21_api_sdk/branch/main/graph/badge.svg?token=O7I31Q7N96)](https://codecov.io/github/ikael21/school21_api_sdk)
5
- ![](https://github.com/ikael21/school21_api_sdk/actions/workflows/rubocop.yml/badge.svg)
5
+ ![rubocop](https://github.com/ikael21/school21_api_sdk/actions/workflows/rubocop.yml/badge.svg)
6
6
 
7
7
  ## Installation
8
8
 
9
9
  Install the gem and add to the application's Gemfile by executing:
10
10
 
11
- $ bundle add school21_api_sdk
11
+ ```bash
12
+ bundle add school21_api_sdk
13
+ ```
12
14
 
13
15
  If bundler is not being used to manage dependencies, install the gem by executing:
14
16
 
15
- $ gem install school21_api_sdk
17
+ ```bash
18
+ gem install school21_api_sdk
19
+ ```
16
20
 
17
21
  ## Usage
18
22
 
19
- There are multiple API's method according to School21 OpenAPI Specification. Check https://edu.21-school.ru/docs
23
+ Please check [docs](https://edu.21-school.ru/docs) for more information.
24
+
25
+ - Require the gem and configure client object
20
26
 
21
27
  ```ruby
22
28
  require 'school21'
@@ -24,9 +30,15 @@ require 'school21'
24
30
  login = 'your_login_here'
25
31
  password = 'your_password_here'
26
32
 
27
- client = School21::Client.new(login: login, password: password)
33
+ client = School21::Client.configure do |config|
34
+ config.credentials = { login: login, password: password }
35
+ config.enable_logging = true # false by default
36
+ end
37
+ ```
38
+
39
+ - Select the domain specific API that you want to use. This API has all endpoints related to that domain. Here's an example of `Participant API` and a call to `/participants/:login`
28
40
 
29
- # Example of getting base info about specific School21 participant
41
+ ```ruby
30
42
  participants_api = client.participants_api
31
43
  response = participants_api.participants('ikael@student.21-school.ru')
32
44
 
@@ -4,21 +4,27 @@ module School21
4
4
  class Client
5
5
  include CoreLibrary
6
6
 
7
- def initialize(login:, password:)
8
- raise ArgumentError, "login can't be nil or empty" if login.nil? || login.empty?
9
- raise ArgumentError, "password can't be nil or empty" if password.nil? || password.empty?
10
-
11
- client_configuration = HttpClientConfiguration.new(logging_configuration:)
12
- http_client = FaradayClient.new(client_configuration)
13
- client_configuration.set_http_client(http_client)
7
+ def self.configure(&)
8
+ new(&)
9
+ end
14
10
 
15
- @login = login
16
- @password = password
11
+ def initialize(&block)
12
+ raise 'A block must be given' unless block_given?
13
+ raise 'You must provide block argument that represents config instance' if block.arity != 1
17
14
 
18
- @config = GlobalConfiguration
19
- .new(client_configuration:)
15
+ @config = GlobalConfig
16
+ .new
20
17
  .base_uri_executor(BaseApi.method(:base_uri))
21
18
 
19
+ yield(@config)
20
+
21
+ validate_credentials!
22
+
23
+ initialize_logging
24
+
25
+ http_client = FaradayClient.new(@config.client_configuration)
26
+ @config.client_configuration.set_http_client(http_client)
27
+
22
28
  initialize_auth!
23
29
  end
24
30
 
@@ -38,6 +44,14 @@ module School21
38
44
 
39
45
  private
40
46
 
47
+ def validate_credentials!
48
+ login = @config.credentials[:login]
49
+ password = @config.credentials[:password]
50
+
51
+ raise "Login can't be nil or empty" if login.nil? || login.empty?
52
+ raise "Password can't be nil or empty" if password.nil? || password.empty?
53
+ end
54
+
41
55
  def initialize_auth!
42
56
  @access_token = request_access_token!
43
57
 
@@ -50,22 +64,26 @@ module School21
50
64
  creds = BearerAuthCredentials.new(access_token: @access_token)
51
65
  auth_managers[BaseApi::SINGLE_AUTH_PARTICIPANT] = AuthorizationHeader.new(creds)
52
66
 
53
- @config.auth_managers(auth_managers)
67
+ @config.auth_managers = auth_managers
54
68
  end
55
69
 
56
70
  def request_access_token!
57
- auth_api_response = auth_api.token(login: @login, password: @password)
71
+ auth_api_response = auth_api.token(login: @config.credentials[:login], password: @config.credentials[:password])
58
72
  raise 'Access Token Error' unless auth_api_response.success?
59
73
 
60
74
  AccessToken.new(*auth_api_response.data.values_at(:access_token, :expires_in))
61
75
  end
62
76
 
63
- def logging_configuration
77
+ def initialize_logging
78
+ return unless @config.enable_logging
79
+
64
80
  headers_to_exclude = ['Authorization']
65
- api_request_config = ApiRequestLoggingConfiguration.new(true, true, headers_to_exclude, nil, nil, true)
66
- api_response_config = ApiResponseLoggingConfiguration.new(true, true, nil, nil, nil)
81
+ api_logging_config = ApiLoggingConfig.new(nil, nil, nil, nil, false)
82
+ api_logging_config.request_logging_config = ApiRequestLoggingConfiguration.new(true, true, headers_to_exclude,
83
+ nil, nil, true)
84
+ api_logging_config.response_logging_config = ApiResponseLoggingConfiguration.new(true, true, nil, nil, nil)
67
85
 
68
- ApiLoggingConfiguration.new(nil, nil, api_request_config, api_response_config, false)
86
+ @config.client_configuration.logging_configuration = api_logging_config
69
87
  end
70
88
  end
71
89
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class ApiLoggingConfig < CoreLibrary::ApiLoggingConfiguration
5
+ attr_writer :request_logging_config, :response_logging_config
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class ClientConfig < CoreLibrary::HttpClientConfiguration
5
+ attr_writer :logging_configuration
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class GlobalConfig < CoreLibrary::GlobalConfiguration
5
+ attr_accessor :auth_managers, :enable_logging, :credentials
6
+ attr_writer :client_configuration
7
+
8
+ def initialize(client_configuration: ClientConfig.new)
9
+ super
10
+
11
+ @enable_logging = false
12
+ @credentials = {}
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module School21
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/school21.rb CHANGED
@@ -14,4 +14,8 @@ require_relative 'school21/api/participants_api'
14
14
  require_relative 'school21/api/auth_api'
15
15
  require_relative 'school21/api/projects_api'
16
16
 
17
+ require_relative 'school21/config/api_logging_config'
18
+ require_relative 'school21/config/client_config'
19
+ require_relative 'school21/config/global_config'
20
+
17
21
  require_relative 'school21/client'
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Client Test' do
6
+ include AuthStub
7
+
8
+ before do
9
+ @login = 'login'
10
+ @password = 'password'
11
+ end
12
+
13
+ let(:valid_init_client) do
14
+ School21::Client.configure do |config|
15
+ config.credentials = { login: @login, password: @password }
16
+ config.enable_logging = false
17
+ end
18
+ end
19
+
20
+ let(:init_client_without_login) do
21
+ School21::Client.configure do |config|
22
+ config.credentials = { login: nil, password: @password }
23
+ config.enable_logging = false
24
+ end
25
+ end
26
+
27
+ let(:init_client_without_password) do
28
+ School21::Client.configure do |config|
29
+ config.credentials = { login: @login, password: nil }
30
+ config.enable_logging = false
31
+ end
32
+ end
33
+
34
+ it 'successfully stubs client auth' do
35
+ stub = stub_token
36
+
37
+ valid_init_client
38
+
39
+ assert_requested(stub)
40
+ end
41
+
42
+ it 'raises an exception without login' do
43
+ stub = stub_token
44
+
45
+ assert_raises(RuntimeError, "Login can't be nil or empty") do
46
+ init_client_without_login
47
+ end
48
+
49
+ refute_requested(stub)
50
+ end
51
+
52
+ it 'raises an exception without password' do
53
+ stub = stub_token
54
+
55
+ assert_raises(RuntimeError, "Password can't be nil or empty") do
56
+ init_client_without_password
57
+ end
58
+
59
+ refute_requested(stub)
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuthStub
4
+ include BaseStub
5
+
6
+ def stub_token
7
+ body = {
8
+ access_token: 'access_token',
9
+ expires_in: 36_000
10
+ }
11
+
12
+ stub_request(:post, stubbed_auth_url).to_return_json(body:)
13
+ end
14
+
15
+ private
16
+
17
+ def stubbed_auth_url
18
+ [BASE_AUTH_URL, '/auth/realms/EduPowerKeycloak/protocol/openid-connect/token'].join
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BaseStub
4
+ BASE_AUTH_URL = 'https://auth.sberclass.ru'
5
+ API_V1_URL = 'https://edu-api.21-school.ru/services/21-school/api/v1'
6
+ end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  require 'simplecov'
4
4
  require 'simplecov-cobertura'
5
+ require 'webmock/minitest'
6
+
7
+ require_relative 'support/stubs/base_stub'
8
+ require_relative 'support/stubs/auth_stub'
5
9
 
6
10
  SimpleCov.start
7
11
  SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
@@ -10,3 +14,6 @@ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
10
14
 
11
15
  require 'school21'
12
16
  require 'minitest/autorun'
17
+ require 'minitest/reporters'
18
+
19
+ Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: school21_api_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Yudin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-03 00:00:00.000000000 Z
11
+ date: 2024-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -100,7 +100,13 @@ files:
100
100
  - lib/school21/auth/authorization_header.rb
101
101
  - lib/school21/auth/bearer_auth_credentials.rb
102
102
  - lib/school21/client.rb
103
+ - lib/school21/config/api_logging_config.rb
104
+ - lib/school21/config/client_config.rb
105
+ - lib/school21/config/global_config.rb
103
106
  - lib/school21/version.rb
107
+ - test/client_test.rb
108
+ - test/support/stubs/auth_stub.rb
109
+ - test/support/stubs/base_stub.rb
104
110
  - test/test_helper.rb
105
111
  homepage: https://github.com/ikael21/school21_api_sdk
106
112
  licenses: