| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe DiscourseAi::Embeddings::SemanticRelated do | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |   subject(:semantic_related) { described_class.new } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  |   fab!(:target) { Fabricate(:topic) } | 
					
						
							|  |  |  |   fab!(:normal_topic_1) { Fabricate(:topic) } | 
					
						
							|  |  |  |   fab!(:normal_topic_2) { Fabricate(:topic) } | 
					
						
							|  |  |  |   fab!(:normal_topic_3) { Fabricate(:topic) } | 
					
						
							|  |  |  |   fab!(:unlisted_topic) { Fabricate(:topic, visible: false) } | 
					
						
							|  |  |  |   fab!(:private_topic) { Fabricate(:private_message_topic) } | 
					
						
							|  |  |  |   fab!(:secured_category) { Fabricate(:category, read_restricted: true) } | 
					
						
							|  |  |  |   fab!(:secured_category_topic) { Fabricate(:topic, category: secured_category) } | 
					
						
							| 
									
										
										
										
											2023-05-09 15:30:50 -03:00
										 |  |  |   fab!(:closed_topic) { Fabricate(:topic, closed: true) } | 
					
						
							| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-01 14:06:51 -03:00
										 |  |  |   before { SiteSetting.ai_embeddings_semantic_related_topics_enabled = true } | 
					
						
							| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 16:58:09 -03:00
										 |  |  |   describe "#related_topic_ids_for" do | 
					
						
							| 
									
										
										
										
											2023-05-23 10:43:24 +10:00
										 |  |  |     context "when embeddings do not exist" do | 
					
						
							| 
									
										
										
										
											2024-02-01 00:38:47 +11:00
										 |  |  |       let(:topic) do | 
					
						
							|  |  |  |         post = Fabricate(:post) | 
					
						
							|  |  |  |         topic = post.topic | 
					
						
							|  |  |  |         described_class.clear_cache_for(target) | 
					
						
							|  |  |  |         topic | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let(:vector_rep) do | 
					
						
							|  |  |  |         strategy = DiscourseAi::Embeddings::Strategies::Truncation.new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         DiscourseAi::Embeddings::VectorRepresentations::Base.current_representation(strategy) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "properly generates embeddings if missing" do | 
					
						
							|  |  |  |         SiteSetting.ai_embeddings_enabled = true | 
					
						
							|  |  |  |         SiteSetting.ai_embeddings_discourse_service_api_endpoint = "http://test.com" | 
					
						
							|  |  |  |         Jobs.run_immediately! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         embedding = Array.new(1024) { 1 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         WebMock.stub_request( | 
					
						
							|  |  |  |           :post, | 
					
						
							|  |  |  |           "#{SiteSetting.ai_embeddings_discourse_service_api_endpoint}/api/v1/classify", | 
					
						
							|  |  |  |         ).to_return(status: 200, body: JSON.dump(embedding)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # miss first | 
					
						
							|  |  |  |         ids = semantic_related.related_topic_ids_for(topic) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # clear cache so we lookup | 
					
						
							|  |  |  |         described_class.clear_cache_for(topic) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # hit cause we queued generation | 
					
						
							|  |  |  |         ids = semantic_related.related_topic_ids_for(topic) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # at this point though the only embedding is ourselves | 
					
						
							|  |  |  |         expect(ids).to eq([topic.id]) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-05-23 10:43:24 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "queues job only once per 15 minutes" do | 
					
						
							|  |  |  |         results = nil | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-01 00:38:47 +11:00
										 |  |  |         expect_enqueued_with( | 
					
						
							|  |  |  |           job: :generate_embeddings, | 
					
						
							|  |  |  |           args: { | 
					
						
							|  |  |  |             target_id: topic.id, | 
					
						
							|  |  |  |             target_type: "Topic", | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         ) { results = semantic_related.related_topic_ids_for(topic) } | 
					
						
							| 
									
										
										
										
											2023-05-23 10:43:24 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(results).to eq([]) | 
					
						
							| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-01 00:38:47 +11:00
										 |  |  |         expect_not_enqueued_with( | 
					
						
							|  |  |  |           job: :generate_embeddings, | 
					
						
							|  |  |  |           args: { | 
					
						
							|  |  |  |             target_id: topic.id, | 
					
						
							|  |  |  |             target_type: "Topic", | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         ) { results = semantic_related.related_topic_ids_for(topic) } | 
					
						
							| 
									
										
										
										
											2023-05-23 10:43:24 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(results).to eq([]) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |