juice-shop/juice-shop

View on GitHub
test/api/challengeApiSpec.ts

Summary

Maintainability
A
0 mins
Test Coverage
/*
 * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors.
 * SPDX-License-Identifier: MIT
 */

import frisby = require('frisby')
const Joi = frisby.Joi
const security = require('../../lib/insecurity')

const API_URL = 'http://localhost:3000/api'
const REST_URL = 'http://localhost:3000/rest'

const authHeader = { Authorization: 'Bearer ' + security.authorize(), 'content-type': 'application/json' }

describe('/api/Challenges', () => {
  it('GET all challenges', () => {
    return frisby.get(API_URL + '/Challenges')
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('jsonTypes', 'data.*', {
        id: Joi.number(),
        key: Joi.string(),
        name: Joi.string(),
        description: Joi.string(),
        difficulty: Joi.number(),
        solved: Joi.boolean()
      })
  })

  it('POST new challenge is forbidden via public API even when authenticated', () => {
    return frisby.post(API_URL + '/Challenges', {
      headers: authHeader,
      body: {
        name: 'Invulnerability',
        description: 'I am not a vulnerability!',
        difficulty: 3,
        solved: false
      }
    })
      .expect('status', 401)
  })
})

describe('/api/Challenges/:id', () => {
  it('GET existing challenge by id is forbidden via public API even when authenticated', () => {
    return frisby.get(API_URL + '/Challenges/1', { headers: authHeader })
      .expect('status', 401)
  })

  it('PUT update existing challenge is forbidden via public API even when authenticated', () => {
    return frisby.put(API_URL + '/Challenges/1', {
      headers: authHeader,
      body: {
        name: 'Vulnerability',
        description: 'I am a vulnerability!!!',
        difficulty: 3
      }
    })
      .expect('status', 401)
  })

  it('DELETE existing challenge is forbidden via public API even when authenticated', () => {
    return frisby.del(API_URL + '/Challenges/1', { headers: authHeader })
      .expect('status', 401)
  })
})

describe('/rest/continue-code', () => {
  it('GET can retrieve continue code for currently solved challenges', () => {
    return frisby.get(REST_URL + '/continue-code')
      .expect('status', 200)
  })

  it('PUT invalid continue code is rejected', () => {
    return frisby.put(REST_URL + '/continue-code/apply/ThisIsDefinitelyNotAValidContinueCode')
      .expect('status', 404)
  })

  it('PUT continue code for more than one challenge is accepted', () => { // using [1, 2] here
    return frisby.put(REST_URL + '/continue-code/apply/yXjv6Z5jWJnzD6a3YvmwPRXK7roAyzHDde2Og19yEN84plqxkMBbLVQrDeoY')
      .expect('status', 200)
  })

  it('PUT continue code for non-existent challenge #999 is accepted', () => {
    return frisby.put(REST_URL + '/continue-code/apply/69OxrZ8aJEgxONZyWoz1Dw4BvXmRGkM6Ae9M7k2rK63YpqQLPjnlb5V5LvDj')
      .expect('status', 200)
  })
})

describe('/rest/continue-code-findIt', () => {
  it('GET can retrieve continue code for currently solved challenges', () => {
    return frisby.get(REST_URL + '/continue-code-findIt')
      .expect('status', 200)
  })

  it('PUT invalid continue code is rejected', () => {
    return frisby.put(REST_URL + '/continue-code-findIt/apply/ThisIsDefinitelyNotAValidContinueCode')
      .expect('status', 404)
  })

  it('PUT continue code for more than one challenge is accepted', () => { // using [15, 69] here which both have a Coding Challenge
    return frisby.put(REST_URL + '/continue-code-findIt/apply/Xg9oK0VdbW5g1KX9G7JYnqLpz3rAPBh6p4eRlkDM6EaBON2QoPmxjyvwMrP6')
      .expect('status', 200)
  })
})

describe('/rest/continue-code-fixIt', () => {
  it('GET can retrieve continue code for currently solved challenges', () => {
    return frisby.get(REST_URL + '/continue-code-fixIt')
      .expect('status', 200)
  })

  it('PUT invalid continue code is rejected', () => {
    return frisby.put(REST_URL + '/continue-code-fixIt/apply/ThisIsDefinitelyNotAValidContinueCode')
      .expect('status', 404)
  })

  it('PUT continue code for more than one challenge is accepted', () => { // using [15, 69] here which both have a Coding Challenge
    return frisby.put(REST_URL + '/continue-code-fixIt/apply/y28BEPE2k3yRrdz5p6DGqJONnj41n5UEWawYWgBMoVmL79bKZ8Qve0Xl5QLW')
      .expect('status', 200)
  })
})