From 77cd193fcdd81185314311ae4754a6679c83368b Mon Sep 17 00:00:00 2001 From: reganlawton Date: Tue, 10 Dec 2024 14:56:41 +1100 Subject: [PATCH 1/9] feat: Added unit testing setup --- .github/ISSUE_TEMPLATE.md | 29 +++++++++ .github/PULL_REQUEST_TEMPLATE.md | 64 +++++++++++++++++++ .github/workflows/pull-request-tests.yml | 72 ++++++++++++++++++++++ .gitignore | 11 ++++ README.md | 34 +++++++++- codeception.yml | 32 ++++++++++ composer.json | 9 ++- docker-compose.yml | 26 ++++++++ src/templates/settings.twig | 3 + tests/.env.example | 9 +++ tests/.gitignore | 1 + tests/_bootstrap.php | 19 ++++++ tests/_craft/.gitignore | 2 + tests/_craft/config/db.php | 9 +++ tests/_craft/config/test.php | 5 ++ tests/_craft/templates/index.twig | 1 + tests/_data/.gitkeep | 0 tests/_output/.gitignore | 2 + tests/_support/.gitignore | 1 + tests/_support/FunctionalTester.php | 26 ++++++++ tests/_support/Helper/Functional.php | 17 +++++ tests/_support/Helper/Unit.php | 16 +++++ tests/_support/UnitTester.php | 26 ++++++++ tests/functional.suite.yml | 13 ++++ tests/functional/ExampleFunctionalCest.php | 17 +++++ tests/unit.suite.yml | 16 +++++ tests/unit/PluginInstanceUnitTest.php | 28 +++++++++ tests/unit/_bootstrap.php | 1 + tests/unit/embeds/InstagramTest.php | 44 +++++++++++++ tests/unit/embeds/TwitterTest.php | 31 ++++++++++ tests/unit/embeds/VimeoTest.php | 38 ++++++++++++ tests/unit/embeds/YoutubeTest.php | 38 ++++++++++++ 32 files changed, 635 insertions(+), 5 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/pull-request-tests.yml mode change 100755 => 100644 README.md create mode 100644 codeception.yml create mode 100644 docker-compose.yml create mode 100644 tests/.env.example create mode 100644 tests/.gitignore create mode 100644 tests/_bootstrap.php create mode 100644 tests/_craft/.gitignore create mode 100644 tests/_craft/config/db.php create mode 100644 tests/_craft/config/test.php create mode 100644 tests/_craft/templates/index.twig create mode 100644 tests/_data/.gitkeep create mode 100644 tests/_output/.gitignore create mode 100644 tests/_support/.gitignore create mode 100644 tests/_support/FunctionalTester.php create mode 100644 tests/_support/Helper/Functional.php create mode 100644 tests/_support/Helper/Unit.php create mode 100644 tests/_support/UnitTester.php create mode 100644 tests/functional.suite.yml create mode 100644 tests/functional/ExampleFunctionalCest.php create mode 100644 tests/unit.suite.yml create mode 100644 tests/unit/PluginInstanceUnitTest.php create mode 100644 tests/unit/_bootstrap.php create mode 100644 tests/unit/embeds/InstagramTest.php create mode 100644 tests/unit/embeds/TwitterTest.php create mode 100644 tests/unit/embeds/VimeoTest.php create mode 100644 tests/unit/embeds/YoutubeTest.php diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..d4b45a0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,29 @@ +# Issue Template + +## Description + + +## Steps to Reproduce (Bug Reports) + +1. +2. +3. + +## Expected Behavior + + +## Actual Behavior + + +## Environment (Bug Reports) + +- Browser: [e.g., Chrome, Firefox, Safari] +- CraftCMS version: [e.g., 4.x] +- PHP version: [e.g., 8.2] +- Other relevant information: + +## Possible Solution (Optional) + + +## Additional Context + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..28e38d9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,64 @@ +# Pull Request + +Please fill out the fields below to help us review your pull request. + +## Description + + +## Related Issue + + +## Motivation and Context + + +## How Has This Been Tested? + + +## Screenshots (if appropriate): + + +## Types of changes + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Documentation update +- [ ] Other (please describe): +- [ ] Refactor +- [ ] Build related changes +- [ ] CI related changes +- [ ] Test related changes +- [ ] Performance related changes +- [ ] Security related changes +- [ ] Dependency related changes +- [ ] License related changes +- [ ] Code style changes (formatting, renaming) +- [ ] Other (please describe): +- [ ] None of the above + +## Checklist: + +- [ ] My code follows the code style of this project. +- [ ] My change requires a change to the documentation. +- [ ] I have updated the documentation accordingly. +- [ ] I have read the **CONTRIBUTING** document. +- [ ] I have added tests to cover my changes. +- [ ] All new and existing tests passed. +- [ ] My changes generate no new warnings. +- [ ] I have updated the **README**. + +## Reviewer Checklist: + +- [ ] The code is well written and easy to understand. +- [ ] The code is commented where necessary. +- [ ] The code is well documented. +- [ ] The code is efficient and performs well. +- [ ] The code is secure and free of vulnerabilities. +- [ ] The code is scalable and can handle large amounts of data. +- [ ] The code is reliable and robust. +- [ ] The code is maintainable and can be easily updated. +- [ ] The code is tested and all tests pass. +- [ ] The code is well organized and follows best practices. + +## Additional Comments: + diff --git a/.github/workflows/pull-request-tests.yml b/.github/workflows/pull-request-tests.yml new file mode 100644 index 0000000..564e88b --- /dev/null +++ b/.github/workflows/pull-request-tests.yml @@ -0,0 +1,72 @@ +name: Pull Request Tests + +on: + pull_request: + branches: + - 'master' + +jobs: + test: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:latest + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + ports: + - 5432:5432 + options: >- + --health-cmd="pg_isready -U postgres" + --health-interval=10s + --health-timeout=5s + --health-retries=5 + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + extensions: pgsql, pdo_pgsql, xdebug + coverage: xdebug + + - name: Cache Composer Dependencies + uses: actions/cache@v3 + with: + path: ~/.composer/cache + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Install Dependencies + run: composer install --no-progress --no-suggest + + - name: Wait for PostgreSQL + run: | + until pg_isready -h localhost -p 5432 -U postgres; do + echo "Waiting for PostgreSQL to be ready..." + sleep 1 + done + + - name: Run Tests + run: vendor/bin/codecept run + + - name: Run Tests with Coverage + env: + CODECLIMATE_TEST_REPORTER_ID: ${{ secrets.CODECLIMATE_TEST_REPORTER_ID }} + run: | + vendor/bin/codecept run --coverage --coverage-xml + + - name: Upload Coverage to Code Climate + env: + CODECLIMATE_TEST_REPORTER_ID: ${{ secrets.CODECLIMATE_TEST_REPORTER_ID }} + run: | + curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + chmod +x ./cc-test-reporter + ./cc-test-reporter before-build + ./cc-test-reporter format-coverage --input-type clover tests/_output/coverage.xml + ./cc-test-reporter upload-coverage \ No newline at end of file diff --git a/.gitignore b/.gitignore index e5294f4..b82e28c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,14 @@ +# Composer vendor composer.lock + +# CraftCms test specific +cpresources + +# Misc .DS_Store +Thumbs.db +.idea +node_modules +npm-debug.log +yarn-error.log \ No newline at end of file diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 128b538..66689b1 --- a/README.md +++ b/README.md @@ -24,12 +24,18 @@ A simple plugin to extract media information from websites, like youtube videos, twitter statuses or blog articles. +## Seeking a New Maintainer + +It's been nearly nine years since I released the first version of Oembed. While it's been an incredible journey, I no longer have the time or energy to actively maintain the project. Since 2019, I've been deeply involved in building a data and analytics startup, which has grown significantly and now demands most of my focus. + +To keep this library alive and thriving, I'm looking for someone passionate about its future to take over its maintenance and development. If you're interested, please reach out by opening an issue or contacting me directly. + +In the meantime, I’ll continue merging pull requests from the community to ensure the project doesn’t stagnate, though I won’t be actively contributing new features or updates. Thank you for your support over the years! + ## Requirements This plugin requires Craft CMS 3.0.0-beta.23 or later. -If use are looking for CraftCMS 2.5 support use previous project [version 1.0.4](https://github.com/hut6/oembed/tree/1.0.4), which is the latest release for CraftCMS 2.5. - ## Versions | Version | CraftCMS Version | Embed Version | PHP Version | Branch | Status | @@ -38,7 +44,6 @@ If use are looking for CraftCMS 2.5 support use previous project [version 1.0.4] | v2 | ^4.0 | ^3.3 | ^8.0.2 | [v2](https://github.com/wrav/oembed/tree/v2) | Discontinued | | v3 | ^3.0 \| ^4.0 \| ^5.0 | ^v4.4 | ^8.2 | [v3](https://github.com/wrav/oembed/tree/v3) | Active | | dev-v3-php74-support | ^3.0 \| ^4.0 \| ^5.0 | ^v4.4 | ^7.4 | [dev-v3-php74-support](https://github.com/wrav/oembed/tree/dev-v3-php74-support) | Active (PHP 7.4 Support) | -β—Š ## Quick FYI on URL issues @@ -223,6 +228,29 @@ Below is an example of a Oembed field called "foobar" add accessing properties f } ``` +## Testing + +This project uses Codeception and Docker Compose (Locally) and I would strongly ask for unit tests, however I understand sometimes this may not be needed. + +***NOTE:*** If your wanting to run the all project tests you'll need to set up the required Meta, Twitter, etc API tokens in the `.env` file. + +```bash +# Setting ENV for testing and edit +cp tests/.env.example tests/.env + +# Spin up docker +docker compose up -d + +# Access shell +docker exec -it app sh + +# Run tests via Codeception +vendor/bin/codecept run {your_file} + +# Run with Coverage +XDEBUG_MODE=coverage vendor/bin/codecept run --coverage +``` + ## Credits Original built while working at [HutSix](https://hutsix.com.au/) I've since been granted permission to continue development here. diff --git a/codeception.yml b/codeception.yml new file mode 100644 index 0000000..2abe8ee --- /dev/null +++ b/codeception.yml @@ -0,0 +1,32 @@ +actor: Tester +paths: + tests: tests + output: tests/_output + data: tests/_data + support: tests/_support + envs: tests/_envs +bootstrap: _bootstrap.php +params: + - tests/.env +modules: + enabled: + - \craft\test\Craft + config: + \craft\test\Craft: + configFile: "tests/_craft/config/test.php" + entryUrl: "https://localhost/index.php" + projectConfig: {} + migrations: [] + plugins: + neo: + class: '\wrav\oembed\Oembed' + handle: oembed + cleanup: true + transaction: true + dbSetup: { clean: true, setupCraft: true } +coverage: + enabled: true + include: + - src/* + exclude: + - tests/* \ No newline at end of file diff --git a/composer.json b/composer.json index d534701..df5c787 100755 --- a/composer.json +++ b/composer.json @@ -30,12 +30,17 @@ } ], "require-dev": { - "roave/security-advisories": "dev-latest" + "roave/security-advisories": "dev-latest", + "phpunit/phpunit": "^11.4", + "codeception/codeception": "^5.1", + "codeception/module-yii2": "^1.1", + "codeception/module-asserts": "^3.0" }, "require": { "craftcms/cms": "^4.0 | ^5.0", "embed/embed": "^v4.4", - "ext-dom": "*" + "ext-dom": "*", + "vlucas/phpdotenv": "^5.6" }, "repositories": [ { diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2390245 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +# Add postgres service for unit testing +services: + postgres: + image: postgres:13-alpine + container_name: postgres + ports: + - 5432:5432 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + healthcheck: + test: ["CMD", "pg_isready", "-U", "craftcms", "-d", "dev_craftcms"] + interval: 5s + retries: 3 + app: + image: craftcms/nginx:8.2-dev + container_name: app + environment: + XDEBUG_CONFIG: client_host=host.docker.internal + depends_on: + postgres: + condition: service_healthy + volumes: + - .:/app + # vendor/bin/codecept run \ No newline at end of file diff --git a/src/templates/settings.twig b/src/templates/settings.twig index fc179db..831ca48 100755 --- a/src/templates/settings.twig +++ b/src/templates/settings.twig @@ -65,3 +65,6 @@ name: 'facebookKey', value: settings.facebookKey, }) }} + + +{{ craft.app.view.renderJsFile('@wrav/oembed/js/settings.js') }} \ No newline at end of file diff --git a/tests/.env.example b/tests/.env.example new file mode 100644 index 0000000..0714f4d --- /dev/null +++ b/tests/.env.example @@ -0,0 +1,9 @@ +CRAFT_DB_DSN="pgsql:host=postgres;port=5432;dbname=postgres" +CRAFT_DB_USER="postgres" +CRAFT_DB_PASSWORD="postgres" +CRAFT_DB_SCHEMA="public" +CRAFT_DB_TABLE_PREFIX="craft" + +CRAFT_SECURITY_KEY=3WaPXa5zWQPi3YqkuZpc97JN8rNO-1Ba + +FACEBOOK_API_KEY= # curl -X GET "https://graph.facebook.com/oauth/access_token?client_id={your-app-id}&client_secret={your-app-secret}&grant_type=client_credentials" \ No newline at end of file diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +.env diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php new file mode 100644 index 0000000..9fe6b43 --- /dev/null +++ b/tests/_bootstrap.php @@ -0,0 +1,19 @@ + getenv('DB_DSN'), + 'user' => getenv('DB_USER'), + 'password' => getenv('DB_PASSWORD'), + 'schema' => getenv('DB_SCHEMA'), + 'tablePrefix' => getenv('DB_TABLE_PREFIX'), +]; \ No newline at end of file diff --git a/tests/_craft/config/test.php b/tests/_craft/config/test.php new file mode 100644 index 0000000..1d13758 --- /dev/null +++ b/tests/_craft/config/test.php @@ -0,0 +1,5 @@ +amOnPage('?p=/'); + $I->seeResponseCodeIs(200); + } +} diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml new file mode 100644 index 0000000..252e8f3 --- /dev/null +++ b/tests/unit.suite.yml @@ -0,0 +1,16 @@ +# Codeception Test Suite Configuration +# +# Suite for unit or integration tests. + +actor: UnitTester +modules: + enabled: + - \craft\test\Craft + # - \craft\test\Craft: + # projectConfig: { + # folder: 'tests/_data/project', + # reset: true + # } + - Asserts + - \Helper\Unit + step_decorators: ~ \ No newline at end of file diff --git a/tests/unit/PluginInstanceUnitTest.php b/tests/unit/PluginInstanceUnitTest.php new file mode 100644 index 0000000..03d8d80 --- /dev/null +++ b/tests/unit/PluginInstanceUnitTest.php @@ -0,0 +1,28 @@ +getPlugins()->getPlugin('oembed'); + + // Assert plugin instance + $this->assertInstanceOf(Oembed::class, $plugin); + } + +} diff --git a/tests/unit/_bootstrap.php b/tests/unit/_bootstrap.php new file mode 100644 index 0000000..a814366 --- /dev/null +++ b/tests/unit/_bootstrap.php @@ -0,0 +1 @@ +render($url, [ + 'facebook:token' => getenv('FACEBOOK_API_KEY'), + 'instagram:token' => getenv('FACEBOOK_API_KEY'), + 'instagram' => [ + 'key' => getenv('FACEBOOK_API_KEY'), + ], + 'facebook' => [ + 'key' => getenv('FACEBOOK_API_KEY'), + ], + ]); + + // Assert that the render contains the iframe parts + $this->assertStringContainsString('assertStringContainsString('src="https://www.youtube.com/embed/9bZkp7q19f0', $render); + $this->assertStringContainsString('width="560"', $render); + $this->assertStringContainsString('height="315"', $render); + $this->assertStringContainsString('autoplay=1', $render); + } + +} diff --git a/tests/unit/embeds/TwitterTest.php b/tests/unit/embeds/TwitterTest.php new file mode 100644 index 0000000..bb9683d --- /dev/null +++ b/tests/unit/embeds/TwitterTest.php @@ -0,0 +1,31 @@ +render($url); + + // Assert that the render contains the iframe parts + $this->assertStringContainsString('