+
Search Result From Mongo:
-
diff --git a/client/simple-web-site/src/theme.scss b/client/simple-web-site/src/material-theme.scss
similarity index 100%
rename from client/simple-web-site/src/theme.scss
rename to client/simple-web-site/src/material-theme.scss
diff --git a/client/simple-web-site/src/styles.scss b/client/simple-web-site/src/styles.scss
index d79ee83..8595cd2 100644
--- a/client/simple-web-site/src/styles.scss
+++ b/client/simple-web-site/src/styles.scss
@@ -1,14 +1,15 @@
+@import "material-theme";
+@import 'color';
+
@tailwind base;
@tailwind components;
@tailwind utilities;
-@import 'color';
-
html,
body {
margin: 0;
}
.active {
- background: $my-blue;
+ background: $my-blue !important;
}
diff --git a/tailwind.config.js b/client/tailwind.config.js
similarity index 75%
rename from tailwind.config.js
rename to client/tailwind.config.js
index e3995d2..e950098 100644
--- a/tailwind.config.js
+++ b/client/tailwind.config.js
@@ -1,6 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
- content: ['client/simple-web-site/src/**/*.{html,ts}'],
+ content: ['./**/*.{html,ts,js}'],
theme: {
extend: {
screens: {
@@ -15,5 +15,5 @@ module.exports = {
},
},
plugins: [],
- important: true,
+ important: false,
};
diff --git a/package-lock.json b/package-lock.json
index 732b9a1..09d9f76 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -114,7 +114,7 @@
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"standard-version": "^9.5.0",
- "tailwindcss": "^3.4.16",
+ "tailwindcss": "^3.4.17",
"three": "^0.165.0",
"tslib": "^2.3.0",
"typescript": "~5.5.4",
diff --git a/package.json b/package.json
index c1a209d..99e731a 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
"test:playwright": "npx playwright test"
},
"lint-staged": {
- "*.{js,ts,css,scss,html,md}": [
+ "{client,server}*.{js,ts,css,scss,html,md}": [
"eslint --fix"
]
},
@@ -121,7 +121,6 @@
"ajv": "^8.12.0",
"allure-commandline": "^2.29.0",
"allure-playwright": "^3.0.0-beta.5",
- "autoprefixer": "^10.4.20",
"commitizen": "^4.3.0",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
@@ -143,12 +142,13 @@
"lint-staged": "^15.2.10",
"mongoose": "^8.9.2",
"nyc": "^15.1.0",
- "postcss": "^8.4.49",
"prettier": "^3.4.2",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"standard-version": "^9.5.0",
- "tailwindcss": "^3.4.16",
+ "tailwindcss": "^3.4.17",
+ "postcss": "^8.4.49",
+ "autoprefixer": "^10.4.20",
"three": "^0.165.0",
"tslib": "^2.3.0",
"typescript": "~5.5.4",
diff --git a/server/.env b/server/.env
index bcb484a..d000bff 100644
--- a/server/.env
+++ b/server/.env
@@ -2,3 +2,4 @@ ENV_NAME=development
DATABASE_PROTOCOL=mongodb://
DATABASE_HOST=localhost:27017/
DATABASE_NAME=test
+PORT=3000
diff --git a/server/.env.production b/server/.env.production
index 2d92bea..065edfa 100644
--- a/server/.env.production
+++ b/server/.env.production
@@ -2,3 +2,4 @@ ENV_NAME=production
DATABASE_PROTOCOL=mongodb://
DATABASE_HOST=localhost:27017/
DATABASE_NAME=test
+PORT=3001
diff --git a/server/nest-cli.json b/server/nest-cli.json
index f57d4b6..6ba8b7d 100644
--- a/server/nest-cli.json
+++ b/server/nest-cli.json
@@ -9,6 +9,10 @@
"include": "../.env.production",
"outDir": "../build/.env"
},
+ {
+ "include": "./assets/*",
+ "outDir": "../build"
+ },
{
"include": "../package.json",
"outDir": "../build/package.json"
diff --git a/server/src/app.module.ts b/server/src/app.module.ts
index 5c0a51a..0964ffc 100644
--- a/server/src/app.module.ts
+++ b/server/src/app.module.ts
@@ -8,6 +8,7 @@ import * as Joi from 'joi';
import { AppController } from 'src/app.controller';
import { AppService } from 'src/app.service';
+import { EsService } from 'src/es/es.service';
import { HeroesModule } from 'src/heroes/heroes.module';
const ENV = process.env.NODE_ENV;
@@ -53,6 +54,6 @@ const ENV = process.env.NODE_ENV;
HeroesModule,
],
controllers: [AppController],
- providers: [AppService],
+ providers: [AppService, EsService],
})
export class AppModule {}
diff --git a/server/src/assets/heroes.json b/server/src/assets/heroes.json
new file mode 100644
index 0000000..0e69f34
--- /dev/null
+++ b/server/src/assets/heroes.json
@@ -0,0 +1,50 @@
+[
+ {
+ "squadName": "Super hero squad",
+ "homeTown": "Metro City",
+ "formed": 2016,
+ "secretBase": "Super tower",
+ "active": true,
+ "members": [
+ {
+ "name": "Molecule Man",
+ "age": 29,
+ "secretIdentity": "Dan Jukes",
+ "powers": [
+ "Radiation resistance",
+ "Turning tiny",
+ "Radiation blast"
+ ]
+ },
+ {
+ "name": "Madame Uppercut",
+ "age": 39,
+ "secretIdentity": "Jane Wilson",
+ "powers": [
+ "Million tonne punch",
+ "Damage resistance",
+ "Superhuman reflexes"
+ ]
+ },
+ {
+ "name": "Eternal Flame",
+ "age": 1000000,
+ "secretIdentity": "Unknown",
+ "powers": [
+ "Immortality",
+ "Heat Immunity",
+ "Inferno",
+ "Teleportation",
+ "Interdimensional travel"
+ ]
+ }
+ ]
+ },
+ {
+ "squadName": "Lonely Super hero",
+ "homeTown": "Lonely City",
+ "formed": 2025,
+ "secretBase": "Lonely tower",
+ "active": false
+ }
+]
diff --git a/server/src/assets/test.json b/server/src/assets/test.json
new file mode 100644
index 0000000..0cfd648
--- /dev/null
+++ b/server/src/assets/test.json
@@ -0,0 +1,3 @@
+{
+ "description": "this file is for testing nestJS build process, which should output this file to build/assets folder"
+}
diff --git a/server/src/es/es.service.ts b/server/src/es/es.service.ts
new file mode 100644
index 0000000..89cb371
--- /dev/null
+++ b/server/src/es/es.service.ts
@@ -0,0 +1,57 @@
+import { Client } from '@elastic/elasticsearch';
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+export class EsService {
+ client = new Client({
+ node: 'http://localhost:9200',
+ });
+
+ constructor() {}
+
+ async deleteHeroIndex(indexName: string) {
+ try {
+ const response = await this.client.indices.delete({
+ index: indexName,
+ });
+ if (response.acknowledged) {
+ console.log(`Index ${indexName} deleted successfully.`);
+ } else {
+ console.error(`Failed to delete index ${indexName}.`);
+ }
+ } catch (error) {
+ console.error(`Error deleting index ${indexName}:`, error);
+ }
+ }
+
+ async createHeroIndex(indexName: string) {
+ try {
+ const exists = await this.client.indices.exists({ index: indexName });
+ if (!exists) {
+ await this.client.indices.create({
+ index: indexName,
+ });
+ console.log(`Index '${indexName}' created successfully.`);
+ } else {
+ console.log(`Index '${indexName}' already exists.`);
+ }
+ } catch (err) {
+ console.error('Error creating index:', err);
+ }
+ }
+
+ async injectData(indexName: string, data: any[]) {
+ const body = data.flatMap((doc) => [{ index: { _index: indexName } }, doc]);
+
+ const response = await this.client.bulk({
+ refresh: true,
+ body,
+ });
+
+ if (response.errors) {
+ console.error('Errors occurred during indexing:', response.errors);
+ } else {
+ console.log(`Successfully indexed ${data.length} documents.`);
+ }
+ }
+}
diff --git a/server/src/main.ts b/server/src/main.ts
index c999c15..f8b0540 100644
--- a/server/src/main.ts
+++ b/server/src/main.ts
@@ -1,8 +1,12 @@
+import * as fs from 'fs';
+import * as path from 'path';
+
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import * as cookieParser from 'cookie-parser';
import { AppModule } from 'src/app.module';
+import { EsService } from 'src/es/es.service';
import { MyLogger } from 'src/myLogger';
async function bootstrap() {
@@ -12,6 +16,13 @@ async function bootstrap() {
app.enableCors();
app.use(cookieParser());
+ const esService = app.get(EsService);
+ await esService.deleteHeroIndex('heroes');
+ await esService.createHeroIndex('heroes');
+ const filePath = path.join(__dirname, 'assets/heroes.json');
+ const data = fs.readFileSync(filePath, 'utf-8');
+ await esService.injectData('heroes', JSON.parse(data));
+
const config = new DocumentBuilder()
.setTitle('Simple Web Site OpenAPI')
.setDescription('The API description')
diff --git a/test/heroes.json b/test/heroes.json
index 510983b..520b885 100644
--- a/test/heroes.json
+++ b/test/heroes.json
@@ -1,50 +1,56 @@
[
{
- "squadName": "Super hero squad",
- "homeTown": "Metro City",
- "formed": 2016,
- "secretBase": "Super tower",
- "active": true,
- "members": [
- {
- "name": "Molecule Man",
- "age": 29,
- "secretIdentity": "Dan Jukes",
- "powers": [
- "Radiation resistance",
- "Turning tiny",
- "Radiation blast"
- ]
+ "_id": {
+ "$oid": "676f1540126a297f0007405e"
},
- {
- "name": "Madame Uppercut",
- "age": 39,
- "secretIdentity": "Jane Wilson",
- "powers": [
- "Million tonne punch",
- "Damage resistance",
- "Superhuman reflexes"
- ]
- },
- {
- "name": "Eternal Flame",
- "age": 1000000,
- "secretIdentity": "Unknown",
- "powers": [
- "Immortality",
- "Heat Immunity",
- "Inferno",
- "Teleportation",
- "Interdimensional travel"
- ]
- }
- ]
-},
+ "squadName": "Super hero squad",
+ "homeTown": "Metro City",
+ "formed": 2016,
+ "secretBase": "Super tower",
+ "active": true,
+ "members": [
+ {
+ "name": "Molecule Man",
+ "age": 29,
+ "secretIdentity": "Dan Jukes",
+ "powers": [
+ "Radiation resistance",
+ "Turning tiny",
+ "Radiation blast"
+ ]
+ },
+ {
+ "name": "Madame Uppercut",
+ "age": 39,
+ "secretIdentity": "Jane Wilson",
+ "powers": [
+ "Million tonne punch",
+ "Damage resistance",
+ "Superhuman reflexes"
+ ]
+ },
+ {
+ "name": "Eternal Flame",
+ "age": 1000000,
+ "secretIdentity": "Unknown",
+ "powers": [
+ "Immortality",
+ "Heat Immunity",
+ "Inferno",
+ "Teleportation",
+ "Interdimensional travel"
+ ]
+ }
+ ]
+ },
{
- "squadName": "Lonely Super hero",
- "homeTown": "Lonely City",
- "formed": 2025,
- "secretBase": "Lonely tower",
- "active": false
-}
+ "_id": {
+ "$oid": "676f1540126a297f0007405f"
+ },
+ "squadName": "Lonely Super hero",
+ "homeTown": "Lonely City",
+ "formed": 2025,
+ "secretBase": "Lonely tower",
+ "active": false
+ }
]
diff --git a/test/src/search-page.spec.ts b/test/src/search-page.spec.ts
index 132ea2a..953d85e 100644
--- a/test/src/search-page.spec.ts
+++ b/test/src/search-page.spec.ts
@@ -1,4 +1,4 @@
-import { expect } from '@playwright/test';
+import {expect} from '@playwright/test';
import test from 'test/fixtures/baseTest';
test.describe('Click search link', async () => {
@@ -8,13 +8,19 @@ test.describe('Click search link', async () => {
await expect(page).toHaveTitle(`Search`);
});
test('es result', async ({page}) => {
- await expect(page.getByTestId('esResult')).toContainText(
+ const appHero = page.getByTestId('esResult').locator('app-hero');
+ await expect(appHero.first()).toContainText(
'Radiation resistance,Turning tiny,Radiation blast'
);
+ await expect(appHero.nth(1)).toContainText('Lonely Super hero'
+ );
});
test('mongo result', async ({page}) => {
- await expect(page.getByTestId('mongoResult')).toContainText(
- 'Radiation resistance,Turning tiny,Radiation blast'
+ const appHero = page.getByTestId('mongoResult').locator('app-hero');
+ await expect(appHero.first()).toContainText(
+ 'Lonely Super hero'
+ );
+ await expect(appHero.nth(1)).toContainText('Radiation resistance,Turning tiny,Radiation blast'
);
});
});