Skip to content
Open
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
10 changes: 7 additions & 3 deletions frontend/src/components/FiltersForm/FiltersForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const LoadingSkeleton = () => (
);

export const FiltersForm = () => {
const { setCategories } = useCategories();
const { categories: selectedFilters, setCategories } = useCategories();
const [categoriesData, setCategoriesData] = useState([]);
const [isLoading, setIsLoading] = useState(true);

Expand Down Expand Up @@ -188,8 +188,11 @@ export const FiltersForm = () => {
useEffect(() => {
const fetchCategories = async () => {
setIsLoading(true);
const categoriesData = await httpService.getCategoriesData();
setCategoriesData(categoriesData);
const { categories, defaultChecked } = await httpService.getCategoriesData();
setCategoriesData(categories);
if (Object.keys(defaultChecked).length > 0) {
setCategories(defaultChecked);
}
setIsLoading(false);
};
fetchCategories();
Expand All @@ -208,6 +211,7 @@ export const FiltersForm = () => {
type="checkbox"
id={name}
value={name}
checked={Boolean(selectedFilters[category]?.includes(name))}
/>
<OptionText>{translation}</OptionText>
{tooltipData && (
Expand Down
15 changes: 13 additions & 2 deletions frontend/src/services/http/httpService.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ export const httpService = {
* Fetches complete categories data including subcategories in a single request.
* Uses the /api/categories-full endpoint to avoid waterfall requests.
*
* @returns {Promise<Array>} Promise resolving to array of category data tuples
* @returns {Promise<{categories: Array, defaultChecked: Object}>} Promise resolving to
* the array of category data tuples plus a map of category key to the option values
* that should be pre-checked by default.
*/
getCategoriesData: async () => {
const response = await fetch(CATEGORIES_FULL).then(res => res.json());

// Transform to expected format: [[key, name], options, help?, optionsHelp?]
return response.categories.map(category => {
const categories = response.categories.map(category => {
const categoryTuple = [category.key, category.name];
const options = category.options;

Expand All @@ -67,6 +69,15 @@ export const httpService = {
}
return [categoryTuple, options];
});

const defaultChecked = {};
for (const category of response.categories) {
if (category.default_checked?.length) {
defaultChecked[category.key] = category.default_checked;
}
}

return { categories, defaultChecked };
},

/**
Expand Down
28 changes: 27 additions & 1 deletion frontend/tests/FiltersForm.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const categories = [
],
];

httpService.getCategoriesData.mockResolvedValue(categories);
httpService.getCategoriesData.mockResolvedValue({ categories, defaultChecked: {} });

describe('Creates good filter_form box', () => {
beforeAll(() => {
Expand Down Expand Up @@ -90,3 +90,29 @@ describe('Creates good filter_form box', () => {
expect(queryByLabelText(/Help: Inaczej rodzaje/i)).toBeInTheDocument();
});
});

describe('Pre-checks options configured as default-checked', () => {
beforeEach(() => {
httpService.getCategoriesData.mockResolvedValueOnce({
categories,
defaultChecked: { types: ['shoes'] },
});
return act(() =>
render(
<CategoriesProvider>
<FiltersForm />
</CategoriesProvider>,
),
);
});

it('renders the default-checked option as checked', () => {
const shoesCheckbox = document.querySelector('#shoes');
expect(shoesCheckbox.checked).toBe(true);
});

it('leaves options not listed as default-checked unchecked', () => {
const clothesCheckbox = document.querySelector('#clothes');
expect(clothesCheckbox.checked).toBe(false);
});
});
2 changes: 2 additions & 0 deletions goodmap/core_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,12 +440,14 @@ def get_categories_full():
result = []

categories_options_help = categories_data.get("categories_options_help", {})
categories_default_checked = categories_data.get("categories_default_checked", {})

for key, options in categories_data["categories"].items():
category_entry = {
"key": key,
"name": gettext(key),
"options": make_tuple_translation(options),
"default_checked": categories_default_checked.get(key, []),
}

if CategoriesHelp in feature_flags:
Expand Down
27 changes: 26 additions & 1 deletion goodmap/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,11 +608,17 @@ def json_db_get_category_data(self, category_type=None):
"categories_options_help": {
category_type: self.data.get("categories_options_help", {}).get(category_type, [])
},
"categories_default_checked": {
category_type: self.data.get("categories_default_checked", {}).get(
category_type, []
)
},
}
return {
"categories": self.data["categories"],
"categories_help": self.data.get("categories_help", []),
"categories_options_help": self.data.get("categories_options_help", {}),
"categories_default_checked": self.data.get("categories_default_checked", {}),
}


Expand All @@ -627,11 +633,15 @@ def json_file_db_get_category_data(self, category_type=None):
"categories_options_help": {
category_type: data.get("categories_options_help", {}).get(category_type, [])
},
"categories_default_checked": {
category_type: data.get("categories_default_checked", {}).get(category_type, [])
},
}
return {
"categories": data["categories"],
"categories_help": data.get("categories_help", []),
"categories_options_help": data.get("categories_options_help", {}),
"categories_default_checked": data.get("categories_default_checked", {}),
}


Expand All @@ -645,11 +655,15 @@ def google_json_db_get_category_data(self, category_type=None):
"categories_options_help": {
category_type: data.get("categories_options_help", {}).get(category_type, [])
},
"categories_default_checked": {
category_type: data.get("categories_default_checked", {}).get(category_type, [])
},
}
return {
"categories": data.get("categories", {}),
"categories_help": data.get("categories_help", []),
"categories_options_help": data.get("categories_options_help", {}),
"categories_default_checked": data.get("categories_default_checked", {}),
}


Expand All @@ -668,13 +682,24 @@ def mongodb_db_get_category_data(self, category_type=None):
category_type, []
)
},
"categories_default_checked": {
category_type: config_doc.get("categories_default_checked", {}).get(
category_type, []
)
},
}
return {
"categories": config_doc.get("categories", {}),
"categories_help": config_doc.get("categories_help", []),
"categories_options_help": config_doc.get("categories_options_help", {}),
"categories_default_checked": config_doc.get("categories_default_checked", {}),
}
return {"categories": {}, "categories_help": [], "categories_options_help": {}}
return {
"categories": {},
"categories_help": [],
"categories_options_help": {},
"categories_default_checked": {},
}


def get_category_data(db):
Expand Down
36 changes: 36 additions & 0 deletions tests/unit_tests/test_core_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,42 @@ def test_categories_full_endpoint(test_app):
assert category["options"][0] == ["test", "test-translated"]
assert category["options"][1] == ["test2", "test2-translated"]

# No default-checked options configured for this category
assert category["default_checked"] == []


@mock.patch("goodmap.core_api.gettext", fake_translation)
def test_categories_full_endpoint_with_default_checked():
test_app = create_test_app(
db_overrides={
"categories": {"test-category": ["opt1", "opt2"]},
"categories_default_checked": {"test-category": ["opt1"]},
}
)
response = test_app.get("/api/categories-full")
assert response.status_code == 200
data = response.json
assert data is not None

category = data["categories"][0]
assert category["default_checked"] == ["opt1"]


@mock.patch("goodmap.core_api.gettext", fake_translation)
def test_categories_full_endpoint_without_default_checked():
test_app = create_test_app(
db_overrides={
"categories": {"test-category": ["opt1", "opt2"]},
}
)
response = test_app.get("/api/categories-full")
assert response.status_code == 200
data = response.json
assert data is not None

category = data["categories"][0]
assert category["default_checked"] == []


@mock.patch("goodmap.core_api.gettext", fake_translation)
def test_categories_full_endpoint_with_multiple_categories():
Expand Down
19 changes: 18 additions & 1 deletion tests/unit_tests/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"location_obligatory_fields": [["name", "str"]],
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
data_json = json.dumps({"map": data})

Expand Down Expand Up @@ -1422,6 +1423,7 @@ def test_json_db_get_category_data():
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1434,6 +1436,7 @@ def test_json_db_get_category_data_specific_category():
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1449,6 +1452,7 @@ def test_json_file_db_get_category_data(tmp_path):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1464,6 +1468,7 @@ def test_json_file_db_get_category_data_specific_category(tmp_path):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1480,6 +1485,7 @@ def test_google_json_db_get_category_data(mock_cli):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1496,6 +1502,7 @@ def test_google_json_db_get_category_data_specific_category(mock_cli):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1509,6 +1516,7 @@ def test_mongodb_db_get_category_data(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}

db = MongoDB("mongodb://localhost:27017", "test_db")
Expand All @@ -1518,6 +1526,7 @@ def test_mongodb_db_get_category_data(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1531,6 +1540,7 @@ def test_mongodb_db_get_category_data_specific_category(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}

db = MongoDB("mongodb://localhost:27017", "test_db")
Expand All @@ -1540,6 +1550,7 @@ def test_mongodb_db_get_category_data_specific_category(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand All @@ -1553,7 +1564,12 @@ def test_mongodb_db_get_category_data_no_config(mock_client):
db = MongoDB("mongodb://localhost:27017", "test_db")
extend_db_with_goodmap_queries(db, LocationBase)
category_data = mongodb_db_get_category_data(db)
expected = {"categories": {}, "categories_help": [], "categories_options_help": {}}
expected = {
"categories": {},
"categories_help": [],
"categories_options_help": {},
"categories_default_checked": {},
}
assert category_data == expected


Expand All @@ -1565,6 +1581,7 @@ def test_get_category_data():
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
"categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected

Expand Down
Loading