DEV: Add tests for invite system (#12524)

DEV: Add tests for invite system (#12524)

diff --git a/app/assets/javascripts/discourse/app/components/invite-panel.js b/app/assets/javascripts/discourse/app/components/invite-panel.js
index 7a77a6d..dd55ebe 100644
--- a/app/assets/javascripts/discourse/app/components/invite-panel.js
+++ b/app/assets/javascripts/discourse/app/components/invite-panel.js
@@ -318,6 +318,11 @@ export default Component.extend({
   },
 
   @action
+  sendCloseModal() {
+    this.attrs.close();
+  },
+
+  @action
   createInvite() {
     if (this.disabled) {
       return;
@@ -388,7 +393,7 @@ export default Component.extend({
   },
 
   @action
-  generateInvitelink() {
+  generateInviteLink() {
     if (this.disabled) {
       return;
     }
diff --git a/app/assets/javascripts/discourse/app/templates/components/invite-panel.hbs b/app/assets/javascripts/discourse/app/templates/components/invite-panel.hbs
index d5cfd1e..f788604 100644
--- a/app/assets/javascripts/discourse/app/templates/components/invite-panel.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/invite-panel.hbs
@@ -87,7 +87,7 @@
   {{#if inviteModel.finished}}
     {{d-button
       class="btn-primary"
-      action=(route-action "closeModal")
+      action=(action "sendCloseModal")
       label="close"}}
   {{else}}
     {{d-button
@@ -99,7 +99,7 @@
     {{#if showCopyInviteButton}}
       {{d-button
         icon="link"
-        action=(action "generateInvitelink")
+        action=(action "generateInviteLink")
         class="btn-primary generate-invite-link"
         disabled=disabledCopyLink
         label="user.invited.generate_link"}}
diff --git a/app/assets/javascripts/discourse/tests/integration/components/invite-panel-test.js b/app/assets/javascripts/discourse/tests/integration/components/invite-panel-test.js
new file mode 100644
index 0000000..8d161d2
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/integration/components/invite-panel-test.js
@@ -0,0 +1,56 @@
+import { set } from "@ember/object";
+import { click, fillIn } from "@ember/test-helpers";
+import User from "discourse/models/user";
+import componentTest, {
+  setupRenderingTest,
+} from "discourse/tests/helpers/component-test";
+import pretender from "discourse/tests/helpers/create-pretender";
+import {
+  discourseModule,
+  queryAll,
+} from "discourse/tests/helpers/qunit-helpers";
+import selectKit from "discourse/tests/helpers/select-kit-helper";
+import hbs from "htmlbars-inline-precompile";
+
+discourseModule("Integration | Component | invite-panel", function (hooks) {
+  setupRenderingTest(hooks);
+
+  componentTest("shows the invite link after it is generated", {
+    template: hbs`{{invite-panel panel=panel}}`,
+
+    beforeEach() {
+      pretender.get("/u/search/users", () => {
+        return [200, { "Content-Type": "application/json" }, { users: [] }];
+      });
+
+      pretender.post("/invites", () => {
+        return [
+          200,
+          { "Content-Type": "application/json" },
+          {
+            link: "http://example.com/invites/92c297e886a0ca03089a109ccd6be155",
+          },
+        ];
+      });
+
+      set(this.currentUser, "details", { can_invite_via_email: true });
+      this.set("panel", {
+        id: "invite",
+        model: { inviteModel: User.create(this.currentUser) },
+      });
+    },
+
+    async test(assert) {
+      const input = selectKit(".invite-user-input");
+      await input.expand();
+      await fillIn(".invite-user-input .filter-input", "eviltrout@example.com");
+      await input.selectRowByValue("eviltrout@example.com");
+      assert.ok(queryAll(".send-invite:disabled").length === 0);
+      await click(".generate-invite-link");
+      assert.equal(
+        find(".invite-link-input")[0].value,
+        "http://example.com/invites/92c297e886a0ca03089a109ccd6be155"
+      );
+    },
+  });
+});
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index ed4ee4d..0e6a2b4 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -247,7 +247,6 @@ class InvitesController < ApplicationController
     raise Discourse::InvalidParameters.new(:email) if invite.blank?
     invite.resend_invite
     render json: success_json
-
   rescue RateLimiter::LimitExceeded
     render_json_error(I18n.t("rate_limiter.slow_down"))
   end
diff --git a/app/models/invite.rb b/app/models/invite.rb
index 749bb85..109b767 100644
--- a/app/models/invite.rb
+++ b/app/models/invite.rb
@@ -70,7 +70,7 @@ class Invite < ActiveRecord::Base
   end
 
   def redeemable?
-    !redeemed? && !expired? && !destroyed? && link_valid?
+    !redeemed? && !expired? && !deleted_at? && !destroyed? && link_valid?
   end
 
   def redeemed?
diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb
index bda281c..35875a3 100644
--- a/spec/models/invite_spec.rb
+++ b/spec/models/invite_spec.rb
@@ -3,537 +3,376 @@
 require 'rails_helper'
 
 describe Invite do
+  fab!(:user) { Fabricate(:user) }
 
-  it { is_expected.to validate_presence_of :invited_by_id }
+  context 'validators' do
+    it { is_expected.to validate_presence_of :invited_by_id }
+    it { is_expected.to rate_limit }
 
-  it { is_expected.to rate_limit }
-
-  let(:iceking) { 'iceking@adventuretime.ooo' }
-
-  context 'user validators' do
-    fab!(:coding_horror) { Fabricate(:coding_horror) }
-    fab!(:user) { Fabricate(:user) }
-    let(:invite) { Invite.create(email: user.email, invited_by: coding_horror) }
-
-    it "should not allow an invite with the same email as an existing user" do
-      expect(invite).not_to be_valid
-    end
-
-    it "should not allow a user to invite themselves" do
-      expect(invite.email_already_exists).to eq(true)
+    it 'allows invites with valid emails' do
+      invite = Fabricate.build(:invite, email: 'test@example.com', invited_by: user)
+      expect(invite).to be_valid
     end
-  end
-
-  context 'email validators' do
-    fab!(:coding_horror) { Fabricate(:coding_horror) }
 
-    it "should not allow an invite with unformatted email address" do
-      invite = Fabricate.build(:invite, email: "John Doe <john.doe@example.com>")
+    it 'does not allow invites with invalid emails' do
+      invite = Fabricate.build(:invite, email: 'John Doe <john.doe@example.com>')
       expect(invite.valid?).to eq(false)
-      expect(invite.errors.details[:email].first[:error]).to eq(I18n.t("user.email.invalid"))
+      expect(invite.errors.details[:email].first[:error]).to eq(I18n.t('user.email.invalid'))
     end
 
-    it "should not allow an invite with blocklisted email" do
-      invite = Invite.create(email: "test@mailinator.com", invited_by: coding_horror)
+    it 'does not allow an invite with the same email as an existing user' do
+      invite = Fabricate.build(:invite, email: Fabricate(:user).email, invited_by: user)
+      expect(invite).not_to be_valid
+
+      invite = Fabricate.build(:invite, email: user.email, invited_by: user)
       expect(invite).not_to be_valid
     end
 
-    it "should allow an invite with non-blocklisted email" do
-      invite = Fabricate(:invite, email: "test@mail.com", invited_by: coding_horror)
-      expect(invite).to be_valid
+    it 'does not allow an invite with blocked email' do
+      invite = Invite.create(email: 'test@mailinator.com', invited_by: user)
+      expect(invite).not_to be_valid
     end
 
-    it "should not allow an invalid email address" do
+    it 'does not allow an invalid email address' do
       invite = Fabricate.build(:invite, email: 'asjdso')
       expect(invite.valid?).to eq(false)
-      expect(invite.errors.details[:email].first[:error]).to eq(I18n.t("user.email.invalid"))
+      expect(invite.errors.details[:email].first[:error]).to eq(I18n.t('user.email.invalid'))
     end
   end
 
-  context '#create' do
-    context 'saved' do
-      subject { Fabricate(:invite) }
-
-      it "works" do
-        expect(subject.invite_key).to be_present

[... diff too long, it was truncated ...]

GitHub sha: dffc3a2f

This commit appears in #12524 which was approved by eviltrout and ZogStriP. It was merged by udan11.