Skip to content

Commit

Permalink
add logic for boolean input; add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dfoxg committed Apr 23, 2024
1 parent 92b203a commit 10af257
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 36 deletions.
67 changes: 67 additions & 0 deletions kratos-admin-ui/src/components/traits/single-field.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import { SingleField } from './single-field'
import exp from 'constants'

describe("test SingleField", () => {

test("check boolean return value", async () => {

const result = render(<SingleField
fieldValues={
{
traits: { test: true },
publicMetadata: {},
adminMetadata: {},
state: 'active'
}
}
setValues={() => { }}
schemaField={
{
name: "test",
format: "boolean",
title: "test",
fieldKind: 'trait',
required: false,
type: "boolean",
subType: "boolean"
}
}
/>)

const checkbox: HTMLInputElement = result.container.querySelector("#checkbox-r0")!;
expect(checkbox).toBeDefined();
expect(checkbox.checked).toBeTruthy();
})

test("check string value", async () => {

const result = render(<SingleField
fieldValues={
{
traits: { test: "jojojo" },
publicMetadata: {},
adminMetadata: {},
state: 'active'
}
}
setValues={() => { }}
schemaField={
{
name: "test",
format: "email",
title: "test",
fieldKind: 'trait',
required: true,
type: "string",
subType: "email"
}
}
/>)

const input: HTMLInputElement = result.container.querySelector("input")!;
expect(input).toBeDefined();
expect(input.value).toBe("jojojo")
})
})
73 changes: 49 additions & 24 deletions kratos-admin-ui/src/components/traits/single-field.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Field, Input } from "@fluentui/react-components"
import { Checkbox, Field, Input } from "@fluentui/react-components"
import { SchemaField, mapSchemaDataType } from "../../service/schema-service"
import { ValueObject, mapFieldKindToValueKey } from "./edit-traits"

Expand All @@ -8,6 +8,7 @@ interface SingleFieldProps {
setValues(values: ValueObject): void
}


