Skip to content

Commit 3e01f71

Browse files
Rename validation methods to use ! convention for exception-throwing
1 parent 5deee18 commit 3e01f71

File tree

6 files changed

+78
-74
lines changed

6 files changed

+78
-74
lines changed

lib/react_on_rails/utils.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def self.react_on_rails_pro?
239239
@react_on_rails_pro = begin
240240
return false unless gem_available?("react_on_rails_pro")
241241

242-
ReactOnRailsPro::Utils.licence_valid?
242+
ReactOnRailsPro::Utils.validate_licence!
243243
end
244244
end
245245

react_on_rails_pro/lib/react_on_rails_pro/engine.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Engine < Rails::Engine
1515
config.after_initialize do
1616
Rails.logger.info "[React on Rails Pro] Validating license..."
1717

18-
if ReactOnRailsPro::LicenseValidator.valid?
18+
if ReactOnRailsPro::LicenseValidator.validate!
1919
Rails.logger.info "[React on Rails Pro] License validation successful"
2020
else
2121
# License validation will raise an error, so this line won't be reached

react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module LicensePublicKey
66
# The private key corresponding to this public key is held by ShakaCode
77
# and is never committed to the repository
88
# Last updated: 2025-10-09 15:57:09 UTC
9-
# Source: http://localhost:8788/api/public-key
9+
# Source: http://shakacode.com/api/public-key
1010
KEY = OpenSSL::PKey::RSA.new(<<~PEM.strip.strip_heredoc)
1111
-----BEGIN PUBLIC KEY-----
1212
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlJFK3aWuycVp9X05qhGo

react_on_rails_pro/lib/react_on_rails_pro/license_validator.rb

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@
66
module ReactOnRailsPro
77
class LicenseValidator
88
class << self
9-
def valid?
10-
return @valid if defined?(@valid)
11-
12-
@valid = validate_license
9+
# Validates the license and raises an exception if invalid.
10+
# Caches the result after first validation.
11+
#
12+
# @return [Boolean] true if license is valid
13+
# @raise [ReactOnRailsPro::Error] if license is invalid
14+
def validate!
15+
return @validate if defined?(@validate)
16+
17+
@validate = validate_license
1318
end
1419

1520
def reset!
16-
remove_instance_variable(:@valid) if defined?(@valid)
21+
remove_instance_variable(:@validate) if defined?(@validate)
1722
remove_instance_variable(:@license_data) if defined?(@license_data)
1823
remove_instance_variable(:@validation_error) if defined?(@validation_error)
1924
end
@@ -22,55 +27,51 @@ def license_data
2227
@license_data ||= load_and_decode_license
2328
end
2429

25-
def validation_error
26-
@validation_error
27-
end
30+
attr_reader :validation_error
2831

2932
private
3033

