|
58 | 58 | end |
59 | 59 | end |
60 | 60 |
|
| 61 | + describe "checklist functionality" do |
| 62 | + let(:company) { create(:company, :without_bank_account) } |
| 63 | + |
| 64 | + describe "#checklist_items" do |
| 65 | + context "for company administrators" do |
| 66 | + let(:company) { create(:company, :pre_onboarding) } |
| 67 | + let(:admin) { create(:company_administrator, company: company) } |
| 68 | + |
| 69 | + it "returns admin checklist items with completion status" do |
| 70 | + items = company.checklist_items(admin) |
| 71 | + |
| 72 | + expect(items).to have_attributes(size: 4) |
| 73 | + expect(items.map { |item| item[:key] }).to contain_exactly( |
| 74 | + "add_company_details", "add_bank_account", "invite_contractor", "send_first_payment" |
| 75 | + ) |
| 76 | + expect(items.all? { |item| item[:completed] == false }).to be true |
| 77 | + end |
| 78 | + |
| 79 | + it "completes company details item when company name is present" do |
| 80 | + items = company.checklist_items(admin) |
| 81 | + company_details_item = items.find { |item| item[:key] == "add_company_details" } |
| 82 | + expect(company_details_item[:completed]).to be false |
| 83 | + |
| 84 | + company.update!(name: "Test Company") |
| 85 | + items = company.reload.checklist_items(admin) |
| 86 | + company_details_item = items.find { |item| item[:key] == "add_company_details" } |
| 87 | + expect(company_details_item[:completed]).to be true |
| 88 | + end |
| 89 | + |
| 90 | + it "completes bank account item when stripe account becomes ready" do |
| 91 | + items = company.checklist_items(admin) |
| 92 | + bank_account_item = items.find { |item| item[:key] == "add_bank_account" } |
| 93 | + expect(bank_account_item[:completed]).to be false |
| 94 | + |
| 95 | + stripe_account = create(:company_stripe_account, company: company, status: "processing") |
| 96 | + items = company.reload.checklist_items(admin) |
| 97 | + bank_account_item = items.find { |item| item[:key] == "add_bank_account" } |
| 98 | + expect(bank_account_item[:completed]).to be false |
| 99 | + |
| 100 | + stripe_account.update!(status: "ready") |
| 101 | + items = company.reload.checklist_items(admin) |
| 102 | + bank_account_item = items.find { |item| item[:key] == "add_bank_account" } |
| 103 | + expect(bank_account_item[:completed]).to be true |
| 104 | + end |
| 105 | + |
| 106 | + it "completes contractor item when worker is created" do |
| 107 | + items = company.checklist_items(admin) |
| 108 | + contractor_item = items.find { |item| item[:key] == "invite_contractor" } |
| 109 | + expect(contractor_item[:completed]).to be false |
| 110 | + |
| 111 | + create(:company_worker, company: company, user: create(:user)) |
| 112 | + items = company.reload.checklist_items(admin) |
| 113 | + contractor_item = items.find { |item| item[:key] == "invite_contractor" } |
| 114 | + expect(contractor_item[:completed]).to be true |
| 115 | + end |
| 116 | + |
| 117 | + it "completes payment item when payment succeeds" do |
| 118 | + items = company.checklist_items(admin) |
| 119 | + payment_item = items.find { |item| item[:key] == "send_first_payment" } |
| 120 | + expect(payment_item[:completed]).to be false |
| 121 | + |
| 122 | + contractor = create(:company_worker, company: company) |
| 123 | + company.update!(name: "Test Company") |
| 124 | + invoice = create(:invoice, company: company, company_worker: contractor, user: contractor.user) |
| 125 | + items = company.reload.checklist_items(admin) |
| 126 | + payment_item = items.find { |item| item[:key] == "send_first_payment" } |
| 127 | + expect(payment_item[:completed]).to be false |
| 128 | + |
| 129 | + invoice.update!(status: Invoice::PAID) |
| 130 | + items = company.reload.checklist_items(admin) |
| 131 | + payment_item = items.find { |item| item[:key] == "send_first_payment" } |
| 132 | + expect(payment_item[:completed]).to be true |
| 133 | + end |
| 134 | + |
| 135 | + it "marks all admin items as completed when conditions are met" do |
| 136 | + company.update!(name: "Test Company") |
| 137 | + create(:company_stripe_account, company: company, status: "ready") |
| 138 | + contractor = create(:company_worker, company: company) |
| 139 | + invoice = create(:invoice, company: company, company_worker: contractor, user: contractor.user) |
| 140 | + invoice.update!(status: Invoice::PAID) |
| 141 | + company.reload |
| 142 | + |
| 143 | + items = company.checklist_items(admin) |
| 144 | + expect(items.all? { |item| item[:completed] }).to be true |
| 145 | + end |
| 146 | + end |
| 147 | + |
| 148 | + context "for company workers" do |
| 149 | + let(:worker) { create(:company_worker, without_contract: true, company: company, user: create(:user, without_bank_account: true)) } |
| 150 | + |
| 151 | + it "returns worker checklist items with completion status" do |
| 152 | + items = company.checklist_items(worker) |
| 153 | + |
| 154 | + expect(items).to have_attributes(size: 3) |
| 155 | + expect(items.map { |item| item[:key] }).to contain_exactly( |
| 156 | + "fill_tax_information", "add_payout_information", "sign_contract" |
| 157 | + ) |
| 158 | + expect(items.all? { |item| item[:completed] == false }).to be true |
| 159 | + end |
| 160 | + |
| 161 | + it "completes tax information item when worker confirms tax details" do |
| 162 | + items = company.checklist_items(worker) |
| 163 | + tax_item = items.find { |item| item[:key] == "fill_tax_information" } |
| 164 | + expect(tax_item[:completed]).to be false |
| 165 | + |
| 166 | + worker.user.compliance_info.update!(tax_information_confirmed_at: Time.current) |
| 167 | + |
| 168 | + items = company.checklist_items(worker) |
| 169 | + tax_item = items.find { |item| item[:key] == "fill_tax_information" } |
| 170 | + expect(tax_item[:completed]).to be true |
| 171 | + end |
| 172 | + |
| 173 | + it "completes payout information item when worker adds bank account" do |
| 174 | + items = company.checklist_items(worker) |
| 175 | + payout_item = items.find { |item| item[:key] == "add_payout_information" } |
| 176 | + expect(payout_item[:completed]).to be false |
| 177 | + |
| 178 | + create(:wise_recipient, user: worker.user, used_for_invoices: true) |
| 179 | + worker.user.reload |
| 180 | + |
| 181 | + items = company.checklist_items(worker) |
| 182 | + payout_item = items.find { |item| item[:key] == "add_payout_information" } |
| 183 | + expect(payout_item[:completed]).to be true |
| 184 | + end |
| 185 | + |
| 186 | + it "completes contract item when worker signs contract" do |
| 187 | + items = company.checklist_items(worker) |
| 188 | + contract_item = items.find { |item| item[:key] == "sign_contract" } |
| 189 | + expect(contract_item[:completed]).to be false |
| 190 | + |
| 191 | + create(:document, company: company, document_type: :consulting_contract, signatories: [worker.user]) |
| 192 | + |
| 193 | + items = company.checklist_items(worker) |
| 194 | + contract_item = items.find { |item| item[:key] == "sign_contract" } |
| 195 | + expect(contract_item[:completed]).to be true |
| 196 | + end |
| 197 | + end |
| 198 | + |
| 199 | + context "for other user types" do |
| 200 | + let(:other_user) { create(:user) } |
| 201 | + |
| 202 | + it "returns empty array for non-company users" do |
| 203 | + items = company.checklist_items(other_user) |
| 204 | + expect(items).to be_empty |
| 205 | + end |
| 206 | + end |
| 207 | + end |
| 208 | + |
| 209 | + describe "#checklist_completion_percentage" do |
| 210 | + context "for company administrators" do |
| 211 | + let(:company) { create(:company, :pre_onboarding) } |
| 212 | + let(:admin) { create(:company_administrator, company: company) } |
| 213 | + |
| 214 | + it "returns 0 when no items are completed" do |
| 215 | + expect(company.checklist_completion_percentage(admin)).to eq(0) |
| 216 | + end |
| 217 | + |
| 218 | + it "returns correct percentage when some items are completed" do |
| 219 | + create(:company_stripe_account, company: company, status: "ready") |
| 220 | + company.reload |
| 221 | + expect(company.checklist_completion_percentage(admin)).to eq(25) |
| 222 | + end |
| 223 | + |
| 224 | + it "returns 100 when all items are completed" do |
| 225 | + company.update!(name: "Test Company") |
| 226 | + create(:company_stripe_account, company: company, status: "ready") |
| 227 | + contractor = create(:company_worker, company: company) |
| 228 | + invoice = create(:invoice, company: company, user: contractor.user) |
| 229 | + invoice.update!(status: Invoice::PAID) |
| 230 | + company.reload |
| 231 | + |
| 232 | + expect(company.checklist_completion_percentage(admin)).to eq(100) |
| 233 | + end |
| 234 | + end |
| 235 | + |
| 236 | + context "for company workers" do |
| 237 | + let(:worker) { create(:company_worker, without_contract: true, company: company, user: create(:user, without_bank_account: true)) } |
| 238 | + |
| 239 | + it "returns 0 when no items are completed" do |
| 240 | + expect(company.checklist_completion_percentage(worker)).to eq(0) |
| 241 | + end |
| 242 | + |
| 243 | + it "returns correct percentage when some items are completed" do |
| 244 | + worker.user.compliance_info.update!(tax_information_confirmed_at: Time.current) |
| 245 | + |
| 246 | + expect(company.checklist_completion_percentage(worker)).to eq(33) |
| 247 | + end |
| 248 | + |
| 249 | + it "returns 100 when all worker items are completed" do |
| 250 | + worker.user.compliance_info.update!(tax_information_confirmed_at: Time.current) |
| 251 | + create(:wise_recipient, user: worker.user, used_for_invoices: true) |
| 252 | + create(:document, company: company, document_type: :consulting_contract, signatories: [worker.user]) |
| 253 | + |
| 254 | + expect(company.checklist_completion_percentage(worker)).to eq(100) |
| 255 | + end |
| 256 | + end |
| 257 | + |
| 258 | + context "for other user types" do |
| 259 | + let(:other_user) { create(:user) } |
| 260 | + |
| 261 | + it "returns 0 for non-company users" do |
| 262 | + expect(company.checklist_completion_percentage(other_user)).to eq(0) |
| 263 | + end |
| 264 | + end |
| 265 | + end |
| 266 | + end |
| 267 | + |
61 | 268 | describe "validations" do |
62 | 269 | it { is_expected.to validate_presence_of(:email) } |
63 | 270 | it { is_expected.to validate_presence_of(:country_code) } |
|
0 commit comments