Commit graph

9938 commits

Author SHA1 Message Date
marcin mikołajczak
681765669c Add test for avatar description
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-17 17:02:44 +02:00
marcin mikołajczak
71ef9f9519 Allow providing avatar/header descriptions
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-17 16:36:27 +02:00
feld
fcf9ad5573 Merge branch 'bugfix-truncate-remote-user-fields' into 'develop'
User: truncate remote user fields instead of rejecting

See merge request pleroma/pleroma!4220
2024-08-16 00:37:10 +00:00
marcin mikołajczak
8cd8cea3fb Fix 'Setting a marker should mark notifications as read'
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-14 19:28:11 +02:00
Haelwenn (lanodan) Monnier
3b1e6ac8f0
User: truncate remote user fields instead of rejecting 2024-08-14 18:09:13 +02:00
feld
5174c29d4c Merge branch 'fix-random-test-errors' into 'develop'
Fix random test failures, revert auto-retry failed tests

See merge request pleroma/pleroma!4221
2024-08-13 20:16:09 +00:00
Mark Felder
b281ad06de Revert "Custom mix task to retry failed tests once in CI pipeline"
This reverts commit ed2976b237.
2024-08-13 15:49:04 -04:00
Mark Felder
2ba5ad8eb5 MRF cleanup
MRFs written over time have been inconsistent with the terminology of what is being processed. MRFs work on Activities, but generally we always named the assignments "message" or "object" which is really confusing when trying to debug or write tests.
2024-08-13 14:22:41 -04:00
Mark Felder
b0c64945c2 MRF.FODirectReply: use Visibility module to verify the scope 2024-08-12 20:18:02 -04:00
feld
4e7928c985 Merge branch 'followers-only-reply-direct-mrf' into 'develop'
MRF.FODirectReply

See merge request pleroma/pleroma!4091
2024-08-12 21:46:45 +00:00
feld
f87aa8b83c Merge branch 'deprecate-subscribe' into 'develop'
Mark `/api/v1/pleroma/accounts/:id/subscribe`/`unsubscribe` as deprecated

See merge request pleroma/pleroma!4216
2024-08-12 21:27:12 +00:00
Mark Felder
488c4b8b98 MRF.FODirectReply
Force replies to followers-only posts to always be direct
2024-08-12 17:06:29 -04:00
feld
c29441f30d Merge branch 'mrf-quietreply' into 'develop'
MRF.QuietReply

See merge request pleroma/pleroma!4213
2024-08-12 20:25:19 +00:00
Mark Felder
471f5c81fd Add module documentation 2024-08-12 16:07:45 -04:00
marcin mikołajczak
34715b8581 remove unused alias
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-12 13:38:33 +02:00
marcin mikołajczak
c1c0f0b144 Mark /api/v1/pleroma/accounts/:id/subscribe/unsubscribe as deprecated
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-12 12:38:51 +02:00
marcin mikołajczak
6e53e94bda Remove stub for /api/v1/accounts/:id/identity_proofs (deprecated by Mastodon 3.5.0)
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-12 12:23:38 +02:00
Mark Felder
5a134a46f7 We must change to/cc in the activity and inner object 2024-08-08 15:23:59 -04:00
Mark Felder
a0af6cba09 Added MRF.QuietReply which prevents replies to public posts from being published to the timelines 2024-08-08 14:12:44 -04:00
Mark Felder
ca934b744f Remove validation for cc fields on Blocks 2024-08-07 21:51:43 -04:00
Mark Felder
526a57ff9f Remove validation for cc fields on Follow Accept/Reject 2024-08-07 21:51:22 -04:00
Mark Felder
8f15000c0f Do not require a cc field when validating an incoming Follow activity
The cc field is not required and the code was keeping the cc if it existed on an activity or replacing it with the default of an empty list when casting. If any Follow activity was received with a cc field, it would attempt to keep it.

This was noticed in !4208 where we would craft Follow requests with a cc value of nil.
2024-08-07 14:38:29 -04:00
feld
45611ed325 Merge branch 'workerhelper-fix' into 'develop'
Fix WebPush notifications not generating jobs

