'use strict';

const Promise = require('bluebird');
const __sinon__ = require('sinon');
const expect = require('chai').expect;
const nock = require('nock');

const LandlordClient = require('../src/index');
const data = {
	endpoint: 'http://landlord.localhost',
	tenantId: '88ce2351-2eda-40ba-8774-d4d46f0d2d1a',
	domain: 'brightspace.localhost',
	scheme: 'http',
	isHttpSite: true,
	tenantUrl: 'http://brightspace.localhost/',
	maxAge: 3600
};

describe('LandlordClient', function() {
	let sandbox = __sinon__.sandbox.create();

	beforeEach(function() {
		sandbox = __sinon__.sandbox.create();
	});

	afterEach(function() {
		sandbox.verifyAndRestore();
	});

	it('looks up tenant id when not cached', function() {
		const getRequest = nock(data.endpoint)
			.get('/v1/tenants')
			.query({ domain: data.domain })
			.reply(200, [{
				tenantId: data.tenantId,
				domain: data.domain
			}]);

		const cacheProto = LandlordClient.LRULandlordCache.prototype;
		const getTenantIdLookupStub =
			sandbox.stub(cacheProto, 'getTenantIdLookup');
		getTenantIdLookupStub
			.withArgs(data.domain)
			.returns(Promise.reject(new Error('Not Found')));
		const cacheTenantIdLookupStub =
			sandbox.stub(cacheProto, 'cacheTenantIdLookup');
		cacheTenantIdLookupStub
			.withArgs(data.domain, data.tenantId)
			.returns(Promise.resolve());

		const instance = new LandlordClient({ endpoint: data.endpoint });
		return expect(instance.lookupTenantId(data.domain))
			.to.eventually
			.equal(data.tenantId)
			.then(function() {
				getRequest.done();
			});
	});

	it('does not look up tenant id when cached', function() {
		const getRequest = nock(data.endpoint);

		const cacheProto = LandlordClient.LRULandlordCache.prototype;
		const getTenantIdLookupStub =
			sandbox.stub(cacheProto, 'getTenantIdLookup');
		getTenantIdLookupStub
			.withArgs(data.domain)
			.returns(Promise.resolve(data.tenantId));
		const cacheTenantUrlLookupSpy =
			sandbox.stub(cacheProto, 'cacheTenantUrlLookup');

		const instance = new LandlordClient({ endpoint: data.endpoint });
		return expect(instance.lookupTenantId(data.domain))
			.to.eventually
			.equal(data.tenantId)
			.then(function() {
				getRequest.done();
			})
			.then(function() {
				expect(cacheTenantUrlLookupSpy.notCalled).to.be.true;
			});
	});

	it('looks up tenant info when not cached', function() {
		const getRequest = nock(data.endpoint)
			.get('/v1/tenants/' + data.tenantId)
			.reply(200, {
				tenantId: data.tenantId,
				domain: data.domain + '/',
				isHttpSite: data.isHttpSite
			}, {
				'Cache-Control': 'max-age=' + data.maxAge
			});

		const cacheProto = LandlordClient.LRULandlordCache.prototype;
		const getTenantUrlLookupStub =
			sandbox.stub(cacheProto, 'getTenantUrlLookup');
		getTenantUrlLookupStub
			.withArgs(data.tenantId)
			.returns(Promise.reject(new Error('Not Found')));
		const cacheTenantUrlLookupStub =
			sandbox.stub(cacheProto, 'cacheTenantUrlLookup');
		cacheTenantUrlLookupStub
			.withArgs(data.tenantId, data.tenantUrl, data.maxAge)
			.returns(Promise.resolve());

		const instance = new LandlordClient({ endpoint: data.endpoint });
		return expect(instance.lookupTenantUrl(data.tenantId))
			.to.eventually
			.equal(data.tenantUrl)
			.then(function() {
				getRequest.done();
			})
			.then(function() {
				expect(cacheTenantUrlLookupStub.calledOnce).to.be.true;
			});
	});

	it('does not look up tenant info when cached', function() {
		const getRequest = nock(data.endpoint);

		const cacheProto = LandlordClient.LRULandlordCache.prototype;
		const getTenantUrlLookupStub =
			sandbox.stub(cacheProto, 'getTenantUrlLookup');
		getTenantUrlLookupStub
			.withArgs(data.tenantId)
			.returns(Promise.resolve(data.tenantUrl));
		const cacheTenantUrlLookupSpy =
			sandbox.stub(cacheProto, 'cacheTenantUrlLookup');

		const instance = new LandlordClient({ endpoint: data.endpoint });
		return expect(instance.lookupTenantUrl(data.tenantId))
			.to.eventually
			.equal(data.tenantUrl)
			.then(function() {
				getRequest.done();
			})
			.then(function() {
				expect(cacheTenantUrlLookupSpy.notCalled).to.be.true;
			});
	});
});

@@ -892,39 +892,38 @@
 ;%0A%0A%09%09const cache
-Proto =
+ = new
  LandlordClient.
@@ -934,34 +934,26 @@
 andlordCache
-.prototype
+()
 ;%0A%09%09const ge
@@ -987,37 +987,32 @@
 ndbox.stub(cache
-Proto
 , 'getTenantIdLo
@@ -1169,37 +1169,32 @@
 ndbox.stub(cache
-Proto
 , 'cacheTenantId
@@ -1358,32 +1358,39 @@
 t: data.endpoint
+, cache
  %7D);%0A%09%09return ex
@@ -1640,39 +1640,38 @@
 ;%0A%0A%09%09const cache
-Proto =
+ = new
  LandlordClient.
@@ -1682,34 +1682,26 @@
 andlordCache
-.prototype
+()
 ;%0A%09%09const ge
@@ -1735,37 +1735,32 @@
 ndbox.stub(cache
-Proto
 , 'getTenantIdLo
@@ -1909,37 +1909,32 @@
 ndbox.stub(cache
-Proto
 , 'cacheTenantUr
@@ -2000,32 +2000,39 @@
 t: data.endpoint
+, cache
  %7D);%0A%09%09return ex
@@ -2575,39 +2575,38 @@
 ;%0A%0A%09%09const cache
-Proto =
+ = new
  LandlordClient.
@@ -2617,34 +2617,26 @@
 andlordCache
-.prototype
+()
 ;%0A%09%09const ge
@@ -2671,37 +2671,32 @@
 ndbox.stub(cache
-Proto
 , 'getTenantUrlL
@@ -2858,37 +2858,32 @@
 ndbox.stub(cache
-Proto
 , 'cacheTenantUr
@@ -3065,32 +3065,39 @@
 t: data.endpoint
+, cache
  %7D);%0A%09%09return ex
@@ -3453,15 +3453,14 @@
 ache
-Proto =
+ = new
  Lan
@@ -3491,18 +3491,10 @@
 ache
-.prototype
+()
 ;%0A%09%09
@@ -3545,21 +3545,16 @@
 ub(cache
-Proto
 , 'getTe
@@ -3728,13 +3728,8 @@
 ache
-Proto
 , 'c
@@ -3815,16 +3815,23 @@
 endpoint
+, cache
  %7D);%0A%09%09r

Use a cache instance instead of stubbing the prototype