Module: Organizations::TestHelpers

Defined in:
lib/organizations/test_helpers.rb

Overview

Test helpers for Minitest. Include in your test helper to get organization-related test utilities.

Examples:

Include in test_helper.rb

require "organizations/test_helpers"

class ActiveSupport::TestCase
  include Organizations::TestHelpers
end

Using in tests

test "admin can invite members" do
  (@user, @org, role: :admin)
  post invitations_path, params: { email: "new@example.com" }
  assert_response :success
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.issue_verification_code(join_request, code: "424242") ⇒ String

Force a KNOWN verification code onto a join request's active challenge, so tests can complete the emailed-code flow without intercepting mail.

The database only ever stores a digest (SHA-256, peppered by row id) — before this helper, every host test suite reverse-engineered that recipe by hand (overwriting verification_code_digest with digest_verification_code). That's gem INTERNALS leaking into host tests; use this instead:

request.start_email_verification!(email: "j.doe@acme.com")
code = issue_verification_code(request)   # => "424242"
request.verify_email_code!(code)          # => Membership

Also callable WITHOUT including the module — Organizations::TestHelpers.issue_verification_code(request) — for suites whose own factory names (create_user, …) would collide with this module's (a real host hit exactly that).

Parameters:

  • join_request (Organizations::JoinRequest)

    with a challenge started

  • code (String) (defaults to: "424242")

    the plaintext code to force (default "424242")

Returns:

  • (String)

    the plaintext code, for typing into the flow



150
151
152
153
154
155
# File 'lib/organizations/test_helpers.rb', line 150

def issue_verification_code(join_request, code: "424242")
  join_request.update!(
    verification_code_digest: Organizations::JoinRequest.digest_verification_code(code, join_request.id)
  )
  code
end

Instance Method Details

#assert_member_of(user, org) ⇒ Object

Assert that a user is a member of an organization

Parameters:



164
165
166
# File 'lib/organizations/test_helpers.rb', line 164

def assert_member_of(user, org)
  assert user.is_member_of?(org), "Expected #{user.email} to be a member of #{org.name}"
end

#assert_permission(user, permission) ⇒ Object

Assert that a user has a specific permission

Parameters:

  • user (User)

    The user

  • permission (Symbol)

    The permission



188
189
190
191
# File 'lib/organizations/test_helpers.rb', line 188

def assert_permission(user, permission)
  assert user.has_organization_permission_to?(permission),
         "Expected #{user.email} to have permission #{permission}"
end

#assert_role(user, role, in: nil) ⇒ Object

Assert that a user has a specific role in an organization

Parameters:



179
180
181
182
183
# File 'lib/organizations/test_helpers.rb', line 179

def assert_role(user, role, in: nil)
  org = binding.local_variable_get(:in)
  actual_role = user.role_in(org)
  assert_equal role.to_sym, actual_role, "Expected #{user.email} to have role #{role} in #{org.name}, got #{actual_role}"
end

#clear_current_organizationObject

Clear the current organization from session/context



36
37
38
39
40
41
42
43
44
# File 'lib/organizations/test_helpers.rb', line 36

def clear_current_organization
  if respond_to?(:session)
    session.delete(Organizations.configuration.session_key)
  end

  if defined?(Current) && Current.respond_to?(:organization=)
    Current.organization = nil
  end
end

#create_invitation(org:, email:, invited_by:, role: :member) ⇒ Organizations::Invitation

Create a test invitation

Parameters:

  • org (Organizations::Organization)

    The organization

  • email (String)

    Email to invite

  • invited_by (User)

    Who is inviting

  • role (Symbol) (defaults to: :member)

    Role for the invitation

Returns:



96
97
98
99
100
101
102
103
104
105
# File 'lib/organizations/test_helpers.rb', line 96

def create_invitation(org:, email:, invited_by:, role: :member)
  Organizations::Invitation.create!(
    organization: org,
    email: email,
    invited_by: invited_by,
    role: role.to_s,
    token: SecureRandom.urlsafe_base64(32),
    expires_at: 7.days.from_now
  )
end

#create_organization(name: "Test Org", owner:) ⇒ Organizations::Organization

Create a test organization with an owner

Parameters:

  • name (String) (defaults to: "Test Org")

    Organization name

  • owner (User)

    The owner user

Returns:



80
81
82
83
84
85
86
87
88
# File 'lib/organizations/test_helpers.rb', line 80

