school21_api_sdk 0.7.1 → 1.0.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: 3e42aec551b383afc2ece96d0a1d51bb17dceebb3a11816458900ad8091d24dc
4
- data.tar.gz: f57ae9a6237370648b071c72be8e9791ec63b80fb0858340bae07a5144d64512
3
+ metadata.gz: 949bf4a28e9e3013429b0a2b04cdb83967da477d44a8127f34f8ab4db6d4b263
4
+ data.tar.gz: dcf8d449ee13e88585c2935de6f52b2dbd4307b1cd7d39ec9735e386601cf0f0
5
5
  SHA512:
6
- metadata.gz: a21fa517788287ca518ba1f474198ec45debb415dc80f4a7821eef55c8376da0c9b8f871977e92db1b8d16f914b892538f93de0e6369f89618593f202bf2ee6f
7
- data.tar.gz: 7cb87167ba4b2f46109761d293579ddd1f7527acc5ac87d03767fc7a739d91cdf6f6cf350956515387600cbd26a905b80ecfc0fa21375c4b2985896755fbe62b
6
+ metadata.gz: 9bdc2eeeb214a91bd793c3b1b9cab2612da62085e47ff75a118b575e4f8d8da6a32936ae30adb548fa125560fcd355b839aedb4e6040f3439ea3d228d5e3a1c2
7
+ data.tar.gz: c3e318bc965832f31a4cd13e4f815f4bded90cb8d4ae23f64cbaac728ed36558e8900b5f007e0bc783408558eaab88ab4611364968189a5ea341c080d5e30da7
@@ -30,15 +30,10 @@ module School21
30
30
  execute_request(new_request)
31
31
  end
32
32
 
33
- def campus_clusters(campus_id, options: {})
33
+ def campus_clusters(campus_id)
34
34
  path = ['/campuses/', campus_id, '/clusters'].join
35
- default_options = { limit: 50, offset: 0 }.merge(options)
36
35
  new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
37
36
 
38
- default_options.each do |key, value|
39
- new_request.query_param(new_parameter(value, key:))
40
- end
41
-
42
37
  execute_request(new_request)
43
38
  end
44
39
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class CoalitionsApi < BaseApi
5
+ def coalition_participants(coalition_id, options: {})
6
+ path = ['/coalitions/', coalition_id, '/participants'].join
7
+ default_options = { limit: 50, offset: 0 }.merge(options)
8
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
9
+
10
+ default_options.each do |key, value|
11
+ new_request.query_param(new_parameter(value, key:))
12
+ end
13
+
14
+ execute_request(new_request)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class CoursesApi < BaseApi
5
+ def course(course_id)
6
+ path = ['/courses/', course_id].join
7
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
8
+
9
+ execute_request(new_request)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module School21
6
+ class EventsApi < BaseApi
7
+ EVENT_TYPES = %w[ACTIVITY EXAM TEST].freeze
8
+
9
+ def events(from:, to:, options: {})
10
+ path = '/events'
11
+ default_options = {
12
+ limit: 50,
13
+ offset: 0
14
+ }.merge(options).merge(
15
+ from: formatted_date_time(from, :from),
16
+ to: formatted_date_time(to, :to)
17
+ ).compact
18
+
19
+ validate_event_type(default_options[:type])
20
+
21
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
22
+
23
+ default_options.each do |key, value|
24
+ new_request.query_param(new_parameter(value, key:))
25
+ end
26
+
27
+ execute_request(new_request)
28
+ end
29
+
30
+ private
31
+
32
+ def formatted_date_time(value, name)
33
+ case value
34
+ when Time
35
+ value.utc.iso8601
36
+ when DateTime
37
+ value.to_time.utc.iso8601
38
+ when String
39
+ Time.iso8601(value)
40
+ value
41
+ else
42
+ raise ArgumentError, "#{name} must be an ISO 8601 date-time string, Time, or DateTime"
43
+ end
44
+ rescue ArgumentError
45
+ raise ArgumentError, "#{name} must be an ISO 8601 date-time, for example: 2024-01-23T00:00:00Z"
46
+ end
47
+
48
+ def validate_event_type(type)
49
+ return if type.blank? || EVENT_TYPES.include?(type)
50
+
51
+ raise ArgumentError, "type must be one of: #{EVENT_TYPES.join(', ')}"
52
+ end
53
+ end
54
+ end
@@ -9,6 +9,13 @@ module School21
9
9
  execute_request(new_request)
