odeon_uk 4.0.1 → 5.1.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 +5 -5
- data/.github/workflows/release.yml +73 -0
- data/.github/workflows/test.yml +43 -0
- data/.gitignore +1 -1
- data/.ruby-version +1 -0
- data/CHANGELOG.md +36 -0
- data/README.md +100 -21
- data/Rakefile +14 -15
- data/lib/odeon_uk/cinema.rb +40 -22
- data/lib/odeon_uk/internal/api_response.rb +19 -39
- data/lib/odeon_uk/internal/guest_token.rb +23 -0
- data/lib/odeon_uk/internal/parser/api/showtime.rb +81 -0
- data/lib/odeon_uk/internal/title_sanitizer.rb +3 -8
- data/lib/odeon_uk/performance.rb +34 -41
- data/lib/odeon_uk/version.rb +3 -3
- data/lib/odeon_uk.rb +16 -2
- data/odeon_uk.gemspec +10 -6
- data/test/fixtures/api/showtimes-824.json +66 -0
- data/test/fixtures/api/sites.json +32 -0
- data/test/lib/odeon_uk/cinema_test.rb +66 -215
- data/test/lib/odeon_uk/internal/api_response_test.rb +48 -29
- data/test/lib/odeon_uk/internal/fixture_shape_test.rb +14 -0
- data/test/lib/odeon_uk/internal/guest_token_test.rb +84 -0
- data/test/lib/odeon_uk/internal/parser/api/showtime_test.rb +77 -0
- data/test/lib/odeon_uk/internal/title_sanitizer_test.rb +109 -89
- data/test/lib/odeon_uk/performance_test.rb +129 -146
- data/test/lib/odeon_uk/version_test.rb +3 -3
- data/test/live/api_shape_test.rb +19 -0
- data/test/live/integration_test.rb +21 -0
- data/test/live/live_helper.rb +11 -0
- data/test/package_test.rb +56 -0
- data/test/support/api_fixtures_helper.rb +5 -30
- data/test/support/api_shapes.rb +46 -0
- data/test/support/fake_api_response.rb +9 -6
- data/test/test_helper.rb +6 -3
- metadata +67 -89
- data/.travis.yml +0 -7
- data/lib/odeon_uk/internal/parser/api/film_lookup.rb +0 -34
- data/lib/odeon_uk/internal/parser/api/performance_day.rb +0 -92
- data/rake/fixture_creator.rb +0 -46
- data/test/fixtures/api/all_cinemas.plist +0 -0
- data/test/fixtures/api/app_init.plist +0 -0
- data/test/fixtures/api/film_times/71-14876.plist +0 -0
- data/test/fixtures/api/film_times/71-15408.plist +0 -0
- data/test/fixtures/api/film_times/71-15684.plist +0 -0
- data/test/fixtures/api/film_times/71-15866.plist +0 -0
- data/test/fixtures/api/film_times/71-15868.plist +0 -0
- data/test/fixtures/api/film_times/71-15961.plist +0 -0
- data/test/fixtures/api/film_times/71-15963.plist +0 -0
- data/test/fixtures/api/film_times/71-15965.plist +0 -0
- data/test/fixtures/api/film_times/71-15967.plist +0 -0
- data/test/fixtures/api/film_times/71-15969.plist +0 -0
- data/test/fixtures/api/film_times/71-15977.plist +0 -0
- data/test/fixtures/api/film_times/71-15980.plist +0 -0
- data/test/fixtures/api/film_times/71-16037.plist +0 -0
- data/test/fixtures/api/film_times/71-16136.plist +0 -0
- data/test/fixtures/api/film_times/71-16142.plist +0 -0
- data/test/fixtures/api/film_times/71-16143.plist +0 -0
- data/test/fixtures/api/film_times/71-16187.plist +0 -0
- data/test/fixtures/api/film_times/71-16369.plist +0 -0
- data/test/fixtures/api/film_times/71-16370.plist +0 -0
- data/test/fixtures/api/film_times/71-16374.plist +0 -0
- data/test/fixtures/api/film_times/71-16386.plist +0 -0
- data/test/fixtures/api/film_times/71-16387.plist +0 -0
- data/test/fixtures/api/film_times/71-16388.plist +0 -0
- data/test/fixtures/api/film_times/71-16438.plist +0 -0
- data/test/fixtures/api/film_times/71-16454.plist +0 -0
- data/test/fixtures/api/film_times/71-16457.plist +0 -0
- data/test/fixtures/api/film_times/71-16477.plist +0 -0
- data/test/fixtures/api/film_times/71-16478.plist +0 -0
- data/test/fixtures/api/film_times/71-16480.plist +0 -0
- data/test/fixtures/api/film_times/71-16482.plist +0 -0
- data/test/fixtures/api/film_times/71-16489.plist +0 -0
|
@@ -1,121 +1,141 @@
|
|
|
1
1
|
require_relative '../../../test_helper'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
class OdeonUk::Internal::TitleSanitizerTest < Minitest::Test
|
|
4
|
+
def test_removes_2d
|
|
5
|
+
assert_sanitized 'Iron Man 3', 'Iron Man 3 2D'
|
|
6
|
+
end
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
def test_removes_3d
|
|
9
|
+
assert_sanitized 'Iron Man 3', 'Iron Man 3 3D'
|
|
10
|
+
end
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
def test_removes_autism_prefix
|
|
13
|
+
assert_sanitized 'Planes', 'Autism Friendly Screening - Planes'
|
|
14
|
+
end
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
+
def test_bolshoi
|
|
17
|
+
assert_sanitized 'Bolshoi: Spartacus', 'Bolshoi - Spartacus (Live)'
|
|
18
|
+
end
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
def test_removes_cinemagic_prefix
|
|
21
|
+
assert_sanitized 'Echo Planet', 'Cinemagic 2013 - Echo Planet'
|
|
22
|
+
end
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
end
|
|
24
|
+
def test_globe_on_screen
|
|
25
|
+
assert_sanitized 'Globe: Twelfth Night', 'Globe On Screen: Twelfth Night'
|
|
26
|
+
end
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
def test_met_opera
|
|
29
|
+
assert_sanitized 'Met Opera: Eugene Onegin 2013', 'Met Opera - Eugene Onegin 2013'
|
|
30
|
+
end
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
def test_met_opera_season
|
|
33
|
+
assert_sanitized 'Met Opera: La Fanciulla del West',
|
|
34
|
+
'Met Opera 2026-27: La Fanciulla del West'
|
|
35
|
+
end
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
def test_nt_live
|
|
38
|
+
assert_sanitized 'National Theatre: War Horse', 'NT Live - War Horse'
|
|
39
|
+
end
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
def test_national_theatre_encore
|
|
42
|
+
assert_sanitized 'National Theatre: Frankenstein',
|
|
43
|
+
'National Theatre Live - Frankenstein (Encore Screening)'
|
|
44
|
+
end
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
def test_roh
|
|
47
|
+
assert_sanitized 'Royal Opera House: Carmen', 'ROH - Carmen'
|
|
48
|
+
end
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
def test_rbo_season
|
|
51
|
+
assert_sanitized 'Royal Ballet and Opera: Swan Lake',
|
|
52
|
+
'RBO Cinema Season 2026-27: Swan Lake'
|
|
53
|
+
end
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
def test_short_rbo_season
|
|
56
|
+
assert_sanitized "Royal Ballet and Opera: Alice's Adventures in Wonderland",
|
|
57
|
+
"RBO 2026-27: Alice's Adventures in Wonderland"
|
|
58
|
+
end
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
end
|
|
60
|
+
def test_rsc
|
|
61
|
+
assert_sanitized 'Royal Shakespeare Company: Richard II', 'Richard II - RSC Live 2013'
|
|
62
|
+
end
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
def test_removes_ukjff_prefix
|
|
65
|
+
assert_sanitized 'From Cable Street To Brick Lane',
|
|
66
|
+
'UKJFF - From Cable Street To Brick Lane'
|
|
67
|
+
end
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
end
|
|
69
|
+
def test_removes_singalong
|
|
70
|
+
assert_sanitized 'Frozen', 'Frozen Sing-a-long'
|
|
71
|
+
end
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
def test_html_ampersands
|
|
74
|
+
assert_sanitized 'Fast & Furious 7', 'Fast & Furious 7'
|
|
75
|
+
end
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
def test_removes_language_suffix
|
|
78
|
+
assert_sanitized 'Jailer 2', 'Jailer 2 (Telugu)'
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_removes_encore_suffix
|
|
82
|
+
assert_sanitized 'Avengers Endgame', 'Avengers Endgame: Encore'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_keeps_sing_along_within_title
|
|
86
|
+
assert_sanitized 'Bebefinn Sing-Along Movie', 'Bebefinn Sing-Along Movie'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_removes_dubbed
|
|
90
|
+
assert_sanitized 'Arrietty', 'Arrietty (Dubbed)'
|
|
91
|
+
end
|
|
72
92
|
|
|
73
|
-
|
|
74
|
-
|
|
93
|
+
def test_removes_subbed
|
|
94
|
+
assert_sanitized 'Arrietty', 'Arrietty (Subbed)'
|
|
95
|
+
end
|
|
75
96
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
end
|
|
97
|
+
def test_removes_english_dub
|
|
98
|
+
assert_sanitized 'Kung Fu Soccer', 'Kung Fu Soccer (English Dub)'
|
|
99
|
+
end
|
|
80
100
|
|
|
81
|
-
|
|
82
|
-
|
|
101
|
+
def test_removes_subtitle_description
|
|
102
|
+
assert_sanitized 'Kung Fu Soccer', 'Kung Fu Soccer (Mandarin with EN/CH subtitles)'
|
|
103
|
+
end
|
|
83
104
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
end
|
|
105
|
+
def test_removes_q_and_a
|
|
106
|
+
assert_sanitized 'NAZA', 'NAZA + Q&A'
|
|
107
|
+
end
|
|
88
108
|
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
def test_removes_in_person_q_and_a
|
|
110
|
+
assert_sanitized "Charlie Shaw's Revenge", "Charlie Shaw's Revenge + In-Person Q&A"
|
|
111
|
+
end
|
|
91
112
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
end
|
|
113
|
+
def test_removes_festival_prefix
|
|
114
|
+
assert_sanitized 'Scum Of The Earth', 'Cine-Excess 2026: Scum Of The Earth'
|
|
115
|
+
end
|
|
96
116
|
|
|
97
|
-
|
|
98
|
-
|
|
117
|
+
def test_removes_anniversary
|
|
118
|
+
assert_sanitized 'SCREAM', 'SCREAM (30th Anniversary)'
|
|
119
|
+
end
|
|
99
120
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
end
|
|
121
|
+
def test_world_tour_is_not_capitalised
|
|
122
|
+
assert_sanitized "ENHYPEN World Tour 'BLOOD SAGA'", "ENHYPEN WORLD TOUR 'BLOOD SAGA'"
|
|
123
|
+
end
|
|
104
124
|
|
|
105
|
-
|
|
106
|
-
|
|
125
|
+
def test_keeps_titles_with_their_own_subtitles
|
|
126
|
+
[
|
|
127
|
+
'Harry Potter and the Deathly Hallows: Part 1',
|
|
128
|
+
'Spider-Man: Brand New Day',
|
|
129
|
+
'Hadestown: The Musical',
|
|
130
|
+
'Rammstein - Live in Mexico City',
|
|
131
|
+
'Ozzy & Black Sabbath: Back to the Beginning',
|
|
132
|
+
"BTS 'ARIRANG' IN BUENOS AIRES: LIVE VIEWING"
|
|
133
|
+
].each { |title| assert_sanitized title, title }
|
|
134
|
+
end
|
|
107
135
|
|
|
108
|
-
|
|
109
|
-
subject.must_equal('Frozen')
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
describe 'HTML ampersands' do
|
|
114
|
-
let(:title) { 'Fast & Furious 7' }
|
|
136
|
+
private
|
|
115
137
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
end
|
|
119
|
-
end
|
|
138
|
+
def assert_sanitized(expected, title)
|
|
139
|
+
assert_equal expected, OdeonUk::Internal::TitleSanitizer.new(title).sanitized
|
|
120
140
|
end
|
|
121
141
|
end
|
|
@@ -1,172 +1,155 @@
|
|
|
1
1
|
require_relative '../../test_helper'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
let(:api_response) { FakeApiResponse.new }
|
|
6
|
-
|
|
7
|
-
before { WebMock.disable_net_connect! }
|
|
8
|
-
after { WebMock.allow_net_connect! }
|
|
9
|
-
|
|
10
|
-
describe '.at(cinema_id)' do
|
|
11
|
-
subject { described_class.at(cinema_id) }
|
|
12
|
-
|
|
13
|
-
describe 'passed Fixnum' do
|
|
14
|
-
let(:cinema_id) { 71 }
|
|
15
|
-
|
|
16
|
-
it 'returns an array of performances' do
|
|
17
|
-
OdeonUk::Internal::ApiResponse.stub :new, api_response do
|
|
18
|
-
subject.must_be_instance_of(Array)
|
|
19
|
-
subject.each do |element|
|
|
20
|
-
element.must_be_instance_of(described_class)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'returns at least a sensible number' do
|
|
26
|
-
OdeonUk::Internal::ApiResponse.stub :new, api_response do
|
|
27
|
-
subject.count.must_be :>, 110
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
3
|
+
class OdeonUk::PerformanceTest < Minitest::Test
|
|
4
|
+
DATE = Date.new(2026, 10, 24)
|
|
31
5
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
it 'returns an array of performances' do
|
|
36
|
-
OdeonUk::Internal::ApiResponse.stub :new, api_response do
|
|
37
|
-
subject.must_be_instance_of(Array)
|
|
38
|
-
subject.each do |element|
|
|
39
|
-
element.must_be_instance_of(described_class)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it 'returns at least a sensible number' do
|
|
45
|
-
OdeonUk::Internal::ApiResponse.stub :new, api_response do
|
|
46
|
-
subject.count.must_be :>, 110
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
6
|
+
def setup
|
|
7
|
+
@api_response = FakeApiResponse.new
|
|
50
8
|
end
|
|
51
9
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
{
|
|
58
|
-
film_name: 'The Big Short',
|
|
59
|
-
cinema_id: 71,
|
|
60
|
-
cinema_name: 'Brighton',
|
|
61
|
-
starting_at: Time.utc(2013, 9, 12, 11, 0)
|
|
62
|
-
}
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it 'sets cinema name and film name' do
|
|
66
|
-
subject.film_name.must_equal 'The Big Short'
|
|
67
|
-
subject.cinema_name.must_equal 'Brighton'
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it 'booking url, dimension & varient are set to defaults' do
|
|
71
|
-
subject.booking_url.must_equal nil
|
|
72
|
-
subject.dimension.must_equal '2d'
|
|
73
|
-
subject.variant.must_equal []
|
|
74
|
-
end
|
|
75
|
-
end
|
|
10
|
+
def test_at_returns_performances
|
|
11
|
+
performances = performances_at(824)
|
|
12
|
+
|
|
13
|
+
assert(performances.all? { |p| p.instance_of?(OdeonUk::Performance) })
|
|
14
|
+
assert_equal 6, performances.count
|
|
76
15
|
end
|
|
77
16
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
film_name: 'Ant Man',
|
|
82
|
-
dimension: '3d',
|
|
83
|
-
cinema_id: 71,
|
|
84
|
-
cinema_name: 'Brighton',
|
|
85
|
-
starting_at: Time.utc(2013, 9, 12, 11, 0)
|
|
86
|
-
}
|
|
87
|
-
end
|
|
17
|
+
def test_at_accepts_string_id
|
|
18
|
+
assert_equal 6, performances_at('824').count
|
|
19
|
+
end
|
|
88
20
|
|
|
89
|
-
|
|
21
|
+
def test_at_sets_cinema_details
|
|
22
|
+
performances = performances_at(824)
|
|
90
23
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
subject.must_equal '3d'
|
|
94
|
-
end
|
|
24
|
+
assert_equal ['824'], performances.map(&:cinema_id).uniq
|
|
25
|
+
assert_equal ['Brighton'], performances.map(&:cinema_name).uniq
|
|
95
26
|
end
|
|
96
27
|
|
|
97
|
-
|
|
98
|
-
|
|
28
|
+
def test_at_parses_first_performance
|
|
29
|
+
performance = performances_at(824).first
|
|
99
30
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
end
|
|
31
|
+
assert_equal 'The Example Film', performance.film_name
|
|
32
|
+
assert_equal Time.utc(2026, 10, 24, 8, 0), performance.starting_at
|
|
33
|
+
assert_equal '2d', performance.dimension
|
|
34
|
+
assert_equal %w(audio_described), performance.variant
|
|
35
|
+
assert_equal 'https://www.odeon.co.uk/ticketing/seat-picker/?showtimeId=824-1001',
|
|
36
|
+
performance.booking_url
|
|
37
|
+
end
|
|
109
38
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
subject.must_equal Time.utc(2013, 9, 12, 11, 0)
|
|
113
|
-
end
|
|
114
|
-
end
|
|
39
|
+
def test_at_parses_3d_imax
|
|
40
|
+
performance = performances_at(824)[1]
|
|
115
41
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
{
|
|
119
|
-
film_name: 'Steve Jobs',
|
|
120
|
-
cinema_id: 71,
|
|
121
|
-
cinema_name: 'Brighton',
|
|
122
|
-
starting_at: Time.new(2013, 9, 12, 11, 0)
|
|
123
|
-
}
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it 'returns UTC time' do
|
|
127
|
-
subject.must_be_instance_of Time
|
|
128
|
-
subject.must_equal Time.utc(2013, 9, 12, 10, 0)
|
|
129
|
-
subject.utc?.must_equal(true)
|
|
130
|
-
end
|
|
131
|
-
end
|
|
42
|
+
assert_equal '3d', performance.dimension
|
|
43
|
+
assert_equal %w(imax), performance.variant
|
|
132
44
|
end
|
|
133
45
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
46
|
+
def test_at_returns_language_and_subtitles
|
|
47
|
+
performances = performances_at(824)
|
|
48
|
+
tamil = performances[3]
|
|
49
|
+
korean = performances[2]
|
|
50
|
+
|
|
51
|
+
assert_equal 'Imaginary Picture', tamil.film_name
|
|
52
|
+
assert_equal 2025, tamil.film_year
|
|
53
|
+
assert_equal 'Tamil', tamil.language
|
|
54
|
+
assert tamil.subtitled?
|
|
55
|
+
assert_equal 'Korean', korean.language
|
|
56
|
+
assert_equal %w(arts subtitled), korean.variant
|
|
57
|
+
end
|
|
143
58
|
|
|
144
|
-
|
|
59
|
+
def test_at_treats_open_captions_as_subtitled
|
|
60
|
+
kids = performances_at(824)[4]
|
|
145
61
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
end
|
|
62
|
+
assert_nil kids.language
|
|
63
|
+
assert_equal %w(kids subtitled), kids.variant
|
|
64
|
+
assert kids.subtitled?
|
|
150
65
|
end
|
|
151
66
|
|
|
152
|
-
|
|
153
|
-
|
|
67
|
+
def test_at_keeps_after_midnight_on_next_utc_day
|
|
68
|
+
assert_equal Time.utc(2026, 10, 24, 23, 15), performances_at(824).last.starting_at
|
|
69
|
+
end
|
|
154
70
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
end
|
|
71
|
+
def test_at_requests_each_date_in_range
|
|
72
|
+
to = DATE + 2
|
|
73
|
+
|
|
74
|
+
with_fake_api { OdeonUk::Performance.at(824, from: DATE, to: to) }
|
|
75
|
+
|
|
76
|
+
assert_equal (DATE..to).to_a, @api_response.requested_dates
|
|
77
|
+
end
|
|
164
78
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
subject.must_equal %w(senior subtitles)
|
|
79
|
+
def test_at_rejects_range_ending_before_start
|
|
80
|
+
assert_raises(ArgumentError) do
|
|
81
|
+
OdeonUk::Performance.at(824, from: DATE, to: DATE - 1)
|
|
169
82
|
end
|
|
170
83
|
end
|
|
171
84
|
|
|
85
|
+
def test_new_sets_names
|
|
86
|
+
performance = OdeonUk::Performance.new(options)
|
|
87
|
+
|
|
88
|
+
assert_equal 'The Big Short', performance.film_name
|
|
89
|
+
assert_equal 'Brighton', performance.cinema_name
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_new_sets_defaults
|
|
93
|
+
performance = OdeonUk::Performance.new(options)
|
|
94
|
+
|
|
95
|
+
assert_nil performance.booking_url
|
|
96
|
+
assert_nil performance.festival
|
|
97
|
+
assert_equal '2d', performance.dimension
|
|
98
|
+
assert_nil performance.language
|
|
99
|
+
refute performance.subtitled?
|
|
100
|
+
assert_equal [], performance.variant
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_language
|
|
104
|
+
assert_equal 'Tamil', OdeonUk::Performance.new(options(language: 'Tamil')).language
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_festival
|
|
108
|
+
festival = Cinebase::Festival.new(name: 'Cine-Excess', year: 2026)
|
|
109
|
+
performance = OdeonUk::Performance.new(options(festival: festival))
|
|
110
|
+
|
|
111
|
+
assert_equal festival, performance.festival
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_film_year
|
|
115
|
+
assert_equal 1996, OdeonUk::Performance.new(options(film_year: 1996)).film_year
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_subtitled
|
|
119
|
+
assert OdeonUk::Performance.new(options(variant: %w(subtitled))).subtitled?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def test_starting_at_converts_local_time_to_utc
|
|
123
|
+
starting_at = OdeonUk::Performance.new(
|
|
124
|
+
options(starting_at: Time.new(2013, 9, 12, 11, 0))
|
|
125
|
+
).starting_at
|
|
126
|
+
|
|
127
|
+
assert_equal Time.utc(2013, 9, 12, 10, 0), starting_at
|
|
128
|
+
assert starting_at.utc?
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_variant_is_sorted_and_lower_case
|
|
132
|
+
performance = OdeonUk::Performance.new(options(variant: %w(Subtitled Senior)))
|
|
133
|
+
|
|
134
|
+
assert_equal %w(senior subtitled), performance.variant
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
private
|
|
138
|
+
|
|
139
|
+
def options(overrides = {})
|
|
140
|
+
{
|
|
141
|
+
film_name: 'The Big Short',
|
|
142
|
+
cinema_id: '824',
|
|
143
|
+
cinema_name: 'Brighton',
|
|
144
|
+
starting_at: Time.utc(2013, 9, 12, 11, 0)
|
|
145
|
+
}.merge(overrides)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def performances_at(cinema_id)
|
|
149
|
+
with_fake_api { OdeonUk::Performance.at(cinema_id, from: DATE, to: DATE) }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def with_fake_api(&block)
|
|
153
|
+
OdeonUk::Internal::ApiResponse.stub(:new, @api_response, &block)
|
|
154
|
+
end
|
|
172
155
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative 'live_helper'
|
|
2
|
+
|
|
3
|
+
class LiveApiShapeTest < Minitest::Test
|
|
4
|
+
include ApiShapes
|
|
5
|
+
|
|
6
|
+
def test_sites_are_readable
|
|
7
|
+
assert_sites_shape('sites' => api.sites)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_showtimes_are_readable
|
|
11
|
+
assert_showtimes_shape(api.showtimes('824', Date.today + 1))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def api
|
|
17
|
+
OdeonUk::Internal::ApiResponse.new
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'live_helper'
|
|
2
|
+
|
|
3
|
+
class LiveCinemaTest < Minitest::Test
|
|
4
|
+
def test_all_returns_cinemas
|
|
5
|
+
cinemas = OdeonUk::Cinema.all
|
|
6
|
+
|
|
7
|
+
assert(cinemas.all? { |cinema| cinema.instance_of?(OdeonUk::Cinema) })
|
|
8
|
+
assert_operator cinemas.size, :>, 90
|
|
9
|
+
assert_equal 'Brighton', cinemas.detect { |cinema| cinema.id == '824' }.name
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class LivePerformanceTest < Minitest::Test
|
|
14
|
+
def test_at_returns_performances
|
|
15
|
+
tomorrow = Date.today + 1
|
|
16
|
+
performances = OdeonUk::Performance.at(824, from: tomorrow, to: tomorrow)
|
|
17
|
+
|
|
18
|
+
assert(performances.all? { |p| p.instance_of?(OdeonUk::Performance) })
|
|
19
|
+
assert_operator performances.count, :>, 10
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'minitest/autorun'
|
|
2
|
+
require 'minitest/reporters'
|
|
3
|
+
|
|
4
|
+
Minitest::Reporters.use! [
|
|
5
|
+
Minitest::Reporters::DefaultReporter.new(color: true)
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
require File.expand_path('../../../lib/odeon_uk.rb', __FILE__)
|
|
9
|
+
require_relative '../support/api_shapes'
|
|
10
|
+
|
|
11
|
+
OdeonUk.token = ENV.fetch('ODEON_TOKEN') { OdeonUk.acquire_token! }
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Run separately after building: ODEON_PACKAGE=pkg/...gem bundle exec ruby test/package_test.rb
|
|
2
|
+
require "minitest/autorun"
|
|
3
|
+
require "rubygems/installer"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
require "open3"
|
|
7
|
+
require "base64"
|
|
8
|
+
require "json"
|
|
9
|
+
|
|
10
|
+
class PlatformPackageTest < Minitest::Test
|
|
11
|
+
def setup
|
|
12
|
+
@directory = Dir.mktmpdir("odeon-package-test")
|
|
13
|
+
@spec = Gem::Installer.at(
|
|
14
|
+
ENV.fetch("ODEON_PACKAGE"), install_dir: @directory, ignore_dependencies: true
|
|
15
|
+
).install
|
|
16
|
+
@vendor = File.join(@spec.full_gem_path, "vendor", "curl-impersonate")
|
|
17
|
+
@binary = File.join(@vendor, "bin", "curl-impersonate")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def teardown
|
|
21
|
+
FileUtils.remove_entry(@directory)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_installs_runnable_executable_with_notices_and_provenance
|
|
25
|
+
assert File.executable?(@binary)
|
|
26
|
+
output, status = Open3.capture2(@binary, "--version")
|
|
27
|
+
assert status.success?
|
|
28
|
+
assert_includes output, "curl"
|
|
29
|
+
assert File.file?(File.join(@vendor, "licenses", "LICENSE_CURL"))
|
|
30
|
+
assert_includes File.read(File.join(@vendor, "SOURCE")), "2.2.3"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_acquires_token_with_gem_local_executable_and_no_curl_on_path
|
|
34
|
+
payload = Base64.urlsafe_encode64(JSON.generate("exp" => Time.now.to_i + 3600), padding: false)
|
|
35
|
+
token = "header.#{payload}.signature"
|
|
36
|
+
data = { "api" => { "authToken" => token } }
|
|
37
|
+
page = "<script>\nwindow.initialData = #{JSON.generate(data)};\n</script>\n200"
|
|
38
|
+
# Substitute only the network response, not the installed package's path resolution.
|
|
39
|
+
File.write(@binary, "#!#{RbConfig.ruby}\nSTDOUT.write(#{page.dump})\n")
|
|
40
|
+
output, error, status = Open3.capture3(
|
|
41
|
+
{ "PATH" => @directory, "RUBYOPT" => nil, "BUNDLER_SETUP" => nil,
|
|
42
|
+
"GEM_PATH" => Gem.path.join(File::PATH_SEPARATOR) }, RbConfig.ruby,
|
|
43
|
+
"-I#{File.join(@spec.full_gem_path, 'lib')}", *cinebase_load_path, "-rodeon_uk",
|
|
44
|
+
"-e", "print OdeonUk.acquire_token!"
|
|
45
|
+
)
|
|
46
|
+
assert status.success?, error
|
|
47
|
+
assert_equal token, output
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
# The package is installed without dependencies, so load the bundle's cinebase.
|
|
53
|
+
def cinebase_load_path
|
|
54
|
+
Gem.loaded_specs.fetch("cinebase").full_require_paths.map { |path| "-I#{path}" }
|
|
55
|
+
end
|
|
56
|
+
end
|