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

6064 – Refactor duplicated media creation methods #2223

Merged
merged 23 commits into from
Feb 27, 2025

Conversation

vasconsaurus
Copy link
Contributor

@vasconsaurus vasconsaurus commented Feb 17, 2025

Description

The Media class and the ProjectMediaCreators concern, in Check API, have some duplicated logic around creating different types of media. The main differences were:

  • the ones in the Media class handle original_claim
  • the ones in ProjectMediaCreators expected a ProjectMedia object,
  • and the ones in the Media class expected the claim/url/file

References: CV2-6064

How to test?

Because Media is such an important class, we should run the whole suite. But while working on this I mainly ran:

# media tests
rails test test/models/media_test.rb

# has tests that call set_media, which call the code we are changing
rails test test/models/bot/smooch_3_test.rb

# have tests related to original claim
rails test test/models/project_media_7_test.rb
rails test test/controllers/graphql_controller_11_test.rb
rails test test/controllers/graphql_controller_12_test.rb

Checklist

  • I have performed a self-review of my code and ensured that it is safe and runnable, that code coverage has not decreased, and that there are no new Code Climate issues. I have also followed Meedan's internal coding guidelines.

@vasconsaurus vasconsaurus changed the title 6064 refactor media creation methods [WIP] 6064 – Refactor duplicated media creation methods Feb 19, 2025
@vasconsaurus
Copy link
Contributor Author

vasconsaurus commented Feb 19, 2025

Some notes on the current state of things

  • I tried to merge the logic but there are slight differences, that I'm not too sure on what the best way to handle is,
    • so there is still some pretty obvious duplication,
    • which I thought was best to leave for now: I think it's easier to see the differences/similarities, so it should be easier for us to discuss possible solutions?
  • the only tests currenlty failing are the two test in rails test test/models/concerns/project_media_creators_test.rb. As they should be, since we no longer have the create_link method inside project_media_creators. Not sure what the best course of action regarding this one is.
  • I don't like how I'm sending the data from ProjectMedia to Media?
    • We need the claim/link/file, for different types of Media we might need different data from ProjectMedia, we need to keep track if it is an original_claim, currently we are not setting the user.. I think there should be a better way to access this?
  • I kept only create_media and removed create_original_claim from ProjectMediaCreators which seems to make more conceptual sense to me, since in the end it is just creating a media.

I think this is the bulk of it, though for sure I'm forgetting something.

Comment on lines 88 to 109
if original_claim
case media_type
when 'UploadedImage', 'UploadedVideo', 'UploadedAudio'
m = find_or_create_uploaded_file_media(original_claim, media_type, true)
when 'Claim'
m = find_or_create_claim_media(original_claim, nil, true)
when 'Link'
m = find_or_create_link_media(original_claim, team, true)
when 'Blank'
m = Blank.create!
end
else
find_or_create_claim_media_from_original_claim(claim)
case media_type
when 'UploadedImage', 'UploadedVideo', 'UploadedAudio'
m = find_or_create_uploaded_file_media(project_media.file, media_type)
when 'Claim'
m = find_or_create_claim_media(project_media.quote, project_media.quote_attributions)
when 'Link'
m = find_or_create_link_media(project_media.url, team)
when 'Blank'
m = Blank.create!
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's try to resolve this duplication by trying to send the media information as an argument. Suggested signature:

find_or_create_media_from_content(type, content, additional_args = [])

I moved the methods to Media so it's easier to compare them side-by-side,
and to make sure this works from Media.

I also made a small change to the create_media method in ProjectAssociation,
so its behavior is closer to create_original_claim. Since those two have differences,
but are both basically creating a Media associated to the ProjectMedia.
Hopefully those two will be turned into one method.
failing tests:
rails test test/models/project_group_test.rb:39
rails test test/models/project_media_5_test.rb:799
rails test test/controllers/graphql_controller_7_test.rb:370
rails test test/controllers/graphql_controller_5_test.rb:200

- we make sure original_claim is not nil before trying to match
- after that was fixed, project_media_5_test.rb:799 was still failing:
     - we werent passing team
     - so it failed to get the pender_key, since that expects a team
     - questions:
          - why was this working before? we expected team before as well
          - do we need to have team?
