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

Creation of e2e test for favorite tasks #819

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
274ca26
Selecting a favorite task changes taskRequests, instead of append (#761)
aaronchongth Aug 31, 2023
58f4869
Feature/task table auto update (#763)
aaronchongth Sep 7, 2023
3388e03
Reverting to latest pnpm version when #6994 is fixed (#754)
aaronchongth Sep 7, 2023
8a4415e
Feature/form input required (#764)
aaronchongth Sep 8, 2023
0d352fe
Display an alert when low display res detected (#767)
aaronchongth Sep 8, 2023
c885e3d
Feature/scheduling month day (#765)
aaronchongth Sep 8, 2023
a3f3615
Editing the schedule (#770)
Angatupyry Sep 19, 2023
b04b8b6
Fixes prompt text, do not display ack button if not awknowledged and …
aaronchongth Sep 20, 2023
34c69c5
start:react builds dependencies before starting dashboard, start just…
aaronchongth Sep 20, 2023
c1d78d2
Schedule event title (#782)
Angatupyry Sep 20, 2023
04eaa15
Support offline doc generation (#784)
aaronchongth Sep 22, 2023
4e4e336
Merge pull request #786 from open-rmf/fix/split-cache-and-static
aaronchongth Sep 25, 2023
c9c4570
Fix - schedule single event (#791)
Angatupyry Oct 6, 2023
99ecd31
Detect 0 as number as well (#793)
aaronchongth Oct 9, 2023
72b99d0
Migration to React three fiber (#775)
Angatupyry Oct 11, 2023
67ed39b
Re-introduced and refactored zoom button implementation (#800)
aaronchongth Oct 12, 2023
f2df563
Fix/doors pagination (#803)
aaronchongth Oct 12, 2023
d3e0c29
Retain camera position after changing tabs (#802)
Angatupyry Oct 12, 2023
f722d64
Fix wheel behavior (#805)
Angatupyry Oct 13, 2023
59065b1
Fix oddly failing robot label and use same as other labels (#812)
aaronchongth Oct 20, 2023
e8ded63
Create e2e test to favorite task
Angatupyry Oct 26, 2023
4947372
Fix lint error
Angatupyry Oct 26, 2023
db60f9c
Using icon to display robot (#809)
Angatupyry Oct 30, 2023
3c19fe6
Test for react three fiber component (#816)
Angatupyry Oct 31, 2023
6f7da8c
Display robot according to its level correctly (#824)
Angatupyry Nov 2, 2023
574de78
Fix recursive call in effect (#826)
aaronchongth Nov 3, 2023
5adca40
Can't submit favorite task with the same name
Angatupyry Nov 9, 2023
c1a6269
Add test for duplicate favorite task name and delete favorite task
Angatupyry Nov 9, 2023
9952c54
Resolve merge conflict with main
Angatupyry Nov 9, 2023
15a9c62
Create longer timeout to accommodate slower runner
aaronchongth Nov 12, 2023
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
2 changes: 1 addition & 1 deletion .github/actions/bootstrap/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ runs:
steps:
- uses: pnpm/[email protected]
with:
version: '8.6.12'
version: 'latest'
- uses: actions/setup-node@v2
with:
node-version: '16'
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ jobs:
- name: setup python
run: apt update && apt install -y python3-venv python-is-python3
- name: bootstrap
env:
NODE_OPTIONS: '--max_old_space_size=4096'
uses: ./.github/actions/bootstrap
with:
package: rmf-dashboard
Expand Down
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packages/api-server/api_server/static/

142 changes: 142 additions & 0 deletions packages/api-client/lib/openapi/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8431,6 +8431,69 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration
...options.headers,
};

return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateScheduleTaskScheduledTasksTaskIdUpdatePost: async (
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options: AxiosRequestConfig = {},
): Promise<RequestArgs> => {
// verify required parameter 'taskId' is not null or undefined
assertParamExists('updateScheduleTaskScheduledTasksTaskIdUpdatePost', 'taskId', taskId);
// verify required parameter 'postScheduledTaskRequest' is not null or undefined
assertParamExists(
'updateScheduleTaskScheduledTasksTaskIdUpdatePost',
'postScheduledTaskRequest',
postScheduledTaskRequest,
);
const localVarPath = `/scheduled_tasks/{task_id}/update`.replace(
`{${'task_id'}}`,
encodeURIComponent(String(taskId)),
);
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}

const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options };
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;

if (exceptDate !== undefined) {
localVarQueryParameter['except_date'] =
(exceptDate as any) instanceof Date ? (exceptDate as any).toISOString() : exceptDate;
}

localVarHeaderParameter['Content-Type'] = 'application/json';

setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {
...localVarHeaderParameter,
...headersFromBaseOptions,
...options.headers,
};
localVarRequestOptions.data = serializeDataIfNeeded(
postScheduledTaskRequest,
localVarRequestOptions,
configuration,
);

return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
Expand Down Expand Up @@ -8891,6 +8954,35 @@ export const TasksApiFp = function (configuration?: Configuration) {
);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options?: AxiosRequestConfig,
): Promise<
(
axios?: AxiosInstance,
basePath?: string,
) => AxiosPromise<ApiServerModelsTortoiseModelsScheduledTaskScheduledTask>
> {
const localVarAxiosArgs =
await localVarAxiosParamCreator.updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId,
postScheduledTaskRequest,
exceptDate,
options,
);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
};
};

Expand Down Expand Up @@ -9271,6 +9363,30 @@ export const TasksApiFactory = function (
)
.then((request) => request(axios, basePath));
},
/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options?: any,
): AxiosPromise<ApiServerModelsTortoiseModelsScheduledTaskScheduledTask> {
return localVarFp
.updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId,
postScheduledTaskRequest,
exceptDate,
options,
)
.then((request) => request(axios, basePath));
},
};
};

Expand Down Expand Up @@ -9680,4 +9796,30 @@ export class TasksApi extends BaseAPI {
)
.then((request) => request(this.axios, this.basePath));
}

/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof TasksApi
*/
public updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options?: AxiosRequestConfig,
) {
return TasksApiFp(this.configuration)
.updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId,
postScheduledTaskRequest,
exceptDate,
options,
)
.then((request) => request(this.axios, this.basePath));
}
}
2 changes: 1 addition & 1 deletion packages/api-client/lib/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { version as rmfModelVer } from 'rmf-models';

export const version = {
rmfModels: rmfModelVer,
rmfServer: 'c8c43e395caae7ccc858008b7663d30914b2cc62',
rmfServer: '60cfa28fb26433cb33254ba1522fc00466fe7146',
openapiGenerator: '6.2.1',
};
47 changes: 47 additions & 0 deletions packages/api-client/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,53 @@ export default {
},
},
},
'/scheduled_tasks/{task_id}/update': {
post: {
tags: ['Tasks'],
summary: 'Update Schedule Task',
operationId: 'update_schedule_task_scheduled_tasks__task_id__update_post',
parameters: [
{
required: true,
schema: { title: 'Task Id', type: 'integer' },
name: 'task_id',
in: 'path',
},
{
required: false,
schema: { title: 'Except Date', type: 'string', format: 'date-time' },
name: 'except_date',
in: 'query',
},
],
requestBody: {
content: {
'application/json': {
schema: { $ref: '#/components/schemas/PostScheduledTaskRequest' },
},
},
required: true,
},
responses: {
'201': {
description: 'Successful Response',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/api_server.models.tortoise_models.scheduled_task.ScheduledTask',
},
},
},
},
'422': {
description: 'Validation Error',
content: {
'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } },
},
},
},
},
},
'/favorite_tasks': {
get: {
tags: ['Tasks'],
Expand Down
60 changes: 50 additions & 10 deletions packages/api-server/api_server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
import schedule
from fastapi import Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
from tortoise import Tortoise

Expand All @@ -27,7 +32,7 @@
User,
)
from .models import tortoise_models as ttm
from .repositories import StaticFilesRepository, TaskRepository
from .repositories import TaskRepository
from .rmf_io import HealthWatchdog, RmfBookKeeper, rmf_events
from .types import is_coroutine

Expand All @@ -46,7 +51,12 @@ async def on_sio_connect(sid: str, _environ: dict, auth: Optional[dict] = None):
return False


app = FastIO(title="RMF API Server", socketio_connect=on_sio_connect)
app = FastIO(
title="RMF API Server",
socketio_connect=on_sio_connect,
docs_url=None,
redoc_url=None,
)


app.add_middleware(
Expand All @@ -56,22 +66,25 @@ async def on_sio_connect(sid: str, _environ: dict, auth: Optional[dict] = None):
allow_methods=["*"],
allow_headers=["*"],
)
os.makedirs(app_config.static_directory, exist_ok=True)

app.mount(
"/static",
StaticFiles(directory=app_config.static_directory),
StaticFiles(
directory=os.path.join(os.path.dirname(os.path.abspath(__file__)), "static")
),
name="static",
)

os.makedirs(app_config.cache_directory, exist_ok=True)
app.mount(
"/cache",
StaticFiles(directory=app_config.cache_directory),
name="cache",
)

# will be called in reverse order on app shutdown
shutdown_cbs: List[Union[Coroutine[Any, Any, Any], Callable[[], None]]] = []

static_files_repo = StaticFilesRepository(
f"{app_config.public_url.geturl()}/static",
app_config.static_directory,
logger.getChild("static_files"),
)

rmf_bookkeeper = RmfBookKeeper(rmf_events, logger=logger.getChild("BookKeeper"))

app.include_router(routes.main_router)
Expand Down Expand Up @@ -202,6 +215,33 @@ async def on_shutdown():
logger.info("shutdown app")


@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
openapi_url = app.openapi_url if app.openapi_url is not None else "/openapi.json"
return get_swagger_ui_html(
openapi_url=openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)


@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()


@app.get("/redoc", include_in_schema=False)
async def redoc_html():
openapi_url = app.openapi_url if app.openapi_url is not None else "/openapi.json"
return get_redoc_html(
openapi_url=openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)


async def _spin_scheduler():
while True:
schedule.run_pending()
Expand Down
2 changes: 1 addition & 1 deletion packages/api-server/api_server/app_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class AppConfig:
port: int
db_url: str
public_url: urllib.parse.ParseResult
static_directory: str
cache_directory: str
log_level: str
builtin_admin: str
jwt_public_key: Optional[str]
Expand Down
2 changes: 1 addition & 1 deletion packages/api-server/api_server/default_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# When being a proxy, this must be the url that rmf-server is mounted on.
# E.g. https://example.com/rmf/api/v1
"public_url": "http://localhost:8000",
"static_directory": "static", # The directory where static files should be stored.
"cache_directory": "run/cache", # The directory where cached files should be stored.
"log_level": "WARNING", # https://docs.python.org/3.8/library/logging.html#levels
# a user that is automatically given admin privileges, note that this does not guarantee that the user exists in the identity provider.
"builtin_admin": "admin",
Expand Down
2 changes: 2 additions & 0 deletions packages/api-server/api_server/fast_io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ def __init__(
**kwargs,
):
super().__init__(*args, **kwargs)
if self.swagger_ui_oauth2_redirect_url is None:
self.swagger_ui_oauth2_redirect_url = "docs/oauth2-redirect"
self.sio = socketio.AsyncServer(
async_mode="asgi", cors_allowed_origins=[], serializer=FastIOPacket
)
Expand Down
Loading
Loading