Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/lib/rex/proto/nuuo/client_spec.rb
Views: 11788
# -*- coding:binary -*-12RSpec.describe Rex::Proto::Nuuo::Client do3subject(:client) {4described_class.new({5protocol: protocol,6user_session: client_user_session,7username: client_username,8password: client_password9})10}11let(:protocol) {'tcp'}12let(:client_user_session) {nil}13let(:client_username) {nil}14let(:client_password) {nil}1516describe '#connect' do17context 'given temp is false' do18context 'when there is no connection' do19it 'returns a tcp connection' do20tcp_connection = double('tcp_connection')21allow(Rex::Socket::Tcp).to receive(:create).and_return(tcp_connection)2223expect(client.connect).to eq(tcp_connection)24end2526it 'saves the tcp connection' do27tcp_connection = double('tcp_connection')28allow(Rex::Socket::Tcp).to receive(:create).and_return(tcp_connection)2930client.connect31expect(client.connection).to eq(tcp_connection)32end33end3435context 'when there is saved connection' do36it 'returns the saved tcp connection' do37tcp_connection = double('tcp_connection')38client.connection = tcp_connection3940expect(client.connect).to eq(tcp_connection)41end42end43end4445context 'given temp is true' do46context 'when there is a saved connection' do47it 'returns a new connection' do48tcp_connection0 = double('tcp_connection')49tcp_connection1 = double('tcp_connection')50allow(Rex::Socket::Tcp).to receive(:create).and_return(tcp_connection1)5152client.connection = tcp_connection053expect(client.connect(temp: true)).to eq(tcp_connection1)54end5556it 'does not overwrite existing connection' do57tcp_connection0 = double('tcp_connection')58tcp_connection1 = double('tcp_connection')59allow(Rex::Socket::Tcp).to receive(:create).and_return(tcp_connection1)6061client.connection = tcp_connection062client.connect(temp: true)63expect(client.connection).to eq(tcp_connection0)64end65end6667context 'when there is no saved connection' do68it 'returns a new connection' do69tcp_connection = double('tcp_connection')70allow(Rex::Socket::Tcp).to receive(:create).and_return(tcp_connection)7172expect(client.connect(temp: true)).to eq(tcp_connection)73end7475it 'does not save the connection' do76tcp_connection = double('tcp_connection')77allow(Rex::Socket::Tcp).to receive(:create).and_return(tcp_connection)7879client.connect(temp: true)80expect(client.connection).to be_nil81end82end83end8485end8687describe '#close' do88context 'given there is a connection' do89it 'calls shutdown on the connection' do90tcp_connection = double('tcp_connection')91allow(tcp_connection).to receive(:shutdown) {true}92allow(tcp_connection).to receive(:closed?) {false}93allow(tcp_connection).to receive(:close) {true}94client.connection = tcp_connection9596expect(tcp_connection).to receive(:shutdown)97client.close98end99100it 'calls closed on the connection' do101tcp_connection = double('tcp_connection')102allow(tcp_connection).to receive(:shutdown) {true}103allow(tcp_connection).to receive(:closed?) {false}104allow(tcp_connection).to receive(:close) {true}105client.connection = tcp_connection106107expect(tcp_connection).to receive(:close)108client.close109end110end111end112113describe '#send_recv' do114context 'given no connection is passed in' do115it 'calls send_request without connection' do116allow(client).to receive(:send_request) do |*args|117expect(args[1]).to be_nil118end119allow(client).to receive(:read_response)120121client.send_recv('test')122end123124it 'calls read_resposne without connection' do125allow(client).to receive(:read_response) do |*args|126expect(args[0]).to be_nil127end128allow(client).to receive(:send_request)129130client.send_recv('test')131end132end133134context 'given a connection is passed in' do135it 'uses the passed in connection' do136tcp_connection = double('tcp_connection')137passed_connection = double('passed_connection')138client.connection = tcp_connection139140allow(passed_connection).to receive(:put)141allow(client).to receive(:read_response)142143expect(passed_connection).to receive(:put)144client.send_recv('test', passed_connection)145end146end147end148149describe '#read_response' do150let(:res) {"NUCM/1.0 200\r\nTest:test\r\nContent-Length:1\r\n\r\na"}151it 'returns a Response object' do152tcp_connection = double('tcp_connection')153allow(tcp_connection).to receive('closed?') {false}154allow(tcp_connection).to receive('get_once') {res}155client.connection = tcp_connection156157expect(client.read_response).to be_a_kind_of(Rex::Proto::Nuuo::Response)158end159end160161describe '#request_ping' do162subject(:ping_request) {163opts = {'user_session' => user_session}164client.request_ping(opts)165}166let(:user_session) {nil}167168it 'returns a PING client request' do169expect(ping_request.to_s).to start_with('PING')170end171172context 'given a user_session option' do173let(:user_session) {'test'}174175context 'when the client does not have a session' do176it 'uses the user_session option' do177expect(ping_request.to_s).to match('User-Session-No: test')178end179end180181context 'when the client has a session' do182let(:client_user_session) {'client'}183184it 'overrides the client session value' do185expect(ping_request.to_s).to match('User-Session-No: test')186end187end188end189190191context 'given no user_session is provided' do192context 'when the client does not have a session' do193it 'does not have a User-Session-No header' do194expect(ping_request.to_s).to_not match('User-Session-No:')195end196end197198context 'when the client has a session' do199let(:client_user_session) {'client'}200201it 'uses the client session' do202expect(ping_request.to_s).to match('User-Session-No: client')203end204end205end206207end208209describe '#request_sendlicfile' do210subject(:sendlicfile_request) {211opts = {212'file_name' => filename,213'data' => data214}215client.request_sendlicfile(opts).to_s216}217let(:filename) {'TestFile'}218let(:data) {'testdata'}219220it 'returns a SENDLICFILE client request' do221expect(sendlicfile_request).to start_with('SENDLICFILE')222end223224context 'given file_name' do225it 'sets the FileName header with the value' do226expect(sendlicfile_request).to match("[^\r\n]\r\nFileName: TestFile\r\n")227end228end229230context 'given no file_name' do231let(:filename) {nil}232233it 'creates an empty FileName header' do234expect(sendlicfile_request).to match("[^\r\n]\r\nFileName: \r\n")235end236end237238context 'given data' do239it 'sets the body to the data contents' do240expect(sendlicfile_request).to end_with("\r\n\r\ntestdata")241end242243it 'sets the Content-Length header with data length' do244expect(sendlicfile_request).to match("[^\r\n]\r\nContent-Length: 8\r\n")245end246end247248context 'given no data' do249let(:data) {nil}250it 'creates an empty body' do251expect(sendlicfile_request).to end_with("\r\n\r\n")252end253254it 'set Content-Length header to 0' do255expect(sendlicfile_request).to match("[^\r\n]\r\nContent-Length: 0\r\n")256end257end258end259260describe '#request_getconfig' do261subject(:getconfig_request) {262opts = {263'file_name' => filename,264'file_type' => filetype265}266client.request_getconfig(opts).to_s267}268let(:filename) {'TestName'}269let(:filetype) {2}270271it 'returns a GETCONFIG client request' do272expect(getconfig_request).to start_with('GETCONFIG')273end274275context 'given file_name' do276it 'sets the FileName header' do277expect(getconfig_request).to match("[^\r\n]\r\nFileName: TestName\r\n")278end279end280281context 'given no file_name' do282let(:filename) {nil}283it 'creates an empty FileName header' do284expect(getconfig_request).to match("[^\r\n]\r\nFileName: \r\n")285end286end287288context 'given a file_type' do289it 'sets the FileType header' do290expect(getconfig_request).to match("[^\r\n]\r\nFileType: 2\r\n")291end292end293294context 'given no file_type' do295let(:filetype) {nil}296it 'defaults to 1' do297expect(getconfig_request).to match("[^\r\n]\r\nFileType: 1\r\n")298end299end300end301302describe '#request_commitconfig' do303subject(:commitconfig_request) {304opts = {305'file_name' => filename,306'file_type' => filetype,307'data' => data308}309client.request_commitconfig(opts).to_s310}311let(:filename) {'TestName'}312let(:filetype) {2}313let(:data) {'testdata'}314315it 'returns a COMMITCONFIG client request' do316expect(commitconfig_request).to start_with('COMMITCONFIG')317end318319context 'given file_name' do320it 'sets the FileName header' do321expect(commitconfig_request).to match("[^\r\n]\r\nFileName: TestName\r\n")322end323end324325context 'given no file_name' do326let(:filename) {nil}327328it 'creates an empty FileName header' do329expect(commitconfig_request).to match("[^\r\n]\r\nFileName: \r\n")330end331end332333context 'given file_type' do334it 'sets the FileType header' do335expect(commitconfig_request).to match("[^\r\n]\r\nFileType: 2\r\n")336end337end338339context 'given no file_type' do340let(:filetype) {nil}341342it 'creates an empty FileType header' do343expect(commitconfig_request).to match("[^\r\n]\r\nFileType: 1\r\n")344end345end346347context 'given data' do348it 'sets the request body to the data' do349expect(commitconfig_request).to end_with("\r\n\r\ntestdata")350end351352it 'sets Content-Length to data length' do353expect(commitconfig_request).to match("[^\r\n]\r\nContent-Length: 8\r\n")354end355end356357context 'given no data' do358let(:data) {nil}359360it 'creates an empty request body' do361expect(commitconfig_request).to end_with("\r\n\r\n")362end363364it 'creates Content-Length header with 0' do365expect(commitconfig_request).to match("[^\r\n]\r\nContent-Length: 0\r\n")366end367end368end369370describe '#request_userlogin' do371subject(:userlogin_request) {372opts = {373'server_version' => server_version,374'username' => username,375'password' => password376}377client.request_userlogin(opts).to_s378}379let(:server_version) {'1.1.1'}380let(:username) {'user'}381let(:password) {'pass'}382383it 'returns a USERLOGIN client request' do384expect(userlogin_request).to start_with('USERLOGIN')385end386387context 'given server_version' do388it 'sets Version header with value' do389expect(userlogin_request).to match("[^\r\n]\r\nVersion: 1.1.1\r\n")390end391end392393context 'given no server_version' do394let(:server_version) {nil}395396it 'creates an empty Version header' do397expect(userlogin_request).to match("[^\r\n]\r\nVersion: \r\n")398end399end400401context 'when client has username' do402let(:client_username) {'client_user'}403404context 'given username' do405it 'sets the Username header with opts username' do406expect(userlogin_request).to match("[^\r\n]\r\nUsername: user\r\n")407end408end409410context 'given no username' do411let(:username) {nil}412413it 'creates an Username header with client username' do414expect(userlogin_request).to match("[^\r\n]\r\nUsername: client_user\r\n")415end416end417end418419context 'when client has no username' do420context 'given username' do421it 'sets the Username header with value' do422expect(userlogin_request).to match("[^\r\n]\r\nUsername: user\r\n")423end424end425426context 'given no username' do427let(:username) {nil}428429it 'creates an empty Username header' do430expect(userlogin_request).to match("[^\r\n]\r\nUsername: \r\n")431end432end433end434435context 'when client has password' do436let(:client_password) {'client_pass'}437438context 'given password' do439it 'sets body with password' do440expect(userlogin_request).to end_with("\r\n\r\npass")441end442443it 'sets Password-Length header' do444expect(userlogin_request).to match("[^\r\n]\r\nPassword-Length: 4\r\n")445end446end447448context 'given no password' do449let(:password) {nil}450451it 'sets body to client password' do452expect(userlogin_request).to end_with("\r\n\r\nclient_pass")453end454455it 'creates Password-Length with client password length' do456expect(userlogin_request).to match("[^\r\n]\r\nPassword-Length: 11\r\n")457end458end459end460461context 'when client has no password' do462context 'given password' do463it 'sets body with password' do464expect(userlogin_request).to end_with("\r\n\r\npass")465end466467it 'sets Password-Length header' do468expect(userlogin_request).to match("[^\r\n]\r\nPassword-Length: 4\r\n")469end470end471472context 'given no password' do473let(:password) {nil}474475it 'sets empty body' do476expect(userlogin_request).to end_with("\r\n\r\n")477end478479it 'creates Password-Length with 0' do480expect(userlogin_request).to match("[^\r\n]\r\nPassword-Length: 0\r\n")481end482end483end484485end486487describe '#request_getopenalarm' do488subject(:getopenalarm_request) {489opts = {490'device_id' => device_id,491'source_server' => source_server,492'last_one' => last_one493}494client.request_getopenalarm(opts).to_s495}496let(:device_id) {nil}497let(:source_server) {nil}498let(:last_one) {nil}499500it 'returns a GETOPENALARM client request' do501expect(getopenalarm_request).to start_with('GETOPENALARM')502end503504context 'given device_id' do505let(:device_id) {2}506507it 'sets DeviceID header with value' do508expect(getopenalarm_request).to match("[^\r\n]\r\nDeviceID: 2\r\n")509end510end511512context 'given no device_id' do513it 'sets DeviceID header to 1' do514expect(getopenalarm_request).to match("[^\r\n]\r\nDeviceID: 1\r\n")515end516end517518context 'given source_server' do519let(:source_server) {2}520521it 'sets SourceServer header with value' do522expect(getopenalarm_request).to match("[^\r\n]\r\nSourceServer: 2\r\n")523end524end525526context 'given no source_server' do527it 'set SourceServer header to 1' do528expect(getopenalarm_request).to match("[^\r\n]\r\nSourceServer: 1\r\n")529end530end531532context 'given last_one' do533let(:last_one) {2}534535it 'sets LastOne header with value' do536expect(getopenalarm_request).to match("[^\r\n]\r\nLastOne: 2\r\n")537end538end539540context 'given no last_one' do541it 'sets LastOne to 1' do542expect(getopenalarm_request).to match("[^\r\n]\r\nLastOne: 1\r\n")543end544end545end546end547548549