Search code examples
ruby-on-railsrubyrspecgitlabgitlab-api

How can I test a method in an API route using rspec?


I'm very new to the ruby,I'm currently trying to contribute to gitlab a new functionality.I stuck at writing some test cases.

pages_domains.rb

# frozen_string_literal: true

module API
  class PagesDomains < ::API::Base
    include PaginationParams

    feature_category :pages

    PAGES_DOMAINS_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(domain: API::NO_SLASH_URL_PART_REGEX)
 
    helpers do
      ##### my custom method   #####
      def is_page_domain_verified
        value=false
        result = VerifyPagesDomainService.new(pages_domain).execute
        if(result[:status] == :success)
          value=true
        end  
        value  
      end
      ##### my custom method   #####        
    end
 

    params do
      requires :id, type: String, desc: 'The ID of a project'
    end
    resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
      before do
        require_pages_enabled!
      end

      # other api endpoint logic

      ########## my custom api endpoint logic ############
      desc 'Verify a pages domain' do
        success Entities::PagesDomain
      end
      params do
        requires :domain, type: String, desc: 'The domain'
      end
      get ":id/pages/domains/:domain/verify",requirements: PAGES_DOMAINS_ENDPOINT_REQUIREMENTS do
        authorize! :update_pages, user_project
        if pages_domain.persisted?

          if (is_page_domain_verified==false)
            render_api_error!("Failed to verify domain ownership", :unprocessable_entity)
          end

          present pages_domain, with: Entities::PagesDomain
        else
          render_validation_error!(pages_domain)
        end

      end
      ########## my custom api endpoint logic ############

      # other api enpoint logic
    end
  end
end

In the pages_domains_spec.rb I have added the test case for failure case as below mentioned code

pages_domains_spec.rb

  describe 'GET verify for page domain', :focus do
    
    context 'Domain Verifications' do
      it 'returns unprocessable_entity if failed to verify' do
        get api(route_domain_verify, admin)
        expect(response).to have_gitlab_http_status(:unprocessable_entity)
      end
    end  
  end

Now How can I write the test cases for the success? For that I need to return true from the method is_page_domain_verified.I explored stubbing but had hard-luck with understanding it. I've tried the following code to test using stubs from referencing other people codes in the project

pages_domains_spec.rb

  describe 'GET verify for page domain', :focus do
    
    context 'Domain Verifications' do
      before do
        allow(PagesDomains.is_page_domain_verified).to receive(:get).and_return(true)
      end

      it 'returns ok if verification successful' do
        get api(route_domain_verify, admin)
        expect(response).to have_gitlab_http_status(:ok)
      end
    end  
  end

When I run this I am getting NoMethodError.Please help writing a test case for success.

Failures:

  1) API::PagesDomains GET verify for page domain Domain Verifications returns ok if verification successful
     Failure/Error: allow(PagesDomains.is_page_domain_verified).to receive(:get).and_return(true)
     
     NoMethodError:
       undefined method `is_page_domain_verified' for PagesDomains:Module
     # ./spec/requests/api/pages_domains_spec.rb:60:in `block (4 levels) in <top (required)>'
     # ./spec/spec_helper.rb:390:in `block (3 levels) in <top (required)>'
     # ./spec/support/sidekiq_middleware.rb:9:in `with_sidekiq_server_middleware'
     # ./spec/spec_helper.rb:381:in `block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:377:in `block (3 levels) in <top (required)>'
     # ./lib/gitlab/application_context.rb:31:in `with_raw_context'
     # ./spec/spec_helper.rb:377:in `block (2 levels) in <top (required)>'

Finished in 6.18 seconds (files took 36.48 seconds to load)
1 example, 1 failure

Thank you.


Solution

  • The error you're seeing is from the PagesDomains.is_page_domain_verified line, is_page_domain_verified is not defined on the PagesDomains class, since it's a helper method.

    We can reach into the controller helpers to stub this method but I'm not sure I love that approach. One option is to stub the instances of the VerifyPagesDomainService class.

    Something like:

    allow_any_instance_of(VerifyPagesDomainService).to receive(:execute) and_return({status: :failed})