docbrown/lib/tasks/add_navigation_links.rake
Jeremy Friesen e1a88d6f81
Allow for skipping navigation link creation (#16112)
* 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
2022-01-17 17:22:24 -05:00

210 lines
6.4 KiB
Ruby

# rubocop:disable Metrics/BlockLength
namespace :navigation_links do
def image_path(*paths)
File.read(Rails.root.join("app/assets/images/#{paths.join('/')}")).freeze
end
def twemoji_path(name)
image_path("twemoji", name)
end
reading_icon = twemoji_path("drawer.svg")
contact_icon = twemoji_path("contact.svg")
thumb_up_icon = twemoji_path("thumb-up.svg")
smart_icon = twemoji_path("smart.svg")
look_icon = twemoji_path("look.svg")
listing_icon = twemoji_path("listing.svg")
mic_icon = twemoji_path("mic.svg")
camera_icon = twemoji_path("camera.svg")
tag_icon = twemoji_path("tag.svg")
bulb_icon = twemoji_path("bulb.svg")
shopping_icon = twemoji_path("shopping.svg")
heart_icon = twemoji_path("heart.svg")
rainbowdev = image_path("rainbowdev.svg")
def perform_create_of_navigation_links?
# Someone really wants this
return true if ApplicationConfig["CREATE_NAVIGATION_LINKS"]
# This logic echoes the InternalPolicy behavior which is used in the
# Admin::AppliciationController.
return false if User.with_any_role(*Authorizer::RoleBasedQueries::ANY_ADMIN_ROLES).any?
true
end
desc "Create navigation links for new forem"
task create: :environment do
if perform_create_of_navigation_links?
puts "Creating navigation links"
# [@jeremyf] I went ahead and atomized these tasks so we _could_ call them individually if
# desired. I did not add descriptions so those tasks will not show up in the task
# list.
Rake::Task["navigation_links:find_or_create:readinglist"].invoke
Rake::Task["navigation_links:find_or_create:contact"].invoke
Rake::Task["navigation_links:find_or_create:code_of_conduct"].invoke
Rake::Task["navigation_links:find_or_create:privacy"].invoke
Rake::Task["navigation_links:find_or_create:terms"].invoke
else
# Adding just a bit of logging
Rails.logger.info "Skipping creation of navigation links"
end
end
namespace :find_or_create do
task readinglist: :environment do
NavigationLink.where(url: "/readinglist").first_or_create(
name: "Reading List",
url: URL.url("readinglist"),
icon: reading_icon,
display_only_when_signed_in: true,
position: 0,
section: :default,
)
end
task contact: :environment do
NavigationLink.where(url: "/contact").first_or_create(
name: "Contact",
url: URL.url("contact"),
icon: contact_icon,
display_only_when_signed_in: false,
position: 1,
section: :default,
)
end
task code_of_conduct: :environment do
NavigationLink.where(url: "/code-of-conduct").first_or_create(
name: "Code of Conduct",
url: URL.url("code-of-conduct"),
icon: thumb_up_icon,
display_only_when_signed_in: false,
position: 0,
section: :other,
)
end
task privacy: :environment do
NavigationLink.where(url: "/privacy").first_or_create(
name: "Privacy Policy",
url: URL.url("privacy"),
icon: smart_icon,
display_only_when_signed_in: false,
position: 1,
section: :other,
)
end
task terms: :environment do
NavigationLink.where(url: "/terms").first_or_create(
name: "Terms of Use",
url: URL.url("terms"),
icon: look_icon,
display_only_when_signed_in: false,
position: 2,
section: :other,
)
end
end
desc "Update DEV's navigation_links"
task update: :environment do
protocol = ApplicationConfig["APP_PROTOCOL"].freeze
domain = Rails.application&.initialized? ? Settings::General.app_domain : ApplicationConfig["APP_DOMAIN"]
base_url = "#{protocol}#{domain}".freeze
NavigationLink.where(url: "#{base_url}/readinglist").first_or_create(
name: "Reading List",
icon: reading_icon,
display_only_when_signed_in: true,
position: 0,
section: :default,
)
NavigationLink.where(url: "#{base_url}/listings").first_or_create(
name: "Listings",
icon: listing_icon,
display_only_when_signed_in: false,
position: 1,
section: :default,
)
NavigationLink.where(url: "#{base_url}/pod").first_or_create(
name: "Podcasts",
icon: mic_icon,
display_only_when_signed_in: false,
position: 2,
section: :default,
)
NavigationLink.where(url: "#{base_url}/videos").first_or_create(
name: "Videos",
icon: camera_icon,
display_only_when_signed_in: false,
position: 3,
section: :default,
)
NavigationLink.where(url: "#{base_url}/tags").first_or_create(
name: "Tags",
icon: tag_icon,
display_only_when_signed_in: false,
position: 4,
section: :default,
)
NavigationLink.where(url: "#{base_url}/code-of-conduct").first_or_create(
name: "Code of Conduct",
icon: thumb_up_icon,
display_only_when_signed_in: false,
position: 0,
section: :other,
)
NavigationLink.where(url: "#{base_url}/faq").first_or_create(
name: "FAQ",
icon: bulb_icon,
display_only_when_signed_in: false,
position: 5,
section: :default,
)
NavigationLink.where(url: "https://shop.dev.to/").first_or_create(
name: "DEV Shop",
icon: shopping_icon,
display_only_when_signed_in: false,
position: 6,
section: :default,
)
NavigationLink.where(url: "#{base_url}/sponsors").first_or_create(
name: "Sponsors",
icon: heart_icon,
display_only_when_signed_in: false,
position: 7,
section: :default,
)
NavigationLink.where(url: "#{base_url}/about").first_or_create(
name: "About",
icon: rainbowdev,
display_only_when_signed_in: false,
position: 8,
section: :default,
)
NavigationLink.where(url: "#{base_url}/privacy").first_or_create(
name: "Privacy Policy",
icon: smart_icon,
display_only_when_signed_in: false,
position: 1,
section: :other,
)
NavigationLink.where(url: "#{base_url}/terms").first_or_create(
name: "Terms of Use",
icon: look_icon,
display_only_when_signed_in: false,
position: 2,
section: :other,
)
NavigationLink.where(url: "#{base_url}/contact").first_or_create(
name: "Contact",
icon: contact_icon,
display_only_when_signed_in: false,
position: 9,
section: :default,
)
end
end
# rubocop:enable Metrics/BlockLength