From fd1c05c8159eb51e194fded4bc3122f41b3fd7bb Mon Sep 17 00:00:00 2001 From: Ram Date: Mon, 26 Aug 2024 10:37:23 -0600 Subject: [PATCH 01/14] Remove wagtail utility routes for authentication (#12655) * Remove wagtail utility routes for authentication * Remove unused imports after `_util` route removal --------- Co-authored-by: Rob DiVincenzo --- .../networkapi/utility/watail_core_url_override.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/network-api/networkapi/utility/watail_core_url_override.py b/network-api/networkapi/utility/watail_core_url_override.py index cf7da20c211..bb983ed434c 100644 --- a/network-api/networkapi/utility/watail_core_url_override.py +++ b/network-api/networkapi/utility/watail_core_url_override.py @@ -2,8 +2,7 @@ # TO ALLOW NON-SLUG URLS FROM MAKING IT INTO THE serve() FUNCTION from django.conf import settings -from django.contrib.auth import views as auth_views -from django.urls import path, re_path +from django.urls import re_path from wagtail import views from wagtail.coreutils import WAGTAIL_APPEND_SLASH @@ -29,16 +28,6 @@ urlpatterns = [ - path( - "_util/authenticate_with_password///", - views.authenticate_with_password, - name="wagtailcore_authenticate_with_password", - ), - path( - "_util/login/", - auth_views.LoginView.as_view(template_name=WAGTAIL_FRONTEND_LOGIN_TEMPLATE), - name="wagtailcore_login", - ), # Front-end page views are handled through Wagtail's core.views.serve # mechanism re_path(serve_pattern, views.serve, name="wagtail_serve"), From 825733cedf232b11e9ccef548582eb258cfb78c1 Mon Sep 17 00:00:00 2001 From: Ram Date: Mon, 26 Aug 2024 16:05:09 -0600 Subject: [PATCH 02/14] Revert "Remove wagtail utility routes for authentication (#12655)" (#12740) This reverts commit fd1c05c8159eb51e194fded4bc3122f41b3fd7bb. --- .../networkapi/utility/watail_core_url_override.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/network-api/networkapi/utility/watail_core_url_override.py b/network-api/networkapi/utility/watail_core_url_override.py index bb983ed434c..cf7da20c211 100644 --- a/network-api/networkapi/utility/watail_core_url_override.py +++ b/network-api/networkapi/utility/watail_core_url_override.py @@ -2,7 +2,8 @@ # TO ALLOW NON-SLUG URLS FROM MAKING IT INTO THE serve() FUNCTION from django.conf import settings -from django.urls import re_path +from django.contrib.auth import views as auth_views +from django.urls import path, re_path from wagtail import views from wagtail.coreutils import WAGTAIL_APPEND_SLASH @@ -28,6 +29,16 @@ urlpatterns = [ + path( + "_util/authenticate_with_password///", + views.authenticate_with_password, + name="wagtailcore_authenticate_with_password", + ), + path( + "_util/login/", + auth_views.LoginView.as_view(template_name=WAGTAIL_FRONTEND_LOGIN_TEMPLATE), + name="wagtailcore_login", + ), # Front-end page views are handled through Wagtail's core.views.serve # mechanism re_path(serve_pattern, views.serve, name="wagtail_serve"), From 0a26e65d6df8e09166dd8d0226acaf65d5972351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20L=C3=B3pez?= <81331806+dlopezvsr@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:49:05 -0600 Subject: [PATCH 03/14] NETWORK_SITE_URL env var removal from files (#12727) * NETWORK_SITE_URL env var removal from files * NETWORK_SITE_URL back for integration tests * Testing if env vars in settings * Tests on bg-main and main js files * Replace network_site variable for heroku_app * Get current domain --- .github/workflows/continous-integration.yml | 5 +---- .github/workflows/visual-regression-testing.yml | 1 - env.default | 3 +-- network-api/networkapi/settings.py | 5 ----- source/js/buyers-guide/bg-main.js | 2 +- source/js/main.js | 2 +- 6 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/continous-integration.yml b/.github/workflows/continous-integration.yml index f544c5608a0..f60956ce08f 100644 --- a/.github/workflows/continous-integration.yml +++ b/.github/workflows/continous-integration.yml @@ -16,7 +16,6 @@ jobs: env: ALLOWED_HOSTS: localhost,mozfest.localhost,default-site.com,secondary-site.com GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NETWORK_SITE_URL: https://foundation.mozilla.org PULSE_API_DOMAIN: https://network-pulse-api-production.herokuapp.com PULSE_DOMAIN: https://www.mozillapulse.org steps: @@ -54,7 +53,6 @@ jobs: DJANGO_SECRET_KEY: secret DOMAIN_REDIRECT_MIDDLEWARE_ENABLED: False GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NETWORK_SITE_URL: http://localhost:8000 PIPENV_VERBOSITY: -1 PULSE_API_DOMAIN: https://network-pulse-api-production.herokuapp.com PULSE_DOMAIN: https://www.mozillapulse.org @@ -132,7 +130,6 @@ jobs: DJANGO_SECRET_KEY: secret DOMAIN_REDIRECT_MIDDLEWARE_ENABLED: False GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NETWORK_SITE_URL: http://localhost:8000 PIPENV_VERBOSITY: -1 PULSE_API_DOMAIN: https://network-pulse-api-production.herokuapp.com PULSE_DOMAIN: https://www.mozillapulse.org @@ -146,7 +143,7 @@ jobs: CSP_CONNECT_SRC: "*" CSP_FONT_SRC: "'self' https://code.cdn.mozilla.net https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/fonts/ data: https://static.fundraiseup.com/common-fonts/" CSP_IMG_SRC: "* data: blob: https://*.fundraiseup.com https://ucarecdn.com https://pay.google.com https://*.paypalobjects.com" - CSP_FRAME_SRC: "'self' https://www.google.com/recaptcha/ https://*.stripe.com https://pay.google.com https://*.paypal.com https://*.fundraiseup.com" + CSP_FRAME_SRC: "'self' https://www.google.com/recaptcha/ https://*.stripe.com https://pay.google.com https://*.paypal.com https://*.fundraiseup.com" CSP_SCRIPT_SRC: "'self' 'unsafe-inline' https://www.google-analytics.com/analytics.js http://*.shpg.org/ https://comments.mozillafoundation.org/ https://airtable.com https://platform.twitter.com https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/ScrollTrigger.min.js https://*.googletagmanager.com https://*.fundraiseup.com https://mozillafoundation.tfaforms.net https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ 'unsafe-eval' https://*.stripe.com https://m.stripe.network https://*.paypal.com https://*.paypalobjects.com https://pay.google.com" CSP_STYLE_SRC: "'self' 'unsafe-inline' https://code.cdn.mozilla.net https://platform.twitter.com https://mozillafoundation.tfaforms.net https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" SECURE_CROSS_ORIGIN_OPENER_POLICY: "same-origin-allow-popups" diff --git a/.github/workflows/visual-regression-testing.yml b/.github/workflows/visual-regression-testing.yml index 4c7667ce5e8..2d097cfb815 100644 --- a/.github/workflows/visual-regression-testing.yml +++ b/.github/workflows/visual-regression-testing.yml @@ -43,7 +43,6 @@ jobs: DJANGO_SECRET_KEY: secret DOMAIN_REDIRECT_MIDDLEWARE_ENABLED: False GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NETWORK_SITE_URL: http://localhost:8000 PIPENV_VERBOSITY: -1 PULSE_API_DOMAIN: https://network-pulse-api-production.herokuapp.com PULSE_DOMAIN: https://www.mozillapulse.org diff --git a/env.default b/env.default index 3d2c935931b..1fee3ab316c 100644 --- a/env.default +++ b/env.default @@ -10,8 +10,7 @@ PULSE_API_DOMAIN=https://network-pulse-api-production.herokuapp.com PULSE_DOMAIN=https://www.mozillapulse.org -# Always add a protocol (ex: https://) in front of the NETWORK_SITE_URL, including for localhost -NETWORK_SITE_URL=http://localhost:8000 +# Always add a protocol (ex: https://) in front of the URL, including for localhost WAGTAILADMIN_BASE_URL=http://localhost:8000 DOMAIN_REDIRECT_MIDDLEWARE_ENABLED=False TARGET_DOMAINS=foundation.mozilla.org diff --git a/network-api/networkapi/settings.py b/network-api/networkapi/settings.py index 94151fcedb3..5a3393ad0dc 100644 --- a/network-api/networkapi/settings.py +++ b/network-api/networkapi/settings.py @@ -56,7 +56,6 @@ HEROKU_RELEASE_VERSION=(str, None), INDEX_PAGE_CACHE_TIMEOUT=(int, 60 * 60 * 24), MOZFEST_DOMAIN_REDIRECT_ENABLED=(bool, False), - NETWORK_SITE_URL=(str, ""), PETITION_TEST_CAMPAIGN_ID=(str, ""), PNI_STATS_DB_URL=(str, None), PULSE_API_DOMAIN=(str, ""), @@ -695,7 +694,6 @@ class DatabasesDict(TypedDict): FRONTEND = { "PULSE_API_DOMAIN": env("PULSE_API_DOMAIN"), "PULSE_DOMAIN": env("PULSE_DOMAIN"), - "NETWORK_SITE_URL": env("NETWORK_SITE_URL"), "TARGET_DOMAINS": env("TARGET_DOMAINS"), "SENTRY_DSN": env("SENTRY_DSN"), "RELEASE_VERSION": env("HEROKU_RELEASE_VERSION"), @@ -718,9 +716,6 @@ class DatabasesDict(TypedDict): # privacynotincluded statistics DB PNI_STATS_DB_URL = env("PNI_STATS_DB_URL") -# Use network_url to check if we're running prod or not -NETWORK_SITE_URL = env("NETWORK_SITE_URL") - # Blog/Campaign index cache setting INDEX_PAGE_CACHE_TIMEOUT = env("INDEX_PAGE_CACHE_TIMEOUT") diff --git a/source/js/buyers-guide/bg-main.js b/source/js/buyers-guide/bg-main.js index a0639fb24f4..98383318ba7 100644 --- a/source/js/buyers-guide/bg-main.js +++ b/source/js/buyers-guide/bg-main.js @@ -42,7 +42,7 @@ let main = { this.fetchEnv((envData) => { env = envData; - networkSiteURL = env.NETWORK_SITE_URL; + networkSiteURL = window.location.origin; if (env.SENTRY_DSN) { // Initialize Sentry error reporting initializeSentry( diff --git a/source/js/main.js b/source/js/main.js index b42d024ad24..ca8d6b234ac 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -66,7 +66,7 @@ let main = { this.fetchEnv((envData) => { env = envData; - networkSiteURL = env.NETWORK_SITE_URL; + networkSiteURL = window.location.origin; if (env.SENTRY_DSN) { // Initialize Sentry error reporting From 1f30b2a64439151cb8e6455416f32b4c6dcab248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20L=C3=B3pez?= <81331806+dlopezvsr@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:35:39 -0600 Subject: [PATCH 04/14] Move override methods from init file to new utils file (#12717) * Move override methods from init file to new utils file * Linting space lines * Linting fix sorted imports * Update test_utils imports from init to override_utils * Linting fix: Sorting imports from tests --------- Co-authored-by: Rob DiVincenzo --- .../networkapi/wagtailpages/__init__.py | 48 ++----------------- .../networkapi/wagtailpages/override_utils.py | 40 ++++++++++++++++ .../wagtailpages/tests/test_utils.py | 10 ++-- 3 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 network-api/networkapi/wagtailpages/override_utils.py diff --git a/network-api/networkapi/wagtailpages/__init__.py b/network-api/networkapi/wagtailpages/__init__.py index bf649cad20b..b8b6be5aa82 100644 --- a/network-api/networkapi/wagtailpages/__init__.py +++ b/network-api/networkapi/wagtailpages/__init__.py @@ -1,7 +1,6 @@ -import functools +from django.utils.translation import trans_real -import django -from django.utils.translation.trans_real import accept_language_re +from .override_utils import parse_accept_lang_header, to_language # WARNING: this is not necessarily a good idea, but is the only way to override # Django's default behaviour of requiring language codes to be lowercased. @@ -9,46 +8,7 @@ # all the core functionality that relies on this - e.g., url resolvers that # the Django admin and third party apps use. # A fix upstream has been asked in https://code.djangoproject.com/ticket/31795 - - -def language_code_to_iso_3166(language): - """Turn a language name (en-us) into an ISO 3166 format (en-US).""" - language, _, country = language.lower().partition("-") - if country: - return f"{language}-{country.upper()}" - return language - - -def to_language(locale): - """Turn a locale name (en_US) into a language name (en-US).""" - return locale.replace("_", "-") - - -@functools.lru_cache(maxsize=1000) -def parse_accept_lang_header(lang_string): - """ - Parse the lang_string, which is the body of an HTTP Accept-Language - header, and return a tuple of (lang, q-value), ordered by 'q' values. - Return an empty tuple if there are any format errors in lang_string. - """ - result = [] - pieces = accept_language_re.split(lang_string.lower()) - if pieces[-1]: - return () - for i in range(0, len(pieces) - 1, 3): - first, lang, priority = pieces[i : i + 3] - if first: - return () - if priority: - priority = float(priority) - else: - priority = 1.0 - result.append((language_code_to_iso_3166(lang), priority)) - result.sort(key=lambda k: k[1], reverse=True) - return tuple(result) - - # Replace some functions in django.utils.translation.trans_real with our own # versions that support a language in the form en-US instead of en-us. -django.utils.translation.trans_real.to_language = to_language -django.utils.translation.trans_real.parse_accept_lang_header = parse_accept_lang_header +trans_real.to_language = to_language +trans_real.parse_accept_lang_header = parse_accept_lang_header diff --git a/network-api/networkapi/wagtailpages/override_utils.py b/network-api/networkapi/wagtailpages/override_utils.py new file mode 100644 index 00000000000..c16953c0f44 --- /dev/null +++ b/network-api/networkapi/wagtailpages/override_utils.py @@ -0,0 +1,40 @@ +import functools + +from django.utils.translation.trans_real import accept_language_re + + +def language_code_to_iso_3166(language): + """Turn a language name (en-us) into an ISO 3166 format (en-US).""" + language, _, country = language.lower().partition("-") + if country: + return f"{language}-{country.upper()}" + return language + + +def to_language(locale): + """Turn a locale name (en_US) into a language name (en-US).""" + return locale.replace("_", "-") + + +@functools.lru_cache(maxsize=1000) +def parse_accept_lang_header(lang_string): + """ + Parse the lang_string, which is the body of an HTTP Accept-Language + header, and return a tuple of (lang, q-value), ordered by 'q' values. + Return an empty tuple if there are any format errors in lang_string. + """ + result = [] + pieces = accept_language_re.split(lang_string.lower()) + if pieces[-1]: + return () + for i in range(0, len(pieces) - 1, 3): + first, lang, priority = pieces[i : i + 3] + if first: + return () + if priority: + priority = float(priority) + else: + priority = 1.0 + result.append((language_code_to_iso_3166(lang), priority)) + result.sort(key=lambda k: k[1], reverse=True) + return tuple(result) diff --git a/network-api/networkapi/wagtailpages/tests/test_utils.py b/network-api/networkapi/wagtailpages/tests/test_utils.py index d71c7cb8ea4..0df2dc14c7f 100644 --- a/network-api/networkapi/wagtailpages/tests/test_utils.py +++ b/network-api/networkapi/wagtailpages/tests/test_utils.py @@ -10,11 +10,6 @@ from wagtail.images.models import Image from wagtail.models import Collection, Locale -from networkapi.wagtailpages import ( - language_code_to_iso_3166, - parse_accept_lang_header, - to_language, -) from networkapi.wagtailpages.factory import blog as blog_factories from networkapi.wagtailpages.factory.blog import ( BlogIndexPageFactory, @@ -22,6 +17,11 @@ FeaturedBlogPagesFactory, ) from networkapi.wagtailpages.factory.profiles import ProfileFactory +from networkapi.wagtailpages.override_utils import ( + language_code_to_iso_3166, + parse_accept_lang_header, + to_language, +) from networkapi.wagtailpages.pagemodels.blog.blog import BlogAuthors, BlogPage from networkapi.wagtailpages.pagemodels.profiles import Profile from networkapi.wagtailpages.tests.base import WagtailpagesTestCase From 2eef82e3b4d5568ff439a873c83eec7385bcfb18 Mon Sep 17 00:00:00 2001 From: Mavis Ou Date: Wed, 28 Aug 2024 13:47:07 -0700 Subject: [PATCH 05/14] Replaced emoji for special page nav link with text (#12728) * Replaced emoji for special page nav link with text * Created a template fragment to render notes for menu link to special page --- .../templates/tags/horizontal_nav.html | 2 +- .../tags/multipage_menu_link_note.html | 18 ++++++++++++++++++ .../wagtailpages/tags/mini_site_sidebar.html | 2 +- source/sass/components/multipage-nav.scss | 16 ---------------- 4 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 network-api/networkapi/templates/tags/multipage_menu_link_note.html diff --git a/network-api/networkapi/templates/tags/horizontal_nav.html b/network-api/networkapi/templates/tags/horizontal_nav.html index 2633eaf3abe..7f5c3c97e2c 100644 --- a/network-api/networkapi/templates/tags/horizontal_nav.html +++ b/network-api/networkapi/templates/tags/horizontal_nav.html @@ -5,7 +5,7 @@ {% for entry in menu_pages %} {% pageurl entry.page as entry_page_url %} {% if entry.depth < 2 %} - {{ entry.menu_title }} + {{ entry.menu_title }} {% include "tags/multipage_menu_link_note.html" with menu_entry=entry %} {% endif %} {% endfor %} diff --git a/network-api/networkapi/templates/tags/multipage_menu_link_note.html b/network-api/networkapi/templates/tags/multipage_menu_link_note.html new file mode 100644 index 00000000000..e20fd33fbc7 --- /dev/null +++ b/network-api/networkapi/templates/tags/multipage_menu_link_note.html @@ -0,0 +1,18 @@ +{% load i18n %} + +{% with class="tw-text-red-80 tw-text-sm tw-ml-1" %} + {% comment %}These notes are internal facing only. Only logged in users can see them.{% endcomment %} + + {% if menu_entry.restriction == "login" %} + (logged in users only) + {% elif menu_entry.restriction == "groups" %} + (restricted to specific groups) + {% elif menu_entry.restriction == "password" %} + (password protected) + {% endif %} + + {% if not menu_entry.page.live %} + (draft) + {% endif %} + +{% endwith %} diff --git a/network-api/networkapi/wagtailpages/templates/wagtailpages/tags/mini_site_sidebar.html b/network-api/networkapi/wagtailpages/templates/wagtailpages/tags/mini_site_sidebar.html index 3059ea832b7..3467fb6da30 100644 --- a/network-api/networkapi/wagtailpages/templates/wagtailpages/tags/mini_site_sidebar.html +++ b/network-api/networkapi/wagtailpages/templates/wagtailpages/tags/mini_site_sidebar.html @@ -7,7 +7,7 @@ {% for entry in menu_pages %} {% pageurl entry.page as entry_page_url %} {% endfor %} diff --git a/source/sass/components/multipage-nav.scss b/source/sass/components/multipage-nav.scss index c63fdb4efaa..97193066a96 100644 --- a/source/sass/components/multipage-nav.scss +++ b/source/sass/components/multipage-nav.scss @@ -36,20 +36,4 @@ @apply tw-mb-12; } } - - .multipage-login-restricted::after { - content: "🙈"; - } - - .multipage-groups-restricted::after { - content: "👥"; - } - - .multipage-password-restricted::after { - content: "🔒"; - } - - .multipage-draft::after { - content: "🐣"; - } } From 6d1497f3ba53722c0ed4c5f851016a1018123e0e Mon Sep 17 00:00:00 2001 From: Mavis Ou Date: Wed, 28 Aug 2024 20:31:54 -0700 Subject: [PATCH 06/14] Add documentation to PNI search related JS files (#12742) * Added doc to utils.js * Added doc to pni-sort-dropdown.js and pni-toggle.js * Added doc to slider-area.js * Added doc to member-functions.js * Added doc to history.js --- source/js/buyers-guide/search/history.js | 35 +++++++--- .../buyers-guide/search/member-functions.js | 17 ++++- .../buyers-guide/search/pni-sort-dropdown.js | 28 ++++++++ source/js/buyers-guide/search/pni-toggle.js | 9 +++ source/js/buyers-guide/search/slider-area.js | 21 +++++- source/js/buyers-guide/search/utils.js | 66 +++++++++++++------ 6 files changed, 140 insertions(+), 36 deletions(-) diff --git a/source/js/buyers-guide/search/history.js b/source/js/buyers-guide/search/history.js index 54bfaffa240..cb11b8012f3 100644 --- a/source/js/buyers-guide/search/history.js +++ b/source/js/buyers-guide/search/history.js @@ -6,10 +6,13 @@ const parentTitle = document.querySelector(`.parent-title`); const toggle = document.querySelector(`#product-filter-pni-toggle`); /** - * ... + * Set up history management + * * @param {*} instance - * @param {*} searchBar - * @param {*} searchInput + * @param {Element} searchBar - The search bar element + * @param {Element} searchInput - The search input element + * @param {Element} mobileSearchBar - The mobile search bar element + * @param {Element} mobileSearchInput - The mobile search input element */ export function setupHistoryManagement( instance, @@ -35,10 +38,18 @@ export function setupHistoryManagement( } /** - * ... + * Update History state and update page UI accordingly + * * @param {*} instance - * @param {*} searchBar - * @param {*} searchInput + * @param {Element} searchBar - The search bar element + * @param {Element} searchInput - The search input element + * @param {Element} mobileSearchBar - The mobile search bar element + * @param {Element} mobileSearchInput - The mobile search input element + * + * @todo FIXME. We need to revisit and improve the implementation of this function. + * It's unclear why history.replaceState needs to be called twice. + * It's also unclear why there are repeated if-else statements especially for search parameters. + * Further investigation is needed to understand the purpose of this function. */ export function performInitialHistoryReplace( instance, @@ -120,10 +131,13 @@ export function performInitialHistoryReplace( } /** - * ... + * Set up the window.popstate event listener + * * @param {*} instance - * @param {*} searchBar - * @param {*} searchInput + * @param {Element} searchBar - The search bar element + * @param {Element} searchInput - The search input element + * @param {Element} mobileSearchBar - The mobile search bar element + * @param {Element} mobileSearchInput - The mobile search input element */ export function setupPopStateHandler( instance, @@ -183,7 +197,8 @@ export function setupPopStateHandler( } /** - * ... + * Apply data stored in the history state to the page + * * @param {*} instance */ export function applyHistory(instance) { diff --git a/source/js/buyers-guide/search/member-functions.js b/source/js/buyers-guide/search/member-functions.js index bb178e42d4c..9cfe673255b 100644 --- a/source/js/buyers-guide/search/member-functions.js +++ b/source/js/buyers-guide/search/member-functions.js @@ -5,7 +5,8 @@ const parentTitle = document.querySelector(`.parent-title`); const subcategories = document.querySelectorAll(`.subcategories`); /** - * ... + * Attach event listeners to the nav links and subcategory links + * * @param {*} instance */ export function setupNavLinks(instance) { @@ -116,7 +117,8 @@ export function setupNavLinks(instance) { } /** - * ... + * Attach event listeners to "go back to all" link + * * @param {*} instance */ export function setupGoBackToAll(instance) { @@ -153,8 +155,11 @@ export function setupGoBackToAll(instance) { } /** - * ... + * Attach event listeners to the Product Review nav links + * * @param {*} instance + * + * @todo See if we can make this DRYer by making use of the toggleProductReviewView function? */ export function setupReviewLinks(instance) { const navLinks = document.querySelectorAll(`.product-review-link`); @@ -179,6 +184,9 @@ export function setupReviewLinks(instance) { } } +/** + * Toggle the Product Review view + */ export function toggleProductReviewView() { const editorialContent = document.querySelector(".editorial-content"); const navLinks = document.querySelectorAll(`.product-review-link`); @@ -190,6 +198,9 @@ export function toggleProductReviewView() { } } +/** + * Toggle the category related articles section + */ export function toggleCategoryRelatedArticles(category) { const relatedArticles = document.querySelectorAll("[data-show-for-category]"); diff --git a/source/js/buyers-guide/search/pni-sort-dropdown.js b/source/js/buyers-guide/search/pni-sort-dropdown.js index 154ec8305fd..a4813c3455c 100644 --- a/source/js/buyers-guide/search/pni-sort-dropdown.js +++ b/source/js/buyers-guide/search/pni-sort-dropdown.js @@ -4,6 +4,9 @@ const DOWN_ARROW_KEY_CODE = 40; const UP_ARROW_KEY_CODE = 38; const ESCAPE_KEY_CODE = 27; +/** + * Dropdown component for sorting products on PNI + */ export class PNISortDropdown { constructor(searchFilter) { this.searchFilter = searchFilter; @@ -81,6 +84,11 @@ export class PNISortDropdown { } } + /** + * Sets the selected list item and updates the dropdown button content. + * @param {Event} e - The event (e.g., click, keydown) + * @param {boolean} [pushUpdate=true] - Whether to push the update to the history state. + */ setSelectedListItem(e, pushUpdate = true) { this.listItems.forEach((item) => { const itemDiv = item.querySelector("div"); @@ -99,12 +107,20 @@ export class PNISortDropdown { } } + /** + * Closes the dropdown list. + */ closeList() { this.listContainer.classList.add("tw-hidden"); this.dropdownButton.setAttribute("aria-expanded", false); this.dropdownButtonArrow.classList.remove("tw-rotate-180"); } + /** + * Opens the dropdown list. + * + * @param {boolean} [withFocus=false] - Whether to focus on the first list item. + */ openList(withFocus = false) { this.listContainer.classList.remove("tw-hidden"); this.dropdownButton.setAttribute("aria-expanded", true); @@ -118,6 +134,11 @@ export class PNISortDropdown { } } + /** + * Toggle the visibility of the dropdown list + * + * @param {Event} e The event (e.g., click, keydown) + */ toggleListVisibility(e) { const isExpanded = this.dropdownButton.getAttribute("aria-expanded") === "true"; @@ -140,6 +161,13 @@ export class PNISortDropdown { } } + /** + * Focus on the next list item based on the given direction. + * + * @param {number} direction - They key code of the direction to move the focus (e.g., key code for up arrow / down arrow) + * + * @todo Consider refactoring this method to make it more readable and maintainable. + */ focusNextListItem(direction) { const activeElementId = document.activeElement.id; const currentActiveElementIndex = this.listItemIds.indexOf(activeElementId); diff --git a/source/js/buyers-guide/search/pni-toggle.js b/source/js/buyers-guide/search/pni-toggle.js index b5c3a47b576..9afbd22218b 100644 --- a/source/js/buyers-guide/search/pni-toggle.js +++ b/source/js/buyers-guide/search/pni-toggle.js @@ -1,6 +1,9 @@ import { Utils } from "./utils.js"; import { gsap } from "gsap"; +/** + * The control that toggles the "Privacy Not Included" filter on the product list. + */ export class PNIToggle { constructor(searchFilter) { this.searchFilter = searchFilter; @@ -51,7 +54,13 @@ export class PNIToggle { }); } + /** + * Toggle the "Privacy Not Included" filter on the product list. + * + * @param {boolean} doFilter - Whether to filter the list for "Privacy Not Included" products. + */ togglePrivacyOnly(doFilter) { + console.log(doFilter); const { searchFilter, categoryTitle } = this; gsap.set("figure.product-box.privacy-ding", { opacity: 1, y: 0 }); diff --git a/source/js/buyers-guide/search/slider-area.js b/source/js/buyers-guide/search/slider-area.js index 524d14323cc..395030816eb 100644 --- a/source/js/buyers-guide/search/slider-area.js +++ b/source/js/buyers-guide/search/slider-area.js @@ -1,8 +1,8 @@ /** - * mouse/touch scroll functionality for the category area - * @param {*} event + * Mouse/touch scroll functionality for the sub category area on mobile + * + * @todo Rename this file to something more specific. Maybe something like subcategory-scroll.js */ - const subcategories = document.querySelectorAll(`.subcategories`); const subContainer = document.querySelector(`.subcategory-header`); const subClasses = subContainer.classList; @@ -14,6 +14,11 @@ function stop(evt) { evt.stopImmediatePropagation(); } +/** + * A event handler that initiate the scroll functionality on the sub category area + * + * @param {Event} event The event that triggered the function + */ export function markScrollStart(event) { stop(event); subClasses.add("cursor-grabbing", "select-none"); @@ -27,6 +32,11 @@ export function markScrollStart(event) { document.addEventListener(`mouseup`, markScrollEnd); } +/** + * A event handler for moving the scorll on the sub category area + * + * @param {Event} event The event that triggered the function + */ function markScrollMove(event) { subcategories.forEach((subcategory) => { subcategory.classList.add("pointer-events-none"); @@ -35,6 +45,11 @@ function markScrollMove(event) { subContainer.scrollLeft = pos.left - dx; } +/** + * A event handler for stopping the scorll on the sub category area + * + * @param {Event} event The event that triggered the function + */ function markScrollEnd(event) { stop(event); diff --git a/source/js/buyers-guide/search/utils.js b/source/js/buyers-guide/search/utils.js index f6544c1e62e..5e57d3c32e7 100644 --- a/source/js/buyers-guide/search/utils.js +++ b/source/js/buyers-guide/search/utils.js @@ -14,9 +14,10 @@ const PARENT_TITLE = document.querySelector(`.parent-title`); export class Utils { /** - *... - * @param {*} category - * @returns + * Return the title of the page based on the category passed in the argument + * + * @param {String} category name of the category + * @returns {String} title of the page */ static getTitle(category) { if (category == "None") @@ -29,9 +30,12 @@ export class Utils { } /** - * ... + * Update page header to the category passed in the argument + * * @param {*} category * @param {*} parent + * + * @todo Improve the implementation to increase code readibility */ static updateHeader(category, parent) { const headerText = document.querySelector(".category-header"); @@ -90,6 +94,7 @@ export class Utils { /** * Activate a specific category nav link + * * @param {String} category category name */ static activateCatNav(category = "None") { @@ -113,6 +118,7 @@ export class Utils { /** * Set active category nav link + * * @param {String} category name of the category */ static setActiveCatNavLink(category) { @@ -128,8 +134,11 @@ export class Utils { } /** - * ... - * @param {*} text + * Toggle products' visibility based on search text + * + * @param {String} text search text + * + * @todo Rename to "filterProductsBySearchText" */ static toggleProducts(text) { gsap.set(ALL_PRODUCTS, { opacity: 1, y: 0 }); @@ -147,7 +156,7 @@ export class Utils { } /** - * Scroll Animation used solely for the 'All Products' section + * Scroll animation used solely for the 'All Products' section */ static toggleScrollAnimation() { gsap.set("figure.product-box.d-flex", { opacity: 0, y: 100 }); @@ -204,8 +213,11 @@ export class Utils { } /** - * ... - * @param {*} category + * Toggle products' visibility based on category + * + * @param {String} category category name + * + * @todo Rename to "filterProductsByCategory" */ static showProductsForCategory(category) { gsap.set(ALL_PRODUCTS, { opacity: 1, y: 0 }); @@ -222,8 +234,9 @@ export class Utils { } /** - * ... - * @param {*} category + * Toggle CTA visibility based on category + * + * @param {String} category category name */ static toggleCtaForCategory(category) { const categoryPageCta = document.getElementById("category-featured-cta"); @@ -239,10 +252,13 @@ export class Utils { } /** - * ... - * @param {*} product - * @param {*} text - * @returns + * Test if any of the product fields contains the search text + * + * @param {Element} product DOM element of the product + * @param {String} text search text + * @returns {Boolean} Whether the product contains the search text + * + * @todo Rename to "doesProductContainSearchText" */ static test(product, text) { // Note that the following is absolutely not true for all @@ -263,16 +279,18 @@ export class Utils { } /** - * ... - * @param {*} product - * @param {*} category - * @returns + * Check if the product belongs to the category + * + * @param {Element} product DOM element of the product + * @param {String} category category name + * @returns {Boolean} Whether the product belongs to the category */ static testCategories(product, category) { if (category === "None") { return true; } + // all the categories this product belongs to const productCategories = Array.from( product.querySelectorAll(".product-categories") ); @@ -281,7 +299,7 @@ export class Utils { } /** - * ... + * Sort the products by the default sort order */ static sortFilteredProducts() { const container = document.querySelector(`.product-box-list`); @@ -316,7 +334,9 @@ export class Utils { } /** + * Toggle the visibility of "no results" notice * + * @todo Rename to "toggleNoResultsNotice" */ static checkForEmptyNotice() { let qs = `figure.product-box:not(.d-none)`; @@ -336,6 +356,11 @@ export class Utils { } } + /** + * Toggle the visibility of the creepy face and speech + * + * @todo Rename to "toggleCreepyFace" + */ static moveCreepyFace() { const CREEPINESS_FACE = document.querySelector( ".creep-o-meter-information" @@ -383,6 +408,7 @@ export class Utils { /** * Scroll to a specific subcategory nav link if it exists on the page + * * @param {string} category - The name of the category */ static scrollToSubCategory(category) { From 76bafa9bdb5d1e5683b3470058f8b1f201924591 Mon Sep 17 00:00:00 2001 From: Mavis Ou Date: Thu, 29 Aug 2024 13:40:47 -0700 Subject: [PATCH 07/14] PNI - Closing the search bar on mobile should also clear search (#12746) --- .../buyers-guide/template-js-handler/mobile-search-bar.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/js/buyers-guide/template-js-handler/mobile-search-bar.js b/source/js/buyers-guide/template-js-handler/mobile-search-bar.js index 53170666cba..259aa6b94a1 100644 --- a/source/js/buyers-guide/template-js-handler/mobile-search-bar.js +++ b/source/js/buyers-guide/template-js-handler/mobile-search-bar.js @@ -17,6 +17,12 @@ export default () => { if (burger && burger.classList.contains("menu-open")) { document.querySelector(".burger").click(); } + + // if the search bar is open, clear the search bar + if (!searchContainer.classList.contains("tw-hidden")) { + searchContainer.querySelector(`.clear-icon`).click(); + } + searchContainer.classList.toggle("tw-hidden"); mobileCatNav.classList.toggle("tw-hidden"); }); From 1d652212ab51c3bace4741151aa56cd7e2051ac7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:10:43 -0700 Subject: [PATCH 08/14] Bump micromatch from 4.0.5 to 4.0.8 (#12741) Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.5 to 4.0.8. - [Release notes](https://github.com/micromatch/micromatch/releases) - [Changelog](https://github.com/micromatch/micromatch/blob/4.0.8/CHANGELOG.md) - [Commits](https://github.com/micromatch/micromatch/compare/4.0.5...4.0.8) --- updated-dependencies: - dependency-name: micromatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Miranda --- package-lock.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index c36f5790045..f7e64e9dace 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,9 +32,9 @@ "react-ga": "3.3.1", "sass": "^1.59.3", "shx": "^0.3.4", - "uuid": "^10.0.0", "swiper": "^11.1.9", "tailwindcss": "^3.4.9", + "uuid": "^10.0.0", "whatwg-fetch": "^3.6.20" }, "devDependencies": { @@ -6635,11 +6635,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -15886,11 +15886,11 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, From d274f544acb00425ca344a7f7c1ed9be0d098122 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:29:45 -0700 Subject: [PATCH 09/14] Bump chart.js from 4.4.3 to 4.4.4 (#12734) Bumps [chart.js](https://github.com/chartjs/Chart.js) from 4.4.3 to 4.4.4. - [Release notes](https://github.com/chartjs/Chart.js/releases) - [Commits](https://github.com/chartjs/Chart.js/compare/v4.4.3...v4.4.4) --- updated-dependencies: - dependency-name: chart.js dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Miranda --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index f7e64e9dace..5b214b4e01e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "autoprefixer": "^10.4.20", "axe-core": "^4.10.0", "bootstrap": "^4.6.0", - "chart.js": "4.4.3", + "chart.js": "4.4.4", "classnames": "2.5.1", "countup.js": "^2.8.0", "cssnano": "^6.1.2", @@ -2656,9 +2656,9 @@ } }, "node_modules/chart.js": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", - "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", "dependencies": { "@kurkle/color": "^0.3.0" }, @@ -12896,9 +12896,9 @@ } }, "chart.js": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", - "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", "requires": { "@kurkle/color": "^0.3.0" } diff --git a/package.json b/package.json index 11b83d37451..9b491747067 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "autoprefixer": "^10.4.20", "axe-core": "^4.10.0", "bootstrap": "^4.6.0", - "chart.js": "4.4.3", + "chart.js": "4.4.4", "classnames": "2.5.1", "countup.js": "^2.8.0", "cssnano": "^6.1.2", From f214c2fd06df563b2c588b338c5271c3f65cf4f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:39:37 -0700 Subject: [PATCH 10/14] Bump python-slugify from 8.0.3 to 8.0.4 (#11850) Bumps [python-slugify](https://github.com/un33k/python-slugify) from 8.0.3 to 8.0.4. - [Changelog](https://github.com/un33k/python-slugify/blob/master/CHANGELOG.md) - [Commits](https://github.com/un33k/python-slugify/compare/v8.0.3...v8.0.4) --- updated-dependencies: - dependency-name: python-slugify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Miranda --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0bfa96ba1a2..bc7824fddbb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -182,7 +182,7 @@ python-dateutil==2.8.2 # botocore # faker # heroku3 -python-slugify==8.0.3 +python-slugify==8.0.4 # via -r requirements.in python3-openid==3.2.0 # via social-auth-core From 1afe5ccfe98c0ca4dfb1c48125fb85e49e837560 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:54:10 -0700 Subject: [PATCH 11/14] Bump wagtail-ab-testing from 0.9 to 0.10 (#12090) Bumps [wagtail-ab-testing](https://github.com/wagtail-nest/wagtail-ab-testing) from 0.9 to 0.10. - [Release notes](https://github.com/wagtail-nest/wagtail-ab-testing/releases) - [Changelog](https://github.com/wagtail-nest/wagtail-ab-testing/blob/main/CHANGELOG.md) - [Commits](https://github.com/wagtail-nest/wagtail-ab-testing/compare/v0.9...v0.10) --- updated-dependencies: - dependency-name: wagtail-ab-testing dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Miranda --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bc7824fddbb..202cd781d43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -263,7 +263,7 @@ wagtail==5.2.6 # wagtail-localize-git # wagtail-metadata # wagtailmedia -wagtail-ab-testing==0.9 +wagtail-ab-testing==0.10 # via -r requirements.in wagtail-color-panel==1.5.0 # via -r requirements.in From 29ed8deb3b7c6e7ccfdb08929665ede75461c858 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:05:00 -0700 Subject: [PATCH 12/14] Bump social-auth-app-django from 5.4.1 to 5.4.2 (#12620) Bumps [social-auth-app-django](https://github.com/python-social-auth/social-app-django) from 5.4.1 to 5.4.2. - [Release notes](https://github.com/python-social-auth/social-app-django/releases) - [Changelog](https://github.com/python-social-auth/social-app-django/blob/master/CHANGELOG.md) - [Commits](https://github.com/python-social-auth/social-app-django/compare/5.4.1...5.4.2) --- updated-dependencies: - dependency-name: social-auth-app-django dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Miranda --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 202cd781d43..1bc9c94776f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -221,7 +221,7 @@ six==1.16.0 # python-dateutil smmap==5.0.0 # via gitdb -social-auth-app-django==5.4.1 +social-auth-app-django==5.4.2 # via -r requirements.in social-auth-core==4.4.1 # via social-auth-app-django From 2dfbceef479033e795dbb80af7204433a6bb5834 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:14:38 -0700 Subject: [PATCH 13/14] Bump django-storages from 1.14.3 to 1.14.4 (#12618) Bumps [django-storages](https://github.com/jschneier/django-storages) from 1.14.3 to 1.14.4. - [Changelog](https://github.com/jschneier/django-storages/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jschneier/django-storages/compare/1.14.3...1.14.4) --- updated-dependencies: - dependency-name: django-storages dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Miranda --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1bc9c94776f..e5bc77849ba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -99,7 +99,7 @@ django-querystring-tag==1.0.3 # via -r requirements.in django-redis==5.4.0 # via -r requirements.in -django-storages==1.14.3 +django-storages==1.14.4 # via -r requirements.in django-taggit==3.0.0 # via wagtail From 30e1488d580c32f9f77f408c7b77c94bfa3b6b1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:32:17 -0700 Subject: [PATCH 14/14] Bump factory-boy from 3.3.0 to 3.3.1 (#12720) Bumps [factory-boy](https://github.com/FactoryBoy/factory_boy) from 3.3.0 to 3.3.1. - [Changelog](https://github.com/FactoryBoy/factory_boy/blob/master/docs/changelog.rst) - [Commits](https://github.com/FactoryBoy/factory_boy/compare/3.3.0...3.3.1) --- updated-dependencies: - dependency-name: factory-boy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Miranda --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e5bc77849ba..51ad99c678c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -113,7 +113,7 @@ draftjs-exporter==2.1.7 # via wagtail et-xmlfile==1.1.0 # via openpyxl -factory-boy==3.3.0 +factory-boy==3.3.1 # via # -r requirements.in # wagtail-factories