diff --git a/browser-tests/tests/initialData.ts b/browser-tests/tests/initialData.ts index a3e40423..9db9edf8 100644 --- a/browser-tests/tests/initialData.ts +++ b/browser-tests/tests/initialData.ts @@ -1,50 +1,34 @@ -import { - testUsername, - testUserPassword, -} from './utils/settings'; +import { testUsername, testUserPassword } from "./utils/settings"; -import { - event, - createNew as createNewEvent -} from './pages/event'; -import { - createNew as createNewOccurence, -} from './pages/occurence'; +import { event, createNew as createNewEvent } from "./pages/event"; +import { createNew as createNewOccurence } from "./pages/occurence"; import { eventGroup, publish as publishEventGroup, - createNew as createNewEventGroup -} from './pages/eventGroup'; -import { - projectExists, - project, -} from './pages/project'; -import { - venue, - venueExists, -} from './pages/venue'; - -import { createNewMessage } from './pages/message'; -import { userExists } from './pages/user'; -import { route as routeHome } from './pages/home'; + createNew as createNewEventGroup, +} from "./pages/eventGroup"; +import { projectExists, project } from "./pages/project"; +import { venue, venueExists } from "./pages/venue"; -import { login } from './utils/login'; +import { createNewMessage } from "./pages/message"; +import { userExists } from "./pages/user"; +import { route as routeHome } from "./pages/home"; -fixture`Event group feature` - .page(routeHome()) - .beforeEach(async (t) => { - await login(t, { - username: testUsername(), - password: testUserPassword(), - }); - await t.wait(1000); +import { login } from "./utils/login"; - await projectExists(t); - await venueExists(t); +fixture`Event group feature`.page(routeHome()).beforeEach(async (t) => { + await login(t, { + username: testUsername(), + password: testUserPassword(), }); + await t.wait(1000); + + await projectExists(t); + await venueExists(t); +}); -test('Add initial data for ui and admin ui tests', async (t) => { - const projectName = `${project.name} ${project.year}`; +test("Add initial data for ui and admin ui tests", async (t) => { + const projectName = new RegExp(`${project.year}$`); // add new event group await createNewEventGroup(t, projectName); diff --git a/browser-tests/tests/pages/event.ts b/browser-tests/tests/pages/event.ts index 1c3d35e4..500458b6 100644 --- a/browser-tests/tests/pages/event.ts +++ b/browser-tests/tests/pages/event.ts @@ -32,7 +32,7 @@ export const routeAdd = () => `${envUrl()}/admin/events/event/add`; // fill add form for new event export const fillFormAdd = async ( t: TestController, - projectName: string, + projectName: string | RegExp, eventGroupName: string ) => { const eventGroupOption = eventAdd.eventGroup.find("option"); @@ -56,7 +56,7 @@ export const fillFormAdd = async ( // create new event export const createNew = async ( t: TestController, - projectName: string, + projectName: string | RegExp, eventGroupName: string ) => { await t.navigateTo(routeAdd()); diff --git a/browser-tests/tests/pages/eventGroup.ts b/browser-tests/tests/pages/eventGroup.ts index 4f67ab1a..cc8850a8 100644 --- a/browser-tests/tests/pages/eventGroup.ts +++ b/browser-tests/tests/pages/eventGroup.ts @@ -31,7 +31,7 @@ export const publish = async (t: TestController) => { await t.navigateTo(route()); // checkbox on event group row - const selectCheckbox = Selector(".field-name") + const selectCheckbox = Selector(".field-name_with_fallback") .withText(eventGroup.name) .parent("tr") .child(".action-checkbox") @@ -48,7 +48,10 @@ export const publish = async (t: TestController) => { }; // fill add form for new event group -export const fillFormAdd = async (t: TestController, projectName: string) => { +export const fillFormAdd = async ( + t: TestController, + projectName: string | RegExp +) => { await t .click(eventGroupAdd.project) .click(getDropdownOption(projectName)) @@ -57,7 +60,10 @@ export const fillFormAdd = async (t: TestController, projectName: string) => { }; // create new event group -export const createNew = async (t: TestController, projectName: string) => { +export const createNew = async ( + t: TestController, + projectName: string | RegExp +) => { await t.navigateTo(routeAdd()); await fillFormAdd(t, projectName); diff --git a/browser-tests/tests/pages/message.ts b/browser-tests/tests/pages/message.ts index dd221d1b..03273b7b 100644 --- a/browser-tests/tests/pages/message.ts +++ b/browser-tests/tests/pages/message.ts @@ -25,7 +25,7 @@ export const routeAdd = () => `${envUrl()}/admin/messaging/message/add/`; // fill add form for new message export const fillFormAdd = async ( t: TestController, - projectName: string, + projectName: string | RegExp, eventName: string ) => { const eventOption = messageAdd.event.find("option"); @@ -49,7 +49,7 @@ export const fillFormAdd = async ( // create new message export const createNewMessage = async ( t: TestController, - projectName: string, + projectName: string | RegExp, eventName: string ) => { await t.navigateTo(routeAdd()); diff --git a/browser-tests/tests/pages/project.ts b/browser-tests/tests/pages/project.ts index 9cceab90..adfac0bc 100644 --- a/browser-tests/tests/pages/project.ts +++ b/browser-tests/tests/pages/project.ts @@ -22,7 +22,6 @@ export const routeAdd = () => `${envUrl()}/admin/projects/project/add/`; export const addProject = async (t: TestController) => { await t.navigateTo(routeAdd()); - await t .typeText(projectAdd.name, project.name) .typeText(projectAdd.year, year.toString()) diff --git a/browser-tests/tests/pages/venue.ts b/browser-tests/tests/pages/venue.ts index 03ece92c..95f43569 100644 --- a/browser-tests/tests/pages/venue.ts +++ b/browser-tests/tests/pages/venue.ts @@ -28,7 +28,7 @@ export const addVenue = async (t: TestController) => { await t .click(venueAdd.project) - .click(getDropdownOption(`${project.name} ${project.year}`)) + .click(getDropdownOption(new RegExp(`${project.year}$`))) .typeText(venueAdd.name, venue.name) .typeText(venueAdd.description, venue.description) .click(venueAdd.saveButton); diff --git a/browser-tests/tests/utils/getDropdownOption.ts b/browser-tests/tests/utils/getDropdownOption.ts index 7b0210c8..770c77f9 100644 --- a/browser-tests/tests/utils/getDropdownOption.ts +++ b/browser-tests/tests/utils/getDropdownOption.ts @@ -1,7 +1,7 @@ -import { screen } from '@testing-library/testcafe'; +import { screen } from "@testing-library/testcafe"; -function getDropdownOption(label: string) { - return screen.getByRole('option', { name: label }); +function getDropdownOption(label: string | RegExp) { + return screen.getByRole("option", { name: label }); } export default getDropdownOption; diff --git a/events/admin.py b/events/admin.py index 75b2dc1e..7d0f0f76 100644 --- a/events/admin.py +++ b/events/admin.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.contrib import admin, messages from django.contrib.admin.widgets import FilteredSelectMultiple from django.core.exceptions import ValidationError @@ -84,6 +85,7 @@ class EventAdmin(TranslatableAdmin): "ticket_system_url", "ticket_system_end_time", ) + search_fields = ("translations__name", "event_group__translations__name") inlines = [ OccurrencesInline, ] @@ -237,19 +239,62 @@ def __init__(self, *args, **kwargs): @admin.register(EventGroup) class EventGroupAdmin(TranslatableAdmin): list_display = ( - "name", - "short_description", + "id", + "name_with_fallback", + "short_description_with_fallback", "project", "get_event_count", "published_at", "created_at", "updated_at", ) - + list_display_links = ("id", "name_with_fallback") readonly_fields = ("published_at",) form = EventGroupForm actions = ("publish",) list_filter = ("project", IsPublishedFilter) + search_fields = ("translations__name", "translations__short_description") + + def name_with_fallback(self, obj): + """By default the current active language is used, + but if the browser is using some other locale than what is set as a default + in the Django, then there might be some missing translations, + because the Kukkuu and Kukkuu Admin UI has been empty string to + untranslated fields. This uses the ddefault language ("fi") in cases + when the current active language returns an empty string. + + Args: + obj (EventGroup): EventGroup model instance + + Returns: + string: name in the current active language or in Finnish as a fallback + """ + return obj.safe_translation_getter( + "name", any_language=True + ) or obj.safe_translation_getter("name", language_code=settings.LANGUAGE_CODE) + + name_with_fallback.short_description = _("name") + + def short_description_with_fallback(self, obj): + """By default the current active language is used, + but if the browser is using some other locale than what is set as a default + in the Django, then there might be some missing translations, + because the Kukkuu and Kukkuu Admin UI has been empty string to + untranslated fields. This uses the ddefault language ("fi") in cases + when the current active language returns an empty string. + + Args: + obj (EventGroup): EventGroup model instance + + Returns: + string: short description in the current active language + or in Finnish as a fallback + """ + return obj.safe_translation_getter( + "short_description", any_language=True + ) or obj.safe_translation_getter("name", language_code=settings.LANGUAGE_CODE) + + short_description_with_fallback.short_description = _("short description") def get_event_count(self, obj): return obj.events.count()