diff --git a/.github/workflows/_run_super_scaffolding_tests.yml b/.github/workflows/_run_super_scaffolding_tests.yml index 715699ea7..ec89577ff 100644 --- a/.github/workflows/_run_super_scaffolding_tests.yml +++ b/.github/workflows/_run_super_scaffolding_tests.yml @@ -17,15 +17,30 @@ on: default: false jobs: - # NOTE: This is here just to make the workflow visualization layout better. - # Without it the layout is really bad and confusing. calculate_matrix: - name: 🤷 Fake Matrix + name: 🏗️ Generate Test List runs-on: ubuntu-latest + outputs: + tests: ${{ steps.generate-test-list.outputs.result }} steps: - - name: Do Nothing - run: echo "This is a useless step that just helps things look nicer..." - shell: bash + - name: Checkout Repo + uses: "actions/checkout@v4" + + - uses: actions/github-script@v7 + id: generate-test-list + name: Generate Test List + with: + script: | + const globber = await glob.create('test/system/super_scaffolding/**/setup.rb') + const tests = [] + for await (const file of globber.globGenerator()) { + console.log(file) + var fileParts = file.split("/") + var test_dir_name = fileParts[fileParts.length - 2]; + console.log("test_dir_name =", test_dir_name) + tests.push(test_dir_name) + } + return tests test: name: "🏗️" runs-on: ubuntu-latest @@ -33,8 +48,7 @@ jobs: strategy: fail-fast: false matrix: - # For super scaffolding tests we need to have exactly 5 runners. - ci_runners: ["TestSite, Project", "Project::Step, Insight", "Personality::Disposition, Personality::Observation", "TestFile, PartialTest", Webhook] + test: ${{ fromJson(needs.calculate_matrix.outputs.tests) }} services: postgres: image: postgres:11-alpine @@ -125,28 +139,17 @@ jobs: - run: yarn build:css working-directory: tmp/starter - # TODO: This might be a bad idea. Maybe we should just have spring in the Gemfile all the time. - - name: Allow adding of spring - run: bundle config unset deployment - working-directory: tmp/starter - - - name: Add spring - run: bundle add spring - working-directory: tmp/starter - - name: 'Setup Super Scaffolding System Test' - run: bundle exec test/bin/setup-super-scaffolding-system-test + run: bundle exec test/system/super_scaffolding/${{ matrix.test }}/setup.rb --allow-dirty-workspace working-directory: tmp/starter - env: - CIRCLE_NODE_INDEX: ${{ strategy.job-index }} - name: 'Run Super Scaffolding Test' - run: bin/rails test test/system/super_scaffolding/ + run: bin/rails test test/system/super_scaffolding/${{ matrix.test }}/ test/system/super_scaffolding/open_api_test.rb working-directory: tmp/starter - name: 'Run Super Scaffolding Webhook Test' run: bin/rails test test/controllers/webhooks/incoming/some_provider_webhooks_controller_test.rb - if: ${{ strategy.job-index == 5 }} + if: ${{ matrix.test == 'webhook' }} working-directory: tmp/starter - name: Upload Test Summary Logs diff --git a/test/bin/setup-super-scaffolding-system-test b/test/bin/setup-super-scaffolding-system-test deleted file mode 100755 index c50ec3965..000000000 --- a/test/bin/setup-super-scaffolding-system-test +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env bash - -# https://gist.github.com/vncsna/64825d5609c146e80de8b1fd623011ca -# Note we're not using `x` because it's noisy. If you want to use it for debugging, uncomment the line below. -set -euo pipefail -#set -x -# -export SPRING=true - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "0" ]; then - rails g super_scaffold TestSite Team name:text_field other_attribute:text_field url:text_field --navbar="ti-world" --sortable - rails g super_scaffold TestPage TestSite,Team name:text_field path:text_field - rails g super_scaffold:field TestSite membership_id:super_select{class_name=Membership} - - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i "" "s/raise .*/team\.memberships/g" app/models/test_site.rb - else - sed -i "s/raise .*/team\.memberships/g" app/models/test_site.rb - fi -else - echo "Skipping \`TestSite\` and \`TestPage\` on this CI node." -fi - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "0" ]; then - rails g super_scaffold Project Team name:text_field description:trix_editor --navbar="ti-layout" - rails g super_scaffold Projects::Deliverable Project,Team name:text_field description:trix_editor - - # Setup for has-many-through test. - rails g super_scaffold Projects::Tag Team name:text_field --navbar="ti-tag" - - rails g super_scaffold:join_model Projects::AppliedTag project_id{class_name=Project} tag_id{class_name=Projects::Tag} - rails g super_scaffold:field Project tag_ids:super_select{class_name=Projects::Tag} - - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i "" "s/raise .*/team\.projects_tags/g" app/models/project.rb - else - sed -i "s/raise .*/team\.projects_tags/g" app/models/project.rb - fi -else - echo "Skipping \`Project\` and \`Projects::Deliverable\` on this CI node." -fi - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "1" ]; then - rails g super_scaffold Projects::Step Team name:text_field description:trix_editor --navbar="ti-world" - rails g super_scaffold Objective Projects::Step,Team name:text_field description:trix_editor -else - echo "Skipping \`Projects::Step\` and \`Objective\` on this CI node." -fi - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "1" ]; then - rails g super_scaffold Insight Team name:text_field description:trix_editor --navbar="ti-world" - rails g super_scaffold Personality::CharacterTrait Insight,Team name:text_field description:trix_editor -else - echo "Skipping \`Insight\` and \`Personality::CharacterTrait\` on this CI node." -fi - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "2" ]; then - rails g super_scaffold Personality::Disposition Team name:text_field description:trix_editor --navbar="ti-world" - rails g super_scaffold Personality::Note Personality::Disposition,Team name:text_field description:trix_editor - - # Test that the foreign key table name will be inserted into the migration. - rails g super_scaffold:field Personality::Note other_membership_id:super_select{class_name=Membership} - - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i "" "s/raise .*/team\.memberships/g" app/models/personality/note.rb - else - sed -i "s/raise .*/team\.memberships/g" app/models/personality/note.rb - fi -else - echo "Skipping \`Personality::Disposition\` and \`Personality::Note\` on this CI node." -fi - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "2" ]; then - rails g super_scaffold Personality::Observation Team name:text_field description:trix_editor --navbar="ti-world" - rails g super_scaffold Personality::Reactions::Response Personality::Observation,Team name:text_field description:trix_editor - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i "" "s/\@response/\@response_object/g" test/controllers/api/v1/personality/reactions/responses_controller_test.rb - else - sed -i "s/\@response/\@response_object/g" test/controllers/api/v1/personality/reactions/responses_controller_test.rb - fi -else - echo "Skipping \`Personality::Observation\` and \`Personality::Reactions::Response\` on this CI node." -fi - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "3" ]; then - rails g super_scaffold TestFile Team name:text_field foo:file_field bars:file_field{multiple} --navbar="ti-tag" - rails g super_scaffold ColorPicker Team color_picker_value:color_picker --navbar="ti-tag" -else - echo "Skipping \`TestFile\` and \`ColorPicker\` on this CI node." -fi - - -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "3" ]; then - # TODO: Generate these in parallel. - rails g super_scaffold PartialTest Team \ - text_field_test:text_field \ - boolean_test:boolean \ - single_button_test:buttons \ - multiple_buttons_test:buttons{multiple} \ - date_test:date_field\ - date_time_test:date_and_time_field \ - file_test:file_field \ - option_test:options \ - multiple_options_test:options{multiple} \ - password_test:password_field \ - phone_field_test:phone_field \ - super_select_test:super_select \ - multiple_super_select_test:super_select{multiple} \ - number_field_test:number_field \ - text_area_test:text_area \ - address_test:address_field --navbar="ti-layout" -else - echo "Skipping \`PartialTest\` on this CI node." -fi - - -# The test for this webhook is run inline in .github/workflows/_run_super_scaffolding_tests.yml -if [ -z "${CIRCLE_NODE_INDEX}" ] || [ "${CIRCLE_NODE_INDEX}" == "4" ]; then - rails g super_scaffold:incoming_webhooks SomeProvider -else - echo "Skipping \`Webhok\` on this CI node." -fi - -bundle exec spring rake db:schema:load db:migrate db:test:prepare diff --git a/test/system/super_scaffolding/README.md b/test/system/super_scaffolding/README.md new file mode 100644 index 000000000..46b7623af --- /dev/null +++ b/test/system/super_scaffolding/README.md @@ -0,0 +1,99 @@ +# About Super Scaffolding Tests + +These tests each require some super scaffolding commands to be run _before_ running the tests. + +Each subdirectory below contains a `setup.rb` file that you can run to generate the necessary scaffolding. + +After running the tests you can run `teardown.rb` from the same directory to remove the super scaffolded code. + +**NOTE** We highly reocmmend that you start with a clean git workspace. The super scaffolding commands generate +a lot of files and the cleanup process is... let's call it "brute force". If you have uncommitted changes in +your repo before running `setup.rb` they're likely to get clobbered when you run `teardown.rb` + +### Example + +To run the `insight` test, you'd run these commands from the main project directory. + +First run the `setup.rb` script to generate the scaffolding and run migrations. + +``` +$ ./test/system/super_scaffolding/insight/setup.rb +Generating Insight model with 'bin/rails generate model Insight team:references name:string description:text' + +Writing './app/controllers/account/insights_controller.rb'. +Fixing Standard Ruby on './app/controllers/account/insights_controller.rb'. +Writing './app/views/account/insights/index.html.erb'. +Writing './app/views/account/insights/_menu_item.html.erb'. +# snip +``` + +Then run the test: + +``` +$ rails test test/system/super_scaffolding/insight/ +🌱 Generating global seeds. +🌱 Generating test environment seeds. +Not requiring Knapsack Pro. +If you'd like to use Knapsack Pro make sure that you've set the environment variable KNAPSACK_PRO_CI_NODE_INDEX +Started with run options --seed 45445 + +BulletTrain::SuperScaffolding::InsightTest +Puma starting in single mode... +* Puma version: 6.5.0 ("Sky's Version") +* Ruby version: ruby 3.3.6 (2024-11-05 revision 75015d4c1f) [arm64-darwin23] +* Min threads: 5 +* Max threads: 5 +* Environment: test +* PID: 55207 +* Listening on http://127.0.0.1:3001 +Use Ctrl-C to stop + test_developers_can_generate_a_Insight_and_a_nested_Personality::CharacterTrait_model PASS (3.51s) + +Finished in 3.51351s +1 tests, 4 assertions, 0 failures, 0 errors, 0 skips +Coverage report generated for test to /Users/jgreen/projects/bullet-train-co/bullet_train/coverage. +Line Coverage: 45.18% (150 / 332) +``` +Then run `teardown.rb` to clean up: + +``` +$ ./test/system/super_scaffolding/insight/teardown.rb +db/schema.rb has changed - we need to rollback +== 20241219204101 CreatePersonalityCharacterTraits: reverting ================= +-- drop_table(:personality_character_traits) + -> 0.0037s +== 20241219204101 CreatePersonalityCharacterTraits: reverted (0.0073s) ======== + +== 20241219204056 CreateInsights: reverting =================================== +-- drop_table(:insights) + -> 0.0016s +== 20241219204056 CreateInsights: reverted (0.0017s) ========================== + +Updated 8 paths from the index + +Removing app/avo/resources/insight.rb +Removing app/avo/resources/personality_character_trait.rb +Removing app/controllers/account/insights_controller.rb +Removing app/controllers/account/personality/ +Removing app/controllers/api/v1/insights_controller.rb +Removing app/controllers/api/v1/personality/ +Removing app/controllers/avo/insights_controller.rb +Removing app/controllers/avo/personality_character_traits_controller.rb +Removing app/models/insight.rb +Removing app/models/personality.rb +Removing app/models/personality/ +Removing app/views/account/insights/ +Removing app/views/account/personality/ +Removing app/views/api/v1/insights/ +Removing app/views/api/v1/personality/ +Removing config/locales/en/insights.en.yml +Removing config/locales/en/personality/ +Removing db/migrate/20241219204056_create_insights.rb +Removing db/migrate/20241219204101_create_personality_character_traits.rb +Removing test/controllers/api/v1/insights_controller_test.rb +Removing test/controllers/api/v1/personality/ +Removing test/factories/insights.rb +Removing test/factories/personality/ +Removing test/models/insight_test.rb +Removing test/models/personality/ +``` diff --git a/test/system/super_scaffolding/insight/insight_test.rb b/test/system/super_scaffolding/insight/insight_test.rb new file mode 100644 index 000000000..d85385cdd --- /dev/null +++ b/test/system/super_scaffolding/insight/insight_test.rb @@ -0,0 +1,42 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::InsightTest < ApplicationSystemTestCase + setup do + @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" + end + + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. + + # force autoload. + [ + "Insight", + "Personality::CharacterTrait" + ].each do |class_name| + class_name.constantize + rescue + nil + end + + if defined?(Insight) + test "developers can generate a Insight and a nested Personality::CharacterTrait model" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + click_on "Add New Insight" + click_on "Create Insight" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Insight" + click_on "Create Insight" + + assert_text("Insight was successfully created.") + + click_on "Add New Character Trait" + click_on "Create Character Trait" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Character Trait" + click_on "Create Character Trait" + assert_text("Character Trait was successfully created.") + end + end +end diff --git a/test/system/super_scaffolding/insight/setup.rb b/test/system/super_scaffolding/insight/setup.rb new file mode 100755 index 000000000..e7c804ec0 --- /dev/null +++ b/test/system/super_scaffolding/insight/setup.rb @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold Insight Team name:text_field description:trix_editor --navbar="ti-world"` + puts `rails g super_scaffold Personality::CharacterTrait Insight,Team name:text_field description:trix_editor` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/insight/teardown.rb b/test/system/super_scaffolding/insight/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/insight/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/open_api_test.rb b/test/system/super_scaffolding/open_api_test.rb new file mode 100644 index 000000000..2f3ebc80c --- /dev/null +++ b/test/system/super_scaffolding/open_api_test.rb @@ -0,0 +1,15 @@ +require "application_system_test_case" + +# We run this in CI on each super scaffold test node to ensure that the OpenAPI Document +# is still valid after generating super scaffolds. +class SuperScaffoldingOpenAPITest < ApplicationSystemTestCase + test "OpenAPI V3 document is still valid" do + visit "/" # Make sure the test server is running before linting the file. + + puts(output = `yarn exec redocly lint http://127.0.0.1:#{Capybara.server_port}/api/v1/openapi.yaml 1> /dev/stdout 2> /dev/stdout`) + # redocly/openapi-core changed the format of their success message in version 1.2.0. + # https://github.com/Redocly/redocly-cli/pull/1239 + # We use a robust regex here so that we can match both formats. + assert output.match?(/Woohoo! Your (Open)?API (definition|description) is valid./) + end +end diff --git a/test/system/super_scaffolding/partial_test.rb b/test/system/super_scaffolding/partial_test/partial_test_test.rb similarity index 60% rename from test/system/super_scaffolding/partial_test.rb rename to test/system/super_scaffolding/partial_test/partial_test_test.rb index a8db8c072..9d6269117 100644 --- a/test/system/super_scaffolding/partial_test.rb +++ b/test/system/super_scaffolding/partial_test/partial_test_test.rb @@ -1,31 +1,15 @@ require "application_system_test_case" -class SuperScaffoldingSystemTest < ApplicationSystemTestCase +class BulletTrain::SuperScaffolding::PartialTest < ApplicationSystemTestCase setup do @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" end - # NOTE: the setup for this test really requires a clean git workspace. - # you'll see why toward the end when you're trying to clean up the files - # created (and then afterwards tested in the test below.) - # - # before this test can be run, we need to do the following setup on the console: - # bundle exec test/bin/setup-super-scaffolding-system-test - # - # to run this test: - # rails test test/system/super_scaffolding/partial_test.rb - # to run the super scaffolding test suite as a whole: - # rails test test/system/super_scaffolding/ - # - # after the test you can tear down what we've done here in the db: - # rake db:migrate VERSION=`ls db/migrate | sort | tail -n 21 | head -n 1` - # git checkout app config - # git clean -d -f app config db test + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. # force autoload. [ - "TestFile", - "ColorPicker", "PartialTest" ].each do |class_name| class_name.constantize @@ -33,76 +17,6 @@ class SuperScaffoldingSystemTest < ApplicationSystemTestCase nil end - if defined?(TestFile) - device_test "developers can Super Scaffold a file partial and perform crud actions on the record" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - assert_text("Test Files") - click_on "Add New Test File" - - fill_in "Name", with: "Test File Name" - assert_text("Upload New File") - fill_in "Name", with: "Foo" - attach_file("Foo", "test/support/foo.txt", make_visible: true) - attach_file("Bars", ["test/support/foo.txt", "test/support/foo-two.txt"], make_visible: true) - click_on "Create Test File" - - assert_text("Test File was successfully created.") - refute TestFile.first.foo.blank? - assert_equal 2, TestFile.first.bars.count - - click_on "Edit" - - assert_text("Remove Current File") - within "[data-fields--file-item-id-value='#{TestFile.first.foo.id}']" do - find("span", text: "Remove Current File").click - end - click_on "Update Test File" - - assert_text("Test File was successfully updated.") - assert TestFile.first.foo.blank? - - click_on "Edit" - assert_text("Remove Current File") - within "[data-fields--file-item-id-value='#{TestFile.first.bars.first.id}']" do - find("span", text: "Remove Current File").click - end - click_on "Update Test File" - - assert_text("Test File was successfully updated.") - assert_equal 1, TestFile.first.bars.count - - # This test consistently adds several new text files, - # so we clear out all instances of foo from the storage directory. - storage = Dir.glob("tmp/storage/**") - storage.each { |dir| FileUtils.rm_r(dir) if dir.match?(/\/([0-9]|[a-z]){2}$/) } - end - end - - if defined?(ColorPicker) - device_test "super scaffolded color pickers function properly" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - assert_text("Add New Color Picker") - click_on "Add New Color Picker" - - assert_text("Color Picker Value") - color_picker_buttons = all(".button-color") - assert_equal color_picker_buttons.size, 8 - color_picker_buttons.first.click - click_on "Create Color Picker" - - assert_text("Color Picker was successfully created.") - - # The default value can be found in the color picker's locale. - color_picker_default_value = "#9C73D2" - assert_equal ColorPicker.first.color_picker_value, color_picker_default_value - assert_text(color_picker_default_value) - end - end - if defined?(PartialTest) device_test "super scaffolded partials function properly" do login_as(@jane, scope: :user) diff --git a/test/system/super_scaffolding/partial_test/setup.rb b/test/system/super_scaffolding/partial_test/setup.rb new file mode 100755 index 000000000..b84b282af --- /dev/null +++ b/test/system/super_scaffolding/partial_test/setup.rb @@ -0,0 +1,36 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + command = %( + rails g super_scaffold PartialTest Team \ + text_field_test:text_field \ + boolean_test:boolean \ + single_button_test:buttons \ + multiple_buttons_test:buttons{multiple} \ + date_test:date_field\ + date_time_test:date_and_time_field \ + file_test:file_field \ + option_test:options \ + multiple_options_test:options{multiple} \ + password_test:password_field \ + phone_field_test:phone_field \ + super_select_test:super_select \ + multiple_super_select_test:super_select{multiple} \ + number_field_test:number_field \ + text_area_test:text_area \ + address_test:address_field --navbar="ti-layout" + ) + puts `#{command}` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/partial_test/teardown.rb b/test/system/super_scaffolding/partial_test/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/partial_test/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/personality_disposition/personality_disposition_test.rb b/test/system/super_scaffolding/personality_disposition/personality_disposition_test.rb new file mode 100644 index 000000000..c5a3743f2 --- /dev/null +++ b/test/system/super_scaffolding/personality_disposition/personality_disposition_test.rb @@ -0,0 +1,42 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::PersonalityDispositionTest < ApplicationSystemTestCase + setup do + @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" + end + + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. + + # force autoload. + [ + "Personality::Disposition", + "Personality::Note", + ].each do |class_name| + class_name.constantize + rescue + nil + end + + if defined?(Personality::Disposition) + test "developers can generate a Personality::Disposition and a nested Personality::Note model" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + click_on "Add New Disposition" + click_on "Create Disposition" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Disposition" + click_on "Create Disposition" + + assert_text("Disposition was successfully created.") + + click_on "Add New Note" + click_on "Create Note" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Note" + click_on "Create Note" + assert_text("Note was successfully created.") + end + end +end diff --git a/test/system/super_scaffolding/personality_disposition/setup.rb b/test/system/super_scaffolding/personality_disposition/setup.rb new file mode 100755 index 000000000..b8dc6de43 --- /dev/null +++ b/test/system/super_scaffolding/personality_disposition/setup.rb @@ -0,0 +1,21 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold Personality::Disposition Team name:text_field description:trix_editor --navbar="ti-world"` + puts `rails g super_scaffold Personality::Note Personality::Disposition,Team name:text_field description:trix_editor` + + # Test that the foreign key table name will be inserted into the migration. + puts `rails g super_scaffold:field Personality::Note other_membership_id:super_select{"class_name=Membership,source=team.memberships"}` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/personality_disposition/teardown.rb b/test/system/super_scaffolding/personality_disposition/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/personality_disposition/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/personality_observation/personality_observation_test.rb b/test/system/super_scaffolding/personality_observation/personality_observation_test.rb new file mode 100644 index 000000000..1a352b333 --- /dev/null +++ b/test/system/super_scaffolding/personality_observation/personality_observation_test.rb @@ -0,0 +1,42 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::PersonalityObservationTest < ApplicationSystemTestCase + setup do + @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" + end + + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. + + # force autoload. + [ + "Personality::Observation", + "Personality::Reactions::Response", + ].each do |class_name| + class_name.constantize + rescue + nil + end + + if defined?(Personality::Observation) + test "developers can generate a Personality::Observation and a nested Personality::Reactions::Response model" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + click_on "Add New Observation" + click_on "Create Observation" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Observation" + click_on "Create Observation" + + assert_text("Observation was successfully created.") + + click_on "Add New Response" + click_on "Create Response" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Response" + click_on "Create Response" + assert_text("Response was successfully created.") + end + end +end diff --git a/test/system/super_scaffolding/personality_observation/setup.rb b/test/system/super_scaffolding/personality_observation/setup.rb new file mode 100755 index 000000000..376084406 --- /dev/null +++ b/test/system/super_scaffolding/personality_observation/setup.rb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold Personality::Observation Team name:text_field description:trix_editor --navbar="ti-world"` + puts `rails g super_scaffold Personality::Reactions::Response Personality::Observation,Team name:text_field description:trix_editor` + + # TODO: This was pulled in from the bash script that we used to use for test setup. It changes instances of @response to + # @response_object in one of the test files generated above. The tests still pass even without. Seems unneccessary. + # Why did we ever do thi? + # + # This tweaks a test file for some reason? + # if Gem::Platform.local.os == "darwin" + # puts `sed -i "" "s/\@response/\@response_object/g" test/controllers/api/v1/personality/reactions/responses_controller_test.rb` + # else + # puts `sed -i "s/\@response/\@response_object/g" test/controllers/api/v1/personality/reactions/responses_controller_test.rb` + # end + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/personality_observation/teardown.rb b/test/system/super_scaffolding/personality_observation/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/personality_observation/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/project/project_test.rb b/test/system/super_scaffolding/project/project_test.rb new file mode 100644 index 000000000..7faec022d --- /dev/null +++ b/test/system/super_scaffolding/project/project_test.rb @@ -0,0 +1,116 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::ProjectTest < ApplicationSystemTestCase + setup do + @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" + end + + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. + + # force autoload. + [ + "Projects::Deliverable", + "Projects::Tag", + "Projects::AppliedTag", + ].each do |class_name| + class_name.constantize + rescue + nil + end + + if defined?(Project) + test "developers can generate a Project and a nested Projects::Deliverable model" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + click_on "Add New Project" + click_on "Create Project" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Project" + click_on "Create Project" + + assert_text("Project was successfully created.") + + click_on "Add New Deliverable" + click_on "Create Deliverable" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Deliverable" + click_on "Create Deliverable" + assert_text("Deliverable was successfully created.") + + within "ol.breadcrumb" do + click_on "Projects" + end + + assert_text("Your Team’s Projects") + + # this is ensuring cascading deletes generate properly. + accept_alert do + click_on "Delete" + end + + assert_text("Project was successfully destroyed.") + + click_on "Add New Project" + assert_text "New Project Details" + fill_in "Name", with: "Example Project" + click_on "Create Project" + assert_text "Project was successfully created." + + within "ol.breadcrumb" do + click_on "Dashboard" + end + + click_on "Example Project" + assert_text "Below are the details we have for Example Project" + + click_on "Back" + assert_text "Below is a list of Projects" + + click_on "Back" + assert_text "No Tags have been added" + + click_on "Add New Tag" + assert_text "Please provide the details of the new Tag" + + fill_in "Name", with: "One" + click_on "Create Tag" + assert_text "Tag was successfully created" + + click_on "Back" + + click_on "Add New Tag" + assert_text "Please provide the details of the new Tag" + + fill_in "Name", with: "Two" + click_on "Create Tag" + assert_text "Tag was successfully created" + + click_on "Back" + + click_on "Add New Tag" + assert_text "Please provide the details of the new Tag" + + fill_in "Name", with: "Three" + click_on "Create Tag" + assert_text "Tag was successfully created" + + click_on "Back" + assert_text "Your Team’s Tags" + click_on "Back" + assert_text "Your Team’s Dashboard" + + click_on "Add New Project" + assert_text "Please provide the details of the new Project" + + fill_in "Name", with: "New Project with Tags" + select2_select "Tags", ["One", "Two"] + click_on "Create Project" + assert_text "Project was successfully created" + + assert_text "Below are the details we have for New Project with Tags" + assert_text "One and Two" + end + end +end diff --git a/test/system/super_scaffolding/project/setup.rb b/test/system/super_scaffolding/project/setup.rb new file mode 100755 index 000000000..c8a33452b --- /dev/null +++ b/test/system/super_scaffolding/project/setup.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold Project Team name:text_field description:trix_editor --navbar="ti-layout"` + puts `rails g super_scaffold Projects::Deliverable Project,Team name:text_field description:trix_editor` + + # Setup for has-many-through test. + puts `rails g super_scaffold Projects::Tag Team name:text_field --navbar="ti-tag"` + + puts `rails g super_scaffold:join_model Projects::AppliedTag project_id{class_name=Project} tag_id{class_name=Projects::Tag}` + puts `rails g super_scaffold:field Project tag_ids:super_select{"class_name=Projects::Tag,source=team.projects_tags"}` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/project/teardown.rb b/test/system/super_scaffolding/project/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/project/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/projects_step/projects_step_test.rb b/test/system/super_scaffolding/projects_step/projects_step_test.rb new file mode 100644 index 000000000..25361c794 --- /dev/null +++ b/test/system/super_scaffolding/projects_step/projects_step_test.rb @@ -0,0 +1,42 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::ProjectsStepTest < ApplicationSystemTestCase + setup do + @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" + end + + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. + + # force autoload. + [ + "Projects::Step", + "Objective", + ].each do |class_name| + class_name.constantize + rescue + nil + end + + if defined?(Projects::Step) + test "developers can generate a Projects::Step and a nested Objective model" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + click_on "Add New Step" + click_on "Create Step" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Step" + click_on "Create Step" + + assert_text("Step was successfully created.") + + click_on "Add New Objective" + click_on "Create Objective" + assert_text("Name can't be blank.") + fill_in "Name", with: "Some New Example Objective" + click_on "Create Objective" + assert_text("Objective was successfully created.") + end + end +end diff --git a/test/system/super_scaffolding/projects_step/setup.rb b/test/system/super_scaffolding/projects_step/setup.rb new file mode 100755 index 000000000..6e384567c --- /dev/null +++ b/test/system/super_scaffolding/projects_step/setup.rb @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold Projects::Step Team name:text_field description:trix_editor --navbar="ti-world"` + puts `rails g super_scaffold Objective Projects::Step,Team name:text_field description:trix_editor` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/projects_step/teardown.rb b/test/system/super_scaffolding/projects_step/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/projects_step/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/super_scaffolding_test.rb b/test/system/super_scaffolding/super_scaffolding_test.rb deleted file mode 100644 index 272d85694..000000000 --- a/test/system/super_scaffolding/super_scaffolding_test.rb +++ /dev/null @@ -1,296 +0,0 @@ -require "application_system_test_case" - -class SuperScaffoldingSystemTest < ApplicationSystemTestCase - setup do - @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" - end - - # NOTE: the setup for this test really requires a clean git workspace. - # you'll see why toward the end when you're trying to clean up the files - # created (and then afterwards tested in the test below.) - # - # before this test can be run, we need to do the following setup on the console: - # bundle exec test/bin/setup-super-scaffolding-system-test - # - # to run this test: - # rails test test/system/super_scaffolding/super_scaffolding_test.rb - # to run the super scaffolding test suite as a whole: - # rails test test/system/super_scaffolding/ - # - # after the test you can tear down what we've done here in the db: - # rake db:migrate VERSION=`ls db/migrate | sort | tail -n 9 | head -n 1` - # git checkout . - # git clean -d -f - - # force autoload. - [ - "TestSite", - "TestPage", - "Project", - "Projects::Deliverable", - "Projects::Tag", - "Projects::AppliedTag", - "Projects::Step", - "Objective", - "Insight", - "Personality::CharacterTrait", - "Personality::Disposition", - "Personality::Note", - "Personality::Observation", - "Personality::Reactions::Response", - ].each do |class_name| - class_name.constantize - rescue - nil - end - - if defined?(TestSite) - test "developers can generate a TestSite and a nested TestPage model" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - assert_text("Test Sites") - click_on "Add New Test Site" - - assert_text("New Test Site Details") - fill_in "Name", with: "Some New Example Site" - fill_in "Other Attribute", with: "Some Other Value" - fill_in "Url", with: "http://example.org/test" - - click_on "Create Test Site" - click_on "Back" - - assert_text "Below is a list of Test Sites that have been added for Your Team." - - # Edit the first test site. - within "table", match: :first do - click_on "Edit", match: :first - end - - assert_text "Edit Test Site Details" - - # Select the membership we created. - find("#select2-test_site_membership_id-container").click - find("li.select2-results__option span", text: "Jane Smith").click - click_on "Update Test Site" - - # Test the has-many-through scaffolding. - assert_text "Test Site was successfully updated." - - # make sure the content is being displayed on the show partial. - assert_text("Test Site Details") - assert_text("Some New Example Site") - assert_text("http://example.org/test") - click_on "Back" - - # we're now looking at the index on the team dashboard. - assert_text("Some New Example Site") - assert_text("http://example.org/test") - click_on "Some New Example Site" - - assert_text("Test Pages") - click_on "Add New Test Page" - - assert_text("New Test Page Details") - fill_in "Name", with: "Some New Example Site" - fill_in "Path", with: "/test" - click_on "Create Test Page" - - assert_text("Some New Example Site") - assert_text("/test") - end - end - - if defined?(Project) - test "developers can generate a Project and a nested Projects::Deliverable model" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - click_on "Add New Project" - click_on "Create Project" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Project" - click_on "Create Project" - - assert_text("Project was successfully created.") - - click_on "Add New Deliverable" - click_on "Create Deliverable" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Deliverable" - click_on "Create Deliverable" - assert_text("Deliverable was successfully created.") - - within "ol.breadcrumb" do - click_on "Projects" - end - - assert_text("Your Team’s Projects") - - # this is ensuring cascading deletes generate properly. - accept_alert do - click_on "Delete" - end - - assert_text("Project was successfully destroyed.") - - click_on "Add New Project" - assert_text "New Project Details" - fill_in "Name", with: "Example Project" - click_on "Create Project" - assert_text "Project was successfully created." - - within "ol.breadcrumb" do - click_on "Dashboard" - end - - click_on "Example Project" - assert_text "Below are the details we have for Example Project" - - click_on "Back" - assert_text "Below is a list of Projects" - - click_on "Back" - assert_text "No Tags have been added" - - click_on "Add New Tag" - assert_text "Please provide the details of the new Tag" - - fill_in "Name", with: "One" - click_on "Create Tag" - assert_text "Tag was successfully created" - - click_on "Back" - - click_on "Add New Tag" - assert_text "Please provide the details of the new Tag" - - fill_in "Name", with: "Two" - click_on "Create Tag" - assert_text "Tag was successfully created" - - click_on "Back" - - click_on "Add New Tag" - assert_text "Please provide the details of the new Tag" - - fill_in "Name", with: "Three" - click_on "Create Tag" - assert_text "Tag was successfully created" - - click_on "Back" - assert_text "Your Team’s Tags" - click_on "Back" - assert_text "Your Team’s Dashboard" - - click_on "Add New Project" - assert_text "Please provide the details of the new Project" - - fill_in "Name", with: "New Project with Tags" - select2_select "Tags", ["One", "Two"] - click_on "Create Project" - assert_text "Project was successfully created" - - assert_text "Below are the details we have for New Project with Tags" - assert_text "One and Two" - end - end - - if defined?(Projects::Step) - test "developers can generate a Projects::Step and a nested Objective model" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - click_on "Add New Step" - click_on "Create Step" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Step" - click_on "Create Step" - - assert_text("Step was successfully created.") - - click_on "Add New Objective" - click_on "Create Objective" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Objective" - click_on "Create Objective" - assert_text("Objective was successfully created.") - end - end - - if defined?(Insight) - test "developers can generate a Insight and a nested Personality::CharacterTrait model" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - click_on "Add New Insight" - click_on "Create Insight" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Insight" - click_on "Create Insight" - - assert_text("Insight was successfully created.") - - click_on "Add New Character Trait" - click_on "Create Character Trait" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Character Trait" - click_on "Create Character Trait" - assert_text("Character Trait was successfully created.") - end - end - - if defined?(Personality::Disposition) - test "developers can generate a Personality::Disposition and a nested Personality::Note model" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - click_on "Add New Disposition" - click_on "Create Disposition" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Disposition" - click_on "Create Disposition" - - assert_text("Disposition was successfully created.") - - click_on "Add New Note" - click_on "Create Note" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Note" - click_on "Create Note" - assert_text("Note was successfully created.") - end - end - - if defined?(Personality::Observation) - test "developers can generate a Personality::Observation and a nested Personality::Reactions::Response model" do - login_as(@jane, scope: :user) - visit account_team_path(@jane.current_team) - - click_on "Add New Observation" - click_on "Create Observation" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Observation" - click_on "Create Observation" - - assert_text("Observation was successfully created.") - - click_on "Add New Response" - click_on "Create Response" - assert_text("Name can't be blank.") - fill_in "Name", with: "Some New Example Response" - click_on "Create Response" - assert_text("Response was successfully created.") - end - end - - test "OpenAPI V3 document is still valid" do - visit "/" # Make sure the test server is running before linting the file. - - puts(output = `yarn exec redocly lint http://127.0.0.1:#{Capybara.server_port}/api/v1/openapi.yaml 1> /dev/stdout 2> /dev/stdout`) - # redocly/openapi-core changed the format of their success message in version 1.2.0. - # https://github.com/Redocly/redocly-cli/pull/1239 - # We use a robust regex here so that we can match both formats. - assert output.match?(/Woohoo! Your (Open)?API (definition|description) is valid./) - end -end diff --git a/test/system/super_scaffolding/super_scaffolding_test_setup.rb b/test/system/super_scaffolding/super_scaffolding_test_setup.rb new file mode 100644 index 000000000..85b80a60d --- /dev/null +++ b/test/system/super_scaffolding/super_scaffolding_test_setup.rb @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby + +require "thor" + +class SuperScaffoldingTestSetup < Thor + # TODO: Need better naming and description. + desc "scaffolding_setup", "Run the setup method for this test." + option :allow_dirty_workspace + def scaffolding_setup + if !git_workspace_clean && !options[:allow_dirty_workspace] + banner = <<~BANNER + -------------------------------------------------------------------------------------------------------- + - It looks like your git workspace is not clean. + - This script will generate a bunch of stuff that you probably don't want to keep. + - The teardown script may clobber your other changes, so we don't recommend running setup in a dirty workspace. + - + - If you really want to run this with your current non-clean workspace + - then you can pass the `--allow-dirty-workspace` flag to skip this notice and run the script. + - + - For example: + - ./test/system/super_scaffolding/test_site/setup.rb --allow-dirty-workspace + ------------------------------------------------------------------------------------------------------- + BANNER + say_error banner, :red + return 1 + end + setup + migrate + end + + # This allows failure to be reported to the shell correctly. + # https://github.com/rails/thor/wiki/Making-An-Executable + def self.exit_on_failure? + true + end + + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + raise "Your subcommand should define the setup method." + end + + def migrate + puts `bundle exec rails db:migrate db:test:prepare` + end + + def git_workspace_clean + # Are there unstaged changes? + `git diff --exit-code` + unstaged_changes_present = !$?.success? + + `git diff --cached --exit-code` + staged_changes_present = !$?.success? + + # puts "workspace_is_clean = #{unstaged_changes_present && staged_changes_present}" + + unstaged_changes_present && staged_changes_present + end + end +end + +# We create our own args array so that we don't have to ask the user to include `bump` on the command line +# args = ["setup"] + ARGV + +# Setup.start(args) diff --git a/test/system/super_scaffolding/super_scaffolding_test_teardown.rb b/test/system/super_scaffolding/super_scaffolding_test_teardown.rb new file mode 100644 index 000000000..7cfdba9c1 --- /dev/null +++ b/test/system/super_scaffolding/super_scaffolding_test_teardown.rb @@ -0,0 +1,55 @@ +#!/usr/bin/env ruby + +require "thor" + +class SuperScaffoldingTestTeardown < Thor + # TODO: Need better naming and description. + desc "scaffolding_teardown", "Run the teardown method for this test." + option :allow_dirty_workspace + def scaffolding_teardown + if db_schema_has_changed + puts "db/schema.rb has changed - we need to rollback" + rollback + else + puts "db/schema.rb has not changed - no need to rollback" + end + clean_workspace + teardown + end + + # This allows failure to be reported to the shell correctly. + # https://github.com/rails/thor/wiki/Making-An-Executable + def self.exit_on_failure? + true + end + + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def clean_workspace + puts `git checkout app config db test` + puts `git clean -d -f app config db test` + end + + def db_schema_has_changed + `git diff --exit-code db/schema.rb` + !$?.success? + end + + def rollback + puts `bundle exec rails db:rollback STEP=#{commits_to_rollback}` + end + + def commits_to_rollback + `git status | grep -c db/migrate` + end + + def teardown + raise "Your subcommand should define the teardown method." + end + end +end + +# We create our own args array so that we don't have to ask the user to include `bump` on the command line +# args = ["teardown"] + ARGV + +# Teardown.start(args) diff --git a/test/system/super_scaffolding/test_file/setup.rb b/test/system/super_scaffolding/test_file/setup.rb new file mode 100755 index 000000000..9e19b5fe0 --- /dev/null +++ b/test/system/super_scaffolding/test_file/setup.rb @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold TestFile Team name:text_field foo:file_field bars:file_field{multiple} --navbar="ti-tag"` + puts `rails g super_scaffold ColorPicker Team color_picker_value:color_picker --navbar="ti-tag"` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/test_file/teardown.rb b/test/system/super_scaffolding/test_file/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/test_file/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/test_file/test_file_test.rb b/test/system/super_scaffolding/test_file/test_file_test.rb new file mode 100644 index 000000000..64e595311 --- /dev/null +++ b/test/system/super_scaffolding/test_file/test_file_test.rb @@ -0,0 +1,90 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::TestFileTest < ApplicationSystemTestCase + setup do + @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" + end + + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. + + # force autoload. + [ + "TestFile", + "ColorPicker", + ].each do |class_name| + class_name.constantize + rescue + nil + end + + if defined?(TestFile) + device_test "developers can Super Scaffold a file partial and perform crud actions on the record" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + assert_text("Test Files") + click_on "Add New Test File" + + fill_in "Name", with: "Test File Name" + assert_text("Upload New File") + fill_in "Name", with: "Foo" + attach_file("Foo", "test/support/foo.txt", make_visible: true) + attach_file("Bars", ["test/support/foo.txt", "test/support/foo-two.txt"], make_visible: true) + click_on "Create Test File" + + assert_text("Test File was successfully created.") + refute TestFile.first.foo.blank? + assert_equal 2, TestFile.first.bars.count + + click_on "Edit" + + assert_text("Remove Current File") + within "[data-fields--file-item-id-value='#{TestFile.first.foo.id}']" do + find("span", text: "Remove Current File").click + end + click_on "Update Test File" + + assert_text("Test File was successfully updated.") + assert TestFile.first.foo.blank? + + click_on "Edit" + assert_text("Remove Current File") + within "[data-fields--file-item-id-value='#{TestFile.first.bars.first.id}']" do + find("span", text: "Remove Current File").click + end + click_on "Update Test File" + + assert_text("Test File was successfully updated.") + assert_equal 1, TestFile.first.bars.count + + # This test consistently adds several new text files, + # so we clear out all instances of foo from the storage directory. + storage = Dir.glob("tmp/storage/**") + storage.each { |dir| FileUtils.rm_r(dir) if dir.match?(/\/([0-9]|[a-z]){2}$/) } + end + end + + if defined?(ColorPicker) + device_test "super scaffolded color pickers function properly" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + assert_text("Add New Color Picker") + click_on "Add New Color Picker" + + assert_text("Color Picker Value") + color_picker_buttons = all(".button-color") + assert_equal color_picker_buttons.size, 8 + color_picker_buttons.first.click + click_on "Create Color Picker" + + assert_text("Color Picker was successfully created.") + + # The default value can be found in the color picker's locale. + color_picker_default_value = "#9C73D2" + assert_equal ColorPicker.first.color_picker_value, color_picker_default_value + assert_text(color_picker_default_value) + end + end +end diff --git a/test/system/super_scaffolding/test_site/setup.rb b/test/system/super_scaffolding/test_site/setup.rb new file mode 100755 index 000000000..2ec950f0e --- /dev/null +++ b/test/system/super_scaffolding/test_site/setup.rb @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold TestSite Team name:text_field other_attribute:text_field url:text_field --navbar="ti-world" --sortable` + puts `rails g super_scaffold TestPage TestSite,Team name:text_field path:text_field` + puts `rails g super_scaffold:field TestSite membership_id:super_select{"class_name=Membership,source=team.memberships"}` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/test_site/teardown.rb b/test/system/super_scaffolding/test_site/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/test_site/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/test_site/test_site_test.rb b/test/system/super_scaffolding/test_site/test_site_test.rb new file mode 100644 index 000000000..6abb7a8f3 --- /dev/null +++ b/test/system/super_scaffolding/test_site/test_site_test.rb @@ -0,0 +1,77 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::TestSiteTest < ApplicationSystemTestCase + setup do + @jane = create :onboarded_user, first_name: "Jane", last_name: "Smith" + end + + # NOTE: This test only runs if the `setup.rb` file in this directory has run. + # See ../README.md for details. + + # force autoload. + [ + "TestSite", + "TestPage" + ].each do |class_name| + class_name.constantize + rescue + nil + end + + if defined?(TestSite) + test "developers can generate a TestSite and a nested TestPage model" do + login_as(@jane, scope: :user) + visit account_team_path(@jane.current_team) + + assert_text("Test Sites") + click_on "Add New Test Site" + + assert_text("New Test Site Details") + fill_in "Name", with: "Some New Example Site" + fill_in "Other Attribute", with: "Some Other Value" + fill_in "Url", with: "http://example.org/test" + + click_on "Create Test Site" + click_on "Back" + + assert_text "Below is a list of Test Sites that have been added for Your Team." + + # Edit the first test site. + within "table", match: :first do + click_on "Edit", match: :first + end + + assert_text "Edit Test Site Details" + + # Select the membership we created. + find("#select2-test_site_membership_id-container").click + find("li.select2-results__option span", text: "Jane Smith").click + click_on "Update Test Site" + + # Test the has-many-through scaffolding. + assert_text "Test Site was successfully updated." + + # make sure the content is being displayed on the show partial. + assert_text("Test Site Details") + assert_text("Some New Example Site") + assert_text("http://example.org/test") + click_on "Back" + + # we're now looking at the index on the team dashboard. + assert_text("Some New Example Site") + assert_text("http://example.org/test") + click_on "Some New Example Site" + + assert_text("Test Pages") + click_on "Add New Test Page" + + assert_text("New Test Page Details") + fill_in "Name", with: "Some New Example Site" + fill_in "Path", with: "/test" + click_on "Create Test Page" + + assert_text("Some New Example Site") + assert_text("/test") + end + end +end diff --git a/test/system/super_scaffolding/webhook/setup.rb b/test/system/super_scaffolding/webhook/setup.rb new file mode 100755 index 000000000..9c15f4639 --- /dev/null +++ b/test/system/super_scaffolding/webhook/setup.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_setup" + +class Setup < SuperScaffoldingTestSetup + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def setup + puts `rails g super_scaffold:incoming_webhooks SomeProvider` + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_setup"] + ARGV + +Setup.start(args) diff --git a/test/system/super_scaffolding/webhook/teardown.rb b/test/system/super_scaffolding/webhook/teardown.rb new file mode 100755 index 000000000..d774df094 --- /dev/null +++ b/test/system/super_scaffolding/webhook/teardown.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require_relative "../super_scaffolding_test_teardown" + +class Teardown < SuperScaffoldingTestTeardown + # This allows us to define helper methods that aren't attached to thor commands + no_commands do + def teardown + # custom teardown goes here + end + end +end + +# We create our own args array so that we don't have to ask the user to include `scaffolding_setup` on the command line +args = ["scaffolding_teardown"] + ARGV + +Teardown.start(args) diff --git a/test/system/super_scaffolding/webhook/webhook_test.rb b/test/system/super_scaffolding/webhook/webhook_test.rb new file mode 100644 index 000000000..ece7b3417 --- /dev/null +++ b/test/system/super_scaffolding/webhook/webhook_test.rb @@ -0,0 +1,8 @@ +require "application_system_test_case" + +class BulletTrain::SuperScaffolding::WebhookTest < ApplicationSystemTestCase + # We don't test anythying direclty on this one one. + # Instead we test that the controller and test that we generated run correctly. + # In CI we explicitly call: + # rails test test/controllers/webhooks/incoming/some_provider_webhooks_controller_test.rb +end