cineworld_uk 4.0.0 → 4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5284f7c7c8b846edbdd724cb3c105b033da4f313eed083d6b691ae6b8714d3b8
4
- data.tar.gz: 1568acd04ed0346ba388509903a17487726c088ff2d280329cfb0fe8f6023eed
3
+ metadata.gz: edfbb0e8f7d6238e878f4018a643befca62b662fffc47cad72367c2e404e9ee7
4
+ data.tar.gz: a0d59a9aa4d3227794fda2f78c00de9e59c62321b3cba3a50dbbd8611856cc82
5
5
  SHA512:
6
- metadata.gz: faff1f58b5e101ce8185a96f791a27088ed31f7c78d3eebf3f9b332b6931848604726b7e5b3d16f3bb51c1878c4693cb993863cf48dcbbe743436208e5c3186b
7
- data.tar.gz: 2ab7741bafc40d66d104390340fa2e28a1a5b0a6d166f85b3526f8eb576d664b6860c5f03032fc3d71a2c21bb3ece25804d5258aeba3a7f74601027610c161d8
6
+ metadata.gz: aefe630b3ad344c2fbced398fc49c5fb9686387331f2cdea072f6dc96ef0893db42af90a6d277117cc7cd1b6ab4505b2fff3e64e859f79896503a71462934a89
7
+ data.tar.gz: cd3ad38fb9b9404504e5379ae03943424d56370b6ce2b0bcda069c9f64fa33a2802ce54dcb567740689408e882bda8e86cba3127193fb510f46fc73b2610c030
@@ -15,3 +15,29 @@ jobs:
15
15
  ruby-version: ${{ matrix.ruby-version }}
16
16
  bundler-cache: true
17
17
  - run: bundle exec rake test
