accountSecurityDetails.spec.jsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import React from 'react';
  2. import {Client} from 'app/api';
  3. import {initializeOrg} from 'sentry-test/initializeOrg';
  4. import {mountWithTheme} from 'sentry-test/enzyme';
  5. import AccountSecurityDetails from 'app/views/settings/account/accountSecurity/accountSecurityDetails';
  6. import AccountSecurityWrapper from 'app/views/settings/account/accountSecurity/accountSecurityWrapper';
  7. const ENDPOINT = '/users/me/authenticators/';
  8. const ORG_ENDPOINT = '/organizations/';
  9. describe('AccountSecurityDetails', function() {
  10. let wrapper;
  11. let routerContext;
  12. let router;
  13. let params;
  14. describe('Totp', function() {
  15. beforeAll(function() {
  16. Client.clearMockResponses();
  17. params = {
  18. authId: 15,
  19. };
  20. ({router, routerContext} = initializeOrg({
  21. router: {
  22. params,
  23. },
  24. }));
  25. Client.addMockResponse({
  26. url: ENDPOINT,
  27. body: TestStubs.AllAuthenticators(),
  28. });
  29. Client.addMockResponse({
  30. url: ORG_ENDPOINT,
  31. body: TestStubs.Organizations(),
  32. });
  33. Client.addMockResponse({
  34. url: `${ENDPOINT}15/`,
  35. body: TestStubs.Authenticators().Totp(),
  36. });
  37. wrapper = mountWithTheme(
  38. <AccountSecurityWrapper>
  39. <AccountSecurityDetails router={router} params={params} />
  40. </AccountSecurityWrapper>,
  41. routerContext
  42. );
  43. });
  44. it('has enrolled circle indicator', function() {
  45. expect(wrapper.find('AuthenticatorStatus').prop('enabled')).toBe(true);
  46. });
  47. it('has created and last used dates', function() {
  48. expect(wrapper.find('AuthenticatorDate')).toHaveLength(2);
  49. });
  50. it('can remove method', function() {
  51. const deleteMock = Client.addMockResponse({
  52. url: `${ENDPOINT}15/`,
  53. method: 'DELETE',
  54. });
  55. wrapper.find('RemoveConfirm Button').simulate('click');
  56. wrapper
  57. .find('Modal Button')
  58. .last()
  59. .simulate('click');
  60. expect(deleteMock).toHaveBeenCalled();
  61. });
  62. it('can remove one of multiple 2fa methods when org requires 2fa', function() {
  63. Client.addMockResponse({
  64. url: ORG_ENDPOINT,
  65. body: TestStubs.Organizations({require2FA: true}),
  66. });
  67. const deleteMock = Client.addMockResponse({
  68. url: `${ENDPOINT}15/`,
  69. method: 'DELETE',
  70. });
  71. wrapper = mountWithTheme(
  72. <AccountSecurityWrapper>
  73. <AccountSecurityDetails router={router} params={params} />
  74. </AccountSecurityWrapper>,
  75. routerContext
  76. );
  77. wrapper.find('RemoveConfirm Button').simulate('click');
  78. wrapper
  79. .find('Modal Button')
  80. .last()
  81. .simulate('click');
  82. expect(deleteMock).toHaveBeenCalled();
  83. });
  84. it('can not remove last 2fa method when org requires 2fa', function() {
  85. Client.addMockResponse({
  86. url: ORG_ENDPOINT,
  87. body: TestStubs.Organizations({require2FA: true}),
  88. });
  89. Client.addMockResponse({
  90. url: ENDPOINT,
  91. body: [TestStubs.Authenticators().Totp()],
  92. });
  93. const deleteMock = Client.addMockResponse({
  94. url: `${ENDPOINT}15/`,
  95. method: 'DELETE',
  96. });
  97. wrapper = mountWithTheme(
  98. <AccountSecurityWrapper>
  99. <AccountSecurityDetails router={router} params={params} />
  100. </AccountSecurityWrapper>,
  101. routerContext
  102. );
  103. wrapper.find('RemoveConfirm Button').simulate('click');
  104. expect(wrapper.find('Modal Button')).toHaveLength(0);
  105. expect(deleteMock).not.toHaveBeenCalled();
  106. });
  107. });
  108. describe('Recovery', function() {
  109. beforeEach(function() {
  110. params = {authId: 16};
  111. ({router, routerContext} = initializeOrg({
  112. router: {
  113. params,
  114. },
  115. }));
  116. Client.clearMockResponses();
  117. Client.addMockResponse({
  118. url: ENDPOINT,
  119. body: TestStubs.AllAuthenticators(),
  120. });
  121. Client.addMockResponse({
  122. url: ORG_ENDPOINT,
  123. body: TestStubs.Organizations(),
  124. });
  125. Client.addMockResponse({
  126. url: `${ENDPOINT}16/`,
  127. body: TestStubs.Authenticators().Recovery(),
  128. });
  129. wrapper = mountWithTheme(
  130. <AccountSecurityWrapper>
  131. <AccountSecurityDetails router={router} params={params} />
  132. </AccountSecurityWrapper>,
  133. routerContext
  134. );
  135. });
  136. it('has enrolled circle indicator', function() {
  137. expect(wrapper.find('AuthenticatorStatus').prop('enabled')).toBe(true);
  138. });
  139. it('has created and last used dates', function() {
  140. expect(wrapper.find('AuthenticatorDate')).toHaveLength(2);
  141. });
  142. it('does not have remove button', function() {
  143. expect(wrapper.find('RemoveConfirm')).toHaveLength(0);
  144. });
  145. it('regenerates codes', function() {
  146. const deleteMock = Client.addMockResponse({
  147. url: `${ENDPOINT}16/`,
  148. method: 'PUT',
  149. });
  150. wrapper.find('RecoveryCodes').prop('onRegenerateBackupCodes')();
  151. expect(deleteMock).toHaveBeenCalled();
  152. });
  153. it('has copy, print and download buttons', function() {
  154. const codes = 'ABCD-1234 \nEFGH-5678';
  155. const downloadCodes = `Button[href="data:text/plain;charset=utf-8,${codes}"]`;
  156. expect(wrapper.find(downloadCodes)).toHaveLength(1);
  157. wrapper.find(downloadCodes).simulate('click');
  158. expect(wrapper.find('Button InlineSvg[src="icon-print"]')).toHaveLength(1);
  159. expect(wrapper.find('iframe[name="printable"]')).toHaveLength(1);
  160. expect(wrapper.find(`Clipboard[value="${codes}"]`)).toHaveLength(1);
  161. });
  162. });
  163. });