Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into FE_Image
  • Loading branch information
saiprabhu-dandanayak committed Feb 5, 2024
2 parents cc06e60 + 0436611 commit d9d64d4
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 8 deletions.
40 changes: 35 additions & 5 deletions .github/workflows/frontendBuild.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build
name: SonarCloud Frontend
on:
push:
branches:
Expand All @@ -8,16 +8,46 @@ on:
- ".github/workflows/frontendBuild.yml"
pull_request:
types: [opened, synchronize, reopened]

jobs:
sonarcloud:
name: SonarCloud
sonarscan:
if: ( startsWith(github.head_ref, 'FE_') && github.event.pull_request.merged == false ) || ( github.event_name == 'push' )
name: FE Sonar Analysis
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
fetch-depth: 0

- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16

- name: Cache node modules
id: cache-nodemodules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
path: ${{ github.workspace }}/frontend/node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}

- name: Install the dependencies
if: steps.cache-nodemodules.outputs.cache-hit != 'true'
run: npm install --legacy-peer-deps

- name: Test and coverage
run: npm run coverage

- name: SonarCloud Scan
with:
projectBaseDir: frontend
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"react-dom": "^18.2.0"
},
"devDependencies": {

"@storybook/addon-essentials": "^7.6.12",
"@storybook/addon-interactions": "^7.6.12",
"@storybook/addon-links": "^7.6.12",
Expand Down
3 changes: 3 additions & 0 deletions frontend/public/assets/images/Vector.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/public/assets/images/eye.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ sonar.sources=./src
sonar.tests=./src
sonar.test.inclusions=**/*.test.ts,**/*.test.tsx
sonar.language=ts
sonar.javascript.lcov.reportPaths=./coverage/lcov.info
sonar.javascript.lcov.reportPaths=./coverage/lcov.info
2 changes: 1 addition & 1 deletion frontend/src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe("App Component", () => {
it("should renders the correct heading", () => {
expect(true).toBe(true);
expect(true).toBe(true);
});
});
35 changes: 35 additions & 0 deletions frontend/src/components/atoms/textfield/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react";
import TextField from "./index";
import { Meta, StoryObj } from "@storybook/react";

export default {
title: "atoms/TextField",
component: TextField,
} as Meta<typeof TextField>;

export const Default: StoryObj<typeof TextField> = {
args: {
placeholder: "Enter your text",
value: "",
onChange: (value: string) => console.log(value),
width: "20%",
height: 40,
size: "medium",
borderRadius: "8px",
},
};

export const Password: StoryObj<typeof TextField> = {
args: {
placeholder: "Enter Password",
value: "",
onChange: (value: string) => console.log(value),
isPassword: true,
width: "20%",
height: 40,
size: "medium",
borderRadius: "8px",
},
};


81 changes: 81 additions & 0 deletions frontend/src/components/atoms/textfield/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { render, fireEvent, screen } from "@testing-library/react";
import CustomTextField from "./index";

describe("CustomTextField", () => {
it("should render with the correct initial value and call onChange handler", () => {
const handleChange = jest.fn();
const { getByPlaceholderText } = render(
<CustomTextField
placeholder="Enter text"
value="Initial value"
onChange={handleChange}
isPassword={false}
/>
);

const input = getByPlaceholderText("Enter text") as HTMLInputElement;
expect(input.value).toBe("Initial value");

fireEvent.change(input, { target: { value: "Updated value" } });
expect(handleChange).toHaveBeenCalledWith("Updated value");
});

it("should handles text change correctly", () => {
let value = "";

const handleChange = (newValue: string) => {
value = newValue;
};

render(
<CustomTextField
placeholder="Enter your text"
value={value}
onChange={handleChange}
isPassword={false}
width="100%"
height={40}
size="medium"
borderRadius="8px"
/>
);

const textField = screen.getByPlaceholderText("Enter your text");
fireEvent.change(textField, { target: { value: "Hello" } });

expect(value).toBe("Hello");
});

it(" should toggles password visibility correctly", () => {
let value = "";

const handleChange = (newValue: string) => {
value = newValue;
};

render(
<CustomTextField
placeholder="Enter your password"
value={value}
onChange={handleChange}
isPassword
width="100%"
height={40}
size="medium"
borderRadius="8px"
/>
);

const textField = screen.getByPlaceholderText("Enter your password");
const toggleButton = screen.getByRole("button");

fireEvent.change(textField, { target: { value: "Secret123" } });
fireEvent.click(toggleButton);

expect(textField.getAttribute("type")).toBe("text");

fireEvent.click(toggleButton);

expect(textField.getAttribute("type")).toBe("password");
});
});
71 changes: 71 additions & 0 deletions frontend/src/components/atoms/textfield/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useState } from 'react';
import { TextField, IconButton, InputAdornment } from '@mui/material';
import EyeOn from "../../../../public/assets/images/eye.svg";
import EyeOff from "../../../../public/assets/images/Vector.svg";
import IconComponent from '../icon';

export interface TextFieldProps {
placeholder?: string;
value: string;
onChange: (value: string) => void;
isPassword: boolean;
width?: string;
height?: string | number;
size?: "small" | "medium";
borderRadius?: string | number;
}

const CustomTextField: React.FC<TextFieldProps> = ({
placeholder,
value,
onChange,
isPassword,
width,
height,
size,
borderRadius,
}) => {
const [showPassword, setShowPassword] = useState(false);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(event.target.value);
};

const handleTogglePasswordVisibility = () => {
setShowPassword((prevShowPassword) => !prevShowPassword);
};

const textFieldStyle = {
width: width ?? "100%",
height: height ?? 40,
borderRadius: borderRadius ?? "8px",
};

return (
<TextField
placeholder={placeholder}
type={isPassword && !showPassword ? "password" : "text"}
value={value}
onChange={handleChange}
fullWidth
margin="normal"
size={size}
InputProps={{
sx: textFieldStyle,
endAdornment: isPassword && (
<InputAdornment position="end">
<IconButton onClick={handleTogglePasswordVisibility} edge="end">
{showPassword ? (
<IconComponent height={"19.41px"} width={"20px"} src={EyeOff} />
) : (
<IconComponent height={"19.41px"} width={"20px"} src={EyeOn} />
)}
</IconButton>
</InputAdornment>
),
}}
/>
);
};

export default CustomTextField;

0 comments on commit d9d64d4

Please sign in to comment.