require 'test_helper'

class VLanTest < ActiveSupport::TestCase
  setup do
    @v_lan = v_lans(:one)
    @v_lan.ip_address = "192.168.1.1"
    @v_lan.net_mask = "255.255.255.0"
    @v_lan.gateway = "192.168.1.254"
    @v_lan.dns1 = "8.8.8.8"
    @v_lan.dns2 = "8.8.4.4"
    @v_lan.dhcp_start_range = "192.168.1.10"
    @v_lan.dhcp_end_range = "192.168.1.100"
    @v_lan.dhcp_mappings = []
  end

  test "should be valid with empty dhcp_mappings" do
    @v_lan.dhcp_mappings = []
    assert @v_lan.valid?
  end

  test "should be valid with a valid dhcp_mapping" do
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "192.168.1.5", "MAC" => "00:11:22:33:44:55" }
    ]
    assert @v_lan.valid?
  end

  test "should be invalid if dhcp_mappings is not an array" do
    @v_lan.dhcp_mappings = "not-an-array"
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "must be an array"
  end

  test "should be invalid if IPADDR or MAC is blank" do
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "", "MAC" => "00:11:22:33:44:55" }
    ]
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "Both IP and MAC is required"
  end

  test "should be invalid if IP format is invalid" do
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "192.168.1.256", "MAC" => "00:11:22:33:44:55" }
    ]
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "Invalid IP address"
  end

  test "should be invalid if MAC format is invalid" do
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "192.168.1.5", "MAC" => "00:11:22:33:44:GG" }
    ]
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "Invalid Mac address"
  end

  test "should be invalid if MAC is multicast" do
    # Multicast MAC has odd digit in first octet second digit, e.g. 01:00:5E:00:00:01
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "192.168.1.5", "MAC" => "01:11:22:33:44:55" }
    ]
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "Multicast MAC not allowed."
  end

  test "should be invalid if IP is not in subnet range" do
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "192.168.2.5", "MAC" => "00:11:22:33:44:55" }
    ]
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "IP Address is not in the range of IP and Gateway fields!"
  end

  test "should be invalid if IP conflicts with gateway or own IP" do
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "192.168.1.1", "MAC" => "00:11:22:33:44:55" }
    ]
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "Field cannot contain same IP Address!"
  end

  test "should be invalid if there are duplicate IPs or MACs" do
    @v_lan.dhcp_mappings = [
      { "IPADDR" => "192.168.1.5", "MAC" => "00:11:22:33:44:55" },
      { "IPADDR" => "192.168.1.6", "MAC" => "00:11:22:33:44:55" }
    ]
    assert_not @v_lan.valid?
    assert_includes @v_lan.errors[:dhcp_mappings], "Duplicate MAC address 00:11:22:33:44:55 in mappings"
  end
end
