Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Signup to Rest API #543

Open
wants to merge 20 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 155 additions & 1 deletion openapi/stregsystem.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ info:
Existing client software utilizing the API include Stregsystem-CLI (STS) and Fappen (F-Club Web App).

Disclaimer - The implementation is not generated using this specification, therefore they can get out of sync if changes are made directly to the codebase without updating the OpenAPI specification file accordingly.
version: "1.1"
version: "1.1.1"
externalDocs:
description: Find out more about Stregsystemet at GitHub.
url: https://github.com/f-klubben/stregsystemet/
Expand All @@ -21,6 +21,8 @@ tags:
description: Related to the products.
- name: Sale
description: Related to performing a sale.
- name: Signup
description: Related to registration of new members.
paths:
/api/member:
get:
Expand Down Expand Up @@ -159,6 +161,38 @@ paths:
$ref: '#/components/responses/SaleSuccess'
'400':
$ref: '#/components/responses/Member_RoomIdParameter_BadResponse'
/api/signup:
post:
tags:
- Signup
summary: Posts a signup
description: Performs a signup using member info.
operationId: api_signup
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/signup_input'
responses:
'200':
$ref: '#/components/responses/SignupSuccess'
'400':
$ref: '#/components/responses/Signup_BadResponse'
/api/signup/status:
get:
tags:
- Signup
summary: Gets status regarding a signup
description: Retrieves the signup status for a specific member by username.
operationId: api_signup_status
parameters:
- $ref: '#/components/parameters/username_param'
responses:
'200':
$ref: '#/components/responses/SignupStatus'
'400':
$ref: '#/components/responses/MemberUsernameParameter_BadResponse'
components:
examples:
MemberNotFoundExample:
Expand All @@ -182,7 +216,20 @@ components:
MissingMemberUsernameExample:
summary: No username given
value: "Parameter missing: username"
UsernameTakenExample:
summary: Member with that username already exist
value: "Username taken"
MissingOrInvalidParameterExample:
summary: A parameter is invalid or missing
value: "Parameter invalid: <parameter>"
parameters:
signup_id_param:
name: signup_id
in: query
description: Signup ID of the signup to retrieve.
required: true
schema:
$ref: '#/components/schemas/signup_id'
member_id_param:
name: member_id
in: query
Expand Down Expand Up @@ -239,6 +286,12 @@ components:
missingMemberUsernameMessage:
type: string
example: "Parameter missing: username"
usernameTakenMessage:
type: string
example: "Username taken"
invalidParameterMessage:
type: string
example: "Parameter invalid: <parameter>"
balance:
type: integer
example: 20000
Expand All @@ -257,6 +310,35 @@ components:
room_id:
type: integer
example: 10
email:
type: string
format: email
example: [email protected]
firstname:
type: string
example: Kresten
lastname:
type: string
example: Laust
education:
type: string
description: Acknowledged shortening, e.g. sw/ixd/dad/dat
example: sw
gender:
type: string
enum:
- U
- M
- F
example: M
approval_status:
type: string
description: U = Unreviewed, A = Approved, I = Ignored, R = Rejected.
enum:
- U
- A
- I
- R
timestamp:
type: string
format: date-time
Expand All @@ -274,13 +356,24 @@ components:
type: integer
example: 1800
stregoere_balance:
type: integer
example: 15000
stregoere_due:
type: integer
example: 20000
stregkroner_balance:
description: Stregbalance in kroner, only used in API-Sale
type: number
format: float
example: 182.00
signup_id:
type: integer
example: 5
named_products_example:
type: object
properties:
beer:
$ref: '#/components/schemas/product_id'
sale_input:
type: object
properties:
Expand All @@ -290,6 +383,21 @@ components:
$ref: '#/components/schemas/buystring'
room:
$ref: '#/components/schemas/room_id'
signup_input:
type: object
properties:
education:
$ref: '#/components/schemas/education'
username:
$ref: '#/components/schemas/username'
email:
$ref: '#/components/schemas/email'
firstname:
$ref: '#/components/schemas/firstname'
lastname:
$ref: '#/components/schemas/lastname'
gender:
$ref: '#/components/schemas/gender'
active_product:
type: object
properties:
Expand Down Expand Up @@ -359,6 +467,13 @@ components:
member_has_low_balance:
type: boolean
example: false
signup_values_result_example:
type: object
properties:
due:
$ref: '#/components/schemas/stregoere_due'
username:
$ref: '#/components/schemas/username'
sale_values_result_example:
type: object
properties:
Expand Down Expand Up @@ -472,6 +587,17 @@ components:
properties:
sales:
$ref: '#/components/schemas/sales'
SignupStatus:
description: Signup information found.
content:
application/json:
schema:
type: object
properties:
due:
$ref: '#/components/schemas/stregoere_due'
status:
$ref: '#/components/schemas/approval_status'
NamedProducts:
description: Dictionary of all named_product names.
content:
Expand Down Expand Up @@ -511,6 +637,21 @@ components:
example: "OK"
values:
$ref: '#/components/schemas/sale_values_result_example'
SignupSuccess:
description: An object containing info regarding the signup.
content:
application/json:
schema:
type: object
properties:
status:
type: integer
example: 200
msg:
type: string
example: "OK"
values:
$ref: '#/components/schemas/signup_values_result_example'
QRCodeGenerated:
description: QR code with link to open MobilePay with the provided information.
content:
Expand Down Expand Up @@ -594,3 +735,16 @@ components:
$ref: '#/components/examples/InvalidRoomIdExample'
missingRoomId:
$ref: '#/components/examples/MissingRoomIdExample'
Signup_BadResponse:
description: Username is taken, missing parameter, or invalid parameter.
content:
text/html:
schema:
oneOf:
- $ref: '#/components/schemas/usernameTakenMessage'
- $ref: '#/components/schemas/invalidParameterMessage'
examples:
usernameTaken:
$ref: '#/components/examples/UsernameTakenExample'
invalidParameter:
$ref: '#/components/examples/MissingOrInvalidParameterExample'
63 changes: 63 additions & 0 deletions stregsystem/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import datetime
import json
from collections import Counter
from copy import deepcopy
from unittest import mock
Expand Down Expand Up @@ -2272,3 +2273,65 @@ def test_welcome_mail_paid_approved(self, mock_mail_method: MagicMock):

