Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
392 changes: 119 additions & 273 deletions core-web/apps/dotcdn/src/app/dotcdn.service.spec.ts

Large diffs are not rendered by default.

44 changes: 25 additions & 19 deletions core-web/apps/dotcdn/src/app/dotcdn.service.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import { format, subDays } from 'date-fns';
import { Observable } from 'rxjs';

import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';

import { mergeMap, pluck } from 'rxjs/operators';
import { mergeMap, map } from 'rxjs/operators';

import { CoreWebService, ResponseView, SiteService } from '@dotcms/dotcms-js';
import { SiteService } from '@dotcms/dotcms-js';
import { DotCMSResponse } from '@dotcms/dotcms-models';

import { DotCDNStats, PurgeReturnData, PurgeUrlOptions } from './app.models';

// Response type for endpoints that return bodyJsonObject
interface DotBodyJsonResponse<T> {
bodyJsonObject: T;
}

@Injectable({
providedIn: 'root'
})
export class DotCDNService {
private coreWebService = inject(CoreWebService);
private http = inject(HttpClient);
private siteService = inject(SiteService);

/**
Expand All @@ -25,58 +32,57 @@ export class DotCDNService {
*/
requestStats(period: string): Observable<DotCDNStats> {
return this.siteService.getCurrentSite().pipe(
pluck('identifier'),
map((site) => site.identifier),
mergeMap((hostId: string) => {
const dateTo = format(new Date(), 'yyyy-MM-dd');
const dateFrom = format(subDays(new Date(), parseInt(period, 10)), 'yyyy-MM-dd');

return this.coreWebService.requestView<DotCDNStats>({
url: `/api/v1/dotcdn/stats?hostId=${hostId}&dateFrom=${dateFrom}&dateTo=${dateTo}`
});
}),
pluck('entity')
return this.http
.get<
DotCMSResponse<DotCDNStats>
>(`/api/v1/dotcdn/stats?hostId=${hostId}&dateFrom=${dateFrom}&dateTo=${dateTo}`)
.pipe(map((response) => response.entity));
})
);
}

/**
* Makes a request to purge the cache
*
* @param {string[]} [urls=[]]
* @return {Observable<ResponseView<PurgeReturnData>>}
* @return {Observable<PurgeReturnData>}
* @memberof DotCDNService
*/
purgeCache(urls?: string[]): Observable<PurgeReturnData> {
return this.siteService.getCurrentSite().pipe(
pluck('identifier'),
map((site) => site.identifier),
mergeMap((hostId: string) => {
return this.purgeUrlRequest({ hostId, invalidateAll: false, urls });
}),
pluck('bodyJsonObject')
map((response) => response.bodyJsonObject)
);
}

/**
* Makes a request to purge the cache
*
* @return {Observable<ResponseView<PurgeReturnData>>}
* @return {Observable<PurgeReturnData>}
* @memberof DotCDNService
*/
purgeCacheAll(): Observable<PurgeReturnData> {
return this.siteService.getCurrentSite().pipe(
pluck('identifier'),
map((site) => site.identifier),
mergeMap((hostId: string) => this.purgeUrlRequest({ hostId, invalidateAll: true })),
pluck('bodyJsonObject')
map((response) => response.bodyJsonObject)
);
}