See merge request pleroma/pleroma!4210
2024-08-07 17:37:44 +00:00
Mark Felder
721005b312 Fix WebPush notifications not generating jobs
Dialyzer pointed this one out.

The WorkerHelper removal in !4166 was missing this Oban.insert() and tests were not noticing any problems because we mocked the Push.send function instead of executing it and checking for the Oban job.
2024-08-07 13:00:31 -04:00
Mark Felder
06e8ece4cc Fix CommonAPI.follow/2 which returned users in the reverse order they were provided to the function 2024-08-07 12:39:58 -04:00
feld
351a306d46 Merge branch 'stream-follow-relationships-count' into 'develop'
StreamerView: Do not leak follows count if hidden

See merge request pleroma/pleroma!4205
2024-08-07 16:17:58 +00:00
Mark Felder
9d27a074c1 Merge branch 'stream-follow-relationships-count' into develop 2024-08-07 11:48:52 -04:00
Mark Felder
7d33b53908 Improve the variable naming 2024-08-07 11:47:43 -04:00
feld
a2490ddd9f Merge branch 'remove/workerhelper' into 'develop'
Remove WorkerHelper

See merge request pleroma/pleroma!4166
2024-08-07 13:26:41 +00:00
Mark Felder
c284c4e3e6 Extract the logic from the map 2024-08-07 09:19:33 -04:00
Mark Felder
0bfe592048 Credo 2024-08-06 12:48:36 -04:00
Mark Felder
9ae9e2fc5c Use a struct to hold the prepared data passed to publish_one/1 2024-08-06 12:16:06 -04:00
Mark Felder
83fcf42c70 Force cc to an empty list if undefined 2024-08-06 12:03:44 -04:00
Mark Felder
f8bdcaa161 Split Federator.publish_one/1 into a second function called prepare_one/1 2024-08-06 11:16:04 -04:00
marcin mikołajczak
52f7033f7a StreamerView: Do not leak follows count if hidden
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-04 16:03:25 +02:00
marcin mikołajczak
de9194893e Support id param in GET /api/v1/statuses
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-08-03 18:28:43 +02:00
Mark Felder
1f986ec713 Gun: Publisher job behavior improvement
Gun's connection pool also returns an error if duplicate workers are launched simultaneously. Snooze on this error as well, and lower the snooze to 3 seconds with the optimism that the connection will still be open by then and the delivery can be completed quickly.

The original setting of 30 seconds is pretty high and means there's an unnatural lag between deliveries of activities destined to the same server that were created at nearly the same time. This configuration should be more efficient.
2024-08-02 09:25:18 -04:00
Mark Felder
e6951e7e40 Fix User.disclose_client never working correctly
Our test environment cheats by constructing a conn with a custom oauth_access/2 function. This assigns a :token to the conn but due to the way it is constructed it has the :user preloaded. When the OAuth Plug fetches a token it does not preload the user, so the check for user.disclose_client was always nil and assumed to be false.

Preloading the :user ensures the test environment matches reality.
2024-07-31 14:14:35 -04:00
Mark Felder
52e9bec156 Remove WorkerHelper 2024-07-30 11:34:48 -04:00
feld
18469f3b1d Merge branch 'oban/simpler-publish' into 'develop'
Publisher job simplification

See merge request pleroma/pleroma!4194
2024-07-30 15:23:28 +00:00
feld
c9042763b0 Merge branch 'oban/backup' into 'develop'
Backups Refactoring