signup_request.approve()
mock_mail_method.assert_called_once()


class ApiTests(TestCase):
"""
A lot of the API testing is done separately using Dredd and OpenAPI.
These are edge-cases which can't be expressed in OpenAPI.
"""
def setUp(self):
member = Member.objects.create(username="martin_p", email="[email protected]", signup_due_paid=False)
member.save()

def test_signup_duplicate_username(self):
response = self.client.post(reverse('api_signup'), json.dumps(
{
'education': "sw",
'username': "martin_p", # Note: Duplicate username
'firstname': "Martin",
'lastname': "P.",
'email': "[email protected]",
'gender': "M"
}
), content_type="application/json")

self.assertNotEquals(response.status_code, 200)

def test_signup_partial_form_no_name(self):
response = self.client.post(reverse('api_signup'), json.dumps(
{
'education': "sw",
'username': "martin_p2",
'email': "[email protected]",
'gender': "M"
}
), content_type="application/json")

self.assertNotEquals(response.status_code, 200)

def test_signup_partial_form_no_username(self):
response = self.client.post(reverse('api_signup'), json.dumps(
{
'education': "sw",
'firstname': "Martin",
'lastname': "P.",
'email': "[email protected]",
'gender': "M"
}
), content_type="application/json")

self.assertNotEquals(response.status_code, 200)

def test_signup_partial_form_no_education(self):
response = self.client.post(reverse('api_signup'), json.dumps(
{
'username': "martin_p2",
'firstname': "Martin",
'lastname': "P.",
'email': "[email protected]",
'gender': "M"
}
), content_type="application/json")

self.assertNotEquals(response.status_code, 200)
2 changes: 2 additions & 0 deletions stregsystem/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@
re_path(r'^api/products/active_products$', views.get_active_items, name="api_active_products"),
re_path(r'^api/products/category_mappings$', views.get_product_category_mappings, name="api_product_mappings"),
re_path(r'^api/sale$', views.api_sale, name="api_sale"),
re_path(r'^api/signup$', views.post_signup, name="api_signup"),
re_path(r'^api/signup/status', views.get_signup_status, name="api_signup_status"),
]
Loading
Loading