* feat: remove initializeSponsorshipVisibility and related code
* feat: remove sponsorships from sidebar
* feat: remove sponsorships from the admin - route, controller, view, spec
* feat: remove the admin menu item
* feat: remove the i8n for admin sponsors controller
* feat: sponsorship decorator was not being used anywhere
* feat: sponsorship slack messenger was not being used anywhere
* feat: remove the sponsorship_headline that gets configures on the admin
* feat: remove the /sponsors page
* feat: remove renedring of single_sponsor partial and associated partials
* feat: remove the navigation link rake task for sponsors
* feat: remove sponsorship from tags
* feat: remove i8n constants used
* remove sponsor references in text to the privacy page
* feat: remove the sponsorship detail from the organization page
* feat: remove the sponsors css that was used for app/views/pages/sponsors.html.erb
* feat: remove the sponsorship i8n that was used in the slack messengers
* feat: swap out the decorators to use Article as an example
* feat: remove spec to show sponsors on home page
* feat: update the specs to use Article Decorator instead of the Sponsorship Decorator
* fix: use direct and not all
* fix: remove tests for tag sponsorship
* fix: remove organization sponsorship test
* feat: remove more i8n
* feat: create a migration to add the display ad name column to the tanle
* feat: add a display ad name to the interface
* feat: add a display ad name after create
* feat: whoops the migration file
* feat: add a DUS to update previous Display Ads names
* fix: test
* refactor: update the name after_save
* fix: add name to params
* Adds a DUS to backfill community_emoji for Forems that have one
* Adds a DUS spec to test backfilling community names
* update the script adn the tests to allow us to change the community name
* feat: add a stub for the community name
* feat: generate a later timestamp so that it doesnt cause confusion
* chcek if the emoji already appears in the community name
* feat: remove community emoji from displaying on the UI
* refactor:remove the else if completely
Co-authored-by: Ridhwana <ridhwana.khan16@gmail.com>
* Try renaming moderator -> super_moderator
* Still finding 'moderator' words
* Fixes for failing specs
* Update test with new role name
* Update app/services/moderator/manage_activity_and_roles.rb
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* add new column with enum value
* refactor to use display_to column
* add some more specs to application_helper
* test for the backfill DUS
* fix line length
* refactor
* Article query spec for scheduled articles
* Added scheduled article badge on the user dashboard
* Added published_at field to editor options
* Accept and validate published_at from editor
* Refactor published_at validation
* Allow 1-minute difference in published_at
* Notice on an unpublished article page
* Added specs for 'Click to edit' link on scheduled article preview page
* ContextNotification model
* Articles::Publish worker
* Added specs for articles publish worker
* Schedule publish articles worker
* Added tests to check for scheduled posts in feeds
* Don't allow managing scheduled articles
* Don't send notifications for scheduled articles
* Set published_at in Articles::Updater when publishing
* Published_at value in post options
* Pass timezone and set published_at accordingly
* Limit setting published_at to the future
* Readonly published_at for articles that were already published
* Chagning published_at format in editor v1 (start)
* Changed published_at format in frontmatter, specs
* Added specs for updating published_at from frontmatter
* Fixed accepting past published_at for articles published_from_feed
* Enabled published_at validation: don't allow updating published_at for already published articles
* Validate published_at on create
* Added a spec for updating published_at for exported articles
* Fixed specs related to creating articles with past published_at
* Fixed specs related to past published_at for articles
* Added a hack so that admins would be able to update published_at
* Switch button text schedule/publish when changin publishedAt
* Fixed saving published_at with timezone
* Added a feature flag for scheduling articles
* Default text in markdown editor depends on feature flag
* Enable article editor cache again
* Fixed the default value in the markdown editor
* Fix sitemaps spec
* Removed tooltip
* Fixed articles update specs
* Added missing locales
* Fixed article create specs
* Fixed spec
* Removed commented code
* Returned enabling extensions in the schema
* Returned accidentally deleted constraint
* Make articles query spec more stable
Co-authored-by: Jeremy Friesen <jeremy.n.friesen@gmail.com>
* Removed commented code
* Removed unused code
* A clearer policy
Co-authored-by: Jeremy Friesen <jeremy.n.friesen@gmail.com>
* Use StringInquirer for article current state
* Added a note and todo to articles factory past trait
* Remove duplicated PropType
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Refactor query in the Articles::PublishWorker
Co-authored-by: Mac Siri <krairit.siri@gmail.com>
* Refactor articleForm.jsx
Co-authored-by: Mac Siri <krairit.siri@gmail.com>
* Removed specs that are no longer relevant
* Removed useless onKeyUp on a hidden input
* Refactored articleForm
* Hide scheduling from post options when published_at is readonly
* Run sends notifications worker every 5 minutes instead of every minute
Co-authored-by: Jeremy Friesen <jeremy.n.friesen@gmail.com>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Mac Siri <krairit.siri@gmail.com>
* Remove sustaining member newsletter, and its settings
This removes the concept of sustaining memberships from the system,
and logic related to or dependent on it.
This does not remove the monthly_dues column from the users table (todo).
* Remove unused newsletter setting
Since nothing accesses the mailchimp_sustaining_members_id setting,
it's safe to remove.
* Use destroy rather than delete to ensure settings cache is cleared
We have a callback in Settings::Base to clear the cache after commit,
I assume it's useful to trigger that. This requires destroy, not
delete, to be called.
* transliterate when generating attribute names to avoid emptiness
If you enter a non-ascii (non `\w` matching) string as the profile
field label, the attribute name is the empty string.
This causes problems outlined in #16391
To avoid losing user provided data, transliterate (Sterile is the same
tool we're using for Article#title_to_slug) before matching against
the word regex.
If we persist an empty string, or persist a non-`\w` name, the
coordinating regex in Profile::ATTRIBUTE_NAME_REGEX will leave a nil
match and raise NoMethodError (the method missing is for
match[:attribute_name] when match was nil, not Profile - that's the
next commit.
* Guard against nil matches
If an attribute name doesn't match the regex, the match is nil, and
trying to access (nil)[:attribute_name] raises a NoMethodError.
If there was no match, assume profile does not respond to the
selector, and don't handle it in method missing.
* Ensure generated attribute name is valid before saving
This raises a validation error if the generated name (from the label)
would be empty.
It's not an optimal error message (since the user can't see the
internal attribute name) but it prevents persisting broken/empty data
* actually raise error when validating
validate/valid? only return true or false (and set errors on the
object). In order to reject the creation, we need to raise a
validation error, not only call validate. I think this is because the
execution of before_create hooks happens after validation (which is
why the validation was only checked on update, not create).
* Generate an attribute name completely independent of the field label
This prevents mistakenly labeling a field "Class" or "Association" or
one of the other hundred public methods an AR model like Profile
exposes. Since attribute_name will be passed to `profile.public_send`
we really shouldn't build selectors from user supplied inputs.
* Use the admin supplied label in the sidebar
The profile decorator is used in the Users#show page to populate the
sidebar fields. Don't use the attribute name (which we mangled during
creation, and now generate randomly) as the label, use the label.
* Make the label lookup null safe, and filter attributes more
* Update data update script to not expect predictable labels
This is low impact since it ran in july, but we no longer know what
attribute name a label will create.
* Fix moderator spec
"Test Field" label no longer predictably generates :test_field as an
attribute name. Ask the field what it's name is before asking profile
about it.
* Fix profile preview card request spec
Remove the assumption that profile responds to a method name based on
the label for Work and Education fields.
* Update old DUS and its test
This can probably be archived
* Update profile spec to use fields generated attribute names
We used to "know" how attributes were generated from labels. Now we don't.
* update e2e seeds for profile field change
* Don't expect attribute name to be based on the label
* expect created profile fields respond to their attribute name
* Update system test
The label, not the attribute name, is shown on the profile form (the
field has an id related to the attribute name, but the view shows the
mutable/human-readable label).
* Keep the field title lowercase when sending the json preview card
The userMetadata component expects "work" and "education" to be
attributes of the metadata, but the ui_attributes_for() method was
titlizing these (for display).
Ideally we wouldn't have "special purposed" these two field names, but
they're there.
* update profile field by attribute name, not based on label
* Update profile field removal assumptions
We don't know what the method selectors will be, we have to ask.
* remove old test
* Update translations for Education and Work
Since the ui_attributes_for(area:) now gives the label, not the
attribute, we need to match the label of the profile field.
Note to self: this exposes an issue in localizing the custom profile
fields (probably a bigger problem for large, international communities
like DEV than some others, but trying to match static translation
files against user-modifiable database records seems like a problem
we'll see again).
* Empty commit to retrigger buildkite
* Remove profile field migration update scripts
Cloned the specs from the other "remove unused scripts" script.
* Remove unused scripts
The data update script removes the entry from the table (recording
that these have run) - we also want to remove the files (preventing
them from running again).
* remove unneeded spec for removed file
* when translation for header area field not found, use the title
Only Work and Education already have keys in the yml translation file,
and there's not a great (or easy?) way to make multiple translations
on these fields right now.
Since an admin can create a new field, and assign it to the header
area, we can't assume the code has a configured translation key for
this field.
Fallback to the title (we do this in another context already) if
there's no translation.
* PR feedback: Avoid n+1 query for labels
the original implementation of "label_for_attribute" had an n+1 query
looping over each matched key.
Follow suggested improvement and pull labels and attributes at once
from the db and modify the returned hash.
* Downcase title before looking for translation key
This avoids putting "odd" capitalized keys into the yml translation
file
Revert addition of "Work" and "Education" to the users files.
* use a let binding for duplicated test data
* Update app/models/profile_field.rb
prefer SecureRandom.hex for a dashless uuid (instead of removing the dashes).
Co-authored-by: Jamie Gaskins <jgaskins@hey.com>
Co-authored-by: Jamie Gaskins <jgaskins@hey.com>
There's an existing data update to introduce the connect feature flag,
and it's been disabled. However, since all the code relying on this is
now gone, it makes sense to remove the flag.
* Removes admin_member_view feature flags and refactors conditionals
* Removes unused admin/users/_email_tools partial and user_email_tools_spec
* Actually remove the admin/user_email_tools_spec this time
* Removes the edit route from admin.rb users
* Adds a DUS (and spec) to disable and remove admin_member_view flag
* Fixes admin/users_spec.rb failures by updating spec with Member Detail changes
* Fixes spec failures within admin_bans_or_warns_user_spec.rb
* Refactors Admin::UsersController#credit_params due to failing specs
* Removes last traces of edit_admin_user_path and fixes buttons, specs, etc.
* Update identities where the auth data dump is a plain hash
All but 3 records in DEV have OmniAuth::AuthHash objects serialized as
auth data dump. Normalize the remaining ones so they don't cause no
method errors when we treat the auth_data_dump as an object (sending
`#info` instead of asking for `['info']`).
should address https://app.honeybadger.io/projects/66984/faults/84183659
Add null safety check in a second example (that null values should not
cause an error, and should not be coerced to auth hashes).
* Ignore rubocop suggestion to create list
Because the factory for identities doesn't automatically create the
required user object, this is impractical.
While I'm here, move the identity hash update into the creation block
rather than doing this in two passes.
Co-authored-by: Jamie Gaskins <jgaskins@hey.com>
* Removes logo_svg-related code
* Removes logo_svg-related specs
* Removes the logo_uploader and logo_uploader DUS spec
* Removes the logo_uploader_spec.rb
* Adds a DUS to remove the logo_svg var from the DB
* Reverts the removal of the logo_svg_uploader.rb
* Short-circuiting parsing any articles to update
Setting a field that is to help track from where we received an image.
Related to #16075 and #16407.
See [Slack Thread][1] for all the details
[1]:https://forem-team.slack.com/archives/CSY5KKK9U/p1643916711077719
* Fix
* Apply suggestions from code review
Co-authored-by: Jamie Gaskins <jgaskins@hey.com>
Co-authored-by: Jamie Gaskins <jgaskins@hey.com>
* Bypassing validiation for data script
Prior to this commit, we attempted to run a script against all articles
using validation. In the case of DEV, we have lots of articles that
would no longer validate. This change now updates the column value
without running validation.
Relates to #16075
* Bump for travis
* Add boolean attribute main_image_from_frontmatter to indicate if cover image was set via frontmatter
* use article model spec for main_image_from_frontmatter test cases
* Add data migration script and spec for main_image_from_frontmatter for articles
* Update app/models/article.rb
Co-authored-by: Jeremy Friesen <jeremy.n.friesen@gmail.com>
Co-authored-by: Jeremy Friesen <jeremy.n.friesen@gmail.com>
Co-authored-by: Michael Kohl <me@citizen428.net>
* move home link to a customisable navlink
* add trailing slash for path
* update specs
* replace positions, set home link to -1
* add update script for adding home navigation link
* update data update script
Prior to this commit, we were treating all NavigationLink attributes as
unique. So, were we to change a position of one of the NavigationLinks
during the add_navigation_links rake task, we would have created a new
NavigationLink (and the only one would have remained).
With this commit, we're introducing the concept of the NavigationLink's
surrogate identity, that is to say if we have two NavigationLink objects
with the same `url` and `name` we should consider them the same
NavigationLink. This allows us to update properties of those
NavigationLinks (via the rake task) without the risk of creating new
entries.
This unblocks PR #16268 which addresses #16076.
On the DEV.to database, I ran the following SQL:
```sql
SELECT name, short_summary FROM tags WHERE short_summary LIKE '%<%';
```
There were three tags with a `<` in them:
- changelog
- cnc2018
- javascript
This PR will tidy up our short summary as part of saving a tag. It will
also tidy up the existing tags.
* Let override of ToS and CoC show in onboarding
Prior to this commit any changes to the terms or code of conduct were
not reflected in the onboarding links.
With this commit, I'm leveraging a newly created method that first
checks if there's a page for the given slug. If there is, use that
page's copy.
To test:
- Overwrite default /terms page on a Forem
- Navigate to /onboarding or sign up as a new user
- Click on Terms of Use link text
- Review Terms of Use
Closes#15296
* Adding spec around not passing a block
* Allow for skipping navigation link creation
This commit provides a possible solution for preventing the re-creation
of a navigation link deleted by a Forem creator.
What I need is a discussion around the life-cycle of the application
installation and updates.
In particular, does this provide a robust enough mechanism for resolving
the issue at hand?
_Note: it pains me to ask about a user's role, but this is provided as a
point of discussion and possible implementationi to address the
underlying issue. But I'm referencing a constant in the Rake task so
hopefully that will help future refactors. Also, it's one reason I
needed to remove the `private_constant` declaration._
If we accept this code change, a future task is to document the ENV and
behavior.
Closes#15960
**Further considerations**:
- How might we refine this to not be as "role" reliant?
- Could we have a Site::Setting that we enable/disable
regarding the navigation links?
Regarding QA:
- Start from an empty database
- Run setup
- Verify Navigation Link exists
- Delete Navigation Link
- Run setup again
- Verify Navigation Link exists (because we don't have a user)
- Run seeds
- Delete Navigation Link
- Run setup again
- Verify Navigation Link exists (because we don't have a user)
```shell
$ cd ./path/to/forem/repo
$ rails db:drop db:create db:schema:load
$ bin/setup
$ bin/rails runner "puts NavigationLink.where(url: '/readinglist').exists?"
=> true
$ bin/rails runner "NavigationLink.where(url: '/readinglist').delete_all"
$ bin/rails runner "puts NavigationLink.where(url: '/readinglist').exists?"
=> false
$ bin/setup
$ bin/rails runner "puts NavigationLink.where(url: '/readinglist').exists?"
=> true
$ bin/rails db:seed
$ bin/rails runner "NavigationLink.where(url: '/readinglist').delete_all"
$ bin/rails runner "puts NavigationLink.where(url: '/readinglist').exists?"
=> false
$ bin/setup
$ bin/rails runner "puts NavigationLink.where(url: '/readinglist').exists?"c
=> false
```
* Bump for travis
* Generator output
Add your logic here!
* replicate the logic from the forem connect migration
* Add data update script
This will generate the expected broadcast message to fix#16059
* Add apple connect to seeds file
* feat/WIP: first version of the svg logo to png logo DUS
* feat: logoSVG Uploader
* refactor: remove the if original_filename
* feat: add a test for the logo_svg_uploader
* feat: update the test and dus
* add soem error handling
* updae the rails spec helper
* feat: provide a content type
* feat: add content type
* Try https://travis-ci.community/t/build-times-out-with-no-apparent-reason/5083/4
* chore: try this suggestion https://stackoverflow.com/questions/41138404/how-to-install-newer-imagemagick-with-webp-support-in-travis-ci-container
* chore: remove libweb adn fix = in the travis.yml
* chore: undo the changes to attempt to update the version for image magick
* feat: install gsfonts for convert
* chore: add a comment for svg
* feat: use the good practices for tempfile, update error handling and update the tests
* chore: update the timestamp on the DUS
* feat: convert to png with a transparent background using Image Magick
* feat: substitute some css variables with real css colors
* chore: revert the path
* fix: set content type
* Update lib/data_update_scripts/20220105112823_migrate_logo_svg_data.rb
Co-authored-by: Jamie Gaskins <jamie@forem.com>
Co-authored-by: Jamie Gaskins <jamie@forem.com>
* Tidying up and documenting Tag model
Prior to this commit we had a custom `where(alias_for: [nil, ""])`
call. That call highlighted that we lacked a term for a Tag that was
not an alias. As part of this commit, I named that a "concrete" tag.
Further, I added scopes to assist in helping "name" those concepts.
This commit also adds a data migration and utilization of
StringAttributeCleaner to hopefully get away from `alias_for == ""`
situations.
As of writing this commit <2022-01-04 Tue 17:22 UTC>, in DEV.to we had 5
tags with `alias_for == ""`:
- actionshackathon21
- regex
- atlashackathon
- hotwire
- foremfest
In https://dev.to/admin/blazer I ran the following:
```sql
SELECT name FROM tags WHERE alias_for = ''
```
* Renaming concrete to direct
* Remove reactions to a user when deleting the user
Fixes#15245
---
I have no idea why `create(:vomit_reaction, reactable: user)` gave a
validation error about category being invalid, but `build().save`
worked fine.
* Move relation details to reaction scope `for_user`
Add a user method to access this by passing self to reaction scope
* Create a moderator when flagging user in factory
This might be a missing requirement in the reactions factory - but
this suppresses an error about invalid category I was getting when
setting a privileged reaction on the user via
create(:vomit_reaction, reactable: user)
Everywhere else it looks like we do this with `user: moderator` (where
there's a trusted user in the surrounding context).
* Move trusted user requirement into vomit_reaction factory
* Add a data update script to remove reactions to deleted users
This cleans up the remaining invalid references and should make the
change in #15249 obsolete (i.e. we don't need to limit the view to
exclude items that no longer exist).
The data update script "nullify empty tag colors" failed to update
because of the way it was written - in two passes, updating the
background color for tags where the background color was empty, then
updating the foreground color for tags where the foreground color was
empty.
Because both attributes have a validation regex, neither pass updated
any tags (the problematic cases observed had empty string values in both
columns).
Perform in a single loop, over the union of the two sets (expected to
include only the same rows as before), an update for both columns at
once.
Additionally, use update_columns which bypasses _other_ validation
issues (the only one I could suspect is the alias_for check).
Nullify empty strings in alias_for (simplifies a few things, now it's
either valid or null).
When a tag is detected with a "danlging alias" repair it by setting
alias for nil.
* Removing the stackbit integration
The feature didn't quite work and Stackbit no longer supports this
integration.
Yes there are a few places where the webhooks has a string of "stackbit"
but I'm hesitant to remove that, as they are the part of the Webhooks
tests.
Closes#15700
* Update lib/data_update_scripts/20211206222716_remove_stackbit_page.rb
Co-authored-by: Michael Kohl <citizen428@forem.com>
Co-authored-by: Michael Kohl <citizen428@forem.com>
* AB Test for Feed Strategy
Adding the plumbing for performing AB Tests on the feed strategy.
You can add the environment variable `AB_TEST_SERVICE_FEED_STRATEGY` to
specify the field test to run.
For example, from the forem application home directory you can run the
following to force a strategy for all users:
```console
AB_TEST_SERVICE_FEED_STRATEGY=original bin/start
```
Forcing the strategy can significantly help with quality assurance testing.
* Adding configurable weighted feed strategy
I wrote about this exploration on [DEV.to][1]. This particular
implementation provides significant configuration options for A/B
testing.
At it's core this `Articles::Feeds::WeightedQueryStrategy` provides a
means to query articles that are relevant to the user. The
configuration helps us test and refine those values.
Further more this implementation introduces the idea of some common
interfaces for feed strategies. I'm not happy with the naming
convention but we can work to change that.
This even hints at a mechanism for administrators to configure.
Related to forem/rfcs#314, as I work towards understanding the feed
algorithm. And #15180
[1]:https://dev.to/jeremyf/practicing-postgresql-and-postulating-improvements-5m
* Renaming AbTestService to AbExperiment
I'm loath to end any production class's filename with "test". I don't
want minitest or rspec coming along and attempting to "test" that file.
In addition, I find that Experiment better describes the concept.
Also, per conversations with Michael K, we favor nouns objects to go
in app/models and verb objects to go in app/services. That's a great
separation.
* Factoring AbExperiment into a Controller concern
I wish this could be a stand-alone module but the implementation of
field test has cases that require controller context.
* Sanitizing configurable weighted strategy cases
* Minor refactoring of coding structure
* Renaming parameter for clarity
* Renaming variable to avoid confusion
Prior to the commit, `env` is a controller variable. The injected `env`
variable didn't collide, but did create just a bit of confusion.
With this change, I'm trying to disentangle from that variable.
* Factoring AbExperiment away from mixin concern
Per discussion with Michael K, we both agree that we do not like
controller concern mixins. They can quickly complicate the legibility
of any given codebase.
This refactor provides a common and simplified interface for a Plain Old
Ruby Object (PORO) that accounts for the implementation considerations
of the underlying "field_test" controller method.
* Adding Datadog.tracer.trace around feed actions
* Adding featured_article_factor
Prior to this commit, there was no consideration for how moderators
engage with an article. This is a first nudge towards that effort.
* Removing spec
Add a spec that says yes or no we're feature testing something seems
fragile. Namely, why are we wanting to assert that as a truism.
* Helping ensure we're "tracing" the same things
From the code comment:
> Hey, why the to_a you say? Because the
> LargeForemExperimental has already done this. But the
> weighted strategy has not. I also don't want to alter the
> weighted query implementation as it returns a lovely
> ActiveRecord::Relation. So this is a concession.
* Addressing parameters for tracing function
* For weight feed query only count positive tags
A user assigns explicit points to the tags that they do or do not want
to see. This change treats the negative explicit_points as an indicator
that they don't want to see the tag.
* Adding weighted factor for privileged user reactions
* Updating comments to better clarify
* Adding additional constraint for published_at
* Updating documentation and adding logger
* Adding documentation concerning method call
* Upping logging level for experiments
See conversations in https://github.com/forem/forem/pull/15240
* Adding group by clauses to appease postgres configs
* Injecting relevant scoring method's joins
Prior to this commit, we included all of the joins regardless of the
scoring methods chosen. With this commit, we only inject joins that are
used with the commit.
What this would allow us to do is to then have some pre-cooked scoring
methods but not turn them on. Or to turn off the more expensive scoring
methods.
* Adding feature flag for feed strategy experiment
* Enable Forem (Passport) Auth
* Remove feature flag DUS
* Add prompt for Forem Passport in admin
* Add spec & fix broken one
* Link to docs instead of passport site