10
10
  end
11
11
 
12
+ def participant_workstation(login)
13
+ path = ['/participants/', login, '/workstation'].join
14
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
15
+
16
+ execute_request(new_request)
17
+ end
18
+
12
19
  def participant_projects(login, options: {})
13
20
  path = ['/participants/', login, '/projects'].join
14
21
  default_options = { limit: 10, offset: 0 }.merge(options)
@@ -28,6 +35,74 @@ module School21
28
35
  execute_request(new_request)
29
36
  end
30
37
 
38
+ def participant_points(login)
39
+ path = ['/participants/', login, '/points'].join
40
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
41
+
42
+ execute_request(new_request)
43
+ end
44
+
45
+ def participant_logtime(login, date: nil)
46
+ path = ['/participants/', login, '/logtime'].join
47
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
48
+
49
+ new_request.query_param(new_parameter(date, key: :date)) if date.present?
50
+
51
+ execute_request(new_request)
52
+ end
53
+
54
+ def participant_feedback(login)
55
+ path = ['/participants/', login, '/feedback'].join
56
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
57
+
58
+ execute_request(new_request)
59
+ end
60
+
61
+ def participant_experience_history(login, options: {})
62
+ path = ['/participants/', login, '/experience-history'].join
63
+ default_options = { limit: 50, offset: 0 }.merge(options)
64
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
65
+
66
+ default_options.each do |key, value|
67
+ new_request.query_param(new_parameter(value, key:))
68
+ end
69
+
70
+ execute_request(new_request)
71
+ end
72
+
73
+ def participant_courses(login, options: {})
74
+ path = ['/participants/', login, '/courses'].join
75
+ default_options = { limit: 10, offset: 0 }.merge(options)
76
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
77
+
78
+ default_options.each do |key, value|
79
+ new_request.query_param(new_parameter(value, key:))
80
+ end
81
+
82
+ execute_request(new_request)
83
+ end
84
+
85
+ def participant_course(login, course_id)
86
+ path = ['/participants/', login, '/courses/', course_id].join
87
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
88
+
89
+ execute_request(new_request)
90
+ end
91
+
92
+ def participant_coalition(login)
93
+ path = ['/participants/', login, '/coalition'].join
94
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
95
+
96
+ execute_request(new_request)
97
+ end
98
+
99
+ def participant_badges(login)
100
+ path = ['/participants/', login, '/badges'].join
101
+ new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
102
+
103
+ execute_request(new_request)
104
+ end
105
+
31
106
  def participant_skills(login)
32
107
  path = ['/participants/', login, '/skills'].join
33
108
  new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
@@ -11,7 +11,7 @@ module School21
11
11
 
12
12
  def project_participants(project_id, options: {})
13
13
  path = ['/projects/', project_id, '/participants'].join
14
- default_options = { limit: 10, offset: 0 }
14
+ default_options = { limit: 50, offset: 0 }
15
15
  new_request = request_with_auth_participant(HttpMethod::GET, path, :api_v1)
16
16
 
17
17
  options.reverse_merge!(default_options)
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class SalesApi < BaseApi
5
+ def sales
6
+ execute_request(request_with_auth_participant(HttpMethod::GET, '/sales', :api_v1))
7
+ end
8
+ end
9
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module School21
4
- VERSION = '0.7.1'
4
+ VERSION = '1.0.0'
5
5
  end
data/lib/school21.rb CHANGED
@@ -18,6 +18,10 @@ require_relative 'school21/api/projects_api'
18
18
  require_relative 'school21/api/campuses_api'
19
19
  require_relative 'school21/api/clusters_api'
20
20
  require_relative 'school21/api/graph_api'
21
+ require_relative 'school21/api/sales_api'
22
+ require_relative 'school21/api/events_api'
23
+ require_relative 'school21/api/courses_api'
24
+ require_relative 'school21/api/coalitions_api'
21
25
 
22
26
  require_relative 'school21/config/api_logging_config'
23
27
  require_relative 'school21/config/client_config'
@@ -45,7 +49,11 @@ module School21
45
49
  ProjectsApi,
46
50
  CampusesApi,
47
51
  ClustersApi,
