test_accounts_api.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. from __future__ import annotations
  2. from flask import url_for
  3. import pytest
  4. from flexmeasures.data.services.users import find_user_by_email
  5. @pytest.mark.parametrize(
  6. "requesting_user, status_code",
  7. [
  8. (None, 401),
  9. ],
  10. indirect=["requesting_user"],
  11. )
  12. def test_get_accounts_missing_auth(client, requesting_user, status_code):
  13. """
  14. Attempt to get accounts with missing auth.
  15. """
  16. # the case without auth: authentication will fail
  17. get_accounts_response = client.get(url_for("AccountAPI:index"))
  18. print("Server responded with:\n%s" % get_accounts_response.data)
  19. assert get_accounts_response.status_code == status_code
  20. @pytest.mark.parametrize(
  21. "requesting_user, num_accounts, sort_by, sort_dir, expected_name_of_first_account",
  22. [
  23. ("test_admin_user@seita.nl", 7, None, None, None),
  24. ("test_prosumer_user@seita.nl", 1, None, None, None),
  25. ("test_consultant@seita.nl", 2, None, None, None),
  26. (
  27. "test_consultancy_user_without_consultant_access@seita.nl",
  28. 1,
  29. None,
  30. None,
  31. None,
  32. ),
  33. ("test_admin_user@seita.nl", 7, "name", "asc", "Multi Role Account"),
  34. ("test_admin_user@seita.nl", 7, "name", "desc", "Test Supplier Account"),
  35. ],
  36. indirect=["requesting_user"],
  37. )
  38. def test_get_accounts(
  39. client,
  40. setup_api_test_data,
  41. requesting_user,
  42. num_accounts,
  43. sort_by,
  44. sort_dir,
  45. expected_name_of_first_account,
  46. ):
  47. """
  48. Get accounts for:
  49. - A normal user.
  50. - An admin user.
  51. - A user with a consultant role, belonging to a consultancy account with a linked consultancy client account.
  52. - A user without a consultant role, belonging to a consultancy account with a linked consultancy client account.
  53. """
  54. query = {}
  55. if sort_by:
  56. query["sort_by"] = sort_by
  57. if sort_dir:
  58. query["sort_dir"] = sort_dir
  59. get_accounts_response = client.get(
  60. url_for("AccountAPI:index"),
  61. query_string=query,
  62. )
  63. print("Server responded with:\n%s" % get_accounts_response.json)
  64. accounts = get_accounts_response.json
  65. assert len(accounts) == num_accounts
  66. account_names = [a["name"] for a in accounts]
  67. assert requesting_user.account.name in account_names
  68. if sort_by:
  69. assert accounts[0]["name"] == expected_name_of_first_account
  70. @pytest.mark.parametrize(
  71. "requesting_user, status_code",
  72. [
  73. (None, 401), # no auth is not allowed
  74. ("test_prosumer_user_2@seita.nl", 200), # gets their own account, okay
  75. ("test_dummy_user_3@seita.nl", 403), # gets from other account
  76. ("test_admin_user@seita.nl", 200), # admin can do this from another account
  77. ],
  78. indirect=["requesting_user"],
  79. )
  80. def test_get_one_account(client, setup_api_test_data, requesting_user, status_code):
  81. """Get one account"""
  82. test_user2_account_id = find_user_by_email(
  83. "test_prosumer_user_2@seita.nl"
  84. ).account.id
  85. get_account_response = client.get(
  86. url_for("AccountAPI:get", id=test_user2_account_id),
  87. )
  88. print("Server responded with:\n%s" % get_account_response.data)
  89. assert get_account_response.status_code == status_code
  90. if status_code == 200:
  91. assert get_account_response.json["name"] == "Test Prosumer Account"
  92. assert get_account_response.json["account_roles"] == [
  93. {"id": 1, "name": "Prosumer"}
  94. ]
  95. @pytest.mark.parametrize(
  96. "requesting_user, status_code",
  97. [
  98. (None, 401), # no auth is not allowed
  99. (
  100. "test_prosumer_user@seita.nl",
  101. 403,
  102. ), # non account admin cant view account audit log
  103. (
  104. "test_prosumer_user_2@seita.nl",
  105. 200,
  106. ), # account-admin can view his account audit log
  107. (
  108. "test_dummy_account_admin@seita.nl",
  109. 403,
  110. ), # account-admin cannot view other account audit logs
  111. ("test_admin_user@seita.nl", 200), # admin can view another account audit log
  112. (
  113. "test_admin_reader_user@seita.nl",
  114. 200,
  115. ), # admin reader can view another account audit log
  116. ],
  117. indirect=["requesting_user"],
  118. )
  119. def test_get_one_account_audit_log(
  120. client, setup_api_test_data, requesting_user, status_code
  121. ):
  122. """Get one account"""
  123. test_user_account_id = find_user_by_email("test_prosumer_user@seita.nl").account.id
  124. get_account_response = client.get(
  125. url_for("AccountAPI:auditlog", id=test_user_account_id),
  126. )
  127. print("Server responded with:\n%s" % get_account_response.data)
  128. assert get_account_response.status_code == status_code
  129. if status_code == 200:
  130. assert get_account_response.json[0] is not None
  131. @pytest.mark.parametrize(
  132. "requesting_user, status_code",
  133. [
  134. # Consultant users can see the audit log of all users in the client accounts.
  135. ("test_consultant@seita.nl", 200),
  136. # Has no consultant role.
  137. ("test_consultancy_user_without_consultant_access@seita.nl", 403),
  138. ],
  139. indirect=["requesting_user"],
  140. )
  141. def test_get_one_user_audit_log_consultant(
  142. client, setup_api_test_data, requesting_user, status_code
  143. ):
  144. """Check correctness of consultant account audit log access rules"""
  145. test_user_account_id = find_user_by_email(
  146. "test_consultant_client@seita.nl"
  147. ).account.id
  148. get_account_response = client.get(
  149. url_for("AccountAPI:auditlog", id=test_user_account_id),
  150. )
  151. print("Server responded with:\n%s" % get_account_response.data)
  152. assert get_account_response.status_code == status_code
  153. if status_code == 200:
  154. assert get_account_response.json[0] is not None