3134
def validate_license
32-
begin
33-
license = load_and_decode_license
34-
# If no license found, load_license_string already handled the error
35-
return false unless license
36-
37-
# Check that exp field exists
38-
unless license["exp"]
39-
@validation_error = "License is missing required expiration field. " \
40-
"Your license may be from an older version. " \
41-
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
42-
handle_invalid_license(@validation_error)
43-
return false
44-
end
45-
46-
# Check expiry
47-
if Time.now.to_i > license["exp"]
48-
@validation_error = "License has expired. " \
49-
"Get a FREE evaluation license (3 months) at https://shakacode.com/react-on-rails-pro " \
50-
"or upgrade to a paid license for production use."
51-
handle_invalid_license(@validation_error)
52-
return false
53-
end
54-
55-
# Log license type if present (for analytics)
56-
log_license_info(license)
57-
58-
true
59-
rescue ReactOnRailsPro::Error
60-
# Re-raise errors from handle_invalid_license
61-
raise
62-
rescue JWT::DecodeError => e
63-
@validation_error = "Invalid license signature: #{e.message}. " \
64-
"Your license file may be corrupted. " \
65-
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
35+
license = load_and_decode_license
36+
# If no license found, load_license_string already handled the error
37+
return false unless license
38+
39+
# Check that exp field exists
40+
unless license["exp"]
41+
@validation_error = "License is missing required expiration field. " \
42+
"Your license may be from an older version. " \
43+
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
6644
handle_invalid_license(@validation_error)
67-
false
68-
rescue StandardError => e
69-
@validation_error = "License validation error: #{e.message}. " \
70-
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
45+
return false
46+
end
47+
48+
# Check expiry
49+
if Time.now.to_i > license["exp"]
50+
@validation_error = "License has expired. " \
51+
"Get a FREE evaluation license (3 months) at https://shakacode.com/react-on-rails-pro " \
52+
"or upgrade to a paid license for production use."
7153
handle_invalid_license(@validation_error)
72-
false
54+
return false
7355
end
56+
57+
# Log license type if present (for analytics)
58+
log_license_info(license)
59+
60+
true
61+
rescue ReactOnRailsPro::Error
62+
# Re-raise errors from handle_invalid_license
63+
raise
64+
rescue JWT::DecodeError => e
65+
@validation_error = "Invalid license signature: #{e.message}. " \
66+
"Your license file may be corrupted. " \
67+
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
68+
handle_invalid_license(@validation_error)
69+
false
70+
rescue StandardError => e
71+
@validation_error = "License validation error: #{e.message}. " \
72+
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
73+
handle_invalid_license(@validation_error)
74+
false
7475
end
7576

7677
def load_and_decode_license
@@ -92,16 +93,16 @@ def load_and_decode_license
9293

9394
def load_license_string
9495
# First try environment variable
95-
license = ENV["REACT_ON_RAILS_PRO_LICENSE"]
96+
license = ENV.fetch("REACT_ON_RAILS_PRO_LICENSE", nil)
9697
return license if license.present?
9798

9899
# Then try config file
99100
config_path = Rails.root.join("config", "react_on_rails_pro_license.key")
100101
return File.read(config_path).strip if config_path.exist?
101102

102103
@validation_error = "No license found. Please set REACT_ON_RAILS_PRO_LICENSE environment variable " \
103-
"or create config/react_on_rails_pro_license.key file. " \
104-
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
104+
"or create config/react_on_rails_pro_license.key file. " \
105+
"Get a FREE evaluation license at https://shakacode.com/react-on-rails-pro"
105106
handle_invalid_license(@validation_error)
106107
nil
107108
end

react_on_rails_pro/lib/react_on_rails_pro/utils.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ def self.rorp_puts(message)
1616
puts "[ReactOnRailsPro] #{message}"
1717
end
1818

19-
def self.licence_valid?
20-
LicenseValidator.valid?
19+
# Validates the license and raises an exception if invalid.
20+
#
21+
# @return [Boolean] true if license is valid
22+
# @raise [ReactOnRailsPro::Error] if license is invalid
23+
def self.validate_licence!
24+
LicenseValidator.validate!
2125
end
2226

2327
def self.copy_assets

react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,31 +40,30 @@
4040
ENV.delete("REACT_ON_RAILS_PRO_LICENSE")
4141

4242
# Stub Rails.logger to avoid nil errors in unit tests
43-
allow(Rails).to receive(:logger).and_return(mock_logger)
4443
# Stub Rails.root for config file path tests
45-
allow(Rails).to receive(:root).and_return(mock_root)
44+
allow(Rails).to receive_messages(logger: mock_logger, root: mock_root)
4645
end
4746

4847
after do
4948
described_class.reset!
5049
ENV.delete("REACT_ON_RAILS_PRO_LICENSE")
5150
end
5251

53-
describe ".valid?" do
52+
describe ".validate!" do
5453
context "with valid license in ENV" do
5554
before do
5655
valid_token = JWT.encode(valid_payload, test_private_key, "RS256")
5756
ENV["REACT_ON_RAILS_PRO_LICENSE"] = valid_token
5857
end
5958

6059
it "returns true" do
61-
expect(described_class.valid?).to be true
60+
expect(described_class.validate!).to be true
6261
end
6362

