Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 api_version.lock
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.1.483
v0.1.484
26 changes: 26 additions & 0 deletions examples/teleop-react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.env

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
2 changes: 1 addition & 1 deletion examples/teleop-react/src/components/connect-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const ConnectForm = (props: ConnectFormProps): JSX.Element => {
setApiKeyId(event.target.value);
};
const handleApiKey: ChangeEventHandler<HTMLInputElement> = (event) => {
setApiKeyId(event.target.value);
setApiKey(event.target.value);
};
const handleSubmit: FormEventHandler = (event) => {
onSubmit({ hostname, apiKeyId, apiKey });
Expand Down
61 changes: 29 additions & 32 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
},
"devDependencies": {
"@bufbuild/buf": "^1.15.0-1",
"@playwright/test": "1.45.3",
"@playwright/test": "1.56.1",
"@types/node": "^20.11.10",
"@typescript-eslint/eslint-plugin": "^6.17.0",
"@typescript-eslint/parser": "^6.17.0",
Expand All @@ -74,7 +74,7 @@
"eslint-plugin-tsdoc": "^0.2.17",
"eslint-plugin-vitest": "^0.3.20",
"grpc-web": "^1.4.2",
"happy-dom": "^15.10.1",
"happy-dom": "^20.0.8",
"npm-check-updates": "^17.1.11",
"prettier": "^3.1.1",
"prettier-plugin-jsdoc": "^1.1.1",
Expand Down
89 changes: 29 additions & 60 deletions src/app/viam-client.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// @vitest-environment happy-dom

import { beforeEach, describe, expect, it, vi } from 'vitest';
import { Location, RobotPart, SharedSecret_State } from '../gen/app/v1/app_pb';
import {
GetRobotPartByNameAndLocationResponse,
RobotPart,
} from '../gen/app/v1/app_pb';
import { createRobotClient } from '../robot/dial';
import { AppClient } from './app-client';
import { BillingClient } from './billing-client';
Expand Down Expand Up @@ -156,98 +159,64 @@ describe('ViamClient', () => {
).rejects.toThrowError('not provided and could not be obtained');
});

it('gets location secret if credential is access token -- host', async () => {
it('gets robot secret if credential is access token -- host', async () => {
options = { credentials: testAccessToken };
const client = await subject();

const location = new Location({
auth: {
secrets: [
{
id: '0',
state: SharedSecret_State.DISABLED, // eslint-disable-line camelcase
secret: 'disabled secret',
},
{
id: '1',
state: SharedSecret_State.UNSPECIFIED, // eslint-disable-line camelcase
secret: 'unspecified secret',
},
{
id: '2',
state: SharedSecret_State.ENABLED, // eslint-disable-line camelcase
secret: 'enabled secret',
},
],
locationId: 'location',
secret: 'secret',
},
const MAIN_PART = new RobotPart({
mainPart: true,
name: 'main-part',
secret: 'fake-robot-secret',
});
const getLocationMock = vi.fn().mockImplementation(() => location);
AppClient.prototype.getLocation = getLocationMock;
const partByNameAndLocationResponse =
new GetRobotPartByNameAndLocationResponse({
part: MAIN_PART,
});
const getRobotPartByNameAndLocationMock = vi
.fn()
.mockImplementation(() => partByNameAndLocationResponse);
AppClient.prototype.getRobotPartByNameAndLocation =
getRobotPartByNameAndLocationMock;

await client.connectToMachine({
host: 'main-part.location.viam.cloud',
});
expect(getLocationMock).toHaveBeenCalledWith('location');
expect(getRobotPartByNameAndLocationMock).toHaveBeenCalledWith(
'main-part',
'location'
);
expect(createRobotClient).toHaveBeenCalledWith(
expect.objectContaining({
credentials: expect.objectContaining({
type: 'robot-location-secret',
payload: 'enabled secret',
type: 'robot-secret',
payload: 'fake-robot-secret',
}),
})
);
});

it('gets location secret if credential is access token -- id', async () => {
it('gets robot secret if credential is access token -- id', async () => {
options = { credentials: testAccessToken };
const client = await subject();

const MAIN_PART = new RobotPart({
mainPart: true,
locationId: 'location-id',
fqdn: 'main-part.fqdn',
secret: 'fake-robot-secret',
});
const robotParts = [MAIN_PART];
const getRobotPartsMock = vi.fn().mockImplementation(() => robotParts);
AppClient.prototype.getRobotParts = getRobotPartsMock;

const location = new Location({
auth: {
secrets: [
{
id: '0',
state: SharedSecret_State.DISABLED, // eslint-disable-line camelcase
secret: 'disabled secret',
},
{
id: '1',
state: SharedSecret_State.UNSPECIFIED, // eslint-disable-line camelcase
secret: 'unspecified secret',
},
{
id: '2',
state: SharedSecret_State.ENABLED, // eslint-disable-line camelcase
secret: 'enabled secret',
},
],
locationId: 'location',
secret: 'secret',
},
});
const getLocationMock = vi.fn().mockImplementation(() => location);
AppClient.prototype.getLocation = getLocationMock;

await client.connectToMachine({
id: 'machine-uuid',
});
expect(getLocationMock).toHaveBeenCalledWith('location-id');
expect(getRobotPartsMock).toHaveBeenCalledWith('machine-uuid');
expect(createRobotClient).toHaveBeenCalledWith(
expect.objectContaining({
credentials: expect.objectContaining({
type: 'robot-location-secret',
payload: 'enabled secret',
type: 'robot-secret',
payload: 'fake-robot-secret',
}),
})
);
Expand Down
Loading