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

Turn on additional search views frontend #4043

Merged
merged 2 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/feat/feature-flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
"additional_search_views": {
"status": {
"staging": "switchable",
"production": "disabled"
"production": "switchable"
},
"description": "Toggle additional search views for tag/creator/source.",
"defaultState": "off",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm a little confused about what the "right" way to toggle the flag on in production is.

We set it to switchable, but default it to on. That means it's basically on in all environments, but an individual could switch it off by visiting /preferences, right? In practice that's irrelevant to everyone except devs because /preferences isn't linked anywhere.

So this feature flag setting could be simpified by: replacing the staging entry with a single production entry, set to enabled, and removing defaultState altogether. Thinking of this in stages, should we do this in two steps, first set production to switchable, default state off, and staging to enabled? And then confirm it in staging as a globally enabled preference (rather than a toggled one), and then update production to enabled? It would be nice if we could control these using environment variables so that it doesn't take an entire new release for each stage to take effect.

Copy link
Member

Choose a reason for hiding this comment

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

In production it seems that "switchable" is essentially "enabled" but with a convenience method for devs to see the disabled state.

Abstractly, I think the flow for launching frontend features should be:

  • Enable the feature by default in staging, switchable but off by default in prod
  • Test it in both of those contexts
  • Enable it in prod

I think we could use a doc outlining how to prep and ship user-facing frontend (or API, for that matter) features. I'll create issues this week.

"defaultState": "on",
"storage": "cookie"
},
"additional_search_types": {
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/VMediaInfo/VMediaTags.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import type { Tag } from "~/types/media"
import type { SupportedMediaType } from "~/constants/media"
import { useFeatureFlagStore } from "~/stores/feature-flag"
import { useSearchStore } from "~/stores/search"
import { useI18n } from "~/composables/use-i18n"

import { focusElement } from "~/utils/focus-management"

Expand Down Expand Up @@ -87,7 +88,8 @@ export default defineComponent({

const searchStore = useSearchStore()
const featureFlagStore = useFeatureFlagStore()
const { app, $sendCustomEvent } = useContext()
const { $sendCustomEvent } = useContext()
const i18n = useI18n()

const additionalSearchViews = computed(() =>
featureFlagStore.isOn("additional_search_views")
Expand All @@ -106,7 +108,7 @@ export default defineComponent({

const collapsibleRowsStartAt = ref<number>()
const dir = computed(() => {
return app.i18n.localeProperties.dir
return i18n.localeProperties.dir
})

function isFurtherInline(previous: HTMLElement, current: HTMLElement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ describe("AudioTrack", () => {

it("should render the full audio track component even without duration", () => {
options.propsData.layout = "full"
const { getByText } = render(VAudioTrack, options, configureVue)
const creator = getByText(props.audio.creator)
expect(creator).toBeInstanceOf(HTMLAnchorElement)
const { getByRole } = render(VAudioTrack, options, configureVue)
const creator = getByRole("link", { name: props.audio.creator })
expect(creator).toBeVisible()
})

it("should show audio title as main page title in full layout", () => {
Expand All @@ -73,10 +73,13 @@ describe("AudioTrack", () => {

it("should show audio creator in a full layout with link", () => {
options.propsData.layout = "full"
const { getByText } = render(VAudioTrack, options, configureVue)
const element = getByText(props.audio.creator)
expect(element).toBeInstanceOf(HTMLAnchorElement)
expect(element).toHaveAttribute("href", props.audio.creator_url)
const { getByRole } = render(VAudioTrack, options, configureVue)
const element = getByRole("link", { name: props.audio.creator })
expect(element).toBeVisible()
expect(element).toHaveAttribute(
"href",
`/audio/collection?source=jamendo&creator=${props.audio.creator}`
)
})

it("should render the row audio track component even without duration", () => {
Expand Down
4 changes: 3 additions & 1 deletion frontend/test/unit/test-utils/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import VueI18n from "vue-i18n"

const messages = require("~/locales/en.json")

export const i18n = new VueI18n({
const i18n = new VueI18n({
locale: "en",
fallbackLocale: "en",
messages: {
en: messages,
},
})
i18n.localeProperties = { code: "en", dir: "ltr" }
export { i18n }
7 changes: 6 additions & 1 deletion frontend/test/unit/test-utils/pinia.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ export const createPinia = () =>
},
},
error: jest.fn(),
localePath: jest.fn(),
localePath: jest.fn((val) => {
const queryString = Object.keys(val?.query)
.map((key) => key + "=" + val?.query[key])
.join("&")
return `${val?.path ?? "/"}?${queryString}`
}),
},
}))

Expand Down