48
- GraphApi
52
+ GraphApi,
53
+ SalesApi,
54
+ EventsApi,
55
+ CoursesApi,
56
+ CoalitionsApi
49
57
  ].freeze
50
58
 
51
59
  API_CLASSES_MAPPINGS.each do |klass|
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Campuses API Test' do
6
+ include AuthStub
7
+ include CampusesStub
8
+
9
+ with_configured_client do
10
+ let(:campus_id) { CampusesStub::TEST_CAMPUS_ID }
11
+
12
+ it 'calls stub campuses success' do
13
+ stubs = [
14
+ stub_token_success,
15
+ stub_campuses_success
16
+ ]
17
+
18
+ School21.campuses_api.campuses
19
+
20
+ stubs.each { |stub| assert_requested(stub) }
21
+ end
22
+
23
+ it 'calls stub campus participants success' do
24
+ stubs = [
25
+ stub_token_success,
26
+ stub_campus_participants_success
27
+ ]
28
+
29
+ School21.campuses_api.campus_participants(campus_id)
30
+
31
+ stubs.each { |stub| assert_requested(stub) }
32
+ end
33
+
34
+ it 'calls stub campus coalitions success' do
35
+ stubs = [
36
+ stub_token_success,
37
+ stub_campus_coalitions_success
38
+ ]
39
+
40
+ School21.campuses_api.campus_coalitions(campus_id)
41
+
42
+ stubs.each { |stub| assert_requested(stub) }
43
+ end
44
+
45
+ it 'calls stub campus clusters success without pagination params' do
46
+ stubs = [
47
+ stub_token_success,
48
+ stub_campus_clusters_success
49
+ ]
50
+
51
+ School21.campuses_api.campus_clusters(campus_id)
52
+
53
+ stubs.each { |stub| assert_requested(stub) }
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Clusters API Test' do
6
+ include AuthStub
7
+ include ClustersStub
8
+
9
+ with_configured_client do
10
+ it 'calls stub cluster map success' do
11
+ stubs = [
12
+ stub_token_success,
13
+ stub_cluster_map_success
14
+ ]
15
+
16
+ School21.clusters_api.map(ClustersStub::TEST_CLUSTER_ID, options: { occupied: true })
17
+
18
+ stubs.each { |stub| assert_requested(stub) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Coalitions API Test' do
6
+ include AuthStub
7
+ include CoalitionsStub
8
+
9
+ with_configured_client do
10
+ it 'calls stub coalition participants success' do
11
+ stubs = [
12
+ stub_token_success,
13
+ stub_coalition_participants_success
14
+ ]
15
+
16
+ School21.coalitions_api.coalition_participants(CoalitionsStub::TEST_COALITION_ID)
17
+
18
+ stubs.each { |stub| assert_requested(stub) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Courses API Test' do
6
+ include AuthStub
7
+ include CoursesStub
8
+
9
+ with_configured_client do
10
+ it 'calls stub course success' do
11
+ stubs = [
12
+ stub_token_success,
13
+ stub_course_success
14
+ ]
15
+
16
+ School21.courses_api.course(CoursesStub::TEST_COURSE_ID)
17
+
18
+ stubs.each { |stub| assert_requested(stub) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Events API Test' do
6
+ include AuthStub
7
+ include EventsStub
8
+
9
+ with_configured_client do
10
+ it 'calls stub events success' do
11
+ stubs = [
12
+ stub_token_success,
13
+ stub_events_success
14
+ ]
15
+
16
+ School21.events_api.events(
17
+ from: '2026-01-01T00:00:00Z',
18
+ to: '2026-01-31T23:59:59Z',
19
+ options: { type: 'EXAM' }
20
+ )
21
+
22
+ stubs.each { |stub| assert_requested(stub) }
23
+ end
24
+
25
+ it 'formats time values as UTC ISO 8601 date-times' do
26
+ stub_token_success
27
+ stub = stub_events_success(
28
+ from: '2026-01-01T00:00:00Z',
29
+ to: '2026-01-31T20:59:59Z'
30
+ )
31
+
32
+ School21.events_api.events(
33
+ from: Time.utc(2026, 1, 1),
34
+ to: Time.new(2026, 1, 31, 23, 59, 59, '+03:00'),
35
+ options: { type: 'EXAM' }
36
+ )
37
+
38
+ assert_requested(stub)
39
+ end
40
+
41
+ it 'rejects plain dates' do
42
+ error = assert_raises(ArgumentError) do
43
+ School21.events_api.events(from: '2026-01-01', to: '2026-01-31')
44
+ end
45
+
46
+ assert_match(/ISO 8601 date-time/, error.message)
47
+ end
48
+
49
+ it 'rejects invalid event types' do
50
+ error = assert_raises(ArgumentError) do
51
+ School21.events_api.events(
52
+ from: '2026-01-01T00:00:00Z',
53
+ to: '2026-01-31T23:59:59Z',
54
+ options: { type: 'LECTURE' }
55
+ )
56
+ end
57
+
58
+ assert_match(/ACTIVITY, EXAM, TEST/, error.message)
59
+ end
60
+ end
61
+ end
@@ -33,5 +33,137 @@ describe 'Participants API Test' do
33
33
 
34
34
  stubs.each { |stub| assert_requested(stub) }
35
35
  end
36
+
37
+ it 'calls stub participant workstation success' do
38
+ stubs = [
39
+ stub_token_success,
40
+ stub_participant_workstation_success
41
+ ]
42
+
43
+ School21.participants_api.participant_workstation(login)
44
+
45
+ stubs.each { |stub| assert_requested(stub) }
46
+ end
47
+
48
+ it 'calls stub participant skills success' do
49
+ stubs = [
50
+ stub_token_success,
51
+ stub_participant_skills_success
52
+ ]
53
+
54
+ School21.participants_api.participant_skills(login)
55
+
56
+ stubs.each { |stub| assert_requested(stub) }
57
+ end
58
+
59
+ it 'calls stub participant projects success' do
60
+ stubs = [
61
+ stub_token_success,
62
+ stub_participant_projects_success
63
+ ]
64
+
65
+ School21.participants_api.participant_projects(login, options: { status: 'IN_PROGRESS' })
66
+
67
+ stubs.each { |stub| assert_requested(stub) }
68
+ end
69
+
70
+ it 'calls stub participant project success' do
71
+ stubs = [
72
+ stub_token_success,
73
+ stub_participant_project_success
74
+ ]
75
+
76
+ School21.participants_api.participant_project(login, 12_313)
77
+
78
+ stubs.each { |stub| assert_requested(stub) }
79
+ end
80
+
81
+ it 'calls stub participant points success' do
82
+ stubs = [
83
+ stub_token_success,
84
+ stub_participant_points_success
85
+ ]
86
+
87
+ School21.participants_api.participant_points(login)
88
+
89
+ stubs.each { |stub| assert_requested(stub) }
90
+ end
91
+
92
+ it 'calls stub participant logtime success' do
93
+ stubs = [
94
+ stub_token_success,
95
+ stub_participant_logtime_success
96
+ ]
97
+
98
+ School21.participants_api.participant_logtime(login, date: '2026-01-01')
99
+
100
+ stubs.each { |stub| assert_requested(stub) }
101
+ end
102
+
103
+ it 'calls stub participant feedback success' do
104
+ stubs = [
105
+ stub_token_success,
106
+ stub_participant_feedback_success
107
+ ]
108
+
109
+ School21.participants_api.participant_feedback(login)
110
+
111
+ stubs.each { |stub| assert_requested(stub) }
112
+ end
113
+
114
+ it 'calls stub participant experience history success' do
115
+ stubs = [
116
+ stub_token_success,
117
+ stub_participant_experience_history_success
118
+ ]
119
+
120
+ School21.participants_api.participant_experience_history(login)
121
+
122
+ stubs.each { |stub| assert_requested(stub) }
123
+ end
124
+
125
+ it 'calls stub participant courses success' do
126
+ stubs = [
127
+ stub_token_success,
128
+ stub_participant_courses_success
129
+ ]
130
+
131
+ School21.participants_api.participant_courses(login, options: { status: 'ACCEPTED' })
132
+
133
+ stubs.each { |stub| assert_requested(stub) }
134
+ end
135
+
136
+ it 'calls stub participant course success' do
137
+ stubs = [
138
+ stub_token_success,
139
+ stub_participant_course_success
140
+ ]
141
+
142
+ School21.participants_api.participant_course(login, 42)
143
+
144
+ stubs.each { |stub| assert_requested(stub) }
145
+ end
146
+
147
+ it 'calls stub participant coalition success' do
148
+ stubs = [
149
+ stub_token_success,
150
+ stub_participant_coalition_success
151
+ ]
152
+
153
+ School21.participants_api.participant_coalition(login)
154
+
155
+ stubs.each { |stub| assert_requested(stub) }
156
+ end
157
+
158
+ it 'calls stub participant badges success' do
159
+ stubs = [
160
+ stub_token_success,
161
+ stub_participant_badges_success
162
+ ]
163
+
164
+ School21.participants_api.participant_badges(login)
165
+
166
+ stubs.each { |stub| assert_requested(stub) }
167
+ end
36
168
  end
37
169
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Projects API Test' do
6
+ include AuthStub
7
+ include ProjectsStub
8
+
9
+ with_configured_client do
10
+ it 'calls stub project success' do
11
+ stubs = [
12
+ stub_token_success,
13
+ stub_project_success
14
+ ]
15
+
16
+ School21.projects_api.project(ProjectsStub::TEST_PROJECT_ID)
17
+
18
+ stubs.each { |stub| assert_requested(stub) }
19
+ end
20
+
21
+ it 'calls stub project participants success' do
22
+ stubs = [
23
+ stub_token_success,
24
+ stub_project_participants_success
25
+ ]
26
+
27
+ School21.projects_api.project_participants(ProjectsStub::TEST_PROJECT_ID)
28
+
29
+ stubs.each { |stub| assert_requested(stub) }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Sales API Test' do
6
+ include AuthStub
7
+ include SalesStub
8
+
9
+ with_configured_client do
10
+ it 'calls stub sales success' do
11
+ stubs = [
12
+ stub_token_success,
13
+ stub_sales_success
14
+ ]
15
+
16
+ School21.sales_api.sales
17
+
18
+ stubs.each { |stub| assert_requested(stub) }
19
+ end
20
+ end
21
+ end
@@ -4,8 +4,23 @@ module BaseStub
4
4
  BASE_AUTH_URL = 'https://auth.21-school.ru'
5
5
  BASE_API_V1_URL = 'https://platform.21-school.ru/services/21-school/api/v1'
6
6
 
7
+ def base_api_url(path)
8
+ [BASE_API_V1_URL, path].join
9
+ end
10
+
7
11
  def base_stub_fail(http_method, url)
8
12
  stub_request(http_method, url)
9
13
  .to_return(status: [500, 'Internal Server Error'])
10
14
  end
15
+
16
+ def stub_api_success(path, query: nil, body: {})
17
+ stub = stub_request(:get, base_api_url(path))
18
+ stub = stub.with(query: stringify_query(query)) if query
19
+
20
+ stub.to_return_json(body:)
21
+ end
22
+
23
+ def stringify_query(query)
24
+ query.transform_values(&:to_s)
25
+ end
11
26
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CampusesStub
4
+ include BaseStub
5
+
6
+ TEST_CAMPUS_ID = '96098f4b-5708-4c42-a62c-6893419169b3'
7
+
8
+ def stub_campuses_success
9
+ stub_api_success('/campuses', body: { campuses: [{ id: TEST_CAMPUS_ID }] })
10
+ end
11
+
12
+ def stub_campus_participants_success
13
+ stub_api_success(
14
+ "/campuses/#{TEST_CAMPUS_ID}/participants",
15
+ query: { limit: 50, offset: 0 },
16
+ body: { logins: ['test_login'] }
17
+ )
18
+ end
19
+
20
+ def stub_campus_coalitions_success
21
+ stub_api_success(
22
+ "/campuses/#{TEST_CAMPUS_ID}/coalitions",
23
+ query: { limit: 50, offset: 0 },
24
+ body: { coalitions: [{ id: 1 }] }
25
+ )
26
+ end
27
+
28
+ def stub_campus_clusters_success
29
+ stub_api_success(
30
+ "/campuses/#{TEST_CAMPUS_ID}/clusters",
31
+ query: {},
32
+ body: { clusters: [{ id: 1 }] }
33
+ )
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ClustersStub
4
+ include BaseStub
5
+
6
+ TEST_CLUSTER_ID = 321
7
+
8
+ def stub_cluster_map_success
9
+ stub_api_success(
10
+ "/clusters/#{TEST_CLUSTER_ID}/map",
11
+ query: { limit: 50, offset: 0, occupied: true },
12
+ body: { workplaces: [{ id: 1 }] }
13
+ )
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoalitionsStub
4
+ include BaseStub
5
+
6
+ TEST_COALITION_ID = 7
7
+
8
+ def stub_coalition_participants_success
9
+ stub_api_success(
10
+ "/coalitions/#{TEST_COALITION_ID}/participants",
11
+ query: { limit: 50, offset: 0 },
12
+ body: { logins: ['test_login'] }
13
+ )
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoursesStub
4
+ include BaseStub
5
+
6
+ TEST_COURSE_ID = 42
7
+
8
+ def stub_course_success
9
+ stub_api_success("/courses/#{TEST_COURSE_ID}", body: { id: TEST_COURSE_ID })
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EventsStub
4
+ include BaseStub
5
+
6
+ def stub_events_success(from: '2026-01-01T00:00:00Z', to: '2026-01-31T23:59:59Z')
7
+ stub_api_success(
8
+ '/events',
9
+ query: { from:, to:, limit: 50, offset: 0, type: 'EXAM' },
10
+ body: { events: [{ id: 1 }] }
11
+ )
12
+ end
13
+ end
@@ -14,4 +14,68 @@ module ParticipantsStub
14
14
  def stub_participant_fail
15
15
  base_stub_fail(:get, STUBBED_PARTICIPANT_URL)
16
16
  end
17
+
18
+ def stub_participant_workstation_success
19
+ stub_api_success("/participants/#{TEST_LOGIN}/workstation", body: { id: 1 })
20
+ end
21
+
22
+ def stub_participant_skills_success
23
+ stub_api_success("/participants/#{TEST_LOGIN}/skills", body: { skills: [{ name: 'Ruby' }] })
24
+ end
25
+
26
+ def stub_participant_projects_success
27
+ stub_api_success(
28
+ "/participants/#{TEST_LOGIN}/projects",
29
+ query: { limit: 10, offset: 0, status: 'IN_PROGRESS' },
30
+ body: { projects: [{ id: 1 }] }
31
+ )
32
+ end
33
+
34
+ def stub_participant_project_success
35
+ stub_api_success("/participants/#{TEST_LOGIN}/projects/12313", body: { id: 12_313 })
36
+ end
37
+
38
+ def stub_participant_points_success
39
+ stub_api_success("/participants/#{TEST_LOGIN}/points", body: { points: 100 })
40
+ end
41
+
42
+ def stub_participant_logtime_success
43
+ stub_api_success(
44
+ "/participants/#{TEST_LOGIN}/logtime",
45
+ query: { date: '2026-01-01' },
46
+ body: { weekly_avg_hours: 10 }
47
+ )
48
+ end
49
+
50
+ def stub_participant_feedback_success
51
+ stub_api_success("/participants/#{TEST_LOGIN}/feedback", body: { feedback: [] })
52
+ end
53
+
54
+ def stub_participant_experience_history_success
55
+ stub_api_success(
56
+ "/participants/#{TEST_LOGIN}/experience-history",
57
+ query: { limit: 50, offset: 0 },
58
+ body: { history: [] }
59
+ )
60
+ end
61
+
62
+ def stub_participant_courses_success
63
+ stub_api_success(
64
+ "/participants/#{TEST_LOGIN}/courses",
65
+ query: { limit: 10, offset: 0, status: 'ACCEPTED' },
66
+ body: { courses: [{ id: 42 }] }
67
+ )
68
+ end
69
+
70
+ def stub_participant_course_success
71
+ stub_api_success("/participants/#{TEST_LOGIN}/courses/42", body: { id: 42 })
72
+ end
73
+
74
+ def stub_participant_coalition_success
75
+ stub_api_success("/participants/#{TEST_LOGIN}/coalition", body: { id: 7 })
76
+ end
77
+
78
+ def stub_participant_badges_success
79
+ stub_api_success("/participants/#{TEST_LOGIN}/badges", body: { badges: [] })
80
+ end
17
81
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ProjectsStub
4
+ include BaseStub
5
+
6
+ TEST_PROJECT_ID = 12_313
7
+
8
+ def stub_project_success
9
+ stub_api_success("/projects/#{TEST_PROJECT_ID}", body: { id: TEST_PROJECT_ID })
10
+ end
11
+
12
+ def stub_project_participants_success
13
+ stub_api_success(
14
+ "/projects/#{TEST_PROJECT_ID}/participants",
15
+ query: { limit: 50, offset: 0 },
16
+ body: { logins: ['test_login'] }
17
+ )
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SalesStub
4
+ include BaseStub
5
+
6
+ def stub_sales_success
7
+ stub_api_success('/sales', body: { sales: [{ status: 'OPEN' }] })
8
+ end
9
+ end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  require 'simplecov'
4
4
  require 'simplecov-cobertura'
5
+
6
+ SimpleCov.command_name 'test'
7
+ SimpleCov.start do
8
+ add_filter '/test/'
9
+ add_filter '/coverage/'
10
+ end
11
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
12
+
13
+ require 'minitest/autorun'
5
14
  require 'webmock/minitest'
6
15
  require 'debug'
7
16
 
@@ -11,14 +20,17 @@ require_relative 'support/stubs/base_stub'
11
20
  require_relative 'support/stubs/auth_stub'
12
21
  require_relative 'support/stubs/participants_stub'
13
22
  require_relative 'support/stubs/graph_stub'
14
-
15
- SimpleCov.start
16
- SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
23
+ require_relative 'support/stubs/projects_stub'
24
+ require_relative 'support/stubs/campuses_stub'
25
+ require_relative 'support/stubs/clusters_stub'
26
+ require_relative 'support/stubs/sales_stub'
27
+ require_relative 'support/stubs/events_stub'
28
+ require_relative 'support/stubs/courses_stub'
29
+ require_relative 'support/stubs/coalitions_stub'
17
30
 
18
31
  $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
19
32
 
20
33
  require 'school21'
21
- require 'minitest/autorun'
22
34
  require 'minitest/reporters'
23
35
 
24
36
  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.7.1
4
+ version: 1.0.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: 2026-01-02 00:00:00.000000000 Z
11
+ date: 2026-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -112,9 +112,13 @@ files:
112
112
  - lib/school21/api/base_api.rb
113
113
  - lib/school21/api/campuses_api.rb
114
114
  - lib/school21/api/clusters_api.rb
115
+ - lib/school21/api/coalitions_api.rb
116
+ - lib/school21/api/courses_api.rb
117
+ - lib/school21/api/events_api.rb
115
118
  - lib/school21/api/graph_api.rb
116
119
  - lib/school21/api/participants_api.rb
117
120
  - lib/school21/api/projects_api.rb
121
+ - lib/school21/api/sales_api.rb
118
122
  - lib/school21/auth/access_token.rb
119
123
  - lib/school21/auth/authenticator.rb
120
124
  - lib/school21/auth/authorization_header.rb
@@ -124,14 +128,28 @@ files:
124
128
  - lib/school21/config/global_config.rb
125
129
  - lib/school21/version.rb
126
130
  - test/auth_api_test.rb
131
+ - test/campuses_api_test.rb
132
+ - test/clusters_api_test.rb
133
+ - test/coalitions_api_test.rb
127
134
  - test/configuration_test.rb
135
+ - test/courses_api_test.rb
136
+ - test/events_api_test.rb
128
137
  - test/graph_api_test.rb
129
138
  - test/participants_api_test.rb
139
+ - test/projects_api_test.rb
140
+ - test/sales_api_test.rb
130
141
  - test/support/shared_data.rb
131
142
  - test/support/stubs/auth_stub.rb
132
143
  - test/support/stubs/base_stub.rb
144
+ - test/support/stubs/campuses_stub.rb
145
+ - test/support/stubs/clusters_stub.rb
146
+ - test/support/stubs/coalitions_stub.rb
147
+ - test/support/stubs/courses_stub.rb
148
+ - test/support/stubs/events_stub.rb
133
149
  - test/support/stubs/graph_stub.rb
134
150
  - test/support/stubs/participants_stub.rb
151
+ - test/support/stubs/projects_stub.rb
152
+ - test/support/stubs/sales_stub.rb
135
153
  - test/test_helper.rb
136
154
  homepage: https://github.com/ikael21/school21_api_sdk
137
155
  licenses: