diff --git a/src/api/app/controllers/public_controller.rb b/src/api/app/controllers/public_controller.rb index 1ecafc2a457..2468a6aaff7 100644 --- a/src/api/app/controllers/public_controller.rb +++ b/src/api/app/controllers/public_controller.rb @@ -145,7 +145,11 @@ def show_request # GET /public/binary_packages/:project/:package def binary_packages check_package_access(params[:project], params[:package], use_source: false) - @pkg = Package.find_by_project_and_name(params[:project], params[:package]) + # Packages of scmsync projects don't exist in the database. follow_project_scmsync_links + # builds a read-only instance from the backend package meta so we can still resolve the + # project, its repositories and the package name/title/description below. + @pkg = Package.get_by_project_and_name(params[:project], params[:package], + use_source: false, follow_project_scmsync_links: true) begin binaries = Xmlhash.parse(Backend::Api::Search.published_binaries_for_package(params[:project], params[:package])) diff --git a/src/api/spec/controllers/public_controller_spec.rb b/src/api/spec/controllers/public_controller_spec.rb index dcda24c8b68..fcfb998ad1d 100644 --- a/src/api/spec/controllers/public_controller_spec.rb +++ b/src/api/spec/controllers/public_controller_spec.rb @@ -189,4 +189,49 @@ it { expect(revisions.count).to eq(1) } end end + + # NOTE: defined last on purpose. VCR names cassettes for anonymous `it { ... }` + # examples after their scoped id, so inserting an example group earlier in this + # file would renumber the recorded cassettes of the groups that follow it. + describe 'GET #binary_packages for a package of an scmsync project' do + let(:scmsync_project) do + create(:project, name: 'scmsync_public_controller_project', scmsync: 'https://github.com/example/scmsync-project.git') + end + let(:package_meta) do + <<~XML + + eza title + eza description + + XML + end + + before do + allow(Backend::Api::Search).to receive(:published_binaries_for_package).and_return('') + end + + context 'when the package exists on the backend' do + before do + # scmsync packages don't exist in the database, they are served from the backend + allow(Backend::Api::Sources::Package).to receive(:meta).and_return(package_meta) + + get :binary_packages, params: { project: scmsync_project.name, package: 'eza' } + end + + it { expect(response).to have_http_status(:success) } + it { expect(assigns(:pkg)).to be_a(Package) } + it { expect(assigns(:pkg).name).to eq('eza') } + it { expect(assigns(:pkg).project).to eq(scmsync_project) } + end + + context 'when the package does not exist on the backend' do + before do + allow(Backend::Api::Sources::Package).to receive(:meta).and_raise(Backend::NotFoundError) + + get :binary_packages, params: { project: scmsync_project.name, package: 'does_not_exist' } + end + + it { expect(response).to have_http_status(:not_found) } + end + end end