influxdata / influxdata/openapi

Create Bucket not enforcing required properties listed in openapi cloud.json

Open
#340 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Shell
Stars
18
Forks
9
PR merge metrics
No merged PRs in 30d

Description

I'm updating grace tests for the endpoint /buckets. I've noticed in OpenAPI that for [POST] /buckets properties marked as "required" in the OpenAPI contract, are not enforced as "required", when making an actual request. The "required" properties in question are name and retentionRules

$ jq '.paths."/buckets".post.requestBody.content."application/json".schema."$ref"' cloud.json
"#/components/schemas/PostBucketRequest"
$ jq '.components.schemas.PostBucketRequest.required' cloud.json
[
  "orgID",
  "name",
  "retentionRules"
]

Note - this is as much a question as it is a report. Do you find this behavior acceptable so that it should be included in grace tests? Or should this be fixed?

Steps to reproduce:
List the minimal actions needed to reproduce the behavior.

  1. create a PostBucketRequest object with 1. an empty name, 2. without a name or 3. without retentionRules as specified as "required" in cloud.json
  2. POST the request to a valid organization using valid credentials

Expected behavior:
Expected the request to be rejected since it contains invalid or empty values for "required" properties.

Note that when preparing tests, we are attempting to use OpenAPI and specifically cloud.json as the source of truth for how the API should behave.

Actual behavior:
The new bucket is created with an empty name or with empty retentionRules. The HTTP response is 201 successfully created.

Environment info:

Testing against K8SIDPE.

latest commit.

commit c11561562b2758f806fcf89f06f3c8197f9748ad (HEAD -> master, origin/master, origin/alchemy/automatic, origin/HEAD)
Author: Hercules Mango Churchill <alchemy@influxdata.com>
Date:   Sat May 28 19:19:09 2022 +0000

Proposed tests - proforma

empty name

         it('BucketsApi: createBucket: Create bucket failure - invalid name', async () => {

            // zero length string
            testBucketReq.name = ''
            let expStatus = 201

            // zero length name allowed
            await request(url)
              .post('/buckets')
              .set('Authorization', `Token ${localAuth.token}`)
              .set('Content-Type', 'application/json')
              .send(JSON.stringify(testBucketReq))
              .then(async (response) => {
                 await helpers.assertHttpStatus(expStatus, response, testBucketReq)
                 ;({body: localBucket} = response)
                 await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
              })

            testBucketReq.name = null

            await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)

            await request(url)
              .post('/buckets')
              .set('Authorization', `Token ${localAuth.token}`)
              .set('Content-Type', 'application/json')
              .send(JSON.stringify(testBucketReq))
              .then(async (response) => {
                 await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
                 ;({body: localBucket} = response)
                 await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
              })

            testBucketReq.name = undefined
            await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)
            await request(url)
              .post('/buckets')
              .set('Authorization', `Token ${localAuth.token}`)
              .set('Content-Type', 'application/json')
              .send(JSON.stringify(testBucketReq))
              .then(async (response) => {
                 await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
                 ;({body: localBucket} = response)
                 await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
              })

            delete testBucketReq.name
            await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)
            await request(url)
              .post('/buckets')
              .set('Authorization', `Token ${localAuth.token}`)
              .set('Content-Type', 'application/json')
              .send(JSON.stringify(testBucketReq))
              .then(async (response) => {
                 await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
                 ;({body: localBucket} = response)
                 await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
              })
         })

empty retentionRules

         it('BucketsApi: createBucket: Create bucket failure - invalid retentionRules', async () => {

            delete testBucketReq.retentionRules
            let expStatus = 201
            await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)
            await request(url)
              .post('/buckets')
              .set('Authorization', `Token ${localAuth.token}`)
              .set('Content-Type', 'application/json')
              .send(JSON.stringify(testBucketReq))
              .then(async (response) => {
                 await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
                 ;({body: localBucket} = response)
                 await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
              })
         })

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with cloud.json and the PostBucketRequest schema for POST /buckets, then review the grace-test cases described for missing or empty name and retentionRules. Compare the declared required properties with the endpoint's observed responses and determine whether the contract or API behavior should change; done means the decision is reflected consistently in the specification and tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, openapi
Domain
api, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.