picturehouse_uk 4.0.0 → 5.0.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.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +26 -0
  3. data/.github/workflows/release.yml +26 -0
  4. data/.gitignore +1 -0
  5. data/.ruby-version +1 -0
  6. data/CHANGELOG.md +25 -0
  7. data/Rakefile +2 -2
  8. data/lib/picturehouse_uk/cinema.rb +30 -14
  9. data/lib/picturehouse_uk/internal/api.rb +42 -0
  10. data/lib/picturehouse_uk/internal/parser/address.rb +21 -6
  11. data/lib/picturehouse_uk/internal/parser/screenings.rb +85 -133
  12. data/lib/picturehouse_uk/internal/website.rb +10 -12
  13. data/lib/picturehouse_uk/version.rb +2 -2
  14. data/lib/picturehouse_uk.rb +1 -0
  15. data/picturehouse_uk.gemspec +2 -3
  16. data/rake/fixture_creator.rb +21 -1
  17. data/test/fixtures/cinemas.html +4262 -0
  18. data/test/fixtures/duke-of-york-s-picturehouse/cinema.html +6187 -0
  19. data/test/fixtures/duke-of-york-s-picturehouse/get_movies.json +120552 -0
  20. data/test/fixtures/duke-of-york-s-picturehouse/information.html +3725 -0
  21. data/test/fixtures/duke-s-at-komedia/cinema.html +6138 -0
  22. data/test/fixtures/duke-s-at-komedia/get_movies.json +112 -0
  23. data/test/fixtures/duke-s-at-komedia/information.html +3690 -0
  24. data/test/fixtures/home.html +6235 -555
  25. data/test/fixtures/phoenix-picturehouse/cinema.html +6089 -0
  26. data/test/fixtures/phoenix-picturehouse/get_movies.json +120552 -0
  27. data/test/fixtures/phoenix-picturehouse/information.html +3630 -0
  28. data/test/lib/picturehouse_uk/cinema_test.rb +34 -34
  29. data/test/lib/picturehouse_uk/internal/api_test.rb +92 -0
  30. data/test/lib/picturehouse_uk/internal/parser/address_test.rb +8 -8
  31. data/test/lib/picturehouse_uk/internal/parser/screenings_test.rb +99 -45
  32. data/test/lib/picturehouse_uk/internal/title_sanitizer_test.rb +48 -48
  33. data/test/lib/picturehouse_uk/internal/website_test.rb +12 -31
  34. data/test/lib/picturehouse_uk/performance_test.rb +63 -23
  35. data/test/lib/picturehouse_uk/version_test.rb +1 -1
  36. data/test/live/integration_test.rb +8 -8
  37. data/test/support/fake_api.rb +16 -0
  38. data/test/support/fake_website.rb +6 -6
  39. data/test/test_helper.rb +3 -2
  40. metadata +34 -50
  41. data/.travis.yml +0 -8
  42. data/test/fixtures/Duke_Of_Yorks/cinema.html +0 -3408
  43. data/test/fixtures/Duke_Of_Yorks/info.html +0 -556
  44. data/test/fixtures/Duke_Of_Yorks/whats_on.html +0 -3159
  45. data/test/fixtures/Dukes_At_Komedia/cinema.html +0 -4764
  46. data/test/fixtures/Dukes_At_Komedia/info.html +0 -526
  47. data/test/fixtures/Dukes_At_Komedia/whats_on.html +0 -4429
  48. data/test/fixtures/National_Media_Museum/cinema.html +0 -9200
  49. data/test/fixtures/National_Media_Museum/info.html +0 -606
  50. data/test/fixtures/National_Media_Museum/whats_on.html +0 -8850
  51. data/test/fixtures/Phoenix_Picturehouse/cinema.html +0 -8274
  52. data/test/fixtures/Phoenix_Picturehouse/info.html +0 -542
  53. data/test/fixtures/Phoenix_Picturehouse/whats_on.html +0 -7986
@@ -12,32 +12,32 @@ describe PicturehouseUk::Cinema do
12
12
 
13
13
  it 'returns an Array of CineworldUK::Cinemas' do
14
14
  PicturehouseUk::Internal::Website.stub :new, website do
15
- subject.must_be_instance_of(Array)
15
+ _(subject).must_be_instance_of(Array)
16
16
  subject.each do |value|
