The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

JMAP::Tester - a JMAP client made for testing JMAP servers

VERSION

version 0.011

OVERVIEW

Achtung! This library is in its really early days, so use it with that in mind.

JMAP::Tester is for testing JMAP servers. Okay? Okay!

JMAP::Tester calls the whole thing you get back from a JMAP server a "response" if it's an HTTP 200. Every JSON Array (of three entries -- go read the spec if you need to!) is called a Sentence. Runs of Sentences with the same client id are called Paragraphs.

You use the test client like this:

  my $jtest = JMAP::Tester->new({
    api_uri => 'https://jmap.local/account/123',
  });

  my $response = $jtest->request([
    [ getMailboxes => {} ],
    [ getMessageUpdates => { sinceState => "123" } ],
  ]);

  # This returns two Paragraph objects if there are exactly two paragraphs.
  # Otherwise, it throws an exception.
  my ($mbx_p, $msg_p) = $response->assert_n_paragraphs(2);

  # These get the single Sentence of each paragraph, asserting that there is
  # exactly one Sentence in each Paragraph, and that it's of the given type.
  my $mbx = $mbx_p->single('mailboxes');
  my $msg = $msg_p->single('messageUpdates');

  is( @{ $mbx->arguments->{list} }, 10, "we expect 10 mailboxes");
  ok( ! $msg->arguments->{hasMoreUpdates}, "we got all the msg updates needed");

By default, all the structures returned have been passed through JSON::Typist, so you may want to strip their type data before using normal Perl code on them. You can do that with:

  my $struct = $response->as_struct;   # gets the complete JSON data
  $jtest->strip_json_types( $struct ); # strips all the JSON::Typist types

Or more simply:

  my $struct = $response->as_stripped_struct;

There is also "as_stripped_pairs" in JMAP::Tester::Response.

ATTRIBUTES

default_arguments

This is a hashref of arguments to be put into each method call. It's especially useful for setting a default accountId. Values given in methods passed to request will override defaults. If the value is a reference to undef, then no value will be passed for that key.

In other words, in this situation:

  my $tester = JMAP::Tester->new({
    ...,
    default_arguments => { a => 1, b => 2, c => 3 },
  });

  $tester->request([
    [ eatPies => { a => 100, b => \undef } ],
  ]);

The request will effectively be:

  [ [ "eatPies", { "a": 100, "c": 3 }, "a" ] ]

METHODS

request

  my $result = $jtest->request([
    [ methodOne => { ... } ],
    [ methodTwo => { ... } ],
  ]);

This method takes an arrayref of method calls and sends them to the JMAP server. If the method calls have a third element (a client id) then it's left as-is. If no client id is given, one is generated. You can mix explicit and autogenerated client ids. They will never conflict.

The arguments to methods are JSON-encoded with a JSON::Typist-aware encoder, so JSON::Typist types can be used to ensure string or number types in the generated JSON. If an argument is a reference to undef, it will be removed before the method call is made. This lets you override a default by omission.

The return value is an object that does the JMAP::Tester::Result role, meaning it's got an is_success method that returns true or false. For now, at least, failures are JMAP::Tester::Result::Failure objects. More refined failure objects may exist in the future. Successful requests return JMAP::Tester::Response objects.

upload

  my $result = $tester->upload($mime_type, $blob_ref, \%arg);

This uploads the given blob, which should be given as a reference to a string.

The return value will either be a failure object or an upload result.

download

  my $result = $tester->download(\%arg);

Valid arguments are:

  blobId    - the blob to download (no default)
  accountId - the account for which we're downloading (no default)
  name      - the name we want the server to provide back (default: "download")

If the download URI template has a blobId or accountId placeholder but no argument for that is given to download, an exception will be thrown.

The return value will either be a failure object or an upload result.

simple_auth

  my $auth_struct = $tester->simple_auth($username, $password);

logout

  $tester->logout;

This method attempts to log out from the server by sending a DELETE request to the authentication URI.

AUTHOR

Ricardo SIGNES <rjbs@cpan.org>

CONTRIBUTORS

  • Alfie John <alfiej@fastmail.fm>

  • Matthew Horsfall <wolfsage@gmail.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by FastMail, Ltd.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.