@ -62,13 +62,16 @@ class ProfileTestCase(BaseTestCase): | |||
def test_it_adds_team_member(self): | |||
self.client.login(username="[email protected]", password="password") | |||
form = {"invite_team_member": "1", "email": "bob@example.org"} | |||
form = {"invite_team_member": "1", "email": "frank@example.org"} | |||
r = self.client.post("/accounts/profile/", form) | |||
assert r.status_code == 200 | |||
member = self.alice.profile.member_set.get() | |||
member_emails = set() | |||
for member in self.alice.profile.member_set.all(): | |||
member_emails.add(member.user.email) | |||
self.assertEqual(member.user.email, "[email protected]") | |||
self.assertEqual(len(member_emails), 2) | |||
self.assertTrue("[email protected]" in member_emails) | |||
# And an email should have been sent | |||
subj = ('You have been invited to join' | |||
@ -78,18 +81,15 @@ class ProfileTestCase(BaseTestCase): | |||
def test_it_removes_team_member(self): | |||
self.client.login(username="[email protected]", password="password") | |||
bob = User(username="bob", email="[email protected]") | |||
bob.save() | |||
m = Member(team=self.alice.profile, user=bob) | |||
m.save() | |||
form = {"remove_team_member": "1", "email": "[email protected]"} | |||
r = self.client.post("/accounts/profile/", form) | |||
assert r.status_code == 200 | |||
self.assertEqual(Member.objects.count(), 0) | |||
self.bobs_profile.refresh_from_db() | |||
self.assertEqual(self.bobs_profile.current_team, None) | |||
def test_it_sets_team_name(self): | |||
self.client.login(username="[email protected]", password="password") | |||
@ -1,37 +1,23 @@ | |||
from django.contrib.auth.models import User | |||
from hc.test import BaseTestCase | |||
from hc.accounts.models import Member, Profile | |||
from hc.api.models import Check | |||
class SwitchTeamTestCase(BaseTestCase): | |||
def setUp(self): | |||
super(SwitchTeamTestCase, self).setUp() | |||
self.bob = User(username="bob", email="[email protected]") | |||
self.bob.set_password("password") | |||
self.bob.save() | |||
bobs_profile = Profile(user=self.bob) | |||
bobs_profile.save() | |||
m = Member(team=bobs_profile, user=self.alice) | |||
m.save() | |||
def test_it_switches(self): | |||
self.client.login(username="[email protected]", password="password") | |||
c = Check(user=self.alice, name="This belongs to Alice") | |||
c.save() | |||
url = "/accounts/switch_team/%s/" % self.bob.username | |||
r = self.client.get(url, follow=True) | |||
self.client.login(username="[email protected]", password="password") | |||
self.assertContains(r, "[email protected]") | |||
url = "/accounts/switch_team/%s/" % self.alice.username | |||
r = self.client.get(url, follow=True) | |||
self.assertContains(r, "This belongs to Alice") | |||
def test_it_checks_team_membership(self): | |||
self.client.login(username="[email protected]", password="password") | |||
url = "/accounts/switch_team/%s/" % self.bob.username | |||
url = "/accounts/switch_team/%s/" % self.alice.username | |||
r = self.client.get(url) | |||
self.assertEqual(r.status_code, 403) |
@ -1,7 +1,7 @@ | |||
import json | |||
from datetime import timedelta as td | |||
from hc.api.models import Check, User | |||
from hc.api.models import Check | |||
from hc.test import BaseTestCase | |||
@ -36,13 +36,12 @@ class ListChecksTestCase(BaseTestCase): | |||
self.assertEqual(checks["Alice 2"]["ping_url"], self.checks[1].url()) | |||
def test_it_shows_only_users_checks(self): | |||
bob = User(username="bob", email="[email protected]") | |||
bob.save() | |||
bob_check = Check(user=bob, name="Bob 1") | |||
bob_check.save() | |||
bobs_check = Check(user=self.bob, name="Bob 1") | |||
bobs_check.save() | |||
r = self.get("/api/v1/checks/", {"api_key": "abc"}) | |||
self.assertEqual(len(r.json()["checks"]), 2) | |||
checks = { check["name"]: check for check in r.json()["checks"] } | |||
self.assertNotIn("Bob 1", checks) | |||
data = r.json() | |||
self.assertEqual(len(data["checks"]), 2) | |||
for check in data["checks"]: | |||
self.assertNotEqual(check["name"], "Bob 1") |
@ -17,6 +17,17 @@ class AddChannelTestCase(BaseTestCase): | |||
self.assertRedirects(r, "/integrations/") | |||
assert Channel.objects.count() == 1 | |||
def test_team_access_works(self): | |||
url = "/integrations/add/" | |||
form = {"kind": "email", "value": "[email protected]"} | |||
self.client.login(username="[email protected]", password="password") | |||
self.client.post(url, form) | |||
ch = Channel.objects.get() | |||
# Added by bob, but should belong to alice (bob has team access) | |||
self.assertEqual(ch.user, self.alice) | |||
def test_it_trims_whitespace(self): | |||
""" Leading and trailing whitespace should get trimmed. """ | |||
@ -92,6 +103,18 @@ class AddChannelTestCase(BaseTestCase): | |||
c = Channel.objects.get() | |||
self.assertEqual(c.value, "http://foo.com\nhttps://bar.com") | |||
def test_it_adds_webhook_using_team_access(self): | |||
form = {"value_down": "http://foo.com", "value_up": "https://bar.com"} | |||
# Logging in as bob, not alice. Bob has team access so this | |||
# should work. | |||
self.client.login(username="[email protected]", password="password") | |||
self.client.post("/integrations/add_webhook/", form) | |||
c = Channel.objects.get() | |||
self.assertEqual(c.user, self.alice) | |||
self.assertEqual(c.value, "http://foo.com\nhttps://bar.com") | |||
def test_it_rejects_non_http_webhook_urls(self): | |||
form = {"value_down": "foo", "value_up": "bar"} | |||
@ -10,3 +10,12 @@ class AddCheckTestCase(BaseTestCase): | |||
r = self.client.post(url) | |||
self.assertRedirects(r, "/checks/") | |||
assert Check.objects.count() == 1 | |||
def test_team_access_works(self): | |||
url = "/checks/add/" | |||
self.client.login(username="[email protected]", password="password") | |||
self.client.post(url) | |||
check = Check.objects.get() | |||
# Added by bob, but should belong to alice (bob has team access) | |||
self.assertEqual(check.user, self.alice) |
@ -17,6 +17,15 @@ class ChannelChecksTestCase(BaseTestCase): | |||
r = self.client.get(url) | |||
self.assertContains(r, "Assign Checks to Channel", status_code=200) | |||
def test_team_access_works(self): | |||
url = "/integrations/%s/checks/" % self.channel.code | |||
# Logging in as bob, not alice. Bob has team access so this | |||
# should work. | |||
self.client.login(username="[email protected]", password="password") | |||
r = self.client.get(url) | |||
self.assertContains(r, "Assign Checks to Channel", status_code=200) | |||
def test_it_checks_owner(self): | |||
# channel does not belong to mallory so this should come back | |||
# with 403 Forbidden: | |||
@ -19,6 +19,15 @@ class LogTestCase(BaseTestCase): | |||
r = self.client.get(url) | |||
self.assertContains(r, "Dates and times are", status_code=200) | |||
def test_team_access_works(self): | |||
url = "/checks/%s/log/" % self.check.code | |||
# Logging in as bob, not alice. Bob has team access so this | |||
# should work. | |||
self.client.login(username="[email protected]", password="password") | |||
r = self.client.get(url) | |||
self.assertEqual(r.status_code, 200) | |||
def test_it_handles_bad_uuid(self): | |||
url = "/checks/not-uuid/log/" | |||
@ -10,6 +10,7 @@ class MyChecksTestCase(BaseTestCase): | |||
self.check.save() | |||
def test_it_works(self): | |||
self.client.login(username="[email protected]", password="password") | |||
r = self.client.get("/checks/") | |||
self.assertContains(r, "Alice Was Here", status_code=200) | |||
for email in ("[email protected]", "[email protected]"): | |||
self.client.login(username=email, password="password") | |||
r = self.client.get("/checks/") | |||
self.assertContains(r, "Alice Was Here", status_code=200) |
@ -19,6 +19,13 @@ class RemoveChannelTestCase(BaseTestCase): | |||
assert Channel.objects.count() == 0 | |||
def test_team_access_works(self): | |||
url = "/integrations/%s/remove/" % self.channel.code | |||
self.client.login(username="[email protected]", password="password") | |||
self.client.post(url) | |||
assert Channel.objects.count() == 0 | |||
def test_it_handles_bad_uuid(self): | |||
url = "/integrations/not-uuid/remove/" | |||
@ -18,6 +18,15 @@ class RemoveCheckTestCase(BaseTestCase): | |||
assert Check.objects.count() == 0 | |||
def test_team_access_works(self): | |||
url = "/checks/%s/remove/" % self.check.code | |||
# Logging in as bob, not alice. Bob has team access so this | |||
# should work. | |||
self.client.login(username="[email protected]", password="password") | |||
self.client.post(url) | |||
assert Check.objects.count() == 0 | |||
def test_it_handles_bad_uuid(self): | |||
url = "/checks/not-uuid/remove/" | |||
@ -28,6 +28,18 @@ class UpdateChannelTestCase(BaseTestCase): | |||
assert len(checks) == 1 | |||
assert checks[0].code == self.check.code | |||
def test_team_access_works(self): | |||
payload = { | |||
"channel": self.channel.code, | |||
"check-%s" % self.check.code: True | |||
} | |||
# Logging in as bob, not alice. Bob has team access so this | |||
# should work. | |||
self.client.login(username="[email protected]", password="password") | |||
r = self.client.post("/integrations/", data=payload, follow=True) | |||
self.assertEqual(r.status_code, 200) | |||
def test_it_checks_channel_user(self): | |||
payload = {"channel": self.channel.code} | |||
@ -20,6 +20,18 @@ class UpdateNameTestCase(BaseTestCase): | |||
check = Check.objects.get(code=self.check.code) | |||
assert check.name == "Alice Was Here" | |||
def test_team_access_works(self): | |||
url = "/checks/%s/name/" % self.check.code | |||
payload = {"name": "Bob Was Here"} | |||
# Logging in as bob, not alice. Bob has team access so this | |||
# should work. | |||
self.client.login(username="[email protected]", password="password") | |||
self.client.post(url, data=payload) | |||
check = Check.objects.get(code=self.check.code) | |||
assert check.name == "Bob Was Here" | |||
def test_it_checks_ownership(self): | |||
url = "/checks/%s/name/" % self.check.code | |||
payload = {"name": "Charlie Sent This"} | |||
@ -21,6 +21,18 @@ class UpdateTimeoutTestCase(BaseTestCase): | |||
assert check.timeout.total_seconds() == 3600 | |||
assert check.grace.total_seconds() == 60 | |||
def test_team_access_works(self): | |||
url = "/checks/%s/timeout/" % self.check.code | |||
payload = {"timeout": 7200, "grace": 60} | |||
# Logging in as bob, not alice. Bob has team access so this | |||
# should work. | |||
self.client.login(username="[email protected]", password="password") | |||
self.client.post(url, data=payload) | |||
check = Check.objects.get(code=self.check.code) | |||
assert check.timeout.total_seconds() == 7200 | |||
def test_it_handles_bad_uuid(self): | |||
url = "/checks/not-uuid/timeout/" | |||
payload = {"timeout": 3600, "grace": 60} | |||
@ -1,7 +1,7 @@ | |||
from django.contrib.auth.models import User | |||
from django.test import TestCase | |||
from hc.accounts.models import Profile | |||
from hc.accounts.models import Member, Profile | |||
class BaseTestCase(TestCase): | |||
@ -9,7 +9,7 @@ class BaseTestCase(TestCase): | |||
def setUp(self): | |||
super(BaseTestCase, self).setUp() | |||
# Normal user for tests | |||
# Alice is a normal user for tests | |||
self.alice = User(username="alice", email="[email protected]") | |||
self.alice.set_password("password") | |||
self.alice.save() | |||
@ -17,7 +17,19 @@ class BaseTestCase(TestCase): | |||
self.profile = Profile(user=self.alice, api_key="abc") | |||
self.profile.save() | |||
# "malicious user for tests | |||
# Bob is on Alice's team and should have access to her stuff | |||
self.bob = User(username="bob", email="[email protected]") | |||
self.bob.set_password("password") | |||
self.bob.save() | |||
self.bobs_profile = Profile(user=self.bob) | |||
self.bobs_profile.current_team = self.profile | |||
self.bobs_profile.save() | |||
m = Member(team=self.profile, user=self.bob) | |||
m.save() | |||
# Charlie should have no access to Alice's stuff | |||
self.charlie = User(username="charlie", email="[email protected]") | |||
self.charlie.set_password("password") | |||
self.charlie.save() | |||