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

Incomplete field names for nested arrays #1021

Open
2 of 4 tasks
aquavitae opened this issue Jun 18, 2021 · 5 comments
Open
2 of 4 tasks

Incomplete field names for nested arrays #1021

aquavitae opened this issue Jun 18, 2021 · 5 comments

Comments

@aquavitae
Copy link

Sorting

  • I'm submitting a ...

    • bug report
    • feature request
    • support request
  • I confirm that I

    • used the search to make sure that a similar issue hasn't already been submit

Expected Behavior

Given a model and controller such as this

export interface Root {
  item: {
    children: {
      name: string;
    }[];
  };
}

@Route('root')
export class RootController extends Controller {
  @Post()
  public async root(@Body() payload: Root): Promise<string> {
    this.setStatus(200);
    return Promise.resolve('ok');
  }
}

and passing it a payload such as {"item":{"children":[{}]}}, I would expect a validation error referencing a missing field at payload.item.$0.children.$0.name. In fact, the validation error references children.$0.name.

It looks like the problem is that parent is not included in https://github.com/lukeautry/tsoa/blob/master/packages/runtime/src/routeGeneration/templateHelpers.ts#L410 and https://github.com/lukeautry/tsoa/blob/master/packages/runtime/src/routeGeneration/templateHelpers.ts#L413. In both those, I suspect that the call should actually be

this.ValidateParam(schema, elementValue, `$${index}`, fieldErrors, parent + name + '.', swaggerConfig);

I'm happy to submit a PR if I'm on the right track with this.

@github-actions
Copy link

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

@github-actions github-actions bot added the Stale label Jul 19, 2021
@aquavitae
Copy link
Author

bump

@WoH
Copy link
Collaborator

WoH commented Jul 22, 2021

I haven't tried to reproduce this, but if you send a PR, the proof should be in the tests.

@igarioshka
Copy link

igarioshka commented Jul 8, 2022

We've also experienced this with a different set of parameters:

Given a model:

interface Child {
  Id: number; 
}
interface ParentModel {
 children: Child[];
}

and controller:

public async createParent(@Body() requestBody: ParentModel[]): Promise<ParentModel[]> {
}

and request:

[
    {
    "children": [{Id:5},{Id:10}]
    },
    {
    "children": [{Id:"string"},{Id:"string"}]
    }
]

the error would contain paths:

children.$0.Id
children.$1.Id

but not the parent index.

@igarioshka
Copy link

igarioshka commented Jul 11, 2022

@WoH, here's a failing templateHelpers.spec.ts test describing the defect:

    it('should invalid array nested value with ref array', () => {
      const name = 'name';
      const value = [{ child: [{ a: 'bcd' }] }, { child: [{ a: 123 }, { a: 'bcd' }] }];
      const error: FieldErrors = {};
      const result = new ValidationService({
        ExampleModel: {
          dataType: 'refObject',
          properties: {
            child: { dataType: 'array', array: { dataType: 'refObject', ref: 'ExampleInternal' }, required: true },
          },
          additionalProperties: false,
        },
        ExampleInternal: {
          dataType: 'refObject',
          properties: {
            a: { dataType: 'string', required: true },
          },
          additionalProperties: false,
        },
      }).validateArray(name, value, error, { noImplicitAdditionalProperties: 'ignore' }, { ref: 'ExampleModel' });
      expect(result).to.deep.equal(undefined);
      expect(error).to.deep.equal({
        [`${name}.$1.child.$0.a`]: {
          message: 'invalid string value',
          value: 123,
        },
      });
    });

and a second failing test, reveling side effects of the issue:

    it('should generate error for both invalid properties', () => {
      const name = 'name';
      const value = [{ child: [{ a: 123 }, { a: 'bcd' }] }, { child: [{ a: 123 }, { a: 'bcd' }] }];
      const error: FieldErrors = {};
      const result = new ValidationService({
        ExampleModel: {
          dataType: 'refObject',
          properties: {
            child: { dataType: 'array', array: { dataType: 'refObject', ref: 'ExampleInternal' }, required: true },
          },
          additionalProperties: false,
        },
        ExampleInternal: {
          dataType: 'refObject',
          properties: {
            a: { dataType: 'string', required: true },
          },
          additionalProperties: false,
        },
      }).validateArray(name, value, error, { noImplicitAdditionalProperties: 'ignore' }, { ref: 'ExampleModel' });
      expect(result).to.deep.equal(undefined);
      expect(Object.keys(error).length).to.equal(2);
    });

@blipk blipk mentioned this issue Sep 6, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants