diff --git a/backend/docker/mount/dumps/testing-dump-big.dump b/backend/docker/mount/dumps/testing-dump-big.dump new file mode 100644 index 00000000..278580a4 Binary files /dev/null and b/backend/docker/mount/dumps/testing-dump-big.dump differ diff --git a/backend/src/config/neo4j/KmapNeo4jModule.ts b/backend/src/config/neo4j/KmapNeo4jModule.ts index 4e46343b..99bb3f57 100644 --- a/backend/src/config/neo4j/KmapNeo4jModule.ts +++ b/backend/src/config/neo4j/KmapNeo4jModule.ts @@ -10,7 +10,7 @@ import { createNeo4jDriver } from './createNeo4jDriver'; */ export class KmapNeo4jModule { /** - * Overrides the driver factory from the {@link Neo4jModule} so additional + * Overrides the driver factory from the {@link Neo4jModule} so * additional {@link Neo4jDriverOptions} are possible. * @private */ diff --git a/backend/tests/e2e/app.service.e2e.spec.ts b/backend/tests/e2e/app.service.e2e.spec.ts index 2c4ffc56..76a2d0c4 100644 --- a/backend/tests/e2e/app.service.e2e.spec.ts +++ b/backend/tests/e2e/app.service.e2e.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { Neo4jService } from 'nest-neo4j/dist'; -import { AppModule } from '../../src/app.module'; +import { ConfigModule } from '@nestjs/config'; import { AppService } from '../../src/app.service'; import { Node, Edge } from '../../src/shared/entities'; import { @@ -9,7 +9,7 @@ import { queryAllDummies, queryAllNoLimitDummies, } from '../fixtures/testingDumpData'; -import { CountQueryResult, QueryResult } from '../../src/shared/queries'; +import { QueryResult } from '../../src/shared/queries'; import { KmapNeo4jModule } from '../../src/config/neo4j/KmapNeo4jModule'; describe('AppService (e2e)', () => { @@ -19,7 +19,14 @@ describe('AppService (e2e)', () => { beforeAll(async () => { // Global setup const mockAppModule: TestingModule = await Test.createTestingModule({ - imports: [AppModule, KmapNeo4jModule], + imports: [ + ConfigModule.forRoot({ + envFilePath: '.env.test', + }), + KmapNeo4jModule.fromEnv({ + disableLosslessIntegers: true, + }), + ], providers: [AppService], }).compile(); @@ -57,6 +64,24 @@ describe('AppService (e2e)', () => { expect(actualResult).toEqual(expectedResult); }); + describe('Method queryAll for no limit', () => { + it('should return expected node length for no limit', async () => { + // Act + const actualResult: QueryResult = await appService.queryAll(); + + // Assert + expect(actualResult.nodes.length).toEqual(4); + }); + + it('should return expected edge length for no limit', async () => { + // Act + const actualResult: QueryResult = await appService.queryAll(); + + // Assert + expect(actualResult.edges.length).toEqual(3); + }); + }); + it('should return no nodes when called with nodes limited to 0', async () => { // Arrange const result = await appService.queryAll({ limits: { nodes: 0 } }); @@ -103,20 +128,4 @@ describe('AppService (e2e)', () => { expect(actualEdges).toEqual(expectedEdges); }); }); - - describe('Method getNumberOfEntities', () => { - it('should return the correct number of nodes and edges', async () => { - // Arrange - const expected: CountQueryResult = { - nodes: 4, - edges: 3, - }; - - // Act - const actual = await appService.getNumberOfEntities(); - - // Assert - expect(actual).toEqual(expected); - }); - }); }); diff --git a/backend/tests/e2e/filter/filter.service.e2e.spec.ts b/backend/tests/e2e/filter/filter.service.e2e.spec.ts index 331c254b..eba970f0 100644 --- a/backend/tests/e2e/filter/filter.service.e2e.spec.ts +++ b/backend/tests/e2e/filter/filter.service.e2e.spec.ts @@ -1,8 +1,8 @@ import { Test, TestingModule } from '@nestjs/testing'; import { Neo4jService } from 'nest-neo4j/dist'; +import { ConfigModule } from '@nestjs/config'; import { FilterService } from '../../../src/filter/filter.service'; import { KmapNeo4jModule } from '../../../src/config/neo4j/KmapNeo4jModule'; -import { AppModule } from '../../../src/app.module'; import { getEdgeTypeFilterModelResult, getNodeTypeFilterModelResult, @@ -23,8 +23,15 @@ describe('FilterService', () => { // Global Setup beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ - imports: [AppModule, KmapNeo4jModule], - providers: [], + imports: [ + ConfigModule.forRoot({ + envFilePath: '.env.test', + }), + KmapNeo4jModule.fromEnv({ + disableLosslessIntegers: true, + }), + ], + providers: [FilterService], }).compile(); service = module.get(FilterService); diff --git a/backend/tests/e2e/schema/schema.service.e2e.spec.ts b/backend/tests/e2e/schema/schema.service.e2e.spec.ts index 3fced1b8..f34f4177 100644 --- a/backend/tests/e2e/schema/schema.service.e2e.spec.ts +++ b/backend/tests/e2e/schema/schema.service.e2e.spec.ts @@ -1,8 +1,8 @@ import { Test, TestingModule } from '@nestjs/testing'; import { Neo4jService } from 'nest-neo4j/dist'; +import { ConfigModule } from '@nestjs/config'; import { SchemaService } from '../../../src/schema/schema.service'; import { KmapNeo4jModule } from '../../../src/config/neo4j/KmapNeo4jModule'; -import { AppModule } from '../../../src/app.module'; import { edgeInfo, nodeInfo } from '../../fixtures/nodeInfo/GraphInfoDb'; /* @@ -16,8 +16,15 @@ describe('SchemaService', () => { // Global Setup beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ - imports: [AppModule, KmapNeo4jModule], - providers: [], + imports: [ + ConfigModule.forRoot({ + envFilePath: '.env.test', + }), + KmapNeo4jModule.fromEnv({ + disableLosslessIntegers: true, + }), + ], + providers: [SchemaService], }).compile(); service = module.get(SchemaService); diff --git a/backend/tests/e2e/search/search.service.e2e.spec.ts b/backend/tests/e2e/search/search.service.e2e.spec.ts index 4fc301d8..8f6f094a 100644 --- a/backend/tests/e2e/search/search.service.e2e.spec.ts +++ b/backend/tests/e2e/search/search.service.e2e.spec.ts @@ -1,8 +1,8 @@ import { Test, TestingModule } from '@nestjs/testing'; import { Neo4jService } from 'nest-neo4j/dist'; +import { ConfigModule } from '@nestjs/config'; import { SearchService } from '../../../src/search/search.service'; import { KmapNeo4jModule } from '../../../src/config/neo4j/KmapNeo4jModule'; -import { AppModule } from '../../../src/app.module'; describe('SearchService', () => { let service: SearchService; @@ -11,7 +11,14 @@ describe('SearchService', () => { // Global Setup beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ - imports: [AppModule, KmapNeo4jModule], + imports: [ + ConfigModule.forRoot({ + envFilePath: '.env.test', + }), + KmapNeo4jModule.fromEnv({ + disableLosslessIntegers: true, + }), + ], providers: [SearchService], }).compile(); diff --git a/frontend/README.md b/frontend/README.md index 73e8c937..429f85d8 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -20,10 +20,11 @@ Open [http://localhost:3000](http://localhost:3000) to view it in the browser. The page will reload if you make edits.\ You will also see any lint errors in the console. -### `yarn test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. +## Testing +1. start react with `yarn run start:forTests` in package.json. +2. open cypress with `yarn run cy:open:e2e` or `yarn run cy:run:e2e`. +3. if `yarn run cy:open:e2e` was used, start all tests manually. +4. print testing-coverage with `yarn run coverage:print`. ### `yarn run build` diff --git a/frontend/cypress/.eslintrc.json b/frontend/cypress/.eslintrc.json index 72a4b571..b3f23ee6 100644 --- a/frontend/cypress/.eslintrc.json +++ b/frontend/cypress/.eslintrc.json @@ -7,7 +7,8 @@ "cypress/no-force": "warn", "cypress/no-async-tests": "error", "import/prefer-default-export": 0, - "class-methods-use-this": "off" + "class-methods-use-this": "off", + "import/extensions": "off" }, "env": { "cypress/globals": true diff --git a/frontend/cypress/integration/visualization/filter.e2e.js b/frontend/cypress/integration/visualization/filter.e2e.js index e6eb4f47..7a1acee0 100644 --- a/frontend/cypress/integration/visualization/filter.e2e.js +++ b/frontend/cypress/integration/visualization/filter.e2e.js @@ -1,3 +1,5 @@ +import '../../support/index.js'; + context('Filter', () => { // Global setup beforeEach(() => { @@ -31,7 +33,7 @@ context('Filter', () => { cy.contains('name'); }); - it('Shows expected property-values', () => { + it('shows expected property-values', () => { // Act cy.get('.Filter').click(); cy.get('.FilterButton:first').click(); @@ -44,17 +46,29 @@ context('Filter', () => { cy.contains('Lana Wachowski'); }); - it('constructs correct filterQuery', () => { + it('selects no property values', () => { + // Act + cy.get('.Filter').click(); + cy.get('.FilterButton:first').click(); + cy.get('.FilterDialog'); + + // eslint-disable-next-line cypress/no-force + cy.get('.ApplyFilter').focus().click({ force: true }); + + cy.get('.AddButton:first').click(); + }); + + it('applies filter', () => { // Act cy.get('.Filter').click(); cy.get('.FilterButton:first').click(); cy.get('.FilterDialog'); cy.get('.FilterSelect:last').click(); - // Assert cy.contains('Keanu Reeves').click(); cy.contains('Carrie-Anne Moss').click(); cy.contains('Lana Wachowski').click(); + // eslint-disable-next-line cypress/no-force cy.get('.ApplyFilter').focus().click({ force: true }); }); @@ -79,7 +93,7 @@ context('Filter', () => { }); context('Edges', () => { - it('Shows expected property-names', () => { + it('shows expected property-names', () => { // Act cy.get('.Filter').click(); cy.contains('Edge Types').click(); @@ -102,7 +116,7 @@ context('Filter', () => { cy.contains('Error: No string').click(); }); - it('constructs correct filterQuery', () => { + it('applies filter', () => { // Act cy.get('.Filter').click(); cy.get('.EdgeTypes').click(); @@ -116,7 +130,7 @@ context('Filter', () => { cy.get('.ApplyFilter').focus().click({ force: true }); }); - it('constructs correct filterQuery', () => { + it('adds edges to view', () => { // Act cy.get('.Filter').click(); cy.get('.EdgeTypes').click(); diff --git a/frontend/cypress/integration/visualization/tabs.e2e.js b/frontend/cypress/integration/visualization/tabs.e2e.js index e620de73..2acff40b 100644 --- a/frontend/cypress/integration/visualization/tabs.e2e.js +++ b/frontend/cypress/integration/visualization/tabs.e2e.js @@ -1,5 +1,6 @@ +import { apiBaseUrl } from '../../support/constants'; + context('Visualization Tabs', () => { - const apiBaseUrl = 'http://localhost:8080/api'; // Global setup beforeEach(() => { cy.visit('http://localhost:3000/visualization'); diff --git a/frontend/cypress/support/commands.js b/frontend/cypress/support/commands.js index 119ab03f..545cc244 100644 --- a/frontend/cypress/support/commands.js +++ b/frontend/cypress/support/commands.js @@ -23,3 +23,12 @@ // // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) + +import { apiBaseUrl } from './constants'; + +Cypress.Commands.add('switchBackendPort', (port) => { + cy.intercept({ url: `${apiBaseUrl}/**`, middleware: true }, (req) => { + req.url = `http://localhost:${port}${req.url.slice(21)}`; + req.continue(); + }); +}); diff --git a/frontend/cypress/support/constants.js b/frontend/cypress/support/constants.js new file mode 100644 index 00000000..1ee3343f --- /dev/null +++ b/frontend/cypress/support/constants.js @@ -0,0 +1,2 @@ +export const apiBaseUrl = + Cypress.env('apiBaseUrl') ?? 'http:localhost:8080/api'; diff --git a/frontend/src/visualization/filtering/components/dialog/EntityFilterDialog.tsx b/frontend/src/visualization/filtering/components/dialog/EntityFilterDialog.tsx index 7b65969d..098a9ca0 100644 --- a/frontend/src/visualization/filtering/components/dialog/EntityFilterDialog.tsx +++ b/frontend/src/visualization/filtering/components/dialog/EntityFilterDialog.tsx @@ -86,7 +86,6 @@ const EntityFilterDialog = (props: { } } - /* istanbul ignore else */ if (filterConditions.length > 0) { setFilterQuery(MatchAllCondition(...filterConditions)); } else { diff --git a/frontend/src/visualization/shared-ops/fetchDataFromService.tsx b/frontend/src/visualization/shared-ops/fetchDataFromService.tsx index 7e80344b..36bba8dc 100644 --- a/frontend/src/visualization/shared-ops/fetchDataFromService.tsx +++ b/frontend/src/visualization/shared-ops/fetchDataFromService.tsx @@ -140,6 +140,7 @@ function fetchDataFromService( } }) .catch((err) => { + /* istanbul ignore if */ if (mounted) { setError(err); setIsLoading(false);