diff --git a/package.json b/package.json index 70088d2..2b72b3f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@internxt/sdk", "author": "Internxt ", - "version": "1.12.3", + "version": "1.12.4", "description": "An sdk for interacting with Internxt's services", "repository": { "type": "git", diff --git a/src/misc/location/index.ts b/src/misc/location/index.ts index 3ee3150..36bf9a3 100644 --- a/src/misc/location/index.ts +++ b/src/misc/location/index.ts @@ -1,3 +1,5 @@ +import { basicHeaders } from '../../shared/headers'; +import { ApiSecurity, ApiUrl, AppDetails } from '../../shared'; import { HttpClient } from '../../shared/http/client'; export interface UserLocation { @@ -5,7 +7,29 @@ export interface UserLocation { location: string; } -export const getUserLocation = async (apiUrl: string): Promise => { - const client = HttpClient.create(apiUrl); - return client.get(`${apiUrl}`, {}); -}; +export class Location { + private readonly client: HttpClient; + private readonly appDetails: AppDetails; + + private constructor(apiUrl: ApiUrl, appDetails: AppDetails, apiSecurity?: ApiSecurity) { + this.client = HttpClient.create(apiUrl, apiSecurity?.unauthorizedCallback); + this.appDetails = appDetails; + } + + public static client(apiUrl: ApiUrl, appDetails: AppDetails, apiSecurity?: ApiSecurity) { + return new Location(apiUrl, appDetails, apiSecurity); + } + + public async getUserLocation(): Promise { + return this.client.get('', this.basicUserHeaders()); + } + + private basicUserHeaders() { + return basicHeaders({ + clientName: this.appDetails.clientName, + clientVersion: this.appDetails.clientVersion, + desktopToken: this.appDetails.desktopHeader, + customHeaders: this.appDetails.customHeaders, + }); + } +} diff --git a/src/shared/headers/index.ts b/src/shared/headers/index.ts index c64b553..5cff9cb 100644 --- a/src/shared/headers/index.ts +++ b/src/shared/headers/index.ts @@ -4,6 +4,13 @@ export interface CustomHeaders { [key: string]: string; } +export interface BasicHeadersPayload { + clientName: string; + clientVersion: string; + customHeaders?: Record; + desktopToken?: Token; +} + type InternxtHeaders = { 'content-type': string; 'internxt-version': string; @@ -20,12 +27,7 @@ export function basicHeaders({ clientVersion, customHeaders, desktopToken, -}: { - clientName: string; - clientVersion: string; - customHeaders?: Record; - desktopToken?: Token; -}): InternxtHeaders { +}: BasicHeadersPayload): InternxtHeaders { const extra: ExtraHeaders = {}; if (desktopToken) { extra['x-internxt-desktop-header'] = desktopToken; diff --git a/test/misc/location/index.test.ts b/test/misc/location/index.test.ts new file mode 100644 index 0000000..fb233c6 --- /dev/null +++ b/test/misc/location/index.test.ts @@ -0,0 +1,108 @@ +import sinon from 'sinon'; +import { AppDetails } from '../../../src/shared'; +import { basicHeaders } from '../../../src/shared/headers'; +import { Location, UserLocation } from '../../../src/misc/location'; +import { HttpClient } from '../../../src/shared/http/client'; + +const httpClient = HttpClient.create(''); + +describe('location service', () => { + beforeEach(() => { + sinon.stub(HttpClient, 'create').returns(httpClient); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('Get user location', () => { + it('should call with right params & return user location', async () => { + // Arrange + const mockLocation: UserLocation = { + ip: '1.1.1.1', + location: 'ES', + }; + const callStub = sinon.stub(httpClient, 'get').resolves(mockLocation); + const { client, headers } = clientAndHeaders(); + + // Act + const result = await client.getUserLocation(); + + // Assert + expect(callStub.firstCall.args).toEqual(['', headers]); + expect(result).toEqual(mockLocation); + }); + + it('should include desktop header when provided', async () => { + // Arrange + const mockLocation: UserLocation = { + ip: '10.0.0.1', + location: 'US', + }; + const callStub = sinon.stub(httpClient, 'get').resolves(mockLocation); + const { client, headers } = clientAndHeaders({ + desktopHeader: 'desktop-token', + }); + + // Act + const result = await client.getUserLocation(); + + // Assert + expect(callStub.firstCall.args).toEqual(['', headers]); + expect(result).toEqual(mockLocation); + }); + + it('should include custom headers when provided', async () => { + // Arrange + const mockLocation: UserLocation = { + ip: '172.16.0.1', + location: 'FR', + }; + const customHeaders = { 'x-custom-header': 'custom-value' }; + const callStub = sinon.stub(httpClient, 'get').resolves(mockLocation); + const { client, headers } = clientAndHeaders({ + customHeaders, + }); + + // Act + const result = await client.getUserLocation(); + + // Assert + expect(callStub.firstCall.args).toEqual(['', headers]); + expect(result).toEqual(mockLocation); + }); + }); +}); + +function clientAndHeaders({ + apiUrl = '', + clientName = 'internxt-client', + clientVersion = '0.1', + desktopHeader, + customHeaders, +}: { + apiUrl?: string; + clientName?: string; + clientVersion?: string; + desktopHeader?: string; + customHeaders?: Record; +} = {}): { + client: Location; + headers: object; +} { + const appDetails: AppDetails = { + clientName, + clientVersion, + desktopHeader, + customHeaders, + }; + + const client = Location.client(apiUrl, appDetails); + const headers = basicHeaders({ + clientName, + clientVersion, + desktopToken: desktopHeader, + customHeaders, + }); + return { client, headers }; +}