17
- value.must_be_instance_of(PicturehouseUk::Cinema)
17
+ _(value).must_be_instance_of(PicturehouseUk::Cinema)
18
18
  end
19
19
  end
20
20
  end
21
21
 
22
22
  it 'returns the correctly sized array' do
23
23
  PicturehouseUk::Internal::Website.stub :new, website do
24
- subject.size.must_equal 23
24
+ _(subject.size).must_equal 25
25
25
  end
26
26
  end
27
27
 
28
28
  it 'returns the right cinemas' do
29
29
  PicturehouseUk::Internal::Website.stub :new, website do
30
- subject.first.name.must_equal 'Clapham Picturehouse'
31
- subject.last.name.must_equal 'City Screen Picturehouse'
30
+ _(subject.first.name).must_equal 'Little Theatre Cinema'
31
+ _(subject.last.name).must_equal 'City Screen York'
32
32
  end
33
33
  end
34
34
  end
35
35
 
36
36
  describe '.new(id)' do
37
- subject { described_class.new('Dukes_At_Komedia') }
37
+ subject { described_class.new('duke-s-at-komedia') }
38
38
 
39
39
  it 'stores id, name, slug and url' do
40
- subject.must_be_instance_of(PicturehouseUk::Cinema)
40
+ _(subject).must_be_instance_of(PicturehouseUk::Cinema)
41
41
  end
42
42
  end
43
43
 
@@ -45,11 +45,11 @@ describe PicturehouseUk::Cinema do
45
45
  subject { described_class.new(id).adr }
46
46
 
47
47
  describe 'no region' do
48
- let(:id) { 'Phoenix_Picturehouse' }
48
+ let(:id) { 'phoenix-picturehouse' }
49
49
 
50
50
  it 'returns address hash' do
51
51
  PicturehouseUk::Internal::Website.stub :new, website do
