Skip to content

Commit fe4e78d

Browse files
committed
Remove obsolete specs for Html2rss::Web components including AutoSource, HealthCheck, HttpCache, LocalConfig, RackAttack, SecurityLogger, SsrfFilterStrategy, and XmlBuilder. These tests are no longer relevant to the current implementation.
1 parent 4a76538 commit fe4e78d

40 files changed

+1322
-2535
lines changed

CONFIGURATION.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
### Health Check Configuration
1616

17-
| Variable | Description | Default | Example |
18-
| -------------------- | ------------------ | ----------- | --------------------------- |
19-
| `HEALTH_CHECK_TOKEN` | Health check token | From config | `health-check-token-xyz789` |
17+
Health check authentication relies on the `health-check` account defined in `config/feeds.yml`. Expose the token via an environment variable and send it as a Bearer token when calling `/health_check.txt` or `/api/v1/health`.
2018

21-
**Note:** Health check authentication now uses Bearer token authentication instead of username/password. The token is configured in `config/feeds.yml` under the `health-check` account.
19+
| Variable | Description | Default | Example |
20+
| -------------------- | -------------------------------------------- | --------------------------- | --------------------------- |
21+
| `HEALTH_CHECK_TOKEN` | Token forwarded to the container health check | `health-check-token-xyz789` | `health-check-token-xyz789` |
2222

2323
### Ruby Integration
2424

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ SHELL ["/bin/ash", "-o", "pipefail", "-c"]
4040

4141
ENV PORT=3000 \
4242
RACK_ENV=production \
43-
RUBY_YJIT_ENABLE=1
43+
RUBY_YJIT_ENABLE=1 \
44+
HEALTH_CHECK_TOKEN=health-check-token-xyz789
4445

4546
EXPOSE $PORT
4647

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ test-frontend: ## Run frontend tests only
4848
test-frontend-unit: ## Run frontend unit tests only
4949
@cd frontend && npm run test:unit
5050

51-
test-frontend-integration: ## Run frontend integration tests only
52-
@cd frontend && npm run test:integration
51+
test-frontend-contract: ## Run frontend contract tests only
52+
@cd frontend && npm run test:contract
53+
54+
test-frontend-smoke: ## Run frontend smoke tests (Playwright)
55+
@cd frontend && npm run test:smoke
5356

5457
lint: lint-ruby lint-js ## Run all linters (Ruby + Frontend) - errors when issues found
5558
@echo "All linting complete!"

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,10 @@ The project includes a modern Astro frontend alongside the Ruby backend:
200200
| `make dev-frontend` | Start Astro dev server only |
201201
| `make test` | Run all tests (Ruby + Frontend) |
202202
| `make test-ruby` | Run Ruby tests only |
203-
| `make test-frontend` | Run frontend tests only |
203+
| `make test-frontend` | Run frontend unit + contract tests |
204+
| `make test-frontend-unit` | Run frontend unit tests only |
205+
| `make test-frontend-contract` | Run frontend contract tests (Vitest + MSW) |
206+
| `make test-frontend-smoke` | Run frontend smoke tests (Playwright) |
204207
| `make lint` | Run all linters (Ruby + Frontend) |
205208
| `make lint-ruby` | Run Ruby linter only |
206209
| `make lint-js` | Run frontend linter only |
@@ -216,6 +219,25 @@ The project includes a modern Astro frontend alongside the Ruby backend:
216219
| `cd frontend && npm install` | Install frontend dependencies |
217220
| `cd frontend && npm run dev` | Start frontend dev server |
218221
| `cd frontend && npm run build` | Build frontend for production |
222+
| `cd frontend && npm run test:unit` | Run unit tests (Vitest) |
223+
| `cd frontend && npm run test:contract` | Run contract tests with MSW |
224+
| `cd frontend && npm run test:smoke` | Run Playwright smoke tests |
225+
226+
### Testing Strategy
227+
228+
| Layer | Tooling | Notes |
229+
| ---------------- | -------------------------- | ----- |
230+
| Ruby API | RSpec + Rack::Test | Deterministic request specs for the Roda app |
231+
| Frontend Unit | Vitest + Testing Library | Hook/component behaviour with mocked fetch |
232+
| Frontend Contract| Vitest + MSW | Exercises real fetch flows against mocked API responses |
233+
| Smoke | Playwright | Minimal API smoke checks via the real Puma server |
234+
235+
To execute Playwright smoke tests locally for the first time, install the required browsers:
236+
237+
```bash
238+
cd frontend
239+
npx playwright install --with-deps
240+
```
219241

220242
## Contributing
221243

Rakefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ task :test do
4040
'-d',
4141
'-p 3000:3000',
4242
'--env PUMA_LOG_CONFIG=1',
43-
'--env HEALTH_CHECK_USERNAME=username',
44-
'--env HEALTH_CHECK_PASSWORD=password',
43+
'--env HEALTH_CHECK_TOKEN=health-check-token-xyz789',
4544
"--mount type=bind,source=#{current_dir}/config,target=/app/config",
4645
'--name html2rss-web-test',
4746
'gilcreator/html2rss-web'].join(' ')
@@ -57,8 +56,12 @@ task :test do
5756
Output.describe 'Generating example feed from feeds.yml'
5857
sh 'curl -f http://127.0.0.1:3000/example.rss || exit 1'
5958

