Skip to content

Commit

Permalink
Fixed sonar and refactor code (#15)
Browse files Browse the repository at this point in the history
Added testcases for UI
  • Loading branch information
Kuldeep-knoldus authored Jul 1, 2024
1 parent 95d3c0e commit b18f665
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 28 deletions.
1 change: 1 addition & 0 deletions blogs-analyzer-ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ testem.log
Thumbs.db
package-lock.json
.editorconfig
.scannerwork
2 changes: 1 addition & 1 deletion blogs-analyzer-ui/sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ sonar.host.url=https://sonarcloud.io
sonar.organization=nashtech
sonar.projectKey=blogs-analyzer-ui
sonar.projectName=blogs-analyzer-ui
sonar.exclusions=**/node_modules/**,**/*.html,**/*.scss,**/*.spec.ts,**/*.css,**/models/**,**/assets/**
sonar.exclusions=**/node_modules/**,**/*.html,**/*.scss,**/*.spec.ts,**/*.css,**/models/**,**/assets/**,**/environments/**
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.token=013631d793a41fe3c4b7d4fefb99224b542318c7
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,76 @@ import { RouterTestingModule } from "@angular/router/testing";
import { HttpClientModule } from "@angular/common/http";
import { MatCardModule } from "@angular/material/card";
import { NO_ERRORS_SCHEMA } from "@angular/core";
import { BlogService } from "../../../services/blog.service";
import { Router } from "@angular/router";
import { of } from "rxjs";

describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
let blogService: jasmine.SpyObj<BlogService>;
let router: jasmine.SpyObj<Router>;

beforeEach(() => {
const blogServiceSpy = jasmine.createSpyObj('BlogService', ['searchPostsByTitle', 'getPostById', 'getPostByAuthorId']);
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);

TestBed.configureTestingModule({
declarations: [HomeComponent],
imports: [RouterTestingModule, HttpClientModule, MatCardModule],
providers: [
{ provide: BlogService, useValue: blogServiceSpy },
{ provide: Router, useValue: routerSpy }
],
schemas: [NO_ERRORS_SCHEMA]
});

fixture = TestBed.createComponent(HomeComponent);
component = fixture.componentInstance;
blogService = TestBed.inject(BlogService) as jasmine.SpyObj<BlogService>;
router = TestBed.inject(Router) as jasmine.SpyObj<Router>;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should call searchPostsByTitle and navigate on searchByTitle', () => {
const mockData = [{ id: 1, title: 'Test Post' }];
blogService.searchPostsByTitle.and.returnValue(of(mockData));

component.searchTitle = 'Test';
component.searchByTitle();

expect(blogService.searchPostsByTitle).toHaveBeenCalledWith('Test');
expect(router.navigate).toHaveBeenCalledWith(['/quality-check'], { state: { data: mockData } });
});

it('should not call searchPostsByTitle if searchTitle is empty', () => {
component.searchTitle = '';
component.searchByTitle();

expect(blogService.searchPostsByTitle).not.toHaveBeenCalled();
expect(router.navigate).not.toHaveBeenCalled();
});

it('should call getPostById and navigate on getBlogById', () => {
const mockData = { id: 1, title: 'Test Post' };
blogService.getPostById.and.returnValue(of(mockData));

component.blogId = 1;
component.getBlogById();

expect(blogService.getPostById).toHaveBeenCalledWith(1);
expect(router.navigate).toHaveBeenCalledWith(['/quality-check'], { state: { data: mockData } });
});

it('should not call getPostById if blogId is not set', () => {
component.blogId = 0;
component.getBlogById();

expect(blogService.getPostById).not.toHaveBeenCalled();
expect(router.navigate).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ export class HomeComponent {
constructor(private blogService: BlogService, private router: Router) {
}

ngOnInit(): void {
}

searchByTitle() {
if (this.searchTitle) {
this.blogService.searchPostsByTitle(this.searchTitle).subscribe((data: any[]) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TabularViewComponent } from './tabular-view.component';
import { RouterTestingModule } from "@angular/router/testing";
import { HttpClientModule } from "@angular/common/http";
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MatCardModule } from "@angular/material/card";
import { NO_ERRORS_SCHEMA } from "@angular/core";
import { HttpClientModule } from "@angular/common/http";
import { RouterTestingModule } from "@angular/router/testing";

describe('TabularViewComponent', () => {
let component: TabularViewComponent;
Expand All @@ -24,4 +23,41 @@ describe('TabularViewComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

it('should change page and fetch posts on page change', () => {
spyOn(component, 'fetchPosts');
component.onPageChange(2);

expect(component.currentPage).toBe(2);
expect(component.fetchPosts).toHaveBeenCalledWith(2);
});

it('should not change page if page is invalid', () => {
spyOn(component, 'fetchPosts');

component.onPageChange(0);
expect(component.currentPage).toBe(1);
expect(component.fetchPosts).not.toHaveBeenCalled();

component.isLastPage = true;
component.currentPage = 1;
component.onPageChange(2);
expect(component.currentPage).toBe(1);
expect(component.fetchPosts).not.toHaveBeenCalled();
});

it('should navigate to the first page', () => {
spyOn(component, 'onPageChange');
component.navigateToFirstPage();

expect(component.onPageChange).toHaveBeenCalledWith(1);
});

it('should navigate to the last page', () => {
component.totalPages = 5;
spyOn(component, 'onPageChange');
component.navigateToLastPage();

expect(component.onPageChange).toHaveBeenCalledWith(5);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import { BlogService } from "../../../services/blog.service";
})
export class TabularViewComponent implements OnInit {
protected columnDefs: any[];
protected rowData: any[];
rowData: any[];
loading: boolean = true;
currentPage: number = 1;
pageSize: number = 10;
isLastPage: boolean = false;
totalPages: number = 1;
@Output() clickEvent = new EventEmitter<number>();

constructor(private blogService: BlogService, private router: Router) {
constructor(public blogService: BlogService, public router: Router) {
this.columnDefs = [
{headerName: 'Blog ID', field: 'id', width: 100},
{headerName: 'Title', field: 'title.rendered', flex: 2},
Expand Down Expand Up @@ -59,8 +59,8 @@ export class TabularViewComponent implements OnInit {

fetchPosts(page: number): void {
this.loading = true;
this.blogService.getAllPosts(page, this.pageSize).subscribe(
(data: any) => {
this.blogService.getAllPosts(page, this.pageSize).subscribe({
next: (data: any) => {
this.rowData = data.posts.map((post: any) => {
return {
id: post.id,
Expand All @@ -75,11 +75,11 @@ export class TabularViewComponent implements OnInit {
this.isLastPage = data.isLastPage;
this.loading = false;
},
(error: any) => {
error: (error: any) => {
console.error('Error fetching posts:', error);
this.loading = false;
}
);
});
}

onPageChange(page: number): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,100 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { QualityCheckComponent } from './quality-check.component';
import { RouterTestingModule } from "@angular/router/testing";
import { HttpClientModule } from "@angular/common/http";
import { HeaderComponent } from "../dashboard/components/header/header.component";
import { MatIconModule } from "@angular/material/icon";
import { MatCardModule } from "@angular/material/card";
import { BlogService } from "../services/blog.service";
import { of, throwError } from 'rxjs';

describe('QualityCheckComponent', () => {
let component: QualityCheckComponent;
let fixture: ComponentFixture<QualityCheckComponent>;
let blogService: BlogService;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [QualityCheckComponent, HeaderComponent],
imports: [RouterTestingModule, HttpClientModule, MatIconModule, MatCardModule]

imports: [RouterTestingModule, HttpClientModule, MatIconModule, MatCardModule],
providers: [BlogService]
});
fixture = TestBed.createComponent(QualityCheckComponent);
component = fixture.componentInstance;
blogService = TestBed.inject(BlogService);
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should call location.back on goBack', () => {
const locationSpy = spyOn(component['location'], 'back');
component.goBack();
expect(locationSpy).toHaveBeenCalled();
});

it('should call blogService.getBlogQuality with correct prompt on checkQuality', () => {
component.postData = 'Sample blog content';
const expectedPrompt = `Review blog with the following content: Sample blog content
Parameters include fields like:
- Duplicate Content
- Spelling Mistakes
- Grammatical Errors
- Overall SEO Report
- Accuracy
- Depth and Completeness
- Clarity and Conciseness
- Logical Flow
- Technical Accuracy
- Targeted Audience
- Structure and Formatting
- Code Examples and Illustrations
- Links and References
- Overall Feedback
Display result in tabular view for respective percentages and accurate feedback;`;

spyOn(blogService, 'getBlogQuality').and.returnValue(of(''));
component.checkQuality();
expect(blogService.getBlogQuality).toHaveBeenCalledWith(expectedPrompt);
});

it('should parse a valid response correctly', () => {
const response = `
| Label | Percentage | Comment |
| Duplicate Content | 10% | Some duplicate content |
| Spelling Mistakes | 5% | Some spelling mistakes |`;
const expectedResults = [
{ originalLabel: 'Duplicate Content', oppositeLabel: 'Original Content', value: 10, comment: 'Some duplicate content' },
{ originalLabel: 'Spelling Mistakes', oppositeLabel: 'Correct Spelling', value: 5, comment: 'Some spelling mistakes' }
];
const results = component.parseResponse(response);
expect(results).toEqual(expectedResults);
});

it('should handle an empty response', () => {
const response = '';
const results = component.parseResponse(response);
expect(results).toEqual([]);
});

it('should handle a response with partially valid rows', () => {
const response = `
| Label | Percentage | Comment |
| Duplicate Content | 10% | Some duplicate content |
| Invalid Row`;
const expectedResults = [
{ originalLabel: 'Duplicate Content', oppositeLabel: 'Original Content', value: 10, comment: 'Some duplicate content' }
];
const results = component.parseResponse(response);
expect(results).toEqual(expectedResults);
});

it('should handle blogService.getBlogQuality error', () => {
spyOn(blogService, 'getBlogQuality').and.returnValue(throwError('Error occurred'));
const consoleSpy = spyOn(console, 'error');
component.checkQuality();
expect(consoleSpy).toHaveBeenCalledWith('Error:', 'Error occurred');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,19 @@ export class QualityCheckComponent {
}

checkQuality() {

const prompt = `Review blog with the following content: ${this.postData}
Parameters include fields like:
${this.labels.map(label => `- ${label.actual}`).join('\n')}
Display result in tabular view for respective percentages and accurate feedback;`;

this.blogService.getBlogQuality(prompt).subscribe(
response => {
this.blogService.getBlogQuality(prompt).subscribe({
next: response => {
this.qualityResults = this.parseResponse(response);
},
error => {
error: error => {
console.error('Error:', error);
}
);
});
}

parseResponse(response: string): { originalLabel: string; oppositeLabel: string; value: number; comment: string }[] {
Expand Down
55 changes: 53 additions & 2 deletions blogs-analyzer-ui/src/app/report/report.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ReportComponent } from './report.component';
import { HighchartsChartModule } from "highcharts-angular";
import { HighchartsChartModule } from 'highcharts-angular';
import * as Highcharts from 'highcharts';

describe('ReportComponent', () => {
let component: ReportComponent;
Expand All @@ -20,4 +20,55 @@ describe('ReportComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

it('should initialize with default values', () => {
expect(component.actualLabel).toEqual([]);
expect(component.oppositeLabel).toEqual([]);
expect(component.chartData).toEqual([]);
expect(component.chartTitle).toBe('');
});

it('should update chart options on ngOnInit', () => {
spyOn(component, 'updateChartOptions');
component.ngOnInit();
expect(component.updateChartOptions).toHaveBeenCalled();
});

it('should update chart options on ngOnChanges', () => {
spyOn(component, 'updateChartOptions');
component.ngOnChanges();
expect(component.updateChartOptions).toHaveBeenCalled();
});

it('should set chart options correctly in updateChartOptions', () => {
component.chartData = [30, 70];
component.actualLabel = ['Actual1', 'Opposite1'];
component.oppositeLabel = ['Actual2', 'Opposite2'];
component.chartTitle = 'Test Chart';

component.updateChartOptions();

const expectedChartOptions: Highcharts.Options = {
chart: { type: 'pie' },
title: { text: 'Test Chart' },
plotOptions: {
pie: {
innerSize: '50%',
dataLabels: { enabled: true }
}
},
series: [{
type: 'pie',
data: [
{ name: 'Actual1', y: 30 },
{ name: 'Opposite1', y: 70 },
{ name: 'Actual2', y: 70 },
{ name: 'Opposite2', y: 30 }
]
}],
tooltip: { pointFormat: '<b>{point.percentage:.1f}%</b>' }
};

expect(component.chartOptions).toEqual(expectedChartOptions);
});
});
Loading

0 comments on commit b18f665

Please sign in to comment.