18
+
19
+ package:
20
+ strategy:
21
+ matrix:
22
+ include:
23
+ - runner: ubuntu-latest
24
+ platform: x86_64-linux-gnu
25
+ - runner: ubuntu-24.04-arm
26
+ platform: aarch64-linux-gnu
27
+ - runner: macos-15
28
+ platform: arm64-darwin
29
+ - runner: macos-15-intel
30
+ platform: x86_64-darwin
31
+ runs-on: ${{ matrix.runner }}
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ - uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: '3.4'
37
+ bundler-cache: true
38
+ - run: bundle exec rake 'package:native[${{ matrix.platform }}]'
39
+ - run: CINEWORLD_PACKAGE="$(echo pkg/*.gem)" bundle exec ruby test/package_test.rb
40
+ - uses: actions/upload-artifact@v4
41
+ with:
42
+ name: gem-${{ matrix.platform }}
43
+ path: pkg/*.gem
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## 4.1.0 - 2026-10-15
6
+
7
+ ### Added
8
+ - Explicit guest token acquisition and renewal with `CineworldUk.acquire_token!`, using the standalone `curl-impersonate` CLI without Python or a browser.
9
+ - Platform-specific gems bundle curl-impersonate 2.2.3 for x86-64/ARM64 glibc Linux and macOS, with pinned archive checksums, upstream notices, and native package CI checks. No separate executable installation is needed on these platforms.
10
+ - Optional executable path for token acquisition. Existing caller-supplied tokens continue to work without the CLI.
11
+ - Expiry checks and authentication errors for unavailable commands, blocked pages, and missing or invalid page tokens; failed acquisition preserves the previous token.
12
+
5
13
  ## 4.0.0 - 2026-10-15
6
14
 
7
15
  ### Changed
data/README.md CHANGED
@@ -27,22 +27,70 @@ Performance titles are sanitized as much as possible, removing 'screening type'
27
27
 
28
28
  ### Authentication
29
29
 
30
- Configure a current guest JWT before retrieving data (without the `Bearer ` prefix):
30
+ Acquire a guest JWT explicitly before retrieving data:
31
31
 
32
32
  ```ruby
33
33
  require 'cineworld_uk'
34
34
 
35
+ CineworldUk.acquire_token!
36
+ CineworldUk::Cinema.all
37
+ ```
38
+
39
+ This shells out to **`curl-impersonate`**, not ordinary system `curl`, using its
40
+ Chrome 150 TLS/HTTP profile. No Python, Chrome, JavaScript execution or browser
41
+ cookies are needed. Platform-specific gem packages include the pinned
42
+ `curl-impersonate` 2.2.3 executable and its upstream licence notices. RubyGems
43
+ and Bundler automatically select the matching package for:
44
+
45
+ - glibc Linux: x86-64 and ARM64 (`x86_64-linux-gnu`, `aarch64-linux-gnu`)
46
+ - macOS: Intel and Apple Silicon (`x86_64-darwin`, `arm64-darwin`)
47
+
48
+ The executable runs directly from the installed gem. There are no separate
49
+ installation commands, PATH changes, or runtime downloads on these platforms.
50
+
51
+ When installing from Git, forcing the source (`ruby`) gem, or using another
52
+ platform (including Alpine/musl and Windows), install a compatible
53
+ [curl-impersonate release](https://github.com/lexiforest/curl-impersonate/releases/tag/v2.2.3)
54
+ with `--impersonate chrome150` support yourself. For an x86-64 Linux checkout:
55
+
56
+ ```sh
57
+ mkdir -p "$HOME/.local/bin"
58
+ curl -fL https://github.com/lexiforest/curl-impersonate/releases/download/v2.2.3/curl-impersonate-v2.2.3.x86_64-linux-gnu.tar.gz \
59
+ | tar -xz -C "$HOME/.local/bin" curl-impersonate
60
+ export PATH="$HOME/.local/bin:$PATH"
61
+ ```
62
+
63
+ Other platforms have separate assets on the release page. You can also specify
64
+ the executable path:
65
+
66
+ ```ruby
67
+ CineworldUk.acquire_token!(curl: '/opt/curl-impersonate/curl-impersonate')
68
+ ```
69
+
70
+ The method returns the token and sets `CineworldUk.token` in memory. It reads
71
+ `__NEXT_DATA__.props.pageProps.environment.gasToken` from the ticketing site's
72
+ root page, even when the page displays a 404. It checks the declared expiry,
73
+ but decoding the JWT does not verify its signature. A blocked page, expired or
74
+ missing token, missing executable, or failed command raises
75
+ `CineworldUk::AuthenticationError` and leaves any previous token unchanged.
76
+ Requests time out after 30 seconds. Certificate verification remains enabled;
77
+ redirects are not followed, and subprocess arguments are passed without a shell.
78
+ Cloudflare may still block requests on other networks or after website changes.
79
+
80
+ Alternatively, supply your own current guest JWT without the `Bearer ` prefix;
81
+ this requires no external executable:
82
+
83
+ ```ruby
35
84
  CineworldUk.token = ENV.fetch('CINEWORLD_TOKEN')
36
85
  ```
37
86
 
38
87
  The gem sends `Authorization: Bearer ...` and `Connect-Region-Code: GB` to
39
- `digital-api.cineworld.co.uk`. It does not acquire or refresh tokens, copy browser
40
- cookies, or bypass Cloudflare. The ticketing website supplies its guest token in
41
- `__NEXT_DATA__.props.pageProps.environment.gasToken`; access to that page may
42
- require an interactive browser.
88
+ `digital-api.cineworld.co.uk`. Normal API calls never acquire or renew a token
89
+ automatically.
43
90
 
44
91
  Missing tokens and HTTP 401 responses raise `CineworldUk::AuthenticationError`.
45
- Set `CineworldUk.token` again with a fresh token before retrying. Other HTTP
92
+ Call `CineworldUk.acquire_token!` again, or set `CineworldUk.token` with a fresh
93
+ token, before retrying. Tokens are never persisted by the gem. Other HTTP
46
94
  failures raise an error rather than returning an empty schedule. Redirects are
47
95
  not followed, so credentials are not forwarded to another host.
48
96
 
@@ -145,6 +193,27 @@ performance.cinema_id
145
193
  #=> 14
146
194
  ```
147
195
 
196
+ ## Building release packages
197
+
198
+ ```sh
199
+ bundle exec rake build # Portable source gem; external curl-impersonate required
200
+ bundle exec rake package:all # Four platform gems with bundled executables
201
+ ```
202
+
203
+ To build and check just one platform on a matching host:
204
+
205
+ ```sh
206
+ bundle exec rake 'package:native[x86_64-linux-gnu]'
207
+ CINEWORLD_PACKAGE=pkg/cineworld_uk-4.1.0-x86_64-linux-gnu.gem bundle exec ruby test/package_test.rb
208
+ ```
209
+
210
+ Native packaging downloads pinned upstream archives at **build time**, verifies
211
+ their SHA-256 digests, and includes the executable, licence files and source
212
+ provenance. Archives and built gems stay in ignored `pkg/`, not Git. CI builds
213
+ and installation-tests each platform on its corresponding runner and saves the
214
+ gems as workflow artifacts; it does not publish them. Publish the source and
215
+ platform gems together for automatic platform selection to work for users.
216
+
148
217
  ## Contributing
149
218
 
150
219
  1. Fork it
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
  require "bundler/gem_tasks"
3
3
 
4
4
  require 'rake/testtask'
5
+ load File.expand_path('tasks/package.rake', __dir__)
5
6
 
6
7
  Rake::TestTask.new do |t|
7
8
  t.libs << 'lib/cineworld_uk'
data/cineworld_uk.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'simplecov', '< 1'
25
25
  spec.add_development_dependency 'webmock'
26
26
 
27
+ spec.add_runtime_dependency 'base64', '~> 0.3'
27
28
  spec.add_runtime_dependency 'cinebase', '~> 5.0'
28
29
  spec.add_runtime_dependency 'nokogiri', '>= 1.11'
29
30
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+ require "json"
5
+ require "nokogiri"
6
+ require "open3"
7
+
8
+ module CineworldUk
9
+ module Internal
10
+ # Retrieves the public guest token without running a browser.
11
+ class GuestToken
12
+ def initialize(curl:)
13
+ @curl = curl || default_curl
14
+ end
15
+
16
+ def fetch
17
+ token = extract_token(request_page)
18
+ validate_expiry!(token)
19
+ token
20
+ rescue JSON::ParserError, ArgumentError, IndexError, TypeError, NoMethodError
21
+ raise AuthenticationError, "Guest token page data is missing or invalid", cause: nil
22
+ end
23
+
24
+ private
25
+
26
+ def default_curl
27
+ bundled = File.expand_path("../../../vendor/curl-impersonate/bin/curl-impersonate", __dir__)
28
+ File.executable?(bundled) ? bundled : "curl-impersonate"
29
+ end
30
+
31
+ def curl_command
32
+ [@curl, "--disable", "--impersonate", "chrome150",
33
+ "--compressed", "--silent", "--show-error",
34
+ "--connect-timeout", "10", "--max-time", "30",
35
+ "--write-out", "\n%{http_code}", "https://web.cineworld.co.uk/"]
36
+ end
37
+
38
+ def request_page
39
+ output, _stderr, result = Open3.capture3(*curl_command)
40
+ unless result.success?
41
+ raise AuthenticationError,
42
+ "Guest token request failed (curl exit #{result.exitstatus})"
43
+ end
44
+
45
+ html, _, status = output.rpartition("\n")
46
+ unless %w[200 404].include?(status)
47
+ raise AuthenticationError, "Guest token page returned HTTP #{status}"
48
+ end
49
+ html
50
+ rescue Errno::ENOENT
51
+ raise AuthenticationError,
52
+ "Install curl-impersonate or pass its executable path with curl:"
53
+ end
54
+
55
+ def extract_token(html)
56
+ script = Nokogiri::HTML(html).at_css("script#__NEXT_DATA__")
57
+ data = JSON.parse(script ? script.content : "")
58
+ token = data.dig("props", "pageProps", "environment", "gasToken")
59
+ unless token.is_a?(String) && !token.empty?
60
+ raise AuthenticationError, "Guest token is missing from the page"
61
+ end
62
+ token
63
+ end
64
+
65
+ def validate_expiry!(token)
66
+ claims = JSON.parse(Base64.urlsafe_decode64(token.split(".").fetch(1)))
67
+ if Integer(claims.fetch("exp")) <= Time.now.to_i
68
+ raise AuthenticationError, "Guest token supplied by the page has expired"
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,6 +1,6 @@
1
1
  # Ruby interface for http://www.cineworld.co.uk
2
- # @version 4.0.0
2
+ # @version 4.1.0
3
3
  module CineworldUk
4
4
  # Gem version
5
- VERSION = "4.0.0".freeze
5
+ VERSION = "4.1.0".freeze
6
6
  end
data/lib/cineworld_uk.rb CHANGED
@@ -5,6 +5,7 @@ require 'cinebase'
5
5
  require_relative './cineworld_uk/version'
6
6
 
7
7
  require_relative './cineworld_uk/internal/api_response'
8
+ require_relative './cineworld_uk/internal/guest_token'
8
9
  require_relative './cineworld_uk/internal/parser/api/cinema_address'
9
10
  require_relative './cineworld_uk/internal/parser/api/film'
10
11
  require_relative './cineworld_uk/internal/parser/api/performance'
@@ -21,5 +22,10 @@ module CineworldUk
21
22
  # A raw guest JWT, without the "Bearer " prefix. Never persisted by the gem.
22
23
  class << self
23
24
  attr_accessor :token
25
+
26
+ # Explicit acquisition/renewal; ordinary API calls never launch a subprocess.
27
+ def acquire_token!(curl: nil)
28
+ self.token = Internal::GuestToken.new(curl: curl).fetch
29
+ end
24
30
  end
25
31
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "fileutils"
5
+ require "rubygems/package"
6
+ require "tmpdir"
7
+ require "zlib"
8
+
9
+ namespace :package do
10
+ # SHA-256 digests from the upstream v2.2.3 release assets.
11
+ releases = {
12
+ "x86_64-linux-gnu" => ["x86_64-linux-gnu", "ca7c8aae49e33260d3a2400db16c7737aaf04692d606a843502056b42990f989"],
13
+ "aarch64-linux-gnu" => ["aarch64-linux-gnu", "5e71795b971f32be8f3d7785895f4dceb232f04414f5a067db266432a5b08657"],
14
+ "arm64-darwin" => ["arm64-macos", "2569f4139460fcb301484d37938de91b1c220efd15487ee22a9db554262062fe"],
15
+ "x86_64-darwin" => ["x86_64-macos", "4686806d59abea93866a917c3025a049ef3d7a3240de742ad66bd1a4d9890dc7"]
16
+ }
17
+
18
+ desc "Build a gem with bundled curl-impersonate 2.2.3 for the given platform"
19
+ task :native, [:platform] do |_task, args|
20
+ platform = args.fetch(:platform)
21
+ target, digest = releases.fetch(platform)
22
+ root = File.expand_path("..", __dir__)
23
+ asset = "curl-impersonate-v2.2.3.#{target}.tar.gz"
24
+ url = "https://github.com/lexiforest/curl-impersonate/releases/download/v2.2.3/#{asset}"
25
+ archive = File.join(root, "pkg", "downloads", asset)
26
+ FileUtils.mkdir_p(File.dirname(archive))
27
+ unless File.exist?(archive)
28
+ sh "curl", "--fail", "--location", "--retry", "3", "--output", archive, url
29
+ end
30
+ abort "SHA-256 mismatch for #{archive}; delete it and retry" unless Digest::SHA256.file(archive).hexdigest == digest
31
+
32
+ spec = Gem::Specification.load(File.join(root, "cineworld_uk.gemspec")).dup
33
+ Dir.mktmpdir("cineworld-package") do |stage|
34
+ spec.files.each do |file|
35
+ destination = File.join(stage, file)
36
+ FileUtils.mkdir_p(File.dirname(destination))
37
+ FileUtils.cp(File.join(root, file), destination)
38
+ end
39
+
40
+ vendor = File.join(stage, "vendor", "curl-impersonate")
41
+ Zlib::GzipReader.open(archive) do |gzip|
42
+ Gem::Package::TarReader.new(gzip) do |tar|
43
+ tar.each do |entry|
44
+ next unless entry.file?
45
+
46
+ name = entry.full_name
47
+ relative = if name == "curl-impersonate"
48
+ "bin/curl-impersonate"
49
+ elsif name.start_with?("LICENSE") && File.basename(name) == name
50
+ "licenses/#{name}"
51
+ end
52
+ next unless relative
53
+
54
+ destination = File.join(vendor, relative)
55
+ FileUtils.mkdir_p(File.dirname(destination))
56
+ File.binwrite(destination, entry.read)
57
+ end
58
+ end
59
+ end
60
+ File.chmod(0o755, File.join(vendor, "bin", "curl-impersonate"))
61
+ File.write(File.join(vendor, "SOURCE"), <<~SOURCE)
62
+ curl-impersonate 2.2.3
63
+ Binary: #{url}
64
+ SHA-256: #{digest}
65
+ Source and build instructions: https://github.com/lexiforest/curl-impersonate/tree/v2.2.3
66
+ Redistribution notices: licenses/
67
+ SOURCE
68
+
69
+ Dir.chdir(stage) do
70
+ spec.platform = Gem::Platform.new(platform)
71
+ spec.files += Dir.glob("vendor/**/*").select { |file| File.file?(file) }
72
+ Gem::Package.build(spec, false, false, File.join(root, "pkg", spec.file_name))
73
+ end
74
+ end
75
+ end
76
+
77
+ desc "Build all supported platform gems with bundled curl-impersonate"
78
+ task :all do
79
+ releases.each_key do |platform|
80
+ Rake::Task["package:native"].reenable
81
+ Rake::Task["package:native"].invoke(platform)
82
+ end
83
+ end
84
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../test_helper"
4
+ require "tmpdir"
4
5
 