See merge request pleroma/pleroma!4158
2024-07-29 16:07:35 +00:00
Mark Felder
b48fd89a41 Revert unintended change to the Logger metadata tag name 2024-07-29 10:03:22 -04:00
Mark Felder
8893ad9899 Fix cancelling jobs 2024-07-29 09:59:35 -04:00
Mark Felder
74072622e0 Remove actor and actor_id from the job as it can be inferred by the activity 2024-07-29 09:52:13 -04:00
Mark Felder
59309a9eff Publisher job simplification
Publisher jobs now store the the activity id instead of inserting duplicate JSON data in the Oban queue for each delivery.
2024-07-28 21:04:36 -04:00
Mark Felder
c19d55cabb Safer string concatenation 2024-07-25 16:18:45 -04:00
Mark Felder
84b15ac111 Improve specs and matching 2024-07-25 16:18:31 -04:00
Mark Felder
775f45cfe2 Merge remote-tracking branch 'origin/develop' into oban/backup 2024-07-25 14:43:40 -04:00
Mark Felder
a964368e31 Add test to fetch and validate an activity that originally failed signature 2024-07-25 14:34:55 -04:00
Mark Felder
1b9c887dbb Extract validate_signature/2 from the HTTPSignaturePlug
This logic only exists in the Plug, so attempting to validate the signature by calling the library function HTTPSignature.validate_conn/2 directly will never work because we do not attempt to construct the (request-target) and @request-target headers with both the commonly misinterpreted and correct implementation of this field. Therefore all attempts to validate a signature from an Oban Job will fail.
2024-07-25 12:54:27 -04:00
Mark Felder
1a482a73c3 Fix Optimistic Inbox for failed signatures
When signatures fail on incoming activities we put the job into Oban to be processed later instead of doing the user fetching and validation inline which is expensive and increases latency on the incoming POST request. Unfortunately we did not retain the :method, :request_path, and :query_string parameters from the conn so the signature validation and Oban Job would always fail.

This was most obvious when Mastodon sends Deletes for users your server has never seen before.
2024-07-25 11:46:30 -04:00
Mark Felder
97d488aea3 Fix RichMedia negative cache entries
The negative cache entry was a nil value, but that is an expected response when the cache is missing an entry so it didn't work as intended.
2024-07-24 15:45:39 -04:00
Mark Felder
5a62868106 Consider errors during HTTP GET and HEAD to be unrecoverable and insert a negative cache entry
This is for a normal HTTP error response or timeout while receiving the data. A hard error from a process crash, DNS lookup failure, etc should produce a different response than {:ok, %Tesla.Env{}} and the request/job will be retryable.
2024-07-24 15:43:49 -04:00
Mark Felder
731f7b87d2 Pad RichMediaWorker timeout to be 2s longer than the Rich Media HTTP timeout 2024-07-24 15:42:50 -04:00
Mark Felder
858fd01c01 Pleroma.HTTP: permit passing through custom Tesla Middlware for requests 2024-07-24 15:40:15 -04:00
Mark Felder
187897874b Make backup timeout configurable 2024-07-23 10:30:57 -04:00
Mark Felder
e5cbbaf3f0 Extend the backup job time limit to 30 minutes 2024-07-23 10:30:57 -04:00
Mark Felder
3f60d7bf64 Better random tempdir format 2024-07-23 10:30:57 -04:00
Mark Felder
ece063586b Limit backup jobs to 5 minutes 2024-07-23 10:30:57 -04:00
Mark Felder
8f285a787f Refactor backups to be fully controlled by Oban 2024-07-23 10:30:40 -04:00
Mark Felder
2ee8f4f062 Fix dialyzer error
lib/pleroma/application.ex:1:pattern_match The pattern can never match the type true.
2024-07-23 10:25:39 -04:00
Mark Felder
12f498bc0d Fix order of args for show_reblogs/2 2024-07-22 19:19:21 -04:00
Mark Felder
3f4f567c9c Fix order of args for hide_reblogs/2 2024-07-22 19:16:00 -04:00
Mark Felder
adb93f7e5d Fix order of args for unfollow/2 2024-07-22 19:11:22 -04:00
Mark Felder
f79a16c062 Fix order of args for follow/2 2024-07-22 19:07:55 -04:00
Mark Felder
082319ff48 Fix order of args for unblock/2 2024-07-22 18:44:32 -04:00
Mark Felder
cbc5e48417 Fix order of args for block/2 2024-07-22 18:41:50 -04:00
Mark Felder
1cccc0fc21 Fix order of args for vote/3 2024-07-22 18:38:02 -04:00
Mark Felder
8127e0d8cc Fix order of args for thread_muted?/2 2024-07-22 18:25:37 -04:00
Mark Felder
4601473aaf Fix order of args for add_mute/2 2024-07-22 18:25:37 -04:00
Mark Felder
d27ad36ce4 Fix order of args for remove_mute/2 2024-07-22 18:25:37 -04:00
Mark Felder
f602813d31 Fix order of args for update/2 2024-07-22 18:25:37 -04:00
Mark Felder
7e37882cf7 Fix order of args for favorite/2 2024-07-22 18:25:37 -04:00
Mark Felder
b1d3348331 Annotate public functions with typespecs and mark some functions as private 2024-07-22 18:25:33 -04:00
Mark Felder
3a79f060bb Add missing type 2024-07-22 15:32:20 -04:00
feld
f77911f05b Merge branch 'oban/more-improvements' into 'develop'
Oban: more improvements

