123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- (*
- * _ _ ____ _
- * _| || |_/ ___| ___ _ __ _ __ ___ | |
- * |_ .. _\___ \ / _ \ '_ \| '_ \ / _ \| |
- * |_ _|___) | __/ |_) | |_) | (_) |_|
- * |_||_| |____/ \___| .__/| .__/ \___/(_)
- * |_| |_|
- *
- * Personal Social Web.
- *
- * as2_test.ml
- *
- * Copyright (C) The #Seppo contributors. All rights reserved.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *)
- open Seppo_lib
- module A = Assrt
- let test_follower_state () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_follower_state");
- Ap.Followers.State.(Pending |> to_string) |>
- A.equals_string __LOC__ "pending"
- let test_inbox_follow () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_inbox_follow");
- let a = File.in_channel "data/follow.mastodon.json" Ezjsonm.from_channel
- |> As2_vocab.Activitypub.Decode.follow
- |> Result.get_ok in
- a.id |> A.equals_uri __LOC__ (Uri.of_string "https://alpaka.social/afe4ac8a-aaeb-41f5-a348-e5d133bdb931");
- a.actor |> A.equals_uri __LOC__ (Uri.of_string "https://alpaka.social/users/traunstein");
- a.object_ |> A.equals_uri __LOC__ (Uri.of_string "https://dev.seppo.social/2023-06-12/activitypub/profile.json");
- match a.state with
- | None -> ()
- | _ -> "-" |> A.equals_string __LOC__ ""
- let test_inbox_unfollow () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_inbox_unfollow");
- let o = File.in_channel "data/undo-follow.mastodon.json" Ezjsonm.from_channel
- |> As2_vocab.Activitypub.Decode.(undo follow)
- |> Result.get_ok in
- o.id |> Uri.to_string |> A.equals_string __LOC__ "https://alpaka.social/users/traunstein#follows/5219/undo";
- o.actor |> Uri.to_string |> A.equals_string __LOC__ "https://alpaka.social/users/traunstein";
- o.obj.id |> Uri.to_string |> A.equals_string __LOC__ "https://alpaka.social/a5fc3ab5-92f3-4641-a33e-96418e9bec78";
- o.obj.object_ |> Uri.to_string |> A.equals_string __LOC__ "https://dev.seppo.social/2023-06-12/activitypub/profile.json";
- assert (o.actor |> Uri.equal o.obj.actor);
- (*
- a.object_ |> A.equals_uri __LOC__ (Uri.of_string "https://dev.seppo.social/2023-06-12/activitypub/profile.json");
- match a.state with
- | None -> ()
- | _ -> "-" |> A.equals_string __LOC__ ""
- *)
- assert true
- let test_followers_page_json_raw () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_followers_page_json_raw");
- let fs = [
- "1/" |> Uri.of_string;
- "2/" |> Uri.of_string;
- "3/" |> Uri.of_string;
- "4/" |> Uri.of_string;
- "5/" |> Uri.of_string;
- ] in
- let base' = "https://example.com/u/" |> Uri.of_string in
- let base = "https://example.com/ap/followers/2.jsa" |> Uri.of_string in
- let p : Uri.t As2_vocab.Types.collection_page = {
- id = base;
- current = Some base;
- first = None;
- is_ordered = true;
- items = fs;
- last = Some (Http.reso ~base (Uri.of_string "0.jsa"));
- next = Some (Http.reso ~base (Uri.of_string "1.jsa"));
- part_of = Some (Http.reso ~base (Uri.of_string "index.jsa"));
- prev = Some (Http.reso ~base (Uri.of_string "3.jsa"));
- total_items= None;
- } in
- p |> As2_vocab.Encode.(collection_page ~base (uri ~base:base'))
- |> Ezjsonm.value_to_string ~minify:false
- |> A.equals_string __LOC__ {|{
- "@context": [
- "https://www.w3.org/ns/activitystreams",
- "https://w3id.org/security/v1",
- {
- "schema": "http://schema.org#",
- "PropertyValue": "schema:PropertyValue",
- "value": "schema:value",
- "@language": "und"
- }
- ],
- "type": "OrderedCollectionPage",
- "id": "https://example.com/ap/followers/2.jsa",
- "current": "https://example.com/ap/followers/2.jsa",
- "last": "https://example.com/ap/followers/0.jsa",
- "next": "https://example.com/ap/followers/1.jsa",
- "partOf": "https://example.com/ap/followers/index.jsa",
- "prev": "https://example.com/ap/followers/3.jsa",
- "orderedItems": [
- "https://example.com/u/1/",
- "https://example.com/u/2/",
- "https://example.com/u/3/",
- "https://example.com/u/4/",
- "https://example.com/u/5/"
- ]
- }|}
- let test_followers_page_json () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_followers_page_json");
- let foo = "https://example.com/foo/usr/" |> Uri.of_string in
- let base = "https://example.com/" |> Uri.of_string in
- let path = Ap.apub ^ "followers/" in
- let base = Http.reso ~base (Uri.make ~path ()) in
- [ "1/"; "2/"; "3/"; "4/"; "5/" ]
- |> List.rev
- |> List.fold_left (fun init path -> (Uri.make ~path () |> Http.reso ~base:foo) :: init) []
- |> Ap.Followers.Json.to_page_json ~base path ~finish:false 2
- |> Ezjsonm.value_to_string ~minify:false
- |> A.equals_string __LOC__ {|{
- "@context": [
- "https://www.w3.org/ns/activitystreams",
- "https://w3id.org/security/v1",
- {
- "schema": "http://schema.org#",
- "PropertyValue": "schema:PropertyValue",
- "value": "schema:value",
- "@language": "und"
- }
- ],
- "type": "OrderedCollectionPage",
- "id": "https://example.com/activitypub/followers/2.jsa",
- "current": "https://example.com/activitypub/followers/2.jsa",
- "last": "https://example.com/activitypub/followers/0.jsa",
- "next": "https://example.com/activitypub/followers/1.jsa",
- "partOf": "https://example.com/activitypub/followers/index.jsa",
- "prev": "https://example.com/activitypub/followers/3.jsa",
- "orderedItems": [
- "https://example.com/foo/usr/1/",
- "https://example.com/foo/usr/2/",
- "https://example.com/foo/usr/3/",
- "https://example.com/foo/usr/4/",
- "https://example.com/foo/usr/5/"
- ]
- }|}
- let test_followers_json () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_followers_json");
- let foo = "https://example.com/foo/usr/" |> Uri.of_string in
- let lst = [ "1/"; "2/"; "3/"; "4/"; "5/" ]
- |> List.rev
- |> List.fold_left (fun init path -> (Uri.make ~path () |> Http.reso ~base:foo) :: init) []
- in
- let base = "https://example.com/" |> Uri.of_string in
- let path = Ap.apub ^ "followers/" in
- let base = Http.reso ~base (Uri.make ~path ()) in
- let _ = File.mkdir_p File.pDir path in
- (* let oc = stdout in *)
- File.out_channel ~tmp:None "/dev/null" (fun oc ->
- Ap.Followers.Json.(List.fold_left
- (fold2pages 3 (flush_page ~base ~oc path))
- (0,0,[],0)
- lst
- |> flush_page ~base ~finish:true ~oc path);
- (* check existence of index.jsa *)
- (* check existence of 0.jsa *)
- (* check existence of 1.jsa *)
- "" |> A.equals_string __LOC__ ""
- )
- let test_followers_cdb_json () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_followers_cdb_json");
- File.out_channel ~tmp:None "/dev/null" (fun oc ->
- let base = "https://example.com/" |> Uri.of_string in
- let path = Ap.apub ^ "follower2/" in
- let base = Http.reso ~base (Uri.make ~path ()) in
- let path = "tmp/" ^ path in
- let _ = File.mkdir_p File.pDir path in
- let _ = Ap.Followers.Json.coll_of_cdb ~base ~oc ~pagesize:3 path (Mapcdb.Cdb "data/followers.cdb") in
- "" |> A.equals_string __LOC__ ""
- )
- let test_create_note_json () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_create_note_json");
- File.in_channel "data/create.note.mastodon2.json" (fun ic ->
- let c : As2_vocab.Types.note As2_vocab.Types.create = Ezjsonm.from_channel ic
- |> As2_vocab.Decode.(create note)
- |> Result.get_ok in
- assert (not c.direct_message);
- let n = c.obj in
- n.id |> Uri.to_string |> A.equals_string __LOC__ "https://bewegung.social/users/mro/statuses/111561416759041219";
- n.actor |> Uri.to_string |> A.equals_string __LOC__ "https://bewegung.social/users/mro";
- n.published |> Option.get |> Ptime.to_rfc3339 |> A.equals_string __LOC__ "2023-12-11T10:55:25-00:00";
- n.in_reply_to |> List.length |> A.equals_int __LOC__ 0;
- assert (n.summary |> Option.is_none);
- n.content |> A.equals_string __LOC__ {|<p>Good morning 😀 <a href="https://bewegung.social/tags/Social" class="mention hashtag" rel="tag">#<span>Social</span></a> <a href="https://bewegung.social/tags/Web" class="mention hashtag" rel="tag">#<span>Web</span></a>! <span class="h-card" translate="no"><a href="https://seppo.social/demo/" class="u-url mention">@<span>demo</span></a></span></p>|};
- n.tags |> List.length |> A.equals_int __LOC__ 3;
- (match n.tags with
- | [
- {ty=`Mention;name=n0;href=h0};
- {ty=`Hashtag;name=n1;href=h1};
- {ty=`Hashtag;name=n2;href=h2};
- ] ->
- n0 |> A.equals_string __LOC__ "@demo@seppo.social";
- h0 |> Uri.to_string |> A.equals_string __LOC__ "https://seppo.social/demo/activitypub/profile.jlda";
- n1 |> A.equals_string __LOC__ "#social";
- h1 |> Uri.to_string |> A.equals_string __LOC__ "https://bewegung.social/tags/social";
- n2 |> A.equals_string __LOC__ "#web";
- h2 |> Uri.to_string |> A.equals_string __LOC__ "https://bewegung.social/tags/web";
- ()
- | _ -> failwith "aua"
- (**) );
- assert true
- )
- let test_reject_json () =
- Logr.info (fun m -> m "%s.%s" "Ap_test" "test_reject_json");
- let reject me id =
- `O [("@context", `String "https://www.w3.org/ns/activitystreams");
- ("type", `String "Reject");
- ("actor", `String (me |> Uri.to_string));
- ("object", `String (id |> Uri.to_string))]
- in
- let me = "https://example.com/alice" |> Uri.of_string in
- let id = match File.in_channel "data/create.note.mastodon2.json" Ezjsonm.from_channel with
- | `O (_ :: ("id", `String id) :: _) -> id |> Uri.of_string
- | _ -> Uri.empty in
- id |> Uri.to_string |> A.equals_string __LOC__ {|https://bewegung.social/users/mro/statuses/111561416759041219/activity|};
- id
- |> reject me
- |> Ezjsonm.value_to_string
- |> A.equals_string __LOC__ {|{"@context":"https://www.w3.org/ns/activitystreams","type":"Reject","actor":"https://example.com/alice","object":"https://bewegung.social/users/mro/statuses/111561416759041219/activity"}|};
- assert true
- let test_subscribed () =
- for i = 0 to 10 do
- try i |> Printf.sprintf "/tmp/%d.xml" |> Unix.unlink
- with | Unix.Unix_error(Unix.ENOENT, "unlink", _) -> ()
- done ;
- let cdb = Mapcdb.Cdb "data/2024-04-30-131146-subscribed.cdb" in
- cdb
- |> Mapcdb.fold_left (fun c _ -> 1 + c) 0
- |> A.equals_int __LOC__ 52;
- let r = Ap.Followers.Atom.rule in
- r.target |> A.equals_string __LOC__ "activitypub/notify/index.xml";
- (match Ap.Followers.Atom.of_cdb
- ~cdb
- ~title:"My Title"
- ~xsl:(Rfc4287.xsl "my.xsl" "./tmp/noop")
- ~rel:(Some Rfc4287.Link.notify)
- ~page_size:5
- "./tmp/" with
- | Error _ -> failwith __LOC__
- | Ok s -> s)
- |> A.equals_string __LOC__ "./tmp/10.xml";
- "./tmp/0.xml" |> File.to_string |> A.equals_string __LOC__ {|<?xml version="1.0"?>
- <?xml-stylesheet type="text/xsl" href="../../themes/current/my.xsl"?>
- <feed xmlns="http://www.w3.org/2005/Atom">
- <title>My Title</title>
- <id>0.xml</id>
- <link rel="self" href="0.xml" title="1"/>
- <link rel="first" href="." title="last"/>
- <link rel="last" href="0.xml" title="1"/>
- <link rel="previous" href="1.xml" title="2"/>
- <link rel="notify" href="https://social.wohlfarth.name/users/alain" title=""/>
- <link rel="notify" href="https://hci.social/users/sigchi" title=""/>
- <link rel="notify" href="https://fosstodon.org/users/nlnetlabs" title=""/>
- <link rel="notify" href="https://mastodon.xyz/users/NGIZero" title=""/>
- <link rel="notify" href="https://w3c.social/users/w3c" title=""/>
- </feed>|};
- "./tmp/10.xml" |> File.to_string |> A.equals_string __LOC__ {|<?xml version="1.0"?>
- <?xml-stylesheet type="text/xsl" href="../../themes/current/my.xsl"?>
- <feed xmlns="http://www.w3.org/2005/Atom">
- <title>My Title</title>
- <id>10.xml</id>
- <link rel="self" href="10.xml" title="11"/>
- <link rel="first" href="." title="last"/>
- <link rel="last" href="0.xml" title="1"/>
- <link rel="previous" href="11.xml" title="12"/>
- <link rel="next" href="9.xml" title="10"/>
- <link rel="notify" href="https://mas.to/users/leostera" title=""/>
- <link rel="notify" href="https://social.network.europa.eu/users/EU_Commission" title="European Commission" rfc7033="acct:EU_Commission@social.network.europa.eu"/>
- </feed>|};
- "?" |> A.equals_string __LOC__ "?"
- let () =
- Unix.chdir "../../../test/";
- test_follower_state ();
- test_inbox_follow ();
- test_inbox_unfollow ();
- test_followers_page_json_raw ();
- test_followers_page_json ();
- test_followers_json ();
- test_followers_cdb_json ();
- test_create_note_json ();
- test_reject_json ();
- test_subscribed ();
- assert true
|