Skip to content

Commit

Permalink
Merge branch 'nested-routes-for-catalogue-#1218' into improve-route-f…
Browse files Browse the repository at this point in the history
…or-home-page-#1233
  • Loading branch information
joshuadkitenge committed Jan 10, 2025
2 parents 91ceedb + fa821d1 commit 0573cc6
Show file tree
Hide file tree
Showing 20 changed files with 419 additions and 91 deletions.
1 change: 1 addition & 0 deletions .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ VITE_APP_INVENTORY_MANAGEMENT_SYSTEM_BUILD_DIRECTORY=/
# Must be explicitly set to false to ensure it is assigned properly (ensuring msw is excluded)
VITE_APP_INCLUDE_MSW=false
VITE_APP_BUILD_STANDALONE=false
VITE_APP_INCLUDE_CODECOV=false
USE_API_SETTINGS=false
31 changes: 30 additions & 1 deletion .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,43 @@ jobs:
run: yarn lint

- name: Run unit tests
run: yarn test
run: yarn test --reporter=default --reporter=junit --outputFile=test-report.junit.xml

- name: Upload coverage reports to Codecov
if: success()
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}

- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}

bundle_analysis:
name: Bundle Analysis
runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4

- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
with:
node-version: 20
cache: 'yarn'

- name: Install dependencies
run: |
yarn --immutable
- name: Build app for production
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: yarn build

e2e-tests:
name: End-to-End (with mock data) Tests
runs-on: ubuntu-latest
Expand Down
29 changes: 29 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,32 @@ coverage:
target: 75
ignore:
- "inventory-management-system/src/mocks"

# Post comment if there are changes in bundle size of any size
comment:
require_bundle_changes: True

# Post comment if there are changes in bundle size exceeding 1Kb
comment:
require_bundle_changes: True
bundle_change_threshold: "1Kb"

# Post comment if there are changes in bundle size increases more than 1Mb
comment:
require_bundle_changes: "bundle_increase"
bundle_change_threshold: "1Mb"

# Post informational status (never fails) with threshold of 5%
# This is the default configuration
bundle_analysis:
warning_threshold: "5%"
status: "informational"

# Disable commit status
bundle_analysis:
status: False

# Post commit status that will fail if change is larger than threshold of 10MB
bundle_analysis:
warning_threshold: "10MB"
status: True
2 changes: 1 addition & 1 deletion cypress/e2e/with_api/app.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('App', () => {
cy.visit('/catalogue');
cy.wait('@getCatalogueCategoryDataRoot', { timeout: 10000 });
cy.findByText(
'There are no catalogue categories. Please add a category using the button in the top left of your screen'
'There are no catalogue categories. Please add a category using the button in the top left of your screen.'
).should('exist');
});
});
4 changes: 2 additions & 2 deletions cypress/e2e/with_mock_data/catalogueCategories.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ describe('Catalogue Category', () => {
it('category with no data displays no results found', () => {
cy.visit('/catalogue/16');
cy.findByText(
'There are no catalogue categories. Please add a category using the button in the top left of your screen'
'There are no catalogue categories. Please add a category using the button in the top left of your screen.'
).should('exist');
});

Expand All @@ -842,7 +842,7 @@ describe('Catalogue Category', () => {
statusCode: 200,
});
cy.findByText(
'There are no catalogue categories. Please add a category using the button in the top left of your screen'
'There are no catalogue categories. Please add a category using the button in the top left of your screen.'
).should('exist');
});