6463
it "caches the result" do
6564
expect(described_class).to receive(:validate_license).once.and_call_original
66-
described_class.valid?
67-
described_class.valid? # Second call should use cache
65+
described_class.validate!
66+
described_class.validate! # Second call should use cache
6867
end
6968
end
7069

@@ -75,11 +74,11 @@
7574
end
7675

7776
it "raises error" do
78-
expect { described_class.valid? }.to raise_error(ReactOnRailsPro::Error, /License has expired/)
77+
expect { described_class.validate! }.to raise_error(ReactOnRailsPro::Error, /License has expired/)
7978
end
8079

8180
it "includes FREE license information in error message" do
82-
expect { described_class.valid? }.to raise_error(ReactOnRailsPro::Error, /FREE evaluation license/)
81+
expect { described_class.validate! }.to raise_error(ReactOnRailsPro::Error, /FREE evaluation license/)
8382
end
8483
end
8584

@@ -98,12 +97,12 @@
9897
end
9998

10099
it "raises error" do
101-
expect { described_class.valid? }
100+
expect { described_class.validate! }
102101
.to raise_error(ReactOnRailsPro::Error, /License is missing required expiration field/)
103102
end
104103

105104
it "includes FREE license information in error message" do
106-
expect { described_class.valid? }.to raise_error(ReactOnRailsPro::Error, /FREE evaluation license/)
105+
expect { described_class.validate! }.to raise_error(ReactOnRailsPro::Error, /FREE evaluation license/)
107106
end
108107
end
109108

@@ -115,11 +114,11 @@
115114
end
116115

117116
it "raises error" do
118-
expect { described_class.valid? }.to raise_error(ReactOnRailsPro::Error, /Invalid license signature/)
117+
expect { described_class.validate! }.to raise_error(ReactOnRailsPro::Error, /Invalid license signature/)
119118
end
120119

121120
it "includes FREE license information in error message" do
122-
expect { described_class.valid? }.to raise_error(ReactOnRailsPro::Error, /FREE evaluation license/)
121+
expect { described_class.validate! }.to raise_error(ReactOnRailsPro::Error, /FREE evaluation license/)
123122
end
124123
end
125124

@@ -130,11 +129,11 @@
130129
end
131130

132131
it "raises error" do
133-
expect { described_class.valid? }.to raise_error(ReactOnRailsPro::Error, /No license found/)
132+
expect { described_class.validate! }.to raise_error(ReactOnRailsPro::Error, /No license found/)
134133
end
135134

136135
it "includes FREE license information in error message" do
137-
expect { described_class.valid? }
136+
expect { described_class.validate! }
138137
.to raise_error(ReactOnRailsPro::Error, /FREE evaluation license/)
139138
end
140139
end
@@ -152,7 +151,7 @@
152151
end
153152

154153
it "returns true" do
155-
expect(described_class.valid?).to be true
154+
expect(described_class.validate!).to be true
156155
end
157156
end
158157
end
@@ -180,7 +179,7 @@
180179

181180
it "returns the error message" do
182181
begin
183-
described_class.valid?
182+
described_class.validate!
184183
rescue ReactOnRailsPro::Error
185184
# Expected error
186185
end
@@ -193,13 +192,13 @@
193192
before do
194193
valid_token = JWT.encode(valid_payload, test_private_key, "RS256")
195194
ENV["REACT_ON_RAILS_PRO_LICENSE"] = valid_token
196-
described_class.valid? # Cache the result
195+
described_class.validate! # Cache the result
197196
end
198197

199198
it "clears the cached validation result" do
200-
expect(described_class.instance_variable_get(:@valid)).to be true
199+
expect(described_class.instance_variable_get(:@validate)).to be true
201200
described_class.reset!
202-
expect(described_class.instance_variable_defined?(:@valid)).to be false
201+
expect(described_class.instance_variable_defined?(:@validate)).to be false
203202
end
204203
end
205204
end

0 commit comments

Comments
 (0)