Skip to content

Commit

Permalink
Feat/v0.4.2 (#282)
Browse files Browse the repository at this point in the history
* fix: formdata header error

* chore: e2e config
  • Loading branch information
scarqin authored Mar 23, 2023
1 parent f46019e commit 221a5fd
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SettingService } from 'pc/browser/src/app/components/system-setting/set
selector: 'eo-extension-setting',
template: `
<div
class="sticky top-0 py-[10px] border-solid border-0 border-b-[1px] z-10 mb-[3px]"
class="sticky top-0 py-[12px] border-solid border-0 border-b-[1px] z-10 mb-[3px]"
style="border-color: var(--border-color); background-color: var(--background-color); border-bottom: 1px solid var(--system-border-color);"
>
<button eo-ng-button nzType="primary" (click)="handleSave()">Save</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="flex flex-col h-full extension-detail" *ngIf="extensionDetail">
<div class="top-0 z-50">
<div class="z-50 top-10">
<div class="pb-[16px]">
<div class="leading-[40px] h-[40px] ml-[5px]">
<button eo-ng-button nzType="text" (click)="backToList()" class="flex !pl-[12px]">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
}

.ant-tabs-content-holder {
padding-top: 12px;
padding-bottom: 8px;
margin-bottom: 0;
overflow: auto;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
></nz-badge>
</ng-template>
<eo-api-test-body
[(contentType)]="model.monacoContentType"
[(contentType)]="model.userSelectedContentType"
[(autoSetContentType)]="model.autoSetContentType"
(contentTypeChange)="setHeaderContentType()"
[(bodyType)]="model.request.apiAttrInfo.contentType"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ import {
beforeScriptCompletions,
afterScriptCompletions
} from 'pc/browser/src/app/pages/workspace/project/api/http/test/api-script/constant';
import { ContentType, CONTENT_TYPE_BY_ABRIDGE } from 'pc/browser/src/app/pages/workspace/project/api/http/test/api-test.model';
import {
ContentType,
CONTENT_TYPE_BY_ABRIDGE,
FORMDATA_CONTENT_TYPE_BY_ABRIDGE
} from 'pc/browser/src/app/pages/workspace/project/api/http/test/api-test.model';
import { ApiTestResultResponseComponent } from 'pc/browser/src/app/pages/workspace/project/api/http/test/result-response/api-test-result-response.component';
import { ApiTestResData, TestServerRes } from 'pc/browser/src/app/pages/workspace/project/api/service/test-server/test-server.model';
import { generateRestFromUrl, syncUrlAndQuery } from 'pc/browser/src/app/pages/workspace/project/api/utils/api.utils';
Expand All @@ -41,7 +45,7 @@ import { interval, Subscription, Subject, fromEvent } from 'rxjs';
import { takeUntil, distinctUntilChanged, takeWhile, finalize } from 'rxjs/operators';

import { eoDeepCopy, isEmptyObj, enumsToArr, JSONParse } from '../../../../../../shared/utils/index.utils';
import { ApiBodyType, ContentType as ContentTypeEnum, RequestMethod } from '../../api.model';
import { ApiBodyType, ApiParamsType, ContentType as ContentTypeEnum, RequestMethod } from '../../api.model';
import { ProjectApiService } from '../../api.service';
import { ApiParamsNumPipe } from '../../pipe/api-param-num.pipe';
import { ApiTestUtilService } from '../../service/api-test-util.service';
Expand All @@ -52,17 +56,25 @@ import { ApiTestService } from './api-test.service';
const API_TEST_DRAG_TOP_HEIGHT_KEY = 'API_TEST_DRAG_TOP_HEIGHT';
const localHeight = Number.parseInt(localStorage.getItem(API_TEST_DRAG_TOP_HEIGHT_KEY));

const contentTypeMap = {
0: 'application/json',
1: 'text/plain',
2: 'application/json',
3: 'application/xml',
6: 'application/json'
/**
* Default Content Type
*/
const contentTypeMap: { [key in ApiBodyType]: ContentType } = {
[ApiBodyType.FormData]: 'application/x-www-form-urlencoded',
[ApiBodyType.Raw]: 'text/plain',
[ApiBodyType.JSON]: 'application/json',
[ApiBodyType.JSONArray]: 'application/json',
[ApiBodyType.XML]: 'application/xml',
//Binary content type need generate from file type
[ApiBodyType.Binary]: '' as ContentType
} as const;

interface testViewModel {
testStartTime?: number;
monacoContentType: ContentType;
/**
* User selected content type
*/
userSelectedContentType: ContentType;
autoSetContentType: boolean;
requestTabIndex: number;
responseTabIndex: number;
Expand Down Expand Up @@ -192,7 +204,8 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
this.authExtForm?.init?.();
if (!this.model || isEmptyObj(this.model)) {
this.model = {
requestTabIndex: 1
requestTabIndex: 1,
responseTabIndex: 0
} as testViewModel;
let uuid = this.route.snapshot.queryParams.uuid;
const initTimes = this.initTimes;
Expand All @@ -210,7 +223,8 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
this.model.testResult = history.response;
} else {
if (!uuid) {
requestInfo = this.resetModel().request;
const newModel = this.resetModel();
requestInfo = newModel.request;
} else {
requestInfo = await this.projectApi.get(uuid);
requestInfo.authInfo.authInfo = JSONParse(requestInfo.authInfo.authInfo);
Expand All @@ -226,7 +240,8 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
} else {
return;
}
this.setMonacoContentType();
this.setUserSelectedContentType();
this.setHeaderContentType();
this.waitSeconds = 0;
this.status = 'start';
} else {
Expand Down Expand Up @@ -335,18 +350,23 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
}

/**
* Return contentType header value by bodyType and monacoContentType
* Return contentType header value by bodyType and userSelectedContentType
*
* @param bodyType
* @returns
*/
getContentTypeByBodyType(bodyType: ApiBodyType = this.model.request?.apiAttrInfo?.contentType): ContentType | string {
switch (bodyType) {
case ApiBodyType.Raw: {
return this.model?.monacoContentType;
const isRawHeader = CONTENT_TYPE_BY_ABRIDGE.some(val => val.value === this.model?.userSelectedContentType);
return isRawHeader ? this.model?.userSelectedContentType : contentTypeMap[ApiBodyType.JSON];
}
case ApiBodyType.FormData: {
return 'multiple/form-data';
//If params has file,dataType must be multiple/form-data
if (this.model?.request?.requestParams?.bodyParams?.some(val => val.dataType === ApiParamsType.file)) return 'multiple/form-data';

const isFormHeader = FORMDATA_CONTENT_TYPE_BY_ABRIDGE.some(val => val.value === this.model?.userSelectedContentType);
return isFormHeader ? this.model?.userSelectedContentType : contentTypeMap[ApiBodyType.FormData];
}
case ApiBodyType.Binary: {
return '';
Expand All @@ -362,6 +382,7 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
contentType,
this.model.request.requestParams.headerParams
);
this.model.userSelectedContentType = contentType as ContentType;
return;
}

Expand All @@ -375,17 +396,23 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
}
changeBodyType($event) {
StorageUtil.set('api_test_body_type', $event);
this.setMonacoContentType();
this.setHeaderContentType();
}
handleBottomTabSelect(tab) {
if (tab.index === 2) {
this.isRequestBodyLoaded = true;
}
}
emitChangeFun(where) {
if (where === 'queryParams') {
this.changeQuery();
switch (where) {
case 'queryParams': {
this.changeQuery();
break;
}
case 'requestBody': {
//When bodyType or params change,change header and content-type
this.setHeaderContentType();
break;
}
}
this.modelChange.emit(this.model);
}
Expand Down Expand Up @@ -529,10 +556,11 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
}
}
}
setMonacoContentType($event = this.model.monacoContentType) {
const contentType = this.model.request?.apiAttrInfo?.contentType;
if (contentType !== ApiBodyType.Raw) return;
this.model.monacoContentType = this.apiTestUtil.getContentType(this.model.request.requestParams.headerParams) || 'text/plain';
setUserSelectedContentType($event = this.model.userSelectedContentType) {
const bodyType = this.model.request?.apiAttrInfo?.contentType;
if (bodyType === ApiBodyType.Binary) return;
this.model.userSelectedContentType =
this.apiTestUtil.getContentType(this.model.request.requestParams.headerParams) || this.getContentTypeByBodyType(bodyType);
}
private watchEnvChange() {
reaction(
Expand All @@ -551,7 +579,7 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
const bodyType = typeof StorageUtil.get('api_test_body_type') === 'number' ? StorageUtil.get('api_test_body_type') : ApiBodyType.Raw;

const headerParams = [];
const contentType = this.getContentTypeByBodyType(bodyType) || contentTypeMap[ApiBodyType.JSON];
const contentType = this.getContentTypeByBodyType(bodyType);
if (bodyType !== ApiBodyType.Binary) {
headerParams.push({
isRequired: 1,
Expand All @@ -561,11 +589,10 @@ export class ApiTestComponent implements OnInit, AfterViewInit, OnDestroy, TabVi
}
});
}

return {
requestTabIndex: 1,
responseTabIndex: 0,
monacoContentType: contentType,
userSelectedContentType: contentType,
request: {
authInfo: {
authInfo: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,14 @@ export const CONTENT_TYPE_BY_ABRIDGE = [
value: 'application/javascript'
}
] as const;
export type ContentType = (typeof CONTENT_TYPE_BY_ABRIDGE)[number]['value'];
export const FORMDATA_CONTENT_TYPE_BY_ABRIDGE = [
{
title: 'x-www-form-urlencoded',
value: 'application/x-www-form-urlencoded'
},
{
title: 'form-data',
value: 'multiple/form-data'
}
] as const;
export type ContentType = (typeof CONTENT_TYPE_BY_ABRIDGE)[number]['value'] | (typeof FORMDATA_CONTENT_TYPE_BY_ABRIDGE)[number]['value'];
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
<eo-ng-radio-group [(ngModel)]="bodyType" (ngModelChange)="changeBodyType()">
<label *ngFor="let item of CONST.API_BODY_TYPE" eo-ng-radio [nzValue]="item.value">{{ item.key }}</label>
</eo-ng-radio-group>
<nz-divider *ngIf="[TYPE_API_BODY['FormData'], TYPE_API_BODY.Raw].includes(bodyType)" nzType="vertical"></nz-divider>
<!--Select content-type-->

<div *ngIf="[TYPE_API_BODY.Raw].includes(bodyType)">
<!-- Import -->
<div *ngIf="[TYPE_API_BODY.FormData].includes(bodyType)" class="inline-flex items-center">
<nz-divider nzType="vertical"></nz-divider>
<params-import [baseData]="model" [contentType]="IMPORT_MUI[bodyType]" (baseDataChange)="handleParamsImport($event)"> </params-import>
</div>

<div *ngIf="[TYPE_API_BODY.Raw, TYPE_API_BODY.FormData].includes(bodyType)">
<nz-divider nzType="vertical"></nz-divider>
<span class="text-[12px]">Content-Type:</span>
<eo-ng-select
class="text-[12px]"
Expand All @@ -14,14 +20,9 @@
[(ngModel)]="contentType"
nzBorderless
>
<eo-ng-option *ngFor="let item of CONST.CONTENT_TYPE" [nzValue]="item.value" [nzLabel]="item.title"></eo-ng-option>
<eo-ng-option *ngFor="let item of CONST.CONTENT_TYPE[bodyType]" [nzValue]="item.value" [nzLabel]="item.title"></eo-ng-option>
</eo-ng-select>
</div>

<!-- Import -->
<div *ngIf="[TYPE_API_BODY['FormData']].includes(bodyType)" class="inline-flex items-center">
<params-import [baseData]="model" [contentType]="IMPORT_MUI[bodyType]" (baseDataChange)="handleParamsImport($event)"> </params-import>
</div>
</div>
<!-- FormData -->
<eo-ng-table-pro
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { BodyParam } from 'pc/browser/src/app/services/storage/db/models/apiData
import { transferFileToDataUrl, whatTextType, whatType } from 'pc/browser/src/app/shared/utils/index.utils';
import { Observable, Observer, pairwise, Subject, takeUntil } from 'rxjs';

import { ContentType, CONTENT_TYPE_BY_ABRIDGE } from '../api-test.model';
import { ContentType, CONTENT_TYPE_BY_ABRIDGE, FORMDATA_CONTENT_TYPE_BY_ABRIDGE } from '../api-test.model';

const whatTextTypeMap = {
xml: 'application/xml',
Expand Down Expand Up @@ -48,7 +48,10 @@ export class ApiTestBodyComponent implements OnInit, OnChanges, OnDestroy {
};
binaryFiles: NzUploadFile[] = [];
CONST = {
CONTENT_TYPE: CONTENT_TYPE_BY_ABRIDGE,
CONTENT_TYPE: {
[ApiBodyType.Raw]: CONTENT_TYPE_BY_ABRIDGE,
[ApiBodyType.FormData]: FORMDATA_CONTENT_TYPE_BY_ABRIDGE
},
API_BODY_TYPE: []
};
IMPORT_MUI = IMPORT_MUI;
Expand Down
3 changes: 2 additions & 1 deletion test/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/images/*.png
/images/*.png
/test-result/**/*.png
Binary file not shown.

0 comments on commit 221a5fd

Please sign in to comment.