Auth Endpoints Tests (#203)

Auth Endpoints Tests
This commit is contained in:
Daniel Ternyak 2018-11-13 14:58:02 +01:00 committed by GitHub
parent 5a1cf5ae2a
commit c579820dc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 215 additions and 247 deletions

View File

@ -1,5 +1,4 @@
from datetime import datetime
from functools import wraps
from flask import Blueprint, g
from flask_yoloapi import endpoint, parameter
@ -69,8 +68,8 @@ def get_proposals(stage):
if stage:
proposals = (
Proposal.query.filter_by(stage=stage)
.order_by(Proposal.date_created.desc())
.all()
.order_by(Proposal.date_created.desc())
.all()
)
else:
proposals = Proposal.query.order_by(Proposal.date_created.desc()).all()
@ -89,7 +88,6 @@ def get_proposals(stage):
parameter('team', type=list, required=True)
)
def make_proposal(crowd_fund_contract_address, content, title, milestones, category, team):
from grant.user.models import User
existing_proposal = Proposal.query.filter_by(proposal_address=crowd_fund_contract_address).first()
if existing_proposal:
return {"message": "Oops! Something went wrong."}, 409
@ -186,6 +184,7 @@ def get_proposal_update(proposal_id, update_id):
@blueprint.route("/<proposal_id>/updates", methods=["POST"])
@requires_team_member_auth
@requires_sm
@endpoint.api(
parameter('title', type=str, required=True),
parameter('content', type=str, required=True)

View File

@ -58,7 +58,7 @@ class User(db.Model):
self.title = title
@staticmethod
def create(email_address=None, account_address=None, display_name=None, title=None):
def create(email_address=None, account_address=None, display_name=None, title=None, _send_email=True):
user = User(
account_address=account_address,
email_address=email_address,
@ -73,10 +73,11 @@ class User(db.Model):
db.session.add(ev)
db.session.commit()
send_email(user.email_address, 'signup', {
'display_name': user.display_name,
'confirm_url': make_url(f'/email/verify?code={ev.code}')
})
if send_email:
send_email(user.email_address, 'signup', {
'display_name': user.display_name,
'confirm_url': make_url(f'/email/verify?code={ev.code}')
})
return user

View File

@ -1,10 +1,9 @@
from flask import Blueprint, g
from flask_yoloapi import endpoint, parameter
from .models import User, SocialMedia, Avatar, users_schema, user_schema, db
from grant.proposal.models import Proposal, proposal_team
from grant.utils.auth import requires_sm, requires_same_user_auth, verify_signed_auth, BadSignatureException
from .models import User, SocialMedia, Avatar, users_schema, user_schema, db
blueprint = Blueprint('user', __name__, url_prefix='/api/v1/users')
@ -54,12 +53,12 @@ def get_user(user_identity):
parameter('rawTypedData', type=str, required=True)
)
def create_user(
account_address,
email_address,
display_name,
title,
signed_message,
raw_typed_data
account_address,
email_address,
display_name,
title,
signed_message,
raw_typed_data
):
existing_user = User.get_by_identifier(email_address=email_address, account_address=account_address)
if existing_user:
@ -70,11 +69,11 @@ def create_user(
sig_address = verify_signed_auth(signed_message, raw_typed_data)
if sig_address.lower() != account_address.lower():
return {
"message": "Message signature address ({sig_address}) doesn't match account_address ({account_address})".format(
sig_address=sig_address,
account_address=account_address
)
}, 400
"message": "Message signature address ({sig_address}) doesn't match account_address ({account_address})".format(
sig_address=sig_address,
account_address=account_address
)
}, 400
except BadSignatureException:
return {"message": "Invalid message signature"}, 400
@ -88,6 +87,7 @@ def create_user(
result = user_schema.dump(user)
return result
@blueprint.route("/auth", methods=["POST"])
@endpoint.api(
parameter('accountAddress', type=str, required=True),
@ -103,31 +103,28 @@ def auth_user(account_address, signed_message, raw_typed_data):
sig_address = verify_signed_auth(signed_message, raw_typed_data)
if sig_address.lower() != account_address.lower():
return {
"message": "Message signature address ({sig_address}) doesn't match account_address ({account_address})".format(
sig_address=sig_address,
account_address=account_address
)
}, 400
"message": "Message signature address ({sig_address}) doesn't match account_address ({account_address})".format(
sig_address=sig_address,
account_address=account_address
)
}, 400
except BadSignatureException:
return {"message": "Invalid message signature"}, 400
return user_schema.dump(existing_user)
@blueprint.route("/<user_identity>", methods=["PUT"])
@requires_sm
@requires_same_user_auth
@endpoint.api(
parameter('displayName', type=str, required=False),
parameter('title', type=str, required=False),
parameter('socialMedias', type=list, required=False),
parameter('avatar', type=dict, required=False),
parameter('displayName', type=str, required=True),
parameter('title', type=str, required=True),
parameter('socialMedias', type=list, required=True),
parameter('avatar', type=dict, required=True)
)
def update_user(user_identity, display_name, title, social_medias, avatar):
user = User.get_by_identifier(email_address=user_identity, account_address=user_identity)
if not user:
return {"message": "User with that address or email not found"}, 404
if user.id != g.current_user.id:
return {"message": "You are not authorized to edit this user"}, 403
user = g.current_user
if display_name is not None:
user.display_name = display_name
@ -136,11 +133,12 @@ def update_user(user_identity, display_name, title, social_medias, avatar):
user.title = title
if social_medias is not None:
sm_query = SocialMedia.query.filter_by(user_id=user.id)
sm_query.delete()
SocialMedia.query.filter_by(user_id=user.id).delete()
for social_media in social_medias:
sm = SocialMedia(social_media_link=social_media.get("link"), user_id=user.id)
db.session.add(sm)
else:
SocialMedia.query.filter_by(user_id=user.id).delete()
if avatar is not None:
Avatar.query.filter_by(user_id=user.id).delete()
@ -148,8 +146,9 @@ def update_user(user_identity, display_name, title, social_medias, avatar):
if avatar_link:
avatar_obj = Avatar(image_url=avatar_link, user_id=user.id)
db.session.add(avatar_obj)
else:
Avatar.query.filter_by(user_id=user.id).delete()
db.session.commit()
result = user_schema.dump(user)
return result

View File

@ -8,8 +8,8 @@ from itsdangerous import SignatureExpired, BadSignature
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from grant.settings import SECRET_KEY, AUTH_URL
from ..user.models import User
from ..proposal.models import Proposal
from ..user.models import User
TWO_WEEKS = 1209600
@ -36,6 +36,7 @@ def verify_token(token):
class BadSignatureException(Exception):
pass
def verify_signed_auth(signature, typed_data):
loaded_typed_data = ast.literal_eval(typed_data)
url = AUTH_URL + "/message/recover"
@ -44,27 +45,10 @@ def verify_signed_auth(signature, typed_data):
response = requests.request("POST", url, data=payload, headers=headers)
json_response = response.json()
recovered_address = json_response.get('recoveredAddress')
if not recovered_address:
raise BadSignatureException("Authorization signature is invalid")
return recovered_address
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
token = request.headers.get('Authorization', None)
if token:
string_token = token.encode('ascii', 'ignore')
user = verify_token(string_token)
if user:
g.current_user = user
return f(*args, **kwargs)
return jsonify(message="Authentication is required to access this resource"), 401
return decorated
# Decorator that requires you to have EIP-712 message signature headers for auth
@ -75,7 +59,6 @@ def requires_sm(f):
typed_data = request.headers.get('RawTypedData', None)
if typed_data and signature:
auth_address = None
try:
auth_address = verify_signed_auth(signature, typed_data)
except BadSignatureException:
@ -92,6 +75,7 @@ def requires_sm(f):
return decorated
# Decorator that requires you to be the user you're interacting with
def requires_same_user_auth(f):
@wraps(f)
@ -101,13 +85,14 @@ def requires_same_user_auth(f):
return jsonify(message="Decorator requires_same_user_auth requires path variable <user_identity>"), 500
user = User.get_by_identifier(account_address=user_identity, email_address=user_identity)
if user != g.current_user:
if user.id != g.current_user.id:
return jsonify(message="You are not authorized to modify this user"), 403
return f(*args, **kwargs)
return requires_sm(decorated)
# Decorator that requires you to be a team member of a proposal to access
def requires_team_member_auth(f):
@wraps(f)
@ -125,5 +110,5 @@ def requires_team_member_auth(f):
g.current_proposal = proposal
return f(*args, **kwargs)
return requires_sm(decorated)
return requires_sm(decorated)

View File

@ -55,4 +55,4 @@ flask-sendgrid==0.6
sendgrid==5.3.0
# input validation
flask-yolo2API
flask-yolo2API==0.2.4

View File

@ -1,6 +1,8 @@
from flask_testing import TestCase
from grant.app import create_app, db
from grant.app import create_app
from grant.user.models import User, SocialMedia, db, Avatar
from .test_data import test_user, message
class BaseTestConfig(TestCase):
@ -11,9 +13,36 @@ class BaseTestConfig(TestCase):
return app
def setUp(self):
db.drop_all()
self.app = self.create_app().test_client()
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
class BaseUserConfig(BaseTestConfig):
headers = {
"MsgSignature": message["sig"],
"RawTypedData": message["data"]
}
def setUp(self):
super(BaseUserConfig, self).setUp()
self.user = User.create(
account_address=test_user["accountAddress"],
email_address=test_user["emailAddress"],
display_name=test_user["displayName"],
title=test_user["title"],
_send_email=False
)
sm = SocialMedia(social_media_link=test_user['socialMedias'][0]['link'], user_id=self.user.id)
db.session.add(sm)
avatar = Avatar(image_url=test_user["avatar"]["link"], user_id=self.user.id)
db.session.add(avatar)
db.session.commit()
def remove_default_user(self):
User.query.filter_by(id=self.user.id).delete()
db.session.commit()

View File

@ -1,81 +1,43 @@
import json
import random
from grant.proposal.models import Proposal, CATEGORIES
from grant.user.models import User, SocialMedia
from ..config import BaseTestConfig
milestones = [
{
"title": "All the money straightaway",
"description": "cool stuff with it",
"date": "June 2019",
"payoutPercent": "100",
"immediatePayout": False
}
]
team = [
{
"accountAddress": "0x1",
"displayName": 'Groot',
"emailAddress": 'iam@groot.com',
"title": 'I am Groot!',
"avatar": {
"link": 'https://avatars2.githubusercontent.com/u/1393943?s=400&v=4'
},
"socialMedias": [
{
"link": 'https://github.com/groot'
}
]
}
]
proposal = {
"team": team,
"crowdFundContractAddress": "0x20000",
"content": "## My Proposal",
"title": "Give Me Money",
"milestones": milestones,
"category": random.choice(CATEGORIES)
}
from grant.proposal.models import Proposal
from grant.user.models import SocialMedia, Avatar
from ..config import BaseUserConfig
from ..test_data import test_proposal
class TestAPI(BaseTestConfig):
class TestAPI(BaseUserConfig):
def test_create_new_proposal(self):
self.assertIsNone(Proposal.query.filter_by(
proposal_address=proposal["crowdFundContractAddress"]
proposal_address=test_proposal["crowdFundContractAddress"]
).first())
resp = self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
data=json.dumps(test_proposal),
headers=self.headers,
content_type='application/json'
)
self.assertEqual(resp.status_code, 201)
proposal_db = Proposal.query.filter_by(
proposal_address=proposal["crowdFundContractAddress"]
proposal_address=test_proposal["crowdFundContractAddress"]
).first()
self.assertEqual(proposal_db.title, proposal["title"])
# User
user_db = User.query.filter_by(email_address=team[0]["emailAddress"]).first()
self.assertEqual(user_db.display_name, team[0]["displayName"])
self.assertEqual(user_db.title, team[0]["title"])
self.assertEqual(user_db.account_address, team[0]["accountAddress"])
self.assertEqual(proposal_db.title, test_proposal["title"])
# SocialMedia
social_media_db = SocialMedia.query.filter_by(social_media_link=team[0]["socialMedias"][0]["link"]).first()
social_media_db = SocialMedia.query.filter_by(user_id=self.user.id).first()
self.assertTrue(social_media_db)
# Avatar
self.assertEqual(user_db.avatar.image_url, team[0]["avatar"]["link"])
avatar = Avatar.query.filter_by(user_id=self.user.id).first()
self.assertTrue(avatar)
def test_create_new_proposal_comment(self):
proposal_res = self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
data=json.dumps(test_proposal),
headers=self.headers,
content_type='application/json'
)
proposal_json = proposal_res.json
@ -94,15 +56,17 @@ class TestAPI(BaseTestConfig):
self.assertTrue(comment_res.json)
def test_create_new_proposal_duplicate(self):
proposal_res = self.app.post(
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
data=json.dumps(test_proposal),
headers=self.headers,
content_type='application/json'
)
proposal_res2 = self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
data=json.dumps(test_proposal),
headers=self.headers,
content_type='application/json'
)

