From 0ef298a28e036a8532243910f3cb53e9225eed36 Mon Sep 17 00:00:00 2001 From: Bram Date: Fri, 12 Apr 2024 13:57:38 +0200 Subject: [PATCH] Connect User to Event type --- src/Internal/Filter/Timeline.elm | 5 +++-- src/Internal/Grammar/ServerName.elm | 6 ++++++ src/Internal/Tools/Json.elm | 4 ++-- src/Internal/Values/Event.elm | 5 +++-- src/Internal/Values/User.elm | 33 +++++++++++++++++++++++++++++ src/Matrix/Event.elm | 5 +++-- tests/Test/Filter/Timeline.elm | 19 +++++++++-------- tests/Test/Grammar/UserId.elm | 8 +++++++ tests/Test/Tools/Hashdict.elm | 4 ++-- tests/Test/Values/Event.elm | 3 ++- 10 files changed, 72 insertions(+), 20 deletions(-) diff --git a/src/Internal/Filter/Timeline.elm b/src/Internal/Filter/Timeline.elm index a4231bf..e43ecce 100644 --- a/src/Internal/Filter/Timeline.elm +++ b/src/Internal/Filter/Timeline.elm @@ -48,6 +48,7 @@ for interacting with the Matrix API. -} import Internal.Config.Text as Text +import Internal.Grammar.UserId as U import Internal.Tools.Json as Json import Json.Decode as D import Json.Encode as E @@ -57,7 +58,7 @@ import Set exposing (Set) {-| Placeholder Event type so the real Event doesn't need to be imported. -} type alias Event a = - { a | eventType : String, sender : String } + { a | eventType : String, sender : U.UserID } {-| The Timeline Filter filters events out of a timeline, guaranteeing that only @@ -246,7 +247,7 @@ match (Filter f) { eventType, sender } = let mentionedSender : Bool mentionedSender = - Set.member sender f.senders + Set.member (U.toString sender) f.senders mentionedType : Bool mentionedType = diff --git a/src/Internal/Grammar/ServerName.elm b/src/Internal/Grammar/ServerName.elm index ac77f4f..4b9f1b6 100644 --- a/src/Internal/Grammar/ServerName.elm +++ b/src/Internal/Grammar/ServerName.elm @@ -1,6 +1,7 @@ module Internal.Grammar.ServerName exposing ( ServerName, toString, fromString , serverNameParser + , HostName(..) ) {-| @@ -19,6 +20,11 @@ other homeservers. @docs serverNameParser + +## Debug + +@docs HostName + -} import Internal.Tools.ParserExtra as PE diff --git a/src/Internal/Tools/Json.elm b/src/Internal/Tools/Json.elm index 4608965..cf31b4f 100644 --- a/src/Internal/Tools/Json.elm +++ b/src/Internal/Tools/Json.elm @@ -4,7 +4,7 @@ module Internal.Tools.Json exposing , succeed, fail, andThen, lazy, map , Docs(..), RequiredField(..), toDocs , list, listWithOne, slowDict, fastDict, fastIntDict, set, maybe - , Field, field + , Field, field, parser , object2, object3, object4, object5, object6, object7, object8, object9, object10, object11 ) @@ -58,7 +58,7 @@ This section creates objects that can be (re)used in the library's JSON specification. For this, the user needs to construct fields for the object first. -@docs Field, field +@docs Field, field, parser Once all fields are constructed, the user can create JSON objects. diff --git a/src/Internal/Values/Event.elm b/src/Internal/Values/Event.elm index 71e18e6..2ee528a 100644 --- a/src/Internal/Values/Event.elm +++ b/src/Internal/Values/Event.elm @@ -35,6 +35,7 @@ of a room. import Internal.Config.Text as Text import Internal.Tools.Json as Json import Internal.Tools.Timestamp as Timestamp exposing (Timestamp) +import Internal.Values.User as User exposing (User) import Json.Encode as E @@ -45,7 +46,7 @@ type alias Event = , eventId : String , originServerTs : Timestamp , roomId : String - , sender : String + , sender : User , stateKey : Maybe String , eventType : String , unsigned : Maybe UnsignedData @@ -112,7 +113,7 @@ coder = { fieldName = "sender" , toField = .sender , description = Text.fields.event.sender - , coder = Json.string + , coder = User.coder } ) (Json.field.optional.value diff --git a/src/Internal/Values/User.elm b/src/Internal/Values/User.elm index c39ebfc..806207d 100644 --- a/src/Internal/Values/User.elm +++ b/src/Internal/Values/User.elm @@ -1,6 +1,7 @@ module Internal.Values.User exposing ( User, toString, fromString , localpart, domain + , coder ) {-| The Matrix user is uniquely identified by their identifier. This User type @@ -28,10 +29,18 @@ Since the username is safely parsed, one can get these parts of the username. @docs localpart, domain + +## JSON + +@docs coder + -} +import Internal.Config.Log as Log exposing (log) import Internal.Grammar.ServerName as ServerName import Internal.Grammar.UserId as UserId +import Internal.Tools.Json as Json +import Parser as P {-| The Matrix user represents a user across multiple Matrix rooms. @@ -40,6 +49,30 @@ type alias User = UserId.UserID +{-| Define a method to encode/decode Matrix users. +-} +coder : Json.Coder User +coder = + Json.parser + { name = "Username" + , p = + P.andThen + (\name -> + P.succeed + ( name + , if UserId.isHistorical name then + [ log.warn "Historical user found" + ] + + else + [] + ) + ) + UserId.userIdParser + , toString = UserId.toString + } + + {-| The domain represents the Matrix homeserver controlling this user. It also offers other Matrix homeservers an indication of where to look if you wish to send a message to this user. diff --git a/src/Matrix/Event.elm b/src/Matrix/Event.elm index da6e114..c234555 100644 --- a/src/Matrix/Event.elm +++ b/src/Matrix/Event.elm @@ -122,9 +122,10 @@ roomId (Event event) = {-| Determine the fully-qualified ID of the user who sent an event. -} -sender : Event -> String +sender : Event -> Types.User sender (Event event) = - Envelope.extract .sender event + Envelope.map .sender event + |> Types.User {-| Determine an event's state key. diff --git a/tests/Test/Filter/Timeline.elm b/tests/Test/Filter/Timeline.elm index 6e880e7..a9f7813 100644 --- a/tests/Test/Filter/Timeline.elm +++ b/tests/Test/Filter/Timeline.elm @@ -3,6 +3,7 @@ module Test.Filter.Timeline exposing (..) import Expect import Fuzz exposing (Fuzzer) import Internal.Filter.Timeline as Filter exposing (Filter) +import Internal.Grammar.UserId as U import Internal.Values.Event as Event import Json.Decode as D import Json.Encode as E @@ -86,7 +87,7 @@ suite = "Only event sender filter matches" (\event -> event - |> Filter.match (Filter.onlySenders [ event.sender ]) + |> Filter.match (Filter.onlySenders [ U.toString event.sender ]) |> Expect.equal True ) , fuzz TestEvent.fuzzer @@ -100,7 +101,7 @@ suite = "Not event sender filter doesn't match" (\event -> event - |> Filter.match (Filter.allSendersExcept [ event.sender ]) + |> Filter.match (Filter.allSendersExcept [ U.toString event.sender ]) |> Expect.equal False ) , fuzz2 TestEvent.fuzzer @@ -109,7 +110,7 @@ suite = (\event senders -> event |> Filter.match (Filter.onlySenders senders) - |> Expect.equal (List.member event.sender senders) + |> Expect.equal (List.member (U.toString event.sender) senders) ) , fuzz2 TestEvent.fuzzer (Fuzz.list Fuzz.string) @@ -125,7 +126,7 @@ suite = (\event senders -> event |> Filter.match (Filter.allSendersExcept senders) - |> Expect.notEqual (List.member event.sender senders) + |> Expect.notEqual (List.member (U.toString event.sender) senders) ) , fuzz2 TestEvent.fuzzer (Fuzz.list Fuzz.string) @@ -302,7 +303,7 @@ suite = l2 = List.filter (\e -> - List.member e.sender senders + List.member (U.toString e.sender) senders && List.member e.eventType types ) events @@ -336,8 +337,8 @@ suite = l2 = List.filter (\e -> - List.member e.sender senders - && (not <| List.member e.eventType types) + List.member (U.toString e.sender) senders + && (not <| List.member (U.toString e.sender) types) ) events in @@ -370,7 +371,7 @@ suite = l2 = List.filter (\e -> - (not <| List.member e.sender senders) + (not <| List.member (U.toString e.sender) senders) && List.member e.eventType types ) events @@ -404,7 +405,7 @@ suite = l2 = List.filter (\e -> - (not <| List.member e.sender senders) + (not <| List.member (U.toString e.sender) senders) && (not <| List.member e.eventType types) ) events diff --git a/tests/Test/Grammar/UserId.elm b/tests/Test/Grammar/UserId.elm index f613902..99ece77 100644 --- a/tests/Test/Grammar/UserId.elm +++ b/tests/Test/Grammar/UserId.elm @@ -2,6 +2,7 @@ module Test.Grammar.UserId exposing (..) import Expect import Fuzz exposing (Fuzzer) +import Internal.Grammar.ServerName as SN import Internal.Grammar.UserId as U import Test exposing (..) import Test.Grammar.ServerName as ServerName @@ -77,6 +78,13 @@ userFuzzer = Fuzz.oneOf [ modernUserFuzzer, historicalUserFuzzer ] +fullUserFuzzer : Fuzzer U.UserID +fullUserFuzzer = + userFuzzer + |> Fuzz.map U.fromString + |> Fuzz.map (Maybe.withDefault { localpart = "a", domain = { host = SN.DNS "a", port_ = Nothing } }) + + suite : Test suite = describe "UserId" diff --git a/tests/Test/Tools/Hashdict.elm b/tests/Test/Tools/Hashdict.elm index cdfdf43..7eb3bbf 100644 --- a/tests/Test/Tools/Hashdict.elm +++ b/tests/Test/Tools/Hashdict.elm @@ -115,7 +115,7 @@ suite = (\event -> Hashdict.singleton .eventId event |> Hashdict.remove event - |> Hashdict.isEqual (Hashdict.empty .sender) + |> Hashdict.isEqual (Hashdict.empty .roomId) |> Expect.equal True ) , fuzz TestEvent.fuzzer @@ -123,7 +123,7 @@ suite = (\event -> Hashdict.singleton .eventId event |> Hashdict.removeKey event.eventId - |> Hashdict.isEqual (Hashdict.empty .sender) + |> Hashdict.isEqual (Hashdict.empty .roomId) |> Expect.equal True ) , fuzz TestEvent.fuzzer diff --git a/tests/Test/Values/Event.elm b/tests/Test/Values/Event.elm index bee07ba..35ba18e 100644 --- a/tests/Test/Values/Event.elm +++ b/tests/Test/Values/Event.elm @@ -5,6 +5,7 @@ import Fuzz exposing (Fuzzer) import Internal.Values.Event as Event exposing (Event) import Json.Encode as E import Test exposing (..) +import Test.Grammar.UserId as UserId import Test.Tools.Timestamp as TestTimestamp @@ -15,7 +16,7 @@ fuzzer = Fuzz.string TestTimestamp.fuzzer Fuzz.string - Fuzz.string + UserId.fullUserFuzzer (Fuzz.maybe Fuzz.string) Fuzz.string (Fuzz.maybe unsignedDataFuzzer)