Commit iniziale di eminuxCRM: CRM Rails con pipeline, campagne email e Docker.
CI / scan_ruby (push) Failing after 11m20s
CI / scan_js (push) Successful in 10m35s
CI / lint (push) Has been cancelled

Include autenticazione, progetti isolati, mail marketing HTML con SMTP, test A/B e editor WYSIWYG.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-17 23:01:48 +02:00
co-authored by Cursor
commit c4e5f289cf
258 changed files with 11293 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
require "test_helper"
class DashboardMetricsTest < ActiveSupport::TestCase
test "computes stage counts and pipeline value" do
metrics = Dashboard::Metrics.new
assert metrics.stage_counts.key?("interested")
assert_kind_of Numeric, metrics.open_pipeline_value
assert_kind_of Array, metrics.funnel_steps
end
test "goal progress" do
goal = sales_goals(:september)
assert_equal 0, goal.current_value
assert_equal 0, goal.progress_percentage
end
end
+35
View File
@@ -0,0 +1,35 @@
require "test_helper"
class OpportunityTest < ActiveSupport::TestCase
setup do
@opp = opportunities(:deal)
@user = users(:marco)
Current.user = @user
Current.project = projects(:matchlivetv)
end
teardown do
Current.user = nil
Current.project = nil
end
test "move to won sets won_at and activates customer" do
@opp.move_to_stage!("won", user: @user)
assert @opp.won?
assert_not_nil @opp.won_at
assert_equal "active_customer", @opp.organization.reload.status
end
test "move to lost requires reason" do
assert_raises(ActiveRecord::RecordInvalid) do
@opp.move_to_stage!("lost", user: @user)
end
end
test "move to lost with reason" do
@opp.move_to_stage!("lost", lost_reason: "price", user: @user)
assert @opp.lost?
assert_equal "price", @opp.lost_reason
assert_not_nil @opp.lost_at
end
end
+16
View File
@@ -0,0 +1,16 @@
require "test_helper"
class OrganizationTest < ActiveSupport::TestCase
test "requires name" do
org = Organization.new(status: "prospect", organization_type: "azienda")
assert_not org.valid?
assert_includes org.errors[:name], "non può essere vuoto"
end
test "has associations" do
org = organizations(:acme)
assert_includes org.contacts, contacts(:primary)
assert_includes org.opportunities, opportunities(:deal)
assert_includes org.tasks, tasks(:follow_up)
end
end
+21
View File
@@ -0,0 +1,21 @@
require "test_helper"
class ProjectAccessTest < ActiveSupport::TestCase
test "admin can access all projects" do
admin = users(:admin)
assert admin.can_access_project?(projects(:matchlivetv))
assert admin.can_access_project?(projects(:riskmeter))
assert_equal Project.active.count, admin.accessible_projects.count
end
test "user only accesses enabled projects" do
marco = users(:marco)
assert marco.can_access_project?(projects(:matchlivetv))
assert_not marco.can_access_project?(projects(:riskmeter))
end
test "organization scoped to project" do
assert_includes Organization.for_project(projects(:matchlivetv)), organizations(:acme)
assert_not_includes Organization.for_project(projects(:riskmeter)), organizations(:acme)
end
end
+19
View File
@@ -0,0 +1,19 @@
require "test_helper"
class TaskTest < ActiveSupport::TestCase
setup do
@task = tasks(:follow_up)
@user = users(:marco)
Current.user = @user
end
teardown { Current.user = nil }
test "complete creates activity" do
assert_difference -> { Activity.count }, 1 do
assert @task.complete!(user: @user)
end
assert @task.completed?
assert_not_nil @task.completed_at
end
end
+51
View File
@@ -0,0 +1,51 @@
require "test_helper"
class UserManagementTest < ActiveSupport::TestCase
test "cannot deactivate the last active admin" do
admin = users(:admin)
assert admin.last_active_admin?
assert_not admin.can_be_deactivated?
admin.active = false
assert_not admin.valid?
assert_includes admin.errors[:base].join, "almeno un amministratore attivo"
end
test "cannot demote the last active admin" do
admin = users(:admin)
admin.role = "user"
assert_not admin.valid?
assert_includes admin.errors[:base].join, "almeno un amministratore attivo"
end
test "can deactivate seed admin when another admin exists" do
other = User.create!(
email: "second-admin@example.com",
first_name: "Second",
last_name: "Admin",
role: "admin",
password: "password123",
password_confirmation: "password123",
active: true
)
admin = users(:admin)
assert_not admin.last_active_admin?
assert admin.can_be_deactivated?
assert admin.update(active: false)
assert_not admin.reload.active?
assert other.reload.active?
end
test "cannot destroy the last active admin" do
admin = users(:admin)
assert_not admin.destroy
assert admin.errors[:base].join.include?("unico amministratore attivo") || User.exists?(admin.id)
end
test "can destroy a regular user" do
marco = users(:marco)
assert marco.destroy
assert_not User.exists?(marco.id)
end
end