private purgeUrlRequest({
urls = [],
invalidateAll,
hostId
}: PurgeUrlOptions): Observable<ResponseView<PurgeReturnData>> {
return this.coreWebService.requestView<PurgeReturnData>({
url: `/api/v1/dotcdn`,
method: 'DELETE',
}: PurgeUrlOptions): Observable<DotBodyJsonResponse<PurgeReturnData>> {
return this.http.request<DotBodyJsonResponse<PurgeReturnData>>('DELETE', '/api/v1/dotcdn', {
body: JSON.stringify({
urls,
invalidateAll,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
import { mockProvider } from '@ngneat/spectator/jest';
import { throwError } from 'rxjs';
import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { getTestBed, TestBed } from '@angular/core/testing';
import { DotHttpErrorManagerService } from '@dotcms/data-access';
import { MockDotHttpErrorManagerService } from '@dotcms/utils-testing';

import { ConfirmationService } from 'primeng/api';

import {
DotHttpErrorManagerService,
DotMessageDisplayService,
DotRouterService,
DotAlertConfirmService,
DotMessageService,
DotFormatDateService
} from '@dotcms/data-access';
import { CoreWebService, LoginService } from '@dotcms/dotcms-js';
import {
CoreWebServiceMock,
LoginServiceMock,
DotMessageDisplayServiceMock,
MockDotRouterService,
DotFormatDateServiceMock,
mockResponseView
} from '@dotcms/utils-testing';

import { DotAddToMenuService, DotCreateCustomTool } from './add-to-menu.service';
DotAddToMenuService,
DotCreateCustomTool,
DotCustomToolToLayout
} from './add-to-menu.service';

const customToolData: DotCreateCustomTool = {
contentTypes: 'Blog',
Expand All @@ -33,39 +18,30 @@ const customToolData: DotCreateCustomTool = {
};

describe('DotAddToMenuService', () => {
let injector: TestBed;
let dotAddToMenuService: DotAddToMenuService;
let dotHttpErrorManagerService: DotHttpErrorManagerService;
let coreWebService: CoreWebService;
let httpMock: HttpTestingController;
let httpTesting: HttpTestingController;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{ provide: CoreWebService, useClass: CoreWebServiceMock },
{
provide: LoginService,
useClass: LoginServiceMock
},
{
provide: DotMessageDisplayService,
useClass: DotMessageDisplayServiceMock
},
{ provide: DotRouterService, useClass: MockDotRouterService },
{ provide: DotFormatDateService, useClass: DotFormatDateServiceMock },
ConfirmationService,
provideHttpClient(),
provideHttpClientTesting(),
DotAddToMenuService,
DotAlertConfirmService,
DotHttpErrorManagerService,
mockProvider(DotMessageService)
{
provide: DotHttpErrorManagerService,
useClass: MockDotHttpErrorManagerService
}
]
});
injector = getTestBed();
dotAddToMenuService = injector.inject(DotAddToMenuService);
dotHttpErrorManagerService = injector.inject(DotHttpErrorManagerService);
coreWebService = injector.inject(CoreWebService);
httpMock = injector.inject(HttpTestingController);

dotAddToMenuService = TestBed.inject(DotAddToMenuService);
dotHttpErrorManagerService = TestBed.inject(DotHttpErrorManagerService);
httpTesting = TestBed.inject(HttpTestingController);
});

afterEach(() => {
httpTesting.verify();
});

it('should clean up Portlet Id value', () => {
Expand All @@ -75,13 +51,11 @@ describe('DotAddToMenuService', () => {
});

it('should create a custom tool portlet', () => {
const url = `v1/portlet/custom`;

dotAddToMenuService.createCustomTool(customToolData).subscribe((response: string) => {
expect(response).toEqual('ok');
});

const req = httpMock.expectOne(url);
const req = httpTesting.expectOne('/api/v1/portlet/custom');
expect(req.request.method).toBe('POST');
expect(req.request.body).toEqual({
...customToolData,
Expand All @@ -93,65 +67,69 @@ describe('DotAddToMenuService', () => {
});

it('should throw null on create custom tool error 400', () => {
const error404 = mockResponseView(400);
jest.spyOn(dotHttpErrorManagerService, 'handle');
jest.spyOn(coreWebService, 'requestView').mockReturnValue(throwError(error404));

dotAddToMenuService.createCustomTool(customToolData).subscribe((response: string) => {
expect(response).toEqual(null);
});

const req = httpTesting.expectOne('/api/v1/portlet/custom');
req.flush(null, { status: 400, statusText: 'Bad Request' });

expect(dotHttpErrorManagerService.handle).not.toHaveBeenCalled();
});

it('should throw error 500 on create custom tool error', () => {
const error404 = mockResponseView(500);
jest.spyOn(dotHttpErrorManagerService, 'handle');
jest.spyOn(coreWebService, 'requestView').mockReturnValue(throwError(error404));

dotAddToMenuService.createCustomTool(customToolData).subscribe((response: string) => {
expect(response).toEqual(null);
});
expect(dotHttpErrorManagerService.handle).toHaveBeenCalledWith(mockResponseView(500));

const req = httpTesting.expectOne('/api/v1/portlet/custom');
req.flush(null, { status: 500, statusText: 'Internal Server Error' });

expect(dotHttpErrorManagerService.handle).toHaveBeenCalled();
});

it('should add to layout a custom tool portlet', () => {
const url = `v1/portlet/custom/c_${customToolData.portletName}_${customToolData.dataViewMode}/_addtolayout/123`;

dotAddToMenuService
.addToLayout({
portletName: customToolData.portletName,
dataViewMode: customToolData.dataViewMode,
layoutId: '123'
})
.subscribe((response: string) => {
expect(response).toEqual('ok');
});

const req = httpMock.expectOne(url);
const layoutData: DotCustomToolToLayout = {
portletName: customToolData.portletName,
dataViewMode: customToolData.dataViewMode,
layoutId: '123'
};

dotAddToMenuService.addToLayout(layoutData).subscribe((response: string) => {
expect(response).toEqual('ok');
});

const req = httpTesting.expectOne(
`/api/v1/portlet/custom/c_${customToolData.portletName}_${customToolData.dataViewMode}/_addtolayout/123`
);
expect(req.request.method).toBe('PUT');
req.flush({
entity: 'ok'
});
});

it('should throw error 400 on add to layout custom portlet', () => {
const error404 = mockResponseView(400);
jest.spyOn(dotHttpErrorManagerService, 'handle');
jest.spyOn(coreWebService, 'requestView').mockReturnValue(throwError(error404));

dotAddToMenuService
.addToLayout({
portletName: customToolData.portletName,
dataViewMode: customToolData.dataViewMode,
layoutId: '123'
})
.subscribe((response: string) => {
expect(response).toEqual(null);
});
expect(dotHttpErrorManagerService.handle).toHaveBeenCalledWith(mockResponseView(400));
});

afterEach(() => {
httpMock.verify();
const layoutData: DotCustomToolToLayout = {
portletName: customToolData.portletName,
dataViewMode: customToolData.dataViewMode,
layoutId: '123'
};

dotAddToMenuService.addToLayout(layoutData).subscribe((response: string) => {
expect(response).toEqual(null);
});

const req = httpTesting.expectOne(
`/api/v1/portlet/custom/c_${customToolData.portletName}_${customToolData.dataViewMode}/_addtolayout/123`
);
req.flush(null, { status: 400, statusText: 'Bad Request' });

expect(dotHttpErrorManagerService.handle).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Observable, of } from 'rxjs';

import { HttpErrorResponse } from '@angular/common/http';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';

import { catchError, map, pluck, take } from 'rxjs/operators';
import { catchError, map, take } from 'rxjs/operators';

import { DotHttpErrorManagerService } from '@dotcms/data-access';
import { CoreWebService } from '@dotcms/dotcms-js';
import { DotCMSResponse } from '@dotcms/dotcms-models';

const addToMenuUrl = `v1/portlet`;
const addToMenuUrl = '/api/v1/portlet';

export interface DotCreateCustomTool {
contentTypes: string;
Expand All @@ -29,7 +29,7 @@ export interface DotCustomToolToLayout {
*/
@Injectable()
export class DotAddToMenuService {
private coreWebService = inject(CoreWebService);
private http = inject(HttpClient);
private httpErrorManagerService = inject(DotHttpErrorManagerService);

/**
Expand All @@ -51,17 +51,13 @@ export class DotAddToMenuService {
* @memberof DotAddToMenuService
*/
createCustomTool(params: DotCreateCustomTool): Observable<string> {
return this.coreWebService
.requestView({
body: {
...params,
portletId: `${this.cleanUpPorletId(params.portletName)}_${params.dataViewMode}`
},
method: 'POST',
url: `${addToMenuUrl}/custom`
return this.http
.post<DotCMSResponse<string>>(`${addToMenuUrl}/custom`, {
...params,
portletId: `${this.cleanUpPorletId(params.portletName)}_${params.dataViewMode}`
})
.pipe(
pluck('entity'),
map((response) => response.entity),
catchError((error: HttpErrorResponse) => {
if (error.status === 400) {
return of(null);
Expand All @@ -85,13 +81,12 @@ export class DotAddToMenuService {
addToLayout(params: DotCustomToolToLayout): Observable<string> {
const portletId = `${this.cleanUpPorletId(params.portletName)}_${params.dataViewMode}`;

return this.coreWebService
.requestView({
method: 'PUT',
url: `${addToMenuUrl}/custom/c_${portletId}/_addtolayout/${params.layoutId}`
})
return this.http
.put<
DotCMSResponse<string>
>(`${addToMenuUrl}/custom/c_${portletId}/_addtolayout/${params.layoutId}`, {})
.pipe(
pluck('entity'),
map((response) => response.entity),
catchError((error: HttpErrorResponse) => {
return this.httpErrorManagerService.handle(error).pipe(
take(1),
Expand Down
Loading
Loading