Skip to content

Commit

Permalink
Merge pull request #1588 from matthieulapatate/AddAxiosVueApp
Browse files Browse the repository at this point in the history
Add Axios Http into generated Vue Webapp
  • Loading branch information
pascalgrimaud authored May 9, 2022
2 parents 6b535a1 + 03970d4 commit 7559440
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ public static List<String> devDependencies() {
"typescript",
"vite",
"vue-jest",
"vue-tsc"
"vue-tsc",
"@types/sinon",
"sinon"
);
}

public static List<String> axiosDependency() {
return List.of("axios");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ private void addCommonVue(Project project) {
addScripts(project);
addJestSonar(project);
addViteConfigFiles(project);
addAxios(project);
addRootFiles(project);
addAppFiles(project);
addRouter(project);
Expand All @@ -86,6 +87,28 @@ private void addPiniaMainConfiguration(Project project) {
);
}

public void addAxios(Project project) {
addAxiosDependency(project);
addAxiosFile(project);
addAxiosTestFiles(project);
}

private void addAxiosTestFiles(Project project) {
String destinationAxiosTest = "src/test/javascript/spec/http";
String sourceAxiosTest = "test/spec/http";
projectRepository.template(project, getPath(SOURCE, sourceAxiosTest), "AxiosHttp.spec.ts", destinationAxiosTest);
projectRepository.template(project, getPath(SOURCE, sourceAxiosTest), "AxiosHttpStub.ts", destinationAxiosTest);
projectRepository.template(project, getPath(SOURCE, sourceAxiosTest), "AxiosStub.ts", destinationAxiosTest);
}

private void addAxiosDependency(Project project) {
Vue.axiosDependency().forEach(dependency -> addDependency(project, dependency));
}

private void addAxiosFile(Project project) {
projectRepository.template(project, getPath(SOURCE, "webapp/app/http"), "AxiosHttp.ts", "src/main/webapp/app/http");
}

public void addDevDependencies(Project project) {
Vue.devDependencies().forEach(devDependency -> addDevDependency(project, devDependency));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { AxiosResponse } from 'axios';
import { AxiosHttp } from '@/http/AxiosHttp';
import { dataAxiosResponse, stubAxiosInstance } from './AxiosStub';

interface Payload {
payload: string;
}

const fakePayload = (): Payload => ({
payload: 'content',
});

interface Result {
result: string;
}

const fakeResult = (): Result => ({
result: 'content',
});

const responseResult = (): AxiosResponse => dataAxiosResponse(fakeResult());

const expectForQuerying = (uri: string, result: AxiosResponse<Result>) => {
expect(result.data).toEqual(fakeResult());
expect(uri).toBe('/uri');
};

const expectForSendingAndQuerying = (uri: string, payload: Payload, result: AxiosResponse<Result>) => {
expect(payload).toEqual<Payload>(fakePayload());
expectForQuerying(uri, result);
};

describe('axiosHttp', () => {
describe('GET', () => {
it('should get content', async () => {
const axiosInstance = stubAxiosInstance();
axiosInstance.get.resolves(responseResult());
const axiosHttp = new AxiosHttp(axiosInstance);
const result = await axiosHttp.get<Result>('/uri');
const [uri] = axiosInstance.get.getCall(0).args;
expectForQuerying(uri, result);
});

it('should get content with params', async () => {
const axiosInstance = stubAxiosInstance();
axiosInstance.get.resolves(responseResult());
const axiosHttp = new AxiosHttp(axiosInstance);
await axiosHttp.get<Result>('/uri', { params: { beer: 'chips' } });

const [, config] = axiosInstance.get.getCall(0).args;
expect(config.params.beer).toBe('chips');
});
});

describe('PUT', () => {
it('should only get content', async () => {
const axiosInstance = stubAxiosInstance();
axiosInstance.put.resolves(responseResult());
const axiosHttp = new AxiosHttp(axiosInstance);
const result = await axiosHttp.put<Result>('/uri');
const [uri] = axiosInstance.put.getCall(0).args;
expectForQuerying(uri, result);
});

it('should send and get content', async () => {
const axiosInstance = stubAxiosInstance();
axiosInstance.put.resolves(responseResult());
const axiosHttp = new AxiosHttp(axiosInstance);
const result = await axiosHttp.put<Result, Payload>('/uri', fakePayload());
const [uri, payload] = axiosInstance.put.getCall(0).args;
expectForSendingAndQuerying(uri, payload, result);
});
});

describe('POST', () => {
it('should only get content', async () => {
const axiosInstance = stubAxiosInstance();
axiosInstance.post.resolves(responseResult());
const axiosHttp = new AxiosHttp(axiosInstance);
const result = await axiosHttp.post<Result>('/uri');
const [uri] = axiosInstance.post.getCall(0).args;
expectForQuerying(uri, result);
});

it('should send and get content', async () => {
const axiosInstance = stubAxiosInstance();
axiosInstance.post.resolves(responseResult());
const axiosHttp = new AxiosHttp(axiosInstance);
const result = await axiosHttp.post<Result, Payload>('/uri', fakePayload());
const [uri, payload] = axiosInstance.post.getCall(0).args;
expectForSendingAndQuerying(uri, payload, result);
});
});

describe('DELETE', () => {
it('should get content', async () => {
const axiosInstance = stubAxiosInstance();
axiosInstance.delete.resolves(responseResult());
const axiosHttp = new AxiosHttp(axiosInstance);
const result = await axiosHttp.delete<Result>('/uri');
const [uri] = axiosInstance.delete.getCall(0).args;
expectForQuerying(uri, result);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import sinon, { SinonStub } from 'sinon';
import { AxiosHttp, AxiosHttpResponse } from '@/http/AxiosHttp';

export interface AxiosHttpStub extends AxiosHttp {
get: SinonStub;
post: SinonStub;
delete: SinonStub;
put: SinonStub;
}

export const stubAxiosHttp = (): AxiosHttpStub =>
({
get: sinon.stub(),
post: sinon.stub(),
delete: sinon.stub(),
put: sinon.stub(),
} as AxiosHttpStub);

export const dataBackendResponse = <T>(data: T): AxiosHttpResponse<T> =>
({
data,
} as AxiosHttpResponse<T>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { AxiosInstance, AxiosResponse } from 'axios';
import sinon, { SinonStub } from 'sinon';

export interface AxiosStubInstance extends AxiosInstance {
get: SinonStub;
put: SinonStub;
post: SinonStub;
delete: SinonStub;
}

export const stubAxiosInstance = (): AxiosStubInstance =>
({
get: sinon.stub(),
put: sinon.stub(),
post: sinon.stub(),
delete: sinon.stub(),
} as AxiosStubInstance);

export const dataAxiosResponse = <T>(data: T): AxiosResponse<T> =>
({
data,
} as AxiosResponse<T>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';

export type AxiosHttpResponse<T> = AxiosResponse<T>;

export class AxiosHttp {
constructor(private axiosInstance: AxiosInstance) {}

async get<Result>(uri: string, config: AxiosRequestConfig = {}): Promise<AxiosResponse<Result>> {
return this.axiosInstance.get<Result>(uri, config);
}

async put<Result, Payload = never>(uri: string, data?: Payload): Promise<AxiosResponse<Result>> {
return this.axiosInstance.put<Result>(uri, data);
}

async post<Result, Payload = never>(uri: string, data?: Payload, config?: AxiosRequestConfig): Promise<AxiosResponse<Result>> {
return this.axiosInstance.post<Result>(uri, data, config);
}

async delete<Result>(uri: string): Promise<AxiosResponse<Result>> {
return this.axiosInstance.delete<Result>(uri);
}
}
3 changes: 3 additions & 0 deletions src/main/resources/generator/dependencies/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "JHipster Lite : used for Vite+Vue3 dependencies",
"license": "Apache-2.0",
"dependencies": {
"axios": "0.26.1",
"pinia": "2.0.14",
"pinia-plugin-persist": "1.0.0",
"vue": "3.2.33",
Expand All @@ -13,6 +14,7 @@
"@pinia/testing": "0.0.12",
"@rushstack/eslint-patch": "1.1.3",
"@types/jest": "27.5.0",
"@types/sinon": "10.0.11",
"@typescript-eslint/parser": "5.22.0",
"@vitejs/plugin-vue": "2.3.2",
"@vue/eslint-config-typescript": "10.0.0",
Expand All @@ -23,6 +25,7 @@
"jest": "26.6.3",
"jest-sonar-reporter": "2.0.0",
"jest-transform-stub": "2.0.0",
"sinon": "13.0.2",
"ts-jest": "26.5.6",
"typescript": "4.6.4",
"vite": "2.9.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void shouldAddVue() {
VueAssert.assertAppFiles(project);
VueAssert.assertRouterFiles(project);
VueAssert.assertAppWithoutCss(project);
VueAssert.assertAxiosFile(project);

VueAssert.assertJestSonar(project);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public static void assertDependency(Project project) {
Vue.dependencies().forEach(dependency -> assertFileContent(project, PACKAGE_JSON, DQ + dependency + DQ));
Vue.routerDependencies().forEach(dependency -> assertFileContent(project, PACKAGE_JSON, DQ + dependency + DQ));
Vue.devDependencies().forEach(devDependency -> assertFileContent(project, PACKAGE_JSON, DQ + devDependency + DQ));
Vue.axiosDependency().forEach(dependency -> assertFileContent(project, PACKAGE_JSON, DQ + dependency + DQ));
}

public static void assertPiniaDependency(Project project) {
Expand Down Expand Up @@ -83,4 +84,11 @@ public static void assertJestSonar(Project project) {
List.of("\"jestSonar\": {", "\"reportPath\": \"target/test-results/jest\",", "\"reportFile\": \"TESTS-results-sonar.xml\"", "}")
);
}

public static void assertAxiosFile(Project project) {
assertFileExist(project, "src/main/webapp/app/http/AxiosHttp.ts");
assertFileExist(project, "src/test/javascript/spec/http/AxiosHttp.spec.ts");
assertFileExist(project, "src/test/javascript/spec/http/AxiosHttpStub.ts");
assertFileExist(project, "src/test/javascript/spec/http/AxiosStub.ts");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void shouldAddDevDependencies() {

vueDomainService.addDevDependencies(project);

verify(npmService, times(17)).addDevDependency(any(Project.class), anyString(), anyString());
verify(npmService, times(19)).addDevDependency(any(Project.class), anyString(), anyString());
}

@Test
Expand Down Expand Up @@ -221,4 +221,26 @@ void shouldUpdateMainConfigurationWhenAddingPinia() {

verify(projectRepository, times(5)).replaceText(eq(project), anyString(), eq("main.ts"), anyString(), anyString());
}

@Test
void shouldAddAxiosDependency() {
Project project = tmpProjectWithPackageJson();
final String version = "0.0.0";
when(npmService.getVersion(anyString(), anyString())).thenReturn(Optional.of(version));

vueDomainService.addAxios(project);

verify(npmService).addDependency(project, "axios", version);
}

@Test
void shouldAddAxiosFile() {
Project project = tmpProjectWithPackageJson();
final String version = "0.0.0";
when(npmService.getVersion(anyString(), anyString())).thenReturn(Optional.of(version));

vueDomainService.addAxios(project);

verify(projectRepository, times(4)).template(any(Project.class), anyString(), anyString(), anyString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ void shouldAddVue() throws Exception {
VueAssert.assertRootFiles(project);
VueAssert.assertAppFiles(project);
VueAssert.assertAppWithoutCss(project);
VueAssert.assertAxiosFile(project);

VueAssert.assertJestSonar(project);
}
Expand Down

0 comments on commit 7559440

Please sign in to comment.