Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
77cd193
feat: Added unit testing setup
reganlawton Dec 10, 2024
efd503b
Merge remote-tracking branch 'origin/master' into feature/unit-tests
reganlawton Dec 10, 2024
c713867
Merge branch 'master' into feature/unit-tests
reganlawton Jul 29, 2025
78a6609
test: Update Instagram and Vimeo tests for embed URLs
reganlawton Jul 29, 2025
baff042
docs: Add CLAUDE.md for project guidance and development instructions
reganlawton Jul 29, 2025
c5401b3
docs: Update CLAUDE.md and ISSUE_TEMPLATE.md for Docker setup and tes…
reganlawton Jul 29, 2025
855cdee
test: Add extended unit tests for twig and service code to be more te…
reganlawton Jul 30, 2025
23b4362
fix: Improve broken URL email notifications with validation and logging
reganlawton Jul 30, 2025
ab74cfc
fix: Resolve GraphQL TypeError with empty oEmbed URLs
reganlawton Jul 30, 2025
d5e5c07
fix: Implement cookie file cleanup system to prevent storage accumula…
reganlawton Jul 30, 2025
164fb4e
Merge branch 'master' into feature/unit-tests
reganlawton Sep 8, 2025
bb5b174
chore: Bump version to 3.1.7 in composer.json
reganlawton Sep 8, 2025
00f7bfc
refactor: unify test cases with new `EmbedTestCase` and enhance mock …
reganlawton Jan 14, 2026
74a155b
test: add integration test for embedded media rendering with entry fi…
reganlawton Jan 14, 2026
11acf01
ci: restructure workflows to support Craft 4.x and 5.x tests with mat…
reganlawton Jan 14, 2026
3b99977
release: v3.2.0 with enhanced CI matrix, new test suite, and template…
reganlawton Jan 14, 2026
ad06f3b
release: update CHANGELOG for v3.2.0 with fixes, improvements, and ne…
reganlawton Jan 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 🐛 Bug Report / 💡 Feature Request

**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.

## 📋 Issue Type
- [ ] 🐛 Bug report
- [ ] 💡 Feature request
- [ ] 📚 Documentation issue
- [ ] ❓ Question/Support

---

## 🔍 **Bug Report** (Skip if feature request)

### What's the issue?
<!-- Clear description of what's wrong -->

### Where does it happen?
- [ ] **Admin CP Field**: Issue in the Craft control panel field interface
- [ ] **Frontend Render**: Problem with `{{ entry.field.render() }}` output
- [ ] **Caching**: Cached content not updating or cache errors
- [ ] **GDPR Compliance**: Issues with privacy settings (YouTube no-cookie, Vimeo DNT, etc.)
- [ ] **Network/Provider**: Provider-specific embed failures
- [ ] **GraphQL**: Issues with GraphQL field queries

### Steps to reproduce
1.
2.
3.

### Expected vs Actual
**Expected:**
**Actual:**

### Your Environment
- **Craft CMS**: <!-- e.g., 4.5.0 -->
- **oEmbed Plugin**: <!-- e.g., 3.1.5 -->
- **PHP**: <!-- e.g., 8.2 -->
- **Provider**: <!-- e.g., YouTube, Vimeo, Instagram, Twitter -->
- **Test URL**: <!-- The URL you're trying to embed -->

---

## 💡 **Feature Request** (Skip if bug report)

### What feature would you like?
<!-- Clear description -->

### What problem does this solve?
<!-- Context about why this is needed -->

### Suggested implementation
<!-- How you think it should work -->

---

## 🔧 Additional Context

### Admin CP Issues (if applicable)
- Field preview not showing?
- Save/validation problems?
- Settings interface issues?

### Frontend Issues (if applicable)
- Template method used: `render()` / `embed()` / `media()` / `valid()`
- Cache enabled/disabled?
- GDPR settings active?

### Provider-Specific Issues
- Does the URL work on the provider's site?
- Using embed URL vs regular URL?
- API tokens configured (for Instagram/Facebook)?

### Error Messages/Screenshots
<!-- Paste any error messages or attach screenshots -->

---