See merge request pleroma/pleroma!4187
2024-07-22 17:45:44 +00:00
Mark Felder
f9647a86ed Fix the ObjectValidator error matching 2024-07-21 00:03:51 -04:00
Mark Felder
fb654acfad Fix OpenGraph and Twitter metadata providers when parsing objects with no content or summary fields. 2024-07-20 23:48:54 -04:00
Mark Felder
fdeb8616e8 Increase timeout for background, remote fetcher, and user refresh jobs 2024-07-20 22:16:33 -04:00
Mark Felder
d62a9afed3 Improved detecting unrecoverable errors for incoming federation jobs 2024-07-20 21:53:03 -04:00
Mark Felder
b8503f1ad4 PollWorker jobs will not retry if the activity no longer exists. 2024-07-20 21:24:13 -04:00
Mark Felder
e509519db4 Publisher jobs will not retry if the error received is a 400 2024-07-20 21:21:21 -04:00
feld
e4a6973e0b Merge branch 'transmogrifier/handle-non-validate-delete-errors' into 'develop'
Transmogrifier: handle non-validate errors on incoming Delete activities

See merge request pleroma/pleroma!4185
2024-07-21 00:47:10 +00:00
Mark Felder
d44765bc13 Support cancelling jobs when Unreacting 2024-07-20 15:14:46 -04:00
Mark Felder
304b7f5093 Support cancelling jobs when Unrepeating 2024-07-20 15:06:19 -04:00
Mark Felder
86ae00f9da Support cancelling jobs when Unfavoriting 2024-07-20 14:54:31 -04:00
Mark Felder
62280a3b9f Cancel queued (undelivered) publishing jobs for an activity when deleting that activity. 2024-07-20 14:54:04 -04:00
Mark Felder
d3c2180181 Formatting 2024-07-18 12:12:34 -04:00
Mint
1f3ac66844 Transmogrifier: handle non-validate errors on incoming Delete activities
This should fix WithClauseError resulting in Oban jobs for processing
incoming deletes being retried without getting cancelled when those
deletes are MRF rejected.
2024-07-18 18:04:32 +03:00
feld
c45ee5fc82 Merge branch 'oban/fetcher-rejected' into 'develop'
Dialyzer fix for RemoteFetcherWorker

See merge request pleroma/pleroma!4183
2024-07-17 18:03:48 +00:00
Mark Felder
c05cbaa937 Dialyzer fix for RemoteFetcherWorker 2024-07-17 13:42:13 -04:00
Mark Felder
f753bd3380 Explicitly handle the GET and HEAD errors 2024-07-17 13:12:51 -04:00
Mark Felder
1e0d5934d5 Fix return for cancelling job 2024-07-17 12:51:38 -04:00
Mark Felder
d124d8645e Rework some Rich Media functionality for better error handling
Oban should not retry jobs that are likely to fail again
2024-07-17 12:40:07 -04:00
Mark Felder
4cbb59c8f6 Add Oban Live Dashboard 2024-07-17 09:32:29 -04:00
Mark Felder
c9203f125c Added a Mix task "pleroma.config fix_mrf_policies" which will remove erroneous MRF policies from ConfigDB 2024-07-15 15:21:16 -04:00
Mark Felder
30defb1674 Create a DeleteWorker and change user and instance deletion jobs to use it
These deletion tasks are slow, but the other background jobs are not. This
will allow us to have a lower timeout on the normal background jobs.
2024-07-15 11:58:07 -04:00
Mark Felder
2f14990c5c Change PurgeExpiredActivity to use the background queue 2024-07-15 11:45:13 -04:00
Mark Felder
2e2caad28d Fix Oban jobs exiting with :error instead of :cancel 2024-07-15 11:45:12 -04:00
Mark Felder
1e8d1904e6 Define missing Oban timeouts 2024-07-15 10:27:37 -04:00
Mark Felder
f52b229baa Oban: change :discard return values to :cancel
:discard will be removed in Oban 3.0. It was only meant for internal use.
2024-07-12 11:40:59 -04:00
feld
3754713599 Merge branch 'oban/fetcher-discard-rejected' into 'develop'
Discard Remote Fetcher jobs which errored due to an MRF rejection

