summaryrefslogtreecommitdiff
path: root/yarns/000.yarn
blob: 57179bbe64d1804a679f1c31b31447552c1c6323 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
---
title: Effiapi test suite
author: Lars Wirzenius
...

[yarn]: https://liw.fi/cmdtest/

# Introduction

This chapter descibes the effiapi API, using [yarn][] automated
scenario tests. It is meant to be understandable to Effi sysadmins,
and those writing applications using the API, as well as be an
executable test suite for the API.

The API is a simple RESTful HTTP API using JSON. This means that:

* each API call is an HTTP request, with a response

* all data is represented as JSON in the body of the request of
  response

* metadata about the data is represeneted as HTTP headers

* standard HTTP verbs (POST, PUT, GET, DELETE) are used to indicate
  the action

* standard HTTP status codes are used to indicate result of the
  request (200 = OK, 404 = not found, etc)

Examples will be provided.

# Test scenarios

## Manage memberships

This section shows the API calls to manage a memberhip: to create the
member, to update and retrieve it, and to search memberships.

    SCENARIO Manage memberships

    GIVEN An effiapi instance

    WHEN admin requests GET /status
    THEN HTTP status is 200
    AND HTTP body matches { "resources": 0 }

    WHEN admin requests POST /memb with body { "fullname": "James Bond" }
    THEN HTTP status is 201
    AND the member id is ID

    WHEN admin requests GET /memb with header Muck-Id: ${ID}
    THEN HTTP status is 200
    AND HTTP body matches { "fullname": "James Bond" }

    FINALLY Effiapi is terminated

TODO:

* update
* delete
* search
* members can see their own data, and can't see each others'
* member follows authn link emailed to them

# Appendix: Yarn scenario step implementations

## Start and stop effiapi

    IMPLEMENTS GIVEN An effiapi instance
    effiapi.write_config()
    effiapi.start()

    IMPLEMENTS FINALLY Effiapi is terminated
    effiapi.terminate()

## Make HTTP requests

    IMPLEMENTS WHEN admin requests POST /memb with body (.+)
    body = get_json_match()
    effiapi.POST('/memb',  {}, body)

    IMPLEMENTS WHEN admin requests GET /status
    effiapi.GET('/status', {}, None)

    IMPLEMENTS WHEN admin requests GET /memb with header (\S+): (\S+)
    header = get_next_match()
    print('header', repr(header))
    value = get_expanded_match()
    print('value', repr(value))
    headers = {
        header: value,
    }
    V['xx'] = {
        'header': header,
        'value': value,
    }
    effiapi.GET('/memb', headers, None)

## Inspect HTTP responses

    IMPLEMENTS THEN the member id is (\S+)
    print('member id')
    name = get_next_match()
    print 'name', repr(name), name
    value = effiapi.get_header('Muck-Id')
    print 'value', repr(value)
    save_for_expansion(name, value)

    IMPLEMENTS THEN HTTP status is (\d+)
    expected = int(get_next_match())
    actual = effiapi.get_status_code()
    print 'actual:', repr(actual)
    print 'expecting:', repr(expected)
    assertEqual(effiapi.get_status_code(), expected)

    IMPLEMENTS THEN HTTP body matches (.+)
    expected = get_json_match()
    actual = effiapi.get_json_body()
    print 'expected:', expected
    print 'actual:  ', actual
    assertEqual(actual, expected)