diff --git a/api/internal/core/entity/entity.go b/api/internal/core/entity/entity.go index f8fcc1c604..b8de0a9e0c 100644 --- a/api/internal/core/entity/entity.go +++ b/api/internal/core/entity/entity.go @@ -65,8 +65,8 @@ type Route struct { BaseInfo URI string `json:"uri,omitempty"` Uris []string `json:"uris,omitempty"` - Name string `json:"name" validate:"max=50"` - Desc string `json:"desc,omitempty" validate:"max=256"` + Name string `json:"name"` + Desc string `json:"desc,omitempty"` Priority int `json:"priority,omitempty"` Methods []string `json:"methods,omitempty"` Host string `json:"host,omitempty"` @@ -280,7 +280,7 @@ type ServerInfo struct { // swagger:model GlobalPlugins type PluginConfig struct { BaseInfo - Desc string `json:"desc,omitempty" validate:"max=256"` + Desc string `json:"desc,omitempty"` Plugins map[string]interface{} `json:"plugins"` Labels map[string]string `json:"labels,omitempty"` } diff --git a/api/test/e2e/route/route_test.go b/api/test/e2e/route/route_test.go index 7fd8d6bb02..e3c2f3e6ca 100644 --- a/api/test/e2e/route/route_test.go +++ b/api/test/e2e/route/route_test.go @@ -64,6 +64,23 @@ var _ = Describe("Route", func() { Headers: map[string]string{"Authorization": base.GetToken()}, ExpectStatus: http.StatusOK, }), + Entry("create long name route3 success", base.HttpTestCase{ + Object: base.ManagerApiExpect(), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r3", + Body: `{ + "name": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", + "uri": "/hello_", + "upstream": { + "nodes": { + "` + base.UpstreamIp + `:1980": 1 + }, + "type": "roundrobin" + } + }`, + Headers: map[string]string{"Authorization": base.GetToken()}, + ExpectStatus: http.StatusOK, + }), Entry("create route failed, name existed", base.HttpTestCase{ Object: base.ManagerApiExpect(), Method: http.MethodPost, @@ -147,6 +164,13 @@ var _ = Describe("Route", func() { Headers: map[string]string{"Authorization": base.GetToken()}, ExpectStatus: http.StatusOK, }), + Entry("delete route3", base.HttpTestCase{ + Object: base.ManagerApiExpect(), + Method: http.MethodDelete, + Path: "/apisix/admin/routes/r3", + Headers: map[string]string{"Authorization": base.GetToken()}, + ExpectStatus: http.StatusOK, + }), Entry("hit route1 that just deleted", base.HttpTestCase{ Object: base.APISIXExpect(), Method: http.MethodGet, diff --git a/web/cypress/e2e/route/create-route-with-proxy-rewrite-plugin.cy.js b/web/cypress/e2e/route/create-route-with-proxy-rewrite-plugin.cy.js index 721d317c35..4086a4bcc4 100644 --- a/web/cypress/e2e/route/create-route-with-proxy-rewrite-plugin.cy.js +++ b/web/cypress/e2e/route/create-route-with-proxy-rewrite-plugin.cy.js @@ -15,8 +15,8 @@ * limitations under the License. */ /* eslint-disable no-undef */ -import menuLocaleUS from '../../../src/locales/en-US/menu'; import componentLocaleUS from '../../../src/locales/en-US/component'; +import menuLocaleUS from '../../../src/locales/en-US/menu'; import routeLocaleUS from '../../../src/pages/Route/locales/en-US'; context('create route with proxy-rewrite plugin', () => { @@ -29,6 +29,7 @@ context('create route with proxy-rewrite plugin', () => { deleteAlert: '.ant-modal-body', notification: '.ant-notification-notice-message', staticUri: '[data-cy=uri-static]', + regexUri: '[data-cy=uri-regex]', staticHost: '[data-cy=host-static]', keepHost: '[data-cy=host-keep]', newUri: '#proxyRewrite_uri', @@ -56,6 +57,7 @@ context('create route with proxy-rewrite plugin', () => { rewriteHeaderKey2: 'test2', rewriteHeaderValue1: '1', rewriteHeaderValue2: '2', + regex: '^/iresty/(.)/(.)/(.*)', }; beforeEach(() => { @@ -154,6 +156,30 @@ context('create route with proxy-rewrite plugin', () => { cy.contains(data.submitSuccess).should('be.visible'); }); + it('should use proxy rewrite in regex uri moode without template', () => { + cy.visit('/'); + cy.contains(menuLocaleUS['menu.routes']).click(); + + cy.get(selector.nameSelector).type(data.routeName); + cy.contains('Search').click(); + cy.contains(data.routeName).siblings().contains('Configure').click(); + + cy.get('#status').should('have.class', 'ant-switch-checked'); + cy.get(selector.regexUri).click(); + cy.get(selector.uriRewriteReg).should('be.visible').type(data.regex); + cy.get(selector.uriRewriteTemp).should('have.value', ''); + cy.contains('Next').click(); + cy.get(selector.nodes_0_host).type(data.host2); + cy.get(selector.nodes_0_port).type(data.port); + cy.get(selector.nodes_0_weight).type(data.weight); + cy.contains('Next').click(); + + cy.contains('proxy-rewrite').should('not.exist'); + cy.contains('Next').click(); + cy.contains('Submit').click(); + cy.contains(data.submitSuccess).should('be.visible'); + }); + it('should delete the route', function () { cy.visit('/routes/list'); cy.get(selector.nameSelector).type(data.routeName); diff --git a/web/src/helpers.tsx b/web/src/helpers.tsx index 0ee105032e..bc9f5af3cf 100644 --- a/web/src/helpers.tsx +++ b/web/src/helpers.tsx @@ -18,6 +18,7 @@ import { FileTextOutlined, InfoCircleOutlined } from '@ant-design/icons'; import type { MenuDataItem } from '@ant-design/pro-layout'; import { notification } from 'antd'; import yaml from 'js-yaml'; +import { isNumber } from 'lodash'; import moment from 'moment'; import React from 'react'; import { history } from 'umi'; @@ -128,12 +129,11 @@ export const getUrlQuery: (key: string) => string | false = (key: string) => { }; export const timestampToLocaleString = (timestamp: number) => { - if (!timestamp) { - // TODO: i18n - return 'None'; + if (isNumber(timestamp)) { + return moment.unix(timestamp).format('YYYY-MM-DD HH:mm:ss'); } - return moment.unix(timestamp).format('YYYY-MM-DD HH:mm:ss'); + return 'None'; }; /** diff --git a/web/src/pages/Route/components/Step1/ProxyRewrite.tsx b/web/src/pages/Route/components/Step1/ProxyRewrite.tsx index 7770ab213e..cbe8738410 100644 --- a/web/src/pages/Route/components/Step1/ProxyRewrite.tsx +++ b/web/src/pages/Route/components/Step1/ProxyRewrite.tsx @@ -100,14 +100,6 @@ const ProxyRewrite: React.FC = ({ form, disabled }) label={formatMessage({ id: 'page.route.form.itemLabel.template' })} name={field.name} key={field.name} - rules={[ - { - required: true, - message: `${formatMessage({ - id: 'component.global.pleaseEnter', - })} ${formatMessage({ id: 'page.route.form.itemLabel.template' })}`, - }, - ]} > = ({ form, disabled }) { value: URI_REWRITE_TYPE.REGEXP, label: formatMessage({ id: 'page.route.radio.regex' }), + dataCypress: 'uri-regex', }, ]; diff --git a/web/src/pages/SSL/typing.d.ts b/web/src/pages/SSL/typing.d.ts index 985e3051a3..3c9281cc4f 100644 --- a/web/src/pages/SSL/typing.d.ts +++ b/web/src/pages/SSL/typing.d.ts @@ -52,7 +52,7 @@ declare namespace SSLModule { snis: string[]; status: number; update_time: number; - validity_start: number; - validity_end: number; + validity_start?: number; + validity_end?: number; }; }