Skip to content

Commit f6f8da4

Browse files
committed
Merge branch 'feature/unit-tests'
2 parents b2fe602 + ad06f3b commit f6f8da4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2891
-254
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# 🐛 Bug Report / 💡 Feature Request
2+
3+
**Thanks for contributing to the oEmbed Craft CMS plugin!** This template helps us understand issues with the field type, embed functionality, caching, and admin interface.
4+
5+
## 📋 Issue Type
6+
- [ ] 🐛 Bug report
7+
- [ ] 💡 Feature request
8+
- [ ] 📚 Documentation issue
9+
- [ ] ❓ Question/Support
10+
11+
---
12+
13+
## 🔍 **Bug Report** (Skip if feature request)
14+
15+
### What's the issue?
16+
<!-- Clear description of what's wrong -->
17+
18+
### Where does it happen?
19+
- [ ] **Admin CP Field**: Issue in the Craft control panel field interface
20+
- [ ] **Frontend Render**: Problem with `{{ entry.field.render() }}` output
21+
- [ ] **Caching**: Cached content not updating or cache errors
22+
- [ ] **GDPR Compliance**: Issues with privacy settings (YouTube no-cookie, Vimeo DNT, etc.)
23+
- [ ] **Network/Provider**: Provider-specific embed failures
24+
- [ ] **GraphQL**: Issues with GraphQL field queries
25+
26+
### Steps to reproduce
27+
1.
28+
2.
29+
3.
30+
31+
### Expected vs Actual
32+
**Expected:**
33+
**Actual:**
34+
35+
### Your Environment
36+
- **Craft CMS**: <!-- e.g., 4.5.0 -->
37+
- **oEmbed Plugin**: <!-- e.g., 3.1.5 -->
38+
- **PHP**: <!-- e.g., 8.2 -->
39+
- **Provider**: <!-- e.g., YouTube, Vimeo, Instagram, Twitter -->
40+
- **Test URL**: <!-- The URL you're trying to embed -->
41+
42+
---
43+
44+
## 💡 **Feature Request** (Skip if bug report)
45+
46+
### What feature would you like?
47+
<!-- Clear description -->
48+
49+
### What problem does this solve?
50+
<!-- Context about why this is needed -->
51+
52+
### Suggested implementation
53+
<!-- How you think it should work -->
54+
55+
---
56+
57+
## 🔧 Additional Context
58+
59+
### Admin CP Issues (if applicable)
60+
- Field preview not showing?
61+
- Save/validation problems?
62+
- Settings interface issues?
63+
64+
### Frontend Issues (if applicable)
65+
- Template method used: `render()` / `embed()` / `media()` / `valid()`
66+
- Cache enabled/disabled?
67+
- GDPR settings active?
68+
69+
### Provider-Specific Issues
70+
- Does the URL work on the provider's site?
71+
- Using embed URL vs regular URL?
72+
- API tokens configured (for Instagram/Facebook)?
73+
74+
### Error Messages/Screenshots
75+
<!-- Paste any error messages or attach screenshots -->
76+
77+
---
78+
79+
**💡 Pro Tips:**
80+
- Many providers need **embed URLs** not regular URLs (check provider's share → embed option)
81+
- Check your **cache settings** - try disabling cache temporarily to test
82+
- For Instagram: requires Facebook API token in plugin settings
83+
- For GDPR: check if privacy settings are affecting embeds

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# 🚀 Pull Request
2+
3+
**Thanks for contributing to the oEmbed Craft CMS plugin!** Please fill out the sections below to help us review your changes.
4+
5+
## 📝 What does this PR do?
6+
<!-- Brief description of your changes -->
7+
8+
## 🔗 Related Issue
9+
<!-- Link to the issue this PR addresses -->
10+
Fixes #
11+
12+
## 🎯 Type of Change
13+
<!-- Put an `x` in the box that applies -->
14+
- [ ] 🐛 **Bug fix** (fixes an issue without breaking existing functionality)
15+
- [ ]**New feature** (adds functionality without breaking changes)
16+
- [ ] 💥 **Breaking change** (fix/feature that changes existing functionality)
17+
- [ ] 🏗️ **Refactor** (code improvement without functional changes)
18+
- [ ] 📚 **Documentation** (README, comments, or docs)
19+
- [ ] 🧪 **Tests** (adding or updating tests)
20+
21+
## 🧪 Testing
22+
23+
### How did you test this?
24+
<!-- Describe your testing approach -->
25+
- [ ] Added/updated unit tests
26+
- [ ] Tested with multiple embed providers (YouTube, Vimeo, etc.)
27+
- [ ] Tested admin CP field functionality
28+
- [ ] Tested frontend rendering
29+
- [ ] Tested caching behavior
30+
- [ ] Tested GDPR compliance features
31+
- [ ] Manual testing in Craft CMS environment
32+
33+
### Test Environment
34+
- **Craft CMS version**:
35+
- **PHP version**:
36+
- **Tested providers**: <!-- e.g., YouTube, Vimeo, Instagram -->
37+
38+
## ✅ Checklist
39+
<!-- Put an `x` in completed boxes -->
40+
41+
### Code Quality
42+
- [ ] My code follows the existing code style
43+
- [ ] I've added comments where code is complex
44+
- [ ] No new warnings or errors introduced
45+
46+
### Functionality
47+
- [ ] Field works correctly in Craft CP
48+
- [ ] Frontend rendering works as expected
49+
- [ ] Caching behaves properly
50+
- [ ] GDPR settings are respected (if applicable)
51+
- [ ] GraphQL queries work (if applicable)
52+
53+
### Testing & Documentation
54+
- [ ] I've added/updated tests for my changes
55+
- [ ] All existing tests still pass
56+
- [ ] I've updated documentation if needed
57+
- [ ] I've tested edge cases and error scenarios
58+
59+
### Plugin-Specific
60+
- [ ] Handles provider URL variations (embed vs regular URLs)
61+
- [ ] Fallback behavior works for unsupported providers
62+
- [ ] Network/timeout errors are handled gracefully
63+
- [ ] API token requirements documented (if applicable)
64+
65+
## 🔍 Review Focus Areas
66+
<!-- Help reviewers know what to focus on -->
67+
- [ ] **Admin UI**: Changes to the control panel field interface
68+
- [ ] **Template Methods**: Changes to `render()`, `embed()`, `media()`, `valid()` methods
69+
- [ ] **Provider Support**: New or modified provider handling
70+
- [ ] **Caching Logic**: Changes to cache behavior
71+
- [ ] **GDPR Features**: Privacy compliance modifications
72+
- [ ] **Error Handling**: Network/provider failure scenarios
73+
74+
## 📸 Screenshots (if applicable)
75+
<!-- Add screenshots for UI changes -->
76+
77+
## 💭 Additional Notes
78+
<!-- Any other context, concerns, or questions for reviewers -->
79+
80+
---
81+
82+
**🔄 Ready for Review?** Make sure all tests pass and the CI checks are green!

.github/workflows/tests.yml

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
name: Tests
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- 'master'
7+
- 'v*'
8+
push:
9+
branches:
10+
- 'master'
11+
- 'v*'
12+
13+
jobs:
14+
craft5-tests:
15+
if: github.ref == 'refs/heads/master' || github.base_ref == 'master'
16+
runs-on: ubuntu-latest
17+
18+
services:
19+
postgres:
20+
image: postgres:13-alpine
21+
env:
22+
POSTGRES_USER: postgres
23+
POSTGRES_PASSWORD: postgres
24+
POSTGRES_DB: postgres
25+
ports:
26+
- 5432:5432
27+
options: >-
28+
--health-cmd pg_isready
29+
--health-interval 10s
30+
--health-timeout 5s
31+
--health-retries 5
32+
33+
strategy:
34+
matrix:
35+
php: [8.2, 8.3]
36+
37+
name: Craft 5.x - PHP ${{ matrix.php }} Tests
38+
39+
steps:
40+
- uses: actions/checkout@v4
41+
42+
- name: Setup PHP
43+
uses: shivammathur/setup-php@v2
44+
with:
45+
php-version: ${{ matrix.php }}
46+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, pdo_pgsql, bcmath, soap, intl, gd, exif, iconv
47+
coverage: xdebug
48+
49+
- name: Cache Composer packages
50+
id: composer-cache
51+
uses: actions/cache@v3
52+
with:
53+
path: vendor
54+
key: craft5-${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
55+
restore-keys: |
56+
craft5-${{ runner.os }}-php-${{ matrix.php }}-
57+
58+
- name: Install dependencies
59+
run: composer install --prefer-dist --no-progress --dev
60+
61+
- name: Setup test environment
62+
run: |
63+
cp tests/.env.example tests/.env
64+
sed -i 's/host=postgres/host=localhost/' tests/.env
65+
mkdir -p tests/_craft/storage/runtime
66+
mkdir -p tests/_craft/storage/logs
67+
mkdir -p tests/_craft/storage/config-deltas
68+
mkdir -p tests/_craft/migrations
69+
mkdir -p tests/_output
70+
71+
- name: Build Codeception
72+
run: vendor/bin/codecept build
73+
74+
- name: Run all tests
75+
run: vendor/bin/codecept run --coverage --coverage-xml
76+
env:
77+
DB_DSN: "pgsql:host=localhost;port=5432;dbname=postgres"
78+
DB_USER: postgres
79+
DB_PASSWORD: postgres
80+
DB_SCHEMA: public
81+
DB_TABLE_PREFIX: craft
82+
CRAFT_SECURITY_KEY: test-security-key-for-github-actions
83+
84+
- name: Upload coverage reports to Codecov
85+
uses: codecov/codecov-action@v3
86+
if: matrix.php == '8.2'
87+
with:
88+
files: ./tests/_output/coverage.xml
89+
fail_ci_if_error: false
90+
verbose: true
91+
92+
craft4-tests:
93+
if: github.ref == 'refs/heads/v2' || github.base_ref == 'v2'
94+
runs-on: ubuntu-latest
95+
96+
strategy:
97+
matrix:
98+
php: [8.0, 8.1, 8.2]
99+
100+
name: Craft 4.x - PHP ${{ matrix.php }} Tests
101+
102+
steps:
103+
- uses: actions/checkout@v4
104+
105+
- name: Setup PHP
106+
uses: shivammathur/setup-php@v2
107+
with:
108+
php-version: ${{ matrix.php }}
109+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv
110+
coverage: xdebug
111+
112+
- name: Cache Composer packages
113+
id: composer-cache
114+
uses: actions/cache@v3
115+
with:
116+
path: vendor
117+
key: craft4-${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
118+
restore-keys: |
119+
craft4-${{ runner.os }}-php-${{ matrix.php }}-
120+
121+
- name: Install dependencies
122+
run: composer install --prefer-dist --no-progress --dev
123+
124+
- name: Build Codeception (if exists)
125+
run: |
126+
if [ -f "vendor/bin/codecept" ]; then
127+
vendor/bin/codecept build
128+
fi
129+
130+
- name: Run unit tests (if exists)
131+
run: |
132+
if [ -f "vendor/bin/codecept" ]; then
133+
vendor/bin/codecept run unit
134+
else
135+
echo "No tests configured for this branch"
136+
fi
137+
138+
code-quality:
139+
runs-on: ubuntu-latest
140+
name: Code Quality
141+
142+
steps:
143+
- uses: actions/checkout@v4
144+
145+
- name: Setup PHP
146+
uses: shivammathur/setup-php@v2
147+
with:
148+
php-version: 8.2
149+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv
150+
151+
- name: Install dependencies
152+
run: composer install --prefer-dist --no-progress --dev
153+
154+
- name: Check PHP syntax
155+
run: find src tests -name "*.php" -exec php -l {} \;

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ Thumbs.db
1111
.idea
1212
node_modules
1313
npm-debug.log
14-
yarn-error.log
14+
yarn-error.log
15+
16+
17+
# Claude AI ignore files
18+
todo.md
19+
.claude/settings.local.json

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
11
# oEmbed Changelog
22

3+
## 3.2.0 - 2026-01-14
4+
5+
### Fixed
6+
7+
- Broken URL notifications now include the invalid URL (fixes #170)
8+
- GraphQL TypeError when querying entries with empty oEmbed URLs (fixes #156)
9+
- Cookie file accumulation via automatic cleanup (fixes #152)
10+
11+
### Added
12+
13+
- Docker-based test environment with PostgreSQL
14+
- Codeception + Craft CMS testing integration
15+
- Unit + functional tests across services, models, jobs, and providers
16+
- CI pipeline for automated testing and coverage reporting
17+
18+
### Improved
19+
20+
- Defensive validation with XSS protection in notifications
21+
- URL normalization at entry points to prevent null/empty URL issues
22+
- Configurable cookie cleanup with console command and throttling
23+
24+
## 3.1.7 - 2025-08-30
25+
26+
### Fixed
27+
28+
- Fixed broken URL email notifications not including the invalid URL in the message. Resolves [#170](https://github.com/wrav/oembed/issues/170)
29+
- Fixed GraphQL error when querying entries with empty oEmbed URLs. Resolves [#156](https://github.com/wrav/oembed/issues/156)
30+
- Fixed cookie file accumulation issue where embed-cookie files were not being cleaned up. Resolves [#152](https://github.com/wrav/oembed/issues/152)
31+
- Added comprehensive validation to prevent empty or null URLs from causing notification issues
32+
- Enhanced email template with better formatting and XSS protection
33+
- Added debug logging for broken URL notification system to aid troubleshooting
34+
- Fixed TypeError in generateCacheKey() when processing null URLs from GraphQL queries
35+
- Implemented automatic cookie cleanup system with configurable cleanup intervals and file age limits
36+
37+
### Added
38+
39+
- Added unit tests for broken URL notification system
40+
- Added validation layers across the notification flow (service → event → job)
41+
- Added comprehensive unit tests for OembedModel null URL handling
42+
- Added URL normalization at entry points (model constructor and service method)
43+
- Added cookie cleanup console command (`php craft oembed/cookie/cleanup`)
44+
- Added cookie cleanup settings: `enableCookieCleanup`, `cookieMaxAge`, and `cookiesPath`
45+
- Added automatic cookie cleanup on plugin initialization with throttling to prevent performance impact
46+
- Added comprehensive unit tests for cookie cleanup functionality
47+
348
## 3.1.6 - 2025-08-08
449

550
### Fixed

0 commit comments

Comments
 (0)