def create_organization(name: "Test Org", owner:)
  org = Organizations::Organization.create!(name: name)
  Organizations::Membership.create!(
    user: owner,
    organization: org,
    role: "owner"
  )
  org
end

#create_user(email: "user@example.com", name: "Test User", org: nil, role: :member) ⇒ User

Create a test user with optional organization membership

Parameters:

  • email (String) (defaults to: "user@example.com")

    User email

  • name (String) (defaults to: "Test User")

    User name

  • org (Organizations::Organization, nil) (defaults to: nil)

    Organization to join

  • role (Symbol) (defaults to: :member)

    Role in the organization

Returns:

  • (User)


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/organizations/test_helpers.rb', line 113

def create_user(email: "user@example.com", name: "Test User", org: nil, role: :member)
  # Respects config.user_class so hosts with a differently-named account
  # model can use this helper unchanged.
  user = Organizations.user_class.create!(email: email, name: name)

  if org
    Organizations::Membership.create!(
      user: user,
      organization: org,
      role: role.to_s
    )
  end

  user
end

#issue_verification_code(join_request, code: "424242") ⇒ String

Force a KNOWN verification code onto a join request's active challenge, so tests can complete the emailed-code flow without intercepting mail.

The database only ever stores a digest (SHA-256, peppered by row id) — before this helper, every host test suite reverse-engineered that recipe by hand (overwriting verification_code_digest with digest_verification_code). That's gem INTERNALS leaking into host tests; use this instead:

request.start_email_verification!(email: "j.doe@acme.com")
code = issue_verification_code(request)   # => "424242"
request.verify_email_code!(code)          # => Membership

Also callable WITHOUT including the module — Organizations::TestHelpers.issue_verification_code(request) — for suites whose own factory names (create_user, …) would collide with this module's (a real host hit exactly that).

Parameters:

  • join_request (Organizations::JoinRequest)

    with a challenge started

  • code (String) (defaults to: "424242")

    the plaintext code to force (default "424242")

Returns:

  • (String)

    the plaintext code, for typing into the flow



150
151
152
153
154
155
# File 'lib/organizations/test_helpers.rb', line 150

def issue_verification_code(join_request, code: "424242")
  join_request.update!(
    verification_code_digest: Organizations::JoinRequest.digest_verification_code(code, join_request.id)
  )
  code
end

#refute_member_of(user, org) ⇒ Object

Assert that a user is NOT a member of an organization

Parameters:



171
172
173
# File 'lib/organizations/test_helpers.rb', line 171

def refute_member_of(user, org)
  refute user.is_member_of?(org), "Expected #{user.email} NOT to be a member of #{org.name}"
end

#refute_permission(user, permission) ⇒ Object

Assert that a user does NOT have a specific permission

Parameters:

  • user (User)

    The user

  • permission (Symbol)

    The permission



196
197
198
199
# File 'lib/organizations/test_helpers.rb', line 196

def refute_permission(user, permission)
  refute user.has_organization_permission_to?(permission),
         "Expected #{user.email} NOT to have permission #{permission}"
end

#set_current_organization(org) ⇒ Object

Set the current organization in the session/context

Parameters:



24
25
26
27
28
29
30
31
32
33
# File 'lib/organizations/test_helpers.rb', line 24

def set_current_organization(org)
  if respond_to?(:session)
    session[Organizations.configuration.session_key] = org.id
  end

  # Also set on Current if available
  if defined?(Current) && Current.respond_to?(:organization=)
    Current.organization = org
  end
end

#sign_in_as_organization_member(user, org, role: :member) ⇒ Object

Sign in as a member of an organization with a specific role

Parameters:

  • user (User)

    The user to sign in

  • org (Organizations::Organization)

    The organization

  • role (Symbol) (defaults to: :member)

    The role (default: :member)



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/organizations/test_helpers.rb', line 50

def (user, org, role: :member)
  # Ensure membership exists with the correct role
  membership = Organizations::Membership.find_or_create_by!(
    user: user,
    organization: org
  ) do |m|
    m.role = role.to_s
  end

  # Update role if different
  membership.update!(role: role.to_s) if membership.role != role.to_s

  # Sign in the user (if Devise or similar is available)
  if respond_to?(:sign_in)
    (user)
  end

  # Set current organization
  set_current_organization(org)

  # Set on user
  user._current_organization_id = org.id if user.respond_to?(:_current_organization_id=)

  membership
end