-
-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Description
Create comprehensive integration tests using mock OAuth servers to test the complete OAuth flow with different providers (GitHub, Google, Microsoft, etc.). This will ensure the library works correctly with various OAuth implementations.
What needs to be done
Create integration tests that:
- Set up mock OAuth servers that simulate real provider behavior
- Test complete authorization flows for major providers
- Test error scenarios (access denied, invalid scope, network errors)
- Test edge cases specific to each provider
- Verify state parameter handling
- Test timeout scenarios
- Test concurrent authorization flows
Why this matters
Different OAuth providers have subtle differences:
- Parameter naming conventions
- Error response formats
- Required vs optional parameters
- Redirect behavior
- State parameter handling
Without integration tests:
- Provider-specific bugs only discovered in production
- Regressions when updating the library
- No confidence that the library works with all providers
Implementation considerations
-
Mock vs Real: Should we test against real OAuth providers in a separate test suite? This would catch actual breaking changes.
-
Test data management: How do we manage test credentials securely? GitHub Secrets? Environment variables?
-
Alternative approach: Use a tool like WireMock or Mockoon to record and replay real OAuth flows
-
CI/CD integration: These tests will be slower. Should they run on every commit or only on releases?
-
Provider versioning: OAuth providers update their APIs. How do we keep our mocks in sync?
Suggested test structure
// tests/integration/providers/github.test.ts
import { expect, test, describe, beforeAll, afterAll } from "bun:test";
import { getAuthCode } from "../../src";
import { createMockOAuthServer } from "../helpers/mock-server";
describe("GitHub OAuth Integration", () => {
let mockServer: MockOAuthServer;
beforeAll(async () => {
mockServer = await createMockOAuthServer({
provider: "github",
port: 4000
});
});
afterAll(async () => {
await mockServer.stop();
});
test("successful authorization flow", async () => {
const state = crypto.randomUUID();
mockServer.expectAuthorization({
client_id: "test-client",
state,
response: {
code: "test-code-123",
state
}
});
const result = await getAuthCode({
authorizationUrl: `http://localhost:4000/authorize?client_id=test-client&state=${state}`,
openBrowser: false
});
expect(result.code).toBe("test-code-123");
expect(result.state).toBe(state);
});
test("user denies access", async () => {
mockServer.expectAuthorization({
response: {
error: "access_denied",
error_description: "The user denied access"
}
});
await expect(getAuthCode({
authorizationUrl: "http://localhost:4000/authorize",
openBrowser: false
})).rejects.toThrow(OAuthError);
});
test("handles GitHub-specific scopes", async () => {
// Test GitHub's specific scope handling...
});
});
// tests/helpers/mock-server.ts
export class MockOAuthServer {
constructor(private config: MockServerConfig) {}
async start() {
// Create HTTP server that mimics OAuth provider
}
expectAuthorization(expectation: AuthExpectation) {
// Set up expected request/response
}
async stop() {
// Clean up
}
}
// Provider-specific behaviors
const providerConfigs = {
github: {
authorizePath: "/login/oauth/authorize",
errorFormat: "query", // vs "fragment"
requiredParams: ["client_id"],
stateRequired: false
},
google: {
authorizePath: "/o/oauth2/v2/auth",
errorFormat: "query",
requiredParams: ["client_id", "response_type", "scope"],
stateRequired: true
},
microsoft: {
authorizePath: "/oauth2/v2.0/authorize",
errorFormat: "query",
requiredParams: ["client_id", "response_type", "scope"],
stateRequired: true
}
};
Test scenarios to cover
Success cases
- Basic authorization with code
- Authorization with state parameter
- Authorization with additional parameters
- Multiple concurrent authorizations
Error cases
- User denies access
- Invalid client ID
- Invalid redirect URI
- Invalid scope
- Server errors (500, 503)
- Network timeouts
- Malformed responses
Provider-specific cases
- GitHub: Apps vs OAuth Apps
- Google: Offline access, consent prompts
- Microsoft: Tenant-specific endpoints
- Auth0: Custom domains
- Okta: Authorization servers
Skills required
- TypeScript
- OAuth 2.0 protocol knowledge
- Integration testing
- Mock server creation
- HTTP protocol
- Testing async flows
Difficulty
Hard - Requires deep understanding of OAuth and testing complex async flows