milady-cima-api 0.2.0 → 0.3.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: dd05960749c0262fe3d556d454389a4183d248dc4a89b87828527ae343c77b6a
4
- data.tar.gz: 00e6c1fc23a40ba8b5211e85f5fa2cf946bca67cc5086db91b5fc4ad557cf178
3
+ metadata.gz: 8e9fdba0b8e942edd14809c180519a39323e7110110b6c862a2006b331741206
4
+ data.tar.gz: d4c5eadceb6dc83739abab360ff44137c7d42b254d86c829d53c1e5aca0aabc0
5
5
  SHA512:
6
- metadata.gz: 20976e6b55d286b1b422cbd7dfef4ed1492bcb434012a55986ac17df905d7dbcb4403f2756bb70437a8f41896d37d305501769c25a757df5b72163b7d4d52afb
7
- data.tar.gz: 668252325045549f3ccc9329b8c9823bb13e1cec9031689cc63cc6852c5f028c72e06b3df563ade3245b6bb7bac16882f2f2b1f44b8106c6c3d8fce5caa956fe
6
+ metadata.gz: 49bbf4f1f574aa9b5d2b6b07f18a943bc2660cb265ccbac038b21ea08e40ae177d631ca0382411d68280a679d886a6fd9a8db8611ab77fc4cc52f70ef71c9fe6
7
+ data.tar.gz: be4ba9b6f41686c4a8acfcaa16a503e17d43b49a59cf6c6b0ea6c91fb5a3b94bf82e500a282f00aedbf0dbd7cb72e9d11869d06d1e908ac81045f4b33f10bfbe
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2025-12-04
4
+
5
+ ### Added
6
+ - Added `Learners` resource under `Courses` to support `GET /courses/{id}/learners` and `GET /courses/{id}/learners/{user_id}`.
7
+
8
+ ### Changed
9
+ - Refactored `Courses`, `Assessments`, and `Learners` resources to inherit from a common `Base` class to share initialization and filter normalization logic.
10
+
11
+ ## [0.2.1] - 2025-12-04
12
+
13
+ ### Added
14
+ - Added `verify_ssl` option to `Client` initialization (defaults to `true`) to allow disabling SSL verification for testing or development.
15
+ - Added `Courses#find` method to retrieve a single course.
16
+ - Added live integration tests for `Courses` and `Assessments` filters (skipped by default).
17
+
18
+ ### Changed
19
+ - Updated `Courses#list` to use explicit keyword arguments for better documentation and usability, matching `Assessments#list`.
20
+
3
21
  ## [0.2.0] - 2025-12-04
4
22
 
5
23
  ### Added
@@ -10,13 +10,15 @@ module MiLadyCimaApi
10
10
  API_PAGE_LIMIT = 100
11
11
 
12
12
  attr_reader :api_key, :base_url
13
+ attr_reader :api_key, :base_url, :verify_ssl
13
14
  attr_reader :users, :organizations, :courses
14
15
 
15
- def initialize(api_key:, base_url: DEFAULT_BASE_URL)
16
+ def initialize(api_key:, base_url: DEFAULT_BASE_URL, verify_ssl: true)
16
17
  raise ArgumentError, 'api_key is required' if api_key.nil? || api_key.strip.empty?
17
18
 
18
19
  @api_key = api_key
19
20
  @base_url = base_url.chomp('/')
21
+ @verify_ssl = verify_ssl
20
22
  @users = MiLadyCimaApi::Resources::Users.new(self)
21
23
  @organizations = MiLadyCimaApi::Resources::Organizations.new(self)
22
24
  @courses = MiLadyCimaApi::Resources::Courses.new(self)
@@ -100,6 +102,7 @@ module MiLadyCimaApi
100
102
  def perform_request(uri, request)
101
103
  http = Net::HTTP.new(uri.host, uri.port)
102
104
  http.use_ssl = uri.scheme == 'https'
105
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless verify_ssl
103
106
  response = http.request(request)
104
107
  handle_response(response)
105
108
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module MiLadyCimaApi
6
+ module Resources
7
+ class Base
8
+ # @param client [MiLadyCimaApi::Client]
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ protected
14
+
15
+ def normalize_filter(filter)
16
+ return filter if filter.is_a?(String)
17
+ return JSON.generate(filter) if filter.is_a?(Hash)
18
+
19
+ raise ArgumentError, 'filter must be a String (JSON) or a Hash'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,14 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../base'
4
+
3
5
  module MiLadyCimaApi
4
6
  module Resources
5
7
  class Courses
6
8
  # Assessments resource exposes endpoints under /courses/{id}/assessments
