123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806 |
- from __future__ import absolute_import
- from mock import patch
- from base64 import b64encode
- from datetime import datetime
- from django.core.urlresolvers import reverse
- from sentry.models import (
- Activity, ApiKey, ApiToken, Release,
- ReleaseCommit, ReleaseProject, Repository
- )
- from sentry.testutils import APITestCase
- class OrganizationReleaseListTest(APITestCase):
- def test_simple(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.organization
- org2 = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team1 = self.create_team(organization=org)
- team2 = self.create_team(organization=org)
- project1 = self.create_project(team=team1, organization=org)
- project2 = self.create_project(team=team2, organization=org2)
- project3 = self.create_project(team=team1, organization=org)
- self.create_member(teams=[team1], user=user, organization=org)
- self.login_as(user=user)
- release1 = Release.objects.create(
- organization_id=org.id,
- version='1',
- date_added=datetime(2013, 8, 13, 3, 8, 24, 880386),
- )
- release1.add_project(project1)
- release2 = Release.objects.create(
- organization_id=org2.id,
- version='2',
- date_added=datetime(2013, 8, 14, 3, 8, 24, 880386),
- )
- release2.add_project(project2)
- release3 = Release.objects.create(
- organization_id=org.id,
- version='3',
- date_added=datetime(2013, 8, 12, 3, 8, 24, 880386),
- date_released=datetime(2013, 8, 15, 3, 8, 24, 880386),
- )
- release3.add_project(project3)
- release4 = Release.objects.create(
- organization_id=org.id,
- version='4',
- date_added=datetime(2013, 8, 14, 3, 8, 24, 880386),
- )
- release4.add_project(project3)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.get(url, format='json')
- assert response.status_code == 200, response.content
- assert len(response.data) == 3
- assert response.data[0]['version'] == release3.version
- assert response.data[1]['version'] == release4.version
- assert response.data[2]['version'] == release1.version
- def test_query_filter(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.organization
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(team=team, organization=org)
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- release = Release.objects.create(
- organization_id=org.id,
- version='foobar',
- date_added=datetime(2013, 8, 13, 3, 8, 24, 880386),
- )
- release.add_project(project)
- release2 = Release.objects.create(
- organization_id=org.id,
- version='sdfsdfsdf',
- date_added=datetime(2013, 8, 13, 3, 8, 24, 880386),
- )
- release2.add_project(project)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.get(url + '?query=foo', format='json')
- assert response.status_code == 200, response.content
- assert len(response.data) == 1
- assert response.data[0]['version'] == release.version
- response = self.client.get(url + '?query=bar', format='json')
- assert response.status_code == 200, response.content
- assert len(response.data) == 0
- def test_project_permissions(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team1 = self.create_team(organization=org)
- team2 = self.create_team(organization=org)
- project1 = self.create_project(team=team1, organization=org)
- project2 = self.create_project(team=team2, organization=org)
- self.create_member(teams=[team1], user=user, organization=org)
- self.login_as(user=user)
- release1 = Release.objects.create(
- organization_id=org.id,
- version='1',
- date_added=datetime(2013, 8, 13, 3, 8, 24, 880386),
- )
- release1.add_project(project1)
- release2 = Release.objects.create(
- organization_id=org.id,
- version='2',
- date_added=datetime(2013, 8, 14, 3, 8, 24, 880386),
- )
- release2.add_project(project2)
- release3 = Release.objects.create(
- organization_id=org.id,
- version='3',
- date_added=datetime(2013, 8, 12, 3, 8, 24, 880386),
- date_released=datetime(2013, 8, 15, 3, 8, 24, 880386),
- )
- release3.add_project(project1)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.get(url, format='json')
- assert response.status_code == 200, response.content
- assert len(response.data) == 2
- assert response.data[0]['version'] == release3.version
- assert response.data[1]['version'] == release1.version
- class OrganizationReleaseCreateTest(APITestCase):
- def test_minimal(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- project2 = self.create_project(
- name='bar',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug,
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project.slug, project2.slug]
- })
- assert response.status_code == 201, response.content
- assert response.data['version']
- release = Release.objects.get(
- version=response.data['version'],
- )
- assert not release.owner
- assert release.organization == org
- assert ReleaseProject.objects.filter(
- release=release, project=project
- ).exists()
- assert ReleaseProject.objects.filter(
- release=release, project=project2
- ).exists()
- def test_duplicate(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- release = Release.objects.create(version='1.2.1',
- organization=org)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug,
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project.slug]
- })
- # should be 201 because project was added
- assert response.status_code == 201, response.content
- assert Release.objects.filter(
- version='1.2.1', organization=org
- ).count() == 1
- # make sure project was added
- assert ReleaseProject.objects.filter(
- release=release, project=project
- ).exists()
- def test_activity(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- project2 = self.create_project(
- name='bar',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- release = Release.objects.create(version='1.2.1',
- date_released=datetime.utcnow(),
- organization=org)
- release.add_project(project)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug,
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project.slug]
- })
- assert response.status_code == 208, response.content
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project.slug, project2.slug]
- })
- # should be 201 because 1 project was added
- assert response.status_code == 201, response.content
- assert not Activity.objects.filter(
- type=Activity.RELEASE,
- project=project,
- ident=release.version
- ).exists()
- assert Activity.objects.filter(
- type=Activity.RELEASE,
- project=project2,
- ident=release.version
- ).exists()
- def test_version_whitespace(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.post(url, data={
- 'version': '1.2.3\n',
- 'projects': [project.slug]
- })
- assert response.status_code == 400, response.content
- response = self.client.post(url, data={
- 'version': '\n1.2.3',
- 'projects': [project.slug]
- })
- assert response.status_code == 400, response.content
- response = self.client.post(url, data={
- 'version': '1.\n2.3',
- 'projects': [project.slug]
- })
- assert response.status_code == 400, response.content
- response = self.client.post(url, data={
- 'version': '1.2.3\f',
- 'projects': [project.slug]
- })
- assert response.status_code == 400, response.content
- response = self.client.post(url, data={
- 'version': '1.2.3\t',
- 'projects': [project.slug]
- })
- assert response.status_code == 400, response.content
- response = self.client.post(url, data={
- 'version': '1.2.3+dev',
- 'projects': [project.slug]
- })
- assert response.status_code == 201, response.content
- assert response.data['version'] == '1.2.3+dev'
- release = Release.objects.get(
- organization_id=org.id,
- version=response.data['version'],
- )
- assert not release.owner
- def test_features(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'owner': self.user.email,
- 'projects': [project.slug]
- })
- assert response.status_code == 201, response.content
- assert response.data['version']
- release = Release.objects.get(
- organization_id=org.id,
- version=response.data['version'],
- )
- assert release.owner == self.user
- def test_commits(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'commits': [
- {'id': 'a' * 40},
- {'id': 'b' * 40},
- ],
- 'projects': [project.slug]
- })
- assert response.status_code == 201, (response.status_code, response.content)
- assert response.data['version']
- release = Release.objects.get(
- organization_id=org.id,
- version=response.data['version'],
- )
- rc_list = list(ReleaseCommit.objects.filter(
- release=release,
- ).select_related('commit', 'commit__author').order_by('order'))
- assert len(rc_list) == 2
- for rc in rc_list:
- assert rc.organization_id
- @patch('sentry.tasks.commits.fetch_commits')
- def test_commits_from_provider(self, mock_fetch_commits):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- repo = Repository.objects.create(
- organization_id=org.id,
- name='example/example',
- provider='dummy',
- )
- repo2 = Repository.objects.create(
- organization_id=org.id,
- name='example/example2',
- provider='dummy',
- )
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- self.client.post(url, data={
- 'version': '1',
- 'refs': [
- {'commit': '0' * 40, 'repository': repo.name},
- {'commit': '0' * 40, 'repository': repo2.name},
- ],
- 'projects': [project.slug]
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'refs': [
- {'commit': 'a' * 40, 'repository': repo.name},
- {'commit': 'b' * 40, 'repository': repo2.name},
- ],
- 'projects': [project.slug]
- })
- assert response.status_code == 201
- mock_fetch_commits.apply_async.assert_called_with(
- kwargs={
- 'release_id': Release.objects.get(version='1.2.1', organization=org).id,
- 'user_id': user.id,
- 'refs': [
- {'commit': 'a' * 40, 'repository': repo.name},
- {'commit': 'b' * 40, 'repository': repo2.name},
- ],
- 'prev_release_id': Release.objects.get(version='1', organization=org).id,
- }
- )
- @patch('sentry.tasks.commits.fetch_commits')
- def test_commits_from_provider_deprecated_head_commits(self, mock_fetch_commits):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- repo = Repository.objects.create(
- organization_id=org.id,
- name='example/example',
- provider='dummy',
- )
- repo2 = Repository.objects.create(
- organization_id=org.id,
- name='example/example2',
- provider='dummy',
- )
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- self.client.post(url, data={
- 'version': '1',
- 'headCommits': [
- {'currentId': '0' * 40, 'repository': repo.name},
- {'currentId': '0' * 40, 'repository': repo2.name},
- ],
- 'projects': [project.slug]
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'headCommits': [
- {'currentId': 'a' * 40, 'repository': repo.name},
- {'currentId': 'b' * 40, 'repository': repo2.name},
- ],
- 'projects': [project.slug]
- })
- mock_fetch_commits.apply_async.assert_called_with(
- kwargs={
- 'release_id': Release.objects.get(version='1.2.1', organization=org).id,
- 'user_id': user.id,
- 'refs': [
- {'commit': 'a' * 40, 'repository': repo.name, 'previousCommit': None},
- {'commit': 'b' * 40, 'repository': repo2.name, 'previousCommit': None},
- ],
- 'prev_release_id': Release.objects.get(version='1', organization=org).id,
- }
- )
- assert response.status_code == 201
- def test_bad_project_slug(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project.slug, 'banana']
- })
- assert response.status_code == 400
- assert 'Invalid project slugs' in response.content
- def test_project_permissions(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team1 = self.create_team(organization=org)
- team2 = self.create_team(organization=org)
- project1 = self.create_project(team=team1, organization=org)
- project2 = self.create_project(team=team2, organization=org)
- self.create_member(teams=[team1], user=user, organization=org)
- self.login_as(user=user)
- release1 = Release.objects.create(
- organization_id=org.id,
- version='1',
- date_added=datetime(2013, 8, 13, 3, 8, 24, 880386),
- )
- release1.add_project(project1)
- release2 = Release.objects.create(
- organization_id=org.id,
- version='2',
- date_added=datetime(2013, 8, 14, 3, 8, 24, 880386),
- )
- release2.add_project(project2)
- release3 = Release.objects.create(
- organization_id=org.id,
- version='3',
- date_added=datetime(2013, 8, 12, 3, 8, 24, 880386),
- date_released=datetime(2013, 8, 15, 3, 8, 24, 880386),
- )
- release3.add_project(project1)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project1.slug, project2.slug]
- })
- assert response.status_code == 400
- assert 'Invalid project slugs' in response.content
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project1.slug]
- })
- assert response.status_code == 201, response.content
- def test_api_key(self):
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- org2 = self.create_organization()
- team1 = self.create_team(organization=org)
- project1 = self.create_project(team=team1, organization=org)
- release1 = Release.objects.create(
- organization_id=org.id,
- version='1',
- date_added=datetime(2013, 8, 13, 3, 8, 24, 880386),
- )
- release1.add_project(project1)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- # test right org, wrong permissions level
- bad_api_key = ApiKey.objects.create(
- organization=org,
- scope_list=['project:read'],
- )
- response = self.client.post(
- url,
- data={
- 'version': '1.2.1',
- 'projects': [
- project1.slug]},
- HTTP_AUTHORIZATION='Basic ' +
- b64encode(
- '{}:'.format(
- bad_api_key.key)))
- assert response.status_code == 403
- # test wrong org, right permissions level
- wrong_org_api_key = ApiKey.objects.create(
- organization=org2,
- scope_list=['project:write'],
- )
- response = self.client.post(
- url,
- data={
- 'version': '1.2.1',
- 'projects': [
- project1.slug]},
- HTTP_AUTHORIZATION='Basic ' +
- b64encode(
- '{}:'.format(
- wrong_org_api_key.key)))
- assert response.status_code == 403
- # test right org, right permissions level
- good_api_key = ApiKey.objects.create(
- organization=org,
- scope_list=['project:write'],
- )
- response = self.client.post(
- url,
- data={
- 'version': '1.2.1',
- 'projects': [
- project1.slug]},
- HTTP_AUTHORIZATION='Basic ' +
- b64encode(
- '{}:'.format(
- good_api_key.key)))
- assert response.status_code == 201, response.content
- @patch('sentry.tasks.commits.fetch_commits')
- def test_api_token(self, mock_fetch_commits):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- repo = Repository.objects.create(
- organization_id=org.id,
- name='getsentry/sentry',
- provider='dummy',
- )
- repo2 = Repository.objects.create(
- organization_id=org.id,
- name='getsentry/sentry-plugins',
- provider='dummy',
- )
- api_token = ApiToken.objects.create(
- user=user,
- scope_list=['project:releases'],
- )
- team1 = self.create_team(organization=org)
- self.create_member(teams=[team1], user=user, organization=org)
- project1 = self.create_project(team=team1, organization=org)
- release1 = Release.objects.create(
- organization_id=org.id,
- version='1',
- date_added=datetime(2013, 8, 13, 3, 8, 24, 880386),
- )
- release1.add_project(project1)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'refs': [
- {'commit': 'a' * 40, 'repository': repo.name, 'previousCommit': 'c' * 40},
- {'commit': 'b' * 40, 'repository': repo2.name},
- ],
- 'projects': [project1.slug]
- }, HTTP_AUTHORIZATION='Bearer {}'.format(api_token.token))
- mock_fetch_commits.apply_async.assert_called_with(
- kwargs={
- 'release_id': Release.objects.get(version='1.2.1', organization=org).id,
- 'user_id': user.id,
- 'refs': [
- {'commit': 'a' * 40, 'repository': repo.name, 'previousCommit': 'c' * 40},
- {'commit': 'b' * 40, 'repository': repo2.name},
- ],
- 'prev_release_id': release1.id,
- }
- )
- assert response.status_code == 201
- def test_bad_repo_name(self):
- user = self.create_user(is_staff=False, is_superuser=False)
- org = self.create_organization()
- org.flags.allow_joinleave = False
- org.save()
- team = self.create_team(organization=org)
- project = self.create_project(
- name='foo',
- organization=org,
- team=team
- )
- self.create_member(teams=[team], user=user, organization=org)
- self.login_as(user=user)
- url = reverse('sentry-api-0-organization-releases', kwargs={
- 'organization_slug': org.slug
- })
- response = self.client.post(url, data={
- 'version': '1.2.1',
- 'projects': [project.slug],
- 'refs': [{
- 'repository': 'not_a_repo',
- 'commit': 'a' * 40,
- }]
- })
- assert response.status_code == 400
- assert response.data == {
- 'refs': [u'Invalid repository names: not_a_repo']
- }
|