diff --git a/app/models/schedule/table.rb b/app/models/schedule/table.rb new file mode 100644 index 00000000..002850d2 --- /dev/null +++ b/app/models/schedule/table.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class Schedule + class Table + attr_reader :track_list, :rows + + def initialize(schedules) + @track_list = schedules.map(&:track_name).sort.uniq + + grouped_schedules = schedules.group_by do |s| + start_at = I18n.l(s.start_at, format: :timetable) + end_at = I18n.l(s.end_at, format: :timetable) + zone = s.end_at.strftime('%Z') + + "#{start_at} - #{end_at} (#{zone})" + end + + @rows = grouped_schedules.map { |_, v| Schedule::Table::Row.new(v) }.sort_by(&:sort_key) + end + end +end diff --git a/app/models/schedule/table/row.rb b/app/models/schedule/table/row.rb new file mode 100644 index 00000000..e5a970b9 --- /dev/null +++ b/app/models/schedule/table/row.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class Schedule + class Table + class Row + attr_reader :start_end, :timezone, :schedules, :tracks, :sort_key + + def initialize(schedules) + start_at = I18n.l(schedules[0].start_at, format: :timetable) + end_at = I18n.l(schedules[0].end_at, format: :timetable) + + @start_end = "#{start_at} - #{end_at}" + @timezone = schedules[0].end_at.strftime('%Z') + @schedules = schedules + @tracks = schedules.map { [_1.track_name, _1] }.to_h + @sort_key = schedules[0].start_at + end + end + end +end diff --git a/app/models/schedule/tables.rb b/app/models/schedule/tables.rb new file mode 100644 index 00000000..4e944520 --- /dev/null +++ b/app/models/schedule/tables.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class Schedule + class Tables + DATE_FORMAT = '%Y-%m-%d' + + def initialize(schedules) + @schedules = schedules + @map = @schedules.group_by { _1.start_at.strftime(DATE_FORMAT) }.transform_values do |v| + Schedule::Table.new(v) + end + end + + def days + @map.keys.sort_by(&:to_i) + end + + def [](key) + @map[key] + end + end +end diff --git a/test/models/schedule/table/row_test.rb b/test/models/schedule/table/row_test.rb new file mode 100644 index 00000000..3ee75464 --- /dev/null +++ b/test/models/schedule/table/row_test.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'test_helper' + +class Schedule + class Table + class RowTest < ActiveSupport::TestCase + def setup + schedules = Schedule.where(event: events(:kaigi)) + @tables = Schedule::Tables.new(schedules) + end + + test 'each rows mapping correct track infomations with fixture' do + day1 = @tables['2024-03-18'] + + assert_equal day1.rows[0].start_end, '10:00 - 10:30' + assert_equal day1.rows[0].tracks['TrackA'], schedules(:kaigi_day1_time1_track1) + + assert_equal day1.rows[1].start_end, '10:40 - 11:00' + assert_equal day1.rows[1].tracks['TrackA'], schedules(:kaigi_day1_time2_track1) + assert_equal day1.rows[1].tracks['TrackB'], schedules(:kaigi_day1_time2_track2) + assert_equal day1.rows[1].tracks['TrackC'], schedules(:kaigi_day1_time2_track3) + + assert_equal day1.rows[2].start_end, '11:10 - 11:30' + assert_equal day1.rows[2].tracks['TrackA'], schedules(:kaigi_day1_time3_track1) + assert_equal day1.rows[2].tracks['TrackB'], schedules(:kaigi_day1_time3_track2) + + assert_equal day1.rows[3].start_end, '11:45 - 12:30' + assert_equal day1.rows[3].tracks['TrackA'], schedules(:kaigi_day1_time4_track1) + + day2 = @tables['2024-03-19'] + + assert_equal day2.rows[0].start_end, '09:00 - 09:30' + assert_equal day2.rows[0].tracks['TrackA'], schedules(:kaigi_day2_time1_track1) + assert_equal day2.rows[0].tracks['TrackB'], schedules(:kaigi_day2_time1_track2) + assert_equal day2.rows[0].tracks['TrackC'], schedules(:kaigi_day2_time1_track3) + + assert_equal day2.rows[1].start_end, '10:00 - 10:30' + assert_equal day2.rows[1].tracks['TrackA'], schedules(:kaigi_day2_time2_track1) + assert_equal day2.rows[1].tracks['TrackB'], schedules(:kaigi_day2_time2_track2) + + assert_equal day2.rows[2].start_end, '10:40 - 11:10' + assert_equal day2.rows[2].tracks['TrackA'], schedules(:kaigi_day2_time3_track1) + assert_equal day2.rows[2].tracks['TrackB'], schedules(:kaigi_day2_time3_track2) + + assert_equal day2.rows[3].start_end, '13:00 - 14:00' + assert_equal day2.rows[3].tracks['TrackA'], schedules(:kaigi_day2_time4_track1) + end + end + end +end diff --git a/test/models/schedule/table_test.rb b/test/models/schedule/table_test.rb new file mode 100644 index 00000000..9cad264b --- /dev/null +++ b/test/models/schedule/table_test.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'test_helper' + +class Schedule + class TableTest < ActiveSupport::TestCase + def setup + schedules = Schedule.where(event: events(:kaigi)) + tables = Schedule::Tables.new(schedules) + @table = tables[tables.days.first] + end + + test '#track_list returns track names array' do + assert_equal @table.track_list, %w[TrackA TrackB TrackC] + end + + test '#rows retuns arrays of Schedule::Table::Row' do + assert @table.rows.all? { _1.instance_of?(Schedule::Table::Row) } + end + + test '#rows returns array sorted by track start time' do + assert_equal @table.rows.map { _1.tracks['TrackA'] }, @table.rows.map { _1.tracks['TrackA'] }.sort_by(&:start_at) + end + end +end diff --git a/test/models/schedule/tables_test.rb b/test/models/schedule/tables_test.rb new file mode 100644 index 00000000..89dffe6f --- /dev/null +++ b/test/models/schedule/tables_test.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'test_helper' + +class Schedule + class TablesTest < ActiveSupport::TestCase + def setup + schedules = Schedule.where(event: events(:kaigi)) + @tables = Schedule::Tables.new(schedules) + end + + test 'schedule table can return days of timetables orderd by asc' do + assert_equal @tables.days, %w[2024-03-18 2024-03-19] + end + + test '[] method returns Schedule::Table' do + assert_equal @tables[@tables.days.first].class, Schedule::Table + end + end +end