7
- class Assessments
8
- # @param client [MiLadyCimaApi::Client]
9
- def initialize(client)
10
- @client = client
11
- end
9
+ class Assessments < Resources::Base
12
10
 
13
11
  # List assessments for a course
14
12
  #
@@ -50,14 +48,6 @@ module MiLadyCimaApi
50
48
  @client.get("/courses/#{course_id}/assessments/#{assessment_id}")
51
49
  end
52
50
 
53
- private
54
-
55
- def normalize_filter(filter)
56
- return filter if filter.is_a?(String)
57
- return JSON.generate(filter) if filter.is_a?(Hash)
58
-
59
- raise ArgumentError, 'filter must be a String (JSON) or a Hash'
60
- end
61
51
  end
62
52
  end
63
53
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base'
4
+
5
+ module MiLadyCimaApi
6
+ module Resources
7
+ class Courses
8
+ # Learners resource exposes endpoints under /courses/{id}/learners
9
+ class Learners < Resources::Base
10
+
11
+ # List learners for a course
12
+ #
13
+ # GET /courses/{id}/learners
14
+ # @param course_id [Integer, String] ID of the course
15
+ # @param filter [Hash, String] Filter using JSON structure
16
+ # @param limit [Integer] Limit the number of returned objects (default 10, max 100)
17
+ # @param offset [Integer] Used for paging through a small dataset
18
+ # @param after [Integer] Used for fast paging
19
+ # @param count [Boolean] If true, just return the number of list items
20
+ # @param include [String] Comma separated list of relationships to include
21
+ # @return [Array, Hash] Parsed JSON response from the API
22
+ def list(course_id:, filter: nil, limit: nil, offset: nil, after: nil, count: nil, include: nil)
23
+ raise ArgumentError, 'course_id is required' if course_id.nil?
24
+
25
+ if limit && limit > 100
26
+ raise ArgumentError, 'limit cannot be greater than 100'
27
+ end
28
+
29
+ params = {}
30
+ params['$filter'] = normalize_filter(filter) if filter
31
+ params['$limit'] = limit if limit
32
+ params['$offset'] = offset if offset
33
+ params['$after'] = after if after
34
+ params['$count'] = count if count
35
+ params['$include'] = include if include
36
+
37
+ @client.get("/courses/#{course_id}/learners", params: params)
38
+ end
39
+
40
+ # Get a single learner
41
+ #
42
+ # GET /courses/{id}/learners/{user_id}
43
+ # @param course_id [Integer, String] ID of the course
44
+ # @param user_id [Integer, String] ID of the user
45
+ # @param include [String] Comma separated list of relationships to include
46
+ # @return [Hash] Parsed JSON response from the API
47
+ def find(course_id:, user_id:, include: nil)
48
+ raise ArgumentError, 'course_id is required' if course_id.nil?
49
+ raise ArgumentError, 'user_id is required' if user_id.nil?
50
+
51
+ params = {}
52
+ params['$include'] = include if include
53
+
54
+ @client.get("/courses/#{course_id}/learners/#{user_id}", params: params)
55
+ end
56
+
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,39 +1,65 @@
1
1
  # frozen_string_literal: true
2
-
3
- require 'json'
4
- require_relative 'courses/assessments'
2
+ require_relative 'base'
5
3
 
6
4
  module MiLadyCimaApi
7
5
  module Resources
8
6
  # Courses resource exposes endpoints under /courses
9
7
  # Provides convenience helpers for building $filter queries.
10
- class Courses
11
- # @param client [MiLadyCimaApi::Client]
12
- def initialize(client)
13
- @client = client
14
- end
8
+ class Courses < Base
15
9
 
16
10
  # @return [MiLadyCimaApi::Resources::Courses::Assessments]
17
11
  def assessments
18
12
  @assessments ||= Assessments.new(@client)
19
13
  end
20
14
 
15
+ # @return [MiLadyCimaApi::Resources::Courses::Learners]
16
+ def learners
17
+ @learners ||= Learners.new(@client)
18
+ end
19
+
21
20
  # List courses
22
21
  #
23
22
  # GET /courses
