Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,31 @@ struct InvoiceSendEmailCommand: MutatingCommand {
@Option(name: .long, help: "Email subject")
var subject: String?

@Option(
name: .customLong("attachment"),
help: "Path to a file to attach (pdf, png, jpg, jpeg or gif), up to 5MB. Repeat for multiple files."
)
var attachments = [String]()

@Flag(help: "Print the request instead of sending it")
var dryRun = false

func perform(client: Client) async throws -> EmptyResponse {
let attachmentPayloads = try attachments.map { path in
let file = try AttachmentFile(path: path)
return Components.Schemas.EmailAttachmentPayload(
data: file.data,
fileName: file.fileName,
contentType: file.contentType
)
}

let emailPayload = Components.Schemas.EmailPayload(
body: body,
from: from,
subject: subject,
to: to
to: to,
attachments: attachmentPayloads.isEmpty ? nil : attachmentPayloads
)

let invoicePayload = Operations.SendInvoiceEmail.Input.Body.JsonPayload.InvoicePayload(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation
import FreeAgentAPI
import Mockable
import Testing

@testable import FreeAgentCLI

struct InvoiceSendEmailCommandTests {
@Test("refuses an unsupported attachment without sending the email")
func unsupportedAttachment() async throws {
let path = FileManager.default.temporaryDirectory.appendingPathComponent("\(UUID().uuidString).txt").path
try Data("timesheet".utf8).write(to: URL(fileURLWithPath: path))

let transport = MockClientTransportInterface()
let client = Client(serverURL: Environment.sandbox.baseURL, transport: transport)
let command = try InvoiceSendEmailCommand.parse(["1234", "--to", "alice@example.com", "--attachment", path])

await #expect(throws: AttachmentFileError.self) {
try await command.perform(client: client)
}

verify(transport).send(.any, body: .any, baseURL: .any, operationID: .value("sendInvoiceEmail")).called(0)
}
}
17 changes: 17 additions & 0 deletions openapi/components/schemas/EmailAttachmentPayload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
type: object
required:
- data
- file_name
- content_type
properties:
data:
type: string
description: Binary data of the file encoded as base64
example: iVBORw0KGgo...
file_name:
type: string
example: timesheet.pdf
content_type:
type: string
description: Required, but ignored - FreeAgent detects the type from the data
example: application/pdf
7 changes: 6 additions & 1 deletion openapi/components/schemas/EmailPayload.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ properties:
example: Testing
to:
type: string
example: Test Contact <test_contact@example.com>
example: test_contact@example.com
attachments:
type: array
description: Files of up to 5MB each
items:
$ref: '#/components/schemas/EmailAttachmentPayload'
2 changes: 2 additions & 0 deletions openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ components:
$ref: 'components/schemas/InvoiceUpdatePayload.yaml'
EmailPayload:
$ref: 'components/schemas/EmailPayload.yaml'
EmailAttachmentPayload:
$ref: 'components/schemas/EmailAttachmentPayload.yaml'
TokenRequest:
$ref: 'components/schemas/TokenRequest.yaml'
AuthorizationCodeGrant:
Expand Down
2 changes: 1 addition & 1 deletion openapi/paths/credit_notes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ send_email:
body: Please find our credit note attached
from: Our Company <us@company.com>
subject: Credit Note
to: Test Contact <test_contact@example.com>
to: test_contact@example.com
responses:
'200':
description: Success
Expand Down
2 changes: 1 addition & 1 deletion openapi/paths/estimates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ send_email:
body: Please find our estimate attached
from: Our Company <us@company.com>
subject: Estimate
to: Test Contact <test_contact@example.com>
to: test_contact@example.com
responses:
'200':
description: Success
Expand Down
2 changes: 1 addition & 1 deletion openapi/paths/invoices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ send_email:
body: Bison bison bison bison bison Bison bison
from: Our Company <us@company.com>
subject: Testing
to: Test Contact <test_contact@example.com>
to: test_contact@example.com
responses:
'200':
description: Success
Expand Down
Loading