Files
rynDNS/spec/requests/clients_request_spec.rb
2021-03-07 16:39:38 -05:00

636 lines
23 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Clients', type: :request do
let!(:admin_client) { create(:admin) }
let!(:public_client) { create(:public) }
let!(:read_client) { create(:read) }
let!(:write_client) { create(:write) }
let!(:clients) { create_list(:client, 20) }
let(:random_client) { clients[Faker::Number.between(from: 0, to: clients.length - 1)] }
let(:valid_client) do
{
name: 'clientA',
description: 'Client across the river',
permission: 'rw',
public_ip: false
}
end
let(:valid_client_update) do
{
name: 'clientA',
permission: 'w',
public_ip: true
}
end
let(:random_client_update) do
{
name: random_client.name,
description: 'updated description',
public_ip: !random_client.public_ip # swap boolean
}
end
let(:admin_perm_update) do
{
name: admin_client.name,
public_ip: !admin_client.public_ip, # swap boolean
permission: 'rw'
}
end
let(:invalid_client_update) { { names: 'clientA' } }
let(:non_existing_client) { 'DOES_NOT_EXIST_123546' }
# admin
describe 'POST /admin/client' do
context 'when sending a valid update request' do
before { post '/admin/client', params: valid_client, headers: api_key_header(admin_client) }
it 'updates client from rw to w and returns 200' do
api_key = json_response['api_key']
post '/admin/client', params: valid_client_update, headers: api_key_header(admin_client)
expect(json_response).not_to be_empty
expect(json_response['api_key'].length).to eq 82
expect(json_response['api_key'].length).not_to eq api_key
expect(response).to have_http_status(200)
api_key = json_response['api_key']
client_name = json_response['name']
# check if request was parsed properly
get "/admin/clients/#{client_name}", headers: api_key_header(admin_client)
expect(json_response).not_to be_empty
expect(json_response['name']).to eq valid_client[:name]
expect(json_response['description']).to eq valid_client[:description]
expect(json_response['permission']).to eq valid_client_update[:permission]
expect(json_response['public_ip']).to eq valid_client_update[:public_ip]
expect(response).to have_http_status(200)
# test the new api_key write
put '/client', headers: api_key_header(nil, api_key)
expect(json_response).not_to be_empty
expect(response).to have_http_status(200)
# test the new api_key read
get "/clients/#{client_name}", headers: api_key_header(nil, api_key)
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when sending a valid request' do
before { post '/admin/client', params: valid_client, headers: api_key_header(admin_client) }
it 'creates client that can read/write and returns 201' do
expect(json_response).not_to be_empty
expect(json_response['name']).to eq valid_client[:name]
expect(json_response['api_key'].length).to eq 82
expect(response).to have_http_status(201)
api_key = json_response['api_key']
# check if request was parsed properly
get "/admin/clients/#{valid_client[:name]}", headers: api_key_header(admin_client)
expect(json_response).not_to be_empty
expect(json_response['name']).to eq valid_client[:name]
expect(json_response['description']).to eq valid_client[:description]
expect(json_response['permission']).to eq valid_client[:permission]
expect(json_response['public_ip']).to eq valid_client[:public_ip]
expect(response).to have_http_status(200)
# test the new client write
put '/client', headers: api_key_header(nil, api_key)
expect(json_response).not_to be_empty
expect(response).to have_http_status(200)
ipv4 = json_response['ipv4']
# test the new client read
get "/clients/#{valid_client[:name]}", headers: api_key_header(nil, api_key)
expect(json_response).not_to be_empty
expect(response).to have_http_status(200)
expect(json_response['ipv4']).to eq ipv4
end
end
context 'when sending a valid request without api_key' do
let!(:client_count) { Client.count }
before { post '/admin/client', params: valid_client }
it 'does not create client and returns status code 401' do
expect(client_count).to eq Client.count
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'when sending a valid request with non admin api_key' do
let!(:client_count) { Client.count }
before { post '/admin/client', params: valid_client, headers: api_key_header(read_client) }
it 'does not create client and returns status code 403' do
expect(client_count).to eq Client.count
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when sending an invalid request' do
let!(:client_count) { Client.count }
before { post '/admin/client', params: invalid_client_update, headers: api_key_header(admin_client) }
it 'does not create client and returns status code 405' do
expect(client_count).to eq Client.count
expect(response.body).to be_empty
expect(response).to have_http_status(405)
end
end
context 'when sending a valid update request to remove last admin permission' do
before { post '/admin/client', params: admin_perm_update, headers: api_key_header(admin_client) }
it 'does not update admin and returns status code 406' do
expect(admin_client.reload.perm_x).to eq true
expect(response.body).to be_empty
expect(response).to have_http_status(406)
end
end
context 'when sending a valid update request to remove non last admin permission' do
before do
post '/admin/client', params: { name: 'admin2', permission: 'x' }, headers: api_key_header(admin_client)
post '/admin/client', params: admin_perm_update, headers: api_key_header(admin_client)
end
it 'does update admin and returns status code 200' do
expect(admin_client.reload.perm_x).to eq false
expect(response.body).not_to be_empty
expect(response).to have_http_status(200)
end
end
context 'when sending a valid request to add another client above the MAX_CLIENTS limit' do
before do
clients_to_create = RynDNS::Application::MAX_CLIENTS - Client.count
create_list(:client, clients_to_create)
post '/admin/client', params: { name: 'extra_user' }, headers: api_key_header(admin_client)
end
it 'does not add another client and returns status code 429' do
expect(Client.count).to eq RynDNS::Application::MAX_CLIENTS
expect(response.body).to be_empty
expect(response).to have_http_status(429)
end
end
end
describe 'PUT /admin/client' do
context 'when sending a valid request' do
before do
put '/admin/client', params: random_client_update, headers: api_key_header(admin_client)
random_client.reload
end
it 'updates client and returns 200' do
expect(random_client.description).to eq random_client_update[:description]
expect(random_client.public_ip).to eq random_client_update[:public_ip]
expect(response.body).to be_empty
expect(response).to have_http_status(200)
end
end
context 'when sending a valid request without api_key' do
before do
put '/admin/client', params: random_client_update
random_client.reload
end
it 'does not update client and returns 401' do
expect(random_client.description).not_to eq random_client_update[:description]
expect(random_client.public_ip).not_to eq random_client_update[:public_ip]
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'when sending a valid request with non admin api_key' do
before do
put '/admin/client', params: random_client_update, headers: api_key_header(write_client)
random_client.reload
end
it 'does not update client and returns 403' do
expect(random_client.description).not_to eq random_client_update[:description]
expect(random_client.public_ip).not_to eq random_client_update[:public_ip]
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when sending a valid request for non existing client' do
before do
random_client_update[:name] = non_existing_client
put '/admin/client', params: random_client_update, headers: api_key_header(admin_client)
random_client.reload
end
it 'does not update client and returns 404' do
expect(random_client.description).not_to eq random_client_update[:description]
expect(random_client.public_ip).not_to eq random_client_update[:public_ip]
expect(response.body).to be_empty
expect(response).to have_http_status(404)
end
end
context 'when sending an invalid valid request' do
before { put '/admin/client', params: invalid_client_update, headers: api_key_header(admin_client) }
it 'returns 405' do
expect(response.body).to be_empty
expect(response).to have_http_status(405)
end
end
context 'when sending a valid valid request to remove last admin permission' do
before do
put '/admin/client', params: admin_perm_update, headers: api_key_header(admin_client)
admin_client.reload
end
it 'does not update admin and returns 406' do
expect(admin_client.perm_x).to eq true
expect(admin_client.public_ip).to_not eq admin_perm_update[:public_ip]
expect(response.body).to be_empty
expect(response).to have_http_status(406)
end
end
context 'when sending a valid update request to remove non last admin permission' do
before do
put '/admin/client', params: { name: random_client.name, permission: 'x' },
headers: api_key_header(admin_client)
put '/admin/client', params: admin_perm_update, headers: api_key_header(admin_client)
end
it 'does update admin and returns status code 200' do
expect(admin_client.reload.perm_x).to eq false
expect(response.body).to be_empty
expect(response).to have_http_status(200)
end
end
end
describe 'GET /admin/clients' do
context 'when requesting all clients' do
before { get '/admin/clients', headers: api_key_header(admin_client) }
it 'returns list of all clients and status code 200' do
expect(list_equals_db?(json_response)).to eq true
expect(response).to have_http_status(200)
end
end
context 'when requesting all clients with no api_key' do
before { get '/admin/clients' }
it 'returns status code 401' do
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'when requesting all clients with write api_key' do
before { get '/admin/clients', headers: api_key_header(write_client) }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when requesting all clients with read api_key' do
before { get '/admin/clients', headers: api_key_header(read_client) }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
end
describe 'GET /admin/clients/:name' do
context 'when requesting random_client.name client with admin api_key' do
before { get "/admin/clients/#{random_client.name}", headers: api_key_header(admin_client) }
it 'returns info and status code 200' do
expect(json_response['name']).to eq random_client.name
expect(json_response['description']).to eq random_client.description
expect(json_response['permission']).to eq parse_permission(random_client.perm_r, random_client.perm_w,
random_client.perm_x)
expect(json_response['public_ip']).to eq random_client.public_ip
expect(json_response['ipv4']).to eq random_client.ipv4
expect(response).to have_http_status(200)
end
end
context 'when requesting random client with no api_key' do
before { get "/admin/clients/#{random_client.name}" }
it 'returns status code 401' do
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'when requesting random client with write api_key' do
before { get "/admin/clients/#{random_client.name}", headers: api_key_header(write_client) }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when requesting random client with read api_key' do
before { get "/admin/clients/#{random_client.name}", headers: api_key_header(read_client) }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when requesting non existing client' do
before { get "/admin/clients/#{non_existing_client}", headers: api_key_header(admin_client) }
it 'returns status code 404' do
expect(response.body).to be_empty
expect(response).to have_http_status(404)
end
end
end
describe 'DELETE /admin/clients/:name' do
context 'when sending a valid request' do
let!(:client_count) { Client.count - 1 }
before { delete "/admin/clients/#{random_client.name}", headers: api_key_header(admin_client) }
it 'deletes client and returns 200' do
expect(Client.find_by(name: random_client.name)).to eq nil
expect(Client.count).to eq client_count
expect(response.body).to be_empty
expect(response).to have_http_status(200)
end
end
context 'when sending a valid request without api_key' do
let!(:client_count) { Client.count }
before { delete "/admin/clients/#{random_client.name}" }
it 'does not delete client and returns 401' do
expect(Client.find_by(name: random_client.name)).to eq random_client
expect(Client.count).to eq client_count
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'when sending a valid request with non admin api_key' do
let!(:client_count) { Client.count }
before { delete "/admin/clients/#{random_client.name}", headers: api_key_header(read_client) }
it 'does not delete client and returns 403' do
expect(Client.find_by(name: random_client.name)).to eq random_client
expect(Client.count).to eq client_count
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when sending a valid request for non existing client' do
let!(:client_count) { Client.count }
before { delete "/admin/clients/#{non_existing_client}", headers: api_key_header(admin_client) }
it 'does not delete client and returns 404' do
expect(Client.count).to eq client_count
expect(response.body).to be_empty
expect(response).to have_http_status(404)
end
end
context 'when sending a valid valid request to delete last admin' do
let!(:client_count) { Client.count }
before { delete "/admin/clients/#{admin_client.name}", headers: api_key_header(admin_client) }
it 'does not delete admin and returns 406' do
expect(Client.find_by(name: admin_client.name)).to eq admin_client
expect(Client.count).to eq client_count
expect(response.body).to be_empty
expect(response).to have_http_status(406)
end
end
context 'when sending a valid update request to delete non last admin' do
let!(:client_count) { Client.count - 1 }
before do
put '/admin/client', params: { name: random_client.name, permission: 'x' },
headers: api_key_header(admin_client)
delete "/admin/clients/#{admin_client.name}", headers: api_key_header(admin_client)
end
it 'does delete admin and returns status code 200' do
expect(Client.find_by(name: admin_client.name)).to eq nil
expect(Client.count).to eq client_count
expect(response.body).to be_empty
expect(response).to have_http_status(200)
end
end
end
# client (write)
describe 'PUT /client' do
context 'when requesting with write api_key' do
before { put '/client', headers: api_key_header(write_client) }
it 'returns status code 200' do
expect(json_response['name']).to eq write_client.name
expect(json_response['ipv4']).to eq '127.0.0.1'
expect(response).to have_http_status(200)
end
end
context 'when requesting with write api_key and body' do
before { put '/client', params: { ipv4: '99.55.66.2' }, headers: api_key_header(write_client) }
it 'returns status code 200' do
expect(json_response['name']).to eq write_client.name
expect(json_response['ipv4']).to eq '99.55.66.2'
expect(response).to have_http_status(200)
end
end
context 'when requesting with no api_key' do
before { put '/client' }
it 'returns status code 401' do
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'when requesting with read api_key' do
before { put '/client', headers: api_key_header(read_client) }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when requesting with api_key of non existing client' do
before do
write_client.delete
put '/client', headers: api_key_header(write_client)
end
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
end
describe 'DELETE /client' do
context 'when requesting with write api_key' do
before { delete '/client', headers: api_key_header(write_client) }
it 'deletes ipv4 value and returns previous value with status code 200' do
expect(json_response['name']).to eq write_client.name
expect(json_response['ipv4']).to eq write_client.ipv4
expect(response).to have_http_status(200)
# check if deletion was successful
write_client.reload
expect(write_client.ipv4).to eq ''
end
end
context 'when requesting with no api_key' do
before { delete '/client' }
it 'returns status code 401' do
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'when requesting with read api_key' do
before { delete '/client', headers: api_key_header(read_client) }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when requesting with write api_key and invalid ip body' do
before { put '/client', params: { ipv4: '5.9.256.66' }, headers: api_key_header(write_client) }
it 'returns status code 406' do
expect(response.body).to be_empty
expect(response).to have_http_status(406)
end
end
end
# client (read)
describe 'GET /clients/:name' do
context 'when requesting write client with read api_key' do
before { get "/clients/#{write_client.name}", headers: api_key_header(read_client) }
it 'returns status code 200' do
expect(json_response['name']).to eq write_client.name
expect(json_response['ipv4']).to eq write_client.ipv4
expect(response).to have_http_status(200)
end
end
context 'when requesting write client with no api_key' do
before { get "/clients/#{write_client.name}" }
it 'returns status code 401' do
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'request write client with write api_key' do
before { get "/clients/#{write_client.name}", headers: api_key_header(write_client) }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
context 'when requesting non existing client' do
before { get "/clients/#{non_existing_client}", headers: api_key_header(read_client) }
it 'returns status code 404' do
expect(response.body).to be_empty
expect(response).to have_http_status(404)
end
end
end
# public
describe 'GET /public/:name' do
context 'request public client' do
before { get "/public/#{public_client.name}" }
it 'returns status code 200' do
expect(json_response['name']).to eq public_client.name
expect(json_response['ipv4']).to eq public_client.ipv4
expect(response).to have_http_status(200)
end
end
context 'request non existing client' do
before { get "/public/#{non_existing_client}" }
it 'returns status code 401' do
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
context 'request non-public client' do
before { get "/public/#{write_client.name}" }
it 'returns status code 401' do
expect(response.body).to be_empty
expect(response).to have_http_status(401)
end
end
end
describe 'POST /public/:name' do
# FIXME: rather have this automated than adding ENV by hand
if ENV['RAILS_API_PUBLIC']
context 'when request to write public client' do
before { post "/public/#{public_client.name}" }
it 'returns status code 200' do
expect(json_response['name']).to eq public_client.name
expect(json_response['ipv4']).to eq '127.0.0.1'
expect(response).to have_http_status(200)
end
end
context 'when requesting to write public client with body' do
before { post "/public/#{public_client.name}", params: { ipv4: '99.55.66.2' } }
it 'returns status code 200' do
expect(json_response['name']).to eq public_client.name
expect(json_response['ipv4']).to eq '99.55.66.2'
expect(response).to have_http_status(200)
end
end
context 'when requesting to write non existing client' do
before { post "/public/#{non_existing_client}" }
it 'returns status code 201' do
expect(json_response['name']).to eq non_existing_client
expect(json_response['ipv4']).to eq '127.0.0.1'
expect(response).to have_http_status(201)
end
end
# TODO: 406 and 429, check client count on 200
else
context 'when request to write public client' do
before { post "/public/#{public_client.name}" }
it 'returns status code 403' do
expect(response.body).to be_empty
expect(response).to have_http_status(403)
end
end
# TODO: check client count/modification
end
end
end