Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate to platform files api in view expense page #2920

Merged
merged 29 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
552cd65
minor
Chethan-Fyle Apr 25, 2024
09cba8d
Merge branch 'master' into fyle-86cv7bcfq
Chethan-Fyle Apr 28, 2024
fa40e1d
Merge branch 'master' into fyle-86cv7bcfq
Chethan-Fyle Apr 29, 2024
0b678f4
minor
Chethan-Fyle Apr 29, 2024
4f33e4c
Merge branch 'master' into fyle-86cv7bcfq
Chethan-Fyle Apr 29, 2024
0835c29
minor
Chethan-Fyle Apr 29, 2024
978c828
minor
Chethan-Fyle Apr 30, 2024
81c065b
minor
Chethan-Fyle Apr 30, 2024
59fb5bd
Merge branch 'fyle-86cv7bcfq' into fyle-86cv5kvqp-2
Chethan-Fyle Apr 30, 2024
bd52292
Merge branch 'master' into fyle-86cv5kvqp-2
Chethan-Fyle Apr 30, 2024
c4c349b
Merge branch 'master' into fyle-86cv5kvqp-2
Chethan-Fyle May 6, 2024
18c9c2d
minor
Chethan-Fyle May 6, 2024
789f5ed
minor
Chethan-Fyle May 6, 2024
6df56eb
minor
Chethan-Fyle May 6, 2024
6735b4f
minor
Chethan-Fyle May 6, 2024
735a361
Merge branch 'master' into fyle-86cv5kvqp-2
Chethan-Fyle May 22, 2024
fd9934e
minor
Chethan-Fyle May 22, 2024
a198ebb
test: updated view expense page unit test to reflect files api migrat…
Chethan-Fyle May 22, 2024
8dc7bd8
Merge branch 'master' into fyle-86cv5kvqp-2
Chethan-Fyle May 23, 2024
d069258
Merge branch 'master' into fyle-86cv5kvqp-2
Chethan-Fyle May 23, 2024
4f7f1f4
minor
Chethan-Fyle May 23, 2024
3efa816
minor
Chethan-Fyle May 23, 2024
fc4f2e4
minor
Chethan-Fyle May 24, 2024
cc1cb5c
minor
Chethan-Fyle May 24, 2024
ee84885
minor
Chethan-Fyle May 24, 2024
81e0f32
minor
Chethan-Fyle May 24, 2024
ed1c434
minor
Chethan-Fyle May 24, 2024
db77503
minor
Chethan-Fyle May 27, 2024
a018b3b
Merge branch 'master' into fyle-86cv5kvqp-2
Chethan-Fyle May 27, 2024
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
12 changes: 12 additions & 0 deletions src/app/core/mock-data/platform-file.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import deepFreeze from 'deep-freeze-strict';
import { PlatformFileGenerateUrlsResponse } from '../models/platform/platform-file-generate-urls-response.model';

