has_groups_examples.rb 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. # Requires: let(:group_access_instance) { ... }
  2. # Requires: let(:new_group_access_instance) { ... }
  3. RSpec.shared_examples 'HasGroups' do
  4. context 'group' do
  5. let(:group_access_instance_inactive) do
  6. group_access_instance.update!(active: false)
  7. group_access_instance
  8. end
  9. let(:group_full) { create(:group) }
  10. let(:group_read) { create(:group) }
  11. let(:group_inactive) { create(:group, active: false) }
  12. context '.group_through_identifier' do
  13. it 'responds to group_through_identifier' do
  14. expect(described_class).to respond_to(:group_through_identifier)
  15. end
  16. it 'returns a Symbol as identifier' do
  17. expect(described_class.group_through_identifier).to be_a(Symbol)
  18. end
  19. it 'instance responds to group_through_identifier method' do
  20. expect(group_access_instance).to respond_to(described_class.group_through_identifier)
  21. end
  22. end
  23. context '.group_through' do
  24. it 'responds to group_through' do
  25. expect(described_class).to respond_to(:group_through)
  26. end
  27. it 'returns the Reflection instance of the has_many :through relation' do
  28. expect(described_class.group_through).to be_a(ActiveRecord::Reflection::HasManyReflection)
  29. end
  30. end
  31. context '#groups' do
  32. it 'responds to groups' do
  33. expect(group_access_instance).to respond_to(:groups)
  34. end
  35. context '#groups.access' do
  36. it 'responds to groups.access' do
  37. expect(group_access_instance.groups).to respond_to(:access)
  38. end
  39. context 'result' do
  40. before(:each) do
  41. group_access_instance.group_names_access_map = {
  42. group_full.name => 'full',
  43. group_read.name => 'read',
  44. group_inactive.name => 'write',
  45. }
  46. end
  47. it 'returns all related Groups' do
  48. expect(group_access_instance.groups.access.size).to eq(3)
  49. end
  50. it 'adds join table attribute(s like) access' do
  51. expect(group_access_instance.groups.access.first).to respond_to(:access)
  52. end
  53. it 'filters for given access parameter' do
  54. expect(group_access_instance.groups.access('read')).to include(group_read)
  55. end
  56. it 'filters for given access list parameter' do
  57. expect(group_access_instance.groups.access('read', 'write')).to include(group_read, group_inactive)
  58. end
  59. it 'always includes full access groups' do
  60. expect(group_access_instance.groups.access('read')).to include(group_full)
  61. end
  62. end
  63. end
  64. end
  65. context '#group_access?' do
  66. it 'responds to group_access?' do
  67. expect(group_access_instance).to respond_to(:group_access?)
  68. end
  69. before(:each) do
  70. group_access_instance.group_names_access_map = {
  71. group_read.name => 'read',
  72. }
  73. end
  74. context 'Group ID parameter' do
  75. include_examples '#group_access? call' do
  76. let(:group_parameter) { group_read.id }
  77. end
  78. end
  79. context 'Group parameter' do
  80. include_examples '#group_access? call' do
  81. let(:group_parameter) { group_read }
  82. end
  83. end
  84. it 'prevents inactive Group' do
  85. group_access_instance.group_names_access_map = {
  86. group_inactive.name => 'read',
  87. }
  88. expect(group_access_instance.group_access?(group_inactive.id, 'read')).to be false
  89. end
  90. it 'prevents inactive instances' do
  91. group_access_instance_inactive.group_names_access_map = {
  92. group_read.name => 'read',
  93. }
  94. expect(group_access_instance_inactive.group_access?(group_read.id, 'read')).to be false
  95. end
  96. end
  97. context '#group_ids_access' do
  98. it 'responds to group_ids_access' do
  99. expect(group_access_instance).to respond_to(:group_ids_access)
  100. end
  101. before(:each) do
  102. group_access_instance.group_names_access_map = {
  103. group_read.name => 'read',
  104. }
  105. end
  106. it 'lists only active Group IDs' do
  107. group_access_instance.group_names_access_map = {
  108. group_read.name => 'read',
  109. group_inactive.name => 'read',
  110. }
  111. result = group_access_instance.group_ids_access('read')
  112. expect(result).not_to include(group_inactive.id)
  113. end
  114. it "doesn't list for inactive instances" do
  115. group_access_instance_inactive.group_names_access_map = {
  116. group_read.name => 'read',
  117. }
  118. expect(group_access_instance_inactive.group_ids_access('read')).to be_empty
  119. end
  120. context 'single access' do
  121. it 'lists access Group IDs' do
  122. result = group_access_instance.group_ids_access('read')
  123. expect(result).to include(group_read.id)
  124. end
  125. it "doesn't list for no access" do
  126. result = group_access_instance.group_ids_access('write')
  127. expect(result).not_to include(group_read.id)
  128. end
  129. end
  130. context 'access list' do
  131. it 'lists access Group IDs' do
  132. result = group_access_instance.group_ids_access(%w(read write))
  133. expect(result).to include(group_read.id)
  134. end
  135. it "doesn't list for no access" do
  136. result = group_access_instance.group_ids_access(%w(write create))
  137. expect(result).not_to include(group_read.id)
  138. end
  139. end
  140. end
  141. context '#groups_access' do
  142. it 'responds to groups_access' do
  143. expect(group_access_instance).to respond_to(:groups_access)
  144. end
  145. it 'wraps #group_ids_access' do
  146. expect(group_access_instance).to receive(:group_ids_access)
  147. group_access_instance.groups_access('read')
  148. end
  149. it 'returns Groups' do
  150. group_access_instance.group_names_access_map = {
  151. group_read.name => 'read',
  152. }
  153. result = group_access_instance.groups_access('read')
  154. expect(result).to include(group_read)
  155. end
  156. end
  157. context '#group_names_access_map=' do
  158. it 'responds to group_names_access_map=' do
  159. expect(group_access_instance).to respond_to(:group_names_access_map=)
  160. end
  161. context 'existing instance' do
  162. it 'stores Hash with String values' do
  163. expect do
  164. group_access_instance.group_names_access_map = {
  165. group_full.name => 'full',
  166. group_read.name => 'read',
  167. }
  168. end.to change {
  169. described_class.group_through.klass.count
  170. }.by(2)
  171. end
  172. it 'stores Hash with Array<String> values' do
  173. expect do
  174. group_access_instance.group_names_access_map = {
  175. group_full.name => 'full',
  176. group_read.name => %w(read write),
  177. }
  178. end.to change {
  179. described_class.group_through.klass.count
  180. }.by(3)
  181. end
  182. end
  183. context 'new instance' do
  184. it "doesn't store directly" do
  185. expect do
  186. new_group_access_instance.group_names_access_map = {
  187. group_full.name => 'full',
  188. group_read.name => 'read',
  189. }
  190. end.not_to change {
  191. described_class.group_through.klass.count
  192. }
  193. end
  194. it 'stores after save' do
  195. expect do
  196. new_group_access_instance.group_names_access_map = {
  197. group_full.name => 'full',
  198. group_read.name => 'read',
  199. }
  200. new_group_access_instance.save
  201. end.to change {
  202. described_class.group_through.klass.count
  203. }.by(2)
  204. end
  205. end
  206. end
  207. context '#group_names_access_map' do
  208. it 'responds to group_names_access_map' do
  209. expect(group_access_instance).to respond_to(:group_names_access_map)
  210. end
  211. it 'returns instance Group name => access relations as Hash' do
  212. expected = {
  213. group_full.name => ['full'],
  214. group_read.name => ['read'],
  215. }
  216. group_access_instance.group_names_access_map = expected
  217. expect(group_access_instance.group_names_access_map).to eq(expected)
  218. end
  219. it "doesn't map for inactive instances" do
  220. group_access_instance_inactive.group_names_access_map = {
  221. group_full.name => ['full'],
  222. group_read.name => ['read'],
  223. }
  224. expect(group_access_instance_inactive.group_names_access_map).to be_empty
  225. end
  226. end
  227. context '#group_ids_access_map=' do
  228. it 'responds to group_ids_access_map=' do
  229. expect(group_access_instance).to respond_to(:group_ids_access_map=)
  230. end
  231. context 'existing instance' do
  232. it 'stores Hash with String values' do
  233. expect do
  234. group_access_instance.group_ids_access_map = {
  235. group_full.id => 'full',
  236. group_read.id => 'read',
  237. }
  238. end.to change {
  239. described_class.group_through.klass.count
  240. }.by(2)
  241. end
  242. it 'stores Hash with String values' do
  243. expect do
  244. group_access_instance.group_ids_access_map = {
  245. group_full.id => 'full',
  246. group_read.id => %w(read write),
  247. }
  248. end.to change {
  249. described_class.group_through.klass.count
  250. }.by(3)
  251. end
  252. end
  253. context 'new instance' do
  254. it "doesn't store directly" do
  255. expect do
  256. new_group_access_instance.group_ids_access_map = {
  257. group_full.id => 'full',
  258. group_read.id => 'read',
  259. }
  260. end.not_to change {
  261. described_class.group_through.klass.count
  262. }
  263. end
  264. it 'stores after save' do
  265. expect do
  266. new_group_access_instance.group_ids_access_map = {
  267. group_full.id => 'full',
  268. group_read.id => 'read',
  269. }
  270. new_group_access_instance.save
  271. end.to change {
  272. described_class.group_through.klass.count
  273. }.by(2)
  274. end
  275. end
  276. end
  277. context '#group_ids_access_map' do
  278. it 'responds to group_ids_access_map' do
  279. expect(group_access_instance).to respond_to(:group_ids_access_map)
  280. end
  281. it 'returns instance Group ID => access relations as Hash' do
  282. expected = {
  283. group_full.id => ['full'],
  284. group_read.id => ['read'],
  285. }
  286. group_access_instance.group_ids_access_map = expected
  287. expect(group_access_instance.group_ids_access_map).to eq(expected)
  288. end
  289. it "doesn't map for inactive instances" do
  290. group_access_instance_inactive.group_ids_access_map = {
  291. group_full.id => ['full'],
  292. group_read.id => ['read'],
  293. }
  294. expect(group_access_instance_inactive.group_ids_access_map).to be_empty
  295. end
  296. end
  297. context '#associations_from_param' do
  298. it 'handles group_ids parameter as group_ids_access_map' do
  299. expected = {
  300. group_full.id => ['full'],
  301. group_read.id => ['read'],
  302. }
  303. group_access_instance.associations_from_param(group_ids: expected)
  304. expect(group_access_instance.group_ids_access_map).to eq(expected)
  305. end
  306. it 'handles groups parameter as group_names_access_map' do
  307. expected = {
  308. group_full.name => ['full'],
  309. group_read.name => ['read'],
  310. }
  311. group_access_instance.associations_from_param(groups: expected)
  312. expect(group_access_instance.group_names_access_map).to eq(expected)
  313. end
  314. end
  315. context '#attributes_with_association_ids' do
  316. it 'includes group_ids as group_ids_access_map' do
  317. expected = {
  318. group_full.id => ['full'],
  319. group_read.id => ['read'],
  320. }
  321. group_access_instance.group_ids_access_map = expected
  322. result = group_access_instance.attributes_with_association_ids
  323. expect(result['group_ids']).to eq(expected)
  324. end
  325. end
  326. context '#attributes_with_association_names' do
  327. it 'includes group_ids as group_ids_access_map' do
  328. expected = {
  329. group_full.id => ['full'],
  330. group_read.id => ['read'],
  331. }
  332. group_access_instance.group_ids_access_map = expected
  333. result = group_access_instance.attributes_with_association_names
  334. expect(result['group_ids']).to eq(expected)
  335. end
  336. it 'includes groups as group_names_access_map' do
  337. expected = {
  338. group_full.name => ['full'],
  339. group_read.name => ['read'],
  340. }
  341. group_access_instance.group_names_access_map = expected
  342. result = group_access_instance.attributes_with_association_names
  343. expect(result['groups']).to eq(expected)
  344. end
  345. end
  346. context '.group_access' do
  347. it 'responds to group_access' do
  348. expect(described_class).to respond_to(:group_access)
  349. end
  350. before(:each) do
  351. group_access_instance.group_names_access_map = {
  352. group_read.name => 'read',
  353. }
  354. end
  355. it 'lists only active instances' do
  356. group_access_instance_inactive.group_names_access_map = {
  357. group_read.name => 'read',
  358. }
  359. result = described_class.group_access(group_read.id, 'read')
  360. expect(result).not_to include(group_access_instance_inactive)
  361. end
  362. context 'Group ID parameter' do
  363. include_examples '.group_access call' do
  364. let(:group_parameter) { group_read.id }
  365. end
  366. end
  367. context 'Group parameter' do
  368. include_examples '.group_access call' do
  369. let(:group_parameter) { group_read }
  370. end
  371. end
  372. end
  373. context '.group_access_ids' do
  374. it 'responds to group_access_ids' do
  375. expect(described_class).to respond_to(:group_access_ids)
  376. end
  377. it 'wraps .group_access' do
  378. expect(described_class).to receive(:group_access).and_call_original
  379. described_class.group_access_ids(group_read, 'read')
  380. end
  381. it 'returns class instances' do
  382. group_access_instance.group_names_access_map = {
  383. group_read.name => 'read',
  384. }
  385. result = described_class.group_access_ids(group_read, 'read')
  386. expect(result).to include(group_access_instance.id)
  387. end
  388. end
  389. it 'destroys relations before instance gets destroyed' do
  390. group_access_instance.group_names_access_map = {
  391. group_full.name => 'full',
  392. group_read.name => 'read',
  393. group_inactive.name => 'write',
  394. }
  395. expect do
  396. group_access_instance.destroy
  397. end.to change {
  398. described_class.group_through.klass.count
  399. }.by(-3)
  400. end
  401. end
  402. end
  403. RSpec.shared_examples '#group_access? call' do
  404. context 'single access' do
  405. it 'checks positive' do
  406. expect(group_access_instance.group_access?(group_parameter, 'read')).to be true
  407. end
  408. it 'checks negative' do
  409. expect(group_access_instance.group_access?(group_parameter, 'write')).to be false
  410. end
  411. end
  412. context 'access list' do
  413. it 'checks positive' do
  414. expect(group_access_instance.group_access?(group_parameter, %w(read write))).to be true
  415. end
  416. it 'checks negative' do
  417. expect(group_access_instance.group_access?(group_parameter, %w(write create))).to be false
  418. end
  419. end
  420. end
  421. RSpec.shared_examples '.group_access call' do
  422. context 'single access' do
  423. it 'lists access IDs' do
  424. expect(described_class.group_access(group_parameter, 'read')).to include(group_access_instance)
  425. end
  426. it 'excludes non access IDs' do
  427. expect(described_class.group_access(group_parameter, 'write')).not_to include(group_access_instance)
  428. end
  429. end
  430. context 'access list' do
  431. it 'lists access IDs' do
  432. expect(described_class.group_access(group_parameter, %w(read write))).to include(group_access_instance)
  433. end
  434. it 'excludes non access IDs' do
  435. expect(described_class.group_access(group_parameter, %w(write create))).not_to include(group_access_instance)
  436. end
  437. end
  438. end