1+ /**
2+ * @license
3+ * Copyright 2025 Google LLC
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+ import { expect } from 'chai' ;
18+ import { GENAI_TYPE } from './constants' ;
19+ import {
20+ encodeInstanceIdentifier ,
21+ decodeInstanceIdentifier
22+ } from './helpers' ;
23+ import { GenAIError } from './errors' ;
24+ import { BackendType , InstanceIdentifier } from './public-types' ;
25+ import { GenAIErrorCode } from './types' ;
26+
27+ describe ( 'Identifier Encoding/Decoding' , ( ) => {
28+ describe ( 'encodeInstanceIdentifier' , ( ) => {
29+ it ( 'should encode Vertex AI identifier with a specific location' , ( ) => {
30+ const identifier : InstanceIdentifier = {
31+ backendType : BackendType . VERTEX_AI ,
32+ location : 'us-central1'
33+ } ;
34+ console . log ( identifier ) ;
35+ const expected = `${ GENAI_TYPE } /vertexai/us-central1` ;
36+ expect ( encodeInstanceIdentifier ( identifier ) ) . to . equal ( expected ) ;
37+ } ) ;
38+
39+ it ( 'should encode Vertex AI identifier using empty location' , ( ) => {
40+ const identifier : InstanceIdentifier = {
41+ backendType : BackendType . VERTEX_AI ,
42+ location : ""
43+ } ;
44+ const expected = `${ GENAI_TYPE } /vertexai/` ;
45+ expect ( encodeInstanceIdentifier ( identifier ) ) . to . equal ( expected ) ;
46+ } ) ;
47+
48+ it ( 'should encode Google AI identifier' , ( ) => {
49+ const identifier : InstanceIdentifier = {
50+ backendType : BackendType . GOOGLE_AI
51+ } ;
52+ const expected = `${ GENAI_TYPE } /googleai` ;
53+ expect ( encodeInstanceIdentifier ( identifier ) ) . to . equal ( expected ) ;
54+ } ) ;
55+
56+ it ( 'should throw GenAIError for unknown backend type' , ( ) => {
57+ const identifier = {
58+ backendType : 'some-future-backend'
59+ } as any ; // bypass type checking for the test
60+
61+ expect ( ( ) => encodeInstanceIdentifier ( identifier ) ) . to . throw ( GenAIError ) ;
62+
63+ try {
64+ encodeInstanceIdentifier ( identifier ) ;
65+ expect . fail ( 'Expected encodeInstanceIdentifier to throw' ) ;
66+ } catch ( e ) {
67+ expect ( e ) . to . be . instanceOf ( GenAIError ) ;
68+ const error = e as GenAIError ;
69+ expect ( error . message ) . to . contain ( `Unknown backend` ) ;
70+ expect ( error . code ) . to . equal ( GenAIErrorCode . ERROR ) ;
71+ }
72+ } ) ;
73+ } ) ;
74+
75+ describe ( 'decodeInstanceIdentifier' , ( ) => {
76+ it ( 'should decode Vertex AI identifier with location' , ( ) => {
77+ const encoded = `${ GENAI_TYPE } /vertexai/europe-west1` ;
78+ const expected : InstanceIdentifier = {
79+ backendType : BackendType . VERTEX_AI ,
80+ location : 'europe-west1'
81+ } ;
82+ expect ( decodeInstanceIdentifier ( encoded ) ) . to . deep . equal ( expected ) ;
83+ } ) ;
84+
85+ it ( 'should throw an error if Vertex AI identifier string without explicit location part' , ( ) => {
86+ const encoded = `${ GENAI_TYPE } /vertexai` ;
87+ expect ( ( ) => decodeInstanceIdentifier ( encoded ) ) . to . throw ( GenAIError ) ;
88+
89+ try {
90+ decodeInstanceIdentifier ( encoded ) ;
91+ expect . fail ( 'Expected encodeInstanceIdentifier to throw' ) ;
92+ } catch ( e ) {
93+ expect ( e ) . to . be . instanceOf ( GenAIError ) ;
94+ const error = e as GenAIError ;
95+ expect ( error . message ) . to . contain ( `Invalid instance identifier, unknown location` ) ;
96+ expect ( error . code ) . to . equal ( GenAIErrorCode . ERROR ) ;
97+ }
98+ } ) ;
99+
100+ it ( 'should decode Google AI identifier' , ( ) => {
101+ const encoded = `${ GENAI_TYPE } /googleai` ;
102+ const expected : InstanceIdentifier = {
103+ backendType : BackendType . GOOGLE_AI
104+ } ;
105+ expect ( decodeInstanceIdentifier ( encoded ) ) . to . deep . equal ( expected ) ;
106+ } ) ;
107+
108+ it ( 'should throw GenAIError for invalid backend string' , ( ) => {
109+ const encoded = `${ GENAI_TYPE } /someotherbackend/location` ;
110+ expect ( ( ) => decodeInstanceIdentifier ( encoded ) ) . to . throw (
111+ GenAIError ,
112+ `Invalid instance identifier string: '${ encoded } '`
113+ ) ;
114+ try {
115+ decodeInstanceIdentifier ( encoded ) ;
116+ expect . fail ( 'Expected decodeInstanceIdentifier to throw' ) ;
117+ } catch ( e ) {
118+ expect ( e ) . to . be . instanceOf ( GenAIError ) ;
119+ expect ( ( e as GenAIError ) . code ) . to . equal ( GenAIErrorCode . ERROR ) ;
120+ }
121+ } ) ;
122+
123+ it ( 'should throw GenAIError for malformed identifier string (too few parts)' , ( ) => {
124+ const encoded = GENAI_TYPE ;
125+ expect ( ( ) => decodeInstanceIdentifier ( encoded ) ) . to . throw (
126+ GenAIError ,
127+ `Invalid instance identifier string: '${ encoded } '`
128+ ) ;
129+ } ) ;
130+
131+ it ( 'should throw GenAIError for malformed identifier string (incorrect prefix)' , ( ) => {
132+ const encoded = 'firebase/vertexai/location' ;
133+ // This will also hit the default case in the switch statement
134+ expect ( ( ) => decodeInstanceIdentifier ( encoded ) ) . to . throw (
135+ GenAIError ,
136+ `Invalid instance identifier, unknown prefix 'firebase'`
137+ ) ;
138+ } ) ;
139+ } ) ;
140+ } ) ;
0 commit comments