role.e2e-spec.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. import { omit } from '@vendure/common/lib/omit';
  2. import {
  3. CUSTOMER_ROLE_CODE,
  4. DEFAULT_CHANNEL_CODE,
  5. SUPER_ADMIN_ROLE_CODE,
  6. } from '@vendure/common/lib/shared-constants';
  7. import { createTestEnvironment } from '@vendure/testing';
  8. import gql from 'graphql-tag';
  9. import path from 'path';
  10. import { initialData } from '../../../e2e-common/e2e-initial-data';
  11. import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
  12. import { ROLE_FRAGMENT } from './graphql/fragments';
  13. import {
  14. ChannelFragment,
  15. CreateChannel,
  16. CreateRole,
  17. CurrencyCode,
  18. DeleteRole,
  19. DeletionResult,
  20. GetRole,
  21. GetRoles,
  22. LanguageCode,
  23. Permission,
  24. Role,
  25. UpdateRole,
  26. } from './graphql/generated-e2e-admin-types';
  27. import { CREATE_CHANNEL, CREATE_ROLE } from './graphql/shared-definitions';
  28. import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
  29. import { sortById } from './utils/test-order-utils';
  30. describe('Role resolver', () => {
  31. const { server, adminClient } = createTestEnvironment(testConfig);
  32. let createdRole: Role.Fragment;
  33. let defaultRoles: Role.Fragment[];
  34. beforeAll(async () => {
  35. await server.init({
  36. initialData,
  37. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
  38. customerCount: 1,
  39. });
  40. await adminClient.asSuperAdmin();
  41. }, TEST_SETUP_TIMEOUT_MS);
  42. afterAll(async () => {
  43. await server.destroy();
  44. });
  45. it('roles', async () => {
  46. const result = await adminClient.query<GetRoles.Query, GetRoles.Variables>(GET_ROLES);
  47. defaultRoles = result.roles.items;
  48. expect(result.roles.items.length).toBe(2);
  49. expect(result.roles.totalItems).toBe(2);
  50. });
  51. it(
  52. 'createRole with invalid permission',
  53. assertThrowsWithMessage(async () => {
  54. await adminClient.query<CreateRole.Mutation, CreateRole.Variables>(CREATE_ROLE, {
  55. input: {
  56. code: 'test',
  57. description: 'test role',
  58. permissions: ['bad permission' as any],
  59. },
  60. });
  61. }, 'Variable "$input" got invalid value "bad permission" at "input.permissions[0]"; Expected type Permission.'),
  62. );
  63. it('createRole with no permissions includes Authenticated', async () => {
  64. const { createRole } = await adminClient.query<CreateRole.Mutation, CreateRole.Variables>(
  65. CREATE_ROLE,
  66. {
  67. input: {
  68. code: 'test',
  69. description: 'test role',
  70. permissions: [],
  71. },
  72. },
  73. );
  74. expect(omit(createRole, ['channels'])).toEqual({
  75. code: 'test',
  76. description: 'test role',
  77. id: 'T_3',
  78. permissions: [Permission.Authenticated],
  79. });
  80. });
  81. it('createRole deduplicates permissions', async () => {
  82. const { createRole } = await adminClient.query<CreateRole.Mutation, CreateRole.Variables>(
  83. CREATE_ROLE,
  84. {
  85. input: {
  86. code: 'test2',
  87. description: 'test role2',
  88. permissions: [Permission.ReadSettings, Permission.ReadSettings],
  89. },
  90. },
  91. );
  92. expect(omit(createRole, ['channels'])).toEqual({
  93. code: 'test2',
  94. description: 'test role2',
  95. id: 'T_4',
  96. permissions: [Permission.Authenticated, Permission.ReadSettings],
  97. });
  98. });
  99. it('createRole with permissions', async () => {
  100. const result = await adminClient.query<CreateRole.Mutation, CreateRole.Variables>(CREATE_ROLE, {
  101. input: {
  102. code: 'test',
  103. description: 'test role',
  104. permissions: [Permission.ReadCustomer, Permission.UpdateCustomer],
  105. },
  106. });
  107. createdRole = result.createRole;
  108. expect(createdRole).toEqual({
  109. code: 'test',
  110. description: 'test role',
  111. id: 'T_5',
  112. permissions: [Permission.Authenticated, Permission.ReadCustomer, Permission.UpdateCustomer],
  113. channels: [
  114. {
  115. code: DEFAULT_CHANNEL_CODE,
  116. id: 'T_1',
  117. token: 'e2e-default-channel',
  118. },
  119. ],
  120. });
  121. });
  122. it('role', async () => {
  123. const result = await adminClient.query<GetRole.Query, GetRole.Variables>(GET_ROLE, {
  124. id: createdRole.id,
  125. });
  126. expect(result.role).toEqual(createdRole);
  127. });
  128. it('updateRole', async () => {
  129. const result = await adminClient.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
  130. input: {
  131. id: createdRole.id,
  132. code: 'test-modified',
  133. description: 'test role modified',
  134. permissions: [Permission.ReadCustomer, Permission.UpdateCustomer, Permission.DeleteCustomer],
  135. },
  136. });
  137. expect(omit(result.updateRole, ['channels'])).toEqual({
  138. code: 'test-modified',
  139. description: 'test role modified',
  140. id: 'T_5',
  141. permissions: [
  142. Permission.Authenticated,
  143. Permission.ReadCustomer,
  144. Permission.UpdateCustomer,
  145. Permission.DeleteCustomer,
  146. ],
  147. });
  148. });
  149. it('updateRole works with partial input', async () => {
  150. const result = await adminClient.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
  151. input: {
  152. id: createdRole.id,
  153. code: 'test-modified-again',
  154. },
  155. });
  156. expect(result.updateRole.code).toBe('test-modified-again');
  157. expect(result.updateRole.description).toBe('test role modified');
  158. expect(result.updateRole.permissions).toEqual([
  159. Permission.Authenticated,
  160. Permission.ReadCustomer,
  161. Permission.UpdateCustomer,
  162. Permission.DeleteCustomer,
  163. ]);
  164. });
  165. it('updateRole deduplicates permissions', async () => {
  166. const result = await adminClient.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
  167. input: {
  168. id: createdRole.id,
  169. permissions: [
  170. Permission.Authenticated,
  171. Permission.Authenticated,
  172. Permission.ReadCustomer,
  173. Permission.ReadCustomer,
  174. ],
  175. },
  176. });
  177. expect(result.updateRole.permissions).toEqual([Permission.Authenticated, Permission.ReadCustomer]);
  178. });
  179. it(
  180. 'updateRole is not allowed for SuperAdmin role',
  181. assertThrowsWithMessage(async () => {
  182. const superAdminRole = defaultRoles.find(r => r.code === SUPER_ADMIN_ROLE_CODE);
  183. if (!superAdminRole) {
  184. fail(`Could not find SuperAdmin role`);
  185. return;
  186. }
  187. return adminClient.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
  188. input: {
  189. id: superAdminRole.id,
  190. code: 'superadmin-modified',
  191. description: 'superadmin modified',
  192. permissions: [Permission.Authenticated],
  193. },
  194. });
  195. }, `The role '${SUPER_ADMIN_ROLE_CODE}' cannot be modified`),
  196. );
  197. it(
  198. 'updateRole is not allowed for Customer role',
  199. assertThrowsWithMessage(async () => {
  200. const customerRole = defaultRoles.find(r => r.code === CUSTOMER_ROLE_CODE);
  201. if (!customerRole) {
  202. fail(`Could not find Customer role`);
  203. return;
  204. }
  205. return adminClient.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
  206. input: {
  207. id: customerRole.id,
  208. code: 'customer-modified',
  209. description: 'customer modified',
  210. permissions: [Permission.Authenticated, Permission.DeleteAdministrator],
  211. },
  212. });
  213. }, `The role '${CUSTOMER_ROLE_CODE}' cannot be modified`),
  214. );
  215. it(
  216. 'deleteRole is not allowed for Customer role',
  217. assertThrowsWithMessage(async () => {
  218. const customerRole = defaultRoles.find(r => r.code === CUSTOMER_ROLE_CODE);
  219. if (!customerRole) {
  220. fail(`Could not find Customer role`);
  221. return;
  222. }
  223. return adminClient.query<DeleteRole.Mutation, DeleteRole.Variables>(DELETE_ROLE, {
  224. id: customerRole.id,
  225. });
  226. }, `The role '${CUSTOMER_ROLE_CODE}' cannot be deleted`),
  227. );
  228. it(
  229. 'deleteRole is not allowed for SuperAdmin role',
  230. assertThrowsWithMessage(async () => {
  231. const superAdminRole = defaultRoles.find(r => r.code === SUPER_ADMIN_ROLE_CODE);
  232. if (!superAdminRole) {
  233. fail(`Could not find Customer role`);
  234. return;
  235. }
  236. return adminClient.query<DeleteRole.Mutation, DeleteRole.Variables>(DELETE_ROLE, {
  237. id: superAdminRole.id,
  238. });
  239. }, `The role '${SUPER_ADMIN_ROLE_CODE}' cannot be deleted`),
  240. );
  241. it('deleteRole deletes a role', async () => {
  242. const { deleteRole } = await adminClient.query<DeleteRole.Mutation, DeleteRole.Variables>(
  243. DELETE_ROLE,
  244. {
  245. id: createdRole.id,
  246. },
  247. );
  248. expect(deleteRole.result).toBe(DeletionResult.DELETED);
  249. const { role } = await adminClient.query<GetRole.Query, GetRole.Variables>(GET_ROLE, {
  250. id: createdRole.id,
  251. });
  252. expect(role).toBeNull();
  253. });
  254. describe('multi-channel', () => {
  255. let secondChannel: ChannelFragment;
  256. let multiChannelRole: CreateRole.CreateRole;
  257. beforeAll(async () => {
  258. const { createChannel } = await adminClient.query<
  259. CreateChannel.Mutation,
  260. CreateChannel.Variables
  261. >(CREATE_CHANNEL, {
  262. input: {
  263. code: 'second-channel',
  264. token: 'second-channel-token',
  265. defaultLanguageCode: LanguageCode.en,
  266. currencyCode: CurrencyCode.GBP,
  267. pricesIncludeTax: true,
  268. defaultShippingZoneId: 'T_1',
  269. defaultTaxZoneId: 'T_1',
  270. },
  271. });
  272. secondChannel = createChannel;
  273. });
  274. it('createRole with specified channel', async () => {
  275. const result = await adminClient.query<CreateRole.Mutation, CreateRole.Variables>(CREATE_ROLE, {
  276. input: {
  277. code: 'multi-test',
  278. description: 'multi channel test role',
  279. permissions: [Permission.ReadCustomer],
  280. channelIds: [secondChannel.id],
  281. },
  282. });
  283. multiChannelRole = result.createRole;
  284. expect(multiChannelRole).toEqual({
  285. code: 'multi-test',
  286. description: 'multi channel test role',
  287. id: 'T_6',
  288. permissions: [Permission.Authenticated, Permission.ReadCustomer],
  289. channels: [
  290. {
  291. code: 'second-channel',
  292. id: 'T_2',
  293. token: 'second-channel-token',
  294. },
  295. ],
  296. });
  297. });
  298. it('updateRole with specified channel', async () => {
  299. const { updateRole } = await adminClient.query<UpdateRole.Mutation, UpdateRole.Variables>(
  300. UPDATE_ROLE,
  301. {
  302. input: {
  303. id: multiChannelRole.id,
  304. channelIds: ['T_1', 'T_2'],
  305. },
  306. },
  307. );
  308. expect(updateRole.channels.sort(sortById)).toEqual([
  309. {
  310. code: DEFAULT_CHANNEL_CODE,
  311. id: 'T_1',
  312. token: 'e2e-default-channel',
  313. },
  314. {
  315. code: 'second-channel',
  316. id: 'T_2',
  317. token: 'second-channel-token',
  318. },
  319. ]);
  320. });
  321. });
  322. });
  323. export const GET_ROLES = gql`
  324. query GetRoles($options: RoleListOptions) {
  325. roles(options: $options) {
  326. items {
  327. ...Role
  328. }
  329. totalItems
  330. }
  331. }
  332. ${ROLE_FRAGMENT}
  333. `;
  334. export const GET_ROLE = gql`
  335. query GetRole($id: ID!) {
  336. role(id: $id) {
  337. ...Role
  338. }
  339. }
  340. ${ROLE_FRAGMENT}
  341. `;
  342. export const UPDATE_ROLE = gql`
  343. mutation UpdateRole($input: UpdateRoleInput!) {
  344. updateRole(input: $input) {
  345. ...Role
  346. }
  347. }
  348. ${ROLE_FRAGMENT}
  349. `;
  350. export const DELETE_ROLE = gql`
  351. mutation DeleteRole($id: ID!) {
  352. deleteRole(id: $id) {
  353. result
  354. message
  355. }
  356. }
  357. `;