# frozen_string_literal: true

require 'spec_helper'

RSpec.describe GitlabSchema.types['VulnerabilityRequestResponseHeader'] do
  let_it_be(:project) { create(:project) }
  let_it_be(:user) { create(:user) }
  let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }

  before do
    stub_licensed_features(api_fuzzing: true, security_dashboard: true)

    project.add_developer(user)
  end

  let(:fields) do
    %i[name value]
  end

  subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }

  specify { expect(described_class.graphql_name).to eq('VulnerabilityRequestResponseHeader') }

  it { expect(described_class).to have_graphql_fields(fields) }

  describe 'checking field contents' do
    before do
      vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
      @vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
    end

    context 'evidence.request.headers fields' do
      let(:query) do
        %(
        query {
          project(fullPath: "#{project.full_path}") {
            pipeline(iid: "#{pipeline.iid}") {
              securityReportFindings {
                nodes {
                  title
                  evidence {
                    request {
                      headers {
                        name
                        value
                      }
                    }
                  }
                }
              }
            }
          }
        }
      )
      end

      it 'checks the contents of the fields' do
        headers = @vulnerability['evidence']['request']['headers']

        expect(headers.length).to eq(11)
        expect(headers.first).to eq({ 'name' => 'Host', 'value' => '127.0.0.1:7777' })
      end
    end

    context 'evidence.response.headers fields' do
      let(:query) do
        %(
        query {
          project(fullPath: "#{project.full_path}") {
            pipeline(iid: "#{pipeline.iid}") {
              securityReportFindings {
                nodes {
                  title
                  evidence {
                    response {
                      headers {
                        name
                        value
                      }
                    }
                  }
                }
              }
            }
          }
        }
      )
      end

      it 'checks the contents of the fields' do
        headers = @vulnerability['evidence']['response']['headers']

        expect(headers.length).to eq(7)
        expect(headers.first).to eq({ 'name' => 'Server', 'value' => 'TwistedWeb/20.3.0' })
      end
    end

    context 'evidence.supportingMessages[].request.headers fields' do
      let(:query) do
        %(
        query {
          project(fullPath: "#{project.full_path}") {
            pipeline(iid: "#{pipeline.iid}") {
              securityReportFindings {
                nodes {
                  title
                  evidence {
                    supportingMessages {
                      name
                      request {
                        headers {
                          name
                          value
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      )
      end

      it 'checks the contents of the fields' do
        request = @vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }['request']

        expect(request['headers'].first).to eq({
                                                                       "name" => "Host",
                                                                       "value" => "127.0.0.1:7777"
                                                                     })
        expect(request['headers'].length).to eq(9)
      end
    end

    context 'evidence.supportingMessages[].response.headers fields' do
      let(:query) do
        %(
        query {
          project(fullPath: "#{project.full_path}") {
            pipeline(iid: "#{pipeline.iid}") {
              securityReportFindings {
                nodes {
                  title
                  evidence {
                    supportingMessages {
                      name
                      response {
                        headers {
                          name
                          value
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      )
      end

      it 'checks the contents of the fields' do
        response = @vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }['response']

        expect(response['headers'].first).to eq({
                                                  "name" => "Server",
                                                  "value" => "TwistedWeb/20.3.0"
                                                })
        expect(response['headers'].length).to eq(6)
      end
    end
  end
end
