sentryApplicationDetails.spec.jsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*global global*/
  2. import {observable} from 'mobx';
  3. import React from 'react';
  4. import {Client} from 'app/api';
  5. import {mount} from 'enzyme';
  6. import SentryApplicationDetails from 'app/views/settings/organizationDeveloperSettings/sentryApplicationDetails';
  7. import {selectByValue} from '../../../../helpers/select';
  8. describe('Sentry Application Details', function() {
  9. let org;
  10. let orgId;
  11. let sentryApp;
  12. let wrapper;
  13. let createAppRequest;
  14. let editAppRequest;
  15. beforeEach(() => {
  16. Client.clearMockResponses();
  17. org = TestStubs.Organization();
  18. orgId = org.slug;
  19. });
  20. describe('new sentry application', () => {
  21. beforeEach(() => {
  22. createAppRequest = Client.addMockResponse({
  23. url: '/sentry-apps/',
  24. method: 'POST',
  25. body: [],
  26. });
  27. wrapper = mount(
  28. <SentryApplicationDetails params={{orgId}} />,
  29. TestStubs.routerContext()
  30. );
  31. });
  32. describe('renders()', () => {
  33. it('it shows empty scopes and no credentials', function() {
  34. expect(wrapper).toMatchSnapshot();
  35. // new app starts off with no scopes selected
  36. expect(wrapper.find('PermissionsObserver').prop('scopes')).toEqual([]);
  37. expect(
  38. wrapper.find('PanelHeader').findWhere(h => h.text() == 'Permissions')
  39. ).toBeDefined();
  40. });
  41. });
  42. describe('saving new app', () => {
  43. it('updates a SentryApp', function() {
  44. wrapper
  45. .find('Input[name="name"]')
  46. .simulate('change', {target: {value: 'Test App'}});
  47. wrapper
  48. .find('Input[name="webhookUrl"]')
  49. .simulate('change', {target: {value: 'https://webhook.com'}});
  50. wrapper
  51. .find('Input[name="redirectUrl"]')
  52. .simulate('change', {target: {value: 'https://webhook.com/setup'}});
  53. wrapper.find('Switch[name="isAlertable"]').simulate('click');
  54. selectByValue(wrapper, 'admin', {name: 'Member--permission'});
  55. selectByValue(wrapper, 'admin', {name: 'Event--permission'});
  56. wrapper
  57. .find('Checkbox')
  58. .first()
  59. .simulate('change', {target: {checked: true}});
  60. wrapper.find('form').simulate('submit');
  61. let data = {
  62. name: 'Test App',
  63. organization: org.slug,
  64. redirectUrl: 'https://webhook.com/setup',
  65. webhookUrl: 'https://webhook.com',
  66. scopes: observable([
  67. 'member:read',
  68. 'member:admin',
  69. 'event:read',
  70. 'event:admin',
  71. ]),
  72. events: observable(['issue']),
  73. isAlertable: true,
  74. };
  75. expect(createAppRequest).toHaveBeenCalledWith(
  76. '/sentry-apps/',
  77. expect.objectContaining({
  78. data,
  79. method: 'POST',
  80. })
  81. );
  82. });
  83. });
  84. });
  85. describe('edit existing application', () => {
  86. beforeEach(() => {
  87. sentryApp = TestStubs.SentryApp();
  88. const appSlug = sentryApp.slug;
  89. Client.addMockResponse({
  90. url: `/sentry-apps/${sentryApp.slug}/`,
  91. body: sentryApp,
  92. });
  93. wrapper = mount(
  94. <SentryApplicationDetails params={{appSlug, orgId}} />,
  95. TestStubs.routerContext()
  96. );
  97. });
  98. describe('renders()', () => {
  99. it('it shows application data and credentials', function() {
  100. expect(wrapper).toMatchSnapshot();
  101. // data should be filled out
  102. expect(wrapper.find('PermissionsObserver').prop('scopes')).toEqual([
  103. 'project:read',
  104. ]);
  105. // 'Credentials' should be last PanelHeader when editing an application.
  106. expect(
  107. wrapper
  108. .find('PanelHeader')
  109. .last()
  110. .text()
  111. ).toBe('Credentials');
  112. });
  113. });
  114. describe('saving edited app', () => {
  115. beforeEach(() => {
  116. sentryApp.events = ['issue'];
  117. editAppRequest = Client.addMockResponse({
  118. url: `/sentry-apps/${sentryApp.slug}/`,
  119. method: 'PUT',
  120. body: [],
  121. });
  122. });
  123. it('it updates app with correct data', function() {
  124. wrapper
  125. .find('Input[name="redirectUrl"]')
  126. .simulate('change', {target: {value: 'https://hello.com/'}});
  127. wrapper
  128. .find('Checkbox')
  129. .first()
  130. .simulate('change', {target: {checked: false}});
  131. wrapper.find('form').simulate('submit');
  132. expect(editAppRequest).toHaveBeenCalledWith(
  133. `/sentry-apps/${sentryApp.slug}/`,
  134. expect.objectContaining({
  135. data: expect.objectContaining({
  136. redirectUrl: 'https://hello.com/',
  137. events: observable.array([]),
  138. }),
  139. method: 'PUT',
  140. })
  141. );
  142. });
  143. it('submits with no-access for event subscription when permission is revoked', () => {
  144. wrapper
  145. .find('Checkbox')
  146. .first()
  147. .simulate('change', {target: {checked: true}});
  148. selectByValue(wrapper, 'no-access', {name: 'Event--permission'});
  149. wrapper.find('form').simulate('submit');
  150. expect(editAppRequest).toHaveBeenCalledWith(
  151. `/sentry-apps/${sentryApp.slug}/`,
  152. expect.objectContaining({
  153. data: expect.objectContaining({
  154. events: observable.array([]),
  155. }),
  156. method: 'PUT',
  157. })
  158. );
  159. });
  160. });
  161. });
  162. });