# frozen_string_literal: true require "stringio" RSpec.describe "Resources" do let(:client) { Fiken::Client.new(token: "t") } let(:slug) { "acme" } describe Fiken::Resources::Contacts do it "lists, finds, creates (via Location), updates with PUT and deletes" do stub_fiken(:get, "/companies/acme/contacts", body: [{ "contactId" => 1, "name" => "A" }]) stub_fiken(:get, "/companies/acme/contacts/1", body: { "contactId" => 1, "name" => "A" }) stub_created(:post, "/companies/acme/contacts", to: "/companies/acme/contacts/9") stub_fiken(:put, "/companies/acme/contacts/1", body: { "contactId" => 1, "name" => "B" }) stub_fiken(:delete, "/companies/acme/contacts/1", status: 204) contacts = client.contacts(slug) expect(contacts.list.map(&:name)).to eq(["A"]) expect(contacts.find(1).name).to eq("A") expect(contacts.create(name: "New").id).to eq("9") expect(contacts.update(1, name: "B").name).to eq("B") expect(contacts.delete(1)).to be(true) expect(a_request(:put, "#{API_BASE}/companies/acme/contacts/1") .with(body: { name: "B" })).to have_been_made end it "uploads an attachment as multipart" do stub_fiken(:post, "/companies/acme/contacts/1/attachments", status: 201) client.contacts(slug).attachments(1).add(io: StringIO.new("PDF"), filename: "f.pdf") expect(a_request(:post, "#{API_BASE}/companies/acme/contacts/1/attachments") .with(headers: { "Content-Type" => %r{multipart/form-data} })).to have_been_made end it "reaches contact persons under a contact" do stub_fiken(:get, "/companies/acme/contacts/1/contactPerson", body: [{ "contactPersonId" => 7 }]) expect(client.contacts(slug).contact_persons(1).list.first.contact_person_id).to eq(7) end end describe Fiken::Resources::Invoices do let(:invoices) { client.invoices(slug) } it "updates a finalized invoice with PATCH" do stub_fiken(:patch, "/companies/acme/invoices/5", body: { "invoiceId" => 5 }) invoices.update(5, sentManually: true) expect(a_request(:patch, "#{API_BASE}/companies/acme/invoices/5")).to have_been_made end it "sends an invoice via dispatch" do stub_fiken(:post, "/companies/acme/invoices/send", status: 200, body: { "success" => true }) invoices.dispatch(invoiceId: 5, method: ["email"]) expect(a_request(:post, "#{API_BASE}/companies/acme/invoices/send")).to have_been_made end it "reads and sets the counter" do stub_fiken(:get, "/companies/acme/invoices/counter", body: { "value" => 100 }) stub_fiken(:post, "/companies/acme/invoices/counter", status: 201) expect(invoices.counter.value).to eq(100) invoices.create_counter(value: 1000) expect(a_request(:post, "#{API_BASE}/companies/acme/invoices/counter")).to have_been_made end it "creates a draft then finalizes it into an invoice" do stub_created(:post, "/companies/acme/invoices/drafts", to: "/companies/acme/invoices/drafts/3") stub_created(:post, "/companies/acme/invoices/drafts/3/createInvoice", to: "/companies/acme/invoices/77") draft = invoices.drafts.create(type: "invoice") expect(draft.id).to eq("3") expect(invoices.drafts.create_document(3).id).to eq("77") end end describe Fiken::Resources::Sales do let(:sales) { client.sales(slug) } it "settles, writes off and deletes via PATCH sub-paths" do stub_fiken(:patch, "/companies/acme/sales/5/settled", body: { "saleId" => 5 }) stub_fiken(:patch, "/companies/acme/sales/5/writeOff", body: { "saleId" => 5 }) stub_fiken(:patch, "/companies/acme/sales/5/delete", status: 200) sales.settle(5, settledDate: "2026-01-01") sales.write_off(5) expect(sales.delete(5)).to be(true) expect(a_request(:patch, "#{API_BASE}/companies/acme/sales/5/writeOff")).to have_been_made end it "creates a payment on a sale" do stub_created(:post, "/companies/acme/sales/5/payments", to: "/companies/acme/sales/5/payments/2") expect(client.sales(slug).payments(5).create(amount: 100).id).to eq("2") end end describe Fiken::Resources::Transactions do it "deletes via PATCH /{id}/delete" do stub_fiken(:patch, "/companies/acme/transactions/8/delete", status: 200) expect(client.transactions(slug).delete(8, description: "oops")).to be(true) end end describe Fiken::Resources::JournalEntries do it "creates a general journal entry on the sibling path" do stub_created(:post, "/companies/acme/generalJournalEntries", to: "/companies/acme/journalEntries/4") expect(client.journal_entries(slug).create_general(description: "x").id).to eq("4") end end describe Fiken::Resources::Products do it "requests a sales report" do stub_fiken(:post, "/companies/acme/products/salesReport", body: [{ "product" => { "name" => "Widget" } }]) report = client.products(slug).sales_report(from: "2026-01-01", to: "2026-01-31") expect(report.first.product.name).to eq("Widget") end end end