# frozen_string_literal: true require "test_helper" class DsnTest < ActiveSupport::TestCase # Disable fixtures since we're creating test data manually self.use_instantiated_fixtures = false def setup @dsn = Dsn.new(name: "Test DSN") end test "should be valid with valid attributes" do assert @dsn.valid? end test "should not be valid without name" do @dsn.name = nil assert_not @dsn.valid? assert_includes @dsn.errors[:name], "can't be blank" end test "should automatically generate key on create" do @dsn.save! assert_not_nil @dsn.key assert_equal 64, @dsn.key.length # hex(32) = 64 characters assert_match /\A[a-f0-9]{64}\z/, @dsn.key end test "should not override existing key when saved" do @dsn.key = "existing-key-123" @dsn.save! assert_equal "existing-key-123", @dsn.key end test "should enforce unique keys" do @dsn.save! dsn2 = Dsn.new(name: "Another DSN", key: @dsn.key) assert_not dsn2.valid? assert_includes dsn2.errors[:key], "has already been taken" end test "should default to enabled" do @dsn.save! assert @dsn.enabled? end test "should authenticate with valid key" do @dsn.save! authenticated_dsn = Dsn.authenticate(@dsn.key) assert_equal @dsn, authenticated_dsn end test "should not authenticate with invalid key" do @dsn.save! assert_nil Dsn.authenticate("invalid-key") end test "should not authenticate disabled DSNs" do @dsn.save! @dsn.update!(enabled: false) assert_nil Dsn.authenticate(@dsn.key) end # URL Generation Tests test "should generate full DSN URL in development" do @dsn.key = "test-key-1234567890abcdef" @dsn.save! expected = "http://test-key-1234567890abcdef@localhost" assert_equal expected, @dsn.full_dsn_url end test "should generate API endpoint URL in development" do @dsn.save! expected = "http://localhost" assert_equal expected, @dsn.api_endpoint_url end test "should use HTTPS in production environment" do # Temporarily switch to production environment original_env = Rails.env Rails.env = "production" @dsn.key = "prod-key-1234567890abcdef" @dsn.save! assert_equal "https://prod-key-1234567890abcdef@localhost", @dsn.full_dsn_url assert_equal "https://localhost", @dsn.api_endpoint_url # Restore original environment Rails.env = original_env end test "should use custom host from environment variable" do ENV['RAILS_HOST'] = 'baffle.example.com' @dsn.key = "custom-key-1234567890abcdef" @dsn.save! assert_equal "http://custom-key-1234567890abcdef@baffle.example.com", @dsn.full_dsn_url assert_equal "http://baffle.example.com", @dsn.api_endpoint_url ENV.delete('RAILS_HOST') end test "should use action mailer default host if configured" do Rails.application.config.action_mailer.default_url_options = { host: 'mail.baffle.com' } @dsn.key = "mail-key-1234567890abcdef" @dsn.save! assert_equal "http://mail-key-1234567890abcdef@mail.baffle.com", @dsn.full_dsn_url assert_equal "http://mail.baffle.com", @dsn.api_endpoint_url Rails.application.config.action_mailer.default_url_options = {} end test "should handle long hex keys in URLs" do long_key = "c92b7f8ad94ea3400299d8a6ff19e409c2df8c4540022c3167b8ac1002931624" @dsn.key = long_key @dsn.save! expected = "http://#{long_key}@localhost" assert_equal expected, @dsn.full_dsn_url end # Scope Tests test "enabled scope should return only enabled DSNs" do enabled_dsn = Dsn.create!(name: "Enabled DSN", enabled: true) disabled_dsn = Dsn.create!(name: "Disabled DSN", enabled: false) enabled_dsns = Dsn.enabled assert_includes enabled_dsns, enabled_dsn assert_not_includes enabled_dsns, disabled_dsn end # Security Tests test "should generate cryptographically secure keys" do keys = [] 10.times do dsn = Dsn.create!(name: "Test DSN #{Time.current.to_f}") keys << dsn.key end # All keys should be unique assert_equal keys.length, keys.uniq.length # All keys should be valid hex keys.each do |key| assert_equal 64, key.length assert_match /\A[a-f0-9]{64}\z/, key end end test "should not allow nil keys" do @dsn.key = nil assert_not @dsn.valid? assert_includes @dsn.errors[:key], "can't be blank" end end