mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-07-01 20:12:15 +00:00
185 lines
5.4 KiB
Ruby
185 lines
5.4 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
RSpec.describe DiscourseAi::Admin::AiEmbeddingsController do
|
||
|
fab!(:admin)
|
||
|
|
||
|
before { sign_in(admin) }
|
||
|
|
||
|
let(:valid_attrs) do
|
||
|
{
|
||
|
display_name: "Embedding config test",
|
||
|
dimensions: 1001,
|
||
|
max_sequence_length: 234,
|
||
|
pg_function: "<#>",
|
||
|
provider: "hugging_face",
|
||
|
url: "https://test.com/api/v1/embeddings",
|
||
|
api_key: "test",
|
||
|
tokenizer_class: "DiscourseAi::Tokenizer::BgeM3Tokenizer",
|
||
|
}
|
||
|
end
|
||
|
|
||
|
describe "POST #create" do
|
||
|
context "with valid attrs" do
|
||
|
it "creates a new embedding definition" do
|
||
|
post "/admin/plugins/discourse-ai/ai-embeddings.json", params: { ai_embedding: valid_attrs }
|
||
|
|
||
|
created_def = EmbeddingDefinition.last
|
||
|
|
||
|
expect(response.status).to eq(201)
|
||
|
expect(created_def.display_name).to eq(valid_attrs[:display_name])
|
||
|
end
|
||
|
|
||
|
it "stores provider-specific config params" do
|
||
|
post "/admin/plugins/discourse-ai/ai-embeddings.json",
|
||
|
params: {
|
||
|
ai_embedding:
|
||
|
valid_attrs.merge(
|
||
|
provider: "open_ai",
|
||
|
provider_params: {
|
||
|
model_name: "embeddings-v1",
|
||
|
},
|
||
|
),
|
||
|
}
|
||
|
|
||
|
created_def = EmbeddingDefinition.last
|
||
|
|
||
|
expect(response.status).to eq(201)
|
||
|
expect(created_def.provider_params["model_name"]).to eq("embeddings-v1")
|
||
|
end
|
||
|
|
||
|
it "ignores parameters not associated with that provider" do
|
||
|
post "/admin/plugins/discourse-ai/ai-embeddings.json",
|
||
|
params: {
|
||
|
ai_embedding: valid_attrs.merge(provider_params: { custom: "custom" }),
|
||
|
}
|
||
|
|
||
|
created_def = EmbeddingDefinition.last
|
||
|
|
||
|
expect(response.status).to eq(201)
|
||
|
expect(created_def.lookup_custom_param("custom")).to be_nil
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context "with invalid attrs" do
|
||
|
it "doesn't create a new embedding defitinion" do
|
||
|
post "/admin/plugins/discourse-ai/ai-embeddings.json",
|
||
|
params: {
|
||
|
ai_embedding: valid_attrs.except(:provider),
|
||
|
}
|
||
|
|
||
|
created_def = EmbeddingDefinition.last
|
||
|
|
||
|
expect(created_def).to be_nil
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe "PUT #update" do
|
||
|
fab!(:embedding_definition)
|
||
|
|
||
|
context "with valid update params" do
|
||
|
let(:update_attrs) { { provider: "open_ai" } }
|
||
|
|
||
|
it "updates the model" do
|
||
|
put "/admin/plugins/discourse-ai/ai-embeddings/#{embedding_definition.id}.json",
|
||
|
params: {
|
||
|
ai_embedding: update_attrs,
|
||
|
}
|
||
|
|
||
|
expect(response.status).to eq(200)
|
||
|
expect(embedding_definition.reload.provider).to eq(update_attrs[:provider])
|
||
|
end
|
||
|
|
||
|
it "returns a 404 if there is no model with the given Id" do
|
||
|
put "/admin/plugins/discourse-ai/ai-embeddings/9999999.json"
|
||
|
|
||
|
expect(response.status).to eq(404)
|
||
|
end
|
||
|
|
||
|
it "doesn't allow dimenstions to be updated" do
|
||
|
new_dimensions = 200
|
||
|
|
||
|
put "/admin/plugins/discourse-ai/ai-embeddings/#{embedding_definition.id}.json",
|
||
|
params: {
|
||
|
ai_embedding: {
|
||
|
dimensions: new_dimensions,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
expect(response.status).to eq(200)
|
||
|
expect(embedding_definition.reload.dimensions).not_to eq(new_dimensions)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context "with invalid update params" do
|
||
|
it "doesn't update the model" do
|
||
|
put "/admin/plugins/discourse-ai/ai-embeddings/#{embedding_definition.id}.json",
|
||
|
params: {
|
||
|
ai_embedding: {
|
||
|
url: "",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
expect(response.status).to eq(422)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe "DELETE #destroy" do
|
||
|
fab!(:embedding_definition)
|
||
|
|
||
|
it "destroys the embedding defitinion" do
|
||
|
expect {
|
||
|
delete "/admin/plugins/discourse-ai/ai-embeddings/#{embedding_definition.id}.json"
|
||
|
|
||
|
expect(response).to have_http_status(:no_content)
|
||
|
}.to change(EmbeddingDefinition, :count).by(-1)
|
||
|
end
|
||
|
|
||
|
it "validates the model is not in use" do
|
||
|
SiteSetting.ai_embeddings_selected_model = embedding_definition.id
|
||
|
|
||
|
delete "/admin/plugins/discourse-ai/ai-embeddings/#{embedding_definition.id}.json"
|
||
|
|
||
|
expect(response.status).to eq(409)
|
||
|
expect(embedding_definition.reload).to eq(embedding_definition)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe "GET #test" do
|
||
|
context "when we can generate an embedding" do
|
||
|
it "returns a success true flag" do
|
||
|
WebMock.stub_request(:post, valid_attrs[:url]).to_return(status: 200, body: [[1]].to_json)
|
||
|
|
||
|
get "/admin/plugins/discourse-ai/ai-embeddings/test.json",
|
||
|
params: {
|
||
|
ai_embedding: valid_attrs,
|
||
|
}
|
||
|
|
||
|
expect(response).to be_successful
|
||
|
expect(response.parsed_body["success"]).to eq(true)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context "when we cannot generate an embedding" do
|
||
|
it "returns a success false flag and the error message" do
|
||
|
error_message = { error: "Embedding generation failed." }
|
||
|
|
||
|
WebMock.stub_request(:post, valid_attrs[:url]).to_return(
|
||
|
status: 422,
|
||
|
body: error_message.to_json,
|
||
|
)
|
||
|
|
||
|
get "/admin/plugins/discourse-ai/ai-embeddings/test.json",
|
||
|
params: {
|
||
|
ai_embedding: valid_attrs,
|
||
|
}
|
||
|
|
||
|
expect(response).to be_successful
|
||
|
expect(response.parsed_body["success"]).to eq(false)
|
||
|
expect(response.parsed_body["error"]).to eq(error_message.to_json)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|