meibo 0.16.0 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|