--- 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)