52
- subject.must_equal(
52
+ _(subject).must_equal(
53
53
  street_address: '57 Walton Street',
54
54
  extended_address: nil,
55
55
  locality: 'Oxford',
@@ -62,11 +62,11 @@ describe PicturehouseUk::Cinema do
62
62
  end
63
63
 
64
64
  describe 'with region' do
65
- let(:id) { 'Dukes_At_Komedia' }
65
+ let(:id) { 'duke-s-at-komedia' }
66
66
 
67
67
  it 'returns address hash' do
68
68
  PicturehouseUk::Internal::Website.stub :new, website do
69
- subject.must_equal(
69
+ _(subject).must_equal(
70
70
  street_address: '44–47 Gardner Street',
71
71
  extended_address: nil,
72
72
  locality: 'Brighton',
@@ -83,11 +83,11 @@ describe PicturehouseUk::Cinema do
83
83
  subject { described_class.new(id).address }
84
84
 
85
85
  describe 'no region' do
86
- let(:id) { 'Phoenix_Picturehouse' }
86
+ let(:id) { 'phoenix-picturehouse' }
87
87
 
88
88
  it 'returns address hash' do
89
89
  PicturehouseUk::Internal::Website.stub :new, website do
90
- subject.must_equal(
90
+ _(subject).must_equal(
91
91
  street_address: '57 Walton Street',
92
92
  extended_address: nil,
93
93
  locality: 'Oxford',
@@ -103,11 +103,11 @@ describe PicturehouseUk::Cinema do
103
103
  describe '#brand' do
104
104
  subject { described_class.new(id).brand }
105
105
 
106
- let(:id) { 'Dukes_At_Komedia' }
106
+ let(:id) { 'duke-s-at-komedia' }
107
107
 
108
108
  it 'returns Picturehouse' do
109
109
  PicturehouseUk::Internal::Website.stub :new, website do
110
- subject.must_equal('Picturehouse')
110
+ _(subject).must_equal('Picturehouse')
111
111
  end
112
112
  end
113
113
  end
@@ -115,11 +115,11 @@ describe PicturehouseUk::Cinema do
115
115
  describe '#country_name' do
116
116
  subject { described_class.new(id).country_name }
117
117
 
118
- let(:id) { 'Dukes_At_Komedia' }
118
+ let(:id) { 'duke-s-at-komedia' }
119
119
 
120
120
  it 'returns country' do
121
121
  PicturehouseUk::Internal::Website.stub :new, website do
122
- subject.must_equal('United Kingdom')
122
+ _(subject).must_equal('United Kingdom')
123
123
  end
124
124
  end
125
125
  end
@@ -127,11 +127,11 @@ describe PicturehouseUk::Cinema do
127
127
  describe '#extended_address' do
128
128
  subject { described_class.new(id).extended_address }
129
129
 
130
- let(:id) { 'Dukes_At_Komedia' }
130
+ let(:id) { 'duke-s-at-komedia' }
131
131
 
132
132
  it 'returns second line of address' do
133
133
  PicturehouseUk::Internal::Website.stub :new, website do
134
- subject.must_equal('')
134
+ _(subject).must_equal('')
135
135
  end
136
136
  end
137
137
  end
@@ -139,12 +139,12 @@ describe PicturehouseUk::Cinema do
139
139
  describe '#full_name' do
140
140
  subject { described_class.new(id).full_name }
141
141
 
142
- let(:id) { 'Dukes_At_Komedia' }
142
+ let(:id) { 'duke-s-at-komedia' }
143
143
 
144
144
  it 'returns full name (same as name)' do
145
145
  PicturehouseUk::Internal::Website.stub :new, website do
146
- subject.must_equal("Duke's at Komedia")
147
- subject.must_equal(described_class.new(id).name)
146
+ _(subject).must_equal("Duke's at Komedia")
147
+ _(subject).must_equal(described_class.new(id).name)
148
148
  end
149
149
  end
150
150
  end
@@ -152,11 +152,11 @@ describe PicturehouseUk::Cinema do
152
152
  describe '#locality' do
153
153
  subject { described_class.new(id).locality }
154
154
 
155
- let(:id) { 'Dukes_At_Komedia' }
155
+ let(:id) { 'duke-s-at-komedia' }
156
156
 
157
157
  it 'returns second line of address' do
158
158
  PicturehouseUk::Internal::Website.stub :new, website do
159
- subject.must_equal('Brighton')
159
+ _(subject).must_equal('Brighton')
160
160
  end
161
161
  end
162
162
  end
@@ -164,11 +164,11 @@ describe PicturehouseUk::Cinema do
164
164
  describe '#name' do
165
165
  subject { described_class.new(id).name }
166
166
 
167
- let(:id) { 'Dukes_At_Komedia' }
167
+ let(:id) { 'duke-s-at-komedia' }
168
168
 
169
169
  it 'returns full name (same as name)' do
170
170
  PicturehouseUk::Internal::Website.stub :new, website do
171
- subject.must_equal("Duke's at Komedia")
171
+ _(subject).must_equal("Duke's at Komedia")
172
172
  end
173
173
  end
174
174
  end
@@ -176,11 +176,11 @@ describe PicturehouseUk::Cinema do
176
176
  describe '#postal_code' do
177
177
  subject { described_class.new(id).postal_code }
178
178
 
179
- let(:id) { 'Dukes_At_Komedia' }
179
+ let(:id) { 'duke-s-at-komedia' }
180
180
 
181
181
  it 'returns second line of address' do
182
182
  PicturehouseUk::Internal::Website.stub :new, website do
183
- subject.must_equal('BN1 1UN')
183
+ _(subject).must_equal('BN1 1UN')
184
184
  end
185
185
  end
186
186
  end
@@ -188,11 +188,11 @@ describe PicturehouseUk::Cinema do
188
188
  describe '#region' do
189
189
  subject { described_class.new(id).region }
190
190
 
191
- let(:id) { 'Dukes_At_Komedia' }
191
+ let(:id) { 'duke-s-at-komedia' }
192
192
 
193
193
  it 'returns second line of address' do
194
194
  PicturehouseUk::Internal::Website.stub :new, website do
195
- subject.must_equal('East Sussex')
195
+ _(subject).must_equal('East Sussex')
196
196
  end
197
197
  end
198
198
  end
@@ -200,11 +200,11 @@ describe PicturehouseUk::Cinema do
200
200
  describe '#slug' do
201
201
  subject { described_class.new(id).slug }
202
202
 
203
- let(:id) { 'Dukes_At_Komedia' }
203
+ let(:id) { 'duke-s-at-komedia' }
204
204
 
205
205
  it 'returns downcased' do
206
206
  PicturehouseUk::Internal::Website.stub :new, website do
207
- subject.must_equal('dukes-at-komedia')
207
+ _(subject).must_equal('dukes-at-komedia')
208
208
  end
209
209
  end
210
210
  end
@@ -212,11 +212,11 @@ describe PicturehouseUk::Cinema do
212
212
  describe '#street_address' do
213
213
  subject { described_class.new(id).street_address }
214
214
 
215
- let(:id) { 'Dukes_At_Komedia' }
215
+ let(:id) { 'duke-s-at-komedia' }
216
216
 
217
217
  it 'returns first line of address' do
218
218
  PicturehouseUk::Internal::Website.stub :new, website do
219
- subject.must_equal('44–47 Gardner Street')
219
+ _(subject).must_equal('44–47 Gardner Street')
220
220
  end
221
221
  end
222
222
  end
@@ -0,0 +1,92 @@
1
+ require_relative '../../../test_helper'
2
+
3
+ describe PicturehouseUk::Internal::Api do
4
+ let(:described_class) { PicturehouseUk::Internal::Api }
5
+
6
+ before { WebMock.disable_net_connect! }
7
+ after { WebMock.allow_net_connect! }
8
+
9
+ describe '#get_movies' do
10
+ let(:client) { described_class.new }
11
+ let(:cinema_id) { 'duke-s-at-komedia' }
12
+
13
+ it 'makes POST request to correct endpoint' do
14
+ stub_request(:post, 'https://www.picturehouses.com/api/get-movies-ajax')
15
+ .with do |request|
16
+ request.body.include?('start_date=show_all_dates') &&
17
+ request.body.include?("cinema_id=#{cinema_id}")
18
+ end
19
+ .to_return(
20
+ status: 200,
21
+ body: '{"response":"success","movies":[]}',
22
+ headers: { 'Content-Type' => 'application/json' }
23
+ )
24
+
25
+ result = client.get_movies(cinema_id)
26
+
27
+ _(result).must_be_instance_of(Hash)
28
+ _(result['response']).must_equal 'success'
29
+ end
30
+
31
+ it 'accepts custom date parameter' do
32
+ stub_request(:post, 'https://www.picturehouses.com/api/get-movies-ajax')
33
+ .with do |request|
34
+ request.body.include?('start_date=2024-11-01') &&
35
+ request.body.include?("cinema_id=#{cinema_id}")
36
+ end
37
+ .to_return(
38
+ status: 200,
39
+ body: '{"response":"success","movies":[]}',
40
+ headers: { 'Content-Type' => 'application/json' }
41
+ )
42
+
43
+ result = client.get_movies(cinema_id, '2024-11-01')
44
+
45
+ _(result['response']).must_equal 'success'
46
+ end
47
+
48
+ it 'returns empty hash on HTTP error' do
49
+ stub_request(:post, 'https://www.picturehouses.com/api/get-movies-ajax')
50
+ .to_return(status: 500, body: 'Internal Server Error')
51
+
52
+ result = client.get_movies(cinema_id)
53
+
54
+ _(result).must_equal({})
55
+ end
56
+
57
+ it 'returns empty hash on network error' do
58
+ stub_request(:post, 'https://www.picturehouses.com/api/get-movies-ajax')
59
+ .to_raise(StandardError.new('Network error'))
60
+
61
+ result = client.get_movies(cinema_id)
62
+
63
+ _(result).must_equal({})
64
+ end
65
+
66
+ it 'parses JSON response' do
67
+ response_body = {
68
+ 'response' => 'success',
69
+ 'movies' => [
70
+ {
71
+ 'Title' => 'Test Film',
72
+ 'ScheduledFilmId' => '12345',
73
+ 'movie_times' => []
74
+ }
75
+ ]
76
+ }.to_json
77
+
78
+ stub_request(:post, 'https://www.picturehouses.com/api/get-movies-ajax')
79
+ .to_return(
80
+ status: 200,
81
+ body: response_body,
82
+ headers: { 'Content-Type' => 'application/json' }
83
+ )
84
+
85
+ result = client.get_movies(cinema_id)
86
+
87
+ _(result).must_be_instance_of(Hash)
88
+ _(result['movies']).must_be_instance_of(Array)
89
+ _(result['movies'].first['Title']).must_equal 'Test Film'
90
+ end
91
+ end
92
+ end
@@ -12,8 +12,8 @@ describe PicturehouseUk::Internal::Parser::Address do
12
12
  let(:html) { nil }
13
13
 
14
14
  it 'returns hash of nils' do
15
- subject.must_be_instance_of(Hash)
16
- subject.must_equal(street_address: nil,
15
+ _(subject).must_be_instance_of(Hash)
16
+ _(subject).must_equal(street_address: nil,
17
17
  extended_address: nil,
18
18
  locality: nil,
19
19
  region: nil,
@@ -26,8 +26,8 @@ describe PicturehouseUk::Internal::Parser::Address do
26
26
  let(:html) { '' }
27
27
 
28
28
  it 'returns hash of nils' do
29
- subject.must_be_instance_of(Hash)
30
- subject.must_equal(street_address: nil,
29
+ _(subject).must_be_instance_of(Hash)
30
+ _(subject).must_equal(street_address: nil,
31
31
  extended_address: nil,
32
32
  locality: nil,
33
33
  region: nil,
@@ -40,12 +40,12 @@ describe PicturehouseUk::Internal::Parser::Address do
40
40
  let(:html) { 'not an address' }
41
41
 
42
42
  it 'returns hash of nils' do
43
- subject.must_be_instance_of(Hash)
44
- subject.must_equal(street_address: nil,
43
+ _(subject).must_be_instance_of(Hash)
44
+ _(subject).must_equal(street_address: nil,
45
45
  extended_address: nil,
46
- locality: "not an address",
46
+ locality: nil,
47
47
  region: nil,
48
- postal_code: "not an address",
48
+ postal_code: nil,
49
49
  country_name: "United Kingdom")
50
50
  end
51
51
  end
@@ -2,69 +2,123 @@ require_relative '../../../../test_helper'
2
2
 
3
3
  describe PicturehouseUk::Internal::Parser::Screenings do
4
4
  let(:described_class) { PicturehouseUk::Internal::Parser::Screenings }
5
- let(:website) { Minitest::Mock.new }
5
+ let(:api_client) { FakeApi.new }
6
6
 
7
7
  before { WebMock.disable_net_connect! }
8
8
  after { WebMock.allow_net_connect! }
9
9
 
10
- %w(Duke_Of_Yorks Dukes_At_Komedia Phoenix_Picturehouse).each do |cinema|
11
- describe "#{cinema}: #to_a" do
12
- subject { described_class.new(cinema).to_a }
13
-
14
- before { website.expect(:whats_on, html(cinema), [cinema]) }
15
-
16
- it 'returns an non-zero array of hashes' do
17
- PicturehouseUk::Internal::Website.stub :new, website do
18
- subject.must_be_instance_of(Array)
19
- subject.size.must_be :>, 0
20
-
21
- subject.each do |element|
22
- element.must_be_instance_of(Hash)
23
- element.keys.must_equal([:film_name, :dimension, :variant,
24
- :booking_url, :starting_at])
25
- element[:film_name].must_be_kind_of(String)
26
- element[:dimension].must_match(/\A[23]d\z/)
27
- if element[:booking_url]
28
- element[:booking_url].must_match(%r{\Ahttps?\://picturehouses.com})
29
- element[:booking_url].must_match(%r{/cinema/#{cinema}/film/[-\w]+/tickets/\d+})
30
- end
31
- element[:starting_at].must_be_kind_of(Time)
32
- end
33
-
34
- variants = subject.flat_map { |e| e[:variant] }.uniq
35
- %w(arts baby senior).each do |expected| # also kids
36
- variants.must_include(expected)
37
- end
10
+ describe '#to_a' do
11
+ subject { described_class.new('duke-s-at-komedia').to_a }
12
+
13
+ it 'returns an array of hashes' do
14
+ PicturehouseUk::Internal::Api.stub :new, api_client do
15
+ _(subject).must_be_instance_of(Array)
16
+ subject.each do |element|
17
+ _(element).must_be_instance_of(Hash)
38
18
  end
39
19
  end
40
20
  end
41
- end
42
21
 
43
- %w(National_Media_Museum).each do |cinema|
44
- describe "#{cinema}: #to_a" do
45
- subject { described_class.new(cinema).to_a }
22
+ it 'has correct hash keys' do
23
+ PicturehouseUk::Internal::Api.stub :new, api_client do
24
+ subject.each do |element|
25
+ _(element.keys.sort).must_equal([:booking_url, :dimension, :film_name, :starting_at, :variant].sort)
26
+ end
27
+ end
28
+ end
46
29
 
47
- before { website.expect(:whats_on, html(cinema), [cinema]) }
30
+ it 'has valid film names' do
31
+ PicturehouseUk::Internal::Api.stub :new, api_client do
32
+ film_names = subject.map { |s| s[:film_name] }.uniq
33
+ _(film_names).must_include 'The Holdovers'
34
+ _(film_names).must_include 'The Marvels'
35
+ end
36
+ end
48
37
 
49
- it 'returns an non-zero array of hashes with imax variants' do
50
- PicturehouseUk::Internal::Website.stub :new, website do
51
- subject.must_be_instance_of(Array)
52
- subject.size.must_be :>, 0
38
+ it 'correctly identifies dimensions' do
39
+ PicturehouseUk::Internal::Api.stub :new, api_client do
40
+ subject.each do |element|
41
+ _(element[:dimension]).must_match(/\A[23]d\z/)
42
+ end
43
+ end
44
+ end
45
+
46
+ it 'generates booking URLs with correct format' do
47
+ PicturehouseUk::Internal::Api.stub :new, api_client do
48
+ subject.each do |element|
49
+ _(element[:booking_url]).must_match(%r{\Ahttps://web\.picturehouses\.com/order/showtimes/})
50
+ _(element[:booking_url]).must_match(%r{/duke-s-at-komedia-\d+/seats\z})
51
+ end
52
+ end
53
+ end
53
54
 
54
- variants = subject.flat_map { |e| e[:variant] }.uniq
55
- variants.must_include('imax')
55
+ it 'parses starting_at as Time objects' do
56
+ PicturehouseUk::Internal::Api.stub :new, api_client do
57
+ subject.each do |element|
58
+ _(element[:starting_at]).must_be_kind_of(Time)
59
+ _(element[:starting_at]).wont_equal Time.utc(1970, 1, 1, 0, 0)
56
60
  end
57
61
  end
58
62
  end
63
+
64
+ it 'extracts variant arrays' do
65
+ PicturehouseUk::Internal::Api.stub :new, api_client do
66
+ variants = subject.flat_map { |e| e[:variant] }.uniq
67
+ _(variants).must_include('kids')
68
+ _(variants).must_include('senior')
69
+ _(variants).must_include('arts')
70
+ end
71
+ end
72
+
73
+ it 'identifies 3D films from title' do
74
+ PicturehouseUk::Internal::Api.stub :new, api_client do
75
+ three_d_films = subject.select { |s| s[:dimension] == '3d' }
76
+ _(three_d_films).wont_be_empty
77
+ three_d_films.each do |screening|
78
+ _(screening[:film_name]).must_match(/Marvels/i)
79
+ end
80
+ end
81
+ end
82
+
83
+ it 'skips sold out screenings' do
84
+ PicturehouseUk::Internal::Api.stub :new, api_client do
85
+ # Our fixture has 9 total screenings but none with SoldoutStatus == 2
86
+ _(subject.count).must_equal 8
87
+ end
88
+ end
59
89
  end
60
90
 
61
- private
91
+ describe 'with empty response' do
92
+ let(:empty_client) do
93
+ Class.new do
94
+ def get_movies(_cinema_id, _date = 'show_all_dates')
95
+ { 'response' => 'error', 'movies' => [] }
96
+ end
97
+ end.new
98
+ end
62
99
 
63
- def read_file(filepath)
64
- File.read(File.expand_path(filepath, __FILE__))
100
+ it 'returns empty array for error response' do
101
+ PicturehouseUk::Internal::Api.stub :new, empty_client do
102
+ result = described_class.new('nonexistent').to_a
103
+ _(result).must_equal []
104
+ end
105
+ end
65
106
  end
66
107
 
67
- def html(cinema)
68
- read_file("../../../../../fixtures/#{cinema}/whats_on.html")
108
+ describe 'with missing movies key' do
109
+ let(:missing_movies_client) do
110
+ Class.new do
111
+ def get_movies(_cinema_id, _date = 'show_all_dates')
112
+ { 'response' => 'success' }
113
+ end
114
+ end.new
115
+ end
116
+
117
+ it 'returns empty array when movies key missing' do
118
+ PicturehouseUk::Internal::Api.stub :new, missing_movies_client do
119
+ result = described_class.new('test').to_a
120
+ _(result).must_equal []
121
+ end
122
+ end
69
123
  end
70
124
  end