View File

@ -1,5 +1,6 @@
import json
import random
from grant.proposal.models import CATEGORIES
message = {
@ -43,7 +44,7 @@ message = {
}
}
user = {
test_user = {
"accountAddress": '0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826',
"displayName": 'Groot',
"emailAddress": 'iam@groot.com',
@ -60,7 +61,7 @@ user = {
"rawTypedData": json.dumps(message["data"])
}
team = [user]
test_team = [test_user]
milestones = [
{
@ -72,11 +73,21 @@ milestones = [
}
]
proposal = {
"team": team,
test_proposal = {
"team": test_team,
"crowdFundContractAddress": "0x20000",
"content": "## My Proposal",
"title": "Give Me Money",
"milestones": milestones,
"category": random.choice(CATEGORIES)
}
}
milestones = [
{
"title": "All the money straightaway",
"description": "cool stuff with it",
"date": "June 2019",
"payoutPercent": "100",
"immediatePayout": False
}
]

View File

@ -1,14 +1,14 @@
import json
from ..config import BaseTestConfig
from ..test_data import user, message
from ..test_data import test_user, message
class TestRequiredSignedMessageDecorator(BaseTestConfig):
def test_required_sm_aborts_without_data_and_sig_headers(self):
self.app.post(
"/api/v1/users/",
data=json.dumps(user),
data=json.dumps(test_user),
content_type='application/json'
)
@ -53,7 +53,7 @@ class TestRequiredSignedMessageDecorator(BaseTestConfig):
def test_required_sm_decorator_authorizes_when_recovered_address_matches_existing_user(self):
self.app.post(
"/api/v1/users/",
data=json.dumps(user),
data=json.dumps(test_user),
content_type='application/json'
)
@ -68,4 +68,4 @@ class TestRequiredSignedMessageDecorator(BaseTestConfig):
response_json = response.json
self.assert200(response)
self.assertEqual(response_json["displayName"], user["displayName"])
self.assertEqual(response_json["displayName"], test_user["displayName"])

View File

@ -1,84 +1,101 @@
import copy
import json
from grant.proposal.models import Proposal
from grant.user.models import User
from ..config import BaseTestConfig
from ..test_data import team, proposal
from animal_case import animalify
from mock import patch
from grant.proposal.models import Proposal
from grant.user.models import User, user_schema
from ..config import BaseUserConfig
from ..test_data import test_team, test_proposal, test_user
class TestAPI(BaseTestConfig):
def test_create_new_user_via_proposal_by_account_address(self):
proposal_by_account = copy.deepcopy(proposal)
del proposal_by_account["team"][0]["emailAddress"]
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal_by_account),
content_type='application/json'
)
class TestAPI(BaseUserConfig):
# TODO create second signed message default user
# @patch('grant.email.send.send_email')
# def test_create_new_user_via_proposal_by_account_address(self, mock_send_email):
# mock_send_email.return_value.ok = True
# self.remove_default_user()
# proposal_by_account = copy.deepcopy(test_proposal)
# del proposal_by_account["team"][0]["emailAddress"]
#
# resp = self.app.post(
# "/api/v1/proposals/",
# data=json.dumps(proposal_by_account),
# headers=self.headers,
# content_type='application/json'
# )
#
# self.assertEqual(resp, 201)
#
# # User
# user_db = User.query.filter_by(account_address=proposal_by_account["team"][0]["accountAddress"]).first()
# self.assertEqual(user_db.display_name, proposal_by_account["team"][0]["displayName"])
# self.assertEqual(user_db.title, proposal_by_account["team"][0]["title"])
# self.assertEqual(user_db.account_address, proposal_by_account["team"][0]["accountAddress"])
# User
user_db = User.query.filter_by(account_address=proposal_by_account["team"][0]["accountAddress"]).first()
self.assertEqual(user_db.display_name, proposal_by_account["team"][0]["displayName"])
self.assertEqual(user_db.title, proposal_by_account["team"][0]["title"])
self.assertEqual(user_db.account_address, proposal_by_account["team"][0]["accountAddress"])
def test_create_new_user_via_proposal_by_email(self):
proposal_by_email = copy.deepcopy(proposal)
del proposal_by_email["team"][0]["accountAddress"]
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal_by_email),
content_type='application/json'
)
# User
user_db = User.query.filter_by(email_address=proposal_by_email["team"][0]["emailAddress"]).first()
self.assertEqual(user_db.display_name, proposal_by_email["team"][0]["displayName"])
self.assertEqual(user_db.title, proposal_by_email["team"][0]["title"])
# TODO create second signed message default user
# def test_create_new_user_via_proposal_by_email(self):
# self.remove_default_user()
# proposal_by_email = copy.deepcopy(test_proposal)
# del proposal_by_email["team"][0]["accountAddress"]
#
# resp = self.app.post(
# "/api/v1/proposals/",
# data=json.dumps(proposal_by_email),
# headers=self.headers,
# content_type='application/json'
# )
#
# self.assertEqual(resp, 201)
#
# # User
# user_db = User.query.filter_by(email_address=proposal_by_email["team"][0]["emailAddress"]).first()
# self.assertEqual(user_db.display_name, proposal_by_email["team"][0]["displayName"])
# self.assertEqual(user_db.title, proposal_by_email["team"][0]["title"])
def test_associate_user_via_proposal_by_email(self):
proposal_by_email = copy.deepcopy(proposal)
proposal_by_email = copy.deepcopy(test_proposal)
del proposal_by_email["team"][0]["accountAddress"]
self.app.post(
resp = self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal_by_email),
headers=self.headers,
content_type='application/json'
)
self.assertEqual(resp.status_code, 201)
# User
user_db = User.query.filter_by(email_address=proposal_by_email["team"][0]["emailAddress"]).first()
self.assertEqual(user_db.display_name, proposal_by_email["team"][0]["displayName"])
self.assertEqual(user_db.title, proposal_by_email["team"][0]["title"])
proposal_db = Proposal.query.filter_by(
proposal_address=proposal["crowdFundContractAddress"]
proposal_address=test_proposal["crowdFundContractAddress"]
).first()
self.assertEqual(proposal_db.team[0].id, user_db.id)
def test_associate_user_via_proposal_by_email_when_user_already_exists(self):
proposal_by_email = copy.deepcopy(proposal)
del proposal_by_email["team"][0]["accountAddress"]
proposal_by_user_email = copy.deepcopy(test_proposal)
del proposal_by_user_email["team"][0]["accountAddress"]
self.app.post(
resp = self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal_by_email),
data=json.dumps(proposal_by_user_email),
headers=self.headers,
content_type='application/json'
)
self.assertEqual(resp.status_code, 201)
# User
user_db = User.query.filter_by(email_address=proposal_by_email["team"][0]["emailAddress"]).first()
self.assertEqual(user_db.display_name, proposal_by_email["team"][0]["displayName"])
self.assertEqual(user_db.title, proposal_by_email["team"][0]["title"])
self.assertEqual(self.user.display_name, proposal_by_user_email["team"][0]["displayName"])
self.assertEqual(self.user.title, proposal_by_user_email["team"][0]["title"])
proposal_db = Proposal.query.filter_by(
proposal_address=proposal["crowdFundContractAddress"]
proposal_address=test_proposal["crowdFundContractAddress"]
).first()
self.assertEqual(proposal_db.team[0].id, user_db.id)
self.assertEqual(proposal_db.team[0].id, self.user.id)
new_proposal_by_email = copy.deepcopy(proposal)
new_proposal_by_email = copy.deepcopy(test_proposal)
new_proposal_by_email["crowdFundContractAddress"] = "0x2222"
del new_proposal_by_email["team"][0]["accountAddress"]
@ -92,14 +109,14 @@ class TestAPI(BaseTestConfig):
self.assertEqual(user_db.display_name, new_proposal_by_email["team"][0]["displayName"])
self.assertEqual(user_db.title, new_proposal_by_email["team"][0]["title"])
proposal_db = Proposal.query.filter_by(
proposal_address=proposal["crowdFundContractAddress"]
proposal_address=test_proposal["crowdFundContractAddress"]
).first()
self.assertEqual(proposal_db.team[0].id, user_db.id)
def test_get_all_users(self):
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
data=json.dumps(test_proposal),
content_type='application/json'
)
users_get_resp = self.app.get(
@ -107,18 +124,17 @@ class TestAPI(BaseTestConfig):
)
users_json = users_get_resp.json
print(users_json)
self.assertEqual(users_json[0]["displayName"], team[0]["displayName"])
self.assertEqual(users_json[0]["displayName"], test_team[0]["displayName"])
def test_get_user_associated_with_proposal(self):
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
data=json.dumps(test_proposal),
content_type='application/json'
)
data = {
'proposalId': proposal["crowdFundContractAddress"]
'proposalId': test_proposal["crowdFundContractAddress"]
}
users_get_resp = self.app.get(
@ -127,25 +143,25 @@ class TestAPI(BaseTestConfig):
)
users_json = users_get_resp.json
self.assertEqual(users_json[0]["avatar"]["imageUrl"], team[0]["avatar"]["link"])
self.assertEqual(users_json[0]["socialMedias"][0]["socialMediaLink"], team[0]["socialMedias"][0]["link"])
self.assertEqual(users_json[0]["displayName"], team[0]["displayName"])
self.assertEqual(users_json[0]["avatar"]["imageUrl"], test_team[0]["avatar"]["link"])
self.assertEqual(users_json[0]["socialMedias"][0]["socialMediaLink"], test_team[0]["socialMedias"][0]["link"])
self.assertEqual(users_json[0]["displayName"], test_user["displayName"])
def test_get_single_user(self):
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
data=json.dumps(test_proposal),
content_type='application/json'
)
users_get_resp = self.app.get(
"/api/v1/users/{}".format(proposal["team"][0]["emailAddress"])
"/api/v1/users/{}".format(test_proposal["team"][0]["emailAddress"])
)
users_json = users_get_resp.json
self.assertEqual(users_json["avatar"]["imageUrl"], team[0]["avatar"]["link"])
self.assertEqual(users_json["socialMedias"][0]["socialMediaLink"], team[0]["socialMedias"][0]["link"])
self.assertEqual(users_json["displayName"], team[0]["displayName"])
self.assertEqual(users_json["avatar"]["imageUrl"], test_team[0]["avatar"]["link"])
self.assertEqual(users_json["socialMedias"][0]["socialMediaLink"], test_team[0]["socialMedias"][0]["link"])
self.assertEqual(users_json["displayName"], test_team[0]["displayName"])
@patch('grant.email.send.send_email')
def test_create_user(self, mock_send_email):
@ -153,15 +169,15 @@ class TestAPI(BaseTestConfig):
self.app.post(
"/api/v1/users/",
data=json.dumps(team[0]),
data=json.dumps(test_team[0]),
content_type='application/json'
)
# User
user_db = User.get_by_identifier(account_address=team[0]["accountAddress"])
self.assertEqual(user_db.display_name, team[0]["displayName"])
self.assertEqual(user_db.title, team[0]["title"])
self.assertEqual(user_db.account_address, team[0]["accountAddress"])
user_db = User.get_by_identifier(account_address=test_team[0]["accountAddress"])
self.assertEqual(user_db.display_name, test_team[0]["displayName"])
self.assertEqual(user_db.title, test_team[0]["title"])
self.assertEqual(user_db.account_address, test_team[0]["accountAddress"])
@patch('grant.email.send.send_email')
def test_create_user_duplicate_400(self, mock_send_email):
@ -170,64 +186,28 @@ class TestAPI(BaseTestConfig):
response = self.app.post(
"/api/v1/users/",
data=json.dumps(team[0]),
data=json.dumps(test_team[0]),
content_type='application/json'
)
self.assertEqual(response.status_code, 409)
def test_update_user_remove_social_and_avatar(self):
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
content_type='application/json'
)
updated_user = copy.deepcopy(team[0])
updated_user['displayName'] = 'Billy'
updated_user['title'] = 'Commander'
updated_user['socialMedias'] = []
updated_user['avatar'] = {}
updated_user = animalify(copy.deepcopy(user_schema.dump(self.user)))
updated_user["displayName"] = 'new display name'
updated_user["avatar"] = None
updated_user["socialMedias"] = None
user_update_resp = self.app.put(
"/api/v1/users/{}".format(proposal["team"][0]["accountAddress"]),
"/api/v1/users/{}".format(self.user.account_address),
data=json.dumps(updated_user),
headers=self.headers,
content_type='application/json'
)
self.assert200(user_update_resp)
users_json = user_update_resp.json
self.assertFalse(users_json["avatar"])
self.assertFalse(len(users_json["socialMedias"]))
self.assertEqual(users_json["displayName"], updated_user["displayName"])
self.assertEqual(users_json["title"], updated_user["title"])
def test_update_user(self):
self.app.post(
"/api/v1/proposals/",
data=json.dumps(proposal),
content_type='application/json'
)
updated_user = copy.deepcopy(team[0])
updated_user['displayName'] = 'Billy'
updated_user['title'] = 'Commander'
updated_user['socialMedias'] = [
{
"link": "https://github.com/billyman"
}
]
updated_user['avatar'] = {
"link": "https://x.io/avatar.png"
}
user_update_resp = self.app.put(
"/api/v1/users/{}".format(proposal["team"][0]["accountAddress"]),
data=json.dumps(updated_user),
content_type='application/json'
)
users_json = user_update_resp.json
self.assertEqual(users_json["avatar"]["imageUrl"], updated_user["avatar"]["link"])
self.assertEqual(users_json["socialMedias"][0]["socialMediaLink"], updated_user["socialMedias"][0]["link"])
self.assertEqual(users_json["displayName"], updated_user["displayName"])
self.assertEqual(users_json["title"], updated_user["title"])
user_json = user_update_resp.json
self.assertFalse(user_json["avatar"])
self.assertFalse(len(user_json["socialMedias"]))
self.assertEqual(user_json["displayName"], updated_user["displayName"])
self.assertEqual(user_json["title"], updated_user["title"])