24
- # @param params [Hash] Optional query params. Supports the special key
25
- # "$filter" (String or Hash). If provided as a Hash, it will be JSON-encoded
26
- # to match the API expectation (e.g., {"organization_id" => 123} or
27
- # {"and" => [{"gt" => {"metadata.created_at" => "2025-01-01T00:00:00.000Z"}}]}).
28
- # @option params [String, Hash] :$filter JSON string or Ruby Hash representing the filter
23
+ # @param filter [Hash, String] Filter using JSON structure
24
+ # @param limit [Integer] Limit the number of returned objects (default 10, max 100)
25
+ # @param offset [Integer] Used for paging through a small dataset
26
+ # @param after [Integer] Used for fast paging
27
+ # @param count [Boolean] If true, just return the number of list items
28
+ # @param order [String] Comma separated attribute names to sort by
29
+ # @param include [String] Comma separated list of relationships to include
29
30
  # @return [Array, Hash] Parsed JSON response from the API
30
- # @raise [MiLadyCimaApi::UnauthorizedError, MiLadyCimaApi::NotFoundError, MiLadyCimaApi::ClientError, MiLadyCimaApi::ServerError]
31
- def list(params = {})
32
- params = params.dup || {} || {}
33
- normalize_filter_param!(params)
31
+ def list(filter: nil, limit: nil, offset: nil, after: nil, count: nil, order: nil, include: nil)
32
+ if limit && limit > 100
33
+ raise ArgumentError, 'limit cannot be greater than 100'
34
+ end
35
+
36
+ params = {}
37
+ params['$filter'] = normalize_filter(filter) if filter
38
+ params['$limit'] = limit if limit
39
+ params['$offset'] = offset if offset
40
+ params['$after'] = after if after
41
+ params['$count'] = count if count
42
+ params['$order'] = order if order
43
+ params['$include'] = include if include
44
+
34
45
  @client.get('/courses', params: params)
35
46
  end
36
47
 
48
+ # Get a single course
49
+ #
50
+ # GET /courses/{id}
51
+ # @param id [Integer, String] ID of the course
52
+ # @param include [String] Comma separated list of relationships to include
53
+ # @return [Hash] Parsed JSON response from the API
54
+ def find(id:, include: nil)
55
+ raise ArgumentError, 'id is required' if id.nil?
56
+
57
+ params = {}
58
+ params['$include'] = include if include
59
+
60
+ @client.get("/courses/#{id}", params: params)
61
+ end
62
+
37
63
  # Convenience: List courses by organization
38
64
  # @param organization_id [Integer, String]
39
65
  # @param extra_params [Hash] Additional query params (e.g., pagination)
@@ -41,7 +67,7 @@ module MiLadyCimaApi
41
67
  def by_organization(organization_id:, **extra_params)
42
68
  raise ArgumentError, 'organization_id is required' if organization_id.nil?
43
69
  filter = { 'organization_id' => organization_id }
44
- list({ '$filter' => filter }.merge(extra_params))
70
+ list(filter: filter, **extra_params)
45
71
  end
46
72
 
47
73
  # Convenience: List courses filtered by created_at with comparison operator
@@ -61,27 +87,12 @@ module MiLadyCimaApi
61
87
  { 'and' => [time_filter, { 'organization_id' => organization_id }] }
62
88
  end
63
89
 
64
- list({ '$filter' => filter }.merge(extra_params))
90
+ list(filter: filter, **extra_params)
65
91
  end
66
92
 
67
- private
68
-
69
- # Mutates params hash to ensure $filter is a JSON string when provided as a Hash
70
- def normalize_filter_param!(params)
71
- # support both symbol and string keys
72
- filter_key = params.key?(:$filter) ? :$filter : (params.key?("$filter") ? "$filter" : nil)
73
- return unless filter_key
74
-
75
- value = params[filter_key]
76
- case value
77
- when Hash
78
- params[filter_key] = JSON.generate(value)
79
- when String
80
- # pass through
81
- else
82
- raise ArgumentError, "$filter must be a String (JSON) or a Hash"
83
- end
84
- end
85
93
  end
86
94
  end
87
95
  end
96
+
97
+ require_relative 'courses/assessments'
98
+ require_relative 'courses/learners'
@@ -2,5 +2,5 @@
2
2
 
3
3
  module MiLadyCimaApi
4
4
  # Gem version
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: milady-cima-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - marcus.salinas
@@ -27,8 +27,10 @@ files:
27
27
  - lib/milady_cima_api.rb
28
28
  - lib/milady_cima_api/client.rb
29
29
  - lib/milady_cima_api/errors.rb
30
+ - lib/milady_cima_api/resources/base.rb
30
31
  - lib/milady_cima_api/resources/courses.rb
31
32
  - lib/milady_cima_api/resources/courses/assessments.rb
33
+ - lib/milady_cima_api/resources/courses/learners.rb
32
34
  - lib/milady_cima_api/resources/organizations.rb
33
35
  - lib/milady_cima_api/resources/users.rb
34
36
  - lib/milady_cima_api/version.rb