Skip to main content

testing

Write correct and complete RSpec tests for Doorkeeper. Use when adding specs for new features, writing regression tests for bug fixes, or reviewing test coverage for a change.

Datos de origen

Repositorio
doorkeeper-gem/doorkeeper
Última actividad en el origen
17 de agosto de 2026 a las 13:19
Idioma detectado de SKILL.md
inglés
Estrellas
5523
Forks
1076

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
testing
description
Write correct and complete RSpec tests for Doorkeeper. Use when adding specs for new features, writing regression tests for bug fixes, or reviewing test coverage for a change.
# Testing When writing or modifying tests in Doorkeeper, use this skill to ensure tests are correct, complete, and follow project conventions. ## Test Organization | What you're testing | Where to put the spec | |--------------------|----------------------| | OAuth request/response flow (integration) | `spec/requests/flows/` | | Endpoint behavior (HTTP layer) | `spec/requests/endpoints/` | | Controller logic (unit) | `spec/controllers/` | | Model behavior & mixins | `spec/models/doorkeeper/` | | OAuth protocol logic (unit) | `spec/lib/oauth/` | | Configuration | `spec/lib/config_spec.rb` | | Generators | `spec/generators/` | | Routing | `spec/routing/` | | Grape integration | `spec/grape/` | ## Spec Conventions ### Style ```ruby # frozen_string_literal: true require "spec_helper" RSpec.describe Doorkeeper::OAuth::SomeClass do describe "#method_name" do context "when condition is met" do it "does the expected thing" do # arrange, act, assert end end end end ``` ### Require Line All specs use `require "spec_helper"`. The `spec_helper` loads the dummy Rails app, database, factories, and support helpers — it covers both unit and integration needs. > **Note:** A legacy `spec_helper_integration` file exists but is just a compatibility wrapper around `spec_helper`. Do not use it in new specs. ### Factories Factories are in `spec/factories.rb`. Use FactoryBot: ```ruby let(:application) { FactoryBot.create(:application) } let(:access_token) { FactoryBot.create(:access_token, application: application) } let(:access_grant) { FactoryBot.create(:access_grant, application: application) } ``` ### Helper Methods Reuse helpers from `spec/support/helpers/`: - `model_helper.rb` — `client_exists`, `create_resource_owner`, token/grant existence checks - `request_spec_helper.rb` — `json_response`, `should_have_status`, `url_should_have_param`, `basic_auth_header_for_client` - `url_helper.rb` — `token_endpoint_url`, `authorization_endpoint_url`, `refresh_token_endpoint_url` - `config_helper.rb` — `config_is_set` (temporarily override config in a block) - `authorization_request_helper.rb` — `resource_owner_is_authenticated`, `default_scopes_exist` ### Configuration Changes in Tests Use `config_is_set` or the Doorkeeper.configure block (resets after each test): ```ruby before do config_is_set(:access_token_expires_in, 100) end ``` ## Test Patterns ### Request/Flow Specs (most important) ```ruby RSpec.describe "Authorization Code Flow" do let(:application) { FactoryBot.create(:application) } let(:resource_owner) { User.create!(name: "owner", password: "password") } before do default_scopes_exist :public resource_owner_is_authenticated resource_owner end it "issues an access token" do visit authorization_endpoint_url(client: application) click_on "Authorize" code = current_params["code"] post token_endpoint_url, params: { grant_type: "authorization_code", code: code, redirect_uri: application.redirect_uri, client_id: application.uid, client_secret: application.secret, } expect(response).to have_http_status(:ok) expect(json_response["access_token"]).to be_present end end ``` ### OAuth Unit Specs ```ruby RSpec.describe Doorkeeper::OAuth::AuthorizationCodeRequest do subject(:request) do described_class.new(server, grant, client, params) end let(:server) do double :server, access_token_expires_in: 2.days, refresh_token_enabled?: false, custom_access_token_expires_in: lambda { |context| context.grant_type == Doorkeeper::OAuth::AUTHORIZATION_CODE ? 1234 : nil } end let(:resource_owner) { FactoryBot.create :resource_owner } let(:grant) do FactoryBot.create :access_grant, resource_owner_id: resource_owner.id, resource_owner_type: resource_owner.class.name end let(:client) { grant.application } let(:redirect_uri) { client.redirect_uri } let(:params) { { redirect_uri: redirect_uri } } before do allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true) end describe "#authorize" do it "issues a new token for the client" do expect { request.authorize }.to change { client.reload.access_tokens.count }.by(1) end it "revokes the grant" do expect { request.authorize }.to(change { grant.reload.accessible? }) end end describe "#validate" do it "requires the grant to be accessible" do grant.revoke request.validate expect(request.error).to eq(Doorkeeper::Errors::InvalidGrant) end it "requires the client" do request = described_class.new(server, grant, nil, params) request.validate expect(request.error).to eq(Doorkeeper::Errors::InvalidClient) end end end ``` ## What to Test ### For new features: 1. Happy path — the feature works as intended 2. Error cases — invalid input, missing parameters, unauthorized access 3. Edge cases — nil values, empty strings, boundary conditions 4. Configuration interaction — does it respect relevant config options? 5. Backward compatibility — does existing behavior still pass? ### For bug fixes: 1. Regression test — reproduce the exact bug scenario, verify it's fixed 2. Related edge cases — similar situations that might also be affected ### For security fixes: 1. The vulnerability is no longer exploitable 2. The fix doesn't break legitimate use cases 3. Error responses don't leak information ## Common Pitfalls - **Don't use `sleep`** — use `Timecop.travel` or `Timecop.freeze` instead - **Don't hardcode token values** — let the system generate them - **Don't test private methods directly** — test through the public interface - **Don't forget scopes** — many features are scope-dependent, set them up explicitly - **Use `Timecop`** for time-dependent tests (expiration, token lifetime) ## Verification 1. Run new specs in isolation: `bundle exec rspec spec/path/to/new_spec.rb` 2. Run the full related directory: `bundle exec rspec spec/lib/oauth/` 3. Run full suite: `bundle exec rake spec` 4. Specs must pass in any order (`--order random`)
Ver en GitHub