WIP: use complement libraries

This commit is contained in:
Kegan Dougal 2023-10-11 12:23:46 +01:00
parent 4d8cbb2709
commit 37aa1469a5
23 changed files with 531 additions and 1228 deletions

16
go.mod
View File

@ -9,12 +9,13 @@ require (
github.com/gorilla/mux v1.8.0
github.com/jmoiron/sqlx v1.3.3
github.com/lib/pq v1.10.9
github.com/matrix-org/gomatrixserverlib v0.0.0-20230822143230-740f742d6993
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
github.com/matrix-org/complement v0.0.0-20231010122615-008239d3b6e7
github.com/matrix-org/gomatrixserverlib v0.0.0-20230921171121-0466775328c7
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
github.com/pressly/goose/v3 v3.14.0
github.com/prometheus/client_golang v1.13.0
github.com/rs/zerolog v1.29.0
github.com/tidwall/gjson v1.14.3
github.com/tidwall/gjson v1.16.0
github.com/tidwall/sjson v1.2.5
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0
go.opentelemetry.io/contrib/propagators/jaeger v1.18.0
@ -34,6 +35,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.0 // indirect
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
@ -43,17 +45,19 @@ require (
github.com/rs/xid v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/otel/metric v1.18.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.58.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
maunium.net/go/mautrix v0.11.0 // indirect
)

39
go.sum
View File

@ -153,6 +153,7 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.0 h1:Rme6CE1aUTyV9WmrEPyGf1V+7W3iQzZ1DZkKnT6z9B0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.0/go.mod h1:Hbb13e3/WtqQ8U5hLGkek9gJvBLasHuPFI0UEGfnQ10=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@ -178,11 +179,14 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230822143230-740f742d6993 h1:88wDfSsqSFyeCnTha8vfK9XJUbNjNXdEZAieOjbBzos=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230822143230-740f742d6993/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
github.com/matrix-org/complement v0.0.0-20231010122615-008239d3b6e7 h1:lamc87j5ig2mNEi5Qqd+ZeIpmLdKtvYgZ3HDSPG0DrI=
github.com/matrix-org/complement v0.0.0-20231010122615-008239d3b6e7/go.mod h1:GCJVyag4p1Qj/WJUmBLlRtRHd04ALFNJkhzOcM/BvgA=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230921171121-0466775328c7 h1:NhPNNFLHwdDb/upeicBh1GkxX/sFinEp5HF1WBqPtiY=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230921171121-0466775328c7/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66/go.mod h1:iBI1foelCqA09JJgPV0FYz4qA5dUXYOxMi57FxKBdd4=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
@ -190,10 +194,11 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@ -254,12 +259,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
@ -299,8 +305,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -311,6 +317,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -443,8 +451,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -490,7 +498,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -584,6 +592,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@ -601,6 +610,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
maunium.net/go/mautrix v0.11.0 h1:B1FBHcvE4Mud+AC+zgNQQOw0JxSVrt40watCejhVA7w=
maunium.net/go/mautrix v0.11.0/go.mod h1:K29EcHwsNg6r7fMfwvi0GHQ9o5wSjqB9+Q8RjCIQEjA=
modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q=
modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ=
modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=

View File

@ -19,8 +19,8 @@ func TestAccountDataRespectsExtensionScope(t *testing.T) {
// Want at least one test of the initial sync behaviour (which hits `ProcessInitial`)
// separate to the incremental sync behaviour (hits `AppendLive`)
t.Log("Alice creates rooms 1 and 2.")
room1 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
room1 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
t.Logf("room1=%s room2=%s", room1, room2)
t.Log("Alice uploads account data for both rooms, plus global account data.")
@ -216,7 +216,7 @@ func TestAccountDataDoesntDupe(t *testing.T) {
// sync response with bytes.Equal.
func putGlobalAccountData(t *testing.T, client *CSAPI, eventType string, content map[string]interface{}) json.RawMessage {
t.Helper()
client.SetGlobalAccountData(t, eventType, content)
client.MustSetGlobalAccountData(t, eventType, content)
serialised := testutils.NewAccountData(t, eventType, content)
return serialised
}
@ -224,7 +224,7 @@ func putGlobalAccountData(t *testing.T, client *CSAPI, eventType string, content
// putRoomAccountData is like putGlobalAccountData, but for room-specific account data.
func putRoomAccountData(t *testing.T, client *CSAPI, roomID, eventType string, content map[string]interface{}) json.RawMessage {
t.Helper()
client.SetRoomAccountData(t, roomID, eventType, content)
client.MustSetRoomAccountData(t, roomID, eventType, content)
serialised := testutils.NewAccountData(t, eventType, content)
return serialised
}

File diff suppressed because it is too large Load Diff

View File

@ -9,13 +9,15 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
func TestInvalidTokenReturnsMUnknownTokenError(t *testing.T) {
alice := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{})
roomID := alice.MustCreateRoom(t, map[string]interface{}{})
// normal sliding sync
alice.SlidingSync(t, sync3.Request{
ConnID: "A",
@ -26,15 +28,15 @@ func TestInvalidTokenReturnsMUnknownTokenError(t *testing.T) {
},
})
// invalidate the access token
alice.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "logout"})
alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "logout"})
// let the proxy realise the token is expired and tell downstream
time.Sleep(time.Second)
var invalidResponses []*http.Response
// using the same token now returns a 401 with M_UNKNOWN_TOKEN
httpRes := alice.DoFunc(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.msc3575", "sync"}, WithQueries(url.Values{
httpRes := alice.Do(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.msc3575", "sync"}, client.WithQueries(url.Values{
"timeout": []string{"500"},
}), WithJSONBody(t, sync3.Request{
}), client.WithJSONBody(t, sync3.Request{
ConnID: "A",
RoomSubscriptions: map[string]sync3.RoomSubscription{
roomID: {
@ -45,9 +47,9 @@ func TestInvalidTokenReturnsMUnknownTokenError(t *testing.T) {
invalidResponses = append(invalidResponses, httpRes)
// using a bogus access token returns a 401 with M_UNKNOWN_TOKEN
alice.AccessToken = "flibble_wibble"
httpRes = alice.DoFunc(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.msc3575", "sync"}, WithQueries(url.Values{
httpRes = alice.Do(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.msc3575", "sync"}, client.WithQueries(url.Values{
"timeout": []string{"500"},
}), WithJSONBody(t, sync3.Request{
}), client.WithJSONBody(t, sync3.Request{
ConnID: "A",
RoomSubscriptions: map[string]sync3.RoomSubscription{
roomID: {
@ -84,7 +86,7 @@ func TestInvalidTokenReturnsMUnknownTokenError(t *testing.T) {
// Test that you can have multiple connections with the same device, and they work independently.
func TestMultipleConns(t *testing.T) {
alice := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{})
roomID := alice.MustCreateRoom(t, map[string]interface{}{})
resA := alice.SlidingSync(t, sync3.Request{
ConnID: "A",
@ -111,7 +113,7 @@ func TestMultipleConns(t *testing.T) {
},
})
eventID := alice.SendEventSynced(t, roomID, Event{
eventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.name",
StateKey: ptr(""),
Content: map[string]interface{}{"name": "pub"},

View File

@ -2,9 +2,11 @@ package syncv3_test
import (
"fmt"
"testing"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
"testing"
)
// Test that state changes "missed" by a poller are injected back into the room when a
@ -15,10 +17,10 @@ func TestGappyState(t *testing.T) {
t.Log("Alice creates a room")
firstRoomName := "Romeo Oscar Oscar Mike"
roomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": firstRoomName})
roomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": firstRoomName})
t.Log("Alice sends a message into that room")
firstMessageID := alice.SendEventSynced(t, roomID, Event{
firstMessageID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -50,19 +52,23 @@ func TestGappyState(t *testing.T) {
)
t.Log("Alice logs out of her first device.")
alice.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "logout"})
alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "logout"})
t.Log("Alice logs in again on her second device.")
alice.Login(t, "password", "device2")
t.Log("Alice changes the room name while the proxy isn't polling.")
nameContent := map[string]interface{}{"name": "potato"}
alice.SetState(t, roomID, "m.room.name", "", nameContent)
alice.Unsafe_SendEventUnsynced(t, roomID, b.Event{
Type: "m.room.name",
StateKey: ptr(""),
Content: nameContent,
})
t.Log("Alice sends lots of message events (more than the poller will request in a timeline.")
var latestMessageID string
for i := 0; i < 51; i++ {
latestMessageID = alice.SendEventUnsynced(t, roomID, Event{
latestMessageID = alice.Unsafe_SendEventUnsynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",

View File

@ -2,9 +2,11 @@ package syncv3_test
import (
"fmt"
"testing"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
"testing"
)
func TestInvitesFromIgnoredUsersOmitted(t *testing.T) {
@ -13,16 +15,16 @@ func TestInvitesFromIgnoredUsersOmitted(t *testing.T) {
nigel := registerNamedUser(t, "nigel")
t.Log("Nigel create two public rooms. Bob joins both.")
room1 := nigel.CreateRoom(t, map[string]any{"preset": "public_chat", "name": "room 1"})
room2 := nigel.CreateRoom(t, map[string]any{"preset": "public_chat", "name": "room 2"})
room1 := nigel.MustCreateRoom(t, map[string]any{"preset": "public_chat", "name": "room 1"})
room2 := nigel.MustCreateRoom(t, map[string]any{"preset": "public_chat", "name": "room 2"})
bob.JoinRoom(t, room1, nil)
bob.JoinRoom(t, room2, nil)
t.Log("Alice makes a room for dumping sentinel messages.")
aliceRoom := alice.CreateRoom(t, map[string]any{"preset": "private_chat"})
aliceRoom := alice.MustCreateRoom(t, map[string]any{"preset": "private_chat"})
t.Log("Alice ignores Nigel.")
alice.SetGlobalAccountData(t, "m.ignored_user_list", map[string]any{
alice.MustSetGlobalAccountData(t, "m.ignored_user_list", map[string]any{
"ignored_users": map[string]any{
nigel.UserID: map[string]any{},
},
@ -35,7 +37,7 @@ func TestInvitesFromIgnoredUsersOmitted(t *testing.T) {
bob.SlidingSyncUntilMembership(t, "", room1, alice, "invite")
t.Log("Alice sends a sentinel message in her private room.")
sentinel := alice.SendEventSynced(t, aliceRoom, Event{
sentinel := alice.SendEventSynced(t, aliceRoom, b.Event{
Type: "m.room.message",
Content: map[string]any{
"body": "Hello, world!",
@ -69,7 +71,7 @@ func TestInvitesFromIgnoredUsersOmitted(t *testing.T) {
bob.SlidingSyncUntilMembership(t, "", room1, alice, "invite")
t.Log("Alice sends a sentinel message in her private room.")
sentinel = alice.SendEventSynced(t, aliceRoom, Event{
sentinel = alice.SendEventSynced(t, aliceRoom, b.Event{
Type: "m.room.message",
Content: map[string]any{
"body": "Hello, world, again",

View File

@ -3,6 +3,7 @@ package syncv3_test
import (
"testing"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
@ -14,12 +15,12 @@ func TestLazyLoading(t *testing.T) {
sentinel := registerNewUser(t) // dummy user to ensure that the proxy has processed sent events
// all 3 join the room and say something
roomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
roomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
bob.JoinRoom(t, roomID, nil)
charlie.JoinRoom(t, roomID, nil)
sentinel.JoinRoom(t, roomID, nil)
alice.SendEventSynced(t, roomID, Event{
alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "Hello world",
@ -27,7 +28,7 @@ func TestLazyLoading(t *testing.T) {
},
})
bob.SendEventSynced(t, roomID, Event{
bob.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "Hello world",
@ -35,7 +36,7 @@ func TestLazyLoading(t *testing.T) {
},
})
lastEventID := charlie.SendEventSynced(t, roomID, Event{
lastEventID := charlie.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "Hello world",
@ -142,7 +143,7 @@ func TestLazyLoading(t *testing.T) {
}))
// alice now sends a message
aliceEventID := alice.SendEventSynced(t, roomID, Event{Type: "m.room.message", Content: map[string]interface{}{"body": "hello", "msgtype": "m.text"}})
aliceEventID := alice.SendEventSynced(t, roomID, b.Event{Type: "m.room.message", Content: map[string]interface{}{"body": "hello", "msgtype": "m.text"}})
sentinel.SlidingSyncUntilEventID(t, "", roomID, aliceEventID)
// bob, who didn't previously get alice's m.room.member event, should now see this
@ -161,7 +162,7 @@ func TestLazyLoading(t *testing.T) {
}))
// alice sends another message
aliceEventID2 := alice.SendEventSynced(t, roomID, Event{Type: "m.room.message", Content: map[string]interface{}{"body": "hello2", "msgtype": "m.text"}})
aliceEventID2 := alice.SendEventSynced(t, roomID, b.Event{Type: "m.room.message", Content: map[string]interface{}{"body": "hello2", "msgtype": "m.text"}})
sentinel.SlidingSyncUntilEventID(t, "", roomID, aliceEventID2)
// bob, who had just got alice's m.room.member event, shouldn't see it again.

View File

@ -2,12 +2,14 @@ package syncv3_test
import (
"fmt"
"github.com/matrix-org/sliding-sync/sync3/extensions"
"github.com/tidwall/gjson"
"sync"
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3/extensions"
"github.com/tidwall/gjson"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
@ -20,13 +22,13 @@ func TestMultipleLists(t *testing.T) {
var encryptedRoomIDs []string
var unencryptedRoomIDs []string
for i := 0; i < 10; i++ {
unencryptedRoomID := alice.CreateRoom(t, map[string]interface{}{
unencryptedRoomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
unencryptedRoomIDs = append([]string{unencryptedRoomID}, unencryptedRoomIDs...) // push in array
encryptedRoomID := alice.CreateRoom(t, map[string]interface{}{
encryptedRoomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"initial_state": []Event{
"initial_state": []b.Event{
NewEncryptionEvent(),
},
})
@ -164,11 +166,11 @@ func TestMultipleListsDMUpdate(t *testing.T) {
// make 5 group rooms and make 5 DMs rooms. Room 0 is most recent to ease checks
for i := 0; i < 5; i++ {
dmUserID := fmt.Sprintf("@dm_%d:synapse", i) // TODO: domain brittle
groupRoomID := alice.CreateRoom(t, map[string]interface{}{
groupRoomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
groupRoomIDs = append([]string{groupRoomID}, groupRoomIDs...) // push in array
dmRoomID := alice.CreateRoom(t, map[string]interface{}{
dmRoomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "trusted_private_chat",
"is_direct": true,
"invite": []string{dmUserID},
@ -178,7 +180,7 @@ func TestMultipleListsDMUpdate(t *testing.T) {
time.Sleep(time.Millisecond) // ensure timestamp changes
}
// set the account data
alice.SetGlobalAccountData(t, "m.direct", dmContent)
alice.MustSetGlobalAccountData(t, "m.direct", dmContent)
// request 2 lists, one set DM, one set no DM
res := alice.SlidingSync(t, sync3.Request{
@ -222,7 +224,7 @@ func TestMultipleListsDMUpdate(t *testing.T) {
}))
// now bring the last DM room to the top with a notif
pingEventID := alice.SendEventSynced(t, dmRoomIDs[len(dmRoomIDs)-1], Event{
pingEventID := alice.SendEventSynced(t, dmRoomIDs[len(dmRoomIDs)-1], b.Event{
Type: "m.room.message",
Content: map[string]interface{}{"body": "ping", "msgtype": "m.text"},
})
@ -269,7 +271,7 @@ func TestNewListMidConnection(t *testing.T) {
var roomIDs []string
// make rooms
for i := 0; i < 4; i++ {
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
roomIDs = append([]string{roomID}, roomIDs...) // push in array
@ -319,7 +321,7 @@ func TestMultipleOverlappingLists(t *testing.T) {
"preset": "private_chat",
}
if isEncrypted {
createContent["initial_state"] = []Event{
createContent["initial_state"] = []b.Event{
NewEncryptionEvent(),
}
}
@ -327,7 +329,7 @@ func TestMultipleOverlappingLists(t *testing.T) {
createContent["is_direct"] = true
createContent["invite"] = []string{dmUserID}
}
roomID := alice.CreateRoom(t, createContent)
roomID := alice.MustCreateRoom(t, createContent)
time.Sleep(time.Millisecond)
if isDM {
var roomIDs []string
@ -346,7 +348,7 @@ func TestMultipleOverlappingLists(t *testing.T) {
// set the account data
t.Logf("DM rooms: %v", dmRoomIDs)
t.Logf("Encrypted rooms: %v", encryptedRoomIDs)
alice.SetGlobalAccountData(t, "m.direct", dmContent)
alice.MustSetGlobalAccountData(t, "m.direct", dmContent)
// seed the proxy: so we can get timeline correctly as it uses limit:1 initially.
alice.SlidingSync(t, sync3.Request{})
@ -357,7 +359,7 @@ func TestMultipleOverlappingLists(t *testing.T) {
// - This ping message (always)
roomToEventID := make(map[string]string, len(allRoomIDs))
for i := len(allRoomIDs) - 1; i >= 0; i-- {
roomToEventID[allRoomIDs[i]] = alice.SendEventSynced(t, allRoomIDs[i], Event{
roomToEventID[allRoomIDs[i]] = alice.SendEventSynced(t, allRoomIDs[i], b.Event{
Type: "m.room.message",
Content: map[string]interface{}{"body": "ping", "msgtype": "m.text"},
})
@ -539,7 +541,7 @@ func TestNot500OnNewRooms(t *testing.T) {
},
},
})
alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
alice.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
@ -556,7 +558,7 @@ func TestNot500OnNewRooms(t *testing.T) {
},
},
}, WithPos(res.Pos))
alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
// should not 500
alice.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{
@ -594,7 +596,7 @@ func TestNewRoomNameCalculations(t *testing.T) {
go func() {
for i := range ch {
roomName := fmt.Sprintf("room %d", i)
roomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": roomName})
roomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": roomName})
roomIDToName.Store(roomID, roomName)
}
}()
@ -698,7 +700,7 @@ func TestChangeSortOrder(t *testing.T) {
}
for i, name := range roomNames {
roomIDs[i] = alice.CreateRoom(t, map[string]interface{}{
roomIDs[i] = alice.MustCreateRoom(t, map[string]interface{}{
"name": name,
})
// we cannot guarantee we will see the right state yet, so just keep track of the room names
@ -739,7 +741,7 @@ func TestShrinkRange(t *testing.T) {
var roomIDs []string // most recent first
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond) // ensure creation timestamp changes
roomIDs = append([]string{alice.CreateRoom(t, map[string]interface{}{
roomIDs = append([]string{alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": fmt.Sprintf("Room %d", i),
})}, roomIDs...)
@ -775,7 +777,7 @@ func TestExpandRange(t *testing.T) {
var roomIDs []string // most recent first
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond) // ensure creation timestamp changes
roomIDs = append([]string{alice.CreateRoom(t, map[string]interface{}{
roomIDs = append([]string{alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": fmt.Sprintf("Room %d", i),
})}, roomIDs...)
@ -809,7 +811,7 @@ func TestMultipleSameList(t *testing.T) {
var roomIDs []string // most recent first
for i := 0; i < 16; i++ {
time.Sleep(time.Millisecond) // ensure creation timestamp changes
roomIDs = append([]string{alice.CreateRoom(t, map[string]interface{}{
roomIDs = append([]string{alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": fmt.Sprintf("Room %d", i),
})}, roomIDs...)
@ -865,14 +867,14 @@ func TestBumpEventTypesHandling(t *testing.T) {
charlie := registerNamedUser(t, "charlie")
t.Log("Alice creates two rooms")
room1 := alice.CreateRoom(
room1 := alice.MustCreateRoom(
t,
map[string]interface{}{
"preset": "public_chat",
"name": "room1",
},
)
room2 := alice.CreateRoom(
room2 := alice.MustCreateRoom(
t,
map[string]interface{}{
"preset": "public_chat",
@ -885,14 +887,14 @@ func TestBumpEventTypesHandling(t *testing.T) {
bob.JoinRoom(t, room2, nil)
t.Log("Bob sends a message in room 2 then room 1.")
bob.SendEventSynced(t, room2, Event{
bob.SendEventSynced(t, room2, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "Hi room 2",
"msgtype": "m.text",
},
})
bob.SendEventSynced(t, room1, Event{
bob.SendEventSynced(t, room1, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "Hello world",
@ -1017,18 +1019,18 @@ func TestBumpEventTypesInOverlappingLists(t *testing.T) {
bob := registerNamedUser(t, "bob")
t.Log("Alice creates four rooms")
room1 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room1"})
room2 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room2"})
room3 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room3"})
room4 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room4"})
room1 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room1"})
room2 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room2"})
room3 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room3"})
room4 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room4"})
t.Log("Alice writes a message in all four rooms.")
// Note: all lists bump on messages, so this will ensure the recency order is sensible.
helloWorld := map[string]interface{}{"body": "Hello world", "msgtype": "m.text"}
alice.SendEventUnsynced(t, room1, Event{Type: "m.room.message", Content: helloWorld})
alice.SendEventUnsynced(t, room2, Event{Type: "m.room.message", Content: helloWorld})
alice.SendEventUnsynced(t, room3, Event{Type: "m.room.message", Content: helloWorld})
alice.SendEventSynced(t, room4, Event{Type: "m.room.message", Content: helloWorld})
alice.Unsafe_SendEventUnsynced(t, room1, b.Event{Type: "m.room.message", Content: helloWorld})
alice.Unsafe_SendEventUnsynced(t, room2, b.Event{Type: "m.room.message", Content: helloWorld})
alice.Unsafe_SendEventUnsynced(t, room3, b.Event{Type: "m.room.message", Content: helloWorld})
alice.SendEventSynced(t, room4, b.Event{Type: "m.room.message", Content: helloWorld})
t.Log("Alice requests a sync with three lists: one bumping on messages, a second bumping on messages and memberships, and a third bumping on all events.")
const listMsg = "message"
@ -1093,7 +1095,11 @@ func TestBumpEventTypesInOverlappingLists(t *testing.T) {
}))
t.Log("Alice sets a room topic in room 3, and syncs until she sees the topic.")
topicEventID := alice.SetState(t, room3, "m.room.topic", "", map[string]interface{}{"topic": "spicy meatballs"})
topicEventID := alice.Unsafe_SendEventUnsynced(t, room3, b.Event{
Type: "m.room.topic",
StateKey: ptr(""),
Content: map[string]interface{}{"topic": "spicy meatballs"},
})
res = alice.SlidingSyncUntilEventID(t, res.Pos, room3, topicEventID)
t.Logf("Alice sees room3 bump in the %s list only", listAll)
@ -1104,7 +1110,7 @@ func TestBumpEventTypesInOverlappingLists(t *testing.T) {
}))
t.Logf("Alice sends a message in room 2, and syncs until she sees it.")
msgEventID := alice.SendEventUnsynced(t, room2, Event{Type: "m.room.message", Content: helloWorld})
msgEventID := alice.Unsafe_SendEventUnsynced(t, room2, b.Event{Type: "m.room.message", Content: helloWorld})
res = alice.SlidingSyncUntilEventID(t, res.Pos, room2, msgEventID)
t.Logf("Alice sees room2 bump in all lists")
@ -1121,25 +1127,33 @@ func TestBumpEventTypesDoesntLeakOnNewConnAfterJoin(t *testing.T) {
bob := registerNamedUser(t, "bob")
t.Log("Alice creates a room and sends a secret state event.")
room1 := alice.CreateRoom(
room1 := alice.MustCreateRoom(
t,
map[string]interface{}{
"preset": "public_chat",
"name": "room1",
},
)
alice.SetState(t, room1, "secret", "", map[string]interface{}{})
alice.Unsafe_SendEventUnsynced(t, room1, b.Event{
Type: "secret",
StateKey: ptr(""),
Content: map[string]interface{}{},
})
t.Log("Bob creates a room and sends a secret state event.")
time.Sleep(1 * time.Millisecond)
room2 := bob.CreateRoom(
room2 := bob.MustCreateRoom(
t,
map[string]interface{}{
"preset": "public_chat",
"name": "room1",
},
)
bob.SetState(t, room2, "secret", "", map[string]interface{}{})
bob.Unsafe_SendEventUnsynced(t, room2, b.Event{
Type: "secret",
StateKey: ptr(""),
Content: map[string]interface{}{},
})
t.Log("Alice invites Bob, who accepts.")
alice.InviteRoom(t, room1, bob.UserID)
@ -1184,25 +1198,33 @@ func TestBumpEventTypesDoesntLeakOnNewConnAfterInvite(t *testing.T) {
bob := registerNamedUser(t, "bob")
t.Log("Alice creates a room and sends a secret state event.")
room1 := alice.CreateRoom(
room1 := alice.MustCreateRoom(
t,
map[string]interface{}{
"preset": "public_chat",
"name": "room1",
},
)
alice.SetState(t, room1, "secret", "", map[string]interface{}{})
alice.Unsafe_SendEventUnsynced(t, room1, b.Event{
Type: "secret",
StateKey: ptr(""),
Content: map[string]interface{}{},
})
t.Log("Bob creates a room and sends a secret state event.")
time.Sleep(1 * time.Millisecond)
room2 := bob.CreateRoom(
room2 := bob.MustCreateRoom(
t,
map[string]interface{}{
"preset": "public_chat",
"name": "room1",
},
)
bob.SetState(t, room2, "secret", "", map[string]interface{}{})
bob.Unsafe_SendEventUnsynced(t, room2, b.Event{
Type: "secret",
StateKey: ptr(""),
Content: map[string]interface{}{},
})
t.Log("Alice invites Bob, who does not respond.")
alice.InviteRoom(t, room1, bob.UserID)
@ -1245,9 +1267,9 @@ func TestRangeOutsideTotalRooms(t *testing.T) {
alice := registerNewUser(t)
t.Log("Alice makes three public rooms.")
room0 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "A"})
room1 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "B"})
room2 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "C"})
room0 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "A"})
room1 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "B"})
room2 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "C"})
t.Log("Alice initial syncs, requesting room ranges [0, 1] and [8, 9]")
syncRes := alice.SlidingSync(t, sync3.Request{
@ -1331,24 +1353,24 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
chris.SetAvatar(t, chrisAvatar)
t.Log("Alice makes a public room, a DM with herself, a DM with Bob, a DM with Chris, and a group-DM with Bob and Chris.")
public := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
public := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
// TODO: you can create a DM with yourself e.g. as below. It probably ought to have
// your own face as an avatar.
// dmAlice := alice.CreateRoom(t, map[string]interface{}{
// dmAlice := alice.MustCreateRoom(t, map[string]interface{}{
// "preset": "trusted_private_chat",
// "is_direct": true,
// })
dmBob := alice.CreateRoom(t, map[string]interface{}{
dmBob := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "trusted_private_chat",
"is_direct": true,
"invite": []string{bob.UserID},
})
dmChris := alice.CreateRoom(t, map[string]interface{}{
dmChris := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "trusted_private_chat",
"is_direct": true,
"invite": []string{chris.UserID},
})
dmBobChris := alice.CreateRoom(t, map[string]interface{}{
dmBobChris := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "trusted_private_chat",
"is_direct": true,
"invite": []string{bob.UserID, chris.UserID},
@ -1380,7 +1402,7 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
t.Run("Avatar not resent on message", func(t *testing.T) {
t.Log("Bob sends a sentinel message.")
sentinel := bob.SendEventSynced(t, dmBob, Event{
sentinel := bob.SendEventSynced(t, dmBob, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "Hello world",
@ -1497,8 +1519,12 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
t.Run("Explicit avatar propagates in non-DM room", func(t *testing.T) {
t.Log("Alice sets an avatar for the public room.")
publicAvatar := uploadAvatar(alice, "public.png")
alice.SetState(t, public, "m.room.avatar", "", map[string]interface{}{
alice.Unsafe_SendEventUnsynced(t, public, b.Event{
Type: "m.room.avatar",
StateKey: ptr(""),
Content: map[string]interface{}{
"url": publicAvatar,
},
})
t.Log("Alice syncs until she sees that avatar.")
res = alice.SlidingSyncUntil(
@ -1512,8 +1538,12 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
t.Log("Alice changes the avatar for the public room.")
publicAvatar2 := uploadAvatar(alice, "public2.png")
alice.SetState(t, public, "m.room.avatar", "", map[string]interface{}{
alice.Unsafe_SendEventUnsynced(t, public, b.Event{
Type: "m.room.avatar",
StateKey: ptr(""),
Content: map[string]interface{}{
"url": publicAvatar2,
},
})
t.Log("Alice syncs until she sees that avatar.")
res = alice.SlidingSyncUntil(
@ -1526,7 +1556,11 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
)
t.Log("Alice removes the avatar for the public room.")
alice.SetState(t, public, "m.room.avatar", "", map[string]interface{}{})
alice.Unsafe_SendEventUnsynced(t, public, b.Event{
Type: "m.room.avatar",
StateKey: ptr(""),
Content: map[string]interface{}{},
})
t.Log("Alice syncs until she sees that avatar vanish.")
res = alice.SlidingSyncUntil(
t,
@ -1559,8 +1593,12 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
t.Log("Chris gives their DM a bespoke avatar.")
dmAvatar := uploadAvatar(chris, "dm.png")
chris.SetState(t, dmChris, "m.room.avatar", "", map[string]interface{}{
chris.Unsafe_SendEventUnsynced(t, dmChris, b.Event{
Type: "m.room.avatar",
StateKey: ptr(""),
Content: map[string]interface{}{
"url": dmAvatar,
},
})
t.Log("Alice syncs until she sees that avatar.")
@ -1586,15 +1624,23 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
t.Log("Chris updates the DM's avatar.")
dmAvatar2 := uploadAvatar(chris, "dm2.png")
chris.SetState(t, dmChris, "m.room.avatar", "", map[string]interface{}{
chris.Unsafe_SendEventUnsynced(t, dmChris, b.Event{
Type: "m.room.avatar",
StateKey: ptr(""),
Content: map[string]interface{}{
"url": dmAvatar2,
},
})
t.Log("Alice syncs until she sees that avatar.")
res = alice.SlidingSyncUntil(t, res.Pos, sync3.Request{}, m.MatchRoomSubscription(dmChris, m.MatchRoomAvatar(dmAvatar2)))
t.Log("Chris removes the DM's avatar.")
chris.SetState(t, dmChris, "m.room.avatar", "", map[string]interface{}{})
chris.Unsafe_SendEventUnsynced(t, dmChris, b.Event{
Type: "m.room.avatar",
StateKey: ptr(""),
Content: map[string]interface{}{},
})
t.Log("Alice syncs until the DM avatar returns to Chris's most recent avatar.")
res = alice.SlidingSyncUntil(t, res.Pos, sync3.Request{}, m.MatchRoomSubscription(dmChris, m.MatchRoomAvatar(chris.AvatarURL)))
@ -1603,7 +1649,7 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
t.Run("Changing DM flag", func(t *testing.T) {
t.Skip("TODO: unimplemented")
t.Log("Alice clears the DM flag on Bob's room.")
alice.SetGlobalAccountData(t, "m.direct", map[string]interface{}{
alice.MustSetGlobalAccountData(t, "m.direct", map[string]interface{}{
"content": map[string][]string{
bob.UserID: {}, // no dmBob here
chris.UserID: {dmChris, dmBobChris},
@ -1636,7 +1682,7 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
}))
t.Log("Alice sets the DM flag on Bob's room.")
alice.SetGlobalAccountData(t, "m.direct", map[string]interface{}{
alice.MustSetGlobalAccountData(t, "m.direct", map[string]interface{}{
"content": map[string][]string{
bob.UserID: {dmBob}, // dmBob reinstated
chris.UserID: {dmChris, dmBobChris},
@ -1672,7 +1718,7 @@ func TestAvatarFieldInRoomResponse(t *testing.T) {
t.Run("See avatar when invited", func(t *testing.T) {
t.Log("Chris invites Alice to a DM.")
dmInvited := chris.CreateRoom(t, map[string]interface{}{
dmInvited := chris.MustCreateRoom(t, map[string]interface{}{
"preset": "trusted_private_chat",
"is_direct": true,
"invite": []string{alice.UserID},

View File

@ -3,7 +3,6 @@ package syncv3_test
import (
"encoding/json"
"fmt"
"net/url"
"os"
"reflect"
"sort"
@ -12,6 +11,7 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
"github.com/tidwall/gjson"
@ -33,13 +33,6 @@ func TestMain(m *testing.M) {
os.Exit(exitCode)
}
func WithPos(pos string) RequestOpt {
return WithQueries(url.Values{
"pos": []string{pos},
"timeout": []string{"500"}, // 0.5s
})
}
func assertEventsEqual(t *testing.T, wantList []Event, gotList []json.RawMessage) {
t.Helper()
err := eventsEqual(wantList, gotList)
@ -212,11 +205,13 @@ func registerNewUser(t *testing.T) *CSAPI {
func registerNamedUser(t *testing.T, localpartPrefix string) *CSAPI {
// create user
localpart := fmt.Sprintf("%s-%d-%d", localpartPrefix, time.Now().Unix(), atomic.AddUint64(&userCounter, 1))
httpClient := NewLoggedClient(t, "localhost", nil)
httpClient := client.NewLoggedClient(t, "localhost", nil)
client := &CSAPI{
CSAPI: &client.CSAPI{
Client: httpClient,
BaseURL: homeserverBaseURL,
SyncUntilTimeout: 3 * time.Second,
},
}
client.UserID, client.AccessToken, client.DeviceID = client.RegisterUser(t, localpart, "password")

View File

@ -5,6 +5,8 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
"github.com/tidwall/gjson"
@ -15,19 +17,19 @@ func TestRoomStateTransitions(t *testing.T) {
bob := registerNewUser(t)
// make 4 rooms and set bob's membership state in each to a different value.
joinRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
joinRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
bob.JoinRoom(t, joinRoomID, nil)
kickRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
kickRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
bob.JoinRoom(t, kickRoomID, nil)
alice.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "rooms", kickRoomID, "kick"}, WithJSONBody(t, map[string]interface{}{
alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", kickRoomID, "kick"}, client.WithJSONBody(t, map[string]interface{}{
"user_id": bob.UserID,
}))
banRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
banRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
bob.JoinRoom(t, banRoomID, nil)
alice.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "rooms", banRoomID, "ban"}, WithJSONBody(t, map[string]interface{}{
alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", banRoomID, "ban"}, client.WithJSONBody(t, map[string]interface{}{
"user_id": bob.UserID,
}))
inviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
inviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
alice.InviteRoom(t, inviteRoomID, bob.UserID)
// seed the proxy with Alice data
@ -134,9 +136,9 @@ func TestInviteRejection(t *testing.T) {
// ensure that invite state correctly propagates. One room will already be in 'invite' state
// prior to the first proxy sync, whereas the 2nd will transition.
firstInviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "First"})
firstInviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "First"})
alice.InviteRoom(t, firstInviteRoomID, bob.UserID)
secondInviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "Second"})
secondInviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "Second"})
t.Logf("TestInviteRejection first %s second %s", firstInviteRoomID, secondInviteRoomID)
// sync as bob, we should see 1 invite
@ -169,10 +171,10 @@ func TestInviteRejection(t *testing.T) {
},
}))
_, since := bob.MustSync(t, SyncReq{})
_, since := bob.MustSync(t, client.SyncReq{})
// now invite bob
alice.InviteRoom(t, secondInviteRoomID, bob.UserID)
since = bob.MustSyncUntil(t, SyncReq{Since: since}, SyncInvitedTo(bob.UserID, secondInviteRoomID))
since = bob.MustSyncUntil(t, client.SyncReq{Since: since}, client.SyncInvitedTo(bob.UserID, secondInviteRoomID))
res = bob.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{
@ -203,7 +205,7 @@ func TestInviteRejection(t *testing.T) {
bob.LeaveRoom(t, firstInviteRoomID)
bob.LeaveRoom(t, secondInviteRoomID)
bob.MustSyncUntil(t, SyncReq{Since: since}, SyncLeftFrom(bob.UserID, secondInviteRoomID))
bob.MustSyncUntil(t, client.SyncReq{Since: since}, client.SyncLeftFrom(bob.UserID, secondInviteRoomID))
// TODO: proxy needs to have processed this event enough for it to be waiting for us
time.Sleep(100 * time.Millisecond)
@ -241,9 +243,9 @@ func TestInviteAcceptance(t *testing.T) {
// ensure that invite state correctly propagates. One room will already be in 'invite' state
// prior to the first proxy sync, whereas the 2nd will transition.
t.Logf("Alice creates two rooms and invites Bob to the first.")
firstInviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "First"})
firstInviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "First"})
alice.InviteRoom(t, firstInviteRoomID, bob.UserID)
secondInviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "Second"})
secondInviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": "Second"})
t.Logf("first %s second %s", firstInviteRoomID, secondInviteRoomID)
t.Log("Sync as Bob, requesting invites only. He should see 1 invite")
@ -353,7 +355,7 @@ func TestInviteRejectionTwice(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomName := "It's-a-me-invitio"
inviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": roomName})
inviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": roomName})
t.Logf("TestInviteRejectionTwice room %s", inviteRoomID)
// sync as bob, we see no invites yet.
@ -406,7 +408,7 @@ func TestLeavingRoomReturnsOneEvent(t *testing.T) {
for _, aliceSyncing := range []bool{false, true} {
t.Run(fmt.Sprintf("leaving a room returns one leave event (multiple poller=%v)", aliceSyncing), func(t *testing.T) {
inviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": roomName})
inviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": roomName})
t.Logf("TestLeavingRoomReturnsOneEvent room %s", inviteRoomID)
if aliceSyncing {
@ -476,7 +478,7 @@ func TestRejectingInviteReturnsOneEvent(t *testing.T) {
for _, aliceSyncing := range []bool{false, true} {
t.Run(fmt.Sprintf("rejecting an invite returns one leave event (multiple poller=%v)", aliceSyncing), func(t *testing.T) {
inviteRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": roomName})
inviteRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "private_chat", "name": roomName})
t.Logf("TestRejectingInviteReturnsOneEvent room %s", inviteRoomID)
if aliceSyncing {
@ -542,7 +544,7 @@ func TestHeroesOnMembershipChanges(t *testing.T) {
t.Run("nameless room uses heroes to calculate roomname", func(t *testing.T) {
// create a room without a name, to ensure we calculate the room name based on
// room heroes
roomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
roomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
bob.JoinRoom(t, roomID, []string{})
@ -571,7 +573,7 @@ func TestHeroesOnMembershipChanges(t *testing.T) {
}
// Send a message, the heroes shouldn't change
msgEv := bob.SendEventSynced(t, roomID, Event{
msgEv := bob.SendEventSynced(t, roomID, b.Event{
Type: "m.room.roomID",
Content: map[string]interface{}{"body": "Hello world", "msgtype": "m.text"},
})
@ -593,7 +595,7 @@ func TestHeroesOnMembershipChanges(t *testing.T) {
})
t.Run("named rooms don't have heroes", func(t *testing.T) {
namedRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "my room without heroes"})
namedRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "my room without heroes"})
// this makes sure that even if bob is joined, we don't return any heroes
bob.JoinRoom(t, namedRoomID, []string{})
@ -604,14 +606,18 @@ func TestHeroesOnMembershipChanges(t *testing.T) {
})
t.Run("rooms with aliases don't have heroes", func(t *testing.T) {
aliasRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
aliasRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
alias := fmt.Sprintf("#%s-%d:%s", t.Name(), time.Now().Unix(), alice.Domain)
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "directory", "room", alias},
WithJSONBody(t, map[string]any{"room_id": aliasRoomID}),
alice.MustDo(t, "PUT", []string{"_matrix", "client", "v3", "directory", "room", alias},
client.WithJSONBody(t, map[string]any{"room_id": aliasRoomID}),
)
alice.SetState(t, aliasRoomID, "m.room.canonical_alias", "", map[string]any{
alice.Unsafe_SendEventUnsynced(t, aliasRoomID, b.Event{
Type: "m.room.canonical_alias",
StateKey: ptr(""),
Content: map[string]any{
"alias": alias,
},
})
bob.JoinRoom(t, aliasRoomID, []string{})
@ -623,7 +629,7 @@ func TestHeroesOnMembershipChanges(t *testing.T) {
})
t.Run("can set heroes=true on room subscriptions", func(t *testing.T) {
subRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
subRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
bob.JoinRoom(t, subRoomID, []string{})
res := alice.SlidingSyncUntilMembership(t, "", subRoomID, bob, "join")
@ -636,7 +642,7 @@ func TestHeroesOnMembershipChanges(t *testing.T) {
})
t.Run("can set heroes=true in lists", func(t *testing.T) {
listRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
listRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
bob.JoinRoom(t, listRoomID, []string{})
res := alice.SlidingSyncUntil(t, "", sync3.Request{
@ -683,9 +689,9 @@ func TestMemberCounts(t *testing.T) {
bob := registerNewUser(t)
charlie := registerNewUser(t)
firstRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "First"})
firstRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "First"})
alice.InviteRoom(t, firstRoomID, bob.UserID)
secondRoomID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "Second"})
secondRoomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "Second"})
alice.InviteRoom(t, secondRoomID, bob.UserID)
charlie.JoinRoom(t, secondRoomID, nil)
t.Logf("first %s second %s", firstRoomID, secondRoomID)
@ -758,7 +764,7 @@ func TestMemberCounts(t *testing.T) {
}))
// sending a message shouldn't update the count as it wastes bandwidth
charlie.SendEventSynced(t, secondRoomID, Event{
charlie.SendEventSynced(t, secondRoomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{"body": "ping", "msgtype": "m.text"},
})
@ -779,7 +785,7 @@ func TestMemberCounts(t *testing.T) {
// leaving a room should update the count
charlie.LeaveRoom(t, secondRoomID)
bob.MustSyncUntil(t, SyncReq{}, SyncLeftFrom(charlie.UserID, secondRoomID))
bob.MustSyncUntil(t, client.SyncReq{}, client.SyncLeftFrom(charlie.UserID, secondRoomID))
res = bob.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{

View File

@ -5,6 +5,7 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
"github.com/tidwall/gjson"
@ -13,11 +14,11 @@ import (
func TestNumLive(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
eventID := alice.SendEventSynced(t, roomID, Event{
eventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -43,7 +44,7 @@ func TestNumLive(t *testing.T) {
))
// live event -> 1 num live
eventID2 := alice.SendEventSynced(t, roomID, Event{
eventID2 := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -72,11 +73,11 @@ func TestNumLive(t *testing.T) {
))
// now the big one -> 3 rooms, ask for top 2, bump 3rd room to top twice -> num_live=2
roomID2 := alice.CreateRoom(t, map[string]interface{}{
roomID2 := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID2, nil)
roomID3 := alice.CreateRoom(t, map[string]interface{}{
roomID3 := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID3, nil)
@ -98,14 +99,14 @@ func TestNumLive(t *testing.T) {
m.MatchV3SyncOp(0, 1, []string{roomID3, roomID2}),
)))
// now send 2 live events into roomID to bump it to the top
eventID3 := alice.SendEventSynced(t, roomID, Event{
eventID3 := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
"body": "bump 1",
},
})
eventID4 := alice.SendEventSynced(t, roomID, Event{
eventID4 := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -138,12 +139,12 @@ func TestNumLive(t *testing.T) {
func TestReqParamStarvation(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
numOtherRooms := 10
for i := 0; i < numOtherRooms; i++ {
bob.CreateRoom(t, map[string]interface{}{
bob.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
}
@ -172,7 +173,7 @@ func TestReqParamStarvation(t *testing.T) {
// We do this for the first few /syncs and don't dictate which response they should arrive
// in, as we do not know and cannot force the proxy to deliver the event in a particular response.
if i < 3 {
eventID := alice.SendEventSynced(t, roomID, Event{
eventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",

View File

@ -3,17 +3,21 @@ package syncv3_test
import (
"encoding/json"
"fmt"
"io"
"net/url"
"testing"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/complement/must"
"github.com/matrix-org/sliding-sync/sync3"
)
func TestPrevBatch(t *testing.T) {
client := registerNewUser(t)
cli := registerNewUser(t)
// create room
roomID := client.CreateRoom(t, map[string]interface{}{})
roomID := cli.MustCreateRoom(t, map[string]interface{}{})
var timeline []Event
// send messages
for i := 0; i < 30; i++ {
@ -24,12 +28,15 @@ func TestPrevBatch(t *testing.T) {
"msgtype": "m.text",
},
}
ev.ID = client.SendEventSynced(t, roomID, ev)
ev.ID = cli.SendEventSynced(t, roomID, b.Event{
Type: ev.Type,
Content: ev.Content,
})
timeline = append(timeline, ev)
}
// hit proxy
res := client.SlidingSync(t, sync3.Request{
res := cli.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
Ranges: sync3.SliceRanges{[2]int64{0, 10}},
@ -49,13 +56,22 @@ func TestPrevBatch(t *testing.T) {
assertEventsEqual(t, []Event{timeline[len(timeline)-1]}, room.Timeline)
// hit /messages with prev_batch token
msgRes := client.MustDoFunc(t, "GET", []string{"_matrix", "client", "v3", "rooms", roomID, "messages"}, WithQueries(url.Values{
msgRes := cli.MustDo(t, "GET", []string{"_matrix", "client", "v3", "rooms", roomID, "messages"}, client.WithQueries(url.Values{
"dir": []string{"b"},
"from": []string{room.PrevBatch},
"limit": []string{"10"},
}))
body, err := io.ReadAll(msgRes.Body)
msgRes.Body.Close()
must.NotError(t, "failed to read response body", err)
type MessagesBatch struct {
Chunk []json.RawMessage `json:"chunk"`
Start string `json:"start"`
End string `json:"end"`
}
var msgBody MessagesBatch
if err := json.Unmarshal(ParseJSON(t, msgRes), &msgBody); err != nil {
if err := json.Unmarshal(body, &msgBody); err != nil {
t.Fatalf("failed to unmarshal /messages response: %v", err)
}
// reverse it

View File

@ -5,6 +5,7 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/sync3/extensions"
"github.com/matrix-org/sliding-sync/testutils/m"
@ -14,11 +15,11 @@ import (
func TestReceipts(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
eventID := alice.SendEventSynced(t, roomID, Event{
eventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -73,13 +74,13 @@ func TestReceiptsLazy(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
charlie := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
charlie.JoinRoom(t, roomID, nil)
alice.SlidingSync(t, sync3.Request{}) // proxy begins tracking
eventID := alice.SendEventSynced(t, roomID, Event{
eventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -94,7 +95,7 @@ func TestReceiptsLazy(t *testing.T) {
// alice sends 5 new events, bob and alice ACK the last event
var fifthEventID string
for i := 0; i < 5; i++ {
fifthEventID = alice.SendEventSynced(t, roomID, Event{
fifthEventID = alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -108,7 +109,7 @@ func TestReceiptsLazy(t *testing.T) {
// alice sends another 5 events and ACKs nothing
var lastEventID string
for i := 0; i < 5; i++ {
lastEventID = alice.SendEventSynced(t, roomID, Event{
lastEventID = alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -171,12 +172,12 @@ func TestReceiptsLazy(t *testing.T) {
func TestReceiptsPrivate(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
eventID := alice.SendEventSynced(t, roomID, Event{
eventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -231,10 +232,10 @@ func TestReceiptsRespectsExtensionScope(t *testing.T) {
var syncResp *sync3.Response
t.Log("Alice creates four rooms.")
room1 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
room3 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 3"})
room4 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 4"})
room1 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
room3 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 3"})
room4 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 4"})
t.Logf("room1=%s room2=%s room3=%s room4=%s", room1, room2, room3, room4)
t.Log("Bob joins those rooms.")
@ -244,7 +245,7 @@ func TestReceiptsRespectsExtensionScope(t *testing.T) {
bob.JoinRoom(t, room4, nil)
t.Log("Alice posts a message to each room")
messageEvent := Event{
messageEvent := b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -323,8 +324,8 @@ func TestReceiptsOnRoomsOnly(t *testing.T) {
bob := registerNamedUser(t, "bob")
t.Log("Alice creates two rooms.")
room1 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
room1 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
t.Logf("room1=%s room2=%s", room1, room2)
t.Log("Bob joins those rooms.")
@ -332,7 +333,7 @@ func TestReceiptsOnRoomsOnly(t *testing.T) {
bob.JoinRoom(t, room2, nil)
t.Log("Alice posts a message to each room")
messageEvent := Event{
messageEvent := b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",

View File

@ -5,6 +5,8 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
"github.com/tidwall/gjson"
@ -12,9 +14,9 @@ import (
func TestRedactionsAreRedactedWherePossible(t *testing.T) {
alice := registerNamedUser(t, "alice")
room := alice.CreateRoom(t, map[string]any{"preset": "public_chat"})
room := alice.MustCreateRoom(t, map[string]any{"preset": "public_chat"})
eventID := alice.SendEventSynced(t, room, Event{
eventID := alice.SendEventSynced(t, room, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -40,7 +42,7 @@ func TestRedactionsAreRedactedWherePossible(t *testing.T) {
}))
// redact the event
redactionEventID := alice.RedactEvent(t, room, eventID)
redactionEventID := alice.MustSendRedaction(t, room, map[string]interface{}{}, eventID)
// see the redaction
alice.SlidingSyncUntilEventID(t, res.Pos, room, redactionEventID)
@ -83,21 +85,29 @@ func TestRedactingRoomStateIsReflectedInNextSync(t *testing.T) {
bob := registerNamedUser(t, "bob")
t.Log("Alice creates a room, then sets a room alias and name.")
room := alice.CreateRoom(t, map[string]any{
room := alice.MustCreateRoom(t, map[string]any{
"preset": "public_chat",
})
alias := fmt.Sprintf("#%s-%d:%s", t.Name(), time.Now().Unix(), alice.Domain)
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "directory", "room", alias},
WithJSONBody(t, map[string]any{"room_id": room}),
alice.MustDo(t, "PUT", []string{"_matrix", "client", "v3", "directory", "room", alias},
client.WithJSONBody(t, map[string]any{"room_id": room}),
)
aliasID := alice.SetState(t, room, "m.room.canonical_alias", "", map[string]any{
aliasID := alice.Unsafe_SendEventUnsynced(t, room, b.Event{
Type: "m.room.canonical_alias",
StateKey: ptr(""),
Content: map[string]interface{}{
"alias": alias,
},
})
const naughty = "naughty room for naughty people"
nameID := alice.SetState(t, room, "m.room.name", "", map[string]any{
nameID := alice.Unsafe_SendEventUnsynced(t, room, b.Event{
Type: "m.room.name",
StateKey: ptr(""),
Content: map[string]interface{}{
"name": naughty,
},
})
t.Log("Alice sliding syncs, subscribing to that room explicitly.")
@ -113,7 +123,7 @@ func TestRedactingRoomStateIsReflectedInNextSync(t *testing.T) {
m.MatchResponse(t, res, m.MatchRoomSubscription(room, m.MatchRoomName(naughty)))
t.Log("Alice redacts the room name.")
redactionID := alice.RedactEvent(t, room, nameID)
redactionID := alice.MustSendRedaction(t, room, map[string]interface{}{}, nameID)
t.Log("Alice syncs until she sees her redaction.")
res = alice.SlidingSyncUntil(t, res.Pos, sync3.Request{}, m.MatchRoomSubscription(
@ -126,15 +136,19 @@ func TestRedactingRoomStateIsReflectedInNextSync(t *testing.T) {
t.Log("Alice sets a room avatar.")
avatarURL := alice.UploadContent(t, smallPNG, "avatar.png", "image/png")
avatarID := alice.SetState(t, room, "m.room.avatar", "", map[string]interface{}{
avatarID := alice.Unsafe_SendEventUnsynced(t, room, b.Event{
Type: "m.room.avatar",
StateKey: ptr(""),
Content: map[string]interface{}{
"url": avatarURL,
},
})
t.Log("Alice waits to see the avatar.")
res = alice.SlidingSyncUntil(t, res.Pos, sync3.Request{}, m.MatchRoomSubscription(room, m.MatchRoomAvatar(avatarURL)))
t.Log("Alice redacts the avatar.")
redactionID = alice.RedactEvent(t, room, avatarID)
redactionID = alice.MustSendRedaction(t, room, map[string]interface{}{}, avatarID)
t.Log("Alice sees the avatar revert to blank.")
res = alice.SlidingSyncUntil(t, res.Pos, sync3.Request{}, m.MatchRoomSubscription(room, m.MatchRoomUnsetAvatar()))
@ -160,13 +174,13 @@ func TestRedactingRoomStateIsReflectedInNextSync(t *testing.T) {
bobJoinID := gjson.GetBytes(timeline[len(timeline)-1], "event_id").Str
t.Log("Alice redacts the alias.")
redactionID = alice.RedactEvent(t, room, aliasID)
redactionID = alice.MustSendRedaction(t, room, map[string]interface{}{}, aliasID)
t.Log("Alice sees the room name reset to Bob's display name.")
res = alice.SlidingSyncUntil(t, res.Pos, sync3.Request{}, m.MatchRoomSubscription(room, m.MatchRoomName(bobDisplayName)))
t.Log("Bob redacts his membership")
redactionID = bob.RedactEvent(t, room, bobJoinID)
redactionID = bob.MustSendRedaction(t, room, map[string]interface{}{}, bobJoinID)
t.Log("Alice sees the room name reset to Bob's username.")
res = alice.SlidingSyncUntil(t, res.Pos, sync3.Request{}, m.MatchRoomSubscription(room, m.MatchRoomName(bob.UserID)))

View File

@ -5,6 +5,8 @@ import (
"fmt"
"testing"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
@ -26,7 +28,7 @@ func TestSecurityLiveStreamEventLeftLeak(t *testing.T) {
eve := registerNewUser(t)
// Alice and Eve in the room
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
eve.JoinRoom(t, roomID, nil)
@ -62,12 +64,12 @@ func TestSecurityLiveStreamEventLeftLeak(t *testing.T) {
)))
// kick Eve
alice.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "kick"}, WithJSONBody(t, map[string]interface{}{
alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "kick"}, client.WithJSONBody(t, map[string]interface{}{
"user_id": eve.UserID,
}))
// send message as Alice, note it shouldn't go down Eve's v2 stream
sensitiveEventID := alice.SendEventSynced(t, roomID, Event{
sensitiveEventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.name",
StateKey: ptr(""),
Content: map[string]interface{}{
@ -157,12 +159,12 @@ func TestSecurityRoomSubscriptionLeak(t *testing.T) {
eve := registerNewUser(t)
// Alice in the room
alicePrivateRoomID := alice.CreateRoom(t, map[string]interface{}{
alicePrivateRoomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "private_chat",
})
// Eve is in an unrelated room
eveUnrelatedRoomID := eve.CreateRoom(t, map[string]interface{}{
eveUnrelatedRoomID := eve.MustCreateRoom(t, map[string]interface{}{
"preset": "private_chat",
})
@ -194,7 +196,7 @@ func TestSecurityRoomSubscriptionLeak(t *testing.T) {
}))
// Assert that live updates still don't feed through to Eve
alice.SendEventSynced(t, alicePrivateRoomID, Event{
alice.SendEventSynced(t, alicePrivateRoomID, b.Event{
Type: "m.room.name",
StateKey: ptr(""),
Content: map[string]interface{}{
@ -226,16 +228,16 @@ func TestSecuritySpaceDataLeak(t *testing.T) {
alice := registerNewUser(t)
eve := registerNewUser(t)
roomA := alice.CreateRoom(t, map[string]interface{}{
roomA := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"creation_content": map[string]string{
"type": "m.space",
},
})
roomB := alice.CreateRoom(t, map[string]interface{}{
roomB := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "private_chat",
})
alice.SendEventSynced(t, roomA, Event{
alice.SendEventSynced(t, roomA, b.Event{
Type: "m.space.child",
StateKey: &roomB,
Content: map[string]interface{}{
@ -273,17 +275,17 @@ func TestSecuritySpaceMetadataLeak(t *testing.T) {
alice := registerNewUser(t)
eve := registerNewUser(t)
roomA := alice.CreateRoom(t, map[string]interface{}{
roomA := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"creation_content": map[string]string{
"type": "m.space",
},
})
roomB := alice.CreateRoom(t, map[string]interface{}{
roomB := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
// Alice has a space A -> B
alice.SendEventSynced(t, roomA, Event{
alice.SendEventSynced(t, roomA, b.Event{
Type: "m.space.child",
StateKey: &roomB,
Content: map[string]interface{}{
@ -294,14 +296,14 @@ func TestSecuritySpaceMetadataLeak(t *testing.T) {
alice.SlidingSync(t, sync3.Request{})
// now Eve also has a space... C -> B
roomC := eve.CreateRoom(t, map[string]interface{}{
roomC := eve.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"creation_content": map[string]string{
"type": "m.space",
},
})
eve.JoinRoom(t, roomB, nil)
eve.SendEventSynced(t, roomC, Event{
eve.SendEventSynced(t, roomC, b.Event{
Type: "m.space.child",
StateKey: &roomB,
Content: map[string]interface{}{

View File

@ -4,6 +4,8 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
@ -21,46 +23,46 @@ import (
// spaces[A,B] => B,C,E
func TestSpacesFilter(t *testing.T) {
alice := registerNewUser(t)
parentA := alice.CreateRoom(t, map[string]interface{}{
parentA := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"creation_content": map[string]string{
"type": "m.space",
},
})
parentD := alice.CreateRoom(t, map[string]interface{}{
parentD := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"creation_content": map[string]string{
"type": "m.space",
},
})
roomB := alice.CreateRoom(t, map[string]interface{}{
roomB := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
roomC := alice.CreateRoom(t, map[string]interface{}{
roomC := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
roomE := alice.CreateRoom(t, map[string]interface{}{
roomE := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
roomF := alice.CreateRoom(t, map[string]interface{}{
roomF := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
t.Logf("A: %s B: %s C: %s D: %s E: %s F: %s", parentA, roomB, roomC, parentD, roomE, roomF)
alice.SendEventSynced(t, parentA, Event{
alice.SendEventSynced(t, parentA, b.Event{
Type: "m.space.child",
StateKey: &roomB,
Content: map[string]interface{}{
"via": []string{"example.com"},
},
})
alice.SendEventSynced(t, parentA, Event{
alice.SendEventSynced(t, parentA, b.Event{
Type: "m.space.child",
StateKey: &roomC,
Content: map[string]interface{}{
"via": []string{"example.com"},
},
})
alice.SendEventSynced(t, parentD, Event{
alice.SendEventSynced(t, parentD, b.Event{
Type: "m.space.child",
StateKey: &roomE,
Content: map[string]interface{}{
@ -71,7 +73,7 @@ func TestSpacesFilter(t *testing.T) {
doSpacesListRequest := func(spaces []string, pos *string, listMatchers ...m.ListMatcher) *sync3.Response {
t.Helper()
var opts []RequestOpt
var opts []client.RequestOpt
if pos != nil {
opts = append(opts, WithPos(*pos))
}
@ -116,7 +118,7 @@ func TestSpacesFilter(t *testing.T) {
}
// now move F into D and re-query D
alice.SendEventSynced(t, parentD, Event{
alice.SendEventSynced(t, parentD, b.Event{
Type: "m.space.child",
StateKey: &roomF,
Content: map[string]interface{}{
@ -127,7 +129,7 @@ func TestSpacesFilter(t *testing.T) {
doInitialSpacesListRequest([]string{parentD}, []string{roomF, roomE})
// now remove B and re-query A
alice.SendEventSynced(t, parentA, Event{
alice.SendEventSynced(t, parentA, b.Event{
Type: "m.space.child",
StateKey: &roomB,
Content: map[string]interface{}{},
@ -136,7 +138,7 @@ func TestSpacesFilter(t *testing.T) {
res := doInitialSpacesListRequest([]string{parentA}, []string{roomC})
// now live stream an update to ensure it gets added
alice.SendEventSynced(t, parentA, Event{
alice.SendEventSynced(t, parentA, b.Event{
Type: "m.space.child",
StateKey: &roomB,
Content: map[string]interface{}{
@ -165,14 +167,14 @@ func TestSpacesFilter(t *testing.T) {
func TestSpacesFilterInvite(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
spaceRoomID := alice.CreateRoom(t, map[string]interface{}{
spaceRoomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Space Room",
"creation_content": map[string]string{
"type": "m.space",
},
})
normalRoomID := alice.CreateRoom(t, map[string]interface{}{
normalRoomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Normal Room",
})
@ -205,7 +207,7 @@ func TestAddingUnknownChildToSpace(t *testing.T) {
bob := registerNewUser(t)
t.Log("Alice creates a space and invites Bob.")
parentID := alice.CreateRoom(t, map[string]interface{}{
parentID := alice.MustCreateRoom(t, map[string]interface{}{
"type": "m.space",
"invite": []string{bob.UserID},
})
@ -226,9 +228,13 @@ func TestAddingUnknownChildToSpace(t *testing.T) {
})
t.Log("Alice creates a room and marks it as a child of the space.")
childID := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
childEventID := alice.SetState(t, parentID, "m.space.child", childID, map[string]interface{}{
childID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
childEventID := alice.Unsafe_SendEventUnsynced(t, parentID, b.Event{
Type: "m.space.child",
StateKey: ptr(childID),
Content: map[string]interface{}{
"via": []string{"localhost"},
},
})
t.Log("Bob syncs until he sees the m.space.child event in the space.")

View File

@ -4,6 +4,7 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
@ -13,7 +14,7 @@ func TestTimestamp(t *testing.T) {
bob := registerNewUser(t)
charlie := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
@ -67,7 +68,7 @@ func TestTimestamp(t *testing.T) {
// Send an event which should NOT bump Bobs timestamp, because it is not listed it
// any BumpEventTypes
emptyStateKey := ""
eventID := alice.SendEventSynced(t, roomID, Event{
eventID := alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.topic",
StateKey: &emptyStateKey,
Content: map[string]interface{}{
@ -85,7 +86,7 @@ func TestTimestamp(t *testing.T) {
expectedTs = gotTs
// Now send a message which bumps the timestamp in myFirstList
eventID = alice.SendEventSynced(t, roomID, Event{
eventID = alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -102,7 +103,7 @@ func TestTimestamp(t *testing.T) {
expectedTs = gotTs
// Now send a message which bumps the timestamp in mySecondList
eventID = alice.SendEventSynced(t, roomID, Event{
eventID = alice.SendEventSynced(t, roomID, b.Event{
Type: "m.reaction",
Content: map[string]interface{}{
"m.relates.to": map[string]interface{}{
@ -122,7 +123,7 @@ func TestTimestamp(t *testing.T) {
expectedTs = bobTimestampReaction
// Send another event which should NOT bump Bobs timestamp
eventID = alice.SendEventSynced(t, roomID, Event{
eventID = alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.name",
StateKey: &emptyStateKey,
Content: map[string]interface{}{

View File

@ -17,7 +17,11 @@ import (
func TestToDeviceDeliveryInitialLogin(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
bob.SendToDevice(t, "m.dummy", alice.UserID, alice.DeviceID, map[string]interface{}{})
bob.SendToDeviceMessages(t, "m.dummy", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{},
},
})
// loop until we see the event
loopUntilToDeviceEvent(t, alice, nil, "", "m.dummy", bob.UserID)
}
@ -33,7 +37,11 @@ func TestToDeviceDeliveryStream(t *testing.T) {
},
},
})
bob.SendToDevice(t, "m.dummy", alice.UserID, alice.DeviceID, map[string]interface{}{})
bob.SendToDeviceMessages(t, "m.dummy", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{},
},
})
// loop until we see the event
loopUntilToDeviceEvent(t, alice, res, res.Extensions.ToDevice.NextBatch, "m.dummy", bob.UserID)
@ -52,7 +60,11 @@ func TestToDeviceDeliveryReconnect(t *testing.T) {
},
},
})
bob.SendToDevice(t, "m.dummy", alice.UserID, alice.DeviceID, map[string]interface{}{})
bob.SendToDeviceMessages(t, "m.dummy", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{},
},
})
// loop until we see the event
loopUntilToDeviceEvent(t, alice, nil, "", "m.dummy", bob.UserID)
}
@ -65,18 +77,30 @@ func TestToDeviceDropStaleKeyRequestsInitial(t *testing.T) {
// send a few dummy messages, cancelling each other
for i := 0; i < sendMessages; i++ {
reqID := util.RandomString(8)
bob.SendToDevice(t, "m.room_key_request", alice.UserID, alice.DeviceID, map[string]interface{}{
bob.SendToDeviceMessages(t, "m.room_key_request", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{
"request_id": reqID,
"action": "request",
"requesting_device_id": "mydevice",
},
},
})
bob.SendToDevice(t, "m.room_key_request", alice.UserID, alice.DeviceID, map[string]interface{}{
bob.SendToDeviceMessages(t, "m.room_key_request", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{
"request_id": reqID,
"action": "request_cancellation",
"requesting_device_id": "mydevice",
},
},
})
}
bob.SendToDevice(t, "sentinel", alice.UserID, alice.DeviceID, map[string]interface{}{})
bob.SendToDeviceMessages(t, "sentinel", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{},
},
})
// Loop until we have the sentinel event, the rest should cancel out.
gotMessages, _ := loopUntilToDeviceEvent(t, alice, nil, "", "sentinel", bob.UserID)
wantCount := 1
@ -89,10 +113,14 @@ func TestToDeviceDropStaleKeyRequestsStreamNoDelete(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
bob.SendToDevice(t, "m.room_key_request", alice.UserID, alice.DeviceID, map[string]interface{}{
bob.SendToDeviceMessages(t, "m.room_key_request", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{
"request_id": "A",
"action": "request",
"requesting_device_id": "mydevice",
},
},
})
msgs1, res := loopUntilToDeviceEvent(t, alice, nil, "", "m.room_key_request", bob.UserID)
if len(msgs1) != 1 {
@ -100,10 +128,14 @@ func TestToDeviceDropStaleKeyRequestsStreamNoDelete(t *testing.T) {
}
// now send a cancellation: we should not delete the cancellation
bob.SendToDevice(t, "m.room_key_request", alice.UserID, alice.DeviceID, map[string]interface{}{
bob.SendToDeviceMessages(t, "m.room_key_request", map[string]map[string]map[string]interface{}{
alice.UserID: map[string]map[string]interface{}{
alice.DeviceID: map[string]interface{}{
"request_id": "A",
"action": "request_cancellation",
"requesting_device_id": "mydevice",
},
},
})
time.Sleep(100 * time.Millisecond)
msgs2, _ := loopUntilToDeviceEvent(t, alice, res, res.Extensions.ToDevice.NextBatch, "m.room_key_request", bob.UserID)

View File

@ -6,6 +6,8 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
"github.com/tidwall/gjson"
@ -14,7 +16,7 @@ import (
// tests that if we upgrade a room it is removed from the list. If we request old rooms it should be included.
func TestIncludeOldRooms(t *testing.T) {
client := registerNewUser(t)
roomID := client.CreateRoom(t, map[string]interface{}{})
roomID := client.MustCreateRoom(t, map[string]interface{}{})
res := client.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{
@ -158,23 +160,23 @@ func TestIncludeOldRoomsLongChain(t *testing.T) {
// seed the server with this client, we need to do this so the proxy has timeline history to
// return so we can assert events appear in the right rooms
res := client.SlidingSync(t, sync3.Request{})
roomA := client.CreateRoom(t, map[string]interface{}{})
client.SendEventSynced(t, roomA, Event{
roomA := client.MustCreateRoom(t, map[string]interface{}{})
client.SendEventSynced(t, roomA, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{"body": "A", "msgtype": "m.text"},
})
roomB := upgradeRoom(t, client, roomA)
eventB := client.SendEventSynced(t, roomB, Event{
eventB := client.SendEventSynced(t, roomB, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{"body": "B", "msgtype": "m.text"},
})
roomC := upgradeRoom(t, client, roomB)
client.SendEventSynced(t, roomC, Event{
client.SendEventSynced(t, roomC, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{"body": "C", "msgtype": "m.text"},
})
roomD := upgradeRoom(t, client, roomC)
eventD := client.SendEventSynced(t, roomD, Event{
eventD := client.SendEventSynced(t, roomD, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{"body": "D", "msgtype": "m.text"},
})
@ -266,7 +268,7 @@ func TestIncludeOldRoomsLongChain(t *testing.T) {
// test that if you have a list version and direct sub version of include_old_rooms, they get unioned correctly.
func TestIncludeOldRoomsSubscriptionUnion(t *testing.T) {
client := registerNewUser(t)
roomA := client.CreateRoom(t, map[string]interface{}{})
roomA := client.MustCreateRoom(t, map[string]interface{}{})
roomB := upgradeRoom(t, client, roomA)
// should union to timeline_limit=2, req_state=create+member+tombstone
@ -322,8 +324,8 @@ func TestIncludeOldRoomsSubscriptionUnion(t *testing.T) {
}))
}
func upgradeRoom(t *testing.T, client *CSAPI, roomID string) (newRoomID string) {
upgradeRes := client.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "upgrade"}, WithJSONBody(t, map[string]interface{}{
func upgradeRoom(t *testing.T, c *CSAPI, roomID string) (newRoomID string) {
upgradeRes := c.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "upgrade"}, client.WithJSONBody(t, map[string]interface{}{
"new_version": "9",
}))
var body map[string]interface{}

View File

@ -5,23 +5,24 @@ import (
"fmt"
"testing"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
func TestTransactionIDsAppear(t *testing.T) {
client := registerNewUser(t)
roomID := client.CreateRoom(t, map[string]interface{}{})
sendRes := client.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", "foobar"},
WithJSONBody(t, map[string]interface{}{
c := registerNewUser(t)
roomID := c.MustCreateRoom(t, map[string]interface{}{})
sendRes := c.MustDo(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", "foobar"},
client.WithJSONBody(t, map[string]interface{}{
"msgtype": "m.text",
"body": "Hello World!",
}))
body := ParseJSON(t, sendRes)
eventID := GetJSONFieldStr(t, body, "event_id")
body := client.ParseJSON(t, sendRes)
eventID := client.GetJSONFieldStr(t, body, "event_id")
// ensure initial syncs include the txn id
res := client.SlidingSync(t, sync3.Request{
res := c.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
Ranges: [][2]int64{{0, 10}},
@ -40,15 +41,15 @@ func TestTransactionIDsAppear(t *testing.T) {
}))
// now live stream another event and ensure that too has a txn ID
sendRes = client.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", "foobar2"},
WithJSONBody(t, map[string]interface{}{
sendRes = c.MustDo(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", "foobar2"},
client.WithJSONBody(t, map[string]interface{}{
"msgtype": "m.text",
"body": "Hello World 2!",
}))
body = ParseJSON(t, sendRes)
eventID = GetJSONFieldStr(t, body, "event_id")
body = client.ParseJSON(t, sendRes)
eventID = client.GetJSONFieldStr(t, body, "event_id")
res = client.SlidingSyncUntilEvent(t, res.Pos, sync3.Request{}, roomID, Event{ID: eventID})
res = c.SlidingSyncUntilEvent(t, res.Pos, sync3.Request{}, roomID, Event{ID: eventID})
m.MatchResponse(t, res, m.MatchRoomSubscriptionsStrict(map[string][]m.RoomMatcher{
roomID: {
matchTransactionID(t, eventID, "foobar2"),
@ -64,7 +65,7 @@ func TestTransactionIDsAppearWithMultiplePollers(t *testing.T) {
alice := registerNamedUser(t, "alice")
t.Log("Alice creates a room and syncs until she sees it.")
roomID := alice.CreateRoom(t, map[string]interface{}{})
roomID := alice.MustCreateRoom(t, map[string]interface{}{})
res := alice.SlidingSync(t, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
@ -95,13 +96,13 @@ func TestTransactionIDsAppearWithMultiplePollers(t *testing.T) {
t.Log("Alice sends a message with a transaction ID.")
const txnID = "foobar"
sendRes := alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", txnID},
WithJSONBody(t, map[string]interface{}{
sendRes := alice.MustDo(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", txnID},
client.WithJSONBody(t, map[string]interface{}{
"msgtype": "m.text",
"body": "Hello, world!",
}))
body := ParseJSON(t, sendRes)
eventID := GetJSONFieldStr(t, body, "event_id")
body := client.ParseJSON(t, sendRes)
eventID := client.GetJSONFieldStr(t, body, "event_id")
t.Log("Alice syncs on her main devices until she sees her message.")
res = alice.SlidingSyncUntilEventID(t, res.Pos, roomID, eventID)

View File

@ -8,6 +8,7 @@ import (
"testing"
"time"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/sync3/extensions"
"github.com/matrix-org/sliding-sync/testutils/m"
@ -17,7 +18,7 @@ import (
func TestTyping(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
@ -65,7 +66,7 @@ func TestTyping(t *testing.T) {
m.MatchResponse(t, res, m.MatchTyping(roomID, []string{bob.UserID, alice.UserID}))
// make sure if you type in a room not returned in the window it does not go through
roomID2 := alice.CreateRoom(t, map[string]interface{}{
roomID2 := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID2, nil)
@ -108,7 +109,7 @@ func TestTyping(t *testing.T) {
func TestTypingNoUpdate(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
@ -136,19 +137,19 @@ func TestTypingNoUpdate(t *testing.T) {
func TestTypingLazyLoad(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
alice.SendEventSynced(t, roomID, Event{
alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "hello world!",
"msgtype": "m.text",
},
})
alice.SendEventSynced(t, roomID, Event{
alice.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"body": "hello world!",
@ -202,8 +203,8 @@ func TestTypingRespectsExtensionScope(t *testing.T) {
// separate to the incremental sync behaviour (hits `AppendLive`)
t.Run("Can limit by room in an initial sync", func(t *testing.T) {
t.Log("Alice creates rooms 1 and 2. Bob joins both.")
room1 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
room1 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 1"})
room2 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 2"})
bob.JoinRoom(t, room1, nil)
bob.JoinRoom(t, room2, nil)
t.Logf("room1=%s room2=%s", room1, room2)
@ -244,8 +245,8 @@ func TestTypingRespectsExtensionScope(t *testing.T) {
t.Run("Can limit by list in an incremental sync", func(t *testing.T) {
t.Log("Alice creates rooms 3 and 4. Bob joins both.")
room3 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 3"})
room4 := alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 4"})
room3 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 3"})
room4 := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": "room 4"})
bob.JoinRoom(t, room3, nil)
bob.JoinRoom(t, room4, nil)
t.Logf("room3=%s room4=%s", room3, room4)
@ -300,7 +301,7 @@ func TestTypingRespectsExtensionScopeWithOmittedFields(t *testing.T) {
t.Log("Alice creates four rooms. Bob joins each one.")
rooms := make([]string, 4)
for i := 0; i < len(rooms); i++ {
rooms[i] = alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": fmt.Sprintf("room %d", i)})
rooms[i] = alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat", "name": fmt.Sprintf("room %d", i)})
bob.JoinRoom(t, rooms[i], nil)
}
t.Logf("rooms = %v", rooms)
@ -356,7 +357,7 @@ func TestTypingRespectsExtensionScopeWithOmittedFields(t *testing.T) {
}
t.Log("Bob sends a sentinel message.")
// Use room 2 because Alice explicitly subscribes to it
bobMsg := bob.SendEventSynced(t, rooms[2], Event{
bobMsg := bob.SendEventSynced(t, rooms[2], b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -388,7 +389,7 @@ func TestTypingRespectsExtensionScopeWithOmittedFields(t *testing.T) {
bob.SendTyping(t, room, true, 5000)
}
t.Log("Bob sends a sentinel message.")
bobMsg = bob.SendEventSynced(t, rooms[2], Event{
bobMsg = bob.SendEventSynced(t, rooms[2], b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -396,7 +397,6 @@ func TestTypingRespectsExtensionScopeWithOmittedFields(t *testing.T) {
},
})
t.Log("Alice now requests typing notifications in all windows, and explicitly in rooms 0 and 3.")
t.Log("Alice incremental syncs until she sees Bob's latest sentinel. She should see no ops.")
seenTyping := map[int]int{}

View File

@ -4,6 +4,8 @@ import (
"fmt"
"testing"
"github.com/matrix-org/complement/b"
"github.com/matrix-org/complement/client"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils/m"
)
@ -11,11 +13,11 @@ import (
func TestUnreadCountsUpdate(t *testing.T) {
alice := registerNewUser(t)
bob := registerNewUser(t)
roomID := alice.CreateRoom(t, map[string]interface{}{
roomID := alice.MustCreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})
bob.JoinRoom(t, roomID, nil)
eventID := bob.SendEventSynced(t, roomID, Event{
eventID := bob.SendEventSynced(t, roomID, b.Event{
Type: "m.room.message",
Content: map[string]interface{}{
"msgtype": "m.text",
@ -35,7 +37,7 @@ func TestUnreadCountsUpdate(t *testing.T) {
m.MatchRoomNotificationCount(1),
},
}))
alice.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "read_markers"}, WithJSONBody(t, map[string]interface{}{
alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "read_markers"}, client.WithJSONBody(t, map[string]interface{}{
"m.fully_read": eventID,
"m.read": eventID,
}))