60-
Output.describe 'Authenticated request to GET /health_check.txt'
61-
sh 'docker exec html2rss-web-test curl -f http://username:password@127.0.0.1:3000/health_check.txt || exit 1'
59+
Output.describe 'Health check endpoint'
60+
sh <<~COMMAND
61+
docker exec html2rss-web-test curl -f \
62+
-H "Authorization: Bearer health-check-token-xyz789" \
63+
http://127.0.0.1:3000/health_check.txt || exit 1
64+
COMMAND
6265

6366
# skipped as html2rss is used in development version
6467
# Output.describe 'Print output of `html2rss help`'

app.rb

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ def development? = self.class.development?
176176
# Skip static file requests
177177
next if feed_name.include?('.') && !feed_name.end_with?('.xml', '.rss')
178178

179-
# Route to feed generation without auth for backward compatibility
180179
handle_feed_generation(r, feed_name)
181180
end
182181
r.get 'health_check.txt' do
@@ -202,24 +201,48 @@ def handle_feed_generation(router, feed_name)
202201
def handle_health_check(router)
203202
router.response['Content-Type'] = 'text/plain'
204203

205-
health_response = Api::V1::Health.show(router)
206-
207-
raise 'unhealthy' unless health_response[:success] && health_response.dig(:data, :health, :status) == 'healthy'
204+
verify_health_check_authorization!(router)
205+
verify_health_status!
208206

209207
'success'
208+
rescue UnauthorizedError => error
209+
router.response.status = 401
210+
error.message
210211
rescue StandardError => error
211212
router.response.status = 500
212213

213214
"health check error: #{error.message}"
214215
end
215216

217+
def verify_health_check_authorization!(router)
218+
health_account = HealthCheck.find_health_check_account
219+
account = Auth.authenticate(router)
220+
221+
return if authorized_health_check_account?(account, health_account)
222+
223+
raise UnauthorizedError, 'health check requires bearer token'
224+
end
225+
226+
def authorized_health_check_account?(account, health_account)
227+
account && health_account &&
228+
account[:username] == health_account[:username] &&
229+
account[:token] == health_account[:token]
230+
end
231+
232+
def verify_health_status!
233+
return if HealthCheck.run == 'success'
234+
235+
raise 'unhealthy'
236+
end
237+
216238
def fallback_html
217239
<<~HTML
218240
<!DOCTYPE html>
219241
<html>
220242
<head>
221243
<title>html2rss-web</title>
222244
<meta name="viewport" content="width=device-width,initial-scale=1">
245+
<meta name="robots" content="noindex,nofollow">
223246
</head>
224247
<body>
225248
<h1>html2rss-web</h1>

app/api/v1/feeds.rb

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,8 @@ module V1
1616
module Feeds
1717
module_function
1818

19-
def index(_request) # rubocop:disable Metrics/MethodLength
20-
feeds = Html2rss::Web::Feeds.list_feeds.map do |feed|
21-
{
22-
id: feed[:name],
23-
name: feed[:name],
24-
description: feed[:description],
25-
public_url: "/#{feed[:name]}",
26-
created_at: nil,
27-
updated_at: nil
28-
}
29-
end
30-
19+
def index(_request)
20+
feeds = Html2rss::Web::Feeds.list_feeds
3121
{ success: true, data: { feeds: feeds }, meta: { total: feeds.count } }
3222
end
3323

@@ -131,6 +121,9 @@ def build_create_response(request, feed_data)
131121
updated_at: Time.now.iso8601
132122
} }, meta: { created: true } }
133123
end
124+
module_function :extract_create_params, :validate_create_params, :build_create_response, :authenticate_request
125+
private_class_method :extract_create_params, :validate_create_params, :build_create_response,
126+
:authenticate_request
134127
end
135128
end
136129
end

app/feeds.rb

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
require_relative 'auth'
66
require_relative 'local_config'
7-
require_relative 'xml_builder'
87

98
module Html2rss
109
module Web
@@ -16,26 +15,20 @@ module Feeds
1615
def list_feeds
1716
LocalConfig.feed_names.map do |name|
1817
{
19-
name: name,
20-
url: "/api/#{name}",
21-
description: "RSS feed for #{name}"
18+
id: name.to_s,
19+
name: name.to_s,
20+
description: "RSS feed for #{name}",
21+
public_url: "/#{name}"
2222
}
2323
end
2424
end
2525

2626
def generate_feed(feed_name, params = {})
2727
config = LocalConfig.find(feed_name)
28-
2928
config[:params] = (config[:params] || {}).merge(params) if params.any?
30-
3129
config[:strategy] ||= Html2rss::RequestService.default_strategy_name
32-
3330
Html2rss.feed(config)
3431
end
35-
36-
def error_feed(message)
37-
XmlBuilder.build_error_feed(message: message)
38-
end
3932
end
4033
end
4134
end

0 commit comments

Comments
 (0)