export const urlsBulkData: PlatformFileGenerateUrlsResponse[] = deepFreeze([
{
content_type: 'application/pdf',
download_url: 'https://exampledownloadurl.com',
id: 'fij7umnwoZUU',
name: 'invoice.pdf',
upload_url: 'https://exampleuploadurl.com',
},
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import deepFreeze from 'deep-freeze-strict';

export const attachReceiptPayload1 = deepFreeze({
data: {
id: 'txcSFe6efB6R',
file_id: 'fi1w2IE6JeqS',
},
});

export const attachReceiptsPayload1 = deepFreeze({
data: [
{
id: 'txcSFe6efB6R',
file_ids: ['fi1w2IE6JeqS', 'fiQ8ejWk25rF'],
},
],
});
24 changes: 24 additions & 0 deletions src/app/core/mock-data/platform/v1/expense.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AccountType } from 'src/app/core/models/platform/v1/account.model';
import { Expense, TransactionStatus } from 'src/app/core/models/platform/v1/expense.model';
import { FileType } from 'src/app/core/models/platform/v1/file.model';
import { CustomFieldTypes } from 'src/app/core/enums/platform/v1/custom-fields-type.enum';
import { CommuteDeduction } from 'src/app/core/enums/commute-deduction.enum';

export const expenseData: Expense = deepFreeze({
accounting_export_summary: {},
Expand Down Expand Up @@ -267,6 +268,29 @@ export const mileageExpense: Expense = deepFreeze({
category_id: 247012,
claim_amount: 459,
code: null,
commute_deduction: CommuteDeduction.ONE_WAY,
commute_details: {
distance: 2.92,
distance_unit: 'MILES',
home_location: {
city: 'Bengaluru',
country: 'India',
formatted_address: 'Bengaluru, Karnataka, India',
latitude: 13.0035068,
longitude: 77.5890953,
state: 'Karnataka',
},
id: 96,
work_location: {
city: 'Bengaluru',
country: 'India',
formatted_address: 'Sarjapura, Bengaluru, Karnataka 562125, India',
latitude: 12.8575579,
longitude: 77.7864057,
state: 'Karnataka',
},
},
commute_details_id: 96,
cost_center: {
code: null,
id: 2885,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ export const expensesResponse: PlatformApiResponse<Expense[]> = deepFreeze({
data: [expenseData],
offset: 0,
});

export const expenseResponse: PlatformApiResponse<Expense> = deepFreeze({
count: 1,
data: expenseData,
offset: 0,
});
29 changes: 29 additions & 0 deletions src/app/core/services/platform/v1/approver/file.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { TestBed } from '@angular/core/testing';
import { ApproverFileService } from './file.service';
import { ApproverPlatformApiService } from '../../../approver-platform-api.service';
import { generateUrlsBulkData1 } from 'src/app/core/mock-data/generate-urls-bulk-response.data';
import { of } from 'rxjs';

describe('ApproverFileService', () => {
let service: ApproverFileService;
Expand All @@ -25,4 +27,31 @@ describe('ApproverFileService', () => {
it('should be created', () => {
expect(service).toBeTruthy();
});

it('generateUrls(): should generate upload and download urls for the given file', (done) => {
approverPlatformApiService.post.and.returnValue(of({ data: generateUrlsBulkData1[0] }));

service.generateUrls('fi').subscribe((response) => {
expect(response).toEqual(generateUrlsBulkData1[0]);
done();
});
});

it('generateUrlsBulk(): should generate upload and download urls for multiple files', (done) => {
approverPlatformApiService.post.and.returnValue(of({ data: generateUrlsBulkData1 }));

service.generateUrlsBulk(['fi']).subscribe((response) => {
expect(response).toEqual(generateUrlsBulkData1);
done();
});
});

it('downloadFile(): should download file', (done) => {
approverPlatformApiService.get.and.returnValue(of({}));

service.downloadFile('fi').subscribe((response) => {
expect(response).toEqual({});
done();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class ApproverFileService {
.pipe(map((response) => response.data));
}

downloadFile(id: string): {} {
downloadFile(id: string): Observable<{}> {
return this.approverPlatformApiService.get('/files/download?id=' + id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@ import { ExpensesService } from './expenses.service';
import { SpenderService } from './spender.service';
import {
expenseData,
expenseResponseData,
readyToReportExpensesData2,
splitExpensesData,
} from 'src/app/core/mock-data/platform/v1/expense.data';
import { PAGINATION_SIZE } from 'src/app/constants';
import { expensesResponse } from 'src/app/core/mock-data/platform/v1/expenses-response.data';
import { expenseResponse, expensesResponse } from 'src/app/core/mock-data/platform/v1/expenses-response.data';
import { getExpensesQueryParams } from 'src/app/core/mock-data/platform/v1/expenses-query-params.data';
import { expenseDuplicateSets } from 'src/app/core/mock-data/platform/v1/expense-duplicate-sets.data';
import { completeStats } from 'src/app/core/mock-data/platform/v1/expenses-stats.data';
import { ExpensesService as SharedExpenseService } from '../shared/expenses.service';
import { expensesCacheBuster$ } from 'src/app/core/cache-buster/expense-cache-buster';
import {
attachReceiptPayload1,
attachReceiptsPayload1,
} from 'src/app/core/mock-data/platform/v1/attach-receipt-payload.data';

describe('ExpensesService', () => {
let service: ExpensesService;
Expand Down Expand Up @@ -238,4 +243,28 @@ describe('ExpensesService', () => {
done();
});
});

it('attachReceiptToExpense(): should attach a receipt to an expense', (done) => {
spenderService.post.and.returnValue(of(expenseResponse));

service
.attachReceiptToExpense(attachReceiptPayload1.data.id, attachReceiptPayload1.data.file_id)
.subscribe((res) => {
expect(res).toEqual(expenseData);
expect(spenderService.post).toHaveBeenCalledOnceWith('/expenses/attach_receipt', attachReceiptPayload1);
done();
});
});

it('attachReceiptsToExpense(): should attach multiple receipts to an expense', (done) => {
spenderService.post.and.returnValue(of(expensesResponse));

service
.attachReceiptsToExpense(attachReceiptPayload1.data.id, attachReceiptsPayload1.data[0].file_ids)
.subscribe((res) => {
expect(res).toEqual(expensesResponse.data);
expect(spenderService.post).toHaveBeenCalledOnceWith('/expenses/attach_files/bulk', attachReceiptsPayload1);
done();
});
});
});
29 changes: 29 additions & 0 deletions src/app/core/services/platform/v1/spender/file.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { TestBed } from '@angular/core/testing';
import { SpenderFileService } from './file.service';
import { SpenderPlatformV1ApiService } from '../../../spender-platform-v1-api.service';
import { of } from 'rxjs';
import { generateUrlsBulkData1 } from 'src/app/core/mock-data/generate-urls-bulk-response.data';

describe('SpenderFileService', () => {
let service: SpenderFileService;
Expand All @@ -25,4 +27,31 @@ describe('SpenderFileService', () => {
it('should be created', () => {
expect(service).toBeTruthy();
});

it('generateUrls(): should generate upload and download urls for the given file', (done) => {
spenderPlatformV1ApiService.post.and.returnValue(of({ data: generateUrlsBulkData1[0] }));

service.generateUrls('fi').subscribe((response) => {
expect(response).toEqual(generateUrlsBulkData1[0]);
done();
});
});

it('generateUrlsBulk(): should generate upload and download urls for multiple files', (done) => {
spenderPlatformV1ApiService.post.and.returnValue(of({ data: generateUrlsBulkData1 }));

service.generateUrlsBulk(['fi']).subscribe((response) => {
expect(response).toEqual(generateUrlsBulkData1);
done();
});
});

it('downloadFile(): should download file', (done) => {
spenderPlatformV1ApiService.get.and.returnValue(of({}));

service.downloadFile('fi').subscribe((response) => {
expect(response).toEqual({});
done();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class SpenderFileService {
.pipe(map((response) => response.data));
}

downloadFile(id: string): {} {
downloadFile(id: string): Observable<{}> {
return this.spenderPlatformV1ApiService.get('/files/download?id=' + id);
}
}
40 changes: 31 additions & 9 deletions src/app/fyle/view-expense/view-expense.page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ import { ExpenseState } from 'src/app/core/models/expense-state.enum';
import { TransactionStatusInfoPopoverComponent } from 'src/app/shared/components/transaction-status-info-popover/transaction-status-info-popover.component';
import { OrgSettings } from 'src/app/core/models/org-settings.model';
import { CustomInput } from 'src/app/core/models/custom-input.model';
import { SpenderFileService } from 'src/app/core/services/platform/v1/spender/file.service';
import { ApproverFileService } from 'src/app/core/services/platform/v1/approver/file.service';
import { urlsBulkData } from 'src/app/core/mock-data/platform-file.data';
import { ApproverReportsService } from 'src/app/core/services/platform/v1/approver/reports.service';
import {
expectedReportsSinglePage,
Expand Down Expand Up @@ -77,6 +80,8 @@ describe('ViewExpensePage', () => {
let dependentFieldsService: jasmine.SpyObj<DependentFieldsService>;
let approverExpensesService: jasmine.SpyObj<ApproverExpensesService>;
let spenderExpensesService: jasmine.SpyObj<SpenderExpensesService>;
let spenderFileService: jasmine.SpyObj<SpenderFileService>;
let approverFileService: jasmine.SpyObj<ApproverFileService>;
let activateRouteMock: ActivatedRoute;
let approverReportsService: jasmine.SpyObj<ApproverReportsService>;

Expand Down Expand Up @@ -127,6 +132,9 @@ describe('ViewExpensePage', () => {
'getReportById',
]);

const spenderFileServiceSpy = jasmine.createSpyObj('SpenderFileService', ['generateUrlsBulk']);
const approverFileServiceSpy = jasmine.createSpyObj('ApproverFileService', ['generateUrlsBulk']);

TestBed.configureTestingModule({
declarations: [ViewExpensePage],
imports: [IonicModule.forRoot(), FormsModule, MatIconModule, MatIconTestingModule],
Expand Down Expand Up @@ -203,6 +211,14 @@ describe('ViewExpensePage', () => {
useValue: spenderExpensesServiceSpy,
provide: SpenderExpensesService,
},
{
useValue: spenderFileServiceSpy,
provide: SpenderFileService,
},
{
useValue: approverFileServiceSpy,
provide: ApproverFileService,
},
{
provide: ApproverReportsService,
useValue: approverReportsServiceSpy,
Expand Down Expand Up @@ -244,6 +260,8 @@ describe('ViewExpensePage', () => {
loaderService = TestBed.inject(LoaderService) as jasmine.SpyObj<LoaderService>;
approverExpensesService = TestBed.inject(ApproverExpensesService) as jasmine.SpyObj<ApproverExpensesService>;
spenderExpensesService = TestBed.inject(SpenderExpensesService) as jasmine.SpyObj<SpenderExpensesService>;
spenderFileService = TestBed.inject(SpenderFileService) as jasmine.SpyObj<SpenderFileService>;
approverFileService = TestBed.inject(ApproverFileService) as jasmine.SpyObj<ApproverFileService>;
approverReportsService = TestBed.inject(ApproverReportsService) as jasmine.SpyObj<ApproverReportsService>;
activateRouteMock = TestBed.inject(ActivatedRoute);

Expand Down Expand Up @@ -882,26 +900,30 @@ describe('ViewExpensePage', () => {

it('should be able to edit expense attachments', fakeAsync(() => {
spyOn(component.updateFlag$, 'next');
component.view = ExpenseView.team;

fileService.getReceiptsDetails.and.returnValue({
const details = {
url: 'mock-url',
type: 'image',
thumbnail: 'mock-thumbnail',
});

const mockDownloadUrl = {
url: 'mock-url',
};
fileService.downloadUrl.and.returnValue(of(mockDownloadUrl.url));

fileService.getReceiptsDetails.and.returnValue(details);
approverFileService.generateUrlsBulk.and.returnValue(of(urlsBulkData));

component.ionViewWillEnter();
tick(500);
component.expense$.subscribe((expense) => {
expect(fileService.downloadUrl).toHaveBeenCalledOnceWith(fileObjectData.id);
expect(fileService.getReceiptsDetails).toHaveBeenCalledOnceWith(fileObjectData.name, fileObjectData.url);
expect(approverFileService.generateUrlsBulk).toHaveBeenCalledOnceWith(expense.file_ids);
expect(fileService.getReceiptsDetails).toHaveBeenCalledOnceWith(
urlsBulkData[0].name,
urlsBulkData[0].download_url
);
});
tick(500);
expect(component.updateFlag$.next).toHaveBeenCalledOnceWith(null);
component.attachments$.subscribe((attachments) => {
expect(attachments).toEqual([fileObjectData]);
expect(attachments).toEqual([details]);
expect(component.isLoading).toBeFalse();
});
}));
Expand Down
Loading
Loading