administrator.e2e-spec.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import { DeletionResult } from '@vendure/common/lib/generated-types';
  2. import { SUPER_ADMIN_USER_IDENTIFIER } from '@vendure/common/lib/shared-constants';
  3. import { createErrorResultGuard, createTestEnvironment, ErrorResultGuard } from '@vendure/testing';
  4. import { fail } from 'assert';
  5. import path from 'path';
  6. import { afterAll, beforeAll, describe, expect, it } from 'vitest';
  7. import { initialData } from '../../../e2e-common/e2e-initial-data';
  8. import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
  9. import { administratorFragment, currentUserFragment } from './graphql/fragments-admin';
  10. import { FragmentOf } from './graphql/graphql-admin';
  11. import {
  12. attemptLoginDocument,
  13. createAdministratorDocument,
  14. deleteAdministratorDocument,
  15. getActiveAdministratorDocument,
  16. getAdministratorDocument,
  17. getAdministratorsDocument,
  18. updateActiveAdministratorDocument,
  19. updateAdministratorDocument,
  20. } from './graphql/shared-definitions';
  21. import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
  22. describe('Administrator resolver', () => {
  23. const { server, adminClient } = createTestEnvironment(testConfig());
  24. let createdAdmin: FragmentOf<typeof administratorFragment>;
  25. beforeAll(async () => {
  26. await server.init({
  27. initialData,
  28. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
  29. customerCount: 1,
  30. });
  31. await adminClient.asSuperAdmin();
  32. }, TEST_SETUP_TIMEOUT_MS);
  33. afterAll(async () => {
  34. await server.destroy();
  35. });
  36. it('administrators', async () => {
  37. const result = await adminClient.query(getAdministratorsDocument);
  38. expect(result.administrators.items.length).toBe(1);
  39. expect(result.administrators.totalItems).toBe(1);
  40. });
  41. it('createAdministrator', async () => {
  42. const result = await adminClient.query(createAdministratorDocument, {
  43. input: {
  44. emailAddress: 'test@test.com',
  45. firstName: 'First',
  46. lastName: 'Last',
  47. password: 'password',
  48. roleIds: ['1'],
  49. },
  50. });
  51. createdAdmin = result.createAdministrator;
  52. expect(createdAdmin).toMatchSnapshot();
  53. });
  54. it('administrator', async () => {
  55. const result = await adminClient.query(getAdministratorDocument, {
  56. id: createdAdmin.id,
  57. });
  58. expect(result.administrator).toEqual(createdAdmin);
  59. });
  60. it('updateAdministrator', async () => {
  61. const result = await adminClient.query(updateAdministratorDocument, {
  62. input: {
  63. id: createdAdmin.id,
  64. emailAddress: 'new-email',
  65. firstName: 'new first',
  66. lastName: 'new last',
  67. password: 'new password',
  68. roleIds: ['2'],
  69. },
  70. });
  71. expect(result.updateAdministrator).toMatchSnapshot();
  72. });
  73. it('updateAdministrator works with partial input', async () => {
  74. const result = await adminClient.query(updateAdministratorDocument, {
  75. input: {
  76. id: createdAdmin.id,
  77. emailAddress: 'newest-email',
  78. },
  79. });
  80. expect(result.updateAdministrator.emailAddress).toBe('newest-email');
  81. expect(result.updateAdministrator.firstName).toBe('new first');
  82. expect(result.updateAdministrator.lastName).toBe('new last');
  83. });
  84. it(
  85. 'updateAdministrator throws with invalid roleId',
  86. assertThrowsWithMessage(
  87. () =>
  88. adminClient.query(updateAdministratorDocument, {
  89. input: {
  90. id: createdAdmin.id,
  91. emailAddress: 'new-email',
  92. firstName: 'new first',
  93. lastName: 'new last',
  94. password: 'new password',
  95. roleIds: ['999'],
  96. },
  97. }),
  98. 'No Role with the id "999" could be found',
  99. ),
  100. );
  101. it('deleteAdministrator', async () => {
  102. const { administrators: before } = await adminClient.query(getAdministratorsDocument);
  103. expect(before.totalItems).toBe(2);
  104. const { deleteAdministrator } = await adminClient.query(deleteAdministratorDocument, {
  105. id: createdAdmin.id,
  106. });
  107. expect(deleteAdministrator.result).toBe(DeletionResult.DELETED);
  108. const { administrators: after } = await adminClient.query(getAdministratorsDocument);
  109. expect(after.totalItems).toBe(1);
  110. });
  111. it('cannot delete sole SuperAdmin', async () => {
  112. const { administrators: before } = await adminClient.query(getAdministratorsDocument);
  113. expect(before.totalItems).toBe(1);
  114. expect(before.items[0].emailAddress).toBe('superadmin');
  115. try {
  116. await adminClient.query(deleteAdministratorDocument, {
  117. id: before.items[0].id,
  118. });
  119. fail('Should have thrown');
  120. } catch (e: any) {
  121. expect(e.message).toBe('The sole SuperAdmin cannot be deleted');
  122. }
  123. const { administrators: after } = await adminClient.query(getAdministratorsDocument);
  124. expect(after.totalItems).toBe(1);
  125. });
  126. it(
  127. 'cannot remove SuperAdmin role from sole SuperAdmin',
  128. assertThrowsWithMessage(async () => {
  129. await adminClient.query(updateAdministratorDocument, {
  130. input: {
  131. id: 'T_1',
  132. roleIds: [],
  133. },
  134. });
  135. }, 'Cannot remove the SuperAdmin role from the sole SuperAdmin'),
  136. );
  137. it('cannot query a deleted Administrator', async () => {
  138. const { administrator } = await adminClient.query(getAdministratorDocument, {
  139. id: createdAdmin.id,
  140. });
  141. expect(administrator).toBeNull();
  142. });
  143. it('activeAdministrator', async () => {
  144. await adminClient.asAnonymousUser();
  145. const { activeAdministrator: result1 } = await adminClient.query(getActiveAdministratorDocument);
  146. expect(result1).toBeNull();
  147. await adminClient.asSuperAdmin();
  148. const { activeAdministrator: result2 } = await adminClient.query(getActiveAdministratorDocument);
  149. expect(result2?.emailAddress).toBe(SUPER_ADMIN_USER_IDENTIFIER);
  150. });
  151. it('updateActiveAdministrator', async () => {
  152. const { updateActiveAdministrator } = await adminClient.query(updateActiveAdministratorDocument, {
  153. input: {
  154. firstName: 'Thomas',
  155. lastName: 'Anderson',
  156. emailAddress: 'neo@metacortex.com',
  157. },
  158. });
  159. expect(updateActiveAdministrator.firstName).toBe('Thomas');
  160. expect(updateActiveAdministrator.lastName).toBe('Anderson');
  161. const { activeAdministrator } = await adminClient.query(getActiveAdministratorDocument);
  162. expect(activeAdministrator?.firstName).toBe('Thomas');
  163. expect(activeAdministrator?.user.identifier).toBe('neo@metacortex.com');
  164. });
  165. it('supports case-sensitive admin identifiers', async () => {
  166. const loginResultGuard: ErrorResultGuard<FragmentOf<typeof currentUserFragment>> =
  167. createErrorResultGuard(input => !!input.identifier);
  168. await adminClient.query(createAdministratorDocument, {
  169. input: {
  170. emailAddress: 'NewAdmin',
  171. firstName: 'New',
  172. lastName: 'Admin',
  173. password: 'password',
  174. roleIds: ['1'],
  175. },
  176. });
  177. const { login } = await adminClient.query(attemptLoginDocument, {
  178. username: 'NewAdmin',
  179. password: 'password',
  180. });
  181. loginResultGuard.assertSuccess(login);
  182. expect(login.identifier).toBe('NewAdmin');
  183. });
  184. });