# frozen_string_literal: true

#
# Copyright (C) 2019 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#

require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require File.expand_path(File.dirname(__FILE__) + '/ims/concerns/advantage_services_shared_context')
require File.expand_path(File.dirname(__FILE__) + '/ims/concerns/lti_services_shared_examples')
require_dependency "lti/public_jwk_controller"

module Lti
  describe PublicJwkController do
    describe '#update' do
      include_context 'advantage services context'
      it_behaves_like 'lti services' do
        let(:action) { :update }
        let(:expected_mime_type) { described_class::MIME_TYPE }
        let(:scope_to_remove) { "https://canvas.instructure.com/lti/public_jwk/scope/update"}
        let(:new_public_jwk) do
          key_hash = Canvas::Security::RSAKeyPair.new.public_jwk.to_h
          key_hash['kty'] = key_hash['kty'].to_s
          key_hash
        end
        let(:params_overrides) do
          { developer_key: { public_jwk: new_public_jwk } }
        end
      end

      context 'check public jwk' do
        let(:expected_mime_type) { described_class::MIME_TYPE }
        let(:scope_to_remove) { "https://canvas.instructure.com/lti/public_jwk/scope/update"}
        let(:action) { :update }
        let(:old_public_jwk) { developer_key.public_jwk }
        let(:new_public_jwk) do
          key_hash = Canvas::Security::RSAKeyPair.new.public_jwk.to_h
          key_hash['kty'] = key_hash['kty'].to_s
          key_hash
        end
        let(:params_overrides) do
          { developer_key: { public_jwk: new_public_jwk } }
        end

        context 'when public jwk is valid' do
          before do
            old_public_jwk
            send_request
          end

          it 'update public jwk was successful' do
            expect(JSON.parse(response.body)['public_jwk']).to_not eq old_public_jwk
            expect(JSON.parse(response.body)['public_jwk']).to eq new_public_jwk
            expect(developer_key.reload.public_jwk).to eq new_public_jwk
          end

          it 'return 200 success http status' do
            expect(response).to have_http_status http_success_status
          end
        end

        context 'when pubic jwk is not valid' do
          let(:params_overrides) do
            { developer_key: { public_jwk: {'hello': 'world'} } }
          end

          before do
            old_public_jwk
            send_request
          end

          it 'update public jwk was not successful' do
            expect(developer_key.public_jwk).to eq old_public_jwk
          end

          it 'return 422 unathorized http status' do
            expect(response).to have_http_status :unprocessable_entity
          end
        end

        context 'when pubic jwk is empty' do
          let(:params_overrides) do
            { developer_key: { public_jwk: {} } }
          end

          before do
            old_public_jwk
            send_request
          end

          it 'update public jwk was not successful' do
            expect(JSON.parse(response.body)['public_jwk']).to eq old_public_jwk
          end

          it 'return 400 unathorized http status' do
            expect(response).to have_http_status :bad_request
          end
        end
      end
    end
  end
end
