meibo 0.16.0 → 0.17.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 +4 -4
- data/.rubocop.yml +8 -4
- data/.rubocop_todo.yml +130 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +11 -2
- data/lib/meibo/academic_session.rb +17 -16
- data/lib/meibo/builder/academic_session_builder.rb +2 -2
- data/lib/meibo/builder/base_builder.rb +3 -2
- data/lib/meibo/builder/classroom_builder.rb +3 -3
- data/lib/meibo/builder/course_builder.rb +3 -3
- data/lib/meibo/builder/demographic_builder.rb +2 -2
- data/lib/meibo/builder/enrollment_builder.rb +3 -3
- data/lib/meibo/builder/organization_builder.rb +2 -2
- data/lib/meibo/builder/role_builder.rb +3 -3
- data/lib/meibo/builder/user_builder.rb +2 -2
- data/lib/meibo/builder/user_profile_builder.rb +3 -3
- data/lib/meibo/builder.rb +3 -2
- data/lib/meibo/classroom.rb +27 -28
- data/lib/meibo/classroom_set.rb +1 -3
- data/lib/meibo/converter.rb +29 -31
- data/lib/meibo/course.rb +15 -16
- data/lib/meibo/course_set.rb +1 -3
- data/lib/meibo/data_model.rb +6 -9
- data/lib/meibo/data_set.rb +17 -8
- data/lib/meibo/demographic.rb +30 -29
- data/lib/meibo/enrollment.rb +18 -17
- data/lib/meibo/factory_bot/academic_session.rb +3 -3
- data/lib/meibo/factory_bot/all.rb +11 -11
- data/lib/meibo/factory_bot/classroom.rb +4 -4
- data/lib/meibo/factory_bot/course.rb +4 -4
- data/lib/meibo/factory_bot/demographic.rb +3 -3
- data/lib/meibo/factory_bot/enrollment.rb +3 -3
- data/lib/meibo/factory_bot/manifest.rb +2 -2
- data/lib/meibo/factory_bot/organization.rb +15 -12
- data/lib/meibo/factory_bot/role.rb +3 -3
- data/lib/meibo/factory_bot/roster.rb +2 -2
- data/lib/meibo/factory_bot/user.rb +6 -6
- data/lib/meibo/factory_bot/user_profile.rb +7 -7
- data/lib/meibo/japan_profile/academic_session.rb +4 -2
- data/lib/meibo/japan_profile/classroom.rb +1 -1
- data/lib/meibo/japan_profile/course.rb +2 -2
- data/lib/meibo/japan_profile/enrollment.rb +9 -8
- data/lib/meibo/japan_profile/organization.rb +2 -2
- data/lib/meibo/japan_profile/role.rb +3 -3
- data/lib/meibo/japan_profile/user.rb +6 -5
- data/lib/meibo/japan_profile/user_set.rb +1 -3
- data/lib/meibo/japan_profile.rb +2 -2
- data/lib/meibo/manifest/processing_mode.rb +6 -5
- data/lib/meibo/manifest.rb +47 -41
- data/lib/meibo/organization.rb +16 -15
- data/lib/meibo/profile.rb +3 -3
- data/lib/meibo/reader.rb +11 -7
- data/lib/meibo/role.rb +28 -27
- data/lib/meibo/role_set.rb +1 -3
- data/lib/meibo/roster.rb +64 -41
- data/lib/meibo/user.rb +29 -28
- data/lib/meibo/user_profile.rb +14 -13
- data/lib/meibo/user_set.rb +1 -3
- data/lib/meibo/version.rb +1 -1
- data/lib/meibo.rb +2 -2
- data/meibo.gemspec +2 -0
- metadata +19 -3
data/lib/meibo/converter.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "date"
|
4
|
+
require "time"
|
5
5
|
|
6
6
|
module Meibo
|
7
7
|
module Converter
|
@@ -20,18 +20,18 @@ module Meibo
|
|
20
20
|
|
21
21
|
class << self
|
22
22
|
def build_header_field_to_attribute_converter(attribute_name_to_header_field_map)
|
23
|
-
header_field_to_attribute_name_map = attribute_name_to_header_field_map.to_h
|
23
|
+
header_field_to_attribute_name_map = attribute_name_to_header_field_map.to_h do |attribute, header_field|
|
24
24
|
[header_field, attribute]
|
25
|
-
|
26
|
-
|
25
|
+
end.freeze
|
26
|
+
->(field) { header_field_to_attribute_name_map.fetch(field, field) }
|
27
27
|
end
|
28
28
|
|
29
29
|
def build_parser_converter(fields:, converters:)
|
30
|
-
build_converter(fields: fields, converters: converters, write_or_parser:
|
30
|
+
build_converter(fields: fields, converters: converters, write_or_parser: "parser")
|
31
31
|
end
|
32
32
|
|
33
33
|
def build_write_converter(fields:, converters:)
|
34
|
-
build_converter(fields: fields, converters: converters, write_or_parser:
|
34
|
+
build_converter(fields: fields, converters: converters, write_or_parser: "write")
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
@@ -42,20 +42,18 @@ module Meibo
|
|
42
42
|
method_name = "build_#{converter_type}_field_#{write_or_parser}_converter"
|
43
43
|
if fields_to_be_converted && respond_to?(method_name, true)
|
44
44
|
if converter_type == :enum
|
45
|
-
enum_definition = fields_to_be_converted.
|
45
|
+
enum_definition = fields_to_be_converted.transform_keys { |field| fields.index(field) }
|
46
46
|
send(method_name, enum_definition)
|
47
47
|
else
|
48
|
-
indexes = fields_to_be_converted.map {|field| fields.index(field) }
|
48
|
+
indexes = fields_to_be_converted.map { |field| fields.index(field) }
|
49
49
|
send(method_name, indexes)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
53
53
|
lambda do |field, field_info|
|
54
54
|
# NOTE: convert blank sourcedId to nil
|
55
|
-
if field_info.index.zero?
|
56
|
-
|
57
|
-
end
|
58
|
-
converter_list.each {|converter| field = converter[field, field_info] }
|
55
|
+
field = nil if field_info.index.zero? && field.empty?
|
56
|
+
converter_list.each { |converter| field = converter[field, field_info] }
|
59
57
|
field
|
60
58
|
end
|
61
59
|
end
|
@@ -65,9 +63,9 @@ module Meibo
|
|
65
63
|
lambda do |field, field_info|
|
66
64
|
if boolean_field_indexes.include?(field_info.index)
|
67
65
|
case field
|
68
|
-
when
|
66
|
+
when "true"
|
69
67
|
true
|
70
|
-
when
|
68
|
+
when "false"
|
71
69
|
false
|
72
70
|
when nil
|
73
71
|
nil
|
@@ -96,8 +94,8 @@ module Meibo
|
|
96
94
|
lambda do |field, field_info|
|
97
95
|
if field && date_field_indexes.include?(field_info.index)
|
98
96
|
begin
|
99
|
-
Date.strptime(field,
|
100
|
-
rescue
|
97
|
+
Date.strptime(field, "%Y-%m-%d")
|
98
|
+
rescue StandardError
|
101
99
|
raise InvalidDataTypeError
|
102
100
|
end
|
103
101
|
else
|
@@ -123,7 +121,7 @@ module Meibo
|
|
123
121
|
if field && datetime_field_indexes.include?(field_info.index)
|
124
122
|
begin
|
125
123
|
Time.iso8601(field)
|
126
|
-
rescue
|
124
|
+
rescue StandardError
|
127
125
|
raise InvalidDataTypeError
|
128
126
|
end
|
129
127
|
else
|
@@ -138,11 +136,8 @@ module Meibo
|
|
138
136
|
return field unless field
|
139
137
|
|
140
138
|
enum = enum_definition[field_info.index]
|
141
|
-
if enum
|
142
|
-
|
143
|
-
raise InvalidDataTypeError
|
144
|
-
end
|
145
|
-
end
|
139
|
+
raise InvalidDataTypeError if enum&.none? { |e| e.match?(field) }
|
140
|
+
|
146
141
|
field
|
147
142
|
end
|
148
143
|
end
|
@@ -153,7 +148,7 @@ module Meibo
|
|
153
148
|
if field && integer_field_indexes.include?(field_info.index)
|
154
149
|
begin
|
155
150
|
Integer(field, 10)
|
156
|
-
rescue
|
151
|
+
rescue StandardError
|
157
152
|
raise InvalidDataTypeError
|
158
153
|
end
|
159
154
|
else
|
@@ -170,7 +165,7 @@ module Meibo
|
|
170
165
|
if field.empty?
|
171
166
|
nil
|
172
167
|
else
|
173
|
-
field.join(
|
168
|
+
field.join(",")
|
174
169
|
end
|
175
170
|
end
|
176
171
|
else
|
@@ -184,7 +179,7 @@ module Meibo
|
|
184
179
|
lambda do |field, field_info|
|
185
180
|
if list_field_indexes.include?(field_info.index)
|
186
181
|
if field
|
187
|
-
field.split(
|
182
|
+
field.split(",").map(&:strip)
|
188
183
|
else
|
189
184
|
[]
|
190
185
|
end
|
@@ -212,7 +207,7 @@ module Meibo
|
|
212
207
|
status_field_indexes = status_field_indexes.dup.freeze
|
213
208
|
lambda do |field, field_info|
|
214
209
|
if field && status_field_indexes.include?(field_info.index)
|
215
|
-
raise InvalidDataTypeError, "invalid status: #{field}" unless
|
210
|
+
raise InvalidDataTypeError, "invalid status: #{field}" unless %w[active tobedeleted].include?(field)
|
216
211
|
else
|
217
212
|
field
|
218
213
|
end
|
@@ -222,9 +217,12 @@ module Meibo
|
|
222
217
|
def build_user_ids_field_parser_converter(user_ids_field_indexes)
|
223
218
|
user_ids_field_indexes = user_ids_field_indexes.dup.freeze
|
224
219
|
lambda do |field, field_info|
|
225
|
-
if user_ids_field_indexes.include?(field_info.index)
|
226
|
-
|
220
|
+
if user_ids_field_indexes.include?(field_info.index) && !field.all? do |user_id|
|
221
|
+
Meibo::User::USER_ID_FORMAT_REGEXP.match?(user_id)
|
222
|
+
end
|
223
|
+
raise InvalidDataTypeError
|
227
224
|
end
|
225
|
+
|
228
226
|
field
|
229
227
|
end
|
230
228
|
end
|
@@ -246,7 +244,7 @@ module Meibo
|
|
246
244
|
if field && year_field_indexes.include?(field_info.index)
|
247
245
|
begin
|
248
246
|
Integer(field, 10)
|
249
|
-
rescue
|
247
|
+
rescue StandardError
|
250
248
|
raise InvalidDataTypeError
|
251
249
|
end
|
252
250
|
else
|
@@ -256,4 +254,4 @@ module Meibo
|
|
256
254
|
end
|
257
255
|
end
|
258
256
|
end
|
259
|
-
end
|
257
|
+
end
|
data/lib/meibo/course.rb
CHANGED
@@ -5,29 +5,28 @@ module Meibo
|
|
5
5
|
DataModel.define(
|
6
6
|
self,
|
7
7
|
attribute_name_to_header_field_map: {
|
8
|
-
sourced_id:
|
9
|
-
status:
|
10
|
-
date_last_modified:
|
11
|
-
school_year_sourced_id:
|
12
|
-
title:
|
13
|
-
course_code:
|
14
|
-
grades:
|
15
|
-
org_sourced_id:
|
16
|
-
subjects:
|
17
|
-
subject_codes:
|
8
|
+
sourced_id: "sourcedId",
|
9
|
+
status: "status",
|
10
|
+
date_last_modified: "dateLastModified",
|
11
|
+
school_year_sourced_id: "schoolYearSourcedId",
|
12
|
+
title: "title",
|
13
|
+
course_code: "courseCode",
|
14
|
+
grades: "grades",
|
15
|
+
org_sourced_id: "orgSourcedId",
|
16
|
+
subjects: "subjects",
|
17
|
+
subject_codes: "subjectCodes"
|
18
18
|
},
|
19
19
|
converters: {
|
20
20
|
datetime: [:date_last_modified],
|
21
|
-
list: [
|
22
|
-
required: [
|
21
|
+
list: %i[grades subjects subject_codes],
|
22
|
+
required: %i[sourced_id title org_sourced_id],
|
23
23
|
status: [:status]
|
24
24
|
}
|
25
25
|
)
|
26
26
|
|
27
|
-
def initialize(sourced_id:, status: nil, date_last_modified: nil, school_year_sourced_id: nil,
|
28
|
-
|
29
|
-
|
30
|
-
end
|
27
|
+
def initialize(sourced_id:, title:, org_sourced_id:, status: nil, date_last_modified: nil, school_year_sourced_id: nil,
|
28
|
+
course_code: nil, grades: [], subjects: [], subject_codes: [], **extension_fields)
|
29
|
+
raise InvalidDataTypeError unless subjects.is_a?(Array) && subject_codes.is_a?(Array) && subjects.size == subject_codes.size
|
31
30
|
|
32
31
|
@sourced_id = sourced_id
|
33
32
|
@status = status
|
data/lib/meibo/course_set.rb
CHANGED
@@ -6,9 +6,7 @@ module Meibo
|
|
6
6
|
super
|
7
7
|
|
8
8
|
each do |course|
|
9
|
-
if course.school_year_sourced_id
|
10
|
-
roster.academic_sessions.find(course.school_year_sourced_id)
|
11
|
-
end
|
9
|
+
roster.academic_sessions.find(course.school_year_sourced_id) if course.school_year_sourced_id
|
12
10
|
|
13
11
|
roster.organizations.find(course.org_sourced_id)
|
14
12
|
end
|
data/lib/meibo/data_model.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "csv"
|
4
4
|
|
5
5
|
module Meibo
|
6
6
|
module DataModel
|
@@ -10,14 +10,11 @@ module Meibo
|
|
10
10
|
|
11
11
|
actual_headers = CSV.parse_line(csv)
|
12
12
|
missing_headers = header_fields - actual_headers
|
13
|
-
unless missing_headers.empty?
|
14
|
-
|
15
|
-
end
|
16
|
-
unless actual_headers.take(header_fields.size) == header_fields
|
17
|
-
raise ScrambledHeadersError
|
18
|
-
end
|
13
|
+
raise MissingHeadersError, "missing headers: #{missing_headers.join(",")}" unless missing_headers.empty?
|
14
|
+
raise ScrambledHeadersError unless actual_headers.take(header_fields.size) == header_fields
|
19
15
|
|
20
|
-
CSV.parse(csv, encoding: Meibo::CSV_ENCODING, headers: true, converters: parser_converters,
|
16
|
+
CSV.parse(csv, encoding: Meibo::CSV_ENCODING, headers: true, converters: parser_converters,
|
17
|
+
header_converters: header_converters).each do |row|
|
21
18
|
yield new(**row.to_h)
|
22
19
|
end
|
23
20
|
end
|
@@ -78,7 +75,7 @@ module Meibo
|
|
78
75
|
end
|
79
76
|
|
80
77
|
def to_a
|
81
|
-
self.class.attribute_names.map {|attribute| public_send(attribute) }
|
78
|
+
self.class.attribute_names.map { |attribute| public_send(attribute) }
|
82
79
|
end
|
83
80
|
|
84
81
|
def to_h
|
data/lib/meibo/data_set.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Meibo
|
2
4
|
class DataSet
|
3
5
|
include Enumerable
|
@@ -12,7 +14,11 @@ module Meibo
|
|
12
14
|
|
13
15
|
def <<(new_data)
|
14
16
|
raise DataNotFoundError, "sourcedIdがありません" unless new_data.sourced_id
|
15
|
-
|
17
|
+
|
18
|
+
if data_by_sourced_id.key?(new_data.sourced_id)
|
19
|
+
raise SourcedIdDuplicatedError,
|
20
|
+
"sourcedId\u304C\u91CD\u8907\u3057\u3066\u3044\u307E\u3059"
|
21
|
+
end
|
16
22
|
|
17
23
|
@data << new_data
|
18
24
|
@cache.clear
|
@@ -20,12 +26,11 @@ module Meibo
|
|
20
26
|
|
21
27
|
def check_semantically_consistent
|
22
28
|
unless @data.size == data_by_sourced_id.size
|
23
|
-
raise SourcedIdDuplicatedError,
|
29
|
+
raise SourcedIdDuplicatedError,
|
30
|
+
"sourcedId\u304C\u91CD\u8907\u3057\u3066\u3044\u307E\u3059"
|
24
31
|
end
|
25
32
|
|
26
|
-
unless data_by_sourced_id[nil].nil?
|
27
|
-
raise DataNotFoundError, "sourcedIdがありません"
|
28
|
-
end
|
33
|
+
raise DataNotFoundError, "sourcedIdがありません" unless data_by_sourced_id[nil].nil?
|
29
34
|
end
|
30
35
|
|
31
36
|
def each(...)
|
@@ -55,14 +60,18 @@ module Meibo
|
|
55
60
|
|
56
61
|
def group_cache
|
57
62
|
@cache[:group_cache] ||= Hash.new do |hash, keys|
|
58
|
-
hash[keys] = @data.group_by
|
59
|
-
|
63
|
+
hash[keys] = @data.group_by do |datum|
|
64
|
+
keys.map do |attribute|
|
65
|
+
datum.public_send(attribute)
|
66
|
+
end
|
67
|
+
end.transform_values do |data|
|
68
|
+
new(data)
|
60
69
|
end
|
61
70
|
end
|
62
71
|
end
|
63
72
|
|
64
73
|
def data_by_sourced_id
|
65
|
-
@cache[:data_by_sourced_id] ||= @data.to_h {|datum| [datum.sourced_id, datum] }
|
74
|
+
@cache[:data_by_sourced_id] ||= @data.to_h { |datum| [datum.sourced_id, datum] }
|
66
75
|
end
|
67
76
|
|
68
77
|
def new(data)
|
data/lib/meibo/demographic.rb
CHANGED
@@ -3,41 +3,41 @@
|
|
3
3
|
module Meibo
|
4
4
|
class Demographic
|
5
5
|
SEX = {
|
6
|
-
male:
|
7
|
-
female:
|
8
|
-
unspecified:
|
9
|
-
other:
|
6
|
+
male: "male",
|
7
|
+
female: "female",
|
8
|
+
unspecified: "unspecified",
|
9
|
+
other: "other"
|
10
10
|
}.freeze
|
11
11
|
|
12
12
|
DataModel.define(
|
13
13
|
self,
|
14
14
|
attribute_name_to_header_field_map: {
|
15
|
-
sourced_id:
|
16
|
-
status:
|
17
|
-
date_last_modified:
|
18
|
-
birth_date:
|
19
|
-
sex:
|
20
|
-
american_indian_or_alaska_native:
|
21
|
-
asian:
|
22
|
-
black_or_african_american:
|
23
|
-
native_hawaiian_or_other_pacific_islander:
|
24
|
-
white:
|
25
|
-
demographic_race_two_or_more_races:
|
26
|
-
hispanic_or_latino_ethnicity:
|
27
|
-
country_of_birth_code:
|
28
|
-
state_of_birth_abbreviation:
|
29
|
-
city_of_birth:
|
30
|
-
public_school_residence_status:
|
15
|
+
sourced_id: "sourcedId",
|
16
|
+
status: "status",
|
17
|
+
date_last_modified: "dateLastModified",
|
18
|
+
birth_date: "birthDate",
|
19
|
+
sex: "sex",
|
20
|
+
american_indian_or_alaska_native: "americanIndianOrAlaskaNative",
|
21
|
+
asian: "asian",
|
22
|
+
black_or_african_american: "blackOrAfricanAmerican",
|
23
|
+
native_hawaiian_or_other_pacific_islander: "nativeHawaiianOrOtherPacificIslander",
|
24
|
+
white: "white",
|
25
|
+
demographic_race_two_or_more_races: "demographicRaceTwoOrMoreRaces",
|
26
|
+
hispanic_or_latino_ethnicity: "hispanicOrLatinoEthnicity",
|
27
|
+
country_of_birth_code: "countryOfBirthCode",
|
28
|
+
state_of_birth_abbreviation: "stateOfBirthAbbreviation",
|
29
|
+
city_of_birth: "cityOfBirth",
|
30
|
+
public_school_residence_status: "publicSchoolResidenceStatus"
|
31
31
|
}.freeze,
|
32
32
|
converters: {
|
33
|
-
boolean: [
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
boolean: %i[
|
34
|
+
american_indian_or_alaska_native
|
35
|
+
asian
|
36
|
+
black_or_african_american
|
37
|
+
native_hawaiian_or_other_pacific_islander
|
38
|
+
white
|
39
|
+
demographic_race_two_or_more_races
|
40
|
+
hispanic_or_latino_ethnicity
|
41
41
|
].freeze,
|
42
42
|
date: [:birth_date].freeze,
|
43
43
|
datetime: [:date_last_modified].freeze,
|
@@ -47,7 +47,8 @@ module Meibo
|
|
47
47
|
}
|
48
48
|
)
|
49
49
|
|
50
|
-
def initialize(sourced_id:, status: nil, date_last_modified: nil, birth_date: nil, sex: nil,
|
50
|
+
def initialize(sourced_id:, status: nil, date_last_modified: nil, birth_date: nil, sex: nil,
|
51
|
+
american_indian_or_alaska_native: nil, asian: nil, black_or_african_american: nil, native_hawaiian_or_other_pacific_islander: nil, white: nil, demographic_race_two_or_more_races: nil, hispanic_or_latino_ethnicity: nil, country_of_birth_code: nil, state_of_birth_abbreviation: nil, city_of_birth: nil, public_school_residence_status: nil, **extension_fields)
|
51
52
|
@sourced_id = sourced_id
|
52
53
|
@status = status
|
53
54
|
@date_last_modified = date_last_modified
|
data/lib/meibo/enrollment.rb
CHANGED
@@ -3,37 +3,38 @@
|
|
3
3
|
module Meibo
|
4
4
|
class Enrollment
|
5
5
|
ROLES = {
|
6
|
-
administrator:
|
7
|
-
proctor:
|
8
|
-
student:
|
9
|
-
teacher:
|
6
|
+
administrator: "administrator",
|
7
|
+
proctor: "proctor",
|
8
|
+
student: "student",
|
9
|
+
teacher: "teacher"
|
10
10
|
}.freeze
|
11
11
|
|
12
12
|
DataModel.define(
|
13
13
|
self,
|
14
14
|
attribute_name_to_header_field_map: {
|
15
|
-
sourced_id:
|
16
|
-
status:
|
17
|
-
date_last_modified:
|
18
|
-
class_sourced_id:
|
19
|
-
school_sourced_id:
|
20
|
-
user_sourced_id:
|
21
|
-
role:
|
22
|
-
primary:
|
23
|
-
begin_date:
|
24
|
-
end_date:
|
15
|
+
sourced_id: "sourcedId",
|
16
|
+
status: "status",
|
17
|
+
date_last_modified: "dateLastModified",
|
18
|
+
class_sourced_id: "classSourcedId",
|
19
|
+
school_sourced_id: "schoolSourcedId",
|
20
|
+
user_sourced_id: "userSourcedId",
|
21
|
+
role: "role",
|
22
|
+
primary: "primary",
|
23
|
+
begin_date: "beginDate",
|
24
|
+
end_date: "endDate"
|
25
25
|
}.freeze,
|
26
26
|
converters: {
|
27
27
|
boolean: [:primary].freeze,
|
28
|
-
date: [
|
28
|
+
date: %i[begin_date end_date].freeze,
|
29
29
|
datetime: [:date_last_modified].freeze,
|
30
30
|
enum: { role: [*ROLES.values, ENUM_EXT_PATTERN].freeze }.freeze,
|
31
|
-
required: [
|
31
|
+
required: %i[sourced_id class_sourced_id school_sourced_id user_sourced_id role].freeze,
|
32
32
|
status: [:status].freeze
|
33
33
|
}
|
34
34
|
)
|
35
35
|
|
36
|
-
def initialize(sourced_id:,
|
36
|
+
def initialize(sourced_id:, class_sourced_id:, school_sourced_id:, user_sourced_id:, role:, status: nil,
|
37
|
+
date_last_modified: nil, primary: nil, begin_date: nil, end_date: nil, **extension_fields)
|
37
38
|
@sourced_id = sourced_id
|
38
39
|
@status = status
|
39
40
|
@date_last_modified = date_last_modified
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "factory_bot"
|
4
|
+
require "securerandom"
|
5
5
|
|
6
6
|
FactoryBot.define do
|
7
|
-
factory :meibo_academic_session, class:
|
7
|
+
factory :meibo_academic_session, class: "Meibo::AcademicSession" do
|
8
8
|
initialize_with { new(**attributes) }
|
9
9
|
|
10
10
|
transient do
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
3
|
+
require "meibo/factory_bot/academic_session"
|
4
|
+
require "meibo/factory_bot/classroom"
|
5
|
+
require "meibo/factory_bot/course"
|
6
|
+
require "meibo/factory_bot/demographic"
|
7
|
+
require "meibo/factory_bot/enrollment"
|
8
|
+
require "meibo/factory_bot/manifest"
|
9
|
+
require "meibo/factory_bot/organization"
|
10
|
+
require "meibo/factory_bot/role"
|
11
|
+
require "meibo/factory_bot/roster"
|
12
|
+
require "meibo/factory_bot/user_profile"
|
13
|
+
require "meibo/factory_bot/user"
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "factory_bot"
|
4
|
+
require "securerandom"
|
5
5
|
|
6
6
|
FactoryBot.define do
|
7
|
-
factory :meibo_classroom, class:
|
7
|
+
factory :meibo_classroom, class: "Meibo::Classroom" do
|
8
8
|
initialize_with { new(**attributes) }
|
9
9
|
|
10
10
|
transient do
|
@@ -14,7 +14,7 @@ FactoryBot.define do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
sourced_id { SecureRandom.uuid }
|
17
|
-
sequence(:title) {|n| "#{n}組" }
|
17
|
+
sequence(:title) { |n| "#{n}組" }
|
18
18
|
course_sourced_id { course&.sourced_id }
|
19
19
|
class_type { Meibo::Classroom::TYPES[:homeroom] }
|
20
20
|
school_sourced_id { school&.sourced_id }
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "factory_bot"
|
4
|
+
require "securerandom"
|
5
5
|
|
6
6
|
FactoryBot.define do
|
7
|
-
factory :meibo_course, class:
|
7
|
+
factory :meibo_course, class: "Meibo::Course" do
|
8
8
|
initialize_with { new(**attributes) }
|
9
9
|
|
10
10
|
transient do
|
@@ -15,7 +15,7 @@ FactoryBot.define do
|
|
15
15
|
sourced_id { SecureRandom.uuid }
|
16
16
|
school_year_sourced_id { school_year&.sourced_id }
|
17
17
|
title { "#{school_year&.title}ホームルーム" }
|
18
|
-
course_code {
|
18
|
+
course_code { "" }
|
19
19
|
org_sourced_id { organization&.sourced_id }
|
20
20
|
|
21
21
|
trait :jp do
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "factory_bot"
|
4
|
+
require "securerandom"
|
5
5
|
|
6
6
|
FactoryBot.define do
|
7
|
-
factory :meibo_demographic, class:
|
7
|
+
factory :meibo_demographic, class: "Meibo::Demographic" do
|
8
8
|
initialize_with { new(**attributes) }
|
9
9
|
|
10
10
|
transient do
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "factory_bot"
|
4
|
+
require "securerandom"
|
5
5
|
|
6
6
|
FactoryBot.define do
|
7
|
-
factory :meibo_enrollment, class:
|
7
|
+
factory :meibo_enrollment, class: "Meibo::Enrollment" do
|
8
8
|
initialize_with { new(**attributes) }
|
9
9
|
|
10
10
|
transient do
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "factory_bot"
|
4
4
|
|
5
5
|
FactoryBot.define do
|
6
|
-
factory :meibo_manifest, class:
|
6
|
+
factory :meibo_manifest, class: "Meibo::Manifest" do
|
7
7
|
initialize_with { new(**attributes) }
|
8
8
|
|
9
9
|
manifest_version { Meibo::Manifest::EXPECTED_VALUES[:manifest_version] }
|
@@ -1,32 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "factory_bot"
|
4
|
+
require "securerandom"
|
5
5
|
|
6
6
|
FactoryBot.define do
|
7
|
-
factory :meibo_organization, class:
|
7
|
+
factory :meibo_organization, class: "Meibo::Organization" do
|
8
8
|
initialize_with { new(**attributes) }
|
9
9
|
|
10
10
|
transient do
|
11
11
|
parent { nil }
|
12
12
|
|
13
13
|
# NOTE: https://www.mext.go.jp/content/20210128-mxt_chousa01-000011635_01.pdf
|
14
|
-
school_type {
|
15
|
-
prefecture_no {
|
16
|
-
kubun {
|
17
|
-
sequence(:school_no) {|n|
|
14
|
+
school_type { "B1" } # 小学校
|
15
|
+
prefecture_no { "01" } # 北海道
|
16
|
+
kubun { "2" } # 公立
|
17
|
+
sequence(:school_no) { |n| "%07d" % n }
|
18
18
|
end
|
19
19
|
|
20
20
|
sourced_id { SecureRandom.uuid }
|
21
21
|
parent_sourced_id { parent&.sourced_id }
|
22
22
|
identifier do
|
23
|
-
school_type_alphabet_map = {
|
23
|
+
school_type_alphabet_map = { "A" => "01", "B" => "02", "C" => "03", "D" => "04", "E" => "05", "F" => "06",
|
24
|
+
"G" => "07", "H" => "08" }.freeze
|
24
25
|
numerized_school_type = school_type.sub(/\A[A-H]/, school_type_alphabet_map)
|
25
26
|
numerized_school_code = "#{numerized_school_type}#{prefecture_no}#{kubun}#{school_no}"
|
26
27
|
|
27
28
|
raise unless numerized_school_code.size == 13
|
28
29
|
|
29
|
-
check_digit = (10 - (numerized_school_code.chars.map(&:to_i).zip([1, 2].cycle).map
|
30
|
+
check_digit = (10 - (numerized_school_code.chars.map(&:to_i).zip([1, 2].cycle).map do |c, n|
|
31
|
+
(c * n).digits.sum
|
32
|
+
end.sum % 10)) % 10
|
30
33
|
"#{school_type}#{prefecture_no}#{kubun}#{school_no}#{check_digit}"
|
31
34
|
end
|
32
35
|
|
@@ -54,10 +57,10 @@ FactoryBot.define do
|
|
54
57
|
type { Meibo::Organization::TYPES[:national] }
|
55
58
|
end
|
56
59
|
|
57
|
-
trait :elementary_school do |
|
60
|
+
trait :elementary_school do |_factory|
|
58
61
|
type { Meibo::Organization::TYPES[:school] }
|
59
|
-
sequence(:name) {|n| "第#{n}小学校" }
|
60
|
-
school_type {
|
62
|
+
sequence(:name) { |n| "第#{n}小学校" }
|
63
|
+
school_type { "B1" }
|
61
64
|
end
|
62
65
|
|
63
66
|
trait :jp do
|