Expand Down
8 changes: 8 additions & 0 deletions cypress/e2e/with_mock_data/catalogueItems.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ describe('Catalogue Items', () => {
afterEach(() => {
cy.clearMocks();
});

it('should navigate back to the catalogue items table from the landing page using the breadcrumbs', () => {
cy.visit('/catalogue/5/items/89');

cy.findByRole('link', { name: 'Energy Meters' }).click();

cy.findByRole('button', { name: 'Add Catalogue Item' }).should('exist');
});
it('adds a catalogue item', () => {
cy.findByRole('button', { name: 'Add Catalogue Item' }).click();

Expand Down
10 changes: 9 additions & 1 deletion cypress/e2e/with_mock_data/systems.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,10 +578,18 @@ describe('Systems', () => {
});

it('edits a system from a landing page', () => {
Cypress.on('uncaught:exception', (err) => {
if (err.message.includes('ResizeObserver')) {
return false;
}
});
cy.visit('/systems/65328f34a40ff5301575a4e3');

cy.findByRole('button', { name: 'systems page actions menu' }).click();
cy.findByText('Edit').click();
cy.findByRole('menuitem', { name: 'Edit' }).should('exist');
cy.findByRole('menuitem', { name: 'Edit' }).click();

cy.findByRole('dialog', { name: 'Edit System' }).should('exist');

cy.findByLabelText('Name *').clear();
cy.findByLabelText('Name *').type('System name');
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"@types/node": "^22.0.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/uuid": "^10.0.0",
"@uppy/aws-s3": "^4.1.0",
"@uppy/core": "^4.2.2",
"@uppy/dashboard": "^4.1.0",
Expand Down Expand Up @@ -45,7 +44,6 @@
"react-router-dom": "^6.23.1",
"single-spa-react": "6.0.2",
"typescript": "^5.4.5",
"uuid": "^11.0.0",
"vite": "^5.2.12",
"vite-plugin-css-injected-by-js": "^3.5.2",
"zod": "^3.23.8"
Expand Down Expand Up @@ -79,6 +77,7 @@
"packageManager": "[email protected]",
"devDependencies": {
"@babel/eslint-parser": "7.25.9",
"@codecov/vite-plugin": "^1.7.0",
"@eslint/compat": "1.2.4",
"@eslint/js": "9.17.0",
"@tanstack/eslint-plugin-query": "5.62.1",
Expand Down
9 changes: 6 additions & 3 deletions src/admin/units/units.component.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ describe('Units', () => {
it('renders table correctly', async () => {
const view = createView();

await waitFor(() => {
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
});
await waitFor(
() => {
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
},
{ timeout: 10000 }
);

await waitFor(() => {
expect(screen.getByText('megapixels')).toBeInTheDocument();
Expand Down
20 changes: 19 additions & 1 deletion src/catalogue/catalogueLayout.component.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ describe('Catalogue Layout', () => {
expect(view.asFragment()).toMatchSnapshot();
});

it('navigates to catalogue category table view', async () => {
createView('/catalogue/5/items/89', 'catalogueItem');
await waitFor(() => {
expect(
screen.getByRole('link', { name: 'Energy Meters' })
).toBeInTheDocument();
});

const breadcrumb = screen.getByRole('link', {
name: 'Energy Meters',
});

await user.click(breadcrumb);

expect(mockedUseNavigate).toHaveBeenCalledTimes(1);
expect(mockedUseNavigate).toHaveBeenCalledWith('/catalogue/5/items');
});

it('renders a catalogue items page correctly', async () => {
const view = createView('/catalogue/4/items', 'catalogueItems');

Expand Down Expand Up @@ -229,7 +247,7 @@ describe('catalogueLayoutLoader', () => {
).rejects.toThrow('Request failed with status code 404');
});

it('should fetch catalogue category data if catalogue_category_id and catalogue_item_id is provided', async () => {
it('should fetch catalogue category data if catalogue_category_id and catalogue_item_id is provided', async () => {
const params = { catalogue_category_id: '4', catalogue_item_id: '1' };
const output = await catalogueLayoutLoader(queryClient)({
params,
Expand Down
28 changes: 21 additions & 7 deletions src/catalogue/catalogueLayout.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { BreadcrumbsInfo } from '../api/api.types';
import {
getCatalogueCategoryQuery,
useGetCatalogueBreadcrumbs,
useGetCatalogueCategory,
} from '../api/catalogueCategories';
import {
getCatalogueItemQuery,
Expand Down Expand Up @@ -91,6 +92,10 @@ function CatalogueLayout() {
const lastSegmentOfCataloguePath = cataloguePath[cataloguePath.length - 1];

const { data: breadcrumbs } = useGetCatalogueBreadcrumbs(catalogueCategoryId);

const { data: catalogueCategory } =
useGetCatalogueCategory(catalogueCategoryId);

const { data: catalogueItem } = useGetCatalogueItem(catalogueItemId);

const { data: item } = useGetItem(itemId);
Expand All @@ -100,22 +105,31 @@ function CatalogueLayout() {
>(breadcrumbs);
React.useEffect(() => {
if (breadcrumbs) {
const catalogueItemBreadcrumbTrail: BreadcrumbsInfo['trail'] =
breadcrumbs.trail.map((breadcrumb) => {
if (breadcrumb[0] === catalogueCategory?.id) {
return [`${breadcrumb[0]}/items`, breadcrumb[1]];
}
return breadcrumb;
});
setCatalogueBreadcrumbs({
...breadcrumbs,
trail: [
// Catalogue categories
...(lastSegmentOfCataloguePath === catalogueCategoryId
...(lastSegmentOfCataloguePath === catalogueCategory?.id &&
!catalogueCategory?.is_leaf
? [...breadcrumbs.trail]
: []),
// Catalogue items
...(lastSegmentOfCataloguePath === 'items' &&
cataloguePath.length === 4
? [...breadcrumbs.trail]
cataloguePath.length === 4 &&
catalogueCategory?.is_leaf
? [...catalogueItemBreadcrumbTrail]
: []),
// Catalogue item landing page
...((catalogueItem && lastSegmentOfCataloguePath === catalogueItem.id
? [
...breadcrumbs.trail,
...catalogueItemBreadcrumbTrail,
[
`${catalogueItem.catalogue_category_id}/items/${catalogueItem.id}`,
catalogueItem.name,
Expand All @@ -125,7 +139,7 @@ function CatalogueLayout() {
// Items table
...((catalogueItem && lastSegmentOfCataloguePath === 'items'
? [
...breadcrumbs.trail,
...catalogueItemBreadcrumbTrail,
[
`${catalogueItem.catalogue_category_id}/items/${catalogueItem.id}`,
`${catalogueItem.name}`,
Expand All @@ -139,7 +153,7 @@ function CatalogueLayout() {
// Item landing page
...((catalogueItem && item && lastSegmentOfCataloguePath === item.id
? [
...breadcrumbs.trail,
...catalogueItemBreadcrumbTrail,
[
`${catalogueItem.catalogue_category_id}/items/${catalogueItem.id}`,
`${catalogueItem.name}`,
Expand All @@ -161,7 +175,7 @@ function CatalogueLayout() {
}
}, [
breadcrumbs,
catalogueCategoryId,
catalogueCategory,
catalogueItem,
cataloguePath.length,
item,
Expand Down
4 changes: 2 additions & 2 deletions src/catalogue/category/catalogueCardView.component.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe('CardView', () => {
await waitFor(() => {
expect(
screen.getByText(
'There are no catalogue categories. Please add a category using the button in the top left of your screen'
'There are no catalogue categories. Please add a category using the button in the top left of your screen.'
)
).toBeInTheDocument();
});
Expand All @@ -134,7 +134,7 @@ describe('CardView', () => {
await waitFor(() => {
expect(
screen.getByText(
'There are no catalogue categories. Please add a category using the button in the top left of your screen'
'There are no catalogue categories. Please add a category using the button in the top left of your screen.'
)
).toBeInTheDocument();
});
Expand Down
3 changes: 1 addition & 2 deletions src/catalogue/category/catalogueCardView.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ function CatalogueCardView() {
const isLeafNode = parentInfo ? parentInfo.is_leaf : false;

const navigate = useNavigate();

React.useEffect(() => {
// If it's a leaf node, redirect to catalogue items page
if (isLeafNode) {
Expand Down Expand Up @@ -541,7 +540,7 @@ function CatalogueCardView() {
sx={{ marginTop: 2 }}
boldErrorText="No results found"
errorText={
'There are no catalogue categories. Please add a category using the button in the top left of your screen'
'There are no catalogue categories. Please add a category using the button in the top left of your screen.'
}
/>
)}
Expand Down
Loading

0 comments on commit 0573cc6

Please sign in to comment.