From 05b5b3ff844bec3b37bbe2f684f779917eedce55 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 05:27:40 +0100 Subject: [PATCH 01/22] Split tests by module and updated winter:test --- .gitignore | 2 +- config/testing/cms.php | 10 +- config/testing/filesystems.php | 4 +- {tests/unit => modules/backend}/phpunit.xml | 9 +- .../tests}/classes/AuthManagerTest.php | 6 +- .../tests}/classes/NavigationManagerTest.php | 24 +- .../tests}/classes/WidgetManagerTest.php | 4 +- .../concerns/InteractsWithAuthentication.php | 2 +- .../tests/fixtures}/assets/compilation.js | 0 .../tests/fixtures}/assets/js/file1.js | 0 .../tests/fixtures}/assets/js/file2.js | 0 .../tests/fixtures}/models/UserFixture.php | 2 +- .../tests/fixtures}/reference/file1.txt | 0 .../tests/fixtures}/reference/file2.txt | 0 .../tests}/helpers/BackendHelperTest.php | 7 +- .../backend/tests}/models/ExportModelTest.php | 10 +- .../backend/tests}/models/ImportModelTest.php | 31 +- .../backend/tests}/traits/WidgetMakerTest.php | 5 +- .../tests}/widgets/FilterWidgetTest.php | 7 +- modules/backend/tests/widgets/FormTest.php | 243 +++++++ .../backend/tests}/widgets/ListsTest.php | 7 +- modules/cms/phpunit.xml | 22 + .../cms/tests}/classes/AssetTest.php | 7 +- .../tests}/classes/CmsCompoundObjectTest.php | 37 +- .../cms/tests}/classes/CmsExceptionTest.php | 11 +- .../cms/tests}/classes/CmsObjectQueryTest.php | 12 +- .../cms/tests}/classes/CmsObjectTest.php | 21 +- .../cms/tests}/classes/CodeParserTest.php | 21 +- .../tests}/classes/ComponentManagerTest.php | 30 +- .../cms/tests}/classes/ContentTest.php | 5 +- .../cms/tests}/classes/ControllerTest.php | 22 +- .../cms/tests}/classes/PageTest.php | 5 +- .../cms/tests}/classes/PartialStackTest.php | 17 +- .../cms/tests}/classes/RouterTest.php | 7 +- .../cms/tests}/classes/ThemeTest.php | 15 +- .../fixtures}/reference/compound-full.htm | 0 .../reference/compound-markup-settings.htm | 0 .../fixtures}/reference/compound-markup.htm | 0 .../reference/namespaces-aliases.php.stub | 0 .../fixtures}/reference/namespaces.php.stub | 0 .../tests}/fixtures/themes/apitest/.gitignore | 0 .../themes/test/assets/css/style1.css | 0 .../themes/test/assets/css/style2.css | 0 .../themes/test/assets/images}/winter.png | Bin .../fixtures/themes/test/assets/js/script1.js | 0 .../fixtures/themes/test/assets/js/script2.js | 0 .../themes/test/assets/js/subdir/script1.js | 0 .../themes/test/content/a/a-content.htm | 0 .../themes/test/content/html-content.htm | 0 .../themes/test/content/layout-content.txt | 0 .../themes/test/content/markdown-content.md | 0 .../themes/test/content/page-content.htm | 0 .../themes/test/content/text-content.txt | 0 .../themes/test/layouts/a/a-layout.htm | 0 .../themes/test/layouts/ajax-test.htm | 0 .../fixtures/themes/test/layouts/content.htm | 0 .../themes/test/layouts/cycle-test.htm | 0 .../fixtures/themes/test/layouts/no-php.htm | 0 .../fixtures/themes/test/layouts/partials.htm | 0 .../themes/test/layouts/php-parser-test.htm | 0 .../themes/test/layouts/placeholder.htm | 0 .../fixtures/themes/test/layouts/sidebar.htm | 0 .../tests}/fixtures/themes/test/pages/404.htm | 0 .../fixtures/themes/test/pages/a/a-page.htm | 0 .../fixtures/themes/test/pages/ajax-test.htm | 0 .../fixtures/themes/test/pages/authors.htm | 0 .../fixtures/themes/test/pages/b/b-page.htm | 0 .../fixtures/themes/test/pages/b/c/c-page.htm | 0 .../themes/test/pages/blog-archive.htm | 0 .../themes/test/pages/blog-category.htm | 0 .../fixtures/themes/test/pages/blog-post.htm | 0 .../test/pages/code-namespaces-aliases.htm | 0 .../themes/test/pages/code-namespaces.htm | 0 .../test/pages/component-custom-render.htm | 0 .../component-partial-alias-override.htm | 0 .../test/pages/component-partial-nesting.htm | 0 .../test/pages/component-partial-override.htm | 0 .../themes/test/pages/component-partial.htm | 0 .../fixtures/themes/test/pages/cycle-test.htm | 0 .../themes/test/pages/filters-test.htm | 0 .../fixtures/themes/test/pages/index.htm | 0 .../themes/test/pages/no-component-class.htm | 0 .../themes/test/pages/no-component.htm | 0 .../fixtures/themes/test/pages/no-layout.htm | 0 .../fixtures/themes/test/pages/no-partial.htm | 0 .../test/pages/no-soft-component-class.htm | 0 .../test/pages/optional-full-php-tags.htm | 0 .../test/pages/optional-short-php-tags.htm | 0 .../fixtures/themes/test/pages/throw-php.htm | 0 .../themes/test/pages/with-component.htm | 0 .../themes/test/pages/with-components.htm | 0 .../themes/test/pages/with-content.htm | 0 .../themes/test/pages/with-layout.htm | 0 .../themes/test/pages/with-partials.htm | 0 .../themes/test/pages/with-placeholder.htm | 0 .../pages/with-soft-component-class-alias.htm | 0 .../test/pages/with-soft-component-class.htm | 0 .../themes/test/partials/a/a-partial.htm | 0 .../themes/test/partials/ajax-result.htm | 0 .../test/partials/ajax-second-result.htm | 0 .../themes/test/partials/layout-partial.htm | 0 .../themes/test/partials/nesting/level1.htm | 0 .../themes/test/partials/nesting/level2.htm | 0 .../themes/test/partials/nesting/level3.htm | 0 .../test/partials/override1/default.htm | 0 .../test/partials/override2/default.htm | 0 .../themes/test/partials/override2/items.htm | 0 .../test/partials/override3/default.htm | 0 .../test/partials/override4/default.htm | 0 .../themes/test/partials/page-partial.htm | 0 .../themes/test/partials/testpost/default.htm | 0 .../fixtures/themes/test/temporary/.gitignore | 0 .../themes/test/testobjects/component.htm | 0 .../themes/test/testobjects/components.htm | 0 .../themes/test/testobjects/compound.htm | 0 .../themes/test/testobjects/plain.html | 0 .../themes/test/testobjects/subdir/obj.html | 0 .../themes/test/testobjects/viewbag.htm | 0 .../cms/tests}/helpers/FileTest.php | 3 + modules/system/classes/FileManifest.php | 28 +- modules/system/classes/SourceManifest.php | 55 +- modules/system/console/WinterTest.php | 163 ++--- modules/system/phpunit.xml | 22 + .../system/tests}/AliasesTest.php | 4 + .../tests/bootstrap}/PluginTestCase.php | 16 +- .../system/tests/bootstrap}/TestCase.php | 7 +- .../system/tests/bootstrap/app.php | 9 +- .../tests}/classes/AutoDatasourceTest.php | 8 +- .../tests}/classes/CombineAssetsTest.php | 9 +- .../system/tests}/classes/CoreLangTest.php | 4 + .../tests}/classes/FileManifestTest.php | 8 +- .../tests}/classes/ImageResizerTest.php | 19 +- .../tests}/classes/MarkupManagerTest.php | 5 +- .../tests}/classes/MediaLibraryTest.php | 5 +- .../tests}/classes/PluginManagerTest.php | 11 +- .../tests}/classes/SourceManifestTest.php | 51 +- .../tests}/classes/UpdatesControllerTest.php | 5 +- .../tests}/classes/VersionManagerTest.php | 9 +- .../system/tests}/console/WinterEnvTest.php | 5 +- .../system/tests}/console/WinterUtilTest.php | 4 + .../system/tests}/fixtures/config/app.php | 0 .../system/tests}/fixtures/config/cache.php | 0 .../system/tests}/fixtures/config/cms.php | 0 .../tests}/fixtures/config/database.php | 0 .../system/tests}/fixtures/config/mail.php | 0 .../system/tests}/fixtures/config/queue.php | 0 .../system/tests}/fixtures/config/session.php | 0 .../manifest/1_0_0/modules/test/file1.php | 0 .../manifest/1_0_1/modules/test/file1.php | 0 .../manifest/1_0_1/modules/test/file2.php | 0 .../manifest/1_0_1/modules/test2/file1.php | 0 .../manifest/1_0_2/modules/test/file2.php | 0 .../manifest/1_0_2/modules/test/file3.php | 0 .../manifest/1_0_2/modules/test2/file1.php | 0 .../manifest/1_0_3/modules/test/file2.php | 0 .../manifest/1_0_3/modules/test2/file1.php | 0 .../manifest/1_1_0/modules/test/file3.php | 0 .../manifest/1_1_0/modules/test/file4.php | 0 .../manifest/1_1_0/modules/test2/file1.php | 0 .../manifest/1_1_0/modules/test3/file1.php | 0 .../manifest/1_1_1/modules/test/file3.php | 0 .../manifest/1_1_1/modules/test/file4.php | 0 .../manifest/1_1_1/modules/test2/file1.php | 0 .../manifest/1_1_1/modules/test3/file1.php | 0 .../manifest/1_1_1/modules/test3/file2.php | 0 .../tests}/fixtures/manifest/forks.json | 0 .../system/tests}/fixtures/media/text.txt | 0 .../tests}/fixtures/media/winter space.png | Bin .../system/tests/fixtures/media}/winter.png | Bin .../plugins/database/tester/Plugin.php | 0 .../database/tester/assets/images/avatar.png | Bin .../plugins/database/tester/models/Author.php | 0 .../database/tester/models/Category.php | 0 .../database/tester/models/Country.php | 0 .../database/tester/models/EventLog.php | 0 .../plugins/database/tester/models/Meta.php | 0 .../plugins/database/tester/models/Phone.php | 0 .../plugins/database/tester/models/Post.php | 0 .../plugins/database/tester/models/Role.php | 0 .../plugins/database/tester/models/Tag.php | 0 .../plugins/database/tester/models/User.php | 0 .../tester/updates/create_authors_table.php | 0 .../updates/create_categories_table.php | 0 .../tester/updates/create_countries_table.php | 0 .../tester/updates/create_event_log_table.php | 0 .../tester/updates/create_meta_table.php | 0 .../tester/updates/create_phones_table.php | 0 .../tester/updates/create_posts_table.php | 0 .../tester/updates/create_roles_table.php | 0 .../tester/updates/create_tags_table.php | 0 .../tester/updates/create_users_table.php | 0 .../database/tester/updates/version.yaml | 0 .../dependencytest/dependency/Plugin.php | 0 .../dependency/updates/version.yaml | 0 .../plugins/dependencytest/found/Plugin.php | 0 .../dependencytest/found/updates/version.yaml | 0 .../dependencytest/notfound/Plugin.php | 0 .../notfound/updates/version.yaml | 0 .../dependencytest/wrongcase/Plugin.php | 0 .../wrongcase/updates/version.yaml | 0 .../plugins/testvendor/goto/Plugin.php | 0 .../plugins/testvendor/test/Plugin.php | 0 .../testvendor/test/formwidgets/Sample.php | 0 .../winter/invalidreplacement/Plugin.php | 0 .../invalidreplacement/updates/version.yaml | 0 .../plugins/winter/noupdates/Plugin.php | 0 .../winter/noupdates/updates/version.yaml | 0 .../plugins/winter/original/Plugin.php | 0 .../winter/original/updates/version.yaml | 0 .../plugins/winter/replacement/Plugin.php | 0 .../winter/replacement/updates/version.yaml | 0 .../fixtures/plugins/winter/sample/Plugin.php | 0 .../winter/sample/updates/version.yaml | 0 .../fixtures/plugins/winter/tester/Plugin.php | 0 .../plugins/winter/tester/classes/Users.php | 0 .../winter/tester/components/Archive.php | 0 .../winter/tester/components/Categories.php | 0 .../winter/tester/components/Comments.php | 0 .../winter/tester/components/ContentBlock.php | 0 .../winter/tester/components/MainMenu.php | 0 .../plugins/winter/tester/components/Post.php | 0 .../tester/components/mainmenu/default.htm | 0 .../tester/components/mainmenu/items.htm | 0 .../winter/tester/components/post/default.htm | 0 .../winter/tester/formwidgets/Preview.php | 0 .../winter/tester/rules/BeLikeBobRule.php | 0 .../updates/create_blog_settings_table.php | 0 .../updates/drop_blog_settings_table.php | 0 .../winter/tester/updates/fix_database.php | 0 .../tester/updates/some_upgrade_file.php | 0 .../winter/tester/updates/version.yaml | 0 .../tests/fixtures/themes/apitest/.gitignore | 2 + .../themes/test/assets/css/style1.css | 0 .../themes/test/assets/css/style2.css | 0 .../themes/test/assets/images/winter.png | Bin 0 -> 7491 bytes .../fixtures/themes/test/assets/js/script1.js | 1 + .../fixtures/themes/test/assets/js/script2.js | 1 + .../themes/test/assets/js/subdir/script1.js | 1 + .../themes/test/content/a/a-content.htm | 1 + .../themes/test/content/html-content.htm | 1 + .../themes/test/content/layout-content.txt | 1 + .../themes/test/content/markdown-content.md | 1 + .../themes/test/content/page-content.htm | 1 + .../themes/test/content/text-content.txt | 1 + .../themes/test/layouts/a/a-layout.htm | 1 + .../themes/test/layouts/ajax-test.htm | 10 + .../fixtures/themes/test/layouts/content.htm | 1 + .../themes/test/layouts/cycle-test.htm | 15 + .../fixtures/themes/test/layouts/no-php.htm | 1 + .../fixtures/themes/test/layouts/partials.htm | 1 + .../themes/test/layouts/php-parser-test.htm | 10 + .../themes/test/layouts/placeholder.htm | 1 + .../fixtures/themes/test/layouts/sidebar.htm | 1 + .../tests/fixtures/themes/test/pages/404.htm | 3 + .../fixtures/themes/test/pages/a/a-page.htm | 4 + .../fixtures/themes/test/pages/ajax-test.htm | 8 + .../fixtures/themes/test/pages/authors.htm | 4 + .../fixtures/themes/test/pages/b/b-page.htm | 3 + .../fixtures/themes/test/pages/b/c/c-page.htm | 3 + .../themes/test/pages/blog-archive.htm | 4 + .../themes/test/pages/blog-category.htm | 4 + .../fixtures/themes/test/pages/blog-post.htm | 4 + .../test/pages/code-namespaces-aliases.htm | 13 + .../themes/test/pages/code-namespaces.htm | 13 + .../test/pages/component-custom-render.htm | 10 + .../component-partial-alias-override.htm | 5 + .../test/pages/component-partial-nesting.htm | 3 + .../test/pages/component-partial-override.htm | 5 + .../themes/test/pages/component-partial.htm | 5 + .../fixtures/themes/test/pages/cycle-test.htm | 12 + .../themes/test/pages/filters-test.htm | 13 + .../fixtures/themes/test/pages/index.htm | 3 + .../themes/test/pages/no-component-class.htm | 5 + .../themes/test/pages/no-component.htm | 3 + .../fixtures/themes/test/pages/no-layout.htm | 4 + .../fixtures/themes/test/pages/no-partial.htm | 4 + .../test/pages/no-soft-component-class.htm | 5 + .../test/pages/optional-full-php-tags.htm | 14 + .../test/pages/optional-short-php-tags.htm | 14 + .../fixtures/themes/test/pages/throw-php.htm | 7 + .../themes/test/pages/with-component.htm | 11 + .../themes/test/pages/with-components.htm | 14 + .../themes/test/pages/with-content.htm | 4 + .../themes/test/pages/with-layout.htm | 4 + .../themes/test/pages/with-partials.htm | 4 + .../themes/test/pages/with-placeholder.htm | 11 + .../pages/with-soft-component-class-alias.htm | 11 + .../test/pages/with-soft-component-class.htm | 11 + .../themes/test/partials/a/a-partial.htm | 1 + .../themes/test/partials/ajax-result.htm | 1 + .../test/partials/ajax-second-result.htm | 1 + .../themes/test/partials/layout-partial.htm | 1 + .../themes/test/partials/nesting/level1.htm | 6 + .../themes/test/partials/nesting/level2.htm | 6 + .../themes/test/partials/nesting/level3.htm | 4 + .../test/partials/override1/default.htm | 1 + .../test/partials/override2/default.htm | 7 + .../themes/test/partials/override2/items.htm | 3 + .../test/partials/override3/default.htm | 1 + .../test/partials/override4/default.htm | 3 + .../themes/test/partials/page-partial.htm | 1 + .../themes/test/partials/testpost/default.htm | 1 + .../fixtures/themes/test/temporary/.gitignore | 2 + .../themes/test/testobjects/component.htm | 5 + .../themes/test/testobjects/components.htm | 8 + .../themes/test/testobjects/compound.htm | 10 + .../themes/test/testobjects/plain.html | 1 + .../themes/test/testobjects/subdir/obj.html | 1 + .../themes/test/testobjects/viewbag.htm | 5 + .../plugins/database/AttachManyModelTest.php | 10 +- .../plugins/database/AttachOneModelTest.php | 16 +- .../database/BelongsToManyModelTest.php | 21 +- .../plugins/database/BelongsToModelTest.php | 8 +- .../plugins/database/DeferredBindingTest.php | 8 +- .../plugins/database/HasManyModelTest.php | 8 +- .../database/HasManyThroughModelTest.php | 10 +- .../plugins/database/HasOneModelTest.php | 8 +- .../database/HasOneThroughModelTest.php | 10 +- .../plugins/database/MorphManyModelTest.php | 13 +- .../plugins/database/MorphOneModelTest.php | 12 +- .../plugins/database/MorphToModelTest.php | 10 +- .../plugins/database/NestedTreeModelTest.php | 6 +- .../plugins/database/NullableModelTest.php | 5 +- .../plugins/database/PluginModelTest.php | 5 +- .../database/RevisionableModelTest.php | 6 +- .../plugins/database/SimpleTreeModelTest.php | 6 +- .../plugins/database/SluggableModelTest.php | 5 +- .../plugins/database/SoftDeleteModelTest.php | 8 +- .../plugins/database/ValidationModelTest.php | 5 +- .../system/CustomValidatorRulesTest.php | 9 +- .../system/tests}/traits/AssetMakerTest.php | 10 +- .../system/tests}/traits/ViewMakerTest.php | 9 +- .../_can_override_php_with_htm.php | 0 .../traits/viewmakerstub/_overridden.php | 0 .../traits/viewmakerstub/_relative_no_ext.php | 0 .../traits/viewmakerstub/folder/_no_ext.php | 0 .../viewmakerstub/layouts/_layout_partial.php | 0 .../traits/viewmakerstub/layouts/default.php | 0 .../tests}/traits/viewmakerstub/specific.php | 0 .../tests}/traits/viewmakerstub/symbols.php | 0 .../tests}/traits/viewmakerstub/view.php | 0 .../_can_override_php_with_htm.htm | 0 .../viewmakerstuboverride/_overridden.php | 0 .../system/tests}/twig/FilterTest.php | 4 + .../system/tests}/twig/SpacelessTest.php | 4 + phpunit.xml | 6 +- storage/.gitignore | 1 + tests/.gitignore | 1 - tests/README.md | 105 --- tests/js/.babelrc | 17 - tests/js/.gitignore | 3 - tests/js/README.md | 32 - tests/js/cases/snowboard/ajax/Request.test.js | 625 ------------------ .../cases/snowboard/extras/DataConfig.test.js | 316 --------- .../cases/snowboard/main/PluginLoader.test.js | 37 -- .../js/cases/snowboard/main/Snowboard.test.js | 383 ----------- .../fixtures/dataConfig/DataConfigFixture.js | 26 - .../fixtures/framework/TestDependencyOne.js | 11 - .../fixtures/framework/TestDependencyTwo.js | 11 - .../fixtures/framework/TestHasDependencies.js | 15 - tests/js/fixtures/framework/TestListener.js | 18 - tests/js/fixtures/framework/TestPlugin.js | 11 - .../fixtures/framework/TestPromiseListener.js | 28 - tests/js/fixtures/framework/TestSingleton.js | 11 - .../framework/TestSingletonWithDependency.js | 25 - tests/js/helpers/FakeDom.js | 189 ------ tests/js/jest.config.js | 194 ------ tests/js/package.json | 37 -- tests/unit/backend/widgets/FormTest.php | 235 ------- .../plugins/backend/ImportModelDbTest.php | 42 -- 370 files changed, 1261 insertions(+), 2755 deletions(-) rename {tests/unit => modules/backend}/phpunit.xml (77%) rename {tests/unit/backend => modules/backend/tests}/classes/AuthManagerTest.php (98%) rename {tests/unit/backend => modules/backend/tests}/classes/NavigationManagerTest.php (95%) rename {tests/unit/backend => modules/backend/tests}/classes/WidgetManagerTest.php (95%) rename {tests => modules/backend/tests}/concerns/InteractsWithAuthentication.php (99%) rename {tests/fixtures/backend => modules/backend/tests/fixtures}/assets/compilation.js (100%) rename {tests/fixtures/backend => modules/backend/tests/fixtures}/assets/js/file1.js (100%) rename {tests/fixtures/backend => modules/backend/tests/fixtures}/assets/js/file2.js (100%) rename {tests/fixtures/backend => modules/backend/tests/fixtures}/models/UserFixture.php (97%) rename {tests/fixtures/backend => modules/backend/tests/fixtures}/reference/file1.txt (100%) rename {tests/fixtures/backend => modules/backend/tests/fixtures}/reference/file2.txt (100%) rename {tests/unit/backend => modules/backend/tests}/helpers/BackendHelperTest.php (66%) rename {tests/unit/backend => modules/backend/tests}/models/ExportModelTest.php (89%) rename {tests/unit/backend => modules/backend/tests}/models/ImportModelTest.php (51%) rename {tests/unit/backend => modules/backend/tests}/traits/WidgetMakerTest.php (93%) rename {tests/unit/backend => modules/backend/tests}/widgets/FilterWidgetTest.php (96%) create mode 100644 modules/backend/tests/widgets/FormTest.php rename {tests/unit/backend => modules/backend/tests}/widgets/ListsTest.php (97%) create mode 100644 modules/cms/phpunit.xml rename {tests/unit/cms => modules/cms/tests}/classes/AssetTest.php (98%) rename {tests/unit/cms => modules/cms/tests}/classes/CmsCompoundObjectTest.php (90%) rename {tests/unit/cms => modules/cms/tests}/classes/CmsExceptionTest.php (93%) rename {tests/unit/cms => modules/cms/tests}/classes/CmsObjectQueryTest.php (92%) rename {tests/unit/cms => modules/cms/tests}/classes/CmsObjectTest.php (93%) rename {tests/unit/cms => modules/cms/tests}/classes/CodeParserTest.php (96%) rename {tests/unit/cms => modules/cms/tests}/classes/ComponentManagerTest.php (82%) rename {tests/unit/cms => modules/cms/tests}/classes/ContentTest.php (95%) rename {tests/unit/cms => modules/cms/tests}/classes/ControllerTest.php (95%) rename {tests/unit/cms => modules/cms/tests}/classes/PageTest.php (89%) rename {tests/unit/cms => modules/cms/tests}/classes/PartialStackTest.php (74%) rename {tests/unit/cms => modules/cms/tests}/classes/RouterTest.php (97%) rename {tests/unit/cms => modules/cms/tests}/classes/ThemeTest.php (82%) rename {tests/fixtures/cms => modules/cms/tests/fixtures}/reference/compound-full.htm (100%) rename {tests/fixtures/cms => modules/cms/tests/fixtures}/reference/compound-markup-settings.htm (100%) rename {tests/fixtures/cms => modules/cms/tests/fixtures}/reference/compound-markup.htm (100%) rename {tests/fixtures/cms => modules/cms/tests/fixtures}/reference/namespaces-aliases.php.stub (100%) rename {tests/fixtures/cms => modules/cms/tests/fixtures}/reference/namespaces.php.stub (100%) rename {tests => modules/cms/tests}/fixtures/themes/apitest/.gitignore (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/assets/css/style1.css (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/assets/css/style2.css (100%) rename {tests/fixtures/media => modules/cms/tests/fixtures/themes/test/assets/images}/winter.png (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/assets/js/script1.js (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/assets/js/script2.js (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/assets/js/subdir/script1.js (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/content/a/a-content.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/content/html-content.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/content/layout-content.txt (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/content/markdown-content.md (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/content/page-content.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/content/text-content.txt (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/a/a-layout.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/ajax-test.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/content.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/cycle-test.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/no-php.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/partials.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/php-parser-test.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/placeholder.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/layouts/sidebar.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/404.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/a/a-page.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/ajax-test.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/authors.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/b/b-page.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/b/c/c-page.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/blog-archive.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/blog-category.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/blog-post.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/code-namespaces-aliases.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/code-namespaces.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/component-custom-render.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/component-partial-alias-override.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/component-partial-nesting.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/component-partial-override.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/component-partial.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/cycle-test.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/filters-test.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/index.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/no-component-class.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/no-component.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/no-layout.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/no-partial.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/no-soft-component-class.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/optional-full-php-tags.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/optional-short-php-tags.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/throw-php.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-component.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-components.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-content.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-layout.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-partials.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-placeholder.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-soft-component-class-alias.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/pages/with-soft-component-class.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/a/a-partial.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/ajax-result.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/ajax-second-result.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/layout-partial.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/nesting/level1.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/nesting/level2.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/nesting/level3.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/override1/default.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/override2/default.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/override2/items.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/override3/default.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/override4/default.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/page-partial.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/partials/testpost/default.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/temporary/.gitignore (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/testobjects/component.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/testobjects/components.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/testobjects/compound.htm (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/testobjects/plain.html (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/testobjects/subdir/obj.html (100%) rename {tests => modules/cms/tests}/fixtures/themes/test/testobjects/viewbag.htm (100%) rename {tests/unit/cms => modules/cms/tests}/helpers/FileTest.php (90%) create mode 100644 modules/system/phpunit.xml rename {tests/unit/system => modules/system/tests}/AliasesTest.php (90%) rename {tests => modules/system/tests/bootstrap}/PluginTestCase.php (93%) rename {tests => modules/system/tests/bootstrap}/TestCase.php (93%) rename tests/bootstrap.php => modules/system/tests/bootstrap/app.php (60%) rename {tests/unit/system => modules/system/tests}/classes/AutoDatasourceTest.php (93%) rename {tests/unit/system => modules/system/tests}/classes/CombineAssetsTest.php (90%) rename {tests/unit/system => modules/system/tests}/classes/CoreLangTest.php (94%) rename {tests/unit/system => modules/system/tests}/classes/FileManifestTest.php (89%) rename {tests/unit/system => modules/system/tests}/classes/ImageResizerTest.php (93%) rename {tests/unit/system => modules/system/tests}/classes/MarkupManagerTest.php (93%) rename {tests/unit/system => modules/system/tests}/classes/MediaLibraryTest.php (97%) rename {tests/unit/system => modules/system/tests}/classes/PluginManagerTest.php (98%) rename {tests/unit/system => modules/system/tests}/classes/SourceManifestTest.php (86%) rename {tests/unit/system => modules/system/tests}/classes/UpdatesControllerTest.php (92%) rename {tests/unit/system => modules/system/tests}/classes/VersionManagerTest.php (95%) rename {tests/unit/system => modules/system/tests}/console/WinterEnvTest.php (96%) rename {tests/unit/system => modules/system/tests}/console/WinterUtilTest.php (97%) rename {tests => modules/system/tests}/fixtures/config/app.php (100%) rename {tests => modules/system/tests}/fixtures/config/cache.php (100%) rename {tests => modules/system/tests}/fixtures/config/cms.php (100%) rename {tests => modules/system/tests}/fixtures/config/database.php (100%) rename {tests => modules/system/tests}/fixtures/config/mail.php (100%) rename {tests => modules/system/tests}/fixtures/config/queue.php (100%) rename {tests => modules/system/tests}/fixtures/config/session.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_0/modules/test/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_1/modules/test/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_1/modules/test/file2.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_1/modules/test2/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_2/modules/test/file2.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_2/modules/test/file3.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_2/modules/test2/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_3/modules/test/file2.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_0_3/modules/test2/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_0/modules/test/file3.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_0/modules/test/file4.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_0/modules/test2/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_0/modules/test3/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_1/modules/test/file3.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_1/modules/test/file4.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_1/modules/test2/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_1/modules/test3/file1.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/1_1_1/modules/test3/file2.php (100%) rename {tests => modules/system/tests}/fixtures/manifest/forks.json (100%) rename {tests => modules/system/tests}/fixtures/media/text.txt (100%) rename {tests => modules/system/tests}/fixtures/media/winter space.png (100%) rename {tests/fixtures/themes/test/assets/images => modules/system/tests/fixtures/media}/winter.png (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/assets/images/avatar.png (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Author.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Category.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Country.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/EventLog.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Meta.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Phone.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Post.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Role.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/Tag.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/models/User.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_authors_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_categories_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_countries_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_event_log_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_meta_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_phones_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_posts_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_roles_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_tags_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/create_users_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/database/tester/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/dependency/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/dependency/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/found/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/found/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/notfound/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/notfound/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/wrongcase/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/dependencytest/wrongcase/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/testvendor/goto/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/testvendor/test/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/testvendor/test/formwidgets/Sample.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/invalidreplacement/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/invalidreplacement/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/noupdates/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/noupdates/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/original/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/original/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/replacement/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/replacement/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/sample/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/sample/updates/version.yaml (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/Plugin.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/classes/Users.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/Archive.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/Categories.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/Comments.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/ContentBlock.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/MainMenu.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/Post.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/mainmenu/default.htm (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/mainmenu/items.htm (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/components/post/default.htm (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/formwidgets/Preview.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/rules/BeLikeBobRule.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/updates/create_blog_settings_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/updates/drop_blog_settings_table.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/updates/fix_database.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/updates/some_upgrade_file.php (100%) rename {tests => modules/system/tests}/fixtures/plugins/winter/tester/updates/version.yaml (100%) create mode 100644 modules/system/tests/fixtures/themes/apitest/.gitignore create mode 100644 modules/system/tests/fixtures/themes/test/assets/css/style1.css create mode 100644 modules/system/tests/fixtures/themes/test/assets/css/style2.css create mode 100644 modules/system/tests/fixtures/themes/test/assets/images/winter.png create mode 100644 modules/system/tests/fixtures/themes/test/assets/js/script1.js create mode 100644 modules/system/tests/fixtures/themes/test/assets/js/script2.js create mode 100644 modules/system/tests/fixtures/themes/test/assets/js/subdir/script1.js create mode 100644 modules/system/tests/fixtures/themes/test/content/a/a-content.htm create mode 100644 modules/system/tests/fixtures/themes/test/content/html-content.htm create mode 100644 modules/system/tests/fixtures/themes/test/content/layout-content.txt create mode 100644 modules/system/tests/fixtures/themes/test/content/markdown-content.md create mode 100644 modules/system/tests/fixtures/themes/test/content/page-content.htm create mode 100644 modules/system/tests/fixtures/themes/test/content/text-content.txt create mode 100644 modules/system/tests/fixtures/themes/test/layouts/a/a-layout.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/ajax-test.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/content.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/cycle-test.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/no-php.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/partials.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/php-parser-test.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/placeholder.htm create mode 100644 modules/system/tests/fixtures/themes/test/layouts/sidebar.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/404.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/a/a-page.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/ajax-test.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/authors.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/b/b-page.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/b/c/c-page.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/blog-archive.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/blog-category.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/blog-post.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/code-namespaces-aliases.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/code-namespaces.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/component-custom-render.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/component-partial-alias-override.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/component-partial-nesting.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/component-partial-override.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/component-partial.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/cycle-test.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/filters-test.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/index.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/no-component-class.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/no-component.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/no-layout.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/no-partial.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/no-soft-component-class.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/optional-full-php-tags.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/optional-short-php-tags.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/throw-php.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-component.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-components.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-content.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-layout.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-partials.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-placeholder.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm create mode 100644 modules/system/tests/fixtures/themes/test/pages/with-soft-component-class.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/a/a-partial.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/ajax-result.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/ajax-second-result.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/layout-partial.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/nesting/level1.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/nesting/level2.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/nesting/level3.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/override1/default.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/override2/default.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/override2/items.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/override3/default.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/override4/default.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/page-partial.htm create mode 100644 modules/system/tests/fixtures/themes/test/partials/testpost/default.htm create mode 100644 modules/system/tests/fixtures/themes/test/temporary/.gitignore create mode 100644 modules/system/tests/fixtures/themes/test/testobjects/component.htm create mode 100644 modules/system/tests/fixtures/themes/test/testobjects/components.htm create mode 100644 modules/system/tests/fixtures/themes/test/testobjects/compound.htm create mode 100644 modules/system/tests/fixtures/themes/test/testobjects/plain.html create mode 100644 modules/system/tests/fixtures/themes/test/testobjects/subdir/obj.html create mode 100644 modules/system/tests/fixtures/themes/test/testobjects/viewbag.htm rename {tests/unit => modules/system/tests}/plugins/database/AttachManyModelTest.php (72%) rename {tests/unit => modules/system/tests}/plugins/database/AttachOneModelTest.php (77%) rename {tests/unit => modules/system/tests}/plugins/database/BelongsToManyModelTest.php (91%) rename {tests/unit => modules/system/tests}/plugins/database/BelongsToModelTest.php (91%) rename {tests/unit => modules/system/tests}/plugins/database/DeferredBindingTest.php (91%) rename {tests/unit => modules/system/tests}/plugins/database/HasManyModelTest.php (92%) rename {tests/unit => modules/system/tests}/plugins/database/HasManyThroughModelTest.php (78%) rename {tests/unit => modules/system/tests}/plugins/database/HasOneModelTest.php (93%) rename {tests/unit => modules/system/tests}/plugins/database/HasOneThroughModelTest.php (67%) rename {tests/unit => modules/system/tests}/plugins/database/MorphManyModelTest.php (92%) rename {tests/unit => modules/system/tests}/plugins/database/MorphOneModelTest.php (92%) rename {tests/unit => modules/system/tests}/plugins/database/MorphToModelTest.php (82%) rename {tests/unit => modules/system/tests}/plugins/database/NestedTreeModelTest.php (95%) rename {tests/unit => modules/system/tests}/plugins/database/NullableModelTest.php (89%) rename {tests/unit => modules/system/tests}/plugins/database/PluginModelTest.php (79%) rename {tests/unit => modules/system/tests}/plugins/database/RevisionableModelTest.php (95%) rename {tests/unit => modules/system/tests}/plugins/database/SimpleTreeModelTest.php (97%) rename {tests/unit => modules/system/tests}/plugins/database/SluggableModelTest.php (94%) rename {tests/unit => modules/system/tests}/plugins/database/SoftDeleteModelTest.php (91%) rename {tests/unit => modules/system/tests}/plugins/database/ValidationModelTest.php (80%) rename {tests/unit => modules/system/tests}/plugins/system/CustomValidatorRulesTest.php (81%) rename {tests/unit/system => modules/system/tests}/traits/AssetMakerTest.php (86%) rename {tests/unit/system => modules/system/tests}/traits/ViewMakerTest.php (94%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/_can_override_php_with_htm.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/_overridden.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/_relative_no_ext.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/folder/_no_ext.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/layouts/_layout_partial.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/layouts/default.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/specific.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/symbols.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstub/view.php (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstuboverride/_can_override_php_with_htm.htm (100%) rename {tests/unit/system => modules/system/tests}/traits/viewmakerstuboverride/_overridden.php (100%) rename {tests/unit/system => modules/system/tests}/twig/FilterTest.php (97%) rename {tests/unit/system => modules/system/tests}/twig/SpacelessTest.php (92%) delete mode 100644 tests/.gitignore delete mode 100644 tests/README.md delete mode 100644 tests/js/.babelrc delete mode 100644 tests/js/.gitignore delete mode 100644 tests/js/README.md delete mode 100644 tests/js/cases/snowboard/ajax/Request.test.js delete mode 100644 tests/js/cases/snowboard/extras/DataConfig.test.js delete mode 100644 tests/js/cases/snowboard/main/PluginLoader.test.js delete mode 100644 tests/js/cases/snowboard/main/Snowboard.test.js delete mode 100644 tests/js/fixtures/dataConfig/DataConfigFixture.js delete mode 100644 tests/js/fixtures/framework/TestDependencyOne.js delete mode 100644 tests/js/fixtures/framework/TestDependencyTwo.js delete mode 100644 tests/js/fixtures/framework/TestHasDependencies.js delete mode 100644 tests/js/fixtures/framework/TestListener.js delete mode 100644 tests/js/fixtures/framework/TestPlugin.js delete mode 100644 tests/js/fixtures/framework/TestPromiseListener.js delete mode 100644 tests/js/fixtures/framework/TestSingleton.js delete mode 100644 tests/js/fixtures/framework/TestSingletonWithDependency.js delete mode 100644 tests/js/helpers/FakeDom.js delete mode 100644 tests/js/jest.config.js delete mode 100644 tests/js/package.json delete mode 100644 tests/unit/backend/widgets/FormTest.php delete mode 100644 tests/unit/plugins/backend/ImportModelDbTest.php diff --git a/.gitignore b/.gitignore index 0a2a3393b4..3582897e81 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,4 @@ package-lock.json /node_modules # Ignore generated public directory from `winter:mirror public` -public \ No newline at end of file +public diff --git a/config/testing/cms.php b/config/testing/cms.php index ba61b54e0d..f8660bbbde 100644 --- a/config/testing/cms.php +++ b/config/testing/cms.php @@ -96,7 +96,7 @@ | */ - 'pluginsPathLocal' => base_path('tests/fixtures/plugins'), + 'pluginsPathLocal' => base_path('modules/system/tests/fixtures/plugins'), /* |-------------------------------------------------------------------------- @@ -107,7 +107,7 @@ | */ - 'themesPathLocal' => base_path('tests/fixtures/themes'), + 'themesPathLocal' => base_path('modules/cms/tests/fixtures/themes'), /* |-------------------------------------------------------------------------- @@ -149,20 +149,20 @@ 'uploads' => [ 'disk' => 'local', 'folder' => 'uploads', - 'path' => '/tests/storage/app/uploads', + 'path' => '/storage/tests/app/uploads', 'temporaryUrlTTL' => 3600, ], 'media' => [ 'disk' => 'local', 'folder' => 'media', - 'path' => '/tests/storage/app/media', + 'path' => '/storage/tests/app/media', ], 'resized' => [ 'disk' => 'local', 'folder' => 'resized', - 'path' => '/tests/storage/app/resized', + 'path' => '/storage/tests/app/resized', ], ], diff --git a/config/testing/filesystems.php b/config/testing/filesystems.php index dc085801ee..d7bf8bf430 100644 --- a/config/testing/filesystems.php +++ b/config/testing/filesystems.php @@ -45,8 +45,8 @@ 'local' => [ 'driver' => 'local', - 'root' => base_path('tests/storage/app'), - 'url' => '/tests/storage/app', + 'root' => base_path('storage/tests/app'), + 'url' => '/storage/tests/app', ], 's3' => [ diff --git a/tests/unit/phpunit.xml b/modules/backend/phpunit.xml similarity index 77% rename from tests/unit/phpunit.xml rename to modules/backend/phpunit.xml index a35949f19b..20888c41d4 100644 --- a/tests/unit/phpunit.xml +++ b/modules/backend/phpunit.xml @@ -1,18 +1,17 @@ - - ./ + + ./tests @@ -20,4 +19,4 @@ - \ No newline at end of file + diff --git a/tests/unit/backend/classes/AuthManagerTest.php b/modules/backend/tests/classes/AuthManagerTest.php similarity index 98% rename from tests/unit/backend/classes/AuthManagerTest.php rename to modules/backend/tests/classes/AuthManagerTest.php index bdb84dd6dd..9556794904 100644 --- a/tests/unit/backend/classes/AuthManagerTest.php +++ b/modules/backend/tests/classes/AuthManagerTest.php @@ -1,6 +1,10 @@ registerMenuItems('Winter.Test', [ 'dashboard' => [ - 'label' => 'Dashboard', - 'icon' => 'icon-dashboard', - 'url' => 'http://example.com', - 'order' => 100 + 'label' => 'Dashboard', + 'icon' => 'icon-dashboard', + 'url' => 'http://example.com', + 'order' => 100 ] ]); @@ -175,9 +177,9 @@ public function testAddSideMenuItems() $manager->addSideMenuItems('Winter.Tester', 'blog', [ 'foo' => [ - 'label' => 'Bar', - 'icon' => 'icon-derp', - 'url' => 'http://google.com', + 'label' => 'Bar', + 'icon' => 'icon-derp', + 'url' => 'http://google.com', 'permissions' => [ 'winter.tester.access_foo', 'winter.tester.access_bar' @@ -213,9 +215,9 @@ public function testAddSideMenuItemsWithAlias() $manager->addSideMenuItems('Winter.Tester', 'blog', [ 'foo' => [ - 'label' => 'Bar', - 'icon' => 'icon-derp', - 'url' => 'http://google.com', + 'label' => 'Bar', + 'icon' => 'icon-derp', + 'url' => 'http://google.com', 'permissions' => [ 'winter.tester.access_foo', 'winter.tester.access_bar' diff --git a/tests/unit/backend/classes/WidgetManagerTest.php b/modules/backend/tests/classes/WidgetManagerTest.php similarity index 95% rename from tests/unit/backend/classes/WidgetManagerTest.php rename to modules/backend/tests/classes/WidgetManagerTest.php index 7cab3f208a..c3aea566ae 100644 --- a/tests/unit/backend/classes/WidgetManagerTest.php +++ b/modules/backend/tests/classes/WidgetManagerTest.php @@ -1,6 +1,8 @@ decompileAsset('tests/fixtures/backend/assets/compilation.js'); + $assets = $backendHelper->decompileAsset('modules/backend/tests/fixtures/assets/compilation.js'); $this->assertCount(2, $assets); $this->assertStringContainsString('file1.js', $assets[0]); @@ -20,6 +23,6 @@ public function testDecompileMissingFile() $this->expectException(DecompileException::class); $backendHelper = new Backend; - $assets = $backendHelper->decompileAsset('tests/fixtures/backend/assets/missing.js'); + $assets = $backendHelper->decompileAsset('modules/backend/tests/fixtures/assets/missing.js'); } } diff --git a/tests/unit/backend/models/ExportModelTest.php b/modules/backend/tests/models/ExportModelTest.php similarity index 89% rename from tests/unit/backend/models/ExportModelTest.php rename to modules/backend/tests/models/ExportModelTest.php index 26bacff54a..4c1d5e8e7a 100644 --- a/tests/unit/backend/models/ExportModelTest.php +++ b/modules/backend/tests/models/ExportModelTest.php @@ -1,6 +1,10 @@ download($csvName); - $request = new Illuminate\Http\Request(); + $request = new Request(); $response->prepare($request); @@ -72,9 +76,9 @@ public function testDownload() $response->send(); $output = ob_get_clean(); - $utf8BOM = chr(239).chr(187).chr(191); + $utf8BOM = chr(239) . chr(187) . chr(191); - $this->assertEquals($utf8BOM."title,title2\nbar,foo\nbar2,foo2\n", $output, "CSV is not right!"); + $this->assertEquals($utf8BOM . "title,title2\nbar,foo\nbar2,foo2\n", $output, "CSV is not right!"); $filePath = temp_path($csvName); diff --git a/tests/unit/backend/models/ImportModelTest.php b/modules/backend/tests/models/ImportModelTest.php similarity index 51% rename from tests/unit/backend/models/ImportModelTest.php rename to modules/backend/tests/models/ImportModelTest.php index 75cda6dd70..23a089393c 100644 --- a/tests/unit/backend/models/ImportModelTest.php +++ b/modules/backend/tests/models/ImportModelTest.php @@ -1,6 +1,10 @@ assertEquals(['art direction', 'roman empire', 'sci-fi'], $result); } + + public function testGetImportFilePath() + { + $model = new ExampleImportModel; + $sessionKey = uniqid('session_key', true); + + $file1 = FileModel::create([ + 'data' => base_path().'/modules/backend/tests/fixtures/reference/file1.txt', + 'is_public' => false, + ]); + + $file2 = FileModel::create([ + 'data' => base_path().'/modules/backend/tests/fixtures/reference/file2.txt', + 'is_public' => false, + ]); + + $model->import_file()->add($file1, $sessionKey); + $model->import_file()->add($file2, $sessionKey); + + $this->assertEquals( + $file2->getLocalPath(), + $model->getImportFilePath($sessionKey), + 'ImportModel::getImportFilePath() should return the last uploaded file.' + ); + } } diff --git a/tests/unit/backend/traits/WidgetMakerTest.php b/modules/backend/tests/traits/WidgetMakerTest.php similarity index 93% rename from tests/unit/backend/traits/WidgetMakerTest.php rename to modules/backend/tests/traits/WidgetMakerTest.php index 9a290b509e..4d1caf2df9 100644 --- a/tests/unit/backend/traits/WidgetMakerTest.php +++ b/modules/backend/tests/traits/WidgetMakerTest.php @@ -1,5 +1,8 @@ actingAs($user); + + $form = $this->restrictedFormFixture(); + + $form->render(); + $this->assertNull($form->getField('testRestricted')); + } + + public function testRestrictedFieldWithUserWithWrongPermissions() + { + $user = new UserFixture; + $this->actingAs($user->withPermission('test.wrong_permission', true)); + + $form = $this->restrictedFormFixture(); + + $form->render(); + $this->assertNull($form->getField('testRestricted')); + } + + public function testRestrictedFieldWithUserWithRightPermissions() + { + $user = new UserFixture; + $this->actingAs($user->withPermission('test.access_field', true)); + + $form = $this->restrictedFormFixture(); + + $form->render(); + $this->assertNotNull($form->getField('testRestricted')); + } + + public function testRestrictedFieldWithUserWithRightWildcardPermissions() + { + $user = new UserFixture; + $this->actingAs($user->withPermission('test.access_field', true)); + + $form = new Form(null, [ + 'model' => new FormTestModel, + 'arrayName' => 'array', + 'fields' => [ + 'testField' => [ + 'type' => 'text', + 'label' => 'Test 1' + ], + 'testRestricted' => [ + 'type' => 'text', + 'label' => 'Test 2', + 'permission' => 'test.*' + ] + ] + ]); + + $form->render(); + $this->assertNotNull($form->getField('testRestricted')); + } + + public function testRestrictedFieldWithSuperuser() + { + $user = new UserFixture; + $this->actingAs($user->asSuperUser()); + + $form = $this->restrictedFormFixture(); + + $form->render(); + $this->assertNotNull($form->getField('testRestricted')); + } + + public function testRestrictedFieldSinglePermissionWithUserWithWrongPermissions() + { + $user = new UserFixture; + $this->actingAs($user->withPermission('test.wrong_permission', true)); + + $form = $this->restrictedFormFixture(true); + + $form->render(); + $this->assertNull($form->getField('testRestricted')); + } + + public function testRestrictedFieldSinglePermissionWithUserWithRightPermissions() + { + $user = new UserFixture; + $this->actingAs($user->withPermission('test.access_field', true)); + + $form = $this->restrictedFormFixture(true); + + $form->render(); + $this->assertNotNull($form->getField('testRestricted')); + } + + public function testCheckboxlistTrigger() + { + $form = new Form(null, [ + 'model' => new FormTestModel, + 'arrayName' => 'array', + 'fields' => [ + 'trigger' => [ + 'type' => 'checkboxlist', + 'options' => [ + '1' => 'Value One' + ] + ], + 'triggered' => [ + 'type' => 'text', + 'trigger' => [ + 'field' => 'trigger[]', + 'action' => 'show', + 'condition' => 'value[1]' + ] + ] + ] + ]); + + $form->render(); + + $attributes = $form->getField('triggered')->getAttributes('container', false); + $this->assertEquals('[name="array[trigger][]"]', array_get($attributes, 'data-trigger')); + } + + public function testOptionsGeneration() + { + $form = new Form(null, [ + 'model' => new FormTestModel, + 'arrayName' => 'array', + 'fields' => [ + 'static_method_options' => [ + 'type' => 'dropdown', + 'options' => 'FormHelper::staticMethodOptions', + 'expect' => ['static', 'method'], + ], + 'callable_options' => [ + 'type' => 'dropdown', + 'options' => [\FormHelper::class, 'staticMethodOptions'], + 'expect' => ['static', 'method'], + ], + 'model_method_options' => [ + 'type' => 'dropdown', + 'options' => 'modelCustomOptionsMethod', + 'expect' => ['model', 'custom', 'options'], + ], + 'defined_options' => [ + 'type' => 'dropdown', + 'options' => ['value1', 'value2'], + 'expect' => ['value1', 'value2'], + ], + 'defined_options_key_value' => [ + 'type' => 'dropdown', + 'options' => [ + 'key1' => 'value1', + 'key2' => 'value2', + ], + 'expect' => [ + 'key1' => 'value1', + 'key2' => 'value2', + ], + ], + 'field_name_on_model_options_method' => [ + 'type' => 'dropdown', + 'expect' => ['model', 'field name', 'options method'], + ], + 'get_dropdown_options_method' => [ + 'type' => 'dropdown', + 'expect' => ['dropdown', 'options'], + ], + ] + ]); + + $form->render(); + + foreach ($form->getFields() as $name => $field) { + $this->assertEquals($field->options(), $field->config['expect']); + } + } + + protected function restrictedFormFixture(bool $singlePermission = false) + { + return new Form(null, [ + 'model' => new FormTestModel, + 'arrayName' => 'array', + 'fields' => [ + 'testField' => [ + 'type' => 'text', + 'label' => 'Test 1' + ], + 'testRestricted' => [ + 'type' => 'text', + 'label' => 'Test 2', + 'permissions' => ($singlePermission) ? 'test.access_field' : [ + 'test.access_field' + ] + ] + ] + ]); + } + } +} + +namespace +{ + class FormHelper + { + public static function staticMethodOptions() + { + return ['static', 'method']; + } + } +} diff --git a/tests/unit/backend/widgets/ListsTest.php b/modules/backend/tests/widgets/ListsTest.php similarity index 97% rename from tests/unit/backend/widgets/ListsTest.php rename to modules/backend/tests/widgets/ListsTest.php index 1df36b14d6..43e194d332 100644 --- a/tests/unit/backend/widgets/ListsTest.php +++ b/modules/backend/tests/widgets/ListsTest.php @@ -1,9 +1,12 @@ + + + + ./tests + + + + + + + + diff --git a/tests/unit/cms/classes/AssetTest.php b/modules/cms/tests/classes/AssetTest.php similarity index 98% rename from tests/unit/cms/classes/AssetTest.php rename to modules/cms/tests/classes/AssetTest.php index 7325d473e5..8d754cb138 100644 --- a/tests/unit/cms/classes/AssetTest.php +++ b/modules/cms/tests/classes/AssetTest.php @@ -1,14 +1,17 @@ assertStringContainsString( 'console.log(\'script1.js\');', diff --git a/tests/unit/cms/classes/CmsCompoundObjectTest.php b/modules/cms/tests/classes/CmsCompoundObjectTest.php similarity index 90% rename from tests/unit/cms/classes/CmsCompoundObjectTest.php rename to modules/cms/tests/classes/CmsCompoundObjectTest.php index e861ef0b90..19b03df8cf 100644 --- a/tests/unit/cms/classes/CmsCompoundObjectTest.php +++ b/modules/cms/tests/classes/CmsCompoundObjectTest.php @@ -1,8 +1,11 @@ assertFileExists($srcPath); $testContent = file_get_contents($srcPath); $this->assertNotEmpty($testContent); @@ -199,7 +202,7 @@ public function testSaveMarkup() { $theme = Theme::load('apitest'); - $destFilePath = $theme->getPath().'/testobjects/compound-markup.htm'; + $destFilePath = $theme->getPath() . '/testobjects/compound-markup.htm'; if (file_exists($destFilePath)) { unlink($destFilePath); } @@ -209,11 +212,11 @@ public function testSaveMarkup() $obj = TestCmsCompoundObject::inTheme($theme); $obj->fill([ 'markup' => '

Hello, world!

', - 'fileName'=>'compound-markup' + 'fileName' => 'compound-markup' ]); $obj->save(); - $referenceFilePath = base_path().'/tests/fixtures/cms/reference/compound-markup.htm'; + $referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/compound-markup.htm'; $this->assertFileExists($referenceFilePath); $this->assertFileExists($destFilePath); @@ -224,7 +227,7 @@ public function testSaveMarkupAndSettings() { $theme = Theme::load('apitest'); - $destFilePath = $theme->getPath().'/testobjects/compound-markup-settings.htm'; + $destFilePath = $theme->getPath() . '/testobjects/compound-markup-settings.htm'; if (file_exists($destFilePath)) { unlink($destFilePath); } @@ -233,13 +236,13 @@ public function testSaveMarkupAndSettings() $obj = TestCmsCompoundObject::inTheme($theme); $obj->fill([ - 'settings'=>['var'=>'value'], + 'settings' => ['var' => 'value'], 'markup' => '

Hello, world!

', - 'fileName'=>'compound-markup-settings' + 'fileName' => 'compound-markup-settings' ]); $obj->save(); - $referenceFilePath = base_path().'/tests/fixtures/cms/reference/compound-markup-settings.htm'; + $referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/compound-markup-settings.htm'; $this->assertFileExists($referenceFilePath); $this->assertFileExists($destFilePath); @@ -250,7 +253,7 @@ public function testSaveFull() { $theme = Theme::load('apitest'); - $destFilePath = $theme->getPath().'/testobjects/compound.htm'; + $destFilePath = $theme->getPath() . '/testobjects/compound.htm'; if (file_exists($destFilePath)) { unlink($destFilePath); } @@ -259,14 +262,14 @@ public function testSaveFull() $obj = TestCmsCompoundObject::inTheme($theme); $obj->fill([ - 'fileName'=>'compound', - 'settings'=>['var'=>'value'], + 'fileName' => 'compound', + 'settings' => ['var' => 'value'], 'code' => 'function a() {return true;}', 'markup' => '

Hello, world!

' ]); $obj->save(); - $referenceFilePath = base_path().'/tests/fixtures/cms/reference/compound-full.htm'; + $referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/compound-full.htm'; $this->assertFileExists($referenceFilePath); $this->assertFileExists($destFilePath); diff --git a/tests/unit/cms/classes/CmsExceptionTest.php b/modules/cms/tests/classes/CmsExceptionTest.php similarity index 93% rename from tests/unit/cms/classes/CmsExceptionTest.php rename to modules/cms/tests/classes/CmsExceptionTest.php index cdc3e4bb2e..2dc127f845 100644 --- a/tests/unit/cms/classes/CmsExceptionTest.php +++ b/modules/cms/tests/classes/CmsExceptionTest.php @@ -1,12 +1,11 @@ property('posts-per-page') == '69'; diff --git a/tests/unit/cms/classes/CmsObjectTest.php b/modules/cms/tests/classes/CmsObjectTest.php similarity index 93% rename from tests/unit/cms/classes/CmsObjectTest.php rename to modules/cms/tests/classes/CmsObjectTest.php index ca5418462d..9d3f3b4b99 100644 --- a/tests/unit/cms/classes/CmsObjectTest.php +++ b/modules/cms/tests/classes/CmsObjectTest.php @@ -1,5 +1,8 @@ assertEquals('

This is a test HTML content file.

', $obj->getContent()); $this->assertEquals('plain.html', $obj->getFileName()); - $path = str_replace('/', DIRECTORY_SEPARATOR, $theme->getPath().'/testobjects/plain.html'); + $path = str_replace('/', DIRECTORY_SEPARATOR, $theme->getPath() . '/testobjects/plain.html'); $this->assertEquals($path, $obj->getFilePath()); $this->assertEquals(filemtime($path), $obj->mtime); } @@ -38,7 +41,7 @@ public function testLoadFromSubdirectory() $this->assertEquals('

This is an object in a subdirectory.

', $obj->getContent()); $this->assertEquals('subdir/obj.html', $obj->getFileName()); - $path = str_replace('/', DIRECTORY_SEPARATOR, $theme->getPath().'/testobjects/subdir/obj.html'); + $path = str_replace('/', DIRECTORY_SEPARATOR, $theme->getPath() . '/testobjects/subdir/obj.html'); $this->assertEquals($path, $obj->getFilePath()); $this->assertEquals(filemtime($path), $obj->mtime); } @@ -214,7 +217,7 @@ public function testSave() { $theme = Theme::load('apitest'); - $destFilePath = $theme->getPath().'/testobjects/mytestobj.htm'; + $destFilePath = $theme->getPath() . '/testobjects/mytestobj.htm'; if (file_exists($destFilePath)) { unlink($destFilePath); } @@ -240,10 +243,10 @@ public function testRename() { $theme = Theme::load('apitest'); - $srcFilePath = $theme->getPath().'/testobjects/mytestobj.htm'; + $srcFilePath = $theme->getPath() . '/testobjects/mytestobj.htm'; $this->assertFileExists($srcFilePath); - $destFilePath = $theme->getPath().'/testobjects/anotherobj.htm'; + $destFilePath = $theme->getPath() . '/testobjects/anotherobj.htm'; if (file_exists($destFilePath)) { unlink($destFilePath); } @@ -272,10 +275,10 @@ public function testRenameToExistingFile() $theme = Theme::load('apitest'); - $srcFilePath = $theme->getPath().'/testobjects/anotherobj.htm'; + $srcFilePath = $theme->getPath() . '/testobjects/anotherobj.htm'; $this->assertFileExists($srcFilePath); - $destFilePath = $theme->getPath().'/testobjects/existingobj.htm'; + $destFilePath = $theme->getPath() . '/testobjects/existingobj.htm'; if (!file_exists($destFilePath)) { file_put_contents($destFilePath, 'str'); } @@ -293,7 +296,7 @@ public function testSaveSameName() { $theme = Theme::load('apitest'); - $filePath = $theme->getPath().'/testobjects/anotherobj.htm'; + $filePath = $theme->getPath() . '/testobjects/anotherobj.htm'; $this->assertFileExists($filePath); $testContents = 'new content'; @@ -313,7 +316,7 @@ public function testSaveNewDir() { $theme = Theme::load('apitest'); - $destFilePath = $theme->getPath().'/testobjects/testsubdir/mytestobj.htm'; + $destFilePath = $theme->getPath() . '/testobjects/testsubdir/mytestobj.htm'; if (file_exists($destFilePath)) { unlink($destFilePath); } diff --git a/tests/unit/cms/classes/CodeParserTest.php b/modules/cms/tests/classes/CodeParserTest.php similarity index 96% rename from tests/unit/cms/classes/CodeParserTest.php rename to modules/cms/tests/classes/CodeParserTest.php index 67d8f30e93..83279f33fb 100644 --- a/tests/unit/cms/classes/CodeParserTest.php +++ b/modules/cms/tests/classes/CodeParserTest.php @@ -1,16 +1,23 @@ source($page, null, $controller); $this->assertInstanceOf(PageCode::class, $obj); - $referenceFilePath = base_path() . '/tests/fixtures/cms/reference/namespaces.php.stub'; + $referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/namespaces.php.stub'; $this->assertFileExists($referenceFilePath); $referenceContents = $this->getContents($referenceFilePath); @@ -295,7 +302,7 @@ public function testNamespacesAliases() $obj = $parser->source($page, null, $controller); $this->assertInstanceOf(PageCode::class, $obj); - $referenceFilePath = base_path() . '/tests/fixtures/cms/reference/namespaces-aliases.php.stub'; + $referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/namespaces-aliases.php.stub'; $this->assertFileExists($referenceFilePath); $referenceContents = $this->getContents($referenceFilePath); diff --git a/tests/unit/cms/classes/ComponentManagerTest.php b/modules/cms/tests/classes/ComponentManagerTest.php similarity index 82% rename from tests/unit/cms/classes/ComponentManagerTest.php rename to modules/cms/tests/classes/ComponentManagerTest.php index 45f3d01dbc..a9e825cccb 100644 --- a/tests/unit/cms/classes/ComponentManagerTest.php +++ b/modules/cms/tests/classes/ComponentManagerTest.php @@ -1,24 +1,28 @@ spoofPageCode(); @@ -114,7 +118,7 @@ public function testMakeComponent() public function testDefineProperties() { - include_once base_path() . '/tests/fixtures/plugins/winter/tester/components/Archive.php'; + include_once base_path() . '/modules/system/tests/fixtures/plugins/winter/tester/components/Archive.php'; $manager = ComponentManager::instance(); $object = $manager->makeComponent('testArchive'); $details = $object->componentDetails(); diff --git a/tests/unit/cms/classes/ContentTest.php b/modules/cms/tests/classes/ContentTest.php similarity index 95% rename from tests/unit/cms/classes/ContentTest.php rename to modules/cms/tests/classes/ContentTest.php index 790501c6f8..7b1298ee88 100644 --- a/tests/unit/cms/classes/ContentTest.php +++ b/modules/cms/tests/classes/ContentTest.php @@ -1,7 +1,10 @@ assertNotEmpty($response); $this->assertInstanceOf('\Illuminate\Http\Response', $response); ob_start(); - include base_path().'/modules/cms/views/404.php'; + include base_path() . '/modules/cms/views/404.php'; $page404Content = ob_get_contents(); ob_end_clean(); $this->assertEquals($page404Content, $response->getContent()); @@ -358,7 +362,7 @@ public function testBasicComponents() public function testComponentAliases() { - include_once base_path() . '/tests/fixtures/plugins/winter/tester/components/Archive.php'; + include_once base_path() . '/modules/system/tests/fixtures/plugins/winter/tester/components/Archive.php'; $theme = Theme::load('test'); $controller = new Controller($theme); diff --git a/tests/unit/cms/classes/PageTest.php b/modules/cms/tests/classes/PageTest.php similarity index 89% rename from tests/unit/cms/classes/PageTest.php rename to modules/cms/tests/classes/PageTest.php index 7a3933406a..796db70ad9 100644 --- a/tests/unit/cms/classes/PageTest.php +++ b/modules/cms/tests/classes/PageTest.php @@ -1,5 +1,8 @@ 'cms-page', 'reference' => 'index', ]; diff --git a/tests/unit/cms/classes/PartialStackTest.php b/modules/cms/tests/classes/PartialStackTest.php similarity index 74% rename from tests/unit/cms/classes/PartialStackTest.php rename to modules/cms/tests/classes/PartialStackTest.php index 5429f3fc9d..e13f448bff 100644 --- a/tests/unit/cms/classes/PartialStackTest.php +++ b/modules/cms/tests/classes/PartialStackTest.php @@ -1,5 +1,8 @@ stackPartial(); - $stack->addComponent('override1', 'Winter\Tester\Components\MainMenu'); - $stack->addComponent('override2', 'Winter\Tester\Components\ContentBlock'); + $stack->addComponent('override1', 'Winter\Tester\Components\MainMenu'); + $stack->addComponent('override2', 'Winter\Tester\Components\ContentBlock'); - $stack->stackPartial(); - $stack->addComponent('override3', 'Winter\Tester\Components\Post'); - $stack->addComponent('post', 'Winter\Tester\Components\Post'); + $stack->stackPartial(); + $stack->addComponent('override3', 'Winter\Tester\Components\Post'); + $stack->addComponent('post', 'Winter\Tester\Components\Post'); - $stack->stackPartial(); - $stack->addComponent('mainMenu', 'Winter\Tester\Components\MainMenu'); + $stack->stackPartial(); + $stack->addComponent('mainMenu', 'Winter\Tester\Components\MainMenu'); /* * Knock em down diff --git a/tests/unit/cms/classes/RouterTest.php b/modules/cms/tests/classes/RouterTest.php similarity index 97% rename from tests/unit/cms/classes/RouterTest.php rename to modules/cms/tests/classes/RouterTest.php index f4eeda27ac..e28c5f00a7 100644 --- a/tests/unit/cms/classes/RouterTest.php +++ b/modules/cms/tests/classes/RouterTest.php @@ -1,13 +1,18 @@ setMaxDepth(1); $it->rewind(); @@ -39,7 +46,7 @@ public function testGetPath() $theme = Theme::load('test'); - $this->assertEquals(base_path('tests/fixtures/themes/test'), $theme->getPath()); + $this->assertEquals(base_path('modules/cms/tests/fixtures/themes/test'), $theme->getPath()); } public function testListPages() @@ -50,7 +57,7 @@ public function testListPages() $pages = array_values($pageCollection->all()); $this->assertIsArray($pages); - $expectedPageNum = $this->countThemePages(base_path().'/tests/fixtures/themes/test/pages'); + $expectedPageNum = $this->countThemePages(base_path() . '/modules/cms/tests/fixtures/themes/test/pages'); $this->assertCount($expectedPageNum, $pages); $this->assertInstanceOf('\Cms\Classes\Page', $pages[0]); diff --git a/tests/fixtures/cms/reference/compound-full.htm b/modules/cms/tests/fixtures/reference/compound-full.htm similarity index 100% rename from tests/fixtures/cms/reference/compound-full.htm rename to modules/cms/tests/fixtures/reference/compound-full.htm diff --git a/tests/fixtures/cms/reference/compound-markup-settings.htm b/modules/cms/tests/fixtures/reference/compound-markup-settings.htm similarity index 100% rename from tests/fixtures/cms/reference/compound-markup-settings.htm rename to modules/cms/tests/fixtures/reference/compound-markup-settings.htm diff --git a/tests/fixtures/cms/reference/compound-markup.htm b/modules/cms/tests/fixtures/reference/compound-markup.htm similarity index 100% rename from tests/fixtures/cms/reference/compound-markup.htm rename to modules/cms/tests/fixtures/reference/compound-markup.htm diff --git a/tests/fixtures/cms/reference/namespaces-aliases.php.stub b/modules/cms/tests/fixtures/reference/namespaces-aliases.php.stub similarity index 100% rename from tests/fixtures/cms/reference/namespaces-aliases.php.stub rename to modules/cms/tests/fixtures/reference/namespaces-aliases.php.stub diff --git a/tests/fixtures/cms/reference/namespaces.php.stub b/modules/cms/tests/fixtures/reference/namespaces.php.stub similarity index 100% rename from tests/fixtures/cms/reference/namespaces.php.stub rename to modules/cms/tests/fixtures/reference/namespaces.php.stub diff --git a/tests/fixtures/themes/apitest/.gitignore b/modules/cms/tests/fixtures/themes/apitest/.gitignore similarity index 100% rename from tests/fixtures/themes/apitest/.gitignore rename to modules/cms/tests/fixtures/themes/apitest/.gitignore diff --git a/tests/fixtures/themes/test/assets/css/style1.css b/modules/cms/tests/fixtures/themes/test/assets/css/style1.css similarity index 100% rename from tests/fixtures/themes/test/assets/css/style1.css rename to modules/cms/tests/fixtures/themes/test/assets/css/style1.css diff --git a/tests/fixtures/themes/test/assets/css/style2.css b/modules/cms/tests/fixtures/themes/test/assets/css/style2.css similarity index 100% rename from tests/fixtures/themes/test/assets/css/style2.css rename to modules/cms/tests/fixtures/themes/test/assets/css/style2.css diff --git a/tests/fixtures/media/winter.png b/modules/cms/tests/fixtures/themes/test/assets/images/winter.png similarity index 100% rename from tests/fixtures/media/winter.png rename to modules/cms/tests/fixtures/themes/test/assets/images/winter.png diff --git a/tests/fixtures/themes/test/assets/js/script1.js b/modules/cms/tests/fixtures/themes/test/assets/js/script1.js similarity index 100% rename from tests/fixtures/themes/test/assets/js/script1.js rename to modules/cms/tests/fixtures/themes/test/assets/js/script1.js diff --git a/tests/fixtures/themes/test/assets/js/script2.js b/modules/cms/tests/fixtures/themes/test/assets/js/script2.js similarity index 100% rename from tests/fixtures/themes/test/assets/js/script2.js rename to modules/cms/tests/fixtures/themes/test/assets/js/script2.js diff --git a/tests/fixtures/themes/test/assets/js/subdir/script1.js b/modules/cms/tests/fixtures/themes/test/assets/js/subdir/script1.js similarity index 100% rename from tests/fixtures/themes/test/assets/js/subdir/script1.js rename to modules/cms/tests/fixtures/themes/test/assets/js/subdir/script1.js diff --git a/tests/fixtures/themes/test/content/a/a-content.htm b/modules/cms/tests/fixtures/themes/test/content/a/a-content.htm similarity index 100% rename from tests/fixtures/themes/test/content/a/a-content.htm rename to modules/cms/tests/fixtures/themes/test/content/a/a-content.htm diff --git a/tests/fixtures/themes/test/content/html-content.htm b/modules/cms/tests/fixtures/themes/test/content/html-content.htm similarity index 100% rename from tests/fixtures/themes/test/content/html-content.htm rename to modules/cms/tests/fixtures/themes/test/content/html-content.htm diff --git a/tests/fixtures/themes/test/content/layout-content.txt b/modules/cms/tests/fixtures/themes/test/content/layout-content.txt similarity index 100% rename from tests/fixtures/themes/test/content/layout-content.txt rename to modules/cms/tests/fixtures/themes/test/content/layout-content.txt diff --git a/tests/fixtures/themes/test/content/markdown-content.md b/modules/cms/tests/fixtures/themes/test/content/markdown-content.md similarity index 100% rename from tests/fixtures/themes/test/content/markdown-content.md rename to modules/cms/tests/fixtures/themes/test/content/markdown-content.md diff --git a/tests/fixtures/themes/test/content/page-content.htm b/modules/cms/tests/fixtures/themes/test/content/page-content.htm similarity index 100% rename from tests/fixtures/themes/test/content/page-content.htm rename to modules/cms/tests/fixtures/themes/test/content/page-content.htm diff --git a/tests/fixtures/themes/test/content/text-content.txt b/modules/cms/tests/fixtures/themes/test/content/text-content.txt similarity index 100% rename from tests/fixtures/themes/test/content/text-content.txt rename to modules/cms/tests/fixtures/themes/test/content/text-content.txt diff --git a/tests/fixtures/themes/test/layouts/a/a-layout.htm b/modules/cms/tests/fixtures/themes/test/layouts/a/a-layout.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/a/a-layout.htm rename to modules/cms/tests/fixtures/themes/test/layouts/a/a-layout.htm diff --git a/tests/fixtures/themes/test/layouts/ajax-test.htm b/modules/cms/tests/fixtures/themes/test/layouts/ajax-test.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/ajax-test.htm rename to modules/cms/tests/fixtures/themes/test/layouts/ajax-test.htm diff --git a/tests/fixtures/themes/test/layouts/content.htm b/modules/cms/tests/fixtures/themes/test/layouts/content.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/content.htm rename to modules/cms/tests/fixtures/themes/test/layouts/content.htm diff --git a/tests/fixtures/themes/test/layouts/cycle-test.htm b/modules/cms/tests/fixtures/themes/test/layouts/cycle-test.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/cycle-test.htm rename to modules/cms/tests/fixtures/themes/test/layouts/cycle-test.htm diff --git a/tests/fixtures/themes/test/layouts/no-php.htm b/modules/cms/tests/fixtures/themes/test/layouts/no-php.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/no-php.htm rename to modules/cms/tests/fixtures/themes/test/layouts/no-php.htm diff --git a/tests/fixtures/themes/test/layouts/partials.htm b/modules/cms/tests/fixtures/themes/test/layouts/partials.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/partials.htm rename to modules/cms/tests/fixtures/themes/test/layouts/partials.htm diff --git a/tests/fixtures/themes/test/layouts/php-parser-test.htm b/modules/cms/tests/fixtures/themes/test/layouts/php-parser-test.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/php-parser-test.htm rename to modules/cms/tests/fixtures/themes/test/layouts/php-parser-test.htm diff --git a/tests/fixtures/themes/test/layouts/placeholder.htm b/modules/cms/tests/fixtures/themes/test/layouts/placeholder.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/placeholder.htm rename to modules/cms/tests/fixtures/themes/test/layouts/placeholder.htm diff --git a/tests/fixtures/themes/test/layouts/sidebar.htm b/modules/cms/tests/fixtures/themes/test/layouts/sidebar.htm similarity index 100% rename from tests/fixtures/themes/test/layouts/sidebar.htm rename to modules/cms/tests/fixtures/themes/test/layouts/sidebar.htm diff --git a/tests/fixtures/themes/test/pages/404.htm b/modules/cms/tests/fixtures/themes/test/pages/404.htm similarity index 100% rename from tests/fixtures/themes/test/pages/404.htm rename to modules/cms/tests/fixtures/themes/test/pages/404.htm diff --git a/tests/fixtures/themes/test/pages/a/a-page.htm b/modules/cms/tests/fixtures/themes/test/pages/a/a-page.htm similarity index 100% rename from tests/fixtures/themes/test/pages/a/a-page.htm rename to modules/cms/tests/fixtures/themes/test/pages/a/a-page.htm diff --git a/tests/fixtures/themes/test/pages/ajax-test.htm b/modules/cms/tests/fixtures/themes/test/pages/ajax-test.htm similarity index 100% rename from tests/fixtures/themes/test/pages/ajax-test.htm rename to modules/cms/tests/fixtures/themes/test/pages/ajax-test.htm diff --git a/tests/fixtures/themes/test/pages/authors.htm b/modules/cms/tests/fixtures/themes/test/pages/authors.htm similarity index 100% rename from tests/fixtures/themes/test/pages/authors.htm rename to modules/cms/tests/fixtures/themes/test/pages/authors.htm diff --git a/tests/fixtures/themes/test/pages/b/b-page.htm b/modules/cms/tests/fixtures/themes/test/pages/b/b-page.htm similarity index 100% rename from tests/fixtures/themes/test/pages/b/b-page.htm rename to modules/cms/tests/fixtures/themes/test/pages/b/b-page.htm diff --git a/tests/fixtures/themes/test/pages/b/c/c-page.htm b/modules/cms/tests/fixtures/themes/test/pages/b/c/c-page.htm similarity index 100% rename from tests/fixtures/themes/test/pages/b/c/c-page.htm rename to modules/cms/tests/fixtures/themes/test/pages/b/c/c-page.htm diff --git a/tests/fixtures/themes/test/pages/blog-archive.htm b/modules/cms/tests/fixtures/themes/test/pages/blog-archive.htm similarity index 100% rename from tests/fixtures/themes/test/pages/blog-archive.htm rename to modules/cms/tests/fixtures/themes/test/pages/blog-archive.htm diff --git a/tests/fixtures/themes/test/pages/blog-category.htm b/modules/cms/tests/fixtures/themes/test/pages/blog-category.htm similarity index 100% rename from tests/fixtures/themes/test/pages/blog-category.htm rename to modules/cms/tests/fixtures/themes/test/pages/blog-category.htm diff --git a/tests/fixtures/themes/test/pages/blog-post.htm b/modules/cms/tests/fixtures/themes/test/pages/blog-post.htm similarity index 100% rename from tests/fixtures/themes/test/pages/blog-post.htm rename to modules/cms/tests/fixtures/themes/test/pages/blog-post.htm diff --git a/tests/fixtures/themes/test/pages/code-namespaces-aliases.htm b/modules/cms/tests/fixtures/themes/test/pages/code-namespaces-aliases.htm similarity index 100% rename from tests/fixtures/themes/test/pages/code-namespaces-aliases.htm rename to modules/cms/tests/fixtures/themes/test/pages/code-namespaces-aliases.htm diff --git a/tests/fixtures/themes/test/pages/code-namespaces.htm b/modules/cms/tests/fixtures/themes/test/pages/code-namespaces.htm similarity index 100% rename from tests/fixtures/themes/test/pages/code-namespaces.htm rename to modules/cms/tests/fixtures/themes/test/pages/code-namespaces.htm diff --git a/tests/fixtures/themes/test/pages/component-custom-render.htm b/modules/cms/tests/fixtures/themes/test/pages/component-custom-render.htm similarity index 100% rename from tests/fixtures/themes/test/pages/component-custom-render.htm rename to modules/cms/tests/fixtures/themes/test/pages/component-custom-render.htm diff --git a/tests/fixtures/themes/test/pages/component-partial-alias-override.htm b/modules/cms/tests/fixtures/themes/test/pages/component-partial-alias-override.htm similarity index 100% rename from tests/fixtures/themes/test/pages/component-partial-alias-override.htm rename to modules/cms/tests/fixtures/themes/test/pages/component-partial-alias-override.htm diff --git a/tests/fixtures/themes/test/pages/component-partial-nesting.htm b/modules/cms/tests/fixtures/themes/test/pages/component-partial-nesting.htm similarity index 100% rename from tests/fixtures/themes/test/pages/component-partial-nesting.htm rename to modules/cms/tests/fixtures/themes/test/pages/component-partial-nesting.htm diff --git a/tests/fixtures/themes/test/pages/component-partial-override.htm b/modules/cms/tests/fixtures/themes/test/pages/component-partial-override.htm similarity index 100% rename from tests/fixtures/themes/test/pages/component-partial-override.htm rename to modules/cms/tests/fixtures/themes/test/pages/component-partial-override.htm diff --git a/tests/fixtures/themes/test/pages/component-partial.htm b/modules/cms/tests/fixtures/themes/test/pages/component-partial.htm similarity index 100% rename from tests/fixtures/themes/test/pages/component-partial.htm rename to modules/cms/tests/fixtures/themes/test/pages/component-partial.htm diff --git a/tests/fixtures/themes/test/pages/cycle-test.htm b/modules/cms/tests/fixtures/themes/test/pages/cycle-test.htm similarity index 100% rename from tests/fixtures/themes/test/pages/cycle-test.htm rename to modules/cms/tests/fixtures/themes/test/pages/cycle-test.htm diff --git a/tests/fixtures/themes/test/pages/filters-test.htm b/modules/cms/tests/fixtures/themes/test/pages/filters-test.htm similarity index 100% rename from tests/fixtures/themes/test/pages/filters-test.htm rename to modules/cms/tests/fixtures/themes/test/pages/filters-test.htm diff --git a/tests/fixtures/themes/test/pages/index.htm b/modules/cms/tests/fixtures/themes/test/pages/index.htm similarity index 100% rename from tests/fixtures/themes/test/pages/index.htm rename to modules/cms/tests/fixtures/themes/test/pages/index.htm diff --git a/tests/fixtures/themes/test/pages/no-component-class.htm b/modules/cms/tests/fixtures/themes/test/pages/no-component-class.htm similarity index 100% rename from tests/fixtures/themes/test/pages/no-component-class.htm rename to modules/cms/tests/fixtures/themes/test/pages/no-component-class.htm diff --git a/tests/fixtures/themes/test/pages/no-component.htm b/modules/cms/tests/fixtures/themes/test/pages/no-component.htm similarity index 100% rename from tests/fixtures/themes/test/pages/no-component.htm rename to modules/cms/tests/fixtures/themes/test/pages/no-component.htm diff --git a/tests/fixtures/themes/test/pages/no-layout.htm b/modules/cms/tests/fixtures/themes/test/pages/no-layout.htm similarity index 100% rename from tests/fixtures/themes/test/pages/no-layout.htm rename to modules/cms/tests/fixtures/themes/test/pages/no-layout.htm diff --git a/tests/fixtures/themes/test/pages/no-partial.htm b/modules/cms/tests/fixtures/themes/test/pages/no-partial.htm similarity index 100% rename from tests/fixtures/themes/test/pages/no-partial.htm rename to modules/cms/tests/fixtures/themes/test/pages/no-partial.htm diff --git a/tests/fixtures/themes/test/pages/no-soft-component-class.htm b/modules/cms/tests/fixtures/themes/test/pages/no-soft-component-class.htm similarity index 100% rename from tests/fixtures/themes/test/pages/no-soft-component-class.htm rename to modules/cms/tests/fixtures/themes/test/pages/no-soft-component-class.htm diff --git a/tests/fixtures/themes/test/pages/optional-full-php-tags.htm b/modules/cms/tests/fixtures/themes/test/pages/optional-full-php-tags.htm similarity index 100% rename from tests/fixtures/themes/test/pages/optional-full-php-tags.htm rename to modules/cms/tests/fixtures/themes/test/pages/optional-full-php-tags.htm diff --git a/tests/fixtures/themes/test/pages/optional-short-php-tags.htm b/modules/cms/tests/fixtures/themes/test/pages/optional-short-php-tags.htm similarity index 100% rename from tests/fixtures/themes/test/pages/optional-short-php-tags.htm rename to modules/cms/tests/fixtures/themes/test/pages/optional-short-php-tags.htm diff --git a/tests/fixtures/themes/test/pages/throw-php.htm b/modules/cms/tests/fixtures/themes/test/pages/throw-php.htm similarity index 100% rename from tests/fixtures/themes/test/pages/throw-php.htm rename to modules/cms/tests/fixtures/themes/test/pages/throw-php.htm diff --git a/tests/fixtures/themes/test/pages/with-component.htm b/modules/cms/tests/fixtures/themes/test/pages/with-component.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-component.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-component.htm diff --git a/tests/fixtures/themes/test/pages/with-components.htm b/modules/cms/tests/fixtures/themes/test/pages/with-components.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-components.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-components.htm diff --git a/tests/fixtures/themes/test/pages/with-content.htm b/modules/cms/tests/fixtures/themes/test/pages/with-content.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-content.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-content.htm diff --git a/tests/fixtures/themes/test/pages/with-layout.htm b/modules/cms/tests/fixtures/themes/test/pages/with-layout.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-layout.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-layout.htm diff --git a/tests/fixtures/themes/test/pages/with-partials.htm b/modules/cms/tests/fixtures/themes/test/pages/with-partials.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-partials.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-partials.htm diff --git a/tests/fixtures/themes/test/pages/with-placeholder.htm b/modules/cms/tests/fixtures/themes/test/pages/with-placeholder.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-placeholder.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-placeholder.htm diff --git a/tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm b/modules/cms/tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm diff --git a/tests/fixtures/themes/test/pages/with-soft-component-class.htm b/modules/cms/tests/fixtures/themes/test/pages/with-soft-component-class.htm similarity index 100% rename from tests/fixtures/themes/test/pages/with-soft-component-class.htm rename to modules/cms/tests/fixtures/themes/test/pages/with-soft-component-class.htm diff --git a/tests/fixtures/themes/test/partials/a/a-partial.htm b/modules/cms/tests/fixtures/themes/test/partials/a/a-partial.htm similarity index 100% rename from tests/fixtures/themes/test/partials/a/a-partial.htm rename to modules/cms/tests/fixtures/themes/test/partials/a/a-partial.htm diff --git a/tests/fixtures/themes/test/partials/ajax-result.htm b/modules/cms/tests/fixtures/themes/test/partials/ajax-result.htm similarity index 100% rename from tests/fixtures/themes/test/partials/ajax-result.htm rename to modules/cms/tests/fixtures/themes/test/partials/ajax-result.htm diff --git a/tests/fixtures/themes/test/partials/ajax-second-result.htm b/modules/cms/tests/fixtures/themes/test/partials/ajax-second-result.htm similarity index 100% rename from tests/fixtures/themes/test/partials/ajax-second-result.htm rename to modules/cms/tests/fixtures/themes/test/partials/ajax-second-result.htm diff --git a/tests/fixtures/themes/test/partials/layout-partial.htm b/modules/cms/tests/fixtures/themes/test/partials/layout-partial.htm similarity index 100% rename from tests/fixtures/themes/test/partials/layout-partial.htm rename to modules/cms/tests/fixtures/themes/test/partials/layout-partial.htm diff --git a/tests/fixtures/themes/test/partials/nesting/level1.htm b/modules/cms/tests/fixtures/themes/test/partials/nesting/level1.htm similarity index 100% rename from tests/fixtures/themes/test/partials/nesting/level1.htm rename to modules/cms/tests/fixtures/themes/test/partials/nesting/level1.htm diff --git a/tests/fixtures/themes/test/partials/nesting/level2.htm b/modules/cms/tests/fixtures/themes/test/partials/nesting/level2.htm similarity index 100% rename from tests/fixtures/themes/test/partials/nesting/level2.htm rename to modules/cms/tests/fixtures/themes/test/partials/nesting/level2.htm diff --git a/tests/fixtures/themes/test/partials/nesting/level3.htm b/modules/cms/tests/fixtures/themes/test/partials/nesting/level3.htm similarity index 100% rename from tests/fixtures/themes/test/partials/nesting/level3.htm rename to modules/cms/tests/fixtures/themes/test/partials/nesting/level3.htm diff --git a/tests/fixtures/themes/test/partials/override1/default.htm b/modules/cms/tests/fixtures/themes/test/partials/override1/default.htm similarity index 100% rename from tests/fixtures/themes/test/partials/override1/default.htm rename to modules/cms/tests/fixtures/themes/test/partials/override1/default.htm diff --git a/tests/fixtures/themes/test/partials/override2/default.htm b/modules/cms/tests/fixtures/themes/test/partials/override2/default.htm similarity index 100% rename from tests/fixtures/themes/test/partials/override2/default.htm rename to modules/cms/tests/fixtures/themes/test/partials/override2/default.htm diff --git a/tests/fixtures/themes/test/partials/override2/items.htm b/modules/cms/tests/fixtures/themes/test/partials/override2/items.htm similarity index 100% rename from tests/fixtures/themes/test/partials/override2/items.htm rename to modules/cms/tests/fixtures/themes/test/partials/override2/items.htm diff --git a/tests/fixtures/themes/test/partials/override3/default.htm b/modules/cms/tests/fixtures/themes/test/partials/override3/default.htm similarity index 100% rename from tests/fixtures/themes/test/partials/override3/default.htm rename to modules/cms/tests/fixtures/themes/test/partials/override3/default.htm diff --git a/tests/fixtures/themes/test/partials/override4/default.htm b/modules/cms/tests/fixtures/themes/test/partials/override4/default.htm similarity index 100% rename from tests/fixtures/themes/test/partials/override4/default.htm rename to modules/cms/tests/fixtures/themes/test/partials/override4/default.htm diff --git a/tests/fixtures/themes/test/partials/page-partial.htm b/modules/cms/tests/fixtures/themes/test/partials/page-partial.htm similarity index 100% rename from tests/fixtures/themes/test/partials/page-partial.htm rename to modules/cms/tests/fixtures/themes/test/partials/page-partial.htm diff --git a/tests/fixtures/themes/test/partials/testpost/default.htm b/modules/cms/tests/fixtures/themes/test/partials/testpost/default.htm similarity index 100% rename from tests/fixtures/themes/test/partials/testpost/default.htm rename to modules/cms/tests/fixtures/themes/test/partials/testpost/default.htm diff --git a/tests/fixtures/themes/test/temporary/.gitignore b/modules/cms/tests/fixtures/themes/test/temporary/.gitignore similarity index 100% rename from tests/fixtures/themes/test/temporary/.gitignore rename to modules/cms/tests/fixtures/themes/test/temporary/.gitignore diff --git a/tests/fixtures/themes/test/testobjects/component.htm b/modules/cms/tests/fixtures/themes/test/testobjects/component.htm similarity index 100% rename from tests/fixtures/themes/test/testobjects/component.htm rename to modules/cms/tests/fixtures/themes/test/testobjects/component.htm diff --git a/tests/fixtures/themes/test/testobjects/components.htm b/modules/cms/tests/fixtures/themes/test/testobjects/components.htm similarity index 100% rename from tests/fixtures/themes/test/testobjects/components.htm rename to modules/cms/tests/fixtures/themes/test/testobjects/components.htm diff --git a/tests/fixtures/themes/test/testobjects/compound.htm b/modules/cms/tests/fixtures/themes/test/testobjects/compound.htm similarity index 100% rename from tests/fixtures/themes/test/testobjects/compound.htm rename to modules/cms/tests/fixtures/themes/test/testobjects/compound.htm diff --git a/tests/fixtures/themes/test/testobjects/plain.html b/modules/cms/tests/fixtures/themes/test/testobjects/plain.html similarity index 100% rename from tests/fixtures/themes/test/testobjects/plain.html rename to modules/cms/tests/fixtures/themes/test/testobjects/plain.html diff --git a/tests/fixtures/themes/test/testobjects/subdir/obj.html b/modules/cms/tests/fixtures/themes/test/testobjects/subdir/obj.html similarity index 100% rename from tests/fixtures/themes/test/testobjects/subdir/obj.html rename to modules/cms/tests/fixtures/themes/test/testobjects/subdir/obj.html diff --git a/tests/fixtures/themes/test/testobjects/viewbag.htm b/modules/cms/tests/fixtures/themes/test/testobjects/viewbag.htm similarity index 100% rename from tests/fixtures/themes/test/testobjects/viewbag.htm rename to modules/cms/tests/fixtures/themes/test/testobjects/viewbag.htm diff --git a/tests/unit/cms/helpers/FileTest.php b/modules/cms/tests/helpers/FileTest.php similarity index 90% rename from tests/unit/cms/helpers/FileTest.php rename to modules/cms/tests/helpers/FileTest.php index dde19f0c38..2e9496c352 100644 --- a/tests/unit/cms/helpers/FileTest.php +++ b/modules/cms/tests/helpers/FileTest.php @@ -1,6 +1,9 @@ setRoot($root); - } else { - $this->setRoot(base_path()); - } - - if (isset($modules)) { - $this->setModules($modules); - } else { - $this->setModules(Config::get('cms.loadModules', ['System', 'Backend', 'Cms'])); - } + $this->setRoot($root ?? base_path()); + $this->setModules($modules ?? Config::get('cms.loadModules', ['System', 'Backend', 'Cms'])); } /** @@ -78,7 +66,7 @@ public function __construct($root = null, array $modules = null) * @param string $root * @throws ApplicationException If the specified root does not exist. */ - public function setRoot($root) + public function setRoot(string $root): static { if (is_string($root)) { $this->root = realpath($root); @@ -98,7 +86,7 @@ public function setRoot($root) * * @param array $modules */ - public function setModules(array $modules) + public function setModules(array $modules): static { $this->modules = array_map(function ($module) { return strtolower($module); @@ -112,7 +100,7 @@ public function setModules(array $modules) * * @return array */ - public function getFiles() + public function getFiles(): array { if (count($this->files)) { return $this->files; @@ -140,7 +128,7 @@ public function getFiles() * * @return array */ - public function getModuleChecksums() + public function getModuleChecksums(): array { if (!count($this->files)) { $this->getFiles(); @@ -169,7 +157,7 @@ public function getModuleChecksums() * @param string $basePath The base path to look for files within. * @return array */ - protected function findFiles(string $basePath) + protected function findFiles(string $basePath): array { $datasource = new FileDatasource($basePath, new Filesystem); diff --git a/modules/system/classes/SourceManifest.php b/modules/system/classes/SourceManifest.php index 24428f753a..08acaf8926 100644 --- a/modules/system/classes/SourceManifest.php +++ b/modules/system/classes/SourceManifest.php @@ -42,34 +42,18 @@ class SourceManifest /** * Constructor - * - * @param string $manifest Manifest file to load - * @param string $branches Branches manifest file to load - * @param bool $autoload Loads the manifest on construct */ - public function __construct($source = null, $forks = null, $autoload = true) + public function __construct(string $source = null, string $forks = null, bool $autoload = true) { - if (isset($source)) { - $this->setSource($source); - } else { - $this->setSource( - Config::get( - 'cms.sourceManifestUrl', - 'https://raw.githubusercontent.com/wintercms/meta/master/manifest/builds.json' - ) - ); - } + $this->setSource($source ?? Config::get( + 'cms.sourceManifestUrl', + 'https://raw.githubusercontent.com/wintercms/meta/master/manifest/builds.json' + )); - if (isset($forks)) { - $this->setForksSource($forks); - } else { - $this->setForksSource( - Config::get( - 'cms.forkManifestUrl', - 'https://raw.githubusercontent.com/wintercms/meta/master/manifest/forks.json' - ) - ); - } + $this->setForksSource($forks ?? Config::get( + 'cms.forkManifestUrl', + 'https://raw.githubusercontent.com/wintercms/meta/master/manifest/forks.json' + )); if ($autoload) { $this->loadSource(); @@ -108,7 +92,7 @@ public function setForksSource($forks) * * @throws ApplicationException If the manifest is invalid, or cannot be parsed. */ - public function loadSource() + public function loadSource(): static { if (file_exists($this->source)) { $source = file_get_contents($this->source); @@ -152,7 +136,7 @@ public function loadSource() * * @throws ApplicationException If the manifest is invalid, or cannot be parsed. */ - public function loadForks() + public function loadForks(): static { if (file_exists($this->forksUrl)) { $forks = file_get_contents($this->forksUrl); @@ -222,7 +206,7 @@ public function addBuild($build, FileManifest $manifest) * * @return array */ - public function getBuilds() + public function getBuilds(): array { return array_values(array_map(function ($build) { return $build['version']; @@ -233,9 +217,8 @@ public function getBuilds() * Generates the JSON data to be stored with the source manifest. * * @throws ApplicationException If no builds have been added to this source manifest. - * @return string */ - public function generate() + public function generate(): string { if (!count($this->builds)) { throw new ApplicationException( @@ -270,9 +253,8 @@ public function generate() * * @param string|integer $build Build version to get the filelist state for. * @throws ApplicationException If the specified build has not been added to the source manifest. - * @return array */ - public function getState($build) + public function getState(mixed $build): array { if (is_string($build)) { $build = $this->getVersionInt($build); @@ -328,9 +310,8 @@ public function getState($build) * * @param FileManifest $manifest The file manifest to compare against the source. * @param bool $detailed If true, the list of files modified, added and deleted will be included in the result. - * @return array */ - public function compare(FileManifest $manifest, $detailed = false) + public function compare(FileManifest $manifest, $detailed = false): array { $modules = $manifest->getModuleChecksums(); @@ -431,7 +412,7 @@ public function compare(FileManifest $manifest, $detailed = false) * or string, used to determine changes with this build. * @return array */ - protected function processChanges(FileManifest $manifest, $previous = null) + protected function processChanges(FileManifest $manifest, $previous = null): array { // If no previous build has been provided, all files are added if (is_null($previous)) { @@ -503,11 +484,9 @@ protected function determineParent(string $build) /** * Converts a version string into an integer for comparison. * - * @param string $version * @throws ApplicationException if a version string does not match the format "major.minor.path" - * @return int */ - protected function getVersionInt(string $version) + protected function getVersionInt(string $version): int { // Get major.minor.patch versions if (!preg_match('/^([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $versionParts)) { diff --git a/modules/system/console/WinterTest.php b/modules/system/console/WinterTest.php index a0709742e9..f66b15b21f 100644 --- a/modules/system/console/WinterTest.php +++ b/modules/system/console/WinterTest.php @@ -7,9 +7,10 @@ use Symfony\Component\Process\Process; use System\Classes\PluginManager; use Winter\Storm\Exception\ApplicationException; +use Config; /** - * Console command to run tests for plugins or the Winter CMS core. + * Console command to run tests for plugins and modules. * * If a plugin is provided, this command will search for a `phpunit.xml` file inside the plugin's directory and run its tests. * @@ -17,6 +18,11 @@ */ class WinterTest extends Command { + /** + * @var string|null The default command name for lazy loading. + */ + protected static $defaultName = 'winter:test'; + /** * @var string The console command name. */ @@ -25,7 +31,12 @@ class WinterTest extends Command /** * @var string The console command signature as ignoreValidationErrors causes options not to be registered. */ - protected $signature = 'winter:test {?--p|plugin=} {?--c|configuration=} {?--o|core}'; + protected $signature = 'winter:test + {phpunitArgs?* : Arguments to pass through to PHPUnit} + {?--c|configuration= : A specific phpunit xml file} + {?--p|plugin=* : List of plugins to test} + {?--m|module=* : List of modules to test} + '; /** * @var string The console command description. @@ -61,62 +72,55 @@ public function __construct() */ public function handle() { - $arguments = $this->getAdditionalArguments(); + $arguments = $this->argument('phpunitArgs'); if (($config = $this->option('configuration')) && file_exists($config)) { return $this->execPhpUnit($config, $arguments); } $configs = $this->getPhpUnitConfigs(); - - if ($this->option('core')) { - if (!$configs['core']) { - throw new ApplicationException("Unable to find the core's phpunit.xml file. Try downloading it from GitHub."); + $exitCode = null; + + // loop over arguments and run specified tests + foreach (['module', 'plugin'] as $type) { + if ($this->option($type)) { + foreach ($this->option($type) as $target) { + $target = strtolower($target); + if (!isset($configs[$type . 's'][$target])) { + throw new ApplicationException(sprintf( + 'Unable to find %s %s\'s phpunit.xml file', + $type, + $target + )); + } + $this->info(sprintf('Running tests for %s: %s', $type, $target)); + $exit = $this->execPhpUnit($configs[$type . 's'][$target], $arguments); + // keep non 0 exit codes for return + $exitCode = !$exitCode ? $exit : $exitCode; + } } - $this->info('Running tests for: Winter CMS core'); - - return $this->execPhpUnit($configs['core'], $arguments); } - if ($plugin = $this->option('plugin')) { - if (!isset($configs['plugins'][strtolower($plugin)])) { - throw new ApplicationException(sprintf("Unable to find %s\'s phpunit.xml file", $plugin)); - } - $this->info('Running tests for plugin: ' . PluginManager::instance()->normalizeIdentifier($plugin)); - - return $this->execPhpUnit($configs['plugins'][strtolower($plugin)], $arguments); + // if we ran a specific test above we should have an exit code + if (!is_null($exitCode)) { + return $exitCode; } - $exitCode = 0; - - foreach (['core', 'plugins'] as $type) { - if (is_array($configs[$type])) { - foreach ($configs[$type] as $plugin => $config) { - $this->info('Running tests for plugin: ' . PluginManager::instance()->normalizeIdentifier($plugin)); - $exit = $this->execPhpUnit($config, $arguments); - $exitCode = $exitCode === 0 ? $exit : $exitCode; - } - continue; + // default to running all defined configs found + foreach (['modules', 'plugins'] as $type) { + foreach ($configs[$type] as $name => $config) { + $this->info( + $type === 'plugins' + ? 'Running tests for plugin: ' . PluginManager::instance()->normalizeIdentifier($name) + : 'Running tests for module: ' . $name + ); + $exit = $this->execPhpUnit($config, $arguments); + // keep non 0 exit codes for return + $exitCode = !$exitCode ? $exit : $exitCode; } - - $this->info('Running tests for Winter CMS: ' . $type); - $exit = $this->execPhpUnit($configs[$type], $arguments); - $exitCode = $exitCode === 0 ? $exit : $exitCode; } - return $exitCode; - } - - /** - * Get the console command options. - */ - protected function getOptions(): array - { - return [ - ['plugin', 'p', InputOption::VALUE_OPTIONAL, 'The name of the plugin. Ex: AuthorName.PluginName', null], - ['configuration', 'c', InputOption::VALUE_OPTIONAL, 'The path to a PHPUnit XML config file', null], - ['core', 'o', InputOption::VALUE_NONE, 'Run the Winter CMS core tests'], - ]; + return $exitCode ?? 0; } /** @@ -173,10 +177,17 @@ protected function execPhpUnit(string $config, array $args): int protected function getPhpUnitConfigs(): array { $configs = [ - 'core' => $this->getPhpUnitXmlFile(base_path()), + 'modules' => [], 'plugins' => [] ]; + foreach (Config::get('cms.loadModules', ['System', 'Cms', 'Backend']) as $module) { + $module = strtolower($module); + if ($path = $this->getPhpUnitXmlFile(base_path('modules/' . $module))) { + $configs['modules'][$module] = $path; + } + } + foreach (PluginManager::instance()->getPlugins() as $plugin) { if ($path = $this->getPhpUnitXmlFile($plugin->getPluginPath())) { $configs['plugins'][strtolower($plugin->getPluginIdentifier())] = $path; @@ -193,68 +204,18 @@ protected function getPhpUnitConfigs(): array protected function getPhpUnitXmlFile(string $path): ?string { // If a phpunit.xml file exists, returns its path - $distFilePath = $path . DIRECTORY_SEPARATOR . 'phpunit.xml'; - if (file_exists($distFilePath)) { - return $distFilePath; - } + $configFilePath = $path . DIRECTORY_SEPARATOR . 'phpunit.xml'; - // Fallback to phpunit.xml.dist file path if it exists - $configFilePath = $path . DIRECTORY_SEPARATOR . 'phpunit.xml.dist'; if (file_exists($configFilePath)) { return $configFilePath; } - return null; - } - - /** - * Strips out commands arguments and options in order to return arguments/options for PHPUnit. - */ - protected function getAdditionalArguments(): array - { - $arguments = $_SERVER['argv']; - - // First two are always "artisan" and "winter:test" - $arguments = array_slice($arguments, 2); - - // If nothing to do then just return - if (!count($arguments)) { - return $arguments; - } - - // Get the arguments provided by this command - foreach ($this->getOptions() as $argument) { - // For position 0 & 1, pass their names with appropriate dashes - for ($i = 0; $i < 2; $i++) { - $arguments = $this->removeArgument($arguments, str_repeat('-', 2 - $i) . $argument[$i]); - } - } - - return $arguments; - } - - /** - * Removes flags from argument list and their value if present - */ - protected function removeArgument(array $arguments, string $remove): array - { - // find args that have trailing chars - $key = array_values(preg_grep("/^({$remove}|{$remove}=).*/i", $arguments)); - $remove = (isset($key[0])) ? $key[0] : $remove; - - // find the position of arguments to remove - if (($position = array_search($remove, $arguments)) === false) { - return $arguments; - } - - // remove argument - unset($arguments[$position]); - - // if the next item in the array is not a flag, consider it a value of the removed argument - if (isset($arguments[$position + 1]) && substr($arguments[$position + 1], 0, 1) !== '-') { - unset($arguments[$position + 1]); + // Fallback to phpunit.xml.dist file path if it exists + $distFilePath = $path . DIRECTORY_SEPARATOR . 'phpunit.xml.dist'; + if (file_exists($distFilePath)) { + return $distFilePath; } - return array_values($arguments); + return null; } } diff --git a/modules/system/phpunit.xml b/modules/system/phpunit.xml new file mode 100644 index 0000000000..6b6057c712 --- /dev/null +++ b/modules/system/phpunit.xml @@ -0,0 +1,22 @@ + + + + + ./tests + + + + + + + + diff --git a/tests/unit/system/AliasesTest.php b/modules/system/tests/AliasesTest.php similarity index 90% rename from tests/unit/system/AliasesTest.php rename to modules/system/tests/AliasesTest.php index 88649f088b..7a5b93ff3a 100644 --- a/tests/unit/system/AliasesTest.php +++ b/modules/system/tests/AliasesTest.php @@ -1,5 +1,9 @@ make('Illuminate\Contracts\Console\Kernel')->bootstrap(); $app['cache']->setDefaultDriver('array'); @@ -51,7 +57,7 @@ public function createApplication() /* * Modify the plugin path away from the test context */ - $app->setPluginsPath(realpath(base_path().Config::get('cms.pluginsPath'))); + $app->setPluginsPath(realpath(base_path() . Config::get('cms.pluginsPath'))); return $app; } @@ -126,7 +132,7 @@ protected function runPluginRefreshCommand($code, $throwException = true) if (!$throwException) { return; } - throw new Exception(sprintf('Invalid plugin code: "%s"', $code)); + throw new \Exception(sprintf('Invalid plugin code: "%s"', $code)); } $manager = PluginManager::instance(); diff --git a/tests/TestCase.php b/modules/system/tests/bootstrap/TestCase.php similarity index 93% rename from tests/TestCase.php rename to modules/system/tests/bootstrap/TestCase.php index a4d5b1569d..3bdb052718 100644 --- a/tests/TestCase.php +++ b/modules/system/tests/bootstrap/TestCase.php @@ -1,8 +1,11 @@ make('Illuminate\Contracts\Console\Kernel')->bootstrap(); diff --git a/tests/bootstrap.php b/modules/system/tests/bootstrap/app.php similarity index 60% rename from tests/bootstrap.php rename to modules/system/tests/bootstrap/app.php index 6e1d5a9fd5..12f3215f09 100644 --- a/tests/bootstrap.php +++ b/modules/system/tests/bootstrap/app.php @@ -1,17 +1,19 @@ register(); @@ -19,3 +21,4 @@ 'modules', 'plugins' ]); + diff --git a/tests/unit/system/classes/AutoDatasourceTest.php b/modules/system/tests/classes/AutoDatasourceTest.php similarity index 93% rename from tests/unit/system/classes/AutoDatasourceTest.php rename to modules/system/tests/classes/AutoDatasourceTest.php index bc459cd40c..d3550ee691 100644 --- a/tests/unit/system/classes/AutoDatasourceTest.php +++ b/modules/system/tests/classes/AutoDatasourceTest.php @@ -1,5 +1,8 @@ datasource = new AutoDatasource([ 'database' => new DbDatasource('test', 'cms_theme_templates'), - 'filesystem' => new FileDatasource(base_path('tests/fixtures/themes/test'), App::make('files')), + 'filesystem' => new FileDatasource( + base_path('modules/system/tests/fixtures/themes/test'), + \App::make('files') + ), ]); } diff --git a/tests/unit/system/classes/CombineAssetsTest.php b/modules/system/tests/classes/CombineAssetsTest.php similarity index 90% rename from tests/unit/system/classes/CombineAssetsTest.php rename to modules/system/tests/classes/CombineAssetsTest.php index 5c5d313bdb..a34dbca8bb 100644 --- a/tests/unit/system/classes/CombineAssetsTest.php +++ b/modules/system/tests/classes/CombineAssetsTest.php @@ -1,5 +1,8 @@ assertNotNull($url); $this->assertRegExp('/\w+[-]\d+/i', $url); // Must contain hash-number @@ -55,7 +58,7 @@ public function testCombine() 'assets/js/script1.js', 'assets/js/script2.js' ], - base_path().'/tests/fixtures/themes/test' + base_path() . '/modules/system/tests/fixtures/themes/test' ); $this->assertNotNull($url); $this->assertRegExp('/\w+[-]\d+/i', $url); // Must contain hash-number @@ -87,7 +90,7 @@ public function testGetTargetPath() public function testMakeCacheId() { $sampleResources = ['assets/css/style1.css', 'assets/css/style2.css']; - $samplePath = base_path().'/tests/fixtures/cms/themes/test'; + $samplePath = base_path() . '/modules/system/tests/fixtures/cms/themes/test'; $combiner = CombineAssets::instance(); self::setProtectedProperty($combiner, 'localPath', $samplePath); diff --git a/tests/unit/system/classes/CoreLangTest.php b/modules/system/tests/classes/CoreLangTest.php similarity index 94% rename from tests/unit/system/classes/CoreLangTest.php rename to modules/system/tests/classes/CoreLangTest.php index 54899a8125..d66a0dbe13 100644 --- a/tests/unit/system/classes/CoreLangTest.php +++ b/modules/system/tests/classes/CoreLangTest.php @@ -1,6 +1,10 @@ fileManifest = new FileManifest(base_path('tests/fixtures/manifest/1_0_1'), ['test', 'test2']); + $this->fileManifest = new FileManifest( + base_path('modules/system/tests/fixtures/manifest/1_0_1'), + ['test', 'test2'] + ); } public function testGetFiles() diff --git a/tests/unit/system/classes/ImageResizerTest.php b/modules/system/tests/classes/ImageResizerTest.php similarity index 93% rename from tests/unit/system/classes/ImageResizerTest.php rename to modules/system/tests/classes/ImageResizerTest.php index 27b051a612..b3bb181260 100644 --- a/tests/unit/system/classes/ImageResizerTest.php +++ b/modules/system/tests/classes/ImageResizerTest.php @@ -1,5 +1,8 @@ getConfig()); // Resize with an customised defaults - $this->markTestSkipped('@TODO: Something is going funky with serialized closures in PHP 8.0 / Laravel 9.x'); +// $this->markTestSkipped('@TODO: Something is going funky with serialized closures in PHP 8.0 / Laravel 9.x'); Event::listen('system.resizer.getDefaultOptions', function (&$options) { $options = array_merge($options, [ 'mode' => 'fit', @@ -253,7 +260,7 @@ public function testURLSources() // URL for a FileModel instance (absolute URL) $fileModel = new FileModel(); - $fileModel->fromFile(base_path('tests/fixtures/plugins/database/tester/assets/images/avatar.png')); + $fileModel->fromFile(base_path('modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png')); $fileModel->save(); $imageResizer = new ImageResizer( @@ -268,7 +275,7 @@ public function testURLSources() // URL of a FileModel instance (relative URL) $fileModel = new FileModel(); - $fileModel->fromFile(base_path('tests/fixtures/plugins/database/tester/assets/images/avatar.png')); + $fileModel->fromFile(base_path('modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png')); $fileModel->save(); $imageResizer = new ImageResizer( @@ -283,7 +290,7 @@ public function testDirectSources() { // FileModel instance itself $fileModel = new FileModel(); - $fileModel->fromFile(base_path('tests/fixtures/plugins/database/tester/assets/images/avatar.png')); + $fileModel->fromFile(base_path('modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png')); $fileModel->save(); $imageResizer = new ImageResizer( @@ -346,7 +353,7 @@ public function testGetResizedUrl() Config::set('cms.linkPolicy', 'detect'); $url = $imageResizer->getResizedUrl(); - $this->assertTrue(starts_with($url, Config::get('cms.storage.resized.path', '/tests/storage/app/resized'))); + $this->assertTrue(starts_with($url, Config::get('cms.storage.resized.path', '/storage/tests/app/resized'))); } public function testGetResizerUrl() @@ -386,7 +393,7 @@ protected function copyMedia() mkdir($mediaPath, 0777, true); } - foreach (glob(base_path('tests/fixtures/media/*')) as $file) { + foreach (glob(base_path('modules/system/tests/fixtures/media/*')) as $file) { $path = pathinfo($file); copy($file, $mediaPath . DIRECTORY_SEPARATOR . $path['basename']); } diff --git a/tests/unit/system/classes/MarkupManagerTest.php b/modules/system/tests/classes/MarkupManagerTest.php similarity index 93% rename from tests/unit/system/classes/MarkupManagerTest.php rename to modules/system/tests/classes/MarkupManagerTest.php index a415b49a25..d5453d193d 100644 --- a/tests/unit/system/classes/MarkupManagerTest.php +++ b/modules/system/tests/classes/MarkupManagerTest.php @@ -1,5 +1,8 @@ loadPlugins(); self::callProtectedMethod($manager, 'loadDependencies'); + self::callProtectedMethod($manager, 'detectPluginReplacements'); $this->manager = $manager; } @@ -156,7 +163,7 @@ public function testGetPluginPath() { $result = $this->manager->getPluginPath('Winter\Tester'); $basePath = str_replace('\\', '/', base_path()); - $this->assertEquals($basePath . '/tests/fixtures/plugins/winter/tester', $result); + $this->assertEquals($basePath . '/modules/system/tests/fixtures/plugins/winter/tester', $result); } public function testGetPlugins() diff --git a/tests/unit/system/classes/SourceManifestTest.php b/modules/system/tests/classes/SourceManifestTest.php similarity index 86% rename from tests/unit/system/classes/SourceManifestTest.php rename to modules/system/tests/classes/SourceManifestTest.php index 8fc7267b21..3b3ed20ea3 100644 --- a/tests/unit/system/classes/SourceManifestTest.php +++ b/modules/system/tests/classes/SourceManifestTest.php @@ -1,5 +1,8 @@ builds = [ - '1.0.0' => new FileManifest(base_path('tests/fixtures/manifest/1_0_0'), ['test', 'test2']), - '1.0.1' => new FileManifest(base_path('tests/fixtures/manifest/1_0_1'), ['test', 'test2']), - '1.0.2' => new FileManifest(base_path('tests/fixtures/manifest/1_0_2'), ['test', 'test2']), - '1.1.0' => new FileManifest(base_path('tests/fixtures/manifest/1_1_0'), ['test', 'test2', 'test3']), - '1.1.1' => new FileManifest(base_path('tests/fixtures/manifest/1_1_1'), ['test', 'test2', 'test3']), - '1.0.3' => new FileManifest(base_path('tests/fixtures/manifest/1_0_3'), ['test', 'test2']), + '1.0.0' => new FileManifest( + base_path('modules/system/tests/fixtures/manifest/1_0_0'), + ['test', 'test2'] + ), + '1.0.1' => new FileManifest( + base_path('modules/system/tests/fixtures/manifest/1_0_1'), + ['test', 'test2'] + ), + '1.0.2' => new FileManifest( + base_path('modules/system/tests/fixtures/manifest/1_0_2'), + ['test', 'test2'] + ), + '1.1.0' => new FileManifest( + base_path('modules/system/tests/fixtures/manifest/1_1_0'), + ['test', 'test2', 'test3'] + ), + '1.1.1' => new FileManifest( + base_path('modules/system/tests/fixtures/manifest/1_1_1'), + ['test', 'test2', 'test3'] + ), + '1.0.3' => new FileManifest( + base_path('modules/system/tests/fixtures/manifest/1_0_3'), + ['test', 'test2'] + ), ]; $this->sourceManifest = new SourceManifest($this->manifestPath(), $this->forksPath(), false); @@ -252,13 +273,13 @@ public function testCompareModified() $this->createManifest(); // Hot-swap "tests/fixtures/manifest/1_1_1/modules/test/file3.php" - $old = file_get_contents(base_path('tests/fixtures/manifest/1_1_1/modules/test/file3.php')); - file_put_contents(base_path('tests/fixtures/manifest/1_1_1/modules/test/file3.php'), 'getFiles(); - file_put_contents(base_path('tests/fixtures/manifest/1_1_1/modules/test/file3.php'), $old); + file_put_contents(base_path('modules/system/tests/fixtures/manifest/1_1_1/modules/test/file3.php'), $old); $this->assertEquals([ 'build' => '1.1.1', @@ -272,12 +293,12 @@ public function testCompareModifiedSecondBranch() $this->createManifest(); // Add "tests/fixtures/manifest/1_0_3/modules/test/file3.php" - file_put_contents(base_path('tests/fixtures/manifest/1_0_3/modules/test/file3.php'), 'getFiles(); - unlink(base_path('tests/fixtures/manifest/1_0_3/modules/test/file3.php')); + unlink(base_path('modules/system/tests/fixtures/manifest/1_0_3/modules/test/file3.php')); $this->assertEquals([ 'build' => '1.0.3', @@ -310,11 +331,11 @@ protected function deleteManifest() protected function manifestPath() { - return base_path('tests/fixtures/manifest/builds.json'); + return base_path('modules/system/tests/fixtures/manifest/builds.json'); } protected function forksPath() { - return base_path('tests/fixtures/manifest/forks.json'); + return base_path('modules/system/tests/fixtures/manifest/forks.json'); } } diff --git a/tests/unit/system/classes/UpdatesControllerTest.php b/modules/system/tests/classes/UpdatesControllerTest.php similarity index 92% rename from tests/unit/system/classes/UpdatesControllerTest.php rename to modules/system/tests/classes/UpdatesControllerTest.php index 7994848650..0a557f8f8f 100644 --- a/tests/unit/system/classes/UpdatesControllerTest.php +++ b/modules/system/tests/classes/UpdatesControllerTest.php @@ -1,5 +1,8 @@ 6IS_oQ#OVOf50wENaBE{W3SPG@M27(ud;>AjXwzyl7 zq94!up7Znh1I{)!bqh--r z6OMs_jiC+JS9(`e6Y{-F}Q7> z)cSL>?Ncj}qwj)j$6~Bup)=E?BV_`&{Fn*&$}nlJ%RnDapF@ntF+Z7cczX7g%0d%>)b1FXK2owx_U#(`_m^BV^YyUQ6%!Xy?uBw zx%5{z#Lq4}{`i75T6MirJPjIz=Y9wcW?%vKG6$M0EK3{pi+&c{=;3f~Ep9U+dHHtV zyQRMxmqqEwP1utqx-<{HR5yNo(l6@c{f#<5yZh{ymTSPfPao1)Hpx?YB;VG|CMiHd zN*Dr_dj8S;t?iz-WAuf?V?#ow_J!G`T~;iSQ#*prJoyx)h=D zvNF_PZ~%6a8U!TyT|UPHCzSzE`@>j#j-KoKsvNWy?ru*myQh$$}fwB^V=URCDP7Nx_W;dlLRoqj%pWIw99p79qkq+8+P$J3$Lw@aMG_;f> zV%5a09c-tt-=K2G42V0xCZr&y)P%tQs8tW_shEAP$!^a|TqNOT^f=t0C`67hk=`R# zpO`I8r%zDXF|^Ed+^#&rYgocMt9fAkn)pB7gG{CuqU>Mt|RdzJ8h@Mf$k8IFp zn8K$u`U`!&Zaz!GRvL}Lg-Zm)K!DqxRK?)q6o$JvNUZ%+d$j^Hj0b2aiC%;irA|uZ+VQ;RyN!?Tp&N zjESns-xCbQmEGtuZQ{MO-YfSCo~?`%Zy@l?&`uTfwk(H%vrWlK9Mm{P#koOzTXs<8 z=mxRE4nmZlrgt=8B(nazxC&~~-X@@SHV1WITRV08T0I3eKS8le;CHh$k30c36CL`A zt6DD6cxQTg|2Wz>Ef)wV-}(dgwv+mBbV--(5%EizYgAb$KXF z7fw3$`1^9`c+czFZr1Z|>d>NPeJgAH{j~{FJ5D|&%a~G7rW#-_BQ{KO966>&Is)}c z<(a`Xjqc(#=NPqBWWl@T3(KCjzeZO&l2#lTQSHl;4up&q%7?dRFhPo> zAgvpbtzHrxR5BR2Lra9=*>mw66p7a9w)I;(MhNC*ALvXD>&1>NOCZHZl_W~(Er zoE~Y^evdOR=VTEvWbcN+OWesWIei<#P|Ly6V1LsrUwboQJi1YhkvCENZF(?$K%??X zNo`_F#{@Qu@1k_i==8=az1#1$p3&1wc5tQMN-icJ2_3HXzq^6rWJ-!Wu7!qk-G3xJ zduvm@S*<_dZ+Q0J8(eATm6~S~wUK@{jbu*#)TJ*oi7vjsJ3sFM--lBD0;W^ri+qo4 zHI==m`k2tWd!xdBJ^*2xTNgf8lHcZXI4}J0#|SCdz|0^iKhYMJU4D=nlH)9>8M{`v zObhL!H>?oICxV!8mIWACm2Bd#lXm_b3CmtM>#=MSYV0?M9AcjjIIzvtX0~O~7d@m3 z4*9nUHtZLZNDfXy&cn0Et7cHsEzvU^yTJzkO}JSmFzBW?KEP^LG2R2d8;oGJZ#ki4 zKwQ#CjDW354n!#8tSHZ^jR1|CS~fT_16YHOjn_Y7<;rBp5{%TxYOZ3e~YXuyhB4% z#KH_A3T@in@t|o{;@ZF-7F)Eob8yq6gaL{aBwPiIsVmF?W|gb5Y3A$q(+JGkUqxzj zB(UZ_XJQ*&Z~H@;^r>@n1RSJvIqP5ac+!QtGl>|EDwzIa`0VP+S#4S{v5pQU=2P0q z9kTla`ehew_g+jsBLB?Qro%OX!-f3cG?@rRW>wU}3fA$Xd%&-`&j%SNPs^lMN&hUD z0z1T)eEl4=zhx;P4n07YAqEOwF}YUIl&@;PEMuOZ_Th7mf~2* z?{W|5S>4hO1$cJ|7&<3*>N(Es9E#?)d-e&wQBqRqa9bosqjO`g12ws(rp2j$R9IpN^#phHKA^_vxKhdE{xdVdh8Jyl11rqaVe z&e`v1XwdOCAUEOP(j)>nkd$BXYHC{|Cnr;Q#CdRcHAosG9L?m-MdY=$L>O60=C?wQ zF_F*pa6b?)EJulfwO43K__#xAKc$f@ThC)iHMqW(Za7XBQjLVd`sm{Z)4or-66Tea zt=QAbsC1)Oj?av)d!WmJ#*A{qsiMdb!9PM$0<;!w%DaIq=8Eg#!f;PO{`A?5D zV8l;nP}dC&lQA0&19m+CcG#$%$mCChGt<42G{|blP8A~2b72f6hMl)pv-LA8ZiscH zW+lafG>ZyxRB2jRDsCMw>YIHSzeD&$<(_YEL|rlJwR=nrDUt16vQsnLhIAY1k7p%%Y@U=^Q$e@qWLnX?sZ^8SmUsr2c8uXGg#4#dh|^oEXycPQG>- zIcIB%&J7wf#rM#FtX~S?C-m_%pjFpt-)orm5hk!O?Mo*=S>4>3^Rzhy1ZZQOD_16S zMfpTK-|o4P+vR_ydo>lU&O}7^{DdzD80PM9?vRHQvT-5OHao8e{G0$QbxPRq!8Cy> zAQ~ewHdm8d#h;X4KX1Jmb?lxhd{*|(Qvn>0F7`{S-|zY+&pEs0sIlM9gt4m9-Dk|G z)BBFoL09x?Fs|?w{hIs>8eWR$=M^*6WY}9nhGY3$Y!XwO2eSO~+*e7RSkjt;?=w8| z(r`4&wLgENayCSc%=&MA#!nE|LOOH&3U)DHI1&HDIXwY8>y4=_aOilL5E9h%anYmT zbg1XGew#%Heh3R%fKJ2l5*}YwUMddj2L;R$)Gk-WT<#G^UmnT}fV*qFzEDvIw>2#@ z)U(gqF979)31Rn7NwFfI^o|P9(0nA0nL})86HwTHbEr^Qj@ltEqBNHAF0qu@WL8lg zIToTQ`D>ZUWQdOy-C&DME>y#sj#fRdBiWC}x$Ixe7jYI7aW{ z^OVeiT#Ko<-R&RG^UILFOim>7K%x$yzzjLkP?!+ucB){*180i4Z|%(+I`|IKe8><* zjIQy)((uxq0>7_x4dc{QePni(y(2mu$gs_&(nX_o5W-EbtKc@PasK6a48)kl-ZV*^5nnm=Y-Nu49e# z)Pt(vxZ`%4uVXU|pa9;Kj4WcX0!I80T|1RDS*VWmFy3p0L^%&tkMvbIkiToyZMet_ zDJvDu6ujk^r9vmwZja>4>ytekGjAtWz6NS`+70!z$U~%G%N1R7h{H-SMqaK zaem{hUq~Mizq9(K-eqA^#YL(5?VuLH?u+55rZM=F@N5ZlzT~}Hv8N1x8ai-gF*?Qp zhp)=!=^&Y~#*t%0!f$FBeV<5!$tZ*d({$Yi=B-@<<##s|J_6sY{f)*nmXI|#wZ>Xf z{GxdtzvMx3L{qR3!~2&_R|5m&>z^sqj`>d`FM!nUD?9aTG5ux_U;fx%0~WyTV49jA zH#KI*`G1~$UA?^{KN#@9p=lqUFvl0s}dE9NB3( zQlPJY&O4zAp^~gE%Jy$Zn98>OTV{$Fwm-bXiI?-Z$bw_tV}kg3C2?W(`VQYv8`Gy# z%9E;crtjQ{I!_B+>U@f7RyEcK6JE;+P}5)<>woj2^~uk{|08bDQ}n@(U+`^8v}K{} zPaN-aMZxFhr?F*t{><&eGzvP~h`UHK(N0~Su#9)e)!eP)`$z(Or58Tw;)=k~2cIe= z2|}n+tCG3T5D+tYoE~_d*v$%elBt3ARn+u_l~?^Bjc<}eKw^F0tw&w!!@aepB7>f7 zu=Ck@ri`DkIJo@%Yvq^X_mFWsByg6fyq_WXP^BXCLERFE8DEU40VPfly;DeulEsj` znKxf%3a;&4%ClHm!^V9yudmqKH2Y8dkanMT&Gc<<)!t>rdSxSpY+n#N?lmYQY&rfF zW_8abW;g=)-NSC4X#MAnZt5JdX=%Y`TC01>goC#=0&IF*v&4sWZhcb0Ds&#R7b|1@mY&DC_IUC| z!28D9`uR*Vgkfe)vqDu(YgAX|UH$xPvv*g+8dq%08(GM?V=?YYUBjtTI`j&is6 zp)t65H1jnG>>i{^nQMYhqI*kMAghAQmbRF|I6{blzsa39`A`u{-{BQnGFOyD_Mknw zeR29wltheDs(caKzE4J-6_YU%PzBKvb=oL2IH<~XF@SrX`kgDY~128OoKo(B=6 z$2Ei?n{^F;kW<|L%%NnH(3CI0B~i||CLg%i-r;u)ZLSszuz2a>Myj!LX6ABTEx>C` zr8s@L{{BaU#>$}z(I}ts6W;5r1d_!V+NC7h7 zMkjJ!#qwTa@zsldq`t9f?#!jrB1i~J!@`Sqp-`ic{QRwYq5ihkx`IdA0 z1Abu%iKlY95sy%hYKoh;zyRQy`9l@Z&XHvA1f0=%%3i>PMPm02XEMe!_)q~ikCA33 z?dR9!A6_a;MDcc(iC(+C29xo=D|pXB9z0e1-W^cq&7JATiCHRSE>1tzGT&C(L0#vq zBkO+_ASp`Tb-;N#9u4%aSF|}z?>GNN#8udCqpTPWD(rEy3dvWd5_{$x<~(t<*9~>SNkNloh(eE}E@n9r|(LWjEoL>TbRl$*$;zfIRl&tZKsQ{GRK6|(8xeKyo>YFnBGnwS? z*10bQ?v^0Mi1qi;9-~5oa5&yX31Mio#SK~DBkK{%v&~ygRsxRq>F%FJ2)uj_*{dpc#0j&gj|Y+aXpy zhF*Z~hMOY#B{-CgJ=1BVGQ(<f{W&#HL}dYd1QAh`I|pXi_n!Ff2U_MvnPdq8g+|>DDR$$h`EU9pJfKZWc*72 z;f!+IM%KI&dsRBnkL`4^CpL&)drB%|f-5GiGh?$paeKN0nNh;fpUT27kfXY|iz-!* z&NW#>>cA@EcU&B}9i3B# zmu4XOuQavQ+;8N(HbU}5t5HgYYqfO)%w=MlfOF3HmHUuMoyjZDlsC^111e`~_T#?0 z|y&)onxT(Z#i{K z3dlikG5*(E0uS3VY%lqd3a`fswxfO&_8TEqa2RT~&ypAri97Rbhz&!}A?W0(Qo2!x z*jvCBU(+znBaLrSfp;EYKy|M@Gs1J)L@CHUK*cyS^hNO}CBQW660;Ie?7K5kYx2b<2XdF8_WZJ<|rONLz{72-|rp%~iEmcBnSr+KE41 zLJXsd5UJ;{kdh_3tK9Z>u>LKp0=1sPQ~G%;VQz8v;L7q%d5-5Iv&gP)oz8l}Z7fDK z@5!nmzG_%}?UZ77Cl^1qSd>f| z+q5DuNcD-lTg?*|a@=QFB<2|2-8mw#4~|k3g&(68M0Zl-R=014m0#|s{@`M8@6H)n zj$>`ds!a@9;|cghZ}wgbwl%kS;l;om8Y7B)TK>hxsoKA-K-5=>9_^aBK9f_i?4XXw z+*U+OGZ?wAn9}HKKR0&J@$!F+x}5u%R-;0V#ySpmcRKWU0_AYX$n)3)C`+L>JH_d= zJ~6Z6Lt&7^2(inKM&@|Sw_Oej&ie_Coa-dx?P3N;Cr@NRqZ;fEQ`wF1I4Gx!+j{(f zaYppVH$E9pG^CJT4MHnk4I(hn@p_zg1t_`b&Llk%)OFC5ft;4cH?B6*@6hN520iqt zaOzv>V!NeQ58=!+Zc~8&8zOuWv`W02QmAG>2SzWR7>4JPB}Y7FZBRx^o++>K{vtkP zl~2{IB!iB(f0r1^ImXd?1mn&{0V9_ka^HFSU^kAQHM=|M!$FVPPRV>iA-{z$rBKR^ zEgJ_q@3RM2iT^R6`l+8W{&*)`d{fhvfCfC>Y`4d%UNcY~no1pLwJ*=L_67GfwhXBM z61MdIs|O_h`{q2nJ!r7%=*{gH^EO~2ZEy&4yPcg~yY%dq%kwg!S;Pz&UiC9@1&kjg zb6xNhGC1b20cCXM~}$tzU#z{LemWNNKt7az;#dM`ZX~A z8n@9r9SZ$&(A0F^=!{<8Mep(GbSc+%;{cp%$(;W)K6w-$^?yx4zBVgLXD literal 0 HcmV?d00001 diff --git a/modules/system/tests/fixtures/themes/test/assets/js/script1.js b/modules/system/tests/fixtures/themes/test/assets/js/script1.js new file mode 100644 index 0000000000..b8bbe4e135 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/assets/js/script1.js @@ -0,0 +1 @@ +console.log('script1.js'); diff --git a/modules/system/tests/fixtures/themes/test/assets/js/script2.js b/modules/system/tests/fixtures/themes/test/assets/js/script2.js new file mode 100644 index 0000000000..54e00dea3b --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/assets/js/script2.js @@ -0,0 +1 @@ +console.log('script2.js'); diff --git a/modules/system/tests/fixtures/themes/test/assets/js/subdir/script1.js b/modules/system/tests/fixtures/themes/test/assets/js/subdir/script1.js new file mode 100644 index 0000000000..bc27e099c0 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/assets/js/subdir/script1.js @@ -0,0 +1 @@ +console.log('subdir/script1.js'); diff --git a/modules/system/tests/fixtures/themes/test/content/a/a-content.htm b/modules/system/tests/fixtures/themes/test/content/a/a-content.htm new file mode 100644 index 0000000000..5f9de3933c --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/content/a/a-content.htm @@ -0,0 +1 @@ +A content \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/content/html-content.htm b/modules/system/tests/fixtures/themes/test/content/html-content.htm new file mode 100644 index 0000000000..9fca008a96 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/content/html-content.htm @@ -0,0 +1 @@ +Stephen Saucier changed his profile picture — 7 hrs ago \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/content/layout-content.txt b/modules/system/tests/fixtures/themes/test/content/layout-content.txt new file mode 100644 index 0000000000..920c278b49 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/content/layout-content.txt @@ -0,0 +1 @@ +LAYOUT CONTENT \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/content/markdown-content.md b/modules/system/tests/fixtures/themes/test/content/markdown-content.md new file mode 100644 index 0000000000..58429128ec --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/content/markdown-content.md @@ -0,0 +1 @@ +Be brave, be **bold**, live *italic* \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/content/page-content.htm b/modules/system/tests/fixtures/themes/test/content/page-content.htm new file mode 100644 index 0000000000..887d78d9cd --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/content/page-content.htm @@ -0,0 +1 @@ +PAGE CONTENT \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/content/text-content.txt b/modules/system/tests/fixtures/themes/test/content/text-content.txt new file mode 100644 index 0000000000..c055462e5d --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/content/text-content.txt @@ -0,0 +1 @@ +Pen is than the sword, HTML is than the text \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/a/a-layout.htm b/modules/system/tests/fixtures/themes/test/layouts/a/a-layout.htm new file mode 100644 index 0000000000..c4f1ab9057 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/a/a-layout.htm @@ -0,0 +1 @@ +
LAYOUT CONTENT {{ page() }}
\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/ajax-test.htm b/modules/system/tests/fixtures/themes/test/layouts/ajax-test.htm new file mode 100644 index 0000000000..d57dd296db --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/ajax-test.htm @@ -0,0 +1,10 @@ +description = "This layout tests the AJAX events" +== +function onTest() { + $this['var'] = 'layout'; +} +function onTestLayout() { + $this['var'] = 'layout-test'; +} +== +{{ page() }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/content.htm b/modules/system/tests/fixtures/themes/test/layouts/content.htm new file mode 100644 index 0000000000..7bc638e2d8 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/content.htm @@ -0,0 +1 @@ +
{{ content('layout-content.txt') }}{{ page() }}
\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/cycle-test.htm b/modules/system/tests/fixtures/themes/test/layouts/cycle-test.htm new file mode 100644 index 0000000000..9d79d760f9 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/cycle-test.htm @@ -0,0 +1,15 @@ +description = "This layout tests the page life cycle" +== +function onStart() { + $this['layoutStartVar'] = 1; +} + +function onBeforePageStart() { + $this['layoutBeforePageStartVar'] = 2; +} + +function onEnd() { + $this['layoutEndVar'] = 5; +} +== +{{ page() }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/no-php.htm b/modules/system/tests/fixtures/themes/test/layouts/no-php.htm new file mode 100644 index 0000000000..ee167f81cb --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/no-php.htm @@ -0,0 +1 @@ +
{{ page() }}
\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/partials.htm b/modules/system/tests/fixtures/themes/test/layouts/partials.htm new file mode 100644 index 0000000000..7974106e38 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/partials.htm @@ -0,0 +1 @@ +
{{ partial('layout-partial') }}{{ page() }}
\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/php-parser-test.htm b/modules/system/tests/fixtures/themes/test/layouts/php-parser-test.htm new file mode 100644 index 0000000000..3f4f1a8c51 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/php-parser-test.htm @@ -0,0 +1,10 @@ +description = "Layout for testing the CMS PHP parser" +== +function onStart() { + +} + +function onEnd() { +} +== +{{ layoutStartVar }}{{ layoutBeforePageStartVar }}{{ pageStartVar }}{{ pageEndVar }}{{ layoutEndVar }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/placeholder.htm b/modules/system/tests/fixtures/themes/test/layouts/placeholder.htm new file mode 100644 index 0000000000..ad6ea14da2 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/placeholder.htm @@ -0,0 +1 @@ +
LAYOUT CONTENT {% placeholder test default %}DEFAULT{% endplaceholder %} {{ page() }}
{% placeholder second %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/layouts/sidebar.htm b/modules/system/tests/fixtures/themes/test/layouts/sidebar.htm new file mode 100644 index 0000000000..eb10b585d1 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/layouts/sidebar.htm @@ -0,0 +1 @@ +
{% page %}
\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/404.htm b/modules/system/tests/fixtures/themes/test/pages/404.htm new file mode 100644 index 0000000000..583e8fd069 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/404.htm @@ -0,0 +1,3 @@ +url = "404" +== +

Page not found

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/a/a-page.htm b/modules/system/tests/fixtures/themes/test/pages/a/a-page.htm new file mode 100644 index 0000000000..fbd83d69ce --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/a/a-page.htm @@ -0,0 +1,4 @@ +url = "/apage" +layout = "a/a-layout" +== +

This page is a subdirectory

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/ajax-test.htm b/modules/system/tests/fixtures/themes/test/pages/ajax-test.htm new file mode 100644 index 0000000000..7af37c437b --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/ajax-test.htm @@ -0,0 +1,8 @@ +url = "/ajax-test" +layout = "ajax-test" +== +function onTest() { + $this['var'] = 'page'; +} +== +{{ layoutStartVar }}{{ layoutBeforePageStartVar }}{{ pageStartVar }}{{ pageEndVar }}{{ layoutEndVar }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/authors.htm b/modules/system/tests/fixtures/themes/test/pages/authors.htm new file mode 100644 index 0000000000..bf938f7feb --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/authors.htm @@ -0,0 +1,4 @@ +url = "/authors/:author_id?no-author|^[0-9]+$" +== +

Authors page

+

This is the Authors page

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/b/b-page.htm b/modules/system/tests/fixtures/themes/test/pages/b/b-page.htm new file mode 100644 index 0000000000..9a3cb6a635 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/b/b-page.htm @@ -0,0 +1,3 @@ +url = "/bpage" +== +

This page is a subdirectory

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/b/c/c-page.htm b/modules/system/tests/fixtures/themes/test/pages/b/c/c-page.htm new file mode 100644 index 0000000000..10915cbea2 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/b/c/c-page.htm @@ -0,0 +1,3 @@ +url = "/cpage" +== +

This page is a subdirectory

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/blog-archive.htm b/modules/system/tests/fixtures/themes/test/pages/blog-archive.htm new file mode 100644 index 0000000000..6f28cc8fcb --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/blog-archive.htm @@ -0,0 +1,4 @@ +url = "/blog/archive-page/:page?1" +== +

Blog Archive

+

Hi there!

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/blog-category.htm b/modules/system/tests/fixtures/themes/test/pages/blog-category.htm new file mode 100644 index 0000000000..0f9389013f --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/blog-category.htm @@ -0,0 +1,4 @@ +url = "/blog/category-page/:category_name?*" +== +

Blog category

+

This is a blog category page

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/blog-post.htm b/modules/system/tests/fixtures/themes/test/pages/blog-post.htm new file mode 100644 index 0000000000..b39ac35356 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/blog-post.htm @@ -0,0 +1,4 @@ +url = "/blog/post/:url_title" +== +

Blog post

+

This is a blog post page

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/code-namespaces-aliases.htm b/modules/system/tests/fixtures/themes/test/pages/code-namespaces-aliases.htm new file mode 100644 index 0000000000..951726af69 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/code-namespaces-aliases.htm @@ -0,0 +1,13 @@ +url = "/code-namespaces" +== + +== +

Page

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/code-namespaces.htm b/modules/system/tests/fixtures/themes/test/pages/code-namespaces.htm new file mode 100644 index 0000000000..1313f826dc --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/code-namespaces.htm @@ -0,0 +1,13 @@ +url = "/code-namespaces" +== + +== +

Page

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/component-custom-render.htm b/modules/system/tests/fixtures/themes/test/pages/component-custom-render.htm new file mode 100644 index 0000000000..9fc2c5d549 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/component-custom-render.htm @@ -0,0 +1,10 @@ +url = "/component-custom-render" + +[Winter\Tester\Components\ContentBlock theblock] +== + +{% component 'theblock' %} + +{% component 'theblock' output="Would you look over Picasso's shoulder" %} + +{% component 'theblock' output='And tell him about his brush strokes?' %} diff --git a/modules/system/tests/fixtures/themes/test/pages/component-partial-alias-override.htm b/modules/system/tests/fixtures/themes/test/pages/component-partial-alias-override.htm new file mode 100644 index 0000000000..094712dd86 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/component-partial-alias-override.htm @@ -0,0 +1,5 @@ +url = "/component-partial-alias-override" + +[Winter\Tester\Components\Post overRide1] +== +{% component 'overRide1' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/component-partial-nesting.htm b/modules/system/tests/fixtures/themes/test/pages/component-partial-nesting.htm new file mode 100644 index 0000000000..41d18f7bbe --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/component-partial-nesting.htm @@ -0,0 +1,3 @@ +url = "/component-partial-nesting" +== +{% partial 'nesting/level1' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/component-partial-override.htm b/modules/system/tests/fixtures/themes/test/pages/component-partial-override.htm new file mode 100644 index 0000000000..42f95a85dd --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/component-partial-override.htm @@ -0,0 +1,5 @@ +url = "/component-partial-override" + +[testPost] +== +{% component 'testPost' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/component-partial.htm b/modules/system/tests/fixtures/themes/test/pages/component-partial.htm new file mode 100644 index 0000000000..beb429194f --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/component-partial.htm @@ -0,0 +1,5 @@ +url = "/component-partial" + +[Winter\Tester\Components\Post post] +== +{% component 'post' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/cycle-test.htm b/modules/system/tests/fixtures/themes/test/pages/cycle-test.htm new file mode 100644 index 0000000000..3f7e8aa389 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/cycle-test.htm @@ -0,0 +1,12 @@ +url = "/cycle-test" +layout = "cycle-test" +== +function onStart() { + $this['pageStartVar'] = 3; +} + +function onEnd() { + $this['pageEndVar'] = 4; +} +== +{{ layoutStartVar }}{{ layoutBeforePageStartVar }}{{ pageStartVar }}{{ pageEndVar }}{{ layoutEndVar }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/filters-test.htm b/modules/system/tests/fixtures/themes/test/pages/filters-test.htm new file mode 100644 index 0000000000..ac6b767690 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/filters-test.htm @@ -0,0 +1,13 @@ +url = "/filters-test/:url_title?" +== +{# Check pageUrl for current page #} +{{ '' | page }} -> {{ '/filters-test/current-slug' | app }} +{# Check pageUrl for persistent URL parameters #} +{{ 'blog-post' | page }} -> {{ '/blog/post/current-slug' | app }} +{# Check pageUrl for providing values for URL parameters #} +{{ 'blog-post' | page({url_title: 'test-slug'}) }} -> {{ '/blog/post/test-slug' | app }} +{# Check pageUrl for disabling persistent URL parameters #} +{{ 'blog-post' | page({}, false) }} -> {{ '/blog/post/default' | app }} +{# Check pageUrl for disabling persistent URL parameters with the second argument being routePersistence #} +{{ 'blog-post' | page(false) }} -> {{ '/blog/post/default' | app }} + diff --git a/modules/system/tests/fixtures/themes/test/pages/index.htm b/modules/system/tests/fixtures/themes/test/pages/index.htm new file mode 100644 index 0000000000..13913b0e8f --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/index.htm @@ -0,0 +1,3 @@ +url = "/" +== +

My Webpage

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/no-component-class.htm b/modules/system/tests/fixtures/themes/test/pages/no-component-class.htm new file mode 100644 index 0000000000..d9e406a4e6 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/no-component-class.htm @@ -0,0 +1,5 @@ +url = "/no-component-class" + +[PeterPan\Nevernever\Land noComponentExist] +== +

Hey

diff --git a/modules/system/tests/fixtures/themes/test/pages/no-component.htm b/modules/system/tests/fixtures/themes/test/pages/no-component.htm new file mode 100644 index 0000000000..0a7761b474 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/no-component.htm @@ -0,0 +1,3 @@ +url = "/no-component" +== +

Hey

{% component 'noComponentExist' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/no-layout.htm b/modules/system/tests/fixtures/themes/test/pages/no-layout.htm new file mode 100644 index 0000000000..06abad0383 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/no-layout.htm @@ -0,0 +1,4 @@ +url = "/no-layout" +layout = "caramba" +== +

Hey

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/no-partial.htm b/modules/system/tests/fixtures/themes/test/pages/no-partial.htm new file mode 100644 index 0000000000..65af950640 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/no-partial.htm @@ -0,0 +1,4 @@ +url = "/no-partial" +== +

Hey

+{% partial 'caramba' %} diff --git a/modules/system/tests/fixtures/themes/test/pages/no-soft-component-class.htm b/modules/system/tests/fixtures/themes/test/pages/no-soft-component-class.htm new file mode 100644 index 0000000000..9559b16dcf --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/no-soft-component-class.htm @@ -0,0 +1,5 @@ +url = "/no-soft-component-class" + +[@PeterPan\Nevernever\Land noComponentExist] +== +

Hey

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/optional-full-php-tags.htm b/modules/system/tests/fixtures/themes/test/pages/optional-full-php-tags.htm new file mode 100644 index 0000000000..1c93ff1467 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/optional-full-php-tags.htm @@ -0,0 +1,14 @@ +url = "/cycle-test" +layout = "cycle-test" +== + +== +{{ layoutStartVar }}{{ layoutBeforePageStartVar }}{{ pageStartVar }}{{ pageEndVar }}{{ layoutEndVar }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/optional-short-php-tags.htm b/modules/system/tests/fixtures/themes/test/pages/optional-short-php-tags.htm new file mode 100644 index 0000000000..2401ae9bcb --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/optional-short-php-tags.htm @@ -0,0 +1,14 @@ +url = "/cycle-test" +layout = "cycle-test" +== + +== +{{ layoutStartVar }}{{ layoutBeforePageStartVar }}{{ pageStartVar }}{{ pageEndVar }}{{ layoutEndVar }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/throw-php.htm b/modules/system/tests/fixtures/themes/test/pages/throw-php.htm new file mode 100644 index 0000000000..1785a3a382 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/throw-php.htm @@ -0,0 +1,7 @@ +url = "/throw-php" +== +function onStart() { + test(); +} +== +

This page will throw an exception

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/with-component.htm b/modules/system/tests/fixtures/themes/test/pages/with-component.htm new file mode 100644 index 0000000000..eff57d3e0b --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-component.htm @@ -0,0 +1,11 @@ +url = "/with-component" +layout = "content" + +[testArchive] +posts-per-page = "69" +== +

This page uses components.

+{% for post in testArchive.posts %} +

{{ post.title }}

+

{{ post.content }}

+{% endfor %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/with-components.htm b/modules/system/tests/fixtures/themes/test/pages/with-components.htm new file mode 100644 index 0000000000..0e5ad47185 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-components.htm @@ -0,0 +1,14 @@ +url = "/with-components" +layout = "content" + +[testArchive firstAlias] +posts-per-page = "6" + +[Winter\Tester\Components\Archive secondAlias] +posts-per-page = "9" +== +

This page uses components.

+{% for post in secondAlias.posts %} +

{{ post.title }}

+

{{ post.content }}

+{% endfor %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/with-content.htm b/modules/system/tests/fixtures/themes/test/pages/with-content.htm new file mode 100644 index 0000000000..c47e05e580 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-content.htm @@ -0,0 +1,4 @@ +url = "/with-content" +layout = "content" +== +

Hey {% content "page-content.htm" %} {% content "a/a-content.htm" %}

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/with-layout.htm b/modules/system/tests/fixtures/themes/test/pages/with-layout.htm new file mode 100644 index 0000000000..9908d6ed7f --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-layout.htm @@ -0,0 +1,4 @@ +url = "/with-layout" +layout = "sidebar" +== +

Hey

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/with-partials.htm b/modules/system/tests/fixtures/themes/test/pages/with-partials.htm new file mode 100644 index 0000000000..5e1531c26b --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-partials.htm @@ -0,0 +1,4 @@ +url = "/with-partials" +layout = "partials" +== +

Hey {% partial "page-partial" firstName="Homer" lastName="Simpson" %} {% partial "a/a-partial" %}

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/with-placeholder.htm b/modules/system/tests/fixtures/themes/test/pages/with-placeholder.htm new file mode 100644 index 0000000000..05601d3e59 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-placeholder.htm @@ -0,0 +1,11 @@ +url = "/with-placeholder" +layout = "placeholder" +== +{% put test %} + BLOCK + {% default %} +{% endput %} +{% put second %} + SECOND BLOCK +{% endput %} +

Hey PAGE CONTENT

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm b/modules/system/tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm new file mode 100644 index 0000000000..072b1e2140 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-soft-component-class-alias.htm @@ -0,0 +1,11 @@ +url = "/with-soft-component-class-alias" +layout = "content" + +[@testArchive someAlias] +posts-per-page = "69" +== +

This page uses components.

+{% for post in someAlias.posts %} +

{{ post.title }}

+

{{ post.content }}

+{% endfor %} diff --git a/modules/system/tests/fixtures/themes/test/pages/with-soft-component-class.htm b/modules/system/tests/fixtures/themes/test/pages/with-soft-component-class.htm new file mode 100644 index 0000000000..330dc565ec --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/pages/with-soft-component-class.htm @@ -0,0 +1,11 @@ +url = "/with-soft-component-class" +layout = "content" + +[@testArchive] +posts-per-page = "69" +== +

This page uses components.

+{% for post in testArchive.posts %} +

{{ post.title }}

+

{{ post.content }}

+{% endfor %} diff --git a/modules/system/tests/fixtures/themes/test/partials/a/a-partial.htm b/modules/system/tests/fixtures/themes/test/partials/a/a-partial.htm new file mode 100644 index 0000000000..c081986734 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/a/a-partial.htm @@ -0,0 +1 @@ +A partial \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/ajax-result.htm b/modules/system/tests/fixtures/themes/test/partials/ajax-result.htm new file mode 100644 index 0000000000..05fcf37093 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/ajax-result.htm @@ -0,0 +1 @@ +{{ var }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/ajax-second-result.htm b/modules/system/tests/fixtures/themes/test/partials/ajax-second-result.htm new file mode 100644 index 0000000000..2147e41889 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/ajax-second-result.htm @@ -0,0 +1 @@ +second \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/layout-partial.htm b/modules/system/tests/fixtures/themes/test/partials/layout-partial.htm new file mode 100644 index 0000000000..1a38c3962a --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/layout-partial.htm @@ -0,0 +1 @@ +LAYOUT PARTIAL \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/nesting/level1.htm b/modules/system/tests/fixtures/themes/test/partials/nesting/level1.htm new file mode 100644 index 0000000000..c9fcb87857 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/nesting/level1.htm @@ -0,0 +1,6 @@ +[Winter\Tester\Components\MainMenu override2] +[Winter\Tester\Components\Post override3] +== +

Level 1

+{% component 'override2' %} +{% component 'override3' %} diff --git a/modules/system/tests/fixtures/themes/test/partials/nesting/level2.htm b/modules/system/tests/fixtures/themes/test/partials/nesting/level2.htm new file mode 100644 index 0000000000..ff772d4afd --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/nesting/level2.htm @@ -0,0 +1,6 @@ +[Winter\Tester\Components\Post post] +[Winter\Tester\Components\Post override4] +== +

Level 2

+{% component 'post' %} +{% component 'override4' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/nesting/level3.htm b/modules/system/tests/fixtures/themes/test/partials/nesting/level3.htm new file mode 100644 index 0000000000..5c4059a9ea --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/nesting/level3.htm @@ -0,0 +1,4 @@ +[Winter\Tester\Components\MainMenu mainMenu] +== +

Level 3

+{% component 'mainMenu' %} diff --git a/modules/system/tests/fixtures/themes/test/partials/override1/default.htm b/modules/system/tests/fixtures/themes/test/partials/override1/default.htm new file mode 100644 index 0000000000..b93cfda167 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/override1/default.htm @@ -0,0 +1 @@ +

I am an override alias partial! Yay

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/override2/default.htm b/modules/system/tests/fixtures/themes/test/partials/override2/default.htm new file mode 100644 index 0000000000..7fb329768e --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/override2/default.htm @@ -0,0 +1,7 @@ +
    +{% partial __SELF__ ~ "::items" items=__SELF__.menuItems %} +{% partial __SELF__ ~ "::items" items=__SELF__.menuItems %} +{% partial __SELF__ ~ "::items" items=__SELF__.menuItems %} +
+ +{% partial 'nesting/level2' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/override2/items.htm b/modules/system/tests/fixtures/themes/test/partials/override2/items.htm new file mode 100644 index 0000000000..0c77fb3c75 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/override2/items.htm @@ -0,0 +1,3 @@ +{% for item in items %} + {{ item }} +{% endfor %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/override3/default.htm b/modules/system/tests/fixtures/themes/test/partials/override3/default.htm new file mode 100644 index 0000000000..c49f68778a --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/override3/default.htm @@ -0,0 +1 @@ +

Insert post here

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/override4/default.htm b/modules/system/tests/fixtures/themes/test/partials/override4/default.htm new file mode 100644 index 0000000000..0b884776e0 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/override4/default.htm @@ -0,0 +1,3 @@ +

I am another post, deep down

+ +{% partial 'nesting/level3' %} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/page-partial.htm b/modules/system/tests/fixtures/themes/test/partials/page-partial.htm new file mode 100644 index 0000000000..c31a9b29e6 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/page-partial.htm @@ -0,0 +1 @@ +PAGE PARTIAL {{ firstName }} {{ lastName }} \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/partials/testpost/default.htm b/modules/system/tests/fixtures/themes/test/partials/testpost/default.htm new file mode 100644 index 0000000000..ebc57e24da --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/partials/testpost/default.htm @@ -0,0 +1 @@ +

I am an override partial! Yay

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/temporary/.gitignore b/modules/system/tests/fixtures/themes/test/temporary/.gitignore new file mode 100644 index 0000000000..c96a04f008 --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/temporary/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/testobjects/component.htm b/modules/system/tests/fixtures/themes/test/testobjects/component.htm new file mode 100644 index 0000000000..d8a2110acb --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/testobjects/component.htm @@ -0,0 +1,5 @@ +var = value +[testArchive] +posts-per-page = 10 +== +

This is a paragraph

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/testobjects/components.htm b/modules/system/tests/fixtures/themes/test/testobjects/components.htm new file mode 100644 index 0000000000..aae5da8a7a --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/testobjects/components.htm @@ -0,0 +1,8 @@ +var = value +[testArchive firstAlias] +posts-per-page = "6" + +[Winter\Tester\Components\Post secondAlias] +show-featured = "true" +== +

This is a paragraph

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/testobjects/compound.htm b/modules/system/tests/fixtures/themes/test/testobjects/compound.htm new file mode 100644 index 0000000000..7174624bcb --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/testobjects/compound.htm @@ -0,0 +1,10 @@ +var = value +[section] +version = 10 +== +function onBeforeDisplay($controller) +{ + $controller->data['something'] = 'some value'; +} +== +

This is a paragraph

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/testobjects/plain.html b/modules/system/tests/fixtures/themes/test/testobjects/plain.html new file mode 100644 index 0000000000..cd817bccba --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/testobjects/plain.html @@ -0,0 +1 @@ +

This is a test HTML content file.

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/testobjects/subdir/obj.html b/modules/system/tests/fixtures/themes/test/testobjects/subdir/obj.html new file mode 100644 index 0000000000..9502022abd --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/testobjects/subdir/obj.html @@ -0,0 +1 @@ +

This is an object in a subdirectory.

\ No newline at end of file diff --git a/modules/system/tests/fixtures/themes/test/testobjects/viewbag.htm b/modules/system/tests/fixtures/themes/test/testobjects/viewbag.htm new file mode 100644 index 0000000000..0a4268e52d --- /dev/null +++ b/modules/system/tests/fixtures/themes/test/testobjects/viewbag.htm @@ -0,0 +1,5 @@ +var = value +[viewBag] +title = "Toxicity" +== +

Chop Suey!

\ No newline at end of file diff --git a/tests/unit/plugins/database/AttachManyModelTest.php b/modules/system/tests/plugins/database/AttachManyModelTest.php similarity index 72% rename from tests/unit/plugins/database/AttachManyModelTest.php rename to modules/system/tests/plugins/database/AttachManyModelTest.php index 1bbd399964..b1453f509e 100644 --- a/tests/unit/plugins/database/AttachManyModelTest.php +++ b/modules/system/tests/plugins/database/AttachManyModelTest.php @@ -1,7 +1,11 @@ runPluginRefreshCommand('Database.Tester'); } @@ -21,7 +25,7 @@ public function testDeleteFlagDestroyRelationship() Model::reguard(); $this->assertEmpty($user->photos); - $user->photos()->create(['data' => base_path().'/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); + $user->photos()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); $user->reloadRelations(); $this->assertNotEmpty($user->photos); @@ -39,7 +43,7 @@ public function testDeleteFlagDeleteModel() Model::reguard(); $this->assertEmpty($user->photos); - $user->photos()->create(['data' => base_path().'/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); + $user->photos()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); $user->reloadRelations(); $this->assertNotEmpty($user->photos); diff --git a/tests/unit/plugins/database/AttachOneModelTest.php b/modules/system/tests/plugins/database/AttachOneModelTest.php similarity index 77% rename from tests/unit/plugins/database/AttachOneModelTest.php rename to modules/system/tests/plugins/database/AttachOneModelTest.php index 08dab04dd0..c7ba1307dc 100644 --- a/tests/unit/plugins/database/AttachOneModelTest.php +++ b/modules/system/tests/plugins/database/AttachOneModelTest.php @@ -1,9 +1,13 @@ runPluginRefreshCommand('Database.Tester'); } @@ -24,7 +28,7 @@ public function testSetRelationValue() Model::reguard(); // Set by string - $user->avatar = base_path().'/tests/fixtures/plugins/database/tester/assets/images/avatar.png'; + $user->avatar = base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png'; // @todo $user->avatar currently sits as a string, not good for validation // this should really assert as an UploadedFile instead. @@ -38,7 +42,7 @@ public function testSetRelationValue() // Set by Uploaded file $sample = $user->avatar; $upload = new UploadedFile( - base_path().'/tests/fixtures/plugins/database/tester/assets/images/avatar.png', + base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png', $sample->file_name, $sample->content_type, null, @@ -65,7 +69,7 @@ public function testDeleteFlagDestroyRelationship() Model::reguard(); $this->assertNull($user->avatar); - $user->avatar()->create(['data' => base_path().'/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); + $user->avatar()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); $user->reloadRelations(); $this->assertNotNull($user->avatar); @@ -83,7 +87,7 @@ public function testDeleteFlagDeleteModel() Model::reguard(); $this->assertNull($user->avatar); - $user->avatar()->create(['data' => base_path().'/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); + $user->avatar()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); $user->reloadRelations(); $this->assertNotNull($user->avatar); @@ -98,7 +102,7 @@ public function testDeleteFlagSoftDeleteModel() $user = SoftDeleteUser::create(['name' => 'Stevie', 'email' => 'stevie@example.com']); Model::reguard(); - $user->avatar()->create(['data' => base_path().'/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); + $user->avatar()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']); $this->assertNotNull($user->avatar); $avatarId = $user->avatar->id; diff --git a/tests/unit/plugins/database/BelongsToManyModelTest.php b/modules/system/tests/plugins/database/BelongsToManyModelTest.php similarity index 91% rename from tests/unit/plugins/database/BelongsToManyModelTest.php rename to modules/system/tests/plugins/database/BelongsToManyModelTest.php index 531da84cb6..71150db329 100644 --- a/tests/unit/plugins/database/BelongsToManyModelTest.php +++ b/modules/system/tests/plugins/database/BelongsToManyModelTest.php @@ -1,9 +1,14 @@ runPluginRefreshCommand('Database.Tester'); } @@ -174,8 +179,8 @@ public function testDeferredBinding() public function testDetachAfterDelete() { // Needed for other "delete" events - include_once base_path().'/tests/fixtures/plugins/database/tester/models/User.php'; - include_once base_path().'/tests/fixtures/plugins/database/tester/models/EventLog.php'; + include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/User.php'; + include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/EventLog.php'; Model::unguard(); $author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']); @@ -187,10 +192,10 @@ public function testDetachAfterDelete() $author->roles()->add($role1); $author->roles()->add($role2); $author->roles()->add($role3); - $this->assertEquals(3, Db::table('database_tester_authors_roles')->where('author_id', $author->id)->count()); + $this->assertEquals(3, DB::table('database_tester_authors_roles')->where('author_id', $author->id)->count()); $author->delete(); - $this->assertEquals(0, Db::table('database_tester_authors_roles')->where('author_id', $author->id)->count()); + $this->assertEquals(0, DB::table('database_tester_authors_roles')->where('author_id', $author->id)->count()); } public function testConditionsWithPivotAttributes() diff --git a/tests/unit/plugins/database/BelongsToModelTest.php b/modules/system/tests/plugins/database/BelongsToModelTest.php similarity index 91% rename from tests/unit/plugins/database/BelongsToModelTest.php rename to modules/system/tests/plugins/database/BelongsToModelTest.php index 160bdf9b3a..5f96081a9b 100644 --- a/tests/unit/plugins/database/BelongsToModelTest.php +++ b/modules/system/tests/plugins/database/BelongsToModelTest.php @@ -1,7 +1,11 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/DeferredBindingTest.php b/modules/system/tests/plugins/database/DeferredBindingTest.php similarity index 91% rename from tests/unit/plugins/database/DeferredBindingTest.php rename to modules/system/tests/plugins/database/DeferredBindingTest.php index 0cb7db4870..a190410a94 100644 --- a/tests/unit/plugins/database/DeferredBindingTest.php +++ b/modules/system/tests/plugins/database/DeferredBindingTest.php @@ -1,8 +1,12 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/HasManyModelTest.php b/modules/system/tests/plugins/database/HasManyModelTest.php similarity index 92% rename from tests/unit/plugins/database/HasManyModelTest.php rename to modules/system/tests/plugins/database/HasManyModelTest.php index 0226f670f0..058b9a9e1b 100644 --- a/tests/unit/plugins/database/HasManyModelTest.php +++ b/modules/system/tests/plugins/database/HasManyModelTest.php @@ -1,8 +1,12 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/HasManyThroughModelTest.php b/modules/system/tests/plugins/database/HasManyThroughModelTest.php similarity index 78% rename from tests/unit/plugins/database/HasManyThroughModelTest.php rename to modules/system/tests/plugins/database/HasManyThroughModelTest.php index 99286a2cd0..568d91a0ce 100644 --- a/tests/unit/plugins/database/HasManyThroughModelTest.php +++ b/modules/system/tests/plugins/database/HasManyThroughModelTest.php @@ -1,9 +1,13 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/HasOneModelTest.php b/modules/system/tests/plugins/database/HasOneModelTest.php similarity index 93% rename from tests/unit/plugins/database/HasOneModelTest.php rename to modules/system/tests/plugins/database/HasOneModelTest.php index 375b85e385..7d0b4907c4 100644 --- a/tests/unit/plugins/database/HasOneModelTest.php +++ b/modules/system/tests/plugins/database/HasOneModelTest.php @@ -1,7 +1,11 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/HasOneThroughModelTest.php b/modules/system/tests/plugins/database/HasOneThroughModelTest.php similarity index 67% rename from tests/unit/plugins/database/HasOneThroughModelTest.php rename to modules/system/tests/plugins/database/HasOneThroughModelTest.php index 91be83b606..e121846afb 100644 --- a/tests/unit/plugins/database/HasOneThroughModelTest.php +++ b/modules/system/tests/plugins/database/HasOneThroughModelTest.php @@ -1,8 +1,12 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/MorphManyModelTest.php b/modules/system/tests/plugins/database/MorphManyModelTest.php similarity index 92% rename from tests/unit/plugins/database/MorphManyModelTest.php rename to modules/system/tests/plugins/database/MorphManyModelTest.php index ef0bb860e5..723046a742 100644 --- a/tests/unit/plugins/database/MorphManyModelTest.php +++ b/modules/system/tests/plugins/database/MorphManyModelTest.php @@ -1,10 +1,14 @@ runPluginRefreshCommand('Database.Tester'); } @@ -158,7 +162,6 @@ public function testDeferredBinding() $this->assertEquals(88, $tagForPost->posts->first()->pivot->added_by); // Commit deferred (model is deleted as per definition) - $this->markTestSkipped("Issues are back at it again"); $author->save(null, $sessionKey); $event = EventLog::find($eventId); $this->assertEquals(0, $author->event_log()->count()); diff --git a/tests/unit/plugins/database/MorphOneModelTest.php b/modules/system/tests/plugins/database/MorphOneModelTest.php similarity index 92% rename from tests/unit/plugins/database/MorphOneModelTest.php rename to modules/system/tests/plugins/database/MorphOneModelTest.php index 41bdc2c979..ce434eaac1 100644 --- a/tests/unit/plugins/database/MorphOneModelTest.php +++ b/modules/system/tests/plugins/database/MorphOneModelTest.php @@ -1,8 +1,12 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/MorphToModelTest.php b/modules/system/tests/plugins/database/MorphToModelTest.php similarity index 82% rename from tests/unit/plugins/database/MorphToModelTest.php rename to modules/system/tests/plugins/database/MorphToModelTest.php index fe78bdf1b0..bdae9f7aaf 100644 --- a/tests/unit/plugins/database/MorphToModelTest.php +++ b/modules/system/tests/plugins/database/MorphToModelTest.php @@ -1,8 +1,12 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/NestedTreeModelTest.php b/modules/system/tests/plugins/database/NestedTreeModelTest.php similarity index 95% rename from tests/unit/plugins/database/NestedTreeModelTest.php rename to modules/system/tests/plugins/database/NestedTreeModelTest.php index 49d46764c6..e533a8b319 100644 --- a/tests/unit/plugins/database/NestedTreeModelTest.php +++ b/modules/system/tests/plugins/database/NestedTreeModelTest.php @@ -1,7 +1,11 @@ runPluginRefreshCommand('Database.Tester'); $this->seedSampleTree(); diff --git a/tests/unit/plugins/database/NullableModelTest.php b/modules/system/tests/plugins/database/NullableModelTest.php similarity index 89% rename from tests/unit/plugins/database/NullableModelTest.php rename to modules/system/tests/plugins/database/NullableModelTest.php index a0092e6e85..14d93c9a1f 100644 --- a/tests/unit/plugins/database/NullableModelTest.php +++ b/modules/system/tests/plugins/database/NullableModelTest.php @@ -1,5 +1,8 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/PluginModelTest.php b/modules/system/tests/plugins/database/PluginModelTest.php similarity index 79% rename from tests/unit/plugins/database/PluginModelTest.php rename to modules/system/tests/plugins/database/PluginModelTest.php index 85d7e31b85..e0514958b5 100644 --- a/tests/unit/plugins/database/PluginModelTest.php +++ b/modules/system/tests/plugins/database/PluginModelTest.php @@ -1,5 +1,8 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/RevisionableModelTest.php b/modules/system/tests/plugins/database/RevisionableModelTest.php similarity index 95% rename from tests/unit/plugins/database/RevisionableModelTest.php rename to modules/system/tests/plugins/database/RevisionableModelTest.php index c8fa19a540..543ac7cd80 100644 --- a/tests/unit/plugins/database/RevisionableModelTest.php +++ b/modules/system/tests/plugins/database/RevisionableModelTest.php @@ -1,7 +1,11 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/SimpleTreeModelTest.php b/modules/system/tests/plugins/database/SimpleTreeModelTest.php similarity index 97% rename from tests/unit/plugins/database/SimpleTreeModelTest.php rename to modules/system/tests/plugins/database/SimpleTreeModelTest.php index c499ac5ba0..1ec3847440 100644 --- a/tests/unit/plugins/database/SimpleTreeModelTest.php +++ b/modules/system/tests/plugins/database/SimpleTreeModelTest.php @@ -1,7 +1,11 @@ runPluginRefreshCommand('Database.Tester'); $this->seedSampleTree(); diff --git a/tests/unit/plugins/database/SluggableModelTest.php b/modules/system/tests/plugins/database/SluggableModelTest.php similarity index 94% rename from tests/unit/plugins/database/SluggableModelTest.php rename to modules/system/tests/plugins/database/SluggableModelTest.php index 22cad1837c..c623337948 100644 --- a/tests/unit/plugins/database/SluggableModelTest.php +++ b/modules/system/tests/plugins/database/SluggableModelTest.php @@ -1,5 +1,8 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/SoftDeleteModelTest.php b/modules/system/tests/plugins/database/SoftDeleteModelTest.php similarity index 91% rename from tests/unit/plugins/database/SoftDeleteModelTest.php rename to modules/system/tests/plugins/database/SoftDeleteModelTest.php index 32c9c68b9a..597bffd3f9 100644 --- a/tests/unit/plugins/database/SoftDeleteModelTest.php +++ b/modules/system/tests/plugins/database/SoftDeleteModelTest.php @@ -1,5 +1,8 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/database/ValidationModelTest.php b/modules/system/tests/plugins/database/ValidationModelTest.php similarity index 80% rename from tests/unit/plugins/database/ValidationModelTest.php rename to modules/system/tests/plugins/database/ValidationModelTest.php index f6b9bcc9a1..08b44da257 100644 --- a/tests/unit/plugins/database/ValidationModelTest.php +++ b/modules/system/tests/plugins/database/ValidationModelTest.php @@ -1,5 +1,8 @@ runPluginRefreshCommand('Database.Tester'); } diff --git a/tests/unit/plugins/system/CustomValidatorRulesTest.php b/modules/system/tests/plugins/system/CustomValidatorRulesTest.php similarity index 81% rename from tests/unit/plugins/system/CustomValidatorRulesTest.php rename to modules/system/tests/plugins/system/CustomValidatorRulesTest.php index 8227a663d9..db3ef7b817 100644 --- a/tests/unit/plugins/system/CustomValidatorRulesTest.php +++ b/modules/system/tests/plugins/system/CustomValidatorRulesTest.php @@ -1,13 +1,18 @@ runPluginRefreshCommand('Winter.Tester'); } diff --git a/tests/unit/system/traits/AssetMakerTest.php b/modules/system/tests/traits/AssetMakerTest.php similarity index 86% rename from tests/unit/system/traits/AssetMakerTest.php rename to modules/system/tests/traits/AssetMakerTest.php index 606df95628..d32b35d897 100644 --- a/tests/unit/system/traits/AssetMakerTest.php +++ b/modules/system/tests/traits/AssetMakerTest.php @@ -1,9 +1,15 @@ createApplication(); $this->stub = new ViewMakerStub(); - $this->relativePath = $this->normalizePath('tests/unit/system/traits/viewmakerstub'); + $this->relativePath = $this->normalizePath('modules/system/tests/traits/viewmakerstub'); } public function testViewPaths() diff --git a/tests/unit/system/traits/viewmakerstub/_can_override_php_with_htm.php b/modules/system/tests/traits/viewmakerstub/_can_override_php_with_htm.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/_can_override_php_with_htm.php rename to modules/system/tests/traits/viewmakerstub/_can_override_php_with_htm.php diff --git a/tests/unit/system/traits/viewmakerstub/_overridden.php b/modules/system/tests/traits/viewmakerstub/_overridden.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/_overridden.php rename to modules/system/tests/traits/viewmakerstub/_overridden.php diff --git a/tests/unit/system/traits/viewmakerstub/_relative_no_ext.php b/modules/system/tests/traits/viewmakerstub/_relative_no_ext.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/_relative_no_ext.php rename to modules/system/tests/traits/viewmakerstub/_relative_no_ext.php diff --git a/tests/unit/system/traits/viewmakerstub/folder/_no_ext.php b/modules/system/tests/traits/viewmakerstub/folder/_no_ext.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/folder/_no_ext.php rename to modules/system/tests/traits/viewmakerstub/folder/_no_ext.php diff --git a/tests/unit/system/traits/viewmakerstub/layouts/_layout_partial.php b/modules/system/tests/traits/viewmakerstub/layouts/_layout_partial.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/layouts/_layout_partial.php rename to modules/system/tests/traits/viewmakerstub/layouts/_layout_partial.php diff --git a/tests/unit/system/traits/viewmakerstub/layouts/default.php b/modules/system/tests/traits/viewmakerstub/layouts/default.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/layouts/default.php rename to modules/system/tests/traits/viewmakerstub/layouts/default.php diff --git a/tests/unit/system/traits/viewmakerstub/specific.php b/modules/system/tests/traits/viewmakerstub/specific.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/specific.php rename to modules/system/tests/traits/viewmakerstub/specific.php diff --git a/tests/unit/system/traits/viewmakerstub/symbols.php b/modules/system/tests/traits/viewmakerstub/symbols.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/symbols.php rename to modules/system/tests/traits/viewmakerstub/symbols.php diff --git a/tests/unit/system/traits/viewmakerstub/view.php b/modules/system/tests/traits/viewmakerstub/view.php similarity index 100% rename from tests/unit/system/traits/viewmakerstub/view.php rename to modules/system/tests/traits/viewmakerstub/view.php diff --git a/tests/unit/system/traits/viewmakerstuboverride/_can_override_php_with_htm.htm b/modules/system/tests/traits/viewmakerstuboverride/_can_override_php_with_htm.htm similarity index 100% rename from tests/unit/system/traits/viewmakerstuboverride/_can_override_php_with_htm.htm rename to modules/system/tests/traits/viewmakerstuboverride/_can_override_php_with_htm.htm diff --git a/tests/unit/system/traits/viewmakerstuboverride/_overridden.php b/modules/system/tests/traits/viewmakerstuboverride/_overridden.php similarity index 100% rename from tests/unit/system/traits/viewmakerstuboverride/_overridden.php rename to modules/system/tests/traits/viewmakerstuboverride/_overridden.php diff --git a/tests/unit/system/twig/FilterTest.php b/modules/system/tests/twig/FilterTest.php similarity index 97% rename from tests/unit/system/twig/FilterTest.php rename to modules/system/tests/twig/FilterTest.php index cd06cea073..7354ed1d06 100644 --- a/tests/unit/system/twig/FilterTest.php +++ b/modules/system/tests/twig/FilterTest.php @@ -1,5 +1,9 @@ - ./tests/unit + ./modules/system + ./modules/cms + ./modules/backend diff --git a/storage/.gitignore b/storage/.gitignore index 9b1dffd90f..617c22a6af 100644 --- a/storage/.gitignore +++ b/storage/.gitignore @@ -1 +1,2 @@ *.sqlite +/tests diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index 5d252d7c9f..0000000000 --- a/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -storage \ No newline at end of file diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 18377968f7..0000000000 --- a/tests/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# Plugin testing - -Individual plugin test cases can be run by running `../../../vendor/bin/phpunit` in the plugin's base directory (ex. `plugins/acme/demo`. - -### Creating plugin tests - -Plugins can be tested by creating a file called `phpunit.xml` in the base directory with the following content, for example, in a file **/plugins/acme/blog/phpunit.xml**: - - - - - - ./tests - - - - - - - - - -Then a **tests/** directory can be created to contain the test classes. The file structure should mimic the base directory with classes having a `Test` suffix. Using a namespace for the class is also recommended. - - 'Hi!']); - $this->assertEquals(1, $post->id); - } - } - -The test class should extend the base class `PluginTestCase` and this is a special class that will set up the Winter database stored in memory, as part of the `setUp` method. It will also refresh the plugin being tested, along with any of the defined dependencies in the plugin registration file. This is the equivalent of running the following before each test: - - php artisan winter:up - php artisan plugin:refresh Acme.Blog - [php artisan plugin:refresh , ...] - -> **Note:** If your plugin uses [configuration files](../plugin/settings#file-configuration), then you will need to run `System\Classes\PluginManager::instance()->registerAll(true);` in the `setUp` method of your tests. Below is an example of a base test case class that should be used if you need to test your plugin working with other plugins instead of in isolation. - - use System\Classes\PluginManager; - - class BaseTestCase extends PluginTestCase - { - public function setUp(): void - { - parent::setUp(); - - // Get the plugin manager - $pluginManager = PluginManager::instance(); - - // Register the plugins to make features like file configuration available - $pluginManager->registerAll(true); - - // Boot all the plugins to test with dependencies of this plugin - $pluginManager->bootAll(true); - } - - public function tearDown(): void - { - parent::tearDown(); - - // Get the plugin manager - $pluginManager = PluginManager::instance(); - - // Ensure that plugins are registered again for the next test - $pluginManager->unregisterAll(); - } - } - -#### Changing database engine for plugins tests - -By default Winter CMS uses SQLite stored in memory for the plugin testing environment. If you want to override the default behavior set the `useConfigForTesting` config to `true` in your `/config/database.php` file. When the `APP_ENV` is `testing` and the `useConfigForTesting` is `true` database parameters will be taken from `/config/database.php`. - -You can override the `/config/database.php` file by creating `/config/testing/database.php`. In this case variables from the latter file will be taken. - -## System testing - -To perform unit testing on the core Winter files, you should download a development copy using composer or cloning the git repo. This will ensure you have the `tests/` directory. - -### Unit tests - -Unit tests can be performed by running `vendor/bin/phpunit` in the root directory of your Winter CMS installation. - -### Functional tests - -Functional tests can be performed by installing the [Winter.Dusk](https://wintercms.com/plugin/winter-dusk) in your Winter CMS installation. The Winter.Dusk plugin is powered by Laravel Dusk, a comprehensive testing suite for the Laravel framework that is designed to test interactions with a fully operational Winter CMS instance through a virtual browser. - -For information on installing and setting up your Winter CMS install to run functional tests, please review the [README](https://github.com/wintercms/wn-dusk-plugin/blob/master/README.md) for the plugin. diff --git a/tests/js/.babelrc b/tests/js/.babelrc deleted file mode 100644 index 710cfd1b16..0000000000 --- a/tests/js/.babelrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "presets": [ - "@babel/preset-env" - ], - "plugins": [ - "@babel/plugin-transform-runtime", - [ - "module-resolver", { - "root": ["."], - "alias": { - "helpers": "./helpers", - "snowboard": "../../modules/system/assets/js/snowboard", - } - } - ] - ] -} diff --git a/tests/js/.gitignore b/tests/js/.gitignore deleted file mode 100644 index 7f9265d1a6..0000000000 --- a/tests/js/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Ignore packages -package-lock.json -node_modules diff --git a/tests/js/README.md b/tests/js/README.md deleted file mode 100644 index 7903252577..0000000000 --- a/tests/js/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Snowboard Framework Testing Suite - -The files in this directory form the testing suite for the new Winter JavaScript framework - Snowboard. You must install -all Node dependencies in order to run the testing suite: - -```bash -cd tests/js -npm install -``` - -You can then run the tests by using the following command: - -```bash -npm run test -``` - -Please note that the tests are run against the "built" versions of Snowboard and its plugins, in order to test -the exact same functionality that would be delivered to the end user. We do this by leveraging the `JSDOM` library to -simulate an entire HTML document. - -Therefore, you must compile a new build if you make any changes and wish to run the tests: - -```bash -php artisan mix:compile --package snowboard -``` - -You can also watch the framework for any changes, which will automatically run a build after a change is made. This will -make development and testing in parallel much quicker: - -```bash -php artisan mix:watch snowboard -``` diff --git a/tests/js/cases/snowboard/ajax/Request.test.js b/tests/js/cases/snowboard/ajax/Request.test.js deleted file mode 100644 index c2dc5cbb1e..0000000000 --- a/tests/js/cases/snowboard/ajax/Request.test.js +++ /dev/null @@ -1,625 +0,0 @@ -import FakeDom from '../../../helpers/FakeDom'; - -jest.setTimeout(2000); - -describe('Request AJAX library', function () { - it('can be setup via a global event', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new dom.window.Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to global event - dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { - listens() { - return { - ajaxSetup: 'ajaxSetup', - }; - } - - ajaxSetup(instance) { - instance.handler = 'onChanged'; - } - }); - - dom.window.Snowboard.request(undefined, 'onTest', { - complete: (data, instance) => { - expect(instance.handler).toEqual('onChanged'); - done(); - } - }); - } - ); - }); - - it('can be cancelled on setup via a global event', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new dom.window.Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to global event - dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { - listens() { - return { - ajaxSetup: 'ajaxSetup', - }; - } - - ajaxSetup() { - // Should cancel - return false; - } - }); - - const instance = dom.window.Snowboard.request(undefined, 'onTest', { - complete: (data, instance) => { - done(new Error('Request did not cancel')); - } - }); - expect(instance.cancelled).toEqual(true); - done(); - } - ); - }); - - it('can be setup via a listener on the HTML element', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render('') - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new dom.window.Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to HTML element event - const element = dom.window.document.getElementById('testElement'); - element.addEventListener('ajaxSetup', (event) => { - expect(event.request).toBeDefined(); - event.request.handler = 'onChanged'; - }); - - - dom.window.Snowboard.request(element, 'onTest', { - complete: (data, instance) => { - expect(instance.handler).toEqual('onChanged'); - done(); - } - }); - } - ); - }); - - it('can be cancelled on setup via a listener on the HTML element', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render('') - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new dom.window.Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to HTML element event - const element = dom.window.document.getElementById('testElement'); - element.addEventListener('ajaxSetup', (event) => { - event.preventDefault(); - }); - - const instance = dom.window.Snowboard.request(element, 'onTest', { - complete: (data, instance) => { - done(new Error('Request did not cancel')); - } - }); - expect(instance.cancelled).toEqual(true); - done(); - } - ); - }); - - it('can do a request and listen for completion', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - dom.window.Snowboard.request(undefined, 'onTest', { - complete: (data, instance) => { - expect(data).toEqual({ - success: true, - }); - expect(instance.responseData).toEqual({ - success: true, - }); - expect(instance.responseError).toEqual(null); - - done(); - return false; - } - }); - } - ); - }); - - it('can do a request and listen for completion via a global event', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to global event - dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { - listens() { - return { - ajaxDone: 'ajaxDone', - }; - } - - ajaxDone(data, instance) { - expect(data).toEqual({ - success: true, - }); - expect(instance.responseData).toEqual({ - success: true, - }); - expect(instance.responseError).toEqual(null); - - done(); - } - }); - - dom.window.Snowboard.request(undefined, 'onTest'); - } - ); - }); - - it('can do a request and listen for completion via a listener on the HTML element', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render('') - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new dom.window.Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to HTML element event - const element = dom.window.document.getElementById('testElement'); - element.addEventListener('ajaxAlways', (event) => { - expect(event.request).toBeDefined(); - expect(event.responseData).toEqual({ - success: true - }); - expect(event.responseError).toEqual(null); - done(); - }); - - dom.window.Snowboard.request(element, 'onTest'); - } - ); - }); - - it('can do a request and listen for success', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - dom.window.Snowboard.request(undefined, 'onTest', { - success: (data, instance) => { - expect(data).toEqual({ - success: true, - }); - expect(instance.responseData).toEqual({ - success: true, - }); - expect(instance.responseError).toEqual(null); - }, - complete: (data, instance) => { - expect(data).toEqual({ - success: true, - }); - expect(instance.responseData).toEqual({ - success: true, - }); - expect(instance.responseError).toEqual(null); - - done(); - }, - }); - } - ); - }); - - it('can do a request and listen for success via a global event', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate success response - const resolved = Promise.resolve({ - success: true - }); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to global event - dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { - listens() { - return { - ajaxSuccess: 'ajaxSuccess', - }; - } - - ajaxSuccess(data, instance) { - expect(data).toEqual({ - success: true, - }) - expect(instance.responseData).toEqual({ - success: true, - }); - expect(instance.responseError).toEqual(null); - - done(); - } - }); - - dom.window.Snowboard.request(undefined, 'onTest'); - } - ); - }); - - it('can do a request and listen for failure', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate error response - const resolved = Promise.reject('This is an error'); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - dom.window.Snowboard.request(undefined, 'onTest', { - error: (data, instance) => { - expect(data).toEqual('This is an error'); - expect(instance.responseData).toEqual(null); - expect(instance.responseError).toEqual('This is an error'); - }, - complete: (data, instance) => { - // Data will be null because no data was provided in the response. - expect(data).toBeNull(); - expect(instance.responseData).toEqual(null); - expect(instance.responseError).toEqual('This is an error'); - - done(); - }, - }); - } - ); - }); - - it('can do a request and listen for failure via global event', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { - // Simulate error response - const resolved = Promise.reject('This is an error'); - - // Mock events - instance.snowboard.globalEvent('ajaxStart', instance, resolved); - - if (instance.element) { - const event = new Event('ajaxPromise'); - event.promise = resolved; - instance.element.dispatchEvent(event); - } - - return resolved; - }); - - // Listen to global event - dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { - listens() { - return { - ajaxError: 'ajaxError', - }; - } - - ajaxError(data, instance) { - expect(data).toEqual('This is an error') - expect(instance.responseData).toEqual(null); - expect(instance.responseError).toEqual('This is an error'); - - done(); - } - }); - - dom.window.Snowboard.request(undefined, 'onTest'); - } - ); - }); - - it('requires a valid HTML element if provided', function () { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - expect(() => { - const docFragment = dom.window.document.createDocumentFragment(); - dom.window.Snowboard.request(docFragment, 'onTest'); - }).toThrow('The element provided must be an Element instance'); - } - ); - }); - - it('requires a handler to be specified', function () { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - expect(() => { - dom.window.Snowboard.request(undefined, undefined); - }).toThrow('The AJAX handler name is not specified'); - } - ); - }); - - it('requires a handler to be of the correct format', function () { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.request.js' - ]) - .render() - .then( - (dom) => { - expect(() => { - dom.window.Snowboard.request(undefined, 'notRight'); - }).toThrow('Invalid AJAX handler name'); - } - ); - }); -}); diff --git a/tests/js/cases/snowboard/extras/DataConfig.test.js b/tests/js/cases/snowboard/extras/DataConfig.test.js deleted file mode 100644 index 339f0c09d3..0000000000 --- a/tests/js/cases/snowboard/extras/DataConfig.test.js +++ /dev/null @@ -1,316 +0,0 @@ -import FakeDom from '../../../helpers/FakeDom'; - -jest.setTimeout(2000); - -describe('The Data Config extra functionality', function () { - it('can read the config from an element\'s data attributes', function (done) { - FakeDom - .new() - .addCss([ - 'modules/system/assets/css/snowboard.extras.css', - ]) - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.extras.js', - 'tests/js/fixtures/dataConfig/DataConfigFixture.js', - ]) - .render( - `
- -
` - ) - .then( - (dom) => { - const instance = dom.window.Snowboard.dataConfigFixture( - dom.window.document.querySelector('#testElement') - ); - - try { - expect(instance.config.get('id')).toEqual(389); - // Name should be null as it's the default value and not specified above - expect(instance.config.get('name')).toBeNull(); - expect(instance.config.get('stringValue')).toBe('Hi there'); - // Missing should be undefined as it's neither defined nor part of the default data - expect(instance.config.get('missing')).toBeUndefined(); - expect(instance.config.get('boolean')).toBe(true); - - expect(instance.config.get()).toMatchObject({ - id: 389, - name: null, - stringValue: 'Hi there', - boolean: true, - base64: null, - }); - } catch (error) { - done(error); - return; - } - - const instanceTwo = dom.window.Snowboard.dataConfigFixture( - dom.window.document.querySelector('#testElementTwo') - ); - - try { - // ID is null as it's the default value and not specified above - expect(instanceTwo.config.get('id')).toBeNull(); - expect(instanceTwo.config.get('name')).toBe('Ben'); - expect(instanceTwo.config.get('stringValue')).toBe('Hi there again'); - expect(instanceTwo.config.get('missing')).toBeUndefined(); - expect(instanceTwo.config.get('boolean')).toBe(false); - // Extra attr is specified above, but it should not be available as a config value - // because it's not part of the `defaults()` in the fixture - expect(instanceTwo.config.get('extraAttr')).toBeUndefined(); - // Base-64 decoded string - expect(instanceTwo.config.get('base64')).toBe('I\'m a Base64-decoded string'); - - done(); - } catch (error) { - done(error); - } - } - ); - }); - - it('can read the config from every data attribute of an element with "acceptAllDataConfigs" enabled', function (done) { - FakeDom - .new() - .addCss([ - 'modules/system/assets/css/snowboard.extras.css', - ]) - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.extras.js', - 'tests/js/fixtures/dataConfig/DataConfigFixture.js', - ]) - .render( - `
` - ) - .then( - (dom) => { - const instance = dom.window.Snowboard.dataConfigFixture( - dom.window.document.querySelector('#testElementTwo') - ); - instance.acceptAllDataConfigs = true; - instance.config.refresh(); - - try { - // ID is null as it's the default value and not specified above - expect(instance.config.get('id')).toBeNull(); - expect(instance.config.get('name')).toBe('Ben'); - expect(instance.config.get('stringValue')).toBe('Hi there again'); - expect(instance.config.get('missing')).toBeUndefined(); - expect(instance.config.get('boolean')).toBe(false); - // These attributes below are specified above, and although they're not part of the - // defaults, they should be available because "acceptAllDataConfigs" is true - expect(instance.config.get('extraAttr')).toBe('This should now be available'); - expect(instance.config.get('json')).toMatchObject({ - name: 'Ben' - }); - expect(instance.config.get('anotherBase64')).toBe(true); - expect(instance.config.get('jsonBase64')).toMatchObject({ - id: 1, - title: 'Some title', - }); - - expect(instance.config.get()).toMatchObject({ - id: null, - name: 'Ben', - stringValue: 'Hi there again', - boolean: false, - extraAttr: 'This should now be available', - json: { - name: 'Ben', - }, - anotherBase64: true, - jsonBase64: { - id: 1, - title: 'Some title', - }, - }); - - done(); - } catch (error) { - done(error); - } - } - ); - }); - - it('can refresh the config from the data attributes on the fly', function (done) { - FakeDom - .new() - .addCss([ - 'modules/system/assets/css/snowboard.extras.css', - ]) - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.extras.js', - 'tests/js/fixtures/dataConfig/DataConfigFixture.js', - ]) - .render( - `
` - ) - .then( - (dom) => { - const instance = dom.window.Snowboard.dataConfigFixture( - dom.window.document.querySelector('#testElement') - ); - - try { - expect(instance.config.get('id')).toBeNull(); - expect(instance.config.get('name')).toBe('Ben'); - expect(instance.config.get('stringValue')).toBe('Hi there again'); - expect(instance.config.get('boolean')).toBe(false); - - expect(instance.config.get()).toMatchObject({ - id: null, - name: 'Ben', - stringValue: 'Hi there again', - boolean: false, - }); - - dom.window.document.querySelector('#testElement').setAttribute('data-id', '456'); - dom.window.document.querySelector('#testElement').setAttribute('data-string-value', 'Changed'); - dom.window.document.querySelector('#testElement').removeAttribute('data-boolean'); - - // Refresh config - instance.config.refresh(); - - expect(instance.config.get('id')).toBe(456); - expect(instance.config.get('name')).toBe('Ben'); - expect(instance.config.get('stringValue')).toBe('Changed'); - expect(instance.config.get('boolean')).toBeNull(); - - expect(instance.config.get()).toMatchObject({ - id: 456, - name: 'Ben', - stringValue: 'Changed', - boolean: null, - }); - - done(); - } catch (error) { - done(error); - } - } - ); - }); - - it('can set config values at runtime', function (done) { - FakeDom - .new() - .addCss([ - 'modules/system/assets/css/snowboard.extras.css', - ]) - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.extras.js', - 'tests/js/fixtures/dataConfig/DataConfigFixture.js', - ]) - .render( - `
` - ) - .then( - (dom) => { - const instance = dom.window.Snowboard.dataConfigFixture( - dom.window.document.querySelector('#testElement') - ); - - try { - expect(instance.config.get('name')).toBe('Ben'); - // Set config - instance.config.set('name', 'Luke'); - expect(instance.config.get('name')).toBe('Luke'); - // Refresh config - instance.config.refresh(); - expect(instance.config.get('name')).toBe('Ben'); - done(); - } catch (error) { - done(error); - } - } - ); - }); - - it('can set config values at runtime that persist through a reset', function (done) { - FakeDom - .new() - .addCss([ - 'modules/system/assets/css/snowboard.extras.css', - ]) - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'modules/system/assets/js/snowboard/build/snowboard.extras.js', - 'tests/js/fixtures/dataConfig/DataConfigFixture.js', - ]) - .render( - `
` - ) - .then( - (dom) => { - const instance = dom.window.Snowboard.dataConfigFixture( - dom.window.document.querySelector('#testElement') - ); - - try { - expect(instance.config.get('name')).toBe('Ben'); - // Set config - instance.config.set('name', 'Luke', true); - expect(instance.config.get('name')).toBe('Luke'); - // Refresh config - instance.config.refresh(); - expect(instance.config.get('name')).toBe('Luke'); - done(); - } catch (error) { - done(error); - } - } - ); - }); -}); diff --git a/tests/js/cases/snowboard/main/PluginLoader.test.js b/tests/js/cases/snowboard/main/PluginLoader.test.js deleted file mode 100644 index 4e7b13e2dd..0000000000 --- a/tests/js/cases/snowboard/main/PluginLoader.test.js +++ /dev/null @@ -1,37 +0,0 @@ -import FakeDom from '../../../helpers/FakeDom'; - -describe('PluginLoader class', function () { - it('can mock plugin methods', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js' - ]) - .render() - .then( - (dom) => { - dom.window.Snowboard.getPlugin('sanitizer').mock('sanitize', () => { - return 'all good'; - }); - - expect( - dom.window.Snowboard.sanitizer().sanitize('

') - ).toEqual('all good'); - - // Test unmock - dom.window.Snowboard.getPlugin('sanitizer').unmock('sanitize'); - - expect( - dom.window.Snowboard.sanitizer().sanitize('

') - ).toEqual('

'); - - done(); - }, - (error) => { - done(error); - } - ); - }); -}); diff --git a/tests/js/cases/snowboard/main/Snowboard.test.js b/tests/js/cases/snowboard/main/Snowboard.test.js deleted file mode 100644 index 9f63ae2e20..0000000000 --- a/tests/js/cases/snowboard/main/Snowboard.test.js +++ /dev/null @@ -1,383 +0,0 @@ -import FakeDom from '../../../helpers/FakeDom'; - -describe('Snowboard framework', function () { - it('initialises correctly', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - try { - expect(dom.window.Snowboard).toBeDefined(); - expect(dom.window.Snowboard.addPlugin).toBeDefined(); - expect(dom.window.Snowboard.addPlugin).toEqual(expect.any(Function)); - - // Check PluginBase and Singleton abstracts exist - expect(dom.window.Snowboard.PluginBase).toBeDefined(); - expect(dom.window.Snowboard.Singleton).toBeDefined(); - - // Check in-built plugins - expect(dom.window.Snowboard.getPluginNames()).toEqual( - expect.arrayContaining(['jsonparser', 'sanitizer']) - ); - expect(dom.window.Snowboard.getPlugin('jsonparser').isFunction()).toEqual(false); - expect(dom.window.Snowboard.getPlugin('jsonparser').isSingleton()).toEqual(true); - expect(dom.window.Snowboard.getPlugin('sanitizer').isFunction()).toEqual(false); - expect(dom.window.Snowboard.getPlugin('sanitizer').isSingleton()).toEqual(true); - - done(); - } catch (error) { - done(error); - } - }, - (error) => { - throw error; - } - ); - }); - - it('can add and remove a plugin', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestPlugin.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - try { - // Check plugin caller - expect(Snowboard.hasPlugin('test')).toBe(true); - expect(Snowboard.getPluginNames()).toEqual( - expect.arrayContaining(['jsonparser', 'sanitizer', 'test']) - ); - expect(Snowboard.test).toEqual(expect.any(Function)); - - const instance = Snowboard.test(); - - // Check plugin injected methods - expect(instance.snowboard).toBe(Snowboard); - expect(instance.destructor).toEqual(expect.any(Function)); - - // Check plugin method - expect(instance.testMethod).toBeDefined(); - expect(instance.testMethod).toEqual(expect.any(Function)); - expect(instance.testMethod()).toEqual('Tested'); - - // Check multiple instances - const instanceOne = Snowboard.test(); - instanceOne.changed = true; - const instanceTwo = Snowboard.test(); - expect(instanceOne).not.toEqual(instanceTwo); - const factory = Snowboard.getPlugin('test'); - expect(factory.getInstances()).toEqual([instance, instanceOne, instanceTwo]); - - // Remove plugin - Snowboard.removePlugin('test'); - expect(Snowboard.hasPlugin('test')).toEqual(false); - expect(dom.window.Snowboard.getPluginNames()).toEqual( - expect.arrayContaining(['jsonparser', 'sanitizer']) - ); - expect(Snowboard.test).not.toBeDefined(); - - done(); - } catch (error) { - done(error); - } - }, - (error) => { - throw error; - } - ); - }); - - it('can add and remove a singleton', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestSingleton.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - try { - // Check plugin caller - expect(Snowboard.hasPlugin('test')).toBe(true); - expect(Snowboard.getPluginNames()).toEqual( - expect.arrayContaining(['jsonparser', 'sanitizer', 'test']) - ); - expect(Snowboard.test).toEqual(expect.any(Function)); - - const instance = Snowboard.test(); - - // Check plugin injected methods - expect(instance.snowboard).toBe(Snowboard); - expect(instance.destructor).toEqual(expect.any(Function)); - - // Check plugin method - expect(instance.testMethod).toBeDefined(); - expect(instance.testMethod).toEqual(expect.any(Function)); - expect(instance.testMethod()).toEqual('Tested'); - - // Check multiple instances (these should all be the same as this instance is a singleton) - const instanceOne = Snowboard.test(); - instanceOne.changed = true; - const instanceTwo = Snowboard.test(); - expect(instanceOne).toEqual(instanceTwo); - const factory = Snowboard.getPlugin('test'); - expect(factory.getInstances()).toEqual([instance]); - - // Remove plugin - Snowboard.removePlugin('test'); - expect(Snowboard.hasPlugin('test')).toEqual(false); - expect(dom.window.Snowboard.getPluginNames()).toEqual( - expect.arrayContaining([ 'jsonparser', 'sanitizer']) - ); - expect(Snowboard.test).not.toBeDefined(); - - done(); - } catch (error) { - done(error); - } - }, - (error) => { - throw error; - } - ); - }); - - it('can listen and call global events', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestListener.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - try { - expect(Snowboard.listensToEvent('eventOne')).toEqual(['test']); - expect(Snowboard.listensToEvent('eventTwo')).toEqual(['test']); - expect(Snowboard.listensToEvent('eventThree')).toEqual([]); - - // Call global event one - const testClass = Snowboard.test(); - Snowboard.globalEvent('eventOne', 42); - expect(testClass.eventResult).toEqual('Event called with arg 42'); - - // Call global event two - should fail as the test plugin doesn't have that method - expect(() => { - Snowboard.globalEvent('eventTwo'); - }).toThrow('Missing "notExists" method in "test" plugin'); - - // Call global event three - nothing should happen - expect(() => { - Snowboard.globalEvent('eventThree'); - }).not.toThrow(); - - done(); - } catch (error) { - done(error); - } - }, - (error) => { - throw error; - } - ); - }); - - it('can listen and call global promise events', function (done) { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestPromiseListener.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - try { - expect(Snowboard.listensToEvent('promiseOne')).toEqual(['test']); - expect(Snowboard.listensToEvent('promiseTwo')).toEqual(['test']); - expect(Snowboard.listensToEvent('promiseThree')).toEqual([]); - - // Call global event one - const testClass = Snowboard.test(); - Snowboard.globalPromiseEvent('promiseOne', 'promise').then( - () => { - expect(testClass.eventResult).toEqual('Event called with arg promise'); - - // Call global event two - it should still work, even though it doesn't return a promise - Snowboard.globalPromiseEvent('promiseTwo', 'promise 2').then( - () => { - expect(testClass.eventResult).toEqual('Promise two called with arg promise 2'); - - // Call global event three - it should still work - Snowboard.globalPromiseEvent('promiseThree', 'promise 3').then( - () => { - done(); - }, - (error) => { - done(error); - } - ); - }, - (error) => { - done(error); - } - ); - }, - (error) => { - done(error); - } - ); - } catch (error) { - done(error); - } - }, - (error) => { - throw error; - } - ); - }); - - it('will throw an error when using a plugin that has unfulfilled dependencies', function () { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestHasDependencies.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - expect(() => { - Snowboard.testHasDependencies(); - }).toThrow('The "testhasdependencies" plugin requires the following plugins: testdependencyone, testdependencytwo'); - }, - (error) => { - throw error; - } - ); - }); - - it('will throw an error when using a plugin that has some unfulfilled dependencies', function () { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestHasDependencies.js', - 'tests/js/fixtures/framework/TestDependencyOne.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - expect(() => { - Snowboard.testHasDependencies(); - }).toThrow('The "testhasdependencies" plugin requires the following plugins: testdependencytwo'); - }, - (error) => { - throw error; - } - ); - }); - - it('will not throw an error when using a plugin that has fulfilled dependencies', function () { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestDependencyTwo.js', - 'tests/js/fixtures/framework/TestHasDependencies.js', - 'tests/js/fixtures/framework/TestDependencyOne.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - expect(() => { - Snowboard.testHasDependencies(); - }).not.toThrow(); - - expect(Snowboard.testHasDependencies().testMethod()).toEqual('Tested'); - }, - (error) => { - throw error; - } - ); - }); - - it('will not initialise a singleton that has unfulfilled dependencies', function () { - FakeDom - .new() - .addScript([ - 'modules/system/assets/js/build/manifest.js', - 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', - 'modules/system/assets/js/snowboard/build/snowboard.base.js', - 'tests/js/fixtures/framework/TestSingletonWithDependency.js', - ]) - .render() - .then( - (dom) => { - // Run assertions - const Snowboard = dom.window.Snowboard; - - expect(() => { - Snowboard.testSingleton(); - }).toThrow('The "testsingleton" plugin requires the following plugins: testdependencyone'); - - expect(Snowboard.listensToEvent('ready')).not.toContain('testsingleton'); - - expect(() => { - Snowboard.globalEvent('ready'); - }).not.toThrow(); - }, - (error) => { - throw error; - } - ); - }); -}); diff --git a/tests/js/fixtures/dataConfig/DataConfigFixture.js b/tests/js/fixtures/dataConfig/DataConfigFixture.js deleted file mode 100644 index 0e73731ce3..0000000000 --- a/tests/js/fixtures/dataConfig/DataConfigFixture.js +++ /dev/null @@ -1,26 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class DataConfigFixture extends Snowboard.PluginBase { - construct(element) { - this.element = element; - this.config = this.snowboard.dataConfig(this, element); - } - - dependencies() { - return ['dataConfig']; - } - - defaults() { - return { - id: null, - name: null, - stringValue: null, - boolean: null, - base64: null, - }; - } - } - - Snowboard.addPlugin('dataConfigFixture', DataConfigFixture); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestDependencyOne.js b/tests/js/fixtures/framework/TestDependencyOne.js deleted file mode 100644 index b4dc4814a9..0000000000 --- a/tests/js/fixtures/framework/TestDependencyOne.js +++ /dev/null @@ -1,11 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestDependencyOne extends Snowboard.Singleton { - testMethod() { - return 'Tested'; - } - } - - Snowboard.addPlugin('testDependencyOne', TestDependencyOne); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestDependencyTwo.js b/tests/js/fixtures/framework/TestDependencyTwo.js deleted file mode 100644 index 3af681b782..0000000000 --- a/tests/js/fixtures/framework/TestDependencyTwo.js +++ /dev/null @@ -1,11 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestDependencyTwo extends Snowboard.Singleton { - testMethod() { - return 'Tested'; - } - } - - Snowboard.addPlugin('testDependencyTwo', TestDependencyTwo); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestHasDependencies.js b/tests/js/fixtures/framework/TestHasDependencies.js deleted file mode 100644 index 18f7859560..0000000000 --- a/tests/js/fixtures/framework/TestHasDependencies.js +++ /dev/null @@ -1,15 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestHasDependencies extends Snowboard.Singleton { - dependencies() { - return ['testDependencyOne', 'testDependencyTwo']; - } - - testMethod() { - return 'Tested'; - } - } - - Snowboard.addPlugin('testHasDependencies', TestHasDependencies); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestListener.js b/tests/js/fixtures/framework/TestListener.js deleted file mode 100644 index 5bd4f6bffb..0000000000 --- a/tests/js/fixtures/framework/TestListener.js +++ /dev/null @@ -1,18 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestListener extends Snowboard.Singleton { - listens() { - return { - eventOne: 'eventOne', - eventTwo: 'notExists' - }; - } - - eventOne(arg) { - this.eventResult = 'Event called with arg ' + arg; - } - } - - Snowboard.addPlugin('test', TestListener); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestPlugin.js b/tests/js/fixtures/framework/TestPlugin.js deleted file mode 100644 index 568d6a6b93..0000000000 --- a/tests/js/fixtures/framework/TestPlugin.js +++ /dev/null @@ -1,11 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestPlugin extends Snowboard.PluginBase { - testMethod() { - return 'Tested'; - } - } - - Snowboard.addPlugin('test', TestPlugin); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestPromiseListener.js b/tests/js/fixtures/framework/TestPromiseListener.js deleted file mode 100644 index 1126ed93ef..0000000000 --- a/tests/js/fixtures/framework/TestPromiseListener.js +++ /dev/null @@ -1,28 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestPromiseListener extends Snowboard.Singleton { - listens() { - return { - promiseOne: 'promiseOne', - promiseTwo: 'promiseTwo' - }; - } - - promiseOne(arg) { - return new Promise((resolve) => { - window.setTimeout(() => { - this.eventResult = 'Event called with arg ' + arg; - resolve(); - }, 500); - }); - } - - promiseTwo(arg) { - this.eventResult = 'Promise two called with arg ' + arg; - return true; - } - } - - Snowboard.addPlugin('test', TestPromiseListener); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestSingleton.js b/tests/js/fixtures/framework/TestSingleton.js deleted file mode 100644 index 45989248bf..0000000000 --- a/tests/js/fixtures/framework/TestSingleton.js +++ /dev/null @@ -1,11 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestSingleton extends Snowboard.Singleton { - testMethod() { - return 'Tested'; - } - } - - Snowboard.addPlugin('test', TestSingleton); -})(window.Snowboard); diff --git a/tests/js/fixtures/framework/TestSingletonWithDependency.js b/tests/js/fixtures/framework/TestSingletonWithDependency.js deleted file mode 100644 index 1aba7718e0..0000000000 --- a/tests/js/fixtures/framework/TestSingletonWithDependency.js +++ /dev/null @@ -1,25 +0,0 @@ -/* globals window */ - -((Snowboard) => { - class TestSingletonWithDependency extends Snowboard.Singleton { - dependencies() { - return ['testDependencyOne']; - } - - listens() { - return { - ready: 'ready', - }; - } - - ready() { - return 'Ready'; - } - - testMethod() { - return 'Tested'; - } - } - - Snowboard.addPlugin('testSingleton', TestSingletonWithDependency); -})(window.Snowboard); diff --git a/tests/js/helpers/FakeDom.js b/tests/js/helpers/FakeDom.js deleted file mode 100644 index 6ddf61e9fd..0000000000 --- a/tests/js/helpers/FakeDom.js +++ /dev/null @@ -1,189 +0,0 @@ -/* globals __dirname, URL */ - -import { JSDOM } from 'jsdom' -import path from 'path' - -export default class FakeDom -{ - constructor(content, options) - { - if (options === undefined) { - options = {}; - } - - // Header settings - this.url = options.url || `file://${path.resolve(__dirname, '../../')}`; - this.referer = options.referer; - this.contentType = options.contentType || 'text/html'; - - // Content settings - this.headStart = options.headStart || 'Fake document'; - this.headEnd = options.headEnd || ''; - this.bodyStart = options.bodyStart || ''; - this.content = content || ''; - this.bodyEnd = options.bodyEnd || ''; - this.foot = options.foot || ''; - - // Callback settings - this.beforeParse = (typeof options.beforeParse === 'function') - ? options.beforeParse - : undefined; - - // Assets - this.css = []; - this.scripts = []; - this.inline = []; - } - - static new(content, options) - { - return new FakeDom(content, options); - } - - setContent(content) - { - this.content = content; - return this; - } - - addScript(script, id) - { - if (Array.isArray(script)) { - script.forEach((item) => { - this.addScript(item); - }); - - return this; - } - - let url = new URL(script, this.url); - let base = new URL(this.url); - - if (url.host === base.host) { - this.scripts.push({ - url: `${url.pathname}`, - id: id || this.generateId(), - }); - } else { - this.scripts.push({ - url, - id: id || this.generateId(), - }); - } - - return this; - } - - addCss(css, id) - { - if (Array.isArray(css)) { - css.forEach((item) => { - this.addCss(item) - }); - - return this; - } - - let url = new URL(css, this.url); - let base = new URL(this.url); - - if (url.host === base.host) { - this.css.push({ - url: `${url.pathname}`, - id: id || this.generateId(), - }); - } else { - this.css.push({ - url, - id: id || this.generateId(), - }); - } - - return this; - } - - addInlineScript(script, id) - { - this.inline.push({ - script, - id: id || this.generateId(), - element: null, - }); - - return this; - } - - generateId() - { - let id = 'script-'; - let chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'; - let charLength = chars.length; - - for (let i = 0; i < 10; i++) { - let currentChar = chars.substr(Math.floor(Math.random() * charLength), 1); - id = `${id}${currentChar}`; - } - - return id; - } - - render(content) - { - if (content) { - this.content = content; - } - return new Promise((resolve, reject) => { - try { - const dom = new JSDOM( - this._renderContent(), - { - url: this.url, - referrer: this.referer, - contentType: this.contentType, - includeNodeLocations: true, - runScripts: 'dangerously', - resources: 'usable', - pretendToBeVisual: true, - beforeParse: this.beforeParse, - } - ); - - dom.window.resolver = () => { - resolve(dom); - }; - } catch (e) { - reject(e); - } - }); - } - - _renderContent() - { - // Create content list - const content = [this.headStart]; - - // Embed CSS - this.css.forEach((css) => { - content.push(``); - }); - - content.push(this.headEnd, this.bodyStart, this.content); - - // Embed scripts - this.scripts.forEach((script) => { - content.push(``); - }); - this.inline.forEach((script) => { - content.push(``); - }); - - // Add resolver - content.push(``); - - // Add final content - content.push(this.bodyEnd); - content.push(this.foot); - - return content.join('\n'); - } -} diff --git a/tests/js/jest.config.js b/tests/js/jest.config.js deleted file mode 100644 index 1363597d68..0000000000 --- a/tests/js/jest.config.js +++ /dev/null @@ -1,194 +0,0 @@ -/* - * For a detailed explanation regarding each configuration property, visit: - * https://jestjs.io/docs/configuration - */ - -module.exports = { - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after `n` failures - // bail: 0, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: "/private/var/folders/81/m6w95r0j7ms_10c47hdbz4gw0000gn/T/jest_dx", - - // Automatically clear mock calls, instances and results before every test - clearMocks: true, - - // Indicates whether the coverage information should be collected while executing the test - // collectCoverage: false, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - // collectCoverageFrom: undefined, - - // The directory where Jest should output its coverage files - // coverageDirectory: undefined, - - // An array of regexp pattern strings used to skip coverage collection - // coveragePathIgnorePatterns: [ - // "/node_modules/" - // ], - - // Indicates which provider should be used to instrument code for coverage - // coverageProvider: "babel", - - // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // "json", - // "text", - // "lcov", - // "clover" - // ], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: undefined, - - // A path to a custom dependency extractor - // dependencyExtractor: undefined, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // A set of global variables that need to be available in all test environments - // globals: {}, - - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. - // maxWorkers: "50%", - - // An array of directory names to be searched recursively up from the requiring module's location - // moduleDirectories: [ - // "node_modules" - // ], - - // An array of file extensions your modules use - // moduleFileExtensions: [ - // "js", - // "jsx", - // "ts", - // "tsx", - // "json", - // "node" - // ], - - // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module - // moduleNameMapper: {}, - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: "failure-change", - - // A preset that is used as a base for Jest's configuration - // preset: undefined, - - // Run tests from one or more projects - // projects: undefined, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state before every test - // resetMocks: false, - - // Reset the module registry before running each individual test - // resetModules: false, - - // A path to a custom resolver - // resolver: undefined, - - // Automatically restore mock state and implementation before every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within - // rootDir: undefined, - - // A list of paths to directories that Jest should use to search for files in - // roots: [ - // "" - // ], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: "jest-runner", - - // The paths to modules that run some code to configure or set up the testing environment before each test - // setupFiles: [], - - // A list of paths to modules that run some code to configure or set up the testing framework before each test - // setupFilesAfterEnv: [], - - // The number of seconds after which a test is considered as slow and reported as such in the results. - // slowTestThreshold: 5, - - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // The test environment that will be used for testing - // testEnvironment: "jest-environment-node", - - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files - // testMatch: [ - // "**/__tests__/**/*.[jt]s?(x)", - // "**/?(*.)+(spec|test).[tj]s?(x)" - // ], - - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // "/node_modules/" - // ], - - // The regexp pattern or array of patterns that Jest uses to detect test files - // testRegex: [], - - // This option allows the use of a custom results processor - // testResultsProcessor: undefined, - - // This option allows use of a custom test runner - // testRunner: "jest-circus/runner", - - // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href - // testURL: "http://localhost", - - // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" - // timers: "real", - - // A map from regular expressions to paths to transformers - // transform: undefined, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - // transformIgnorePatterns: [ - // "/node_modules/", - // "\\.pnp\\.[^\\/]+$" - // ], - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - // verbose: undefined, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, -}; diff --git a/tests/js/package.json b/tests/js/package.json deleted file mode 100644 index 650f38698f..0000000000 --- a/tests/js/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@wintercms/tests", - "description": "Test cases for the Winter JavaScript framework", - "private": true, - "scripts": { - "test": "jest" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/wintercms/winter.git" - }, - "contributors": [ - { - "name": "Ben Thomson", - "email": "git@alfreido.com" - }, - { - "name": "Winter CMS Maintainers", - "url": "https://wintercms.com/" - } - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/wintercms/winter/issues" - }, - "homepage": "https://wintercms.com/", - "devDependencies": { - "@babel/core": "^7.16.0", - "@babel/plugin-transform-runtime": "^7.16.4", - "@babel/preset-env": "^7.16.4", - "@babel/register": "^7.16.0", - "@babel/runtime": "^7.16.3", - "babel-plugin-module-resolver": "^4.1.0", - "jest": "^27.4.3", - "jsdom": "^18.1.1" - } -} diff --git a/tests/unit/backend/widgets/FormTest.php b/tests/unit/backend/widgets/FormTest.php deleted file mode 100644 index bcfd630d00..0000000000 --- a/tests/unit/backend/widgets/FormTest.php +++ /dev/null @@ -1,235 +0,0 @@ -actingAs($user); - - $form = $this->restrictedFormFixture(); - - $form->render(); - $this->assertNull($form->getField('testRestricted')); - } - - public function testRestrictedFieldWithUserWithWrongPermissions() - { - $user = new UserFixture; - $this->actingAs($user->withPermission('test.wrong_permission', true)); - - $form = $this->restrictedFormFixture(); - - $form->render(); - $this->assertNull($form->getField('testRestricted')); - } - - public function testRestrictedFieldWithUserWithRightPermissions() - { - $user = new UserFixture; - $this->actingAs($user->withPermission('test.access_field', true)); - - $form = $this->restrictedFormFixture(); - - $form->render(); - $this->assertNotNull($form->getField('testRestricted')); - } - - public function testRestrictedFieldWithUserWithRightWildcardPermissions() - { - $user = new UserFixture; - $this->actingAs($user->withPermission('test.access_field', true)); - - $form = new Form(null, [ - 'model' => new FormTestModel, - 'arrayName' => 'array', - 'fields' => [ - 'testField' => [ - 'type' => 'text', - 'label' => 'Test 1' - ], - 'testRestricted' => [ - 'type' => 'text', - 'label' => 'Test 2', - 'permission' => 'test.*' - ] - ] - ]); - - $form->render(); - $this->assertNotNull($form->getField('testRestricted')); - } - - public function testRestrictedFieldWithSuperuser() - { - $user = new UserFixture; - $this->actingAs($user->asSuperUser()); - - $form = $this->restrictedFormFixture(); - - $form->render(); - $this->assertNotNull($form->getField('testRestricted')); - } - - public function testRestrictedFieldSinglePermissionWithUserWithWrongPermissions() - { - $user = new UserFixture; - $this->actingAs($user->withPermission('test.wrong_permission', true)); - - $form = $this->restrictedFormFixture(true); - - $form->render(); - $this->assertNull($form->getField('testRestricted')); - } - - public function testRestrictedFieldSinglePermissionWithUserWithRightPermissions() - { - $user = new UserFixture; - $this->actingAs($user->withPermission('test.access_field', true)); - - $form = $this->restrictedFormFixture(true); - - $form->render(); - $this->assertNotNull($form->getField('testRestricted')); - } - - public function testCheckboxlistTrigger() - { - $form = new Form(null, [ - 'model' => new FormTestModel, - 'arrayName' => 'array', - 'fields' => [ - 'trigger' => [ - 'type' => 'checkboxlist', - 'options' => [ - '1' => 'Value One' - ] - ], - 'triggered' => [ - 'type' => 'text', - 'trigger' => [ - 'field' => 'trigger[]', - 'action' => 'show', - 'condition' => 'value[1]' - ] - ] - ] - ]); - - $form->render(); - - $attributes = $form->getField('triggered')->getAttributes('container', false); - $this->assertEquals('[name="array[trigger][]"]', array_get($attributes, 'data-trigger')); - } - - public function testOptionsGeneration() - { - $form = new Form(null, [ - 'model' => new FormTestModel, - 'arrayName' => 'array', - 'fields' => [ - 'static_method_options' => [ - 'type' => 'dropdown', - 'options' => 'FormHelper::staticMethodOptions', - 'expect' => ['static', 'method'], - ], - 'callable_options' => [ - 'type' => 'dropdown', - 'options' => [\FormHelper::class, 'staticMethodOptions'], - 'expect' => ['static', 'method'], - ], - 'model_method_options' => [ - 'type' => 'dropdown', - 'options' => 'modelCustomOptionsMethod', - 'expect' => ['model', 'custom', 'options'], - ], - 'defined_options' => [ - 'type' => 'dropdown', - 'options' => ['value1', 'value2'], - 'expect' => ['value1', 'value2'], - ], - 'defined_options_key_value' => [ - 'type' => 'dropdown', - 'options' => [ - 'key1' => 'value1', - 'key2' => 'value2', - ], - 'expect' => [ - 'key1' => 'value1', - 'key2' => 'value2', - ], - ], - 'field_name_on_model_options_method' => [ - 'type' => 'dropdown', - 'expect' => ['model', 'field name', 'options method'], - ], - 'get_dropdown_options_method' => [ - 'type' => 'dropdown', - 'expect' => ['dropdown', 'options'], - ], - ] - ]); - - $form->render(); - - foreach ($form->getFields() as $name => $field) { - $this->assertEquals($field->options(), $field->config['expect']); - } - } - - protected function restrictedFormFixture(bool $singlePermission = false) - { - return new Form(null, [ - 'model' => new FormTestModel, - 'arrayName' => 'array', - 'fields' => [ - 'testField' => [ - 'type' => 'text', - 'label' => 'Test 1' - ], - 'testRestricted' => [ - 'type' => 'text', - 'label' => 'Test 2', - 'permissions' => ($singlePermission) ? 'test.access_field' : [ - 'test.access_field' - ] - ] - ] - ]); - } -} diff --git a/tests/unit/plugins/backend/ImportModelDbTest.php b/tests/unit/plugins/backend/ImportModelDbTest.php deleted file mode 100644 index 61a1d8ea95..0000000000 --- a/tests/unit/plugins/backend/ImportModelDbTest.php +++ /dev/null @@ -1,42 +0,0 @@ - base_path().'/tests/fixtures/backend/reference/file1.txt', - 'is_public' => false, - ]); - - $file2 = FileModel::create([ - 'data' => base_path().'/tests/fixtures/backend/reference/file2.txt', - 'is_public' => false, - ]); - - $model->import_file()->add($file1, $sessionKey); - $model->import_file()->add($file2, $sessionKey); - - $this->assertEquals( - $file2->getLocalPath(), - $model->getImportFilePath($sessionKey), - 'ImportModel::getImportFilePath() should return the last uploaded file.' - ); - } -} From 7b441ad3021929bc9a69c2df4959e51343a92f17 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 05:33:47 +0100 Subject: [PATCH 02/22] Added js tests --- modules/system/tests/js/.babelrc | 17 + modules/system/tests/js/.gitignore | 3 + modules/system/tests/js/README.md | 32 + .../js/cases/snowboard/ajax/Request.test.js | 625 ++++++++++++++++++ .../cases/snowboard/extras/DataConfig.test.js | 316 +++++++++ .../cases/snowboard/main/PluginLoader.test.js | 37 ++ .../js/cases/snowboard/main/Snowboard.test.js | 383 +++++++++++ .../fixtures/dataConfig/DataConfigFixture.js | 26 + .../fixtures/framework/TestDependencyOne.js | 11 + .../fixtures/framework/TestDependencyTwo.js | 11 + .../fixtures/framework/TestHasDependencies.js | 15 + .../js/fixtures/framework/TestListener.js | 18 + .../tests/js/fixtures/framework/TestPlugin.js | 11 + .../fixtures/framework/TestPromiseListener.js | 28 + .../js/fixtures/framework/TestSingleton.js | 11 + .../framework/TestSingletonWithDependency.js | 25 + modules/system/tests/js/helpers/FakeDom.js | 189 ++++++ modules/system/tests/js/jest.config.js | 194 ++++++ modules/system/tests/js/package.json | 37 ++ 19 files changed, 1989 insertions(+) create mode 100644 modules/system/tests/js/.babelrc create mode 100644 modules/system/tests/js/.gitignore create mode 100644 modules/system/tests/js/README.md create mode 100644 modules/system/tests/js/cases/snowboard/ajax/Request.test.js create mode 100644 modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js create mode 100644 modules/system/tests/js/cases/snowboard/main/PluginLoader.test.js create mode 100644 modules/system/tests/js/cases/snowboard/main/Snowboard.test.js create mode 100644 modules/system/tests/js/fixtures/dataConfig/DataConfigFixture.js create mode 100644 modules/system/tests/js/fixtures/framework/TestDependencyOne.js create mode 100644 modules/system/tests/js/fixtures/framework/TestDependencyTwo.js create mode 100644 modules/system/tests/js/fixtures/framework/TestHasDependencies.js create mode 100644 modules/system/tests/js/fixtures/framework/TestListener.js create mode 100644 modules/system/tests/js/fixtures/framework/TestPlugin.js create mode 100644 modules/system/tests/js/fixtures/framework/TestPromiseListener.js create mode 100644 modules/system/tests/js/fixtures/framework/TestSingleton.js create mode 100644 modules/system/tests/js/fixtures/framework/TestSingletonWithDependency.js create mode 100644 modules/system/tests/js/helpers/FakeDom.js create mode 100644 modules/system/tests/js/jest.config.js create mode 100644 modules/system/tests/js/package.json diff --git a/modules/system/tests/js/.babelrc b/modules/system/tests/js/.babelrc new file mode 100644 index 0000000000..710cfd1b16 --- /dev/null +++ b/modules/system/tests/js/.babelrc @@ -0,0 +1,17 @@ +{ + "presets": [ + "@babel/preset-env" + ], + "plugins": [ + "@babel/plugin-transform-runtime", + [ + "module-resolver", { + "root": ["."], + "alias": { + "helpers": "./helpers", + "snowboard": "../../modules/system/assets/js/snowboard", + } + } + ] + ] +} diff --git a/modules/system/tests/js/.gitignore b/modules/system/tests/js/.gitignore new file mode 100644 index 0000000000..7f9265d1a6 --- /dev/null +++ b/modules/system/tests/js/.gitignore @@ -0,0 +1,3 @@ +# Ignore packages +package-lock.json +node_modules diff --git a/modules/system/tests/js/README.md b/modules/system/tests/js/README.md new file mode 100644 index 0000000000..7903252577 --- /dev/null +++ b/modules/system/tests/js/README.md @@ -0,0 +1,32 @@ +# Snowboard Framework Testing Suite + +The files in this directory form the testing suite for the new Winter JavaScript framework - Snowboard. You must install +all Node dependencies in order to run the testing suite: + +```bash +cd tests/js +npm install +``` + +You can then run the tests by using the following command: + +```bash +npm run test +``` + +Please note that the tests are run against the "built" versions of Snowboard and its plugins, in order to test +the exact same functionality that would be delivered to the end user. We do this by leveraging the `JSDOM` library to +simulate an entire HTML document. + +Therefore, you must compile a new build if you make any changes and wish to run the tests: + +```bash +php artisan mix:compile --package snowboard +``` + +You can also watch the framework for any changes, which will automatically run a build after a change is made. This will +make development and testing in parallel much quicker: + +```bash +php artisan mix:watch snowboard +``` diff --git a/modules/system/tests/js/cases/snowboard/ajax/Request.test.js b/modules/system/tests/js/cases/snowboard/ajax/Request.test.js new file mode 100644 index 0000000000..c2dc5cbb1e --- /dev/null +++ b/modules/system/tests/js/cases/snowboard/ajax/Request.test.js @@ -0,0 +1,625 @@ +import FakeDom from '../../../helpers/FakeDom'; + +jest.setTimeout(2000); + +describe('Request AJAX library', function () { + it('can be setup via a global event', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new dom.window.Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to global event + dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { + listens() { + return { + ajaxSetup: 'ajaxSetup', + }; + } + + ajaxSetup(instance) { + instance.handler = 'onChanged'; + } + }); + + dom.window.Snowboard.request(undefined, 'onTest', { + complete: (data, instance) => { + expect(instance.handler).toEqual('onChanged'); + done(); + } + }); + } + ); + }); + + it('can be cancelled on setup via a global event', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new dom.window.Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to global event + dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { + listens() { + return { + ajaxSetup: 'ajaxSetup', + }; + } + + ajaxSetup() { + // Should cancel + return false; + } + }); + + const instance = dom.window.Snowboard.request(undefined, 'onTest', { + complete: (data, instance) => { + done(new Error('Request did not cancel')); + } + }); + expect(instance.cancelled).toEqual(true); + done(); + } + ); + }); + + it('can be setup via a listener on the HTML element', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render('') + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new dom.window.Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to HTML element event + const element = dom.window.document.getElementById('testElement'); + element.addEventListener('ajaxSetup', (event) => { + expect(event.request).toBeDefined(); + event.request.handler = 'onChanged'; + }); + + + dom.window.Snowboard.request(element, 'onTest', { + complete: (data, instance) => { + expect(instance.handler).toEqual('onChanged'); + done(); + } + }); + } + ); + }); + + it('can be cancelled on setup via a listener on the HTML element', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render('') + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new dom.window.Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to HTML element event + const element = dom.window.document.getElementById('testElement'); + element.addEventListener('ajaxSetup', (event) => { + event.preventDefault(); + }); + + const instance = dom.window.Snowboard.request(element, 'onTest', { + complete: (data, instance) => { + done(new Error('Request did not cancel')); + } + }); + expect(instance.cancelled).toEqual(true); + done(); + } + ); + }); + + it('can do a request and listen for completion', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + dom.window.Snowboard.request(undefined, 'onTest', { + complete: (data, instance) => { + expect(data).toEqual({ + success: true, + }); + expect(instance.responseData).toEqual({ + success: true, + }); + expect(instance.responseError).toEqual(null); + + done(); + return false; + } + }); + } + ); + }); + + it('can do a request and listen for completion via a global event', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to global event + dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { + listens() { + return { + ajaxDone: 'ajaxDone', + }; + } + + ajaxDone(data, instance) { + expect(data).toEqual({ + success: true, + }); + expect(instance.responseData).toEqual({ + success: true, + }); + expect(instance.responseError).toEqual(null); + + done(); + } + }); + + dom.window.Snowboard.request(undefined, 'onTest'); + } + ); + }); + + it('can do a request and listen for completion via a listener on the HTML element', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render('') + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new dom.window.Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to HTML element event + const element = dom.window.document.getElementById('testElement'); + element.addEventListener('ajaxAlways', (event) => { + expect(event.request).toBeDefined(); + expect(event.responseData).toEqual({ + success: true + }); + expect(event.responseError).toEqual(null); + done(); + }); + + dom.window.Snowboard.request(element, 'onTest'); + } + ); + }); + + it('can do a request and listen for success', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + dom.window.Snowboard.request(undefined, 'onTest', { + success: (data, instance) => { + expect(data).toEqual({ + success: true, + }); + expect(instance.responseData).toEqual({ + success: true, + }); + expect(instance.responseError).toEqual(null); + }, + complete: (data, instance) => { + expect(data).toEqual({ + success: true, + }); + expect(instance.responseData).toEqual({ + success: true, + }); + expect(instance.responseError).toEqual(null); + + done(); + }, + }); + } + ); + }); + + it('can do a request and listen for success via a global event', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate success response + const resolved = Promise.resolve({ + success: true + }); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to global event + dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { + listens() { + return { + ajaxSuccess: 'ajaxSuccess', + }; + } + + ajaxSuccess(data, instance) { + expect(data).toEqual({ + success: true, + }) + expect(instance.responseData).toEqual({ + success: true, + }); + expect(instance.responseError).toEqual(null); + + done(); + } + }); + + dom.window.Snowboard.request(undefined, 'onTest'); + } + ); + }); + + it('can do a request and listen for failure', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate error response + const resolved = Promise.reject('This is an error'); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + dom.window.Snowboard.request(undefined, 'onTest', { + error: (data, instance) => { + expect(data).toEqual('This is an error'); + expect(instance.responseData).toEqual(null); + expect(instance.responseError).toEqual('This is an error'); + }, + complete: (data, instance) => { + // Data will be null because no data was provided in the response. + expect(data).toBeNull(); + expect(instance.responseData).toEqual(null); + expect(instance.responseError).toEqual('This is an error'); + + done(); + }, + }); + } + ); + }); + + it('can do a request and listen for failure via global event', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('request').mock('doAjax', (instance) => { + // Simulate error response + const resolved = Promise.reject('This is an error'); + + // Mock events + instance.snowboard.globalEvent('ajaxStart', instance, resolved); + + if (instance.element) { + const event = new Event('ajaxPromise'); + event.promise = resolved; + instance.element.dispatchEvent(event); + } + + return resolved; + }); + + // Listen to global event + dom.window.Snowboard.addPlugin('testListener', class TestListener extends dom.window.Snowboard.Singleton { + listens() { + return { + ajaxError: 'ajaxError', + }; + } + + ajaxError(data, instance) { + expect(data).toEqual('This is an error') + expect(instance.responseData).toEqual(null); + expect(instance.responseError).toEqual('This is an error'); + + done(); + } + }); + + dom.window.Snowboard.request(undefined, 'onTest'); + } + ); + }); + + it('requires a valid HTML element if provided', function () { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + expect(() => { + const docFragment = dom.window.document.createDocumentFragment(); + dom.window.Snowboard.request(docFragment, 'onTest'); + }).toThrow('The element provided must be an Element instance'); + } + ); + }); + + it('requires a handler to be specified', function () { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + expect(() => { + dom.window.Snowboard.request(undefined, undefined); + }).toThrow('The AJAX handler name is not specified'); + } + ); + }); + + it('requires a handler to be of the correct format', function () { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.request.js' + ]) + .render() + .then( + (dom) => { + expect(() => { + dom.window.Snowboard.request(undefined, 'notRight'); + }).toThrow('Invalid AJAX handler name'); + } + ); + }); +}); diff --git a/modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js b/modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js new file mode 100644 index 0000000000..339f0c09d3 --- /dev/null +++ b/modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js @@ -0,0 +1,316 @@ +import FakeDom from '../../../helpers/FakeDom'; + +jest.setTimeout(2000); + +describe('The Data Config extra functionality', function () { + it('can read the config from an element\'s data attributes', function (done) { + FakeDom + .new() + .addCss([ + 'modules/system/assets/css/snowboard.extras.css', + ]) + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.extras.js', + 'tests/js/fixtures/dataConfig/DataConfigFixture.js', + ]) + .render( + `
+ +
` + ) + .then( + (dom) => { + const instance = dom.window.Snowboard.dataConfigFixture( + dom.window.document.querySelector('#testElement') + ); + + try { + expect(instance.config.get('id')).toEqual(389); + // Name should be null as it's the default value and not specified above + expect(instance.config.get('name')).toBeNull(); + expect(instance.config.get('stringValue')).toBe('Hi there'); + // Missing should be undefined as it's neither defined nor part of the default data + expect(instance.config.get('missing')).toBeUndefined(); + expect(instance.config.get('boolean')).toBe(true); + + expect(instance.config.get()).toMatchObject({ + id: 389, + name: null, + stringValue: 'Hi there', + boolean: true, + base64: null, + }); + } catch (error) { + done(error); + return; + } + + const instanceTwo = dom.window.Snowboard.dataConfigFixture( + dom.window.document.querySelector('#testElementTwo') + ); + + try { + // ID is null as it's the default value and not specified above + expect(instanceTwo.config.get('id')).toBeNull(); + expect(instanceTwo.config.get('name')).toBe('Ben'); + expect(instanceTwo.config.get('stringValue')).toBe('Hi there again'); + expect(instanceTwo.config.get('missing')).toBeUndefined(); + expect(instanceTwo.config.get('boolean')).toBe(false); + // Extra attr is specified above, but it should not be available as a config value + // because it's not part of the `defaults()` in the fixture + expect(instanceTwo.config.get('extraAttr')).toBeUndefined(); + // Base-64 decoded string + expect(instanceTwo.config.get('base64')).toBe('I\'m a Base64-decoded string'); + + done(); + } catch (error) { + done(error); + } + } + ); + }); + + it('can read the config from every data attribute of an element with "acceptAllDataConfigs" enabled', function (done) { + FakeDom + .new() + .addCss([ + 'modules/system/assets/css/snowboard.extras.css', + ]) + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.extras.js', + 'tests/js/fixtures/dataConfig/DataConfigFixture.js', + ]) + .render( + `
` + ) + .then( + (dom) => { + const instance = dom.window.Snowboard.dataConfigFixture( + dom.window.document.querySelector('#testElementTwo') + ); + instance.acceptAllDataConfigs = true; + instance.config.refresh(); + + try { + // ID is null as it's the default value and not specified above + expect(instance.config.get('id')).toBeNull(); + expect(instance.config.get('name')).toBe('Ben'); + expect(instance.config.get('stringValue')).toBe('Hi there again'); + expect(instance.config.get('missing')).toBeUndefined(); + expect(instance.config.get('boolean')).toBe(false); + // These attributes below are specified above, and although they're not part of the + // defaults, they should be available because "acceptAllDataConfigs" is true + expect(instance.config.get('extraAttr')).toBe('This should now be available'); + expect(instance.config.get('json')).toMatchObject({ + name: 'Ben' + }); + expect(instance.config.get('anotherBase64')).toBe(true); + expect(instance.config.get('jsonBase64')).toMatchObject({ + id: 1, + title: 'Some title', + }); + + expect(instance.config.get()).toMatchObject({ + id: null, + name: 'Ben', + stringValue: 'Hi there again', + boolean: false, + extraAttr: 'This should now be available', + json: { + name: 'Ben', + }, + anotherBase64: true, + jsonBase64: { + id: 1, + title: 'Some title', + }, + }); + + done(); + } catch (error) { + done(error); + } + } + ); + }); + + it('can refresh the config from the data attributes on the fly', function (done) { + FakeDom + .new() + .addCss([ + 'modules/system/assets/css/snowboard.extras.css', + ]) + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.extras.js', + 'tests/js/fixtures/dataConfig/DataConfigFixture.js', + ]) + .render( + `
` + ) + .then( + (dom) => { + const instance = dom.window.Snowboard.dataConfigFixture( + dom.window.document.querySelector('#testElement') + ); + + try { + expect(instance.config.get('id')).toBeNull(); + expect(instance.config.get('name')).toBe('Ben'); + expect(instance.config.get('stringValue')).toBe('Hi there again'); + expect(instance.config.get('boolean')).toBe(false); + + expect(instance.config.get()).toMatchObject({ + id: null, + name: 'Ben', + stringValue: 'Hi there again', + boolean: false, + }); + + dom.window.document.querySelector('#testElement').setAttribute('data-id', '456'); + dom.window.document.querySelector('#testElement').setAttribute('data-string-value', 'Changed'); + dom.window.document.querySelector('#testElement').removeAttribute('data-boolean'); + + // Refresh config + instance.config.refresh(); + + expect(instance.config.get('id')).toBe(456); + expect(instance.config.get('name')).toBe('Ben'); + expect(instance.config.get('stringValue')).toBe('Changed'); + expect(instance.config.get('boolean')).toBeNull(); + + expect(instance.config.get()).toMatchObject({ + id: 456, + name: 'Ben', + stringValue: 'Changed', + boolean: null, + }); + + done(); + } catch (error) { + done(error); + } + } + ); + }); + + it('can set config values at runtime', function (done) { + FakeDom + .new() + .addCss([ + 'modules/system/assets/css/snowboard.extras.css', + ]) + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.extras.js', + 'tests/js/fixtures/dataConfig/DataConfigFixture.js', + ]) + .render( + `
` + ) + .then( + (dom) => { + const instance = dom.window.Snowboard.dataConfigFixture( + dom.window.document.querySelector('#testElement') + ); + + try { + expect(instance.config.get('name')).toBe('Ben'); + // Set config + instance.config.set('name', 'Luke'); + expect(instance.config.get('name')).toBe('Luke'); + // Refresh config + instance.config.refresh(); + expect(instance.config.get('name')).toBe('Ben'); + done(); + } catch (error) { + done(error); + } + } + ); + }); + + it('can set config values at runtime that persist through a reset', function (done) { + FakeDom + .new() + .addCss([ + 'modules/system/assets/css/snowboard.extras.css', + ]) + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'modules/system/assets/js/snowboard/build/snowboard.extras.js', + 'tests/js/fixtures/dataConfig/DataConfigFixture.js', + ]) + .render( + `
` + ) + .then( + (dom) => { + const instance = dom.window.Snowboard.dataConfigFixture( + dom.window.document.querySelector('#testElement') + ); + + try { + expect(instance.config.get('name')).toBe('Ben'); + // Set config + instance.config.set('name', 'Luke', true); + expect(instance.config.get('name')).toBe('Luke'); + // Refresh config + instance.config.refresh(); + expect(instance.config.get('name')).toBe('Luke'); + done(); + } catch (error) { + done(error); + } + } + ); + }); +}); diff --git a/modules/system/tests/js/cases/snowboard/main/PluginLoader.test.js b/modules/system/tests/js/cases/snowboard/main/PluginLoader.test.js new file mode 100644 index 0000000000..4e7b13e2dd --- /dev/null +++ b/modules/system/tests/js/cases/snowboard/main/PluginLoader.test.js @@ -0,0 +1,37 @@ +import FakeDom from '../../../helpers/FakeDom'; + +describe('PluginLoader class', function () { + it('can mock plugin methods', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js' + ]) + .render() + .then( + (dom) => { + dom.window.Snowboard.getPlugin('sanitizer').mock('sanitize', () => { + return 'all good'; + }); + + expect( + dom.window.Snowboard.sanitizer().sanitize('

') + ).toEqual('all good'); + + // Test unmock + dom.window.Snowboard.getPlugin('sanitizer').unmock('sanitize'); + + expect( + dom.window.Snowboard.sanitizer().sanitize('

') + ).toEqual('

'); + + done(); + }, + (error) => { + done(error); + } + ); + }); +}); diff --git a/modules/system/tests/js/cases/snowboard/main/Snowboard.test.js b/modules/system/tests/js/cases/snowboard/main/Snowboard.test.js new file mode 100644 index 0000000000..9f63ae2e20 --- /dev/null +++ b/modules/system/tests/js/cases/snowboard/main/Snowboard.test.js @@ -0,0 +1,383 @@ +import FakeDom from '../../../helpers/FakeDom'; + +describe('Snowboard framework', function () { + it('initialises correctly', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + try { + expect(dom.window.Snowboard).toBeDefined(); + expect(dom.window.Snowboard.addPlugin).toBeDefined(); + expect(dom.window.Snowboard.addPlugin).toEqual(expect.any(Function)); + + // Check PluginBase and Singleton abstracts exist + expect(dom.window.Snowboard.PluginBase).toBeDefined(); + expect(dom.window.Snowboard.Singleton).toBeDefined(); + + // Check in-built plugins + expect(dom.window.Snowboard.getPluginNames()).toEqual( + expect.arrayContaining(['jsonparser', 'sanitizer']) + ); + expect(dom.window.Snowboard.getPlugin('jsonparser').isFunction()).toEqual(false); + expect(dom.window.Snowboard.getPlugin('jsonparser').isSingleton()).toEqual(true); + expect(dom.window.Snowboard.getPlugin('sanitizer').isFunction()).toEqual(false); + expect(dom.window.Snowboard.getPlugin('sanitizer').isSingleton()).toEqual(true); + + done(); + } catch (error) { + done(error); + } + }, + (error) => { + throw error; + } + ); + }); + + it('can add and remove a plugin', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestPlugin.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + try { + // Check plugin caller + expect(Snowboard.hasPlugin('test')).toBe(true); + expect(Snowboard.getPluginNames()).toEqual( + expect.arrayContaining(['jsonparser', 'sanitizer', 'test']) + ); + expect(Snowboard.test).toEqual(expect.any(Function)); + + const instance = Snowboard.test(); + + // Check plugin injected methods + expect(instance.snowboard).toBe(Snowboard); + expect(instance.destructor).toEqual(expect.any(Function)); + + // Check plugin method + expect(instance.testMethod).toBeDefined(); + expect(instance.testMethod).toEqual(expect.any(Function)); + expect(instance.testMethod()).toEqual('Tested'); + + // Check multiple instances + const instanceOne = Snowboard.test(); + instanceOne.changed = true; + const instanceTwo = Snowboard.test(); + expect(instanceOne).not.toEqual(instanceTwo); + const factory = Snowboard.getPlugin('test'); + expect(factory.getInstances()).toEqual([instance, instanceOne, instanceTwo]); + + // Remove plugin + Snowboard.removePlugin('test'); + expect(Snowboard.hasPlugin('test')).toEqual(false); + expect(dom.window.Snowboard.getPluginNames()).toEqual( + expect.arrayContaining(['jsonparser', 'sanitizer']) + ); + expect(Snowboard.test).not.toBeDefined(); + + done(); + } catch (error) { + done(error); + } + }, + (error) => { + throw error; + } + ); + }); + + it('can add and remove a singleton', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestSingleton.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + try { + // Check plugin caller + expect(Snowboard.hasPlugin('test')).toBe(true); + expect(Snowboard.getPluginNames()).toEqual( + expect.arrayContaining(['jsonparser', 'sanitizer', 'test']) + ); + expect(Snowboard.test).toEqual(expect.any(Function)); + + const instance = Snowboard.test(); + + // Check plugin injected methods + expect(instance.snowboard).toBe(Snowboard); + expect(instance.destructor).toEqual(expect.any(Function)); + + // Check plugin method + expect(instance.testMethod).toBeDefined(); + expect(instance.testMethod).toEqual(expect.any(Function)); + expect(instance.testMethod()).toEqual('Tested'); + + // Check multiple instances (these should all be the same as this instance is a singleton) + const instanceOne = Snowboard.test(); + instanceOne.changed = true; + const instanceTwo = Snowboard.test(); + expect(instanceOne).toEqual(instanceTwo); + const factory = Snowboard.getPlugin('test'); + expect(factory.getInstances()).toEqual([instance]); + + // Remove plugin + Snowboard.removePlugin('test'); + expect(Snowboard.hasPlugin('test')).toEqual(false); + expect(dom.window.Snowboard.getPluginNames()).toEqual( + expect.arrayContaining([ 'jsonparser', 'sanitizer']) + ); + expect(Snowboard.test).not.toBeDefined(); + + done(); + } catch (error) { + done(error); + } + }, + (error) => { + throw error; + } + ); + }); + + it('can listen and call global events', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestListener.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + try { + expect(Snowboard.listensToEvent('eventOne')).toEqual(['test']); + expect(Snowboard.listensToEvent('eventTwo')).toEqual(['test']); + expect(Snowboard.listensToEvent('eventThree')).toEqual([]); + + // Call global event one + const testClass = Snowboard.test(); + Snowboard.globalEvent('eventOne', 42); + expect(testClass.eventResult).toEqual('Event called with arg 42'); + + // Call global event two - should fail as the test plugin doesn't have that method + expect(() => { + Snowboard.globalEvent('eventTwo'); + }).toThrow('Missing "notExists" method in "test" plugin'); + + // Call global event three - nothing should happen + expect(() => { + Snowboard.globalEvent('eventThree'); + }).not.toThrow(); + + done(); + } catch (error) { + done(error); + } + }, + (error) => { + throw error; + } + ); + }); + + it('can listen and call global promise events', function (done) { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestPromiseListener.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + try { + expect(Snowboard.listensToEvent('promiseOne')).toEqual(['test']); + expect(Snowboard.listensToEvent('promiseTwo')).toEqual(['test']); + expect(Snowboard.listensToEvent('promiseThree')).toEqual([]); + + // Call global event one + const testClass = Snowboard.test(); + Snowboard.globalPromiseEvent('promiseOne', 'promise').then( + () => { + expect(testClass.eventResult).toEqual('Event called with arg promise'); + + // Call global event two - it should still work, even though it doesn't return a promise + Snowboard.globalPromiseEvent('promiseTwo', 'promise 2').then( + () => { + expect(testClass.eventResult).toEqual('Promise two called with arg promise 2'); + + // Call global event three - it should still work + Snowboard.globalPromiseEvent('promiseThree', 'promise 3').then( + () => { + done(); + }, + (error) => { + done(error); + } + ); + }, + (error) => { + done(error); + } + ); + }, + (error) => { + done(error); + } + ); + } catch (error) { + done(error); + } + }, + (error) => { + throw error; + } + ); + }); + + it('will throw an error when using a plugin that has unfulfilled dependencies', function () { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestHasDependencies.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + expect(() => { + Snowboard.testHasDependencies(); + }).toThrow('The "testhasdependencies" plugin requires the following plugins: testdependencyone, testdependencytwo'); + }, + (error) => { + throw error; + } + ); + }); + + it('will throw an error when using a plugin that has some unfulfilled dependencies', function () { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestHasDependencies.js', + 'tests/js/fixtures/framework/TestDependencyOne.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + expect(() => { + Snowboard.testHasDependencies(); + }).toThrow('The "testhasdependencies" plugin requires the following plugins: testdependencytwo'); + }, + (error) => { + throw error; + } + ); + }); + + it('will not throw an error when using a plugin that has fulfilled dependencies', function () { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestDependencyTwo.js', + 'tests/js/fixtures/framework/TestHasDependencies.js', + 'tests/js/fixtures/framework/TestDependencyOne.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + expect(() => { + Snowboard.testHasDependencies(); + }).not.toThrow(); + + expect(Snowboard.testHasDependencies().testMethod()).toEqual('Tested'); + }, + (error) => { + throw error; + } + ); + }); + + it('will not initialise a singleton that has unfulfilled dependencies', function () { + FakeDom + .new() + .addScript([ + 'modules/system/assets/js/build/manifest.js', + 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', + 'modules/system/assets/js/snowboard/build/snowboard.base.js', + 'tests/js/fixtures/framework/TestSingletonWithDependency.js', + ]) + .render() + .then( + (dom) => { + // Run assertions + const Snowboard = dom.window.Snowboard; + + expect(() => { + Snowboard.testSingleton(); + }).toThrow('The "testsingleton" plugin requires the following plugins: testdependencyone'); + + expect(Snowboard.listensToEvent('ready')).not.toContain('testsingleton'); + + expect(() => { + Snowboard.globalEvent('ready'); + }).not.toThrow(); + }, + (error) => { + throw error; + } + ); + }); +}); diff --git a/modules/system/tests/js/fixtures/dataConfig/DataConfigFixture.js b/modules/system/tests/js/fixtures/dataConfig/DataConfigFixture.js new file mode 100644 index 0000000000..0e73731ce3 --- /dev/null +++ b/modules/system/tests/js/fixtures/dataConfig/DataConfigFixture.js @@ -0,0 +1,26 @@ +/* globals window */ + +((Snowboard) => { + class DataConfigFixture extends Snowboard.PluginBase { + construct(element) { + this.element = element; + this.config = this.snowboard.dataConfig(this, element); + } + + dependencies() { + return ['dataConfig']; + } + + defaults() { + return { + id: null, + name: null, + stringValue: null, + boolean: null, + base64: null, + }; + } + } + + Snowboard.addPlugin('dataConfigFixture', DataConfigFixture); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestDependencyOne.js b/modules/system/tests/js/fixtures/framework/TestDependencyOne.js new file mode 100644 index 0000000000..b4dc4814a9 --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestDependencyOne.js @@ -0,0 +1,11 @@ +/* globals window */ + +((Snowboard) => { + class TestDependencyOne extends Snowboard.Singleton { + testMethod() { + return 'Tested'; + } + } + + Snowboard.addPlugin('testDependencyOne', TestDependencyOne); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestDependencyTwo.js b/modules/system/tests/js/fixtures/framework/TestDependencyTwo.js new file mode 100644 index 0000000000..3af681b782 --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestDependencyTwo.js @@ -0,0 +1,11 @@ +/* globals window */ + +((Snowboard) => { + class TestDependencyTwo extends Snowboard.Singleton { + testMethod() { + return 'Tested'; + } + } + + Snowboard.addPlugin('testDependencyTwo', TestDependencyTwo); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestHasDependencies.js b/modules/system/tests/js/fixtures/framework/TestHasDependencies.js new file mode 100644 index 0000000000..18f7859560 --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestHasDependencies.js @@ -0,0 +1,15 @@ +/* globals window */ + +((Snowboard) => { + class TestHasDependencies extends Snowboard.Singleton { + dependencies() { + return ['testDependencyOne', 'testDependencyTwo']; + } + + testMethod() { + return 'Tested'; + } + } + + Snowboard.addPlugin('testHasDependencies', TestHasDependencies); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestListener.js b/modules/system/tests/js/fixtures/framework/TestListener.js new file mode 100644 index 0000000000..5bd4f6bffb --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestListener.js @@ -0,0 +1,18 @@ +/* globals window */ + +((Snowboard) => { + class TestListener extends Snowboard.Singleton { + listens() { + return { + eventOne: 'eventOne', + eventTwo: 'notExists' + }; + } + + eventOne(arg) { + this.eventResult = 'Event called with arg ' + arg; + } + } + + Snowboard.addPlugin('test', TestListener); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestPlugin.js b/modules/system/tests/js/fixtures/framework/TestPlugin.js new file mode 100644 index 0000000000..568d6a6b93 --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestPlugin.js @@ -0,0 +1,11 @@ +/* globals window */ + +((Snowboard) => { + class TestPlugin extends Snowboard.PluginBase { + testMethod() { + return 'Tested'; + } + } + + Snowboard.addPlugin('test', TestPlugin); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestPromiseListener.js b/modules/system/tests/js/fixtures/framework/TestPromiseListener.js new file mode 100644 index 0000000000..1126ed93ef --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestPromiseListener.js @@ -0,0 +1,28 @@ +/* globals window */ + +((Snowboard) => { + class TestPromiseListener extends Snowboard.Singleton { + listens() { + return { + promiseOne: 'promiseOne', + promiseTwo: 'promiseTwo' + }; + } + + promiseOne(arg) { + return new Promise((resolve) => { + window.setTimeout(() => { + this.eventResult = 'Event called with arg ' + arg; + resolve(); + }, 500); + }); + } + + promiseTwo(arg) { + this.eventResult = 'Promise two called with arg ' + arg; + return true; + } + } + + Snowboard.addPlugin('test', TestPromiseListener); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestSingleton.js b/modules/system/tests/js/fixtures/framework/TestSingleton.js new file mode 100644 index 0000000000..45989248bf --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestSingleton.js @@ -0,0 +1,11 @@ +/* globals window */ + +((Snowboard) => { + class TestSingleton extends Snowboard.Singleton { + testMethod() { + return 'Tested'; + } + } + + Snowboard.addPlugin('test', TestSingleton); +})(window.Snowboard); diff --git a/modules/system/tests/js/fixtures/framework/TestSingletonWithDependency.js b/modules/system/tests/js/fixtures/framework/TestSingletonWithDependency.js new file mode 100644 index 0000000000..1aba7718e0 --- /dev/null +++ b/modules/system/tests/js/fixtures/framework/TestSingletonWithDependency.js @@ -0,0 +1,25 @@ +/* globals window */ + +((Snowboard) => { + class TestSingletonWithDependency extends Snowboard.Singleton { + dependencies() { + return ['testDependencyOne']; + } + + listens() { + return { + ready: 'ready', + }; + } + + ready() { + return 'Ready'; + } + + testMethod() { + return 'Tested'; + } + } + + Snowboard.addPlugin('testSingleton', TestSingletonWithDependency); +})(window.Snowboard); diff --git a/modules/system/tests/js/helpers/FakeDom.js b/modules/system/tests/js/helpers/FakeDom.js new file mode 100644 index 0000000000..6ddf61e9fd --- /dev/null +++ b/modules/system/tests/js/helpers/FakeDom.js @@ -0,0 +1,189 @@ +/* globals __dirname, URL */ + +import { JSDOM } from 'jsdom' +import path from 'path' + +export default class FakeDom +{ + constructor(content, options) + { + if (options === undefined) { + options = {}; + } + + // Header settings + this.url = options.url || `file://${path.resolve(__dirname, '../../')}`; + this.referer = options.referer; + this.contentType = options.contentType || 'text/html'; + + // Content settings + this.headStart = options.headStart || 'Fake document'; + this.headEnd = options.headEnd || ''; + this.bodyStart = options.bodyStart || ''; + this.content = content || ''; + this.bodyEnd = options.bodyEnd || ''; + this.foot = options.foot || ''; + + // Callback settings + this.beforeParse = (typeof options.beforeParse === 'function') + ? options.beforeParse + : undefined; + + // Assets + this.css = []; + this.scripts = []; + this.inline = []; + } + + static new(content, options) + { + return new FakeDom(content, options); + } + + setContent(content) + { + this.content = content; + return this; + } + + addScript(script, id) + { + if (Array.isArray(script)) { + script.forEach((item) => { + this.addScript(item); + }); + + return this; + } + + let url = new URL(script, this.url); + let base = new URL(this.url); + + if (url.host === base.host) { + this.scripts.push({ + url: `${url.pathname}`, + id: id || this.generateId(), + }); + } else { + this.scripts.push({ + url, + id: id || this.generateId(), + }); + } + + return this; + } + + addCss(css, id) + { + if (Array.isArray(css)) { + css.forEach((item) => { + this.addCss(item) + }); + + return this; + } + + let url = new URL(css, this.url); + let base = new URL(this.url); + + if (url.host === base.host) { + this.css.push({ + url: `${url.pathname}`, + id: id || this.generateId(), + }); + } else { + this.css.push({ + url, + id: id || this.generateId(), + }); + } + + return this; + } + + addInlineScript(script, id) + { + this.inline.push({ + script, + id: id || this.generateId(), + element: null, + }); + + return this; + } + + generateId() + { + let id = 'script-'; + let chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'; + let charLength = chars.length; + + for (let i = 0; i < 10; i++) { + let currentChar = chars.substr(Math.floor(Math.random() * charLength), 1); + id = `${id}${currentChar}`; + } + + return id; + } + + render(content) + { + if (content) { + this.content = content; + } + return new Promise((resolve, reject) => { + try { + const dom = new JSDOM( + this._renderContent(), + { + url: this.url, + referrer: this.referer, + contentType: this.contentType, + includeNodeLocations: true, + runScripts: 'dangerously', + resources: 'usable', + pretendToBeVisual: true, + beforeParse: this.beforeParse, + } + ); + + dom.window.resolver = () => { + resolve(dom); + }; + } catch (e) { + reject(e); + } + }); + } + + _renderContent() + { + // Create content list + const content = [this.headStart]; + + // Embed CSS + this.css.forEach((css) => { + content.push(``); + }); + + content.push(this.headEnd, this.bodyStart, this.content); + + // Embed scripts + this.scripts.forEach((script) => { + content.push(``); + }); + this.inline.forEach((script) => { + content.push(``); + }); + + // Add resolver + content.push(``); + + // Add final content + content.push(this.bodyEnd); + content.push(this.foot); + + return content.join('\n'); + } +} diff --git a/modules/system/tests/js/jest.config.js b/modules/system/tests/js/jest.config.js new file mode 100644 index 0000000000..1363597d68 --- /dev/null +++ b/modules/system/tests/js/jest.config.js @@ -0,0 +1,194 @@ +/* + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/configuration + */ + +module.exports = { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + // bail: 0, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/private/var/folders/81/m6w95r0j7ms_10c47hdbz4gw0000gn/T/jest_dx", + + // Automatically clear mock calls, instances and results before every test + clearMocks: true, + + // Indicates whether the coverage information should be collected while executing the test + // collectCoverage: false, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + // coverageDirectory: undefined, + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + // coverageProvider: "babel", + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // "json", + // "text", + // "lcov", + // "clover" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: "50%", + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "jsx", + // "ts", + // "tsx", + // "json", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "failure-change", + + // A preset that is used as a base for Jest's configuration + // preset: undefined, + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state before every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state and implementation before every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // "" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + // testEnvironment: "jest-environment-node", + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + // testMatch: [ + // "**/__tests__/**/*.[jt]s?(x)", + // "**/?(*.)+(spec|test).[tj]s?(x)" + // ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: "jest-circus/runner", + + // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href + // testURL: "http://localhost", + + // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" + // timers: "real", + + // A map from regular expressions to paths to transformers + // transform: undefined, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +}; diff --git a/modules/system/tests/js/package.json b/modules/system/tests/js/package.json new file mode 100644 index 0000000000..650f38698f --- /dev/null +++ b/modules/system/tests/js/package.json @@ -0,0 +1,37 @@ +{ + "name": "@wintercms/tests", + "description": "Test cases for the Winter JavaScript framework", + "private": true, + "scripts": { + "test": "jest" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/wintercms/winter.git" + }, + "contributors": [ + { + "name": "Ben Thomson", + "email": "git@alfreido.com" + }, + { + "name": "Winter CMS Maintainers", + "url": "https://wintercms.com/" + } + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/wintercms/winter/issues" + }, + "homepage": "https://wintercms.com/", + "devDependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/register": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-module-resolver": "^4.1.0", + "jest": "^27.4.3", + "jsdom": "^18.1.1" + } +} From 07c7ef536e1b0c7f066b9c00ef6e1bb817c28bdd Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 05:41:58 +0100 Subject: [PATCH 03/22] Fixed js test pathing issues --- .../cases/snowboard/extras/DataConfig.test.js | 10 ++++----- .../js/cases/snowboard/main/Snowboard.test.js | 22 +++++++++---------- modules/system/tests/js/helpers/FakeDom.js | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js b/modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js index 339f0c09d3..7f6a642245 100644 --- a/modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js +++ b/modules/system/tests/js/cases/snowboard/extras/DataConfig.test.js @@ -14,7 +14,7 @@ describe('The Data Config extra functionality', function () { 'modules/system/assets/js/snowboard/build/snowboard.vendor.js', 'modules/system/assets/js/snowboard/build/snowboard.base.js', 'modules/system/assets/js/snowboard/build/snowboard.extras.js', - 'tests/js/fixtures/dataConfig/DataConfigFixture.js', + 'modules/system/tests/js/fixtures/dataConfig/DataConfigFixture.js', ]) .render( `
Date: Tue, 21 Jun 2022 05:42:42 +0100 Subject: [PATCH 04/22] Updated js test github action working dir --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c405164021..06f7ac39a5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,11 +24,11 @@ jobs: node-version: 12 - name: Install Node dependencies - working-directory: ./tests/js + working-directory: ./modules/system/tests/js run: npm install - name: Run tests - working-directory: ./tests/js + working-directory: ./modules/system/tests/js run: npm run test phpUnitTests: strategy: From 8e32b13b079f59e538d9583b5def2ea365657c43 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 05:47:28 +0100 Subject: [PATCH 05/22] Added nl to improve readability --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 06f7ac39a5..08c6c2fcb0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,6 +30,7 @@ jobs: - name: Run tests working-directory: ./modules/system/tests/js run: npm run test + phpUnitTests: strategy: max-parallel: 8 From b684ff6a2c06f4bbe44e74fda1c8f86192ac19b0 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 05:49:31 +0100 Subject: [PATCH 06/22] Code cleanup --- modules/backend/tests/widgets/FilterWidgetTest.php | 1 - modules/system/tests/bootstrap/app.php | 1 - 2 files changed, 2 deletions(-) diff --git a/modules/backend/tests/widgets/FilterWidgetTest.php b/modules/backend/tests/widgets/FilterWidgetTest.php index 3c35f23173..7848cd657d 100644 --- a/modules/backend/tests/widgets/FilterWidgetTest.php +++ b/modules/backend/tests/widgets/FilterWidgetTest.php @@ -8,7 +8,6 @@ use ApplicationException; use Backend\Models\User; - class FilterWidgetTest extends PluginTestCase { public function testRestrictedScopeWithUserWithNoPermissions() diff --git a/modules/system/tests/bootstrap/app.php b/modules/system/tests/bootstrap/app.php index 12f3215f09..9be7e9d5db 100644 --- a/modules/system/tests/bootstrap/app.php +++ b/modules/system/tests/bootstrap/app.php @@ -21,4 +21,3 @@ 'modules', 'plugins' ]); - From f0c561e7f07a2ffb39ce34bc25665b75ee2d9043 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 05:52:29 +0100 Subject: [PATCH 07/22] Removed dev autoload as no longer required --- composer.json | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 1b144268b7..a2d8dffb18 100644 --- a/composer.json +++ b/composer.json @@ -45,14 +45,6 @@ "php-parallel-lint/php-parallel-lint": "^1.0", "dms/phpunit-arraysubset-asserts": "^0.1.0|^0.2.1" }, - "autoload-dev": { - "classmap": [ - "tests/concerns/InteractsWithAuthentication.php", - "tests/fixtures/backend/models/UserFixture.php", - "tests/TestCase.php", - "tests/PluginTestCase.php" - ] - }, "scripts": { "post-create-project-cmd": [ "@php artisan key:generate", @@ -66,7 +58,7 @@ "phpunit --stop-on-failure" ], "lint": [ - "parallel-lint --exclude vendor --exclude storage --exclude tests/fixtures/plugins/testvendor/goto/Plugin.php ." + "parallel-lint --exclude vendor --exclude storage --exclude modules/system/tests/fixtures/plugins/testvendor/goto/Plugin.php ." ], "sniff": [ "phpcs --colors -nq --report=\"full\" --extensions=\"php\"" From 9d4c4e8124fa107ed655ebdf4b988c6654dfee2f Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 05:58:55 +0100 Subject: [PATCH 08/22] Switched linting command for composer alias --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 08c6c2fcb0..3b081f3c4a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -118,5 +118,5 @@ jobs: - name: Run Linting and Tests run: | - ./vendor/bin/parallel-lint --exclude vendor --exclude storage --exclude tests/fixtures/plugins/testvendor/goto/Plugin.php . + composer lint ./vendor/bin/phpunit From 5d6aa7691ede34362938408158c234826c019d69 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 06:06:04 +0100 Subject: [PATCH 09/22] Added snowboard tests to eslint ignore --- modules/system/.eslintignore | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/system/.eslintignore b/modules/system/.eslintignore index 74d302af37..64d9b745a2 100644 --- a/modules/system/.eslintignore +++ b/modules/system/.eslintignore @@ -9,3 +9,4 @@ assets/js !assets/js/snowboard assets/ui assets/vendor +tests/js From 1fd838b053761721249e3e34bf892c2e736c8fba Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Tue, 21 Jun 2022 06:08:22 +0100 Subject: [PATCH 10/22] Added backend module eslint ignore & comments --- modules/backend/.eslintignore | 3 +++ modules/system/.eslintignore | 2 ++ 2 files changed, 5 insertions(+) diff --git a/modules/backend/.eslintignore b/modules/backend/.eslintignore index e0d3f30269..b84f8627b8 100644 --- a/modules/backend/.eslintignore +++ b/modules/backend/.eslintignore @@ -12,3 +12,6 @@ controllers/**/*.js formwidgets/**/*.js reportwidgets/**/*.js widgets/**/*.js + +# Ignore test fixtures +tests diff --git a/modules/system/.eslintignore b/modules/system/.eslintignore index 64d9b745a2..b6b27f1dfc 100644 --- a/modules/system/.eslintignore +++ b/modules/system/.eslintignore @@ -9,4 +9,6 @@ assets/js !assets/js/snowboard assets/ui assets/vendor + +# Ignore test fixtures tests/js From 4ae39379c65b20cd0dd324e04b0a17924fb8e3da Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 00:32:33 -0600 Subject: [PATCH 11/22] Update modules/backend/tests/widgets/FormTest.php --- modules/backend/tests/widgets/FormTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/backend/tests/widgets/FormTest.php b/modules/backend/tests/widgets/FormTest.php index 67bae9fa45..618ec70ee7 100644 --- a/modules/backend/tests/widgets/FormTest.php +++ b/modules/backend/tests/widgets/FormTest.php @@ -30,7 +30,6 @@ public function staticMethodOptions() } } - class FormTest extends PluginTestCase { public function testRestrictedFieldWithUserWithNoPermissions() From a0f88762ab75ecfd45209d760134df26119707ed Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 00:33:57 -0600 Subject: [PATCH 12/22] Update modules/cms/tests/classes/AssetTest.php --- modules/cms/tests/classes/AssetTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/cms/tests/classes/AssetTest.php b/modules/cms/tests/classes/AssetTest.php index 8d754cb138..c7be820af1 100644 --- a/modules/cms/tests/classes/AssetTest.php +++ b/modules/cms/tests/classes/AssetTest.php @@ -11,7 +11,6 @@ class AssetTest extends TestCase public function testLoad() { $theme = Theme::load('test'); - // Valid direct path $this->assertStringContainsString( 'console.log(\'script1.js\');', From d0008d2bfb5dfc7ab50109fc7b53b7c5948ed2f8 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 00:34:29 -0600 Subject: [PATCH 13/22] Update modules/backend/tests/widgets/FormTest.php --- modules/backend/tests/widgets/FormTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/backend/tests/widgets/FormTest.php b/modules/backend/tests/widgets/FormTest.php index 618ec70ee7..048a374ef3 100644 --- a/modules/backend/tests/widgets/FormTest.php +++ b/modules/backend/tests/widgets/FormTest.php @@ -3,7 +3,7 @@ namespace Backend\Tests\Widgets { use System\Tests\Bootstrap\PluginTestCase; - use Illuminate\Database\Eloquent\Model; + use Winter\Storm\Database\Model; use Backend\Tests\Fixtures\Models\UserFixture; use Backend\Widgets\Form; From 0fe4d6d01e9ea32cc5d50b748c91de33021b944f Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 07:12:18 -0600 Subject: [PATCH 14/22] Remove unnecessary docblock comments --- modules/system/classes/FileManifest.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/modules/system/classes/FileManifest.php b/modules/system/classes/FileManifest.php index 1a0c11142b..5a0522b3c5 100644 --- a/modules/system/classes/FileManifest.php +++ b/modules/system/classes/FileManifest.php @@ -63,7 +63,6 @@ public function __construct(string $root = null, array $modules = null) /** * Sets the root folder. * - * @param string $root * @throws ApplicationException If the specified root does not exist. */ public function setRoot(string $root): static @@ -83,8 +82,6 @@ public function setRoot(string $root): static /** * Sets the modules. - * - * @param array $modules */ public function setModules(array $modules): static { @@ -97,8 +94,6 @@ public function setModules(array $modules): static /** * Gets a list of files and their corresponding hashsums. - * - * @return array */ public function getFiles(): array { @@ -125,8 +120,6 @@ public function getFiles(): array /** * Gets the checksum of a specific install. - * - * @return array */ public function getModuleChecksums(): array { @@ -153,9 +146,6 @@ public function getModuleChecksums(): array /** * Finds all files within the path. - * - * @param string $basePath The base path to look for files within. - * @return array */ protected function findFiles(string $basePath): array { @@ -173,9 +163,6 @@ protected function findFiles(string $basePath): array /** * Returns the filename without the root. - * - * @param string $file - * @return string */ protected function getFilename(string $file): string { @@ -184,9 +171,6 @@ protected function getFilename(string $file): string /** * Normalises the file contents, irrespective of OS. - * - * @param string $file - * @return string */ protected function normalizeFileContents(string $file): string { From 7ded8872dd65dd330473dc906933c402ffbb65d2 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 07:20:59 -0600 Subject: [PATCH 15/22] Cleanup docblocks --- modules/system/classes/SourceManifest.php | 33 ++++++++--------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/modules/system/classes/SourceManifest.php b/modules/system/classes/SourceManifest.php index 08acaf8926..677de5cf94 100644 --- a/modules/system/classes/SourceManifest.php +++ b/modules/system/classes/SourceManifest.php @@ -63,28 +63,18 @@ public function __construct(string $source = null, string $forks = null, bool $a /** * Sets the source manifest URL. - * - * @param string $source - * @return void */ - public function setSource($source) + public function setSource(string $source): void { - if (is_string($source)) { - $this->source = $source; - } + $this->source = $source; } /** * Sets the forked version manifest URL. - * - * @param string $forks - * @return void */ - public function setForksSource($forks) + public function setForksSource(string $forks): void { - if (is_string($forks)) { - $this->forksUrl = $forks; - } + $this->forksUrl = $forks; } /** @@ -180,9 +170,8 @@ public function loadForks(): static * * @param integer $build Build number. * @param FileManifest $manifest The file manifest to add as a build. - * @return void */ - public function addBuild($build, FileManifest $manifest) + public function addBuild($build, FileManifest $manifest): void { $parent = $this->determineParent($build); @@ -203,8 +192,6 @@ public function addBuild($build, FileManifest $manifest) /** * Gets all builds. - * - * @return array */ public function getBuilds(): array { @@ -311,7 +298,7 @@ public function getState(mixed $build): array * @param FileManifest $manifest The file manifest to compare against the source. * @param bool $detailed If true, the list of files modified, added and deleted will be included in the result. */ - public function compare(FileManifest $manifest, $detailed = false): array + public function compare(FileManifest $manifest, bool $detailed = false): array { $modules = $manifest->getModuleChecksums(); @@ -410,9 +397,8 @@ public function compare(FileManifest $manifest, $detailed = false): array * @param FileManifest $manifest The current build's file manifest. * @param FileManifest|string|integer $previous Either a previous manifest, or the previous build number as an int * or string, used to determine changes with this build. - * @return array */ - protected function processChanges(FileManifest $manifest, $previous = null): array + protected function processChanges(FileManifest $manifest, mixed $previous = null): array { // If no previous build has been provided, all files are added if (is_null($previous)) { @@ -459,7 +445,10 @@ protected function processChanges(FileManifest $manifest, $previous = null): arr return $changes; } - protected function determineParent(string $build) + /** + * Determine the parent of the provided build number + */ + protected function determineParent(string $build): ?array { $buildInt = $this->getVersionInt($build); From 64e4d4a01ff741cb98cbd1039769a858ddaeb3f1 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 07:42:05 -0600 Subject: [PATCH 16/22] Re-add README --- modules/system/tests/README.md | 110 +++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 modules/system/tests/README.md diff --git a/modules/system/tests/README.md b/modules/system/tests/README.md new file mode 100644 index 0000000000..6315253366 --- /dev/null +++ b/modules/system/tests/README.md @@ -0,0 +1,110 @@ +# Plugin testing + +Individual plugin test cases can be run by running either `artisan winter:test -p MyAuthor.MyPlugin` in the project root or `../../../vendor/bin/phpunit` in the plugin's base directory (ex. `plugins/acme/demo`). + +### Creating plugin tests + +Plugins can be tested by creating a file called `phpunit.xml` in the base directory with the following content, for example, in a file **/plugins/acme/blog/phpunit.xml**: + + + + + + ./tests + + + + + + + + + +Then a **tests/** directory can be created to contain the test classes. The file structure should mimic the base directory with classes having a `Test` suffix. Using a namespace for the class is also recommended. + +```php +namespace Acme\Blog\Tests\Models; + +use Acme\Blog\Models\Post; +use System\Tests\Bootstrap\PluginTestCase; + +class PostTest extends PluginTestCase +{ + public function testCreateFirstPost() + { + $post = Post::create(['title' => 'Hi!']); + $this->assertEquals(1, $post->id); + } +} +``` + +The test class should extend the base class `System\Tests\Boostrap\PluginTestCase` and this is a special class that will set up the Winter database stored in memory, as part of the `setUp` method. It will also refresh the plugin being tested, along with any of the defined dependencies in the plugin registration file. This is the equivalent of running the following before each test: + +```bash +php artisan winter:up +php artisan plugin:refresh Acme.Blog +[php artisan plugin:refresh , ...] +``` + +> **Note:** If your plugin uses [configuration files](../plugin/settings#file-configuration), then you will need to run `System\Classes\PluginManager::instance()->registerAll(true);` in the `setUp` method of your tests. Below is an example of a base test case class that should be used if you need to test your plugin working with other plugins instead of in isolation. + +```php +use System\Classes\PluginManager; +use System\Tests\Bootstrap\PluginTestCase; + +class BaseTestCase extends PluginTestCase +{ + public function setUp(): void + { + parent::setUp(); + + // Get the plugin manager + $pluginManager = PluginManager::instance(); + + // Register the plugins to make features like file configuration available + $pluginManager->registerAll(true); + + // Boot all the plugins to test with dependencies of this plugin + $pluginManager->bootAll(true); + } + + public function tearDown(): void + { + parent::tearDown(); + + // Get the plugin manager + $pluginManager = PluginManager::instance(); + + // Ensure that plugins are registered again for the next test + $pluginManager->unregisterAll(); + } +} +``` + +#### Changing database engine for plugins tests + +By default Winter CMS uses SQLite stored in memory for the plugin testing environment. If you want to override the default behavior you can override the `/config/database.php` file by creating `/config/testing/database.php`. In this case, variables from the latter file will be taken. + +## Winter core modules testing + +To perform unit testing on the core Winter modules run `artisan winter:test -m system -m backend -m cms`. + +### Unit tests + +Unit tests can be performed by running `vendor/bin/phpunit` in the root directory of your Winter CMS installation. + +### Functional tests + +Functional tests can be performed by installing the [Winter.Dusk](https://wintercms.com/plugin/winter-dusk) in your Winter CMS installation. The Winter.Dusk plugin is powered by Laravel Dusk, a comprehensive testing suite for the Laravel framework that is designed to test interactions with a fully operational Winter CMS instance through a virtual browser. + +For information on installing and setting up your Winter CMS install to run functional tests, please review the [README](https://github.com/wintercms/wn-dusk-plugin/blob/master/README.md) for the plugin. From 6d9fcbf7cfa006ed7f5cd59045b1b8ce3ae8e232 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 07:42:45 -0600 Subject: [PATCH 17/22] Update modules/cms/tests/classes/PageTest.php --- modules/cms/tests/classes/PageTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms/tests/classes/PageTest.php b/modules/cms/tests/classes/PageTest.php index 796db70ad9..e2cbeebd4b 100644 --- a/modules/cms/tests/classes/PageTest.php +++ b/modules/cms/tests/classes/PageTest.php @@ -14,7 +14,7 @@ public function testResolveMenuItem() $theme = Theme::load('test'); $controller = new Controller; - $item = (object)[ + $item = (object) [ 'type' => 'cms-page', 'reference' => 'index', ]; From 392610a77ceffad6cf3dc7bdac9f75d75216b3ce Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 21 Jun 2022 07:42:53 -0600 Subject: [PATCH 18/22] Update modules/system/tests/classes/ImageResizerTest.php --- modules/system/tests/classes/ImageResizerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/system/tests/classes/ImageResizerTest.php b/modules/system/tests/classes/ImageResizerTest.php index b3bb181260..eafbefd3fd 100644 --- a/modules/system/tests/classes/ImageResizerTest.php +++ b/modules/system/tests/classes/ImageResizerTest.php @@ -89,7 +89,6 @@ public function testConfiguration() ], $imageResizer->getConfig()); // Resize with an customised defaults -// $this->markTestSkipped('@TODO: Something is going funky with serialized closures in PHP 8.0 / Laravel 9.x'); Event::listen('system.resizer.getDefaultOptions', function (&$options) { $options = array_merge($options, [ 'mode' => 'fit', From fba6446d3f8a0f4f9920e605d283de02803df68b Mon Sep 17 00:00:00 2001 From: Jack Wilkinson <31214002+jaxwilko@users.noreply.github.com> Date: Tue, 21 Jun 2022 22:55:05 +0100 Subject: [PATCH 19/22] [WIP] Split Test - 1.2 - PluginManager lower case internal IDs (#583) This modifies the plugin manager to internally treat plugin identifiers as lower case strings, only transforming them to their normalized versions when requested by methods like getPlugins() & getAllPlugins(). The idea behind this is that it provides a much simpler way to internally handle checking, especially for plugin replacement where casing could cause issues. Replaces #576. Fixes #575. --- modules/system/classes/PluginManager.php | 79 ++++++++---- .../tests/classes/PluginManagerTest.php | 112 ++++++++++++++++-- .../winter/replacenotinstalled/Plugin.php | 20 ++++ .../replacenotinstalled/updates/version.yaml | 2 + 4 files changed, 180 insertions(+), 33 deletions(-) create mode 100644 modules/system/tests/fixtures/plugins/winter/replacenotinstalled/Plugin.php create mode 100644 modules/system/tests/fixtures/plugins/winter/replacenotinstalled/updates/version.yaml diff --git a/modules/system/classes/PluginManager.php b/modules/system/classes/PluginManager.php index 04fed249d8..73f2c75146 100644 --- a/modules/system/classes/PluginManager.php +++ b/modules/system/classes/PluginManager.php @@ -136,7 +136,7 @@ public function loadPlugins(): array // Sort all the plugins by number of dependencies $this->sortByDependencies(); - return $this->plugins; + return $this->getAllPlugins(); } /** @@ -173,14 +173,15 @@ public function loadPlugin(string $namespace, string $path): ?PluginBase } $classId = $this->getIdentifier($pluginObj); + $lowerClassId = strtolower($classId); - $this->plugins[$classId] = $pluginObj; - $this->normalizedMap[strtolower($classId)] = $classId; + $this->plugins[$lowerClassId] = $pluginObj; + $this->normalizedMap[$lowerClassId] = $classId; $replaces = $pluginObj->getReplaces(); if ($replaces) { foreach ($replaces as $replace) { - $this->replacementMap[$replace] = $classId; + $this->replacementMap[strtolower($replace)] = $lowerClassId; } } @@ -226,7 +227,7 @@ public function loadPluginFlags(): void ]; }); - list($this->pluginFlag, $this->replacementMap, $this->activeReplacementMap) = $data; + list($this->pluginFlags, $this->replacementMap, $this->activeReplacementMap) = $data; } /** @@ -409,7 +410,14 @@ public function exists(PluginBase|string $plugin): bool */ public function getPlugins(): array { - return array_diff_key($this->plugins, $this->pluginFlags); + $plugins = array_diff_key($this->plugins, $this->pluginFlags); + $keys = []; + + foreach ($plugins as $code => $plugin) { + $keys[] = $this->normalizedMap[$code]; + } + + return array_combine($keys, $plugins); } /** @@ -419,7 +427,13 @@ public function getPlugins(): array */ public function getAllPlugins(): array { - return $this->plugins; + $plugins = []; + + foreach ($this->plugins as $code => $plugin) { + $plugins[$this->normalizedMap[$code]] = $plugin; + } + + return $plugins; } /** @@ -427,7 +441,7 @@ public function getAllPlugins(): array */ public function findByNamespace(string $namespace): ?PluginBase { - $identifier = $this->getIdentifier($namespace); + $identifier = $this->getIdentifier($namespace, true); return $this->plugins[$identifier] ?? null; } @@ -441,12 +455,10 @@ public function findByIdentifier(PluginBase|string $identifier, bool $ignoreRepl return $identifier; } - if (!$ignoreReplacements && is_string($identifier) && isset($this->replacementMap[$identifier])) { - $identifier = $this->replacementMap[$identifier]; - } + $identifier = $this->getNormalizedIdentifier($identifier, true); - if (!isset($this->plugins[$identifier])) { - $identifier = $this->getNormalizedIdentifier($identifier); + if (!$ignoreReplacements && isset($this->replacementMap[$identifier])) { + $identifier = $this->replacementMap[$identifier]; } return $this->plugins[$identifier] ?? null; @@ -457,7 +469,7 @@ public function findByIdentifier(PluginBase|string $identifier, bool $ignoreRepl */ public function hasPlugin(PluginBase|string $plugin): bool { - $normalized = $this->getNormalizedIdentifier($plugin); + $normalized = $this->getNormalizedIdentifier($plugin, true); return isset($this->plugins[$normalized]) || isset($this->replacementMap[$normalized]); } @@ -518,7 +530,7 @@ public function getVendorAndPluginNames(): array * Resolves a plugin identifier (Author.Plugin) from a plugin class name * (Author\Plugin) or PluginBase instance. */ - public function getIdentifier(PluginBase|string $plugin): string + public function getIdentifier(PluginBase|string $plugin, bool $lower = false): string { $namespace = Str::normalizeClassName($plugin); if (strpos($namespace, '\\') === null) { @@ -529,7 +541,7 @@ public function getIdentifier(PluginBase|string $plugin): string $slice = array_slice($parts, 1, 2); $namespace = implode('.', $slice); - return $namespace; + return $lower ? strtolower($namespace) : $namespace; } /** @@ -565,9 +577,10 @@ public function normalizeIdentifier(string $code): string * Returns the normalized identifier (i.e. Winter.Blog) from the provided * string or PluginBase instance. */ - public function getNormalizedIdentifier(PluginBase|string $plugin): string + public function getNormalizedIdentifier(PluginBase|string $plugin, bool $lower = false): string { - return $this->normalizeIdentifier($this->getIdentifier($plugin)); + $identifier = $this->normalizeIdentifier($this->getIdentifier($plugin)); + return $lower ? strtolower($identifier) : $identifier; } /** @@ -600,7 +613,7 @@ public function getRegistrationMethodValues(string $methodName): array public function getPluginFlags(PluginBase|string $plugin): array { - $code = $this->getNormalizedIdentifier($plugin); + $code = $this->getNormalizedIdentifier($plugin, true); return $this->pluginFlags[$code] ?? []; } @@ -609,7 +622,7 @@ public function getPluginFlags(PluginBase|string $plugin): array */ protected function flagPlugin(PluginBase|string $plugin, string $flag): void { - $code = $this->getNormalizedIdentifier($plugin); + $code = $this->getNormalizedIdentifier($plugin, true); $this->pluginFlags[$code][$flag] = true; } @@ -618,7 +631,7 @@ protected function flagPlugin(PluginBase|string $plugin, string $flag): void */ protected function unflagPlugin(PluginBase|string $plugin, string $flag): void { - $code = $this->getNormalizedIdentifier($plugin); + $code = $this->getNormalizedIdentifier($plugin, true); unset($this->pluginFlags[$code][$flag]); } @@ -652,7 +665,7 @@ protected function loadDisabled(): void */ public function isDisabled(PluginBase|string $plugin): bool { - $code = $this->getNormalizedIdentifier($plugin); + $code = $this->getNormalizedIdentifier($plugin, true); // @TODO: Limit this to only disabled flags if we add more than disabled flags return !empty($this->pluginFlags[$code]); @@ -671,9 +684,18 @@ public function getReplacementMap(): array */ public function getActiveReplacementMap(PluginBase|string $plugin = null): array|string|null { - return $plugin - ? $this->activeReplacementMap[$this->getNormalizedIdentifier($plugin)] ?? null - : $this->activeReplacementMap; + if ($plugin) { + return $this->normalizedMap[ + $this->activeReplacementMap[$this->getNormalizedIdentifier($plugin, true)] ?? null + ] ?? null; + } + + $map = []; + foreach ($this->activeReplacementMap as $key => $value) { + $map[$this->normalizedMap[$key]] = $this->normalizedMap[$value]; + } + + return $map; } /** @@ -694,7 +716,12 @@ protected function detectPluginReplacements(): void // Only allow one of the replaced plugin or the replacing plugin to exist // at once depending on whether the version constraints are met or not - if ($this->plugins[$replacement]->canReplacePlugin($target, $this->plugins[$target]->getPluginVersion())) { + if ( + $this->plugins[$replacement]->canReplacePlugin( + $this->normalizeIdentifier($target), + $this->plugins[$target]->getPluginVersion() + ) + ) { // Set the plugin flags to disable the target plugin $this->flagPlugin($target, static::DISABLED_REPLACED); $this->unflagPlugin($replacement, static::DISABLED_REPLACEMENT_FAILED); diff --git a/modules/system/tests/classes/PluginManagerTest.php b/modules/system/tests/classes/PluginManagerTest.php index ac5fb41a24..426cfb14ea 100644 --- a/modules/system/tests/classes/PluginManagerTest.php +++ b/modules/system/tests/classes/PluginManagerTest.php @@ -2,17 +2,20 @@ namespace System\Tests\Classes; -use Illuminate\Support\Facades\Artisan; use System\Tests\Bootstrap\TestCase; use System\Classes\PluginManager; use System\Classes\UpdateManager; use System\Classes\VersionManager; -use Cache; use ReflectionClass; + use Winter\Storm\Database\Model as ActiveRecord; class PluginManagerTest extends TestCase { + const INSTALLED_PLUGIN_COUNT = 13; + const ENABLED_PLUGIN_COUNT = 10; + const PLUGIN_NAMESPACE_COUNT = 14; + public $manager; protected $output; @@ -66,7 +69,6 @@ public function setUp() : void self::callProtectedMethod($manager, 'loadDisabled'); $manager->loadPlugins(); self::callProtectedMethod($manager, 'loadDependencies'); - self::callProtectedMethod($manager, 'detectPluginReplacements'); $this->manager = $manager; } @@ -128,7 +130,7 @@ public function testLoadPlugins() { $result = $this->manager->loadPlugins(); - $this->assertCount(12, $result); + $this->assertCount(static::INSTALLED_PLUGIN_COUNT, $result); $this->assertArrayHasKey('Winter.NoUpdates', $result); $this->assertArrayHasKey('Winter.Sample', $result); $this->assertArrayHasKey('Winter.Tester', $result); @@ -170,7 +172,7 @@ public function testGetPlugins() { $result = $this->manager->getPlugins(); - $this->assertCount(9, $result); + $this->assertCount(static::ENABLED_PLUGIN_COUNT, $result); $this->assertArrayHasKey('Winter.NoUpdates', $result); $this->assertArrayHasKey('Winter.Sample', $result); $this->assertArrayHasKey('Winter.Tester', $result); @@ -230,7 +232,7 @@ public function testGetPluginNamespaces() { $result = $this->manager->getPluginNamespaces(); - $this->assertCount(13, $result); + $this->assertCount(static::PLUGIN_NAMESPACE_COUNT, $result); $this->assertArrayHasKey('\winter\noupdates', $result); $this->assertArrayHasKey('\winter\sample', $result); $this->assertArrayHasKey('\winter\tester', $result); @@ -284,7 +286,7 @@ public function testPluginDetails() public function testUnregisterall() { $result = $this->manager->getPlugins(); - $this->assertCount(9, $result); + $this->assertCount(static::ENABLED_PLUGIN_COUNT, $result); $this->manager->unregisterAll(); $this->assertEmpty($this->manager->getPlugins()); @@ -353,6 +355,102 @@ public function testReplacement() $this->assertEquals('Winter.Replacement', $this->manager->findByIdentifier('Winter.Original')->getPluginIdentifier()); } + public function testHasPluginReplacement() + { + // check a replaced plugin + $this->assertTrue($this->manager->hasPlugin('Winter.Original')); + $this->assertTrue($this->manager->isDisabled('Winter.Original')); + // check a replacement plugin + $this->assertTrue($this->manager->hasPlugin('Winter.Replacement')); + $this->assertFalse($this->manager->isDisabled('Winter.Replacement')); + // check a plugin where the replacement is invalid + $this->assertTrue($this->manager->hasPlugin('Winter.InvalidReplacement')); + $this->assertTrue($this->manager->isDisabled('Winter.InvalidReplacement')); + // check a plugin replacing a plugin not found on disk + $this->assertTrue($this->manager->hasPlugin('Winter.ReplaceNotInstalled')); + $this->assertFalse($this->manager->isDisabled('Winter.ReplaceNotInstalled')); + // ensure searching for the alias of a replacement (plugin not installed) + $this->assertTrue($this->manager->hasPlugin('Winter.NotInstalled')); + + $this->assertInstanceOf(\Winter\Replacement\Plugin::class, $this->manager->findByIdentifier('Winter.Original')); + $this->assertInstanceOf(\Winter\Replacement\Plugin::class, $this->manager->findByIdentifier('Winter.Replacement')); + + // check getting a plugin via it's not installed original plugin identifier + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('Winter.NotInstalled')); + $this->assertNull($this->manager->findByIdentifier('Winter.NotInstalled', true)); + + // force getting the original plugin + $this->assertInstanceOf(\Winter\Original\Plugin::class, $this->manager->findByIdentifier('Winter.Original', true)); + } + + public function testHasPluginReplacementMixedCase() + { + // test checking casing of installed plugin (resolved via getNormalizedIdentifier()) + $this->assertTrue($this->manager->hasPlugin('Winter.ReplaceNotInstalled')); + $this->assertTrue($this->manager->hasPlugin('Winter.replaceNotInstalled')); + $this->assertTrue($this->manager->hasPlugin('Winter.replacenotInstalled')); + $this->assertTrue($this->manager->hasPlugin('winter.replacenotInstalled')); + $this->assertTrue($this->manager->hasPlugin('winter.replacenotinstalled')); + + // test checking casing of installed replaced plugin (resolved via getNormalizedIdentifier() & replacementMap) + $this->assertTrue($this->manager->hasPlugin('Winter.Original')); + $this->assertTrue($this->manager->hasPlugin('Winter.original')); + $this->assertTrue($this->manager->hasPlugin('winter.original')); + + // test checking casing of uninstalled plugin (resolved via strtolower() on replacement keys) + $this->assertTrue($this->manager->hasPlugin('Winter.NotInstalled')); + $this->assertTrue($this->manager->hasPlugin('Winter.notInstalled')); + $this->assertTrue($this->manager->hasPlugin('winter.notInstalled')); + $this->assertTrue($this->manager->hasPlugin('Winter.notinstalled')); + } + + public function testExistsReplacementMixedCase() + { + // test checking casing of installed plugin (resolved via getNormalizedIdentifier()) + $this->assertTrue($this->manager->exists('Winter.ReplaceNotInstalled')); + $this->assertTrue($this->manager->exists('Winter.replaceNotInstalled')); + $this->assertTrue($this->manager->exists('Winter.replacenotInstalled')); + $this->assertTrue($this->manager->exists('winter.replacenotInstalled')); + $this->assertTrue($this->manager->exists('winter.replacenotinstalled')); + + // test checking casing of installed replaced plugin (resolved via getNormalizedIdentifier() & replacementMap) + $this->assertFalse($this->manager->exists('Winter.Original')); + $this->assertFalse($this->manager->exists('Winter.original')); + $this->assertFalse($this->manager->exists('winter.original')); + + // test checking casing of uninstalled plugin (resolved via strtolower() on replacement keys) + $this->assertTrue($this->manager->exists('Winter.NotInstalled')); + $this->assertTrue($this->manager->exists('Winter.notInstalled')); + $this->assertTrue($this->manager->exists('winter.notInstalled')); + $this->assertTrue($this->manager->exists('Winter.notinstalled')); + } + + public function testFindByIdentifierReplacementMixedCase() + { + // test resolving plugin with mixed casing + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('Winter.ReplaceNotInstalled')); + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('Winter.replaceNotInstalled')); + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('Winter.replacenotInstalled')); + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('winter.replacenotInstalled')); + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('winter.replacenotinstalled')); + + // test resolving replacement plugin with mixed casing + $this->assertInstanceOf(\Winter\Replacement\Plugin::class, $this->manager->findByIdentifier('Winter.Original')); + $this->assertInstanceOf(\Winter\Replacement\Plugin::class, $this->manager->findByIdentifier('Winter.original')); + $this->assertInstanceOf(\Winter\Replacement\Plugin::class, $this->manager->findByIdentifier('winter.original')); + + // test resolving original plugin with mixed casing when ignoring replacements + $this->assertInstanceOf(\Winter\Original\Plugin::class, $this->manager->findByIdentifier('Winter.Original', true)); + $this->assertInstanceOf(\Winter\Original\Plugin::class, $this->manager->findByIdentifier('Winter.original', true)); + $this->assertInstanceOf(\Winter\Original\Plugin::class, $this->manager->findByIdentifier('winter.original', true)); + + // test resolving replacement plugin of uninstalled plugin with mixed casing + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('Winter.NotInstalled')); + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('Winter.notInstalled')); + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('winter.notInstalled')); + $this->assertInstanceOf(\Winter\ReplaceNotInstalled\Plugin::class, $this->manager->findByIdentifier('Winter.notinstalled')); + } + public function testGetReplacements() { $replacementPluginReplaces = $this->manager->findByIdentifier('Winter.Replacement')->getReplaces(); diff --git a/modules/system/tests/fixtures/plugins/winter/replacenotinstalled/Plugin.php b/modules/system/tests/fixtures/plugins/winter/replacenotinstalled/Plugin.php new file mode 100644 index 0000000000..963b667704 --- /dev/null +++ b/modules/system/tests/fixtures/plugins/winter/replacenotinstalled/Plugin.php @@ -0,0 +1,20 @@ + 'Winter Sample Plugin', + 'description' => 'Sample plugin used by unit tests.', + 'author' => 'Alexey Bobkov, Samuel Georges', + 'replaces' => [ + 'Winter.NotInstalled' => '>=1.0.3' + ] + ]; + } +} diff --git a/modules/system/tests/fixtures/plugins/winter/replacenotinstalled/updates/version.yaml b/modules/system/tests/fixtures/plugins/winter/replacenotinstalled/updates/version.yaml new file mode 100644 index 0000000000..979448dee1 --- /dev/null +++ b/modules/system/tests/fixtures/plugins/winter/replacenotinstalled/updates/version.yaml @@ -0,0 +1,2 @@ +1.0.0: Initial build +1.0.1: Updated plugin From 46a8921cea5815cf2fcca3e12b94d194ed0c0ffc Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 22 Jun 2022 01:12:11 +0100 Subject: [PATCH 20/22] Simplified getPlugins method key translation --- modules/system/classes/PluginManager.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/system/classes/PluginManager.php b/modules/system/classes/PluginManager.php index 73f2c75146..52a31d6e8e 100644 --- a/modules/system/classes/PluginManager.php +++ b/modules/system/classes/PluginManager.php @@ -411,13 +411,7 @@ public function exists(PluginBase|string $plugin): bool public function getPlugins(): array { $plugins = array_diff_key($this->plugins, $this->pluginFlags); - $keys = []; - - foreach ($plugins as $code => $plugin) { - $keys[] = $this->normalizedMap[$code]; - } - - return array_combine($keys, $plugins); + return array_combine(array_map(fn($code) => $this->normalizedMap[$code], array_keys($plugins)), $plugins); } /** From d1ff0945d6959097f453fbb736d447a6efa2d966 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 22 Jun 2022 01:13:24 +0100 Subject: [PATCH 21/22] Removed imports of global functions --- modules/cms/tests/classes/CmsObjectQueryTest.php | 2 -- modules/cms/tests/classes/CodeParserTest.php | 2 -- modules/cms/tests/classes/ComponentManagerTest.php | 1 - modules/cms/tests/classes/RouterTest.php | 1 - modules/cms/tests/classes/ThemeTest.php | 2 -- 5 files changed, 8 deletions(-) diff --git a/modules/cms/tests/classes/CmsObjectQueryTest.php b/modules/cms/tests/classes/CmsObjectQueryTest.php index 0132f3d3e0..3d0b3d8173 100644 --- a/modules/cms/tests/classes/CmsObjectQueryTest.php +++ b/modules/cms/tests/classes/CmsObjectQueryTest.php @@ -6,8 +6,6 @@ use Cms\Classes\Layout; use Cms\Classes\Page; use Winter\Storm\Halcyon\Model; -use function base_path; -use function sort; class CmsObjectQueryTest extends TestCase { diff --git a/modules/cms/tests/classes/CodeParserTest.php b/modules/cms/tests/classes/CodeParserTest.php index 83279f33fb..519d0dcc59 100644 --- a/modules/cms/tests/classes/CodeParserTest.php +++ b/modules/cms/tests/classes/CodeParserTest.php @@ -12,8 +12,6 @@ use Cms\Classes\Theme; use File; use ReflectionClass; -use function base_path; -use function storage_path; class CodeParserTest extends TestCase { diff --git a/modules/cms/tests/classes/ComponentManagerTest.php b/modules/cms/tests/classes/ComponentManagerTest.php index a9e825cccb..a28abbf646 100644 --- a/modules/cms/tests/classes/ComponentManagerTest.php +++ b/modules/cms/tests/classes/ComponentManagerTest.php @@ -9,7 +9,6 @@ use Cms\Classes\Layout; use Cms\Classes\Page; use Cms\Classes\Theme; -use function base_path; class ComponentManagerTest extends TestCase { diff --git a/modules/cms/tests/classes/RouterTest.php b/modules/cms/tests/classes/RouterTest.php index e28c5f00a7..0cb61343cb 100644 --- a/modules/cms/tests/classes/RouterTest.php +++ b/modules/cms/tests/classes/RouterTest.php @@ -6,7 +6,6 @@ use Cms\Classes\Router; use Cms\Classes\Theme; use ReflectionClass; -use function count; class RouterTest extends TestCase { diff --git a/modules/cms/tests/classes/ThemeTest.php b/modules/cms/tests/classes/ThemeTest.php index 7dc7d6dbd2..e5d5ab06cf 100644 --- a/modules/cms/tests/classes/ThemeTest.php +++ b/modules/cms/tests/classes/ThemeTest.php @@ -6,8 +6,6 @@ use Cms\Classes\Theme; use Config; use Event; -use function base_path; -use const PHP_OS_FAMILY; class ThemeTest extends TestCase { From 556c3dcf9f1581d8d937207d9f9684da556396d3 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 22 Jun 2022 01:25:31 +0100 Subject: [PATCH 22/22] Improved readability --- modules/system/classes/PluginManager.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/system/classes/PluginManager.php b/modules/system/classes/PluginManager.php index 52a31d6e8e..a613302385 100644 --- a/modules/system/classes/PluginManager.php +++ b/modules/system/classes/PluginManager.php @@ -410,8 +410,14 @@ public function exists(PluginBase|string $plugin): bool */ public function getPlugins(): array { - $plugins = array_diff_key($this->plugins, $this->pluginFlags); - return array_combine(array_map(fn($code) => $this->normalizedMap[$code], array_keys($plugins)), $plugins); + $activePlugins = array_diff_key($this->plugins, $this->pluginFlags); + return array_combine( + array_map( + fn($code) => $this->normalizedMap[$code], + array_keys($activePlugins) + ), + $activePlugins + ); } /**