Skip to content

Commit 08d4522

Browse files
teetanghclaude
andcommitted
feat: Modernize test infrastructure and update to Ruby 3.4.1
- Reorganize tests: move integration tests to spec/requests/api/v1/ - Convert swagger specs to documentation-only - Add health check endpoint for monitoring - Update Ruby version from 3.3.0 to 3.4.1 - Enhance CI workflow with validation and swagger generation - Add dev.env support for local development - Update README with troubleshooting and test documentation - Modernize dependabot configuration - Add .tool-versions for asdf compatibility - Include Ruby on Rails installation guide 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 7ee236a commit 08d4522

File tree

22 files changed

+1885
-1147
lines changed

22 files changed

+1885
-1147
lines changed

.github/dependabot.yml

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,51 @@
11
version: 2
22
updates:
3+
# Keep bundler dependencies up to date
34
- package-ecosystem: "bundler"
45
directory: "/"
56
schedule:
6-
interval: "daily"
7+
interval: "weekly"
8+
groups:
9+
# Group Rails and related gems together
10+
rails:
11+
patterns:
12+
- "rails*"
13+
- "actionpack"
14+
- "actionview"
15+
- "activerecord"
16+
- "activejob"
17+
- "actioncable"
18+
- "actionmailer"
19+
- "activestorage"
20+
- "actionmailbox"
21+
- "actiontext"
22+
# Group testing gems together
23+
testing:
24+
patterns:
25+
- "rspec*"
26+
- "capybara"
27+
- "selenium-webdriver"
28+
labels:
29+
- "dependencies"
30+
- "ruby"
31+
open-pull-requests-limit: 10
32+
33+
# Keep GitHub Actions up to date
34+
- package-ecosystem: "github-actions"
35+
directory: "/"
36+
schedule:
37+
interval: "weekly"
38+
labels:
39+
- "dependencies"
40+
- "github-actions"
41+
open-pull-requests-limit: 5
42+
43+
# Keep Docker base image up to date
44+
- package-ecosystem: "docker"
45+
directory: "/"
46+
schedule:
47+
interval: "weekly"
48+
labels:
49+
- "dependencies"
50+
- "docker"
51+
open-pull-requests-limit: 5

.github/workflows/ci.yml

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
branches: [main]
88
schedule:
99
- cron: "50 9 * * *"
10+
workflow_dispatch:
1011

1112
jobs:
1213
run_tests:
@@ -23,12 +24,30 @@ jobs:
2324
- name: Set up Ruby
2425
uses: ruby/setup-ruby@v1
2526
with:
26-
ruby-version: 3.3.0
27+
ruby-version: 3.4.1
28+
bundler-cache: true
2729
- name: Install dependencies
2830
run: bundle install
2931

30-
- name: Run tests
31-
run: bundle exec rspec test/integration
32+
- name: Validate Couchbase configuration
33+
run: |
34+
if [ -z "$DB_CONN_STR" ] || [ -z "$DB_USERNAME" ] || [ -z "$DB_PASSWORD" ]; then
35+
echo "Error: Missing required Couchbase configuration"
36+
echo "DB_CONN_STR, DB_USERNAME, and DB_PASSWORD must all be set"
37+
exit 1
38+
fi
39+
echo "Couchbase configuration validated successfully"
40+
41+
- name: Run integration tests
42+
run: bundle exec rspec spec/requests/api/v1
43+
44+
- name: Verify Swagger documentation generates
45+
run: bundle exec rake rswag:specs:swaggerize
46+
env:
47+
DB_CONN_STR: ${{ vars.DB_CONN_STR }}
48+
DB_USERNAME: ${{ vars.DB_USERNAME }}
49+
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
50+
CI: true
3251

3352
- name: Report Status
3453
if: always()

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Gemfile.lock
1616
# Ignore all environment files (except templates).
1717
/.env*
1818
!/.env*.erb
19+
/dev.env
1920

