require_relative 'spec_helper'

describe CVE::Vulnerability do
  mocker = VulnerabilityMock.new
  cve_vul_obj = VulnerabilityMock.generate

  it 'should not error when passing a valid hash' do
    id = mocker.identifier

    item = CVE::Vulnerability.new({
      :identifier => id,
      :title => mocker.title(id),
      :link => mocker.link(id),
      :description => mocker.description,
      :date => mocker.date
    })

    expect(item).to be_a(CVE::Vulnerability)
  end

  it 'should compare to a CVE with the same identifier and link' do
    id = mocker.identifier
    link = mocker.link(id)
    item = CVE::Vulnerability.new({
      :identifier => id,
      :title => mocker.title(id),
      :link => link,
      :description => mocker.description,
      :date => mocker.date
    })

    item_roughly_identical = CVE::Vulnerability.new({
        :identifier => id,
        :title => mocker.title(id),
        :link => link,
        :description => mocker.description,
        :date => mocker.date
    })

    expect(item.equal?(item_roughly_identical, false)).to equal(true)
  end

  it 'should compare strictly to an identical CVE' do
    id = mocker.identifier
    item = CVE::Vulnerability.new({
      :identifier => id,
      :title => mocker.title(id),
      :link => mocker.link(id),
      :description => mocker.description,
      :date => mocker.date
    })

    item_identical = item.clone

    expect(item.equal?(item_identical, true)).to equal(true)
  end

  it 'should fail compare strictly to an unidentical CVE with the same ID' do
    id = mocker.identifier
    item = CVE::Vulnerability.new({
      :identifier => id,
      :title => mocker.title(id),
      :link => mocker.link(id),
      :description => mocker.description,
      :date => mocker.date
    })

    item_unidentical = CVE::Vulnerability.new({
      :identifier => id,
      :title => mocker.title(id),
      :link => mocker.link(id),
      :description => mocker.description,
      :date => mocker.date
    })

    expect(item.equal?(item_unidentical, true)).to equal(false)
  end

  it 'should fail compare to an unidentical CVE' do
    id = mocker.identifier
    item = CVE::Vulnerability.new({
      :identifier => id,
      :title => mocker.title(id),
      :link => mocker.link(id),
      :description => mocker.description,
      :date => mocker.date
    })

    id = mocker.identifier
    item_unidentical = CVE::Vulnerability.new({
      :identifier => id,
      :title => mocker.title(id),
      :link => mocker.link(id),
      :description => mocker.description,
      :date => mocker.date
    })

    expect(item.equal?(item_unidentical, false)).to equal(false)
  end

  it 'should be able to extract a single software from the title' do
    title = 'CVE-2015-123 (firefox)'
    extract = cve_vul_obj.extract_software_from_title(title)

    expect(extract.count).to eq(1)
    expect(extract[0]).to eq('firefox')
  end

  it 'should be able to extract many software from the title' do
    title = 'CVE-2015-123 (firefox, firefox_esr, flash)'
    extract = cve_vul_obj.extract_software_from_title(title)

    expect(extract.count).to eq(3)
    expect(extract[0]).to eq('firefox')
    expect(extract[1]).to eq('firefox_esr')
    expect(extract[2]).to eq('flash')
  end

  it 'should return nil for affected software when not included' do
    title = 'CVE-2015-123'
    extract = cve_vul_obj.extract_software_from_title(title)

    expect(extract).to eq(nil)
  end

  it 'should error when not passing a hash' do
    expect{ CVE::Vulnerability.new('') }.to raise_error(RuntimeError)
  end

  it 'should error when passing an empty hash' do
    expect{ CVE::Vulnerability.new({}) }.to raise_error(RuntimeError)
  end

  it 'should error when passing a hash with missing keys' do
    expect{ CVE::Vulnerability.new({:identifier => 'abc', :title => 'title'}) }.to raise_error(RuntimeError)
  end
end