5
6
  # This block groups independent Minitest cases, not application logic.
6
7
  describe "Vista retrieval" do # rubocop:disable Metrics/BlockLength
@@ -129,3 +130,78 @@ describe "Vista retrieval" do # rubocop:disable Metrics/BlockLength
129
130
  end
130
131
  end
131
132
  end
133
+
134
+ describe "Guest token acquisition" do
135
+ before do
136
+ @directory = Dir.mktmpdir("cineworld token ")
137
+ @curl = File.join(@directory, "curl-impersonate")
138
+ CineworldUk.token = "existing-token"
139
+ end
140
+
141
+ after do
142
+ FileUtils.remove_entry(@directory)
143
+ CineworldUk.token = nil
144
+ end
145
+
146
+ def serve_token_page(html, status: 200, exit_code: 0)
147
+ output = "#{html}\n#{status}"
148
+ File.write(@curl, "#!#{RbConfig.ruby}\nSTDOUT.write(#{output.dump})\nexit #{exit_code}\n")
149
+ File.chmod(0o700, @curl)
150
+ end
151
+
152
+ def token_page(expires)
153
+ payload = Base64.urlsafe_encode64(JSON.generate("exp" => expires), padding: false)
154
+ token = "header.#{payload}.signature"
155
+ data = { "props" => { "pageProps" => { "environment" => { "gasToken" => token } } } }
156
+ ["<script type='application/json' id='__NEXT_DATA__'>#{JSON.generate(data)}</script>", token]
157
+ end
158
+
159
+ it "sets and returns the guest JWT from either a 200 or 404 page" do
160
+ html, token = token_page(Time.now.to_i + 3600)
161
+ [200, 404].each do |status|
162
+ serve_token_page(html, status: status)
163
+ _(CineworldUk.acquire_token!(curl: @curl)).must_equal token
164
+ _(CineworldUk.token).must_equal token
165
+ end
166
+ end
167
+
168
+ it "rejects expired tokens including the expiry boundary without replacing the current token" do
169
+ now = Time.at(1_800_000_000)
170
+ Time.stub(:now, now) do
171
+ [-1, 0, 1].each do |offset|
172
+ html, token = token_page(now.to_i + offset)
173
+ serve_token_page(html)
174
+ if offset.positive?
175
+ _(CineworldUk.acquire_token!(curl: @curl)).must_equal token
176
+ else
177
+ assert_raises(CineworldUk::AuthenticationError) { CineworldUk.acquire_token!(curl: @curl) }
178
+ _(CineworldUk.token).must_equal "existing-token"
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ it "reports blocked, redirected, missing and malformed page data without exposing the response" do
185
+ html, token = token_page(Time.now.to_i + 3600)
186
+ invalid_payload = Base64.urlsafe_encode64("broken-secret", padding: false)
187
+ [[html, 403], [html, 302], ["Cloudflare block", 200],
188
+ ["<script id='__NEXT_DATA__'>{</script>", 200],
189
+ ["<script id='__NEXT_DATA__'>{}</script>", 200],
190
+ [html.sub(token, "broken-secret"), 200],
191
+ [html.sub(token, "header.#{invalid_payload}.signature"), 200]].each do |body, status|
192
+ serve_token_page(body, status: status)
193
+ error = assert_raises(CineworldUk::AuthenticationError) { CineworldUk.acquire_token!(curl: @curl) }
194
+ refute_includes error.full_message, token
195
+ refute_includes error.full_message, "broken-secret"
196
+ _(CineworldUk.token).must_equal "existing-token"
197
+ end
198
+ end
199
+
200
+ it "reports a missing executable or curl failure as an authentication error" do
201
+ error = assert_raises(CineworldUk::AuthenticationError) { CineworldUk.acquire_token!(curl: @curl) }
202
+ assert_includes error.message, "Install curl-impersonate"
203
+ serve_token_page("", status: 0, exit_code: 28)
204
+ error = assert_raises(CineworldUk::AuthenticationError) { CineworldUk.acquire_token!(curl: @curl) }
205
+ assert_includes error.message, "curl exit 28"
206
+ end
207
+ end
@@ -0,0 +1,49 @@
1
+ # Run separately after building: CINEWORLD_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
+ describe "Platform package" do
11
+ before do
12
+ @directory = Dir.mktmpdir("cineworld-package-test")
13
+ @spec = Gem::Installer.at(
14
+ ENV.fetch("CINEWORLD_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
+ after do
21
+ FileUtils.remove_entry(@directory)
22
+ end
23
+
24
+ it "installs a runnable executable with upstream notices and provenance" do
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
+ it "acquires a token using the gem-local executable without any curl on PATH" do
34
+ payload = Base64.urlsafe_encode64(JSON.generate("exp" => Time.now.to_i + 3600), padding: false)
35
+ token = "header.#{payload}.signature"
36
+ data = { "props" => { "pageProps" => { "environment" => { "gasToken" => token } } } }
37
+ page = "<script id='__NEXT_DATA__'>#{JSON.generate(data)}</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')}", "-rcineworld_uk",
44
+ "-e", "print CineworldUk.acquire_token!"
45
+ )
46
+ assert status.success?, error
47
+ _(output).must_equal token
48
+ end
49
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cineworld_uk
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Croll
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: base64
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.3'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.3'
96
110
  - !ruby/object:Gem::Dependency
97
111
  name: cinebase
98
112
  requirement: !ruby/object:Gem::Requirement
@@ -142,12 +156,14 @@ files:
142
156
  - lib/cineworld_uk.rb
143
157
  - lib/cineworld_uk/cinema.rb
144
158
  - lib/cineworld_uk/internal/api_response.rb
159
+ - lib/cineworld_uk/internal/guest_token.rb
145
160
  - lib/cineworld_uk/internal/parser/api/cinema_address.rb
146
161
  - lib/cineworld_uk/internal/parser/api/film.rb
147
162
  - lib/cineworld_uk/internal/parser/api/performance.rb
148
163
  - lib/cineworld_uk/internal/title_sanitizer.rb
149
164
  - lib/cineworld_uk/performance.rb
150
165
  - lib/cineworld_uk/version.rb
166
+ - tasks/package.rake
151
167
  - test/fixtures/api/cinema-list.json
152
168
  - test/fixtures/api/dates-14.json
153
169
  - test/fixtures/api/performances-tomorrow-14.json
@@ -161,6 +177,7 @@ files:
161
177
  - test/lib/cineworld_uk/performance_test.rb
162
178
  - test/lib/cineworld_uk/version_test.rb
163
179
  - test/live/integration_test.rb
180
+ - test/package_test.rb
164
181
  - test/support/fixture_reader.rb
165
182
  - test/test_helper.rb
166
183
  homepage: https://github.com/andycroll/cineworld_uk
@@ -199,5 +216,6 @@ test_files:
199
216
  - test/lib/cineworld_uk/performance_test.rb
200
217
  - test/lib/cineworld_uk/version_test.rb
201
218
  - test/live/integration_test.rb
219
+ - test/package_test.rb
202
220
  - test/support/fixture_reader.rb
203
221
  - test/test_helper.rb