Fix/add some tests. Configure email sending address

This commit is contained in:
Dan Milne
2025-10-26 20:13:39 +11:00
parent d98f777e7d
commit 227e29ce0a
7 changed files with 644 additions and 30 deletions

View File

@@ -1,7 +1,193 @@
require "test_helper"
class OidcAuthorizationCodeTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
def setup
@auth_code = oidc_authorization_codes(:one)
end
test "should be valid with all required attributes" do
assert @auth_code.valid?
end
test "should belong to an application" do
assert_respond_to @auth_code, :application
assert_equal applications(:kavita_app), @auth_code.application
end
test "should belong to a user" do
assert_respond_to @auth_code, :user
assert_equal users(:alice), @auth_code.user
end
test "should generate code before validation on create" do
new_code = OidcAuthorizationCode.new(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback"
)
assert_nil new_code.code
assert new_code.save
assert_not_nil new_code.code
assert_match /^[A-Za-z0-9_-]+$/, new_code.code
end
test "should set expiry before validation on create" do
new_code = OidcAuthorizationCode.new(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback"
)
assert_nil new_code.expires_at
assert new_code.save
assert_not_nil new_code.expires_at
assert new_code.expires_at > Time.current
assert new_code.expires_at <= 11.minutes.from_now # Allow some variance
end
test "should validate presence of code" do
@auth_code.code = nil
assert_not @auth_code.valid?
assert_includes @auth_code.errors[:code], "can't be blank"
end
test "should validate uniqueness of code" do
@auth_code.save! if @auth_code.changed?
duplicate = OidcAuthorizationCode.new(
code: @auth_code.code,
application: applications(:another_app),
user: users(:bob),
redirect_uri: "https://example.com/callback"
)
assert_not duplicate.valid?
assert_includes duplicate.errors[:code], "has already been taken"
end
test "should validate presence of redirect_uri" do
@auth_code.redirect_uri = nil
assert_not @auth_code.valid?
assert_includes @auth_code.errors[:redirect_uri], "can't be blank"
end
test "should identify expired codes correctly" do
@auth_code.expires_at = 5.minutes.ago
assert @auth_code.expired?, "Should identify past expiry as expired"
@auth_code.expires_at = 5.minutes.from_now
assert_not @auth_code.expired?, "Should identify future expiry as not expired"
@auth_code.expires_at = Time.current
assert @auth_code.expired?, "Should identify current time as expired"
end
test "should identify usable codes correctly" do
# Fresh, unused code should be usable
@auth_code.expires_at = 5.minutes.from_now
@auth_code.used = false
assert @auth_code.usable?, "Fresh unused code should be usable"
# Used code should not be usable
@auth_code.used = true
assert_not @auth_code.usable?, "Used code should not be usable"
# Expired code should not be usable
@auth_code.used = false
@auth_code.expires_at = 5.minutes.ago
assert_not @auth_code.usable?, "Expired code should not be usable"
# Used and expired code should not be usable
@auth_code.used = true
@auth_code.expires_at = 5.minutes.ago
assert_not @auth_code.usable?, "Used and expired code should not be usable"
end
test "should consume code correctly" do
@auth_code.used = false
assert_not @auth_code.used?, "Code should initially be unused"
@auth_code.consume!
@auth_code.reload
assert @auth_code.used?, "Code should be marked as used after consumption"
end
test "valid scope should return only unused and non-expired codes" do
# Create codes with different states
valid_code = OidcAuthorizationCode.create!(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback"
)
used_code = OidcAuthorizationCode.create!(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback",
used: true
)
expired_code = OidcAuthorizationCode.create!(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback",
expires_at: 5.minutes.ago
)
valid_codes = OidcAuthorizationCode.valid
assert_includes valid_codes, valid_code
assert_not_includes valid_codes, used_code
assert_not_includes valid_codes, expired_code
end
test "expired scope should return only expired codes" do
# Create codes with different expiry states
non_expired_code = OidcAuthorizationCode.create!(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback",
expires_at: 5.minutes.from_now
)
expired_code = OidcAuthorizationCode.create!(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback",
expires_at: 5.minutes.ago
)
expired_codes = OidcAuthorizationCode.expired
assert_includes expired_codes, expired_code
assert_not_includes expired_codes, non_expired_code
end
test "should handle concurrent consumption safely" do
@auth_code.used = false
@auth_code.save!
# Simulate concurrent consumption
original_used = @auth_code.used?
@auth_code.consume!
assert_not original_used, "Code should be unused before consumption"
assert @auth_code.used?, "Code should be used after consumption"
end
test "should generate secure random codes" do
codes = []
5.times do
code = OidcAuthorizationCode.create!(
application: applications(:kavita_app),
user: users(:alice),
redirect_uri: "https://example.com/callback"
)
codes << code.code
end
# All codes should be unique
assert_equal codes.length, codes.uniq.length
# All codes should match the expected pattern
codes.each do |code|
assert_match /^[A-Za-z0-9_-]+$/, code
assert_equal 43, code.length # Base64 padding removed
end
end
end