**💡 Pro Tips:**
- Many providers need **embed URLs** not regular URLs (check provider's share → embed option)
- Check your **cache settings** - try disabling cache temporarily to test
- For Instagram: requires Facebook API token in plugin settings
- For GDPR: check if privacy settings are affecting embeds
82 changes: 82 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# 🚀 Pull Request

**Thanks for contributing to the oEmbed Craft CMS plugin!** Please fill out the sections below to help us review your changes.

## 📝 What does this PR do?
<!-- Brief description of your changes -->

## 🔗 Related Issue
<!-- Link to the issue this PR addresses -->
Fixes #

## 🎯 Type of Change
<!-- Put an `x` in the box that applies -->
- [ ] 🐛 **Bug fix** (fixes an issue without breaking existing functionality)
- [ ] ✨ **New feature** (adds functionality without breaking changes)
- [ ] 💥 **Breaking change** (fix/feature that changes existing functionality)
- [ ] 🏗️ **Refactor** (code improvement without functional changes)
- [ ] 📚 **Documentation** (README, comments, or docs)
- [ ] 🧪 **Tests** (adding or updating tests)

## 🧪 Testing

### How did you test this?
<!-- Describe your testing approach -->
- [ ] Added/updated unit tests
- [ ] Tested with multiple embed providers (YouTube, Vimeo, etc.)
- [ ] Tested admin CP field functionality
- [ ] Tested frontend rendering
- [ ] Tested caching behavior
- [ ] Tested GDPR compliance features
- [ ] Manual testing in Craft CMS environment

### Test Environment
- **Craft CMS version**:
- **PHP version**:
- **Tested providers**: <!-- e.g., YouTube, Vimeo, Instagram -->

## ✅ Checklist
<!-- Put an `x` in completed boxes -->

### Code Quality
- [ ] My code follows the existing code style
- [ ] I've added comments where code is complex
- [ ] No new warnings or errors introduced

### Functionality
- [ ] Field works correctly in Craft CP
- [ ] Frontend rendering works as expected
- [ ] Caching behaves properly
- [ ] GDPR settings are respected (if applicable)
- [ ] GraphQL queries work (if applicable)

### Testing & Documentation
- [ ] I've added/updated tests for my changes
- [ ] All existing tests still pass
- [ ] I've updated documentation if needed
- [ ] I've tested edge cases and error scenarios

### Plugin-Specific
- [ ] Handles provider URL variations (embed vs regular URLs)
- [ ] Fallback behavior works for unsupported providers
- [ ] Network/timeout errors are handled gracefully
- [ ] API token requirements documented (if applicable)

## 🔍 Review Focus Areas
<!-- Help reviewers know what to focus on -->
- [ ] **Admin UI**: Changes to the control panel field interface
- [ ] **Template Methods**: Changes to `render()`, `embed()`, `media()`, `valid()` methods
- [ ] **Provider Support**: New or modified provider handling
- [ ] **Caching Logic**: Changes to cache behavior
- [ ] **GDPR Features**: Privacy compliance modifications
- [ ] **Error Handling**: Network/provider failure scenarios

## 📸 Screenshots (if applicable)
<!-- Add screenshots for UI changes -->

## 💭 Additional Notes
<!-- Any other context, concerns, or questions for reviewers -->

---

**🔄 Ready for Review?** Make sure all tests pass and the CI checks are green!
155 changes: 155 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: Tests

on:
pull_request:
branches:
- 'master'
- 'v*'
push:
branches:
- 'master'
- 'v*'

jobs:
craft5-tests:
if: github.ref == 'refs/heads/master' || github.base_ref == 'master'
runs-on: ubuntu-latest

services:
postgres:
image: postgres:13-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

strategy:
matrix:
php: [8.2, 8.3]

name: Craft 5.x - PHP ${{ matrix.php }} Tests

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, pdo_pgsql, bcmath, soap, intl, gd, exif, iconv
coverage: xdebug

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: craft5-${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
craft5-${{ runner.os }}-php-${{ matrix.php }}-

- name: Install dependencies
run: composer install --prefer-dist --no-progress --dev

- name: Setup test environment
run: |
cp tests/.env.example tests/.env
sed -i 's/host=postgres/host=localhost/' tests/.env
mkdir -p tests/_craft/storage/runtime
mkdir -p tests/_craft/storage/logs
mkdir -p tests/_craft/storage/config-deltas
mkdir -p tests/_craft/migrations
mkdir -p tests/_output

- name: Build Codeception
run: vendor/bin/codecept build

- name: Run all tests
run: vendor/bin/codecept run --coverage --coverage-xml
env:
DB_DSN: "pgsql:host=localhost;port=5432;dbname=postgres"
DB_USER: postgres
DB_PASSWORD: postgres
DB_SCHEMA: public
DB_TABLE_PREFIX: craft
CRAFT_SECURITY_KEY: test-security-key-for-github-actions

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
if: matrix.php == '8.2'
with:
files: ./tests/_output/coverage.xml
fail_ci_if_error: false
verbose: true

craft4-tests:
if: github.ref == 'refs/heads/v2' || github.base_ref == 'v2'
runs-on: ubuntu-latest

strategy:
matrix:
php: [8.0, 8.1, 8.2]

name: Craft 4.x - PHP ${{ matrix.php }} Tests

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv
coverage: xdebug

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: craft4-${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
craft4-${{ runner.os }}-php-${{ matrix.php }}-

- name: Install dependencies
run: composer install --prefer-dist --no-progress --dev

- name: Build Codeception (if exists)
run: |
if [ -f "vendor/bin/codecept" ]; then
vendor/bin/codecept build
fi

- name: Run unit tests (if exists)
run: |
if [ -f "vendor/bin/codecept" ]; then
vendor/bin/codecept run unit
else
echo "No tests configured for this branch"
fi

code-quality:
runs-on: ubuntu-latest
name: Code Quality

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv

- name: Install dependencies
run: composer install --prefer-dist --no-progress --dev

- name: Check PHP syntax
run: find src tests -name "*.php" -exec php -l {} \;
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ Thumbs.db
.idea
node_modules
npm-debug.log
yarn-error.log
yarn-error.log


# Claude AI ignore files
todo.md
.claude/settings.local.json
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,50 @@
# oEmbed Changelog

## 3.2.0 - 2026-01-14

### Fixed

- Broken URL notifications now include the invalid URL (fixes #170)
- GraphQL TypeError when querying entries with empty oEmbed URLs (fixes #156)
- Cookie file accumulation via automatic cleanup (fixes #152)

### Added

- Docker-based test environment with PostgreSQL
- Codeception + Craft CMS testing integration
- Unit + functional tests across services, models, jobs, and providers
- CI pipeline for automated testing and coverage reporting

### Improved

- Defensive validation with XSS protection in notifications
- URL normalization at entry points to prevent null/empty URL issues
- Configurable cookie cleanup with console command and throttling

## 3.1.7 - 2025-08-30

### Fixed

- Fixed broken URL email notifications not including the invalid URL in the message. Resolves [#170](https://github.com/wrav/oembed/issues/170)
- Fixed GraphQL error when querying entries with empty oEmbed URLs. Resolves [#156](https://github.com/wrav/oembed/issues/156)
- Fixed cookie file accumulation issue where embed-cookie files were not being cleaned up. Resolves [#152](https://github.com/wrav/oembed/issues/152)
- Added comprehensive validation to prevent empty or null URLs from causing notification issues
- Enhanced email template with better formatting and XSS protection
- Added debug logging for broken URL notification system to aid troubleshooting
- Fixed TypeError in generateCacheKey() when processing null URLs from GraphQL queries
- Implemented automatic cookie cleanup system with configurable cleanup intervals and file age limits

### Added

- Added unit tests for broken URL notification system
- Added validation layers across the notification flow (service → event → job)
- Added comprehensive unit tests for OembedModel null URL handling
- Added URL normalization at entry points (model constructor and service method)
- Added cookie cleanup console command (`php craft oembed/cookie/cleanup`)
- Added cookie cleanup settings: `enableCookieCleanup`, `cookieMaxAge`, and `cookiesPath`
- Added automatic cookie cleanup on plugin initialization with throttling to prevent performance impact
- Added comprehensive unit tests for cookie cleanup functionality

## 3.1.6 - 2025-08-08

### Fixed
Expand Down
Loading