Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing for multiple collection curators, studies in multiple collections (SCP-3849, SCP-3867, SCP-3872) #1265

Merged
merged 18 commits into from
Nov 22, 2021

Conversation

bistline
Copy link
Contributor

@bistline bistline commented Nov 16, 2021

Currently, each collection may only have one "curator" (user who controls assigning studies to collections), and a study may only belong to one collection. Also, curators are not allowed to edit the collection themselves, and must go through an SCP admin to make any updates to the collection itself (like the tag line, or visual characteristics).

This update allows for collections to have multiple curators (who can now directly edit the collection), and for studies to belong to multiple collections. This is done by changing the associations from has_many -> belongs_to to has_and_belongs_to_many for the Study, BrandingGroup (collections), and User models. This way, we can access all the studies for a collection directly from the collection itself, and vice versa. This update also includes a new integration test suite to cover all new functionality. In addition, a reversible data migration has been added to migrate from the existing association structure to the new one.

There is also now a visual indication on the Collections page as to whether a collection has been published or not. This only shows if a user is signed in, and is a curator for at least one collection (otherwise, the only collections visible will all be published, and the indicator is not necessary). Example:

Screen Shot 2021-11-18 at 10 30 39 AM

MANUAL TESTING

  1. Pull this branch, and run the migration via rails db:migrate
  2. Enter the Rails console and run SyntheticBrandingGroupPopulator.populate_all
  3. Sign in as an admin, and select "Branding Groups" from the profile menu
  4. For each new synthetic collection, in the "curators" text field, add another non-admin user account:
    Screen Shot 2021-11-16 at 6 11 25 PM
  5. Sign out, and sign in as the non-admin
  6. Go to the "My Studies" page, and for any study click "Edit study"
  7. In the "Add to a collection" menu, select both collections, then click "Save study"
  8. From the "Browse Collections" page, select both new collections and ensure that they contain the study you just added
  9. From the "Browse Collections" page, confirm that the non-admin account can see & click the "Edit" button for the new collections:
    Screen Shot 2021-11-18 at 10 28 48 AM

This PR satisfies SCP-3849, SCP-3867, and SCP-3872.

@codecov
Copy link

codecov bot commented Nov 16, 2021

Codecov Report

Merging #1265 (26efc9e) into development (e89b0bc) will decrease coverage by 0.01%.
The diff coverage is 95.65%.

Impacted file tree graph

@@               Coverage Diff               @@
##           development    #1265      +/-   ##
===============================================
- Coverage        68.99%   68.97%   -0.02%     
===============================================
  Files              241      242       +1     
  Lines            18814    18887      +73     
  Branches           950      950              
===============================================
+ Hits             12980    13027      +47     
- Misses            5665     5691      +26     
  Partials           169      169              
Impacted Files Coverage Δ
app/controllers/api/v1/studies_controller.rb 85.13% <ø> (ø)
app/controllers/studies_controller.rb 21.78% <ø> (ø)
app/lib/synthetic_branding_group_populator.rb 92.15% <66.66%> (-3.68%) ⬇️
app/controllers/api/v1/search_controller.rb 96.41% <100.00%> (ø)
app/controllers/branding_groups_controller.rb 88.33% <100.00%> (ø)
app/helpers/branding_groups_helper.rb 100.00% <100.00%> (+33.33%) ⬆️
app/models/branding_group.rb 100.00% <100.00%> (+7.69%) ⬆️
app/models/study.rb 83.34% <100.00%> (-0.47%) ⬇️
app/models/user.rb 67.85% <100.00%> (+1.19%) ⬆️
app/uploaders/branding_group_image_uploader.rb 58.82% <0.00%> (-35.30%) ⬇️
... and 10 more

Copy link
Contributor

@devonbush devonbush left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good stuff, taking our Collections to a new level of sophistication. I think you can simplify a lot fo this code by operating on the associations (e.g. BrandingGroup.users) rather than the id properties (e.g. BrandingGroup.user_ids). By using the associations, Rails+Mongoid will handle the reciprocal relationship bookkeeping for you.

app/controllers/branding_groups_controller.rb Outdated Show resolved Hide resolved
app/lib/synthetic_branding_group_populator.rb Outdated Show resolved Hide resolved
image_info = branding_group_config.dig('images')
# dynamically assign image files
image_info.each do |attribute_name, filename|
File.open(Rails.root.join('test', 'test_data', 'branding_groups', filename)) do |image_file|
branding_group.send("#{attribute_name}=", image_file)
# copy file to tmp directory to avoid CarrierWave deleting the original
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, thanks!

app/models/branding_group.rb Outdated Show resolved Hide resolved
app/models/branding_group.rb Outdated Show resolved Hide resolved
app/controllers/branding_groups_controller.rb Outdated Show resolved Hide resolved
Comment on lines 73 to 75
if @branding_group.users.include?(current_user)
user_ids << current_user.id unless user_ids.include?(current_user.id)
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consolidate the logic

Suggested change
if @branding_group.users.include?(current_user)
user_ids << current_user.id unless user_ids.include?(current_user.id)
end
if @branding_group.users.include?(current_user) && !user_ids.include?(current_user.id)
user_ids << current_user.id
end


class SearchControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
include Requests::JsonHelpers
include Requests::HttpHelpers
include Minitest::Hooks
include ::TestInstrumentor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, thanks for updating this test

Copy link
Member

@eweitz eweitz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I noted a user-facing letter case inconsistency, a comment typo, and suggested some (perhaps naive) refinements.

app/controllers/branding_groups_controller.rb Outdated Show resolved Hide resolved
app/controllers/branding_groups_controller.rb Outdated Show resolved Hide resolved
app/views/studies/_form.html.erb Outdated Show resolved Hide resolved
app/views/studies/_form.html.erb Outdated Show resolved Hide resolved
@bistline bistline requested a review from devonbush November 18, 2021 15:20
BrandingGroup.all.each do |collection|
associations = collection_map[collection.id.to_s]
collection.update(studies: associations[:studies], users: associations[:users])
end
Copy link
Contributor

@devonbush devonbush Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not worth changing now, but reading your comment, I realize this migration probably would have been cleaner with a migration class like we use for featureFlags

class StudyMigrator
     include Mongoid::Document
     store_in collection: 'studies'
     belongs_to :branding_group, optional: true,
  end 

and

class BrandingGroupMigrator
     include Mongoid::Document
     store_in collection: 'branding_groups'
     belongs_to :user
  end 

Then you could just do:

BrandingGroup.all.each |bg|
  bg.update!(
    users: [BrandingGroupMigrator.find(bg._id).user],
    studies: StudyMigrator.where(branding_group_id: bg._id).to_a
  )
end

@bistline bistline merged commit 55d75cf into development Nov 22, 2021
@bistline bistline deleted the jb-collection-refactor branch November 22, 2021 14:41
@eweitz eweitz mentioned this pull request Nov 23, 2021
@eweitz
Copy link
Member

eweitz commented Nov 23, 2021

I've verified this on staging. See here, here and here. I've also updated the testing instructions above to fill a small gap I stumbled over.

Anyone on the SCP team can independently validate this by signing into the non-admin account [email protected] using instructions here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants