Skip to content

Commit

Permalink
Generator specs and fixes (#56)
Browse files Browse the repository at this point in the history
* Add specs for generators
* Comment out config.auth.user_admin when --skip-account passed to install generator
* Ensure auth config is inserted before final end in trestle.rb, even when improperly indented
  • Loading branch information
spohlenz authored Sep 30, 2024
1 parent 4a6c7ee commit 0a012ef
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 6 deletions.
10 changes: 7 additions & 3 deletions lib/generators/trestle/auth/install/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def check_trestle_installed
end

def insert_configuration
inject_into_file "config/initializers/trestle.rb", before: /^end/ do
inject_into_file "config/initializers/trestle.rb", before: /end(?!.*end.*)/m do
format_configuration(template_content(configuration_template))
end
end
Expand All @@ -28,17 +28,21 @@ def generate_model
end

def generate_admin
generate "trestle:auth:admin", model, ("--devise" if devise?)
generate "trestle:auth:admin", model, *("--devise" if devise?)
end

def generate_account
generate "trestle:auth:account", model, ("--devise" if devise?) unless options[:skip_account]
generate "trestle:auth:account", model, *("--devise" if devise?) unless skip_account?
end

def devise?
options[:devise]
end

def skip_account?
options[:skip_account]
end

def configuration_template
devise? ? "devise.rb.erb" : "basic.rb.erb"
end
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/trestle/auth/install/templates/basic.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ config.auth.user_class = -> { <%= model %> }

# Specify the Trestle admin for managing the current user (My Account).
#
config.auth.user_admin = -> { :"auth/account" }
<% if skip_account? %># <% end %>config.auth.user_admin = -> { :"auth/account" }

# Specify the parameter (along with a password) to be used to
# authenticate an administrator. Defaults to :email.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ config.auth.user_class = -> { <%= model %> }

# Specify the Trestle admin for managing the current user (My Account).
#
config.auth.user_admin = -> { :"auth/account" }
<% if skip_account? %># <% end %>config.auth.user_admin = -> { :"auth/account" }

# Specify the parameter (along with a password) to be used to
# authenticate an administrator. Defaults to :email if not specified below.
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/trestle/auth/model/model_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class ModelGenerator < ::Rails::Generators::Base
argument :name, type: :string, default: "Administrator"

def create_model
generate "model", "#{name} email:string password_digest:string first_name:string last_name:string remember_token:string remember_token_expires_at:datetime"
generate "model", name, "email:string password_digest:string first_name:string last_name:string remember_token:string remember_token_expires_at:datetime"
end

def inject_model_methods
Expand Down
47 changes: 47 additions & 0 deletions spec/generators/account_generator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require "spec_helper"

require "generators/trestle/auth/account/account_generator"

describe Trestle::Auth::Generators::AccountGenerator, type: :generator do
destination File.expand_path("../../../tmp", __FILE__)

before do
prepare_destination
end

context "for a regular user model" do
describe "the generated files" do
before do
run_generator
end

describe "the admin resource" do
subject { file("app/admin/auth/account_admin.rb") }

it { is_expected.to exist }
it { is_expected.to have_correct_syntax }
it { is_expected.to contain "Trestle.resource(:account, model: Administrator, scope: Auth, singular: true) do" }
it { is_expected.to contain "params.require(:account).permit(:email, :first_name, :last_name, :password, :password_confirmation)" }
it { is_expected.not_to contain "if Devise.sign_in_after_reset_password" }
end
end
end

context "for a Devise user model" do
describe "the generated files" do
before do
run_generator %w(User --devise)
end

describe "the admin resource" do
subject { file("app/admin/auth/account_admin.rb") }

it { is_expected.to exist }
it { is_expected.to have_correct_syntax }
it { is_expected.to contain "Trestle.resource(:account, model: User, scope: Auth, singular: true) do" }
it { is_expected.to contain "params.require(:account).permit(:email, :password, :password_confirmation)" }
it { is_expected.to contain "if Devise.sign_in_after_reset_password" }
end
end
end
end
45 changes: 45 additions & 0 deletions spec/generators/admin_generator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require "spec_helper"

require "generators/trestle/auth/admin/admin_generator"

describe Trestle::Auth::Generators::AdminGenerator, type: :generator do
destination File.expand_path("../../../tmp", __FILE__)

before do
prepare_destination
end

context "for a regular user model" do
describe "the generated files" do
before do
run_generator
end

describe "the admin resource" do
subject { file("app/admin/auth/administrators_admin.rb") }

it { is_expected.to exist }
it { is_expected.to have_correct_syntax }
it { is_expected.to contain "Trestle.resource(:administrators, model: Administrator, scope: Auth) do" }
it { is_expected.not_to contain "if Devise.sign_in_after_reset_password" }
end
end
end

context "for a Devise user model" do
describe "the generated files" do
before do
run_generator %w(User --devise)
end

describe "the admin resource" do
subject { file("app/admin/auth/users_admin.rb") }

it { is_expected.to exist }
it { is_expected.to have_correct_syntax }
it { is_expected.to contain "Trestle.resource(:users, model: User, scope: Auth) do" }
it { is_expected.to contain "if Devise.sign_in_after_reset_password" }
end
end
end
end
160 changes: 160 additions & 0 deletions spec/generators/install_generator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
require "spec_helper"

require "generators/trestle/auth/install/install_generator"

describe Trestle::Auth::Generators::InstallGenerator, type: :generator do
destination File.expand_path("../../../tmp", __FILE__)

let(:generator_params) { [] }

before do
prepare_destination

allow(generator(generator_params)).to receive(:generate)
stub_file "config/initializers/trestle.rb", configuration
end

let(:configuration) do
<<~EOF
Trestle.configure do |config|
end
EOF
end

context "regular mode" do
it "generates a model" do
expect(generator(generator_params)).to receive(:generate).with("trestle:auth:model", "Administrator")
run_generator generator_params
end

it "generates an admin resource" do
expect(generator(generator_params)).to receive(:generate).with("trestle:auth:admin", "Administrator")
run_generator generator_params
end

it "generates an account resource" do
expect(generator(generator_params)).to receive(:generate).with("trestle:auth:account", "Administrator")
run_generator generator_params
end

context "when --skip-account is passed" do
let(:generator_params) { %w(--skip-account) }

it "does not generate an account resource" do
expect(generator(generator_params)).not_to receive(:generate).with("trestle:auth:account", "Administrator")
run_generator generator_params
end

describe "the generated files" do
before do
run_generator generator_params
end

describe "the Trestle configuration" do
subject { file("config/initializers/trestle.rb") }

it { is_expected.to contain "# config.auth.user_admin = -> { :\"auth/account\" }" }
end
end
end

describe "the generated files" do
before do
run_generator generator_params
end

describe "the Trestle configuration" do
subject { file("config/initializers/trestle.rb") }

it { is_expected.to exist }
it { is_expected.to have_correct_syntax }
it { is_expected.to contain "config.auth.user_class = -> { Administrator }" }
it { is_expected.to contain "config.auth.user_admin = -> { :\"auth/account\" }" }
it { is_expected.not_to contain "config.auth.backend = :devise" }
end
end
end

context "Devise mode (--devise)" do
let(:generator_params) { %w(User --devise) }

it "does not generate a model" do
expect(generator(generator_params)).not_to receive(:generate).with("trestle:auth:model", "User")
run_generator generator_params
end

it "generates an admin resource" do
expect(generator(generator_params)).to receive(:generate).with("trestle:auth:admin", "User", "--devise")
run_generator generator_params
end

it "generates an account resource" do
expect(generator(generator_params)).to receive(:generate).with("trestle:auth:account", "User", "--devise")
run_generator generator_params
end

context "when --skip-account is passed" do
let(:generator_params) { %w(User --devise --skip-account) }

it "does not generate an account resource" do
expect(generator(generator_params)).not_to receive(:generate).with("trestle:auth:account", "User", "--devise")
run_generator generator_params
end

describe "the generated files" do
before do
run_generator generator_params
end

describe "the Trestle configuration" do
subject { file("config/initializers/trestle.rb") }

it { is_expected.to contain "# config.auth.user_admin = -> { :\"auth/account\" }" }
end
end
end

describe "the generated files" do
before do
run_generator generator_params
end

describe "the Trestle configuration" do
subject { file("config/initializers/trestle.rb") }

it { is_expected.to exist }
it { is_expected.to have_correct_syntax }
it { is_expected.to contain "config.auth.backend = :devise" }
it { is_expected.to contain "config.auth.warden.scope = :user" }
it { is_expected.to contain "config.auth.user_class = -> { User }" }
it { is_expected.to contain "config.auth.user_admin = -> { :\"auth/account\" }" }
it { is_expected.to contain "config.auth.authenticate_with = -> { Devise.authentication_keys.first }" }
end
end
end

context "when the existing Trestle configuration is improperly indented" do
let(:configuration) do
<<~EOF
Trestle.configure do |config|
config.menu do
end
end
EOF
end

describe "the generated files" do
before do
run_generator generator_params
end

describe "the Trestle configuration" do
subject { file("config/initializers/trestle.rb") }

it { is_expected.to have_correct_syntax }
it { is_expected.to contain "# == Authentication Options" }
it { is_expected.not_to contain /config.menu do\n\s*# == Authentication Options/ }
end
end
end
end
37 changes: 37 additions & 0 deletions spec/generators/model_generator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require "spec_helper"

require "generators/trestle/auth/model/model_generator"

describe Trestle::Auth::Generators::ModelGenerator, type: :generator do
destination File.expand_path("../../../tmp", __FILE__)

before do
prepare_destination
end

it "generates an ActiveRecord model with the default name" do
expect(generator).to receive(:generate).with("model", "Administrator", "email:string password_digest:string first_name:string last_name:string remember_token:string remember_token_expires_at:datetime") { stub_model_file }
run_generator
end

it "generates an ActiveRecord model with the specified name" do
expect(generator(%w(TrestleAdmin))).to receive(:generate).with("model", "TrestleAdmin", "email:string password_digest:string first_name:string last_name:string remember_token:string remember_token_expires_at:datetime") { stub_model_file("TrestleAdmin") }
run_generator %w(TrestleAdmin)
end

describe "the generated files" do
before do
allow(generator).to receive(:generate) { stub_model_file }
run_generator
end

describe "the model" do
subject { file("app/models/administrator.rb") }

it { is_expected.to exist }
it { is_expected.to have_correct_syntax }
it { is_expected.to contain "include Trestle::Auth::ModelMethods" }
it { is_expected.to contain "include Trestle::Auth::ModelMethods::Rememberable" }
end
end
end
2 changes: 2 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'rspec/rails'
require 'show_me_the_cookies'
require 'timecop'
require 'ammeter/init'

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
Expand Down Expand Up @@ -46,4 +47,5 @@

config.include ShowMeTheCookies, type: :feature
config.include Trestle::Auth::Test::LoginHelpers, type: :feature
config.include Trestle::Auth::Test::GeneratorHelpers, type: :generator
end
21 changes: 21 additions & 0 deletions spec/support/generator_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Trestle
module Auth
module Test
module GeneratorHelpers
def stub_model_file(name="Administrator")
stub_file "app/models/#{name.underscore}.rb", <<~EOF
class #{name} < ApplicationRecord
end
EOF
end

def stub_file(path, contents)
filepath = file(path)

FileUtils.mkdir_p(filepath.dirname)
File.open(filepath, "w") { |f| f.write(contents) }
end
end
end
end
end
1 change: 1 addition & 0 deletions trestle-auth.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rspec-rails"
spec.add_development_dependency "show_me_the_cookies", "~> 6.0"
spec.add_development_dependency "timecop", "~> 0.9.1"
spec.add_development_dependency "ammeter", "~> 1.1.7"
end

0 comments on commit 0a012ef

Please sign in to comment.