One big difference between how we create Media is in one case we were
sending the entire project_media, but when creating from original_claim
we weren't.

I think since this is Media it makes more sense only to receive what we
need, instead of the whole project_media. So this is a step in that
direction.

There is still a lot of duplication, and I think there should be better
ways to access the values we want.
The method signature changed, so I updated the tests.
however: should it change? is there a better way to deal with this?
create_media checked if media_type.blank? before running, however,
the graphql request might send original_claim and media_type set to Blank.
Which means in the case of original_claim present we do want to check and
re-set media_type if needed.
The issue here, I think, is create_project_media creates a bunch of stuff
by default. So it was creating an extra Link Media, which caused some
confusion on when debugging a different issue.

So maybe it's a good idea to be more conservative in using sample_data's
methods?
They are now both doing the same thing. And I think conceptually they
both create media, even if it is a media from an original claim.
To make clear this method mutates the original object.
Depending on the type of Media we try to create, it needs different data
from the ProjectMedia object. Still, Media shouldn't need to know too much
about ProjectMedia.

So, we are deciding on what to send in ProjectMediaCreators, and only
sending what is necessary:
- I created a method that gets those media_arguments
- Moved that and set_media_type under protected
- Inside media it only gets that data and forwards it
     - There were a few changes to method's signatures (so tests were
     also updated)
     - Because there are a few differences between arguments needed, we
     are sending those as an additional_args hash
create_link is no longer in ProjectMediaCreators, only in Media.
I think these two tests are already covered in media_test.rb
@vasconsaurus vasconsaurus force-pushed the 6064-refactor-media-creation-methods branch from bd631f1 to 09625ae Compare February 24, 2025 13:29
Copy link

codeclimate bot commented Feb 24, 2025

Code Climate has analyzed commit 09625ae and detected 0 issues on this pull request.

The test coverage on the diff in this pull request is 100.0% (100% is the threshold).

This pull request will bring the total coverage in the repository to 100.0% (0.0% change).

View more on Code Climate.

@vasconsaurus vasconsaurus changed the title [WIP] 6064 – Refactor duplicated media creation methods 6064 – Refactor duplicated media creation methods Feb 25, 2025
@vasconsaurus vasconsaurus marked this pull request as ready for review February 25, 2025 14:03
@vasconsaurus vasconsaurus requested a review from caiosba February 25, 2025 17:51
@caiosba
Copy link
Contributor

caiosba commented Feb 26, 2025

@melsawy @jayjay-w please review this as well.

Copy link
Contributor

@caiosba caiosba left a comment

Choose a reason for hiding this comment

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

Thanks Manu for addressing the things we discussed before! I left a couple of comments, but they are not blockers.

Comment on lines 137 to 138
# we set it to UploadedImage by default, should we?
# def self.create_with_file(project_media, media_type = 'UploadedImage')
Copy link
Contributor

Choose a reason for hiding this comment

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

We can remove these comments now, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes! But should we set media_type = 'UploadedImage' by default?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, I don't think it makes sense to have any default.

@@ -870,7 +870,7 @@ def teardown
WebMock.stub_request(:get, pender_url).with({ query: { url: url } }).to_return(body: response_body)

t = create_team
pm = create_project_media team: t, set_original_claim: url
pm = ProjectMedia.create(team: t, set_original_claim: url)
cd = create_claim_description project_media: pm
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest you replace ProjectMedia.create by ProjectMedia.create! - just to make it more verbose if it fails.

m = self.create_media
self.media_id = m.id unless m.nil?
self.create_media!
self.media_id unless self.media_id.nil?
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: this line should return self.media_id or assign a value to self.media_id

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The create_media method changes the object and assigns the value, if I'm not mistaken. So I think we should be able to just return self.media_id.

@vasconsaurus vasconsaurus merged commit 2bf3532 into develop Feb 27, 2025
13 of 14 checks passed
@vasconsaurus vasconsaurus deleted the 6064-refactor-media-creation-methods branch February 27, 2025 15:20
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