See merge request pleroma/pleroma!4174
2024-07-12 14:56:55 +00:00
Mark Felder
b051e68bb0 Discard Remote Fetcher jobs which errored due to an MRF rejection 2024-07-12 10:15:02 -04:00
Taylan Kammer
03c3c58d74 LDAP Authenticator: Improve error reporting. 2024-07-10 09:22:58 +02:00
Mark Felder
272aae157e Refactor maybe_handle_group_posts/1 2024-07-06 17:02:33 -04:00
Mark Felder
3127c5f0af Fix automatic LDAP account registration on OTP 24.3+ 2024-07-01 15:58:15 -04:00
Mark Felder
9402789437 Dialyzer: fix typespec 2024-07-01 11:47:27 -04:00
Mark Felder
b283b686c4 Dialyzer: Function application with args (_ :: map()) will not succeed. 2024-07-01 11:45:27 -04:00
Mark Felder
7955cd90e6 Dialyzer: The guard clause can never succeed. 2024-07-01 11:45:27 -04:00
Mark Felder
fd62969dc4 Dialyzer: pattern can never match the type 2024-07-01 11:45:25 -04:00
Mark Felder
a008005bdd Dialyzer: fix typespec 2024-07-01 11:38:40 -04:00
Mark Felder
69482004fc Dialyzer: pattern can never match the type because it is covered by previous clauses. 2024-07-01 11:38:40 -04:00
Mark Felder
fb52099a13 Elixir 1.17 single quote charlist warning 2024-07-01 11:38:40 -04:00
Mark Felder
6e1aa8aeeb Elixir 1.17 undefined module warning
Fixes module name being not fully qualified

    warning: AdminAPI.FallbackController.call/2 is undefined (module AdminAPI.FallbackController is not available or is yet to be defined)
    │
  5 │ defmodule Pleroma.Web.AdminAPI.RuleController do
    │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/pleroma/web/admin_api/controllers/rule_controller.ex:5: Pleroma.Web.AdminAPI.RuleController.action/2

    warning: AdminAPI.FallbackController.init/1 is undefined (module AdminAPI.FallbackController is not available or is yet to be defined)
    │
  5 │ defmodule Pleroma.Web.AdminAPI.RuleController do
    │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/pleroma/web/admin_api/controllers/rule_controller.ex:5: Pleroma.Web.AdminAPI.RuleController.action/2
2024-07-01 11:38:40 -04:00
Mark Felder
d3cccce9fd Elixir 1.17 warnings for parens
Function calls must have parens
2024-07-01 11:38:40 -04:00
lain
ccbbee7963 Merge branch 'exif' into 'develop'
Ensure StripLocation works for PNGs

See merge request pleroma/pleroma!4167
2024-06-30 09:28:17 +00:00
Lain Soykaf
6d4fb53206 StripLocation: Remove all PNG extra info to make sure that GPS data is gone. 2024-06-28 21:59:00 +04:00
feld
801a9367d0 Merge branch 'fix/oban-user-refresh-unique' into 'develop'
Oban Jobs for refreshing users were not respecting the uniqueness setting

See merge request pleroma/pleroma!4164
2024-06-28 14:47:25 +00:00
Mark Felder
9e5adf31c0 Change Gun connection pool logs to debug 2024-06-28 10:23:02 -04:00
Mark Felder
51a36bc9b8 Oban Jobs for refreshing users were not respecting the uniqueness setting 2024-06-28 10:12:58 -04:00
Mark Felder
b135fa35a1 RichMedia: test that activity is streamed out 2024-06-24 09:47:16 -04:00
Mark Felder
634e3d4155 Add test validating the activity_id is correctly present in the Oban job
This was preventing the activity from being streamed over websockets.
2024-06-23 21:45:56 -04:00
Mark Felder
9ef021e2da Switch the reclaimer to GenServer.start so it is not linked 2024-06-20 14:17:28 -04:00
Mark Felder
c765fcbe7e Gun Connection Pool: successfully retry after reclaiming the pool 2024-06-20 14:03:22 -04:00
Mark Felder
17d04ccc8b RichMedia backfill processing through Oban 2024-06-19 23:20:22 -04:00
Mark Felder
4dfa50f256 Rename RichMediaExpirationWorker to RichMediaWorker 2024-06-19 22:24:48 -04:00
Mark Felder
ed2976b237 Custom mix task to retry failed tests once in CI pipeline
This will be temporary* as we hunt down the cause of the random test failures

* gonna regret this
2024-06-19 19:04:12 -04:00
Mark Felder
3a8420b141 Remove remaining vestiges of Logger support in ConfigDB/TransferTask 2024-06-19 14:29:44 -04:00
Mark Felder
e43e09a04c Merge remote-tracking branch 'origin/develop' into bugfix/elixir-1.15 2024-06-18 16:47:01 +00:00
Mark Felder
9c67637255 Refactor the async user refreshing to use Oban
Previous implementation could cause duplicate simultaneous profile fetches which is not polite.
2024-06-17 10:41:14 -04:00
Mark Felder
e37845cd35 Stale user refreshing should be done async to prevent blocking of rendering activities 2024-06-16 17:39:35 -04:00
Mark Felder
cbf8f8ac0d Fix mix pleroma.config dump on Elixir 1.15 2024-06-13 10:48:50 -04:00
Lain Soykaf
41434ffcec Tests: Don't spawn processes in tests. 2024-06-12 15:20:04 -04:00
Haelwenn (lanodan) Monnier
c389ea0f42 Fix compatibility with Loggers in Elixir 1.15+ 2024-06-12 15:18:47 -04:00
Haelwenn (lanodan) Monnier
2180537a2b MediaProxy: :whitelist config fallback to [] 2024-06-12 15:18:47 -04:00
Haelwenn (lanodan) Monnier
66ac2e9b81 Upload.base_url: Don't pass nil to Path.join(), don't return nil 2024-06-12 15:18:47 -04:00
Haelwenn (lanodan) Monnier
cb91dab75f Switch formatting checks to Elixir 1.15 2024-06-12 15:18:47 -04:00
Lain Soykaf
1ae5c2b020 Transmogrifier: Encode Emoji id to be valid. 2024-06-12 12:41:33 +04:00
Mark Felder
5c8afbe646 Fix tests 2024-06-11 18:55:10 -04:00
Mark Felder
6a9d9da26f Cyclical complexity 2024-06-11 18:38:41 -04:00
Mark Felder
603a575766 The user is not always preloaded into the notification 2024-06-11 18:14:07 -04:00
Mark Felder
568819c08a WebPush refactoring: separate build and deliver steps 2024-06-11 17:58:02 -04:00
feld
f47a124698 Merge branch 'webpush-polls' into 'develop'
Render nice web push notifications for polls

See merge request pleroma/pleroma!4144
2024-06-11 20:24:15 +00:00
Mark Felder
5313255b1a Use conn.request_path for more legible error log 2024-06-11 16:07:22 -04:00
Mark Felder
c1b84edefc Increase web push character limit for the body 2024-06-08 22:48:38 -04:00
Mark Felder
dcc50da400 Stream the notifications as part of the job 2024-06-08 22:40:08 -04:00
Mark Felder
3211557f74 Render nice web push notifications for polls 2024-06-08 22:08:12 -04:00
Mark Felder
b1ef6e5e9a Cleanup to make the code easier to follow 2024-06-08 19:50:01 -04:00
Mark Felder
86fa0889bc Remove unnecessary mastodon_type hack 2024-06-08 19:30:27 -04:00
Mark Felder
db88bf30d5 Add spec for send/1 2024-06-08 19:20:38 -04:00