Skip to content

Commit

Permalink
Add generic Alice/Bob test
Browse files Browse the repository at this point in the history
This uses a generic Client interface so it can work with both JS/FFI.

Currently only an FFI impl exists though.
  • Loading branch information
kegsay committed Nov 2, 2023
1 parent 42b8622 commit 79d8e94
Show file tree
Hide file tree
Showing 10 changed files with 461 additions and 2 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Complement for Rust SDK crypto.

**EXPERIMENTAL: As of Nov 2023 this repo is under active development currently so things will break constantly.**


### What is it? Why?

Expand All @@ -11,6 +13,16 @@ Why:
- To detect "unable to decrypt" failures and add regression tests for them.
- To date, there exists no test suite which meets the scope of Complement-Crypto.

### How do I run it?

You need to build Rust SDK FFI bindings _and_ JS SDK before you can get this to run. You also need a Complement homeserver image. When that is setup:

```
COMPLEMENT_BASE_IMAGE=homeserver:latest go test -v ./tests
```

TODO: consider checking in working builds so you can git clone and run. Git LFS for `libmatrix_sdk_ffi.so` given it's 60MB?

### JS SDK

Prerequisites:
Expand Down
66 changes: 66 additions & 0 deletions internal/api/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package api

import (
"testing"
"time"

"github.com/matrix-org/complement/client"
)

// Client represents a generic crypto client.
// It is an abstraction to allow tests to interact with JS and FFI bindings in an agnostic way.
type Client interface {
// Init is called prior to any test execution. Do any setup code here e.g run a browser.
// Call close() when the test terminates to clean up resources.
// TODO: will this be too slow if we spin up a browser for each test?
Init(t *testing.T) (close func())
// StartSyncing to begin syncing from sync v2 / sliding sync.
// Tests should call stopSyncing() at the end of the test.
StartSyncing(t *testing.T) (stopSyncing func())
// IsRoomEncrypted returns true if the room is encrypted. May return an error e.g if you
// provide a bogus room ID.
IsRoomEncrypted(roomID string) (bool, error)
// SendMessage sends the given text as an m.room.message with msgtype:m.text into the given
// room. Returns the event ID of the sent event.
SendMessage(t *testing.T, roomID, text string)
// Wait until an event with the given body is seen. Not all impls expose event IDs
// hence needing to use body as a proxy.
WaitUntilEventInRoom(t *testing.T, roomID, wantBody string) Waiter
}

// ClientCreationOpts are generic opts to use when creating crypto clients.
// Because this is generic, some features possible in some clients are unsupported here, notably
// you cannot provide an existing access_token to the FFI binding layer, hence you don't see
// an AccessToken field here.
type ClientCreationOpts struct {
// Required. The base URL of the homeserver.
BaseURL string
// Required. The user to login as.
UserID string
// Required. The password for this account.
Password string

// Optional. Set this to login with this device ID.
DeviceID string
}

func FromComplementClient(c *client.CSAPI, password string) ClientCreationOpts {
return ClientCreationOpts{
BaseURL: c.BaseURL,
UserID: c.UserID,
Password: password,
DeviceID: c.DeviceID,
}
}

type Event struct {
ID string
Text string // FFI bindings don't expose the content object
Sender string
// FFI bindings don't expose state key
// FFI bindings don't expose type
}

type Waiter interface {
Wait(t *testing.T, s time.Duration)
}
40 changes: 40 additions & 0 deletions internal/api/js.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package api

import (
"testing"
)

type JSClient struct{}

func NewJSClient(opts ClientCreationOpts) Client {
return nil
}

// Init is called prior to any test execution. Do any setup code here e.g run a browser.
// Call close() when the test terminates to clean up resources.
// TODO: will this be too slow if we spin up a browser for each test?
func (c *JSClient) Init(t *testing.T) (close func()) {
return
}

// StartSyncing to begin syncing from sync v2 / sliding sync.
// Tests should call stopSyncing() at the end of the test.
func (c *JSClient) StartSyncing(t *testing.T) (stopSyncing func()) {
return
}

// IsRoomEncrypted returns true if the room is encrypted. May return an error e.g if you
// provide a bogus room ID.
func (c *JSClient) IsRoomEncrypted(roomID string) (bool, error) {
return false, nil
}

// SendMessage sends the given text as an m.room.message with msgtype:m.text into the given
// room. Returns the event ID of the sent event.
func (c *JSClient) SendMessage(t *testing.T, roomID, text string) {
return
}

func (c *JSClient) WaitUntilEventInRoom(t *testing.T, roomID, wantBody string) Waiter {
return nil
}
Loading

0 comments on commit 79d8e94

Please sign in to comment.