diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..7898fbf8 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "eslint-config-discourse" +} diff --git a/.github/workflows/plugin-linting.yml b/.github/workflows/plugin-linting.yml new file mode 100644 index 00000000..a121658d --- /dev/null +++ b/.github/workflows/plugin-linting.yml @@ -0,0 +1,53 @@ +name: Linting + +on: + push: + branches: + - master + - main + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Set up ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7 + + - name: Setup bundler + run: gem install bundler -v 2.1.4 --no-doc + + - name: Setup gems + run: bundle install --jobs 4 + + - name: Yarn install + run: yarn install --dev + + - name: ESLint + run: yarn eslint --ext .js,.js.es6 --no-error-on-unmatched-pattern {test,assets}/javascripts + + - name: Prettier + run: | + yarn prettier -v + if [ -d "assets" ]; then \ + yarn prettier --list-different "assets/**/*.{scss,js,es6}" ; \ + fi + if [ -d "test" ]; then \ + yarn prettier --list-different "test/**/*.{js,es6}" ; \ + fi + + - name: Ember template lint + run: yarn ember-template-lint assets/javascripts + + - name: Rubocop + run: bundle exec rubocop . \ No newline at end of file diff --git a/.github/workflows/plugin-tests.yml b/.github/workflows/plugin-tests.yml new file mode 100644 index 00000000..ce6112af --- /dev/null +++ b/.github/workflows/plugin-tests.yml @@ -0,0 +1,137 @@ +name: Plugin Tests + +on: + push: + branches: + - master + - main + pull_request: + +jobs: + build: + name: ${{ matrix.build_type }} + runs-on: ubuntu-latest + timeout-minutes: 60 + + env: + DISCOURSE_HOSTNAME: www.example.com + RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072 + RAILS_ENV: test + PGHOST: localhost + PGUSER: discourse + PGPASSWORD: discourse + + strategy: + fail-fast: false + + matrix: + build_type: ["backend", "frontend"] + ruby: ["2.7"] + postgres: ["12"] + redis: ["4.x"] + + services: + postgres: + image: postgres:${{ matrix.postgres }} + ports: + - 5432:5432 + env: + POSTGRES_USER: discourse + POSTGRES_PASSWORD: discourse + options: >- + --mount type=tmpfs,destination=/var/lib/postgresql/data + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v2 + with: + repository: discourse/discourse + fetch-depth: 1 + + - name: Install plugin + uses: actions/checkout@v2 + with: + path: plugins/${{ github.event.repository.name }} + fetch-depth: 1 + + - name: Check spec existence + id: check_spec + uses: andstor/file-existence-action@v1 + with: + files: "plugins/${{ github.event.repository.name }}/spec" + + - name: Check qunit existence + id: check_qunit + uses: andstor/file-existence-action@v1 + with: + files: "plugins/${{ github.event.repository.name }}/test/javascripts" + + - name: Setup Git + run: | + git config --global user.email "ci@ci.invalid" + git config --global user.name "Discourse CI" + + - name: Setup packages + run: | + sudo apt-get update + sudo apt-get -yqq install postgresql-client libpq-dev gifsicle jpegoptim optipng jhead + wget -qO- https://raw.githubusercontent.com/discourse/discourse_docker/master/image/base/install-pngquant | sudo sh + + - name: Update imagemagick + if: matrix.build_type == 'backend' + run: | + wget https://raw.githubusercontent.com/discourse/discourse_docker/master/image/base/install-imagemagick + chmod +x install-imagemagick + sudo ./install-imagemagick + + - name: Setup redis + uses: shogo82148/actions-setup-redis@v1 + with: + redis-version: ${{ matrix.redis }} + + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + + - name: Lint English locale + if: matrix.build_type == 'backend' + run: bundle exec ruby script/i18n_lint.rb "plugins/${{ github.event.repository.name }}/locales/{client,server}.en.yml" + + - name: Get yarn cache directory + id: yarn-cache-dir + run: echo "::set-output name=dir::$(yarn cache dir)" + + - name: Yarn cache + uses: actions/cache@v2 + id: yarn-cache + with: + path: ${{ steps.yarn-cache-dir.outputs.dir }} + key: ${{ runner.os }}-${{ matrix.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-${{ matrix.os }}-yarn- + + - name: Yarn install + run: yarn install --dev + + - name: Migrate database + run: | + bin/rake db:create + bin/rake db:migrate + + - name: Plugin RSpec + if: matrix.build_type == 'backend' && steps.check_spec.outputs.files_exists == 'true' + run: bin/rake plugin:spec[${{ github.event.repository.name }}] + + - name: Plugin QUnit + if: matrix.build_type == 'frontend' && steps.check_qunit.outputs.files_exists == 'true' + run: bundle exec rake plugin:qunit['${{ github.event.repository.name }}','1200000'] + timeout-minutes: 30 + + - name: Simplecov Report + if: matrix.build_type == 'backend' + run: COVERAGE=1 bin/rake plugin:spec[${{ github.event.repository.name }}] diff --git a/.gitignore b/.gitignore index 98902d6e..11ce0a3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ coverage/* !coverage/.last_run.json gems/ +.bundle/ +auto_generated +.DS_Store +node_modules/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..d46296cf --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,2 @@ +inherit_gem: + rubocop-discourse: default.yml diff --git a/.template-lintrc.js b/.template-lintrc.js new file mode 100644 index 00000000..a558b8e3 --- /dev/null +++ b/.template-lintrc.js @@ -0,0 +1,4 @@ +module.exports = { + plugins: ["ember-template-lint-plugin-discourse"], + extends: "discourse:recommended", +}; diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..7da32ec0 --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +group :development do + gem 'rubocop-discourse' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..2416ce66 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,38 @@ +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + parallel (1.20.1) + parser (3.0.1.0) + ast (~> 2.4.1) + rainbow (3.0.0) + regexp_parser (2.1.1) + rexml (3.2.5) + rubocop (1.12.1) + parallel (~> 1.10) + parser (>= 3.0.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.2.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.4.1) + parser (>= 2.7.1.5) + rubocop-discourse (2.4.1) + rubocop (>= 1.1.0) + rubocop-rspec (>= 2.0.0) + rubocop-rspec (2.2.0) + rubocop (~> 1.0) + rubocop-ast (>= 1.1.0) + ruby-progressbar (1.11.0) + unicode-display_width (2.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + rubocop-discourse + +BUNDLED WITH + 2.2.16 diff --git a/assets/javascripts/wizard/templates/components/validator.hbs b/assets/javascripts/wizard/templates/components/validator.hbs index 88ffa227..a233df9c 100644 --- a/assets/javascripts/wizard/templates/components/validator.hbs +++ b/assets/javascripts/wizard/templates/components/validator.hbs @@ -1,5 +1,5 @@ {{#if isValid}} {{wizard-i18n validMessageKey}} -{{else}} +{{else}} {{wizard-i18n invalidMessageKey}} {{/if}} diff --git a/lib/custom_wizard/action.rb b/lib/custom_wizard/action.rb index fbfa17a5..0d01c8f0 100644 --- a/lib/custom_wizard/action.rb +++ b/lib/custom_wizard/action.rb @@ -307,15 +307,15 @@ class CustomWizard::Action return end - groups = group_map.reduce([]) do |groups, g| + groups = group_map.reduce([]) do |result, g| begin - groups.push(Integer(g)) + result.push(Integer(g)) rescue ArgumentError group = Group.find_by(name: g) - groups.push(group.id) if group + result.push(group.id) if group end - groups + result end result = nil diff --git a/lib/custom_wizard/api/endpoint.rb b/lib/custom_wizard/api/endpoint.rb index 71af3453..9dbbc590 100644 --- a/lib/custom_wizard/api/endpoint.rb +++ b/lib/custom_wizard/api/endpoint.rb @@ -74,7 +74,7 @@ class CustomWizard::Api::Endpoint headers["Authorization"] = auth_string if auth_string headers["Content-Type"] = content_type if content_type - connection = Excon.new(URI.parse(URI.encode(endpoint.url)).to_s, headers: headers) + connection = Excon.new(UrlHelper.encode_and_parse(endpoint.url), headers: headers) params = { method: endpoint.method } diff --git a/package.json b/package.json new file mode 100644 index 00000000..c6692218 --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "name": "discourse-custom-wizard", + "version": "1.0.0", + "repository": "git@github.com:paviliondev/discourse-custom-wizard.git", + "author": "Discourse", + "license": "MIT", + "devDependencies": { + "eslint-config-discourse": "^1.1.8" + } +} diff --git a/spec/components/custom_wizard/action_spec.rb b/spec/components/custom_wizard/action_spec.rb index 9ccb51bf..bbf266d4 100644 --- a/spec/components/custom_wizard/action_spec.rb +++ b/spec/components/custom_wizard/action_spec.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require_relative '../../plugin_helper' describe CustomWizard::Action do @@ -121,8 +122,8 @@ describe CustomWizard::Action do end it 'encodes special characters in the title and body' do - open_composer['title'][0]['output'] = "Title that's special $" - open_composer['post_template'] = "Body & more body & more body" + open_composer['title'][0]['output'] = "Title that's special $".dup + open_composer['post_template'] = "Body & more body & more body".dup wizard = CustomWizard::Wizard.new(@template, user) diff --git a/spec/components/custom_wizard/builder_spec.rb b/spec/components/custom_wizard/builder_spec.rb index 9ad4348e..54a6ceff 100644 --- a/spec/components/custom_wizard/builder_spec.rb +++ b/spec/components/custom_wizard/builder_spec.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require_relative '../../plugin_helper' describe CustomWizard::Builder do diff --git a/spec/components/custom_wizard/realtime_validations/similar_topics_spec.rb b/spec/components/custom_wizard/realtime_validations/similar_topics_spec.rb index 7d871d45..eb81509e 100644 --- a/spec/components/custom_wizard/realtime_validations/similar_topics_spec.rb +++ b/spec/components/custom_wizard/realtime_validations/similar_topics_spec.rb @@ -5,7 +5,6 @@ require_relative '../../../plugin_helper' describe ::CustomWizard::RealtimeValidation::SimilarTopics do let(:post) { create_post(title: "matching similar topic") } let(:topic) { post.topic } - let(:user) { post.user } let(:category) { Fabricate(:category) } let(:cat_post) { create_post(title: "matching similar topic slightly different", category: category) } diff --git a/spec/components/custom_wizard/wizard_spec.rb b/spec/components/custom_wizard/wizard_spec.rb index e613ddf9..57d15241 100644 --- a/spec/components/custom_wizard/wizard_spec.rb +++ b/spec/components/custom_wizard/wizard_spec.rb @@ -98,7 +98,7 @@ describe CustomWizard::Wizard do CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted? ).to eq(true) end - + it "permits everyone if everyone is permitted" do @permitted_template['permitted'][0]['output'] = Group::AUTO_GROUPS[:everyone] expect( @@ -185,7 +185,7 @@ describe CustomWizard::Wizard do ).to eq('I am a user submission') end - context do + context "class methods" do before do CustomWizard::Template.save(@permitted_template, skip_jobs: true) diff --git a/spec/extensions/invites_controller_spec.rb b/spec/extensions/invites_controller_spec.rb index ee75500e..47c4ca84 100644 --- a/spec/extensions/invites_controller_spec.rb +++ b/spec/extensions/invites_controller_spec.rb @@ -4,7 +4,7 @@ require_relative '../plugin_helper' describe InvitesControllerCustomWizard, type: :request do fab!(:topic) { Fabricate(:topic) } let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) } - + let(:template) do JSON.parse(File.open( "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" @@ -19,6 +19,6 @@ describe InvitesControllerCustomWizard, type: :request do template['after_signup'] = true CustomWizard::Template.save(template, skip_jobs: true) put "/invites/show/#{invite.invite_key}.json" - expect(response.parsed_body["redirect_to"]).to eq("/w/super-mega-fun-wizard") + expect(cookies[:destination_url]).to eq("/w/super-mega-fun-wizard") end end