function getDefaultValue(schemaField: SchemaField, values: ValueObject): string {
const fieldKindKey = mapFieldKindToValueKey(schemaField.fieldKind);
if (schemaField.type === "array") {
Expand All @@ -26,33 +27,57 @@ function getDefaultValue(schemaField: SchemaField, values: ValueObject): string
return "";
}

function getBooleanValue(schemaField: SchemaField, values: ValueObject): boolean {
const val = getDefaultValue(schemaField, values);
if (val || val == "true") {
return true;
}
return false;
}

function updateInputValue(value: any, props: SingleFieldProps) {
if (props.fieldValues) {
const fieldKindKey = mapFieldKindToValueKey(props.schemaField.fieldKind);
if (props.schemaField.parentName) {
if (!props.fieldValues[fieldKindKey][props.schemaField.parentName]) {
props.fieldValues[fieldKindKey][props.schemaField.parentName] = {}
}
props.fieldValues[fieldKindKey][props.schemaField.parentName][props.schemaField.name] = value
} else {
props.fieldValues[fieldKindKey][props.schemaField.name] = value
}
props.setValues(props.fieldValues)
}
}

export function SingleField(props: SingleFieldProps) {

return (
<>
<Field
label={props.schemaField.title}
required={props.schemaField.required}
>
<Input
onChange={(event, value) => {
if (props.fieldValues) {
const fieldKindKey = mapFieldKindToValueKey(props.schemaField.fieldKind);
if (props.schemaField.parentName) {
if (!props.fieldValues[fieldKindKey][props.schemaField.parentName]) {
props.fieldValues[fieldKindKey][props.schemaField.parentName] = {}
}
props.fieldValues[fieldKindKey][props.schemaField.parentName][props.schemaField.name] = value.value
} else {
props.fieldValues[fieldKindKey][props.schemaField.name] = value.value
}
props.setValues(props.fieldValues)
}
}}
defaultValue={getDefaultValue(props.schemaField, props.fieldValues)}
type={mapSchemaDataType(props.schemaField.format)}
></Input>
</Field>

{props.schemaField.type === "boolean" &&
<Checkbox
label={props.schemaField.title}
required={props.schemaField.required}
defaultChecked={getBooleanValue(props.schemaField, props.fieldValues)}
onChange={(event, value) => { updateInputValue(value.checked, props); }}
>

</Checkbox>
}
{props.schemaField.type !== "boolean" &&
<Field
label={props.schemaField.title}
required={props.schemaField.required}
>
<Input
onChange={(event, value) => { updateInputValue(value.value, props); }}
defaultValue={getDefaultValue(props.schemaField, props.fieldValues)}
type={mapSchemaDataType(props.schemaField.format)}
></Input>
</Field>
}

</>
)

Expand Down
102 changes: 92 additions & 10 deletions kratos-admin-ui/src/service/schema-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,13 +359,13 @@ describe("test getSchemaFields", () => {
"metadata_public": {
"type": "object",
"properties": {
"groups": {
"title": "Groups",
"type": "array",
"items": {
"type": "string"
"groups": {
"title": "Groups",
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
}
Expand Down Expand Up @@ -419,10 +419,10 @@ describe("test getSchemaFields", () => {
"metadata_admin": {
"type": "object",
"properties": {
"notes": {
"title": "Notes",
"type": "string"
}
"notes": {
"title": "Notes",
"type": "string"
}
}
},
}
Expand All @@ -439,4 +439,86 @@ describe("test getSchemaFields", () => {
expect(fields[1].title).toBe("Notes");
expect(fields[1].fieldKind).toBe("metadata_admin");
})


test("test boolean schema", () => {
const schema = {
"$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"definitions": {
"tosUrl": {
"type": "string",
"const": "http://example.com/terms"
}
},
"properties": {
"traits": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"title": "E-Mail",
"minLength": 3,
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
},
"verification": {
"via": "email"
},
"recovery": {
"via": "email"
}
}
},
"username": {
"title": "Username",
"type": "string",
"readOnly": true
},
"name": {
"type": "object",
"properties": {
"first": {
"title": "First Name",
"type": "string"
},
"last": {
"title": "Last Name",
"type": "string"
}
}
},
"tos": {
"title": "Accept Terms of Service",
"type": "boolean",
"description": "I accept the terms of service",
"writeOnly": true,
"tosUrl": {
"$ref": "#/definitions/tosUrl"
}
},
"newsletter": {
"type": "boolean",
"title": "Newsletter subscription"
}
},
"required": [
"email",
"username",
"tos"
],
"additionalProperties": false
}
}
}

const fields: SchemaField[] = SchemaService.getSchemaFields(schema);
expect(fields[4].type).toBe("boolean");
})
})
11 changes: 9 additions & 2 deletions kratos-admin-ui/src/sites/identities/view/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ export class ViewIdentitySite extends React.Component<any, ViewIdentityState> {
return typeof object === 'object' && object !== null;
}

getStringValue(any: any) : string {
if (typeof any === "boolean") {
return any.toString();
}
return any;
}

getUnorderdList(object: any): ReactNode {
return (
<ul>
Expand All @@ -51,7 +58,7 @@ export class ViewIdentitySite extends React.Component<any, ViewIdentityState> {
}
{this.isObject(object[element]) ||
<li>
<b>{element}</b>: {object[element]}
<b>{element}</b>: {this.getStringValue(object[element])}
</li>
}
</div>
Expand Down Expand Up @@ -84,7 +91,7 @@ export class ViewIdentitySite extends React.Component<any, ViewIdentityState> {
mapCredentials(credentials?: { [key: string]: IdentityCredentials }): string {
if (credentials) {
return Object.entries(credentials).map(e => {
return e[0] + " (" + e[1].identifiers + ")";
return e[0] + " (" + e[1].identifiers + ")";
}).join(", ");
}
return ""
Expand Down

0 comments on commit 10af257

Please sign in to comment.