2021
# Ignore all logfiles and tempfiles.
2122
/log/*

.ruby-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ruby-3.3.0
1+
3.4.1

.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ruby 3.4.1

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Use the official Ruby 3.0.0 image as the base image
2-
FROM ruby:3.3.0
1+
# Use the official Ruby 3.4.1 image as the base image
2+
FROM ruby:3.4.1
33

44
# Install essential Linux packages
55
RUN apt-get update -qq && \

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
source 'https://rubygems.org'
22

3-
ruby '3.3.0'
3+
ruby '3.4.1'
44

55
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
66
gem 'rails', '~> 7.1.3', '>= 7.1.3.2'

README.md

Lines changed: 157 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ To run this prebuilt project, you will need:
1515

1616
- [Couchbase Capella cluster](https://www.couchbase.com/products/capella/) with [travel-sample bucket](https://docs.couchbase.com/ruby-sdk/current/ref/travel-app-data-model.html) loaded.
1717
- To run this tutorial using a [self-managed Couchbase cluster](https://docs.couchbase.com/capella/current/getting-started/self-managed-cluster.html), please refer to the appendix.
18-
- [Ruby 3.3.0](https://www.ruby-lang.org/en/documentation/installation/) is installed on the local machine.
18+
- [Ruby 3.4.1](https://www.ruby-lang.org/en/documentation/installation/) is installed on the local machine.
1919
- Basic knowledge of [Ruby](https://www.ruby-lang.org/en/documentation/), [Ruby on Rails](https://rubyonrails.org/), and [RSpec](https://rspec.info/).
2020

2121
## Loading Travel Sample Bucket
@@ -48,7 +48,27 @@ To learn more about connecting to your Capella cluster, please follow the instru
4848

4949
Specifically, you need to do the following:
5050

51-
Open the `config/couchbase.yml` file and update the connection string, username, password, and bucket name for the development and test environments.
51+
#### For Development and Test Environments
52+
53+
Copy the `dev.env.example` file to `dev.env` and update the connection details:
54+
55+
```sh
56+
cp dev.env.example dev.env
57+
```
58+
59+
Edit `dev.env` with your Couchbase credentials:
60+
61+
```sh
62+
DB_USERNAME="your_username"
63+
DB_PASSWORD="your_password"
64+
DB_CONN_STR="couchbases://your-cluster.cloud.couchbase.com"
65+
```
66+
67+
The application will automatically load these environment variables in development and test environments.
68+
69+
#### Configuration File Reference
70+
71+
The `config/couchbase.yml` file defines how the application connects to Couchbase:
5272

5373
```yml
5474
common: &common
@@ -109,14 +129,105 @@ The application will run on the port specified by Rails on your local machine (e
109129

110130
## Running The Tests
111131

112-
The application comes with a set of integration tests that can be run to verify the functionality of the application. The tests are written using RSpec, a popular testing framework for Ruby.
132+
The application includes two types of tests:
133+
134+
### Integration Tests
113135

114-
To run the tests, you can use the following command:
136+
Integration tests verify the actual functionality of the API endpoints. They test the full request-response cycle including database operations.
115137

116138
```sh
117-
bundle exec rspec test/integration
139+
bundle exec rspec spec/requests/api/v1
118140
```
119141

142+
### Swagger Documentation Tests
143+
144+
These tests generate the OpenAPI/Swagger documentation and verify the API contract without performing full integration testing.
145+
146+
```sh
147+
bundle exec rake rswag:specs:swaggerize
148+
```
149+
150+
## Health Check Endpoint
151+
152+
The application provides a health check endpoint to monitor the status of the service and its dependencies:
153+
154+
```sh
155+
GET /api/v1/health
156+
```
157+
158+
This endpoint returns the health status of the application and its connection to Couchbase. Example response:
159+
160+
```json
161+
{
162+
"status": "healthy",
163+
"timestamp": "2025-12-02T10:30:00Z",
164+
"services": {
165+
"couchbase": {
166+
"status": "up",
167+
"message": "Connected to Couchbase bucket: travel-sample"
168+
}
169+
}
170+
}
171+
```
172+
173+
You can use this endpoint for monitoring and alerting in production environments.
174+
175+
## Troubleshooting
176+
177+
### Couchbase ORM Connection Issues
178+
179+
If you encounter connection issues with Couchbase ORM, verify the following:
180+
181+
1. **Check configuration**: Ensure `config/couchbase.yml` has the correct connection string, username, and password.
182+
2. **Connection string format**: The connection string should start with `couchbase://` (for non-TLS) or `couchbases://` (for TLS).
183+
3. **Bucket access**: Verify that the user has read/write permissions to the travel-sample bucket.
184+
4. **Network connectivity**: Ensure your application can reach the Couchbase cluster on the required ports (typically 8091-8096, 11210).
185+
186+
### Common couchbase-orm Errors
187+
188+
**Error: `Couchbase::Error::BucketNotFound`**
189+
- The specified bucket doesn't exist or isn't accessible
190+
- Solution: Verify the bucket name in `config/couchbase.yml` and ensure the travel-sample bucket is loaded
191+
192+
**Error: `Couchbase::Error::AuthenticationFailure`**
193+
- Invalid credentials
194+
- Solution: Check username and password in `config/couchbase.yml` or environment variables
195+
196+
**Error: `Couchbase::Error::Timeout`**
197+
- Network connectivity issues or cluster overload
198+
- Solution: Check network connectivity, increase timeout in connection options, or verify cluster health
199+
200+
**Error: `NoMethodError: undefined method 'bucket' for Model`**
201+
- ORM not properly initialized
202+
- Solution: Ensure `config/couchbase.yml` is correctly configured and the Rails application has loaded the configuration
203+
204+
### Test Setup Issues
205+
206+
**Tests failing with connection errors:**
207+
- Ensure environment variables `DB_CONN_STR`, `DB_USERNAME`, and `DB_PASSWORD` are set for the test environment
208+
- Verify the travel-sample bucket is loaded and accessible
209+
- Check that the test configuration in `config/couchbase.yml` references these environment variables
210+
211+
**Swagger generation fails:**
212+
- Run `bundle exec rake rswag:specs:swaggerize` with proper environment variables
213+
- Check that all swagger specs in `spec/requests/swagger/` are valid
214+
215+
### CI/CD Configuration
216+
217+
When setting up GitHub Actions or other CI/CD pipelines:
218+
219+
1. Set required secrets/variables:
220+
- `DB_CONN_STR`: Connection string to your Couchbase cluster
221+
- `DB_USERNAME`: Username with bucket access
222+
- `DB_PASSWORD`: Password (set as a secret, not a variable)
223+
224+
2. Ensure the CI environment can access your Couchbase cluster (check firewall rules and allowed IP addresses)
225+
226+
3. The CI workflow runs:
227+
- Configuration validation
228+
- Integration tests: `bundle exec rspec spec/requests/api/v1`
229+
- Swagger generation: `bundle exec rake rswag:specs:swaggerize`
230+
120231
# Appendix
121232

122233
## Data Model
@@ -151,62 +262,74 @@ If you would like to add another entity to the APIs, follow these steps:
151262
- Implement the necessary CRUD actions (index, show, create, update, destroy) in the controller.
152263
- Example: `app/controllers/api/v1/customers_controller.rb`
153264

154-
4. Add Swagger documentation:
155-
- Open the `spec/requests/api/v1/customers_spec.rb` file.
265+
4. Add Swagger documentation (for API documentation only):
266+
- Create a new swagger spec file in `spec/requests/swagger/customers_spec.rb`.
156267
- Define the Swagger documentation for the new entity's API endpoints using RSpec and the `rswag` gem.
157-
- Specify the request and response parameters, headers, and schemas for each endpoint.
268+
- These specs should be documentation-only (no actual database operations).
158269
- Example:
159270
```ruby
160271
require 'swagger_helper'
161272
273+
# Documentation-only specs for Swagger/OpenAPI generation
274+
# Actual integration testing done in spec/requests/api/v1/customers_spec.rb
162275
describe 'Customers API', type: :request do
163-
path '/api/v1/customers' do
164-
get 'Retrieves all customers' do
276+
path '/api/v1/customers/{id}' do
277+
get 'Retrieves a customer' do
165278
tags 'Customers'
166279
produces 'application/json'
167-
168-
response '200', 'customers retrieved' do
169-
schema type: :array,
170-
items: {
171-
type: :object,
172-
properties: {
173-
id: { type: :integer },
174-
name: { type: :string },
175-
email: { type: :string }
176-
},
177-
required: ['id', 'name', 'email']
178-
}
179-
180-
run_test!
280+
parameter name: :id, in: :path, type: :string
281+
282+
response '200', 'customer found' do
283+
schema type: :object,
284+
properties: {
285+
name: { type: :string },
286+
email: { type: :string }
287+
},
288+
required: ['name', 'email']
289+
290+
let(:id) { 'customer_123' }
291+
run_test! do |response|
292+
# Documentation-only - actual testing in spec/requests/api/v1/customers_spec.rb
293+
end
181294
end
182295
end
183296
end
184297
end
185298
```
186299

187-
5. Add integration tests:
188-
- Create a new integration test file for the entity in the `test/integration` folder.
189-
- Write integration tests to cover the CRUD operations of the new entity.
190-
- Example: `test/integration/customers_spec.rb`
300+
5. Add integration tests (for actual functionality testing):
301+
- Create a new integration test file for the entity in the `spec/requests/api/v1/` folder.
302+
- Write comprehensive integration tests to verify CRUD operations work correctly.
303+
- Example: `spec/requests/api/v1/customers_spec.rb`
191304
```ruby
192305
require 'rails_helper'
193306
194307
RSpec.describe 'Customers API', type: :request do
195-
describe 'GET /api/v1/customers' do
196-
# Add tests for retrieving customers
308+
describe 'GET /api/v1/customers/{id}' do
309+
it 'returns the customer' do
310+
get '/api/v1/customers/customer_123'
311+
expect(response).to have_http_status(:ok)
312+
# Add more assertions
313+
end
197314
end
198315
199-
describe 'POST /api/v1/customers' do
200-
# Add tests for creating a customer
316+
describe 'POST /api/v1/customers/{id}' do
317+
it 'creates a customer' do
318+
post '/api/v1/customers/customer_new', params: { customer: { name: 'Test', email: '[email protected]' } }
319+
expect(response).to have_http_status(:created)
320+
# Clean up
321+
delete '/api/v1/customers/customer_new'
322+
end
201323
end
202324
203325
# Add more tests for other CRUD operations
204326
end
205327
```
206328

207329
6. Run tests and verify:
208-
- Run the integration tests using the command `bundle exec rspec test/integration`.
209-
- Ensure that all tests pass and the new entity's CRUD operations are working as expected.
330+
- Run the integration tests: `bundle exec rspec spec/requests/api/v1/customers_spec.rb`
331+
- Generate swagger documentation: `bundle exec rake rswag:specs:swaggerize`
332+
- Ensure that all tests pass and the new entity's CRUD operations work correctly.
210333

211334
By following these steps, you can systematically extend the API functionality with a new entity while maintaining a well-structured and tested codebase.
212335

0 commit comments

Comments
 (0)