Commit 800a5f8e authored by Kamil Trzcinski's avatar Kamil Trzcinski

Add serializer matchers

parent 97729015
...@@ -15,13 +15,13 @@ module Projects ...@@ -15,13 +15,13 @@ module Projects
end end
def destroy def destroy
respond_to do |format| if tag.delete
format.json do respond_to do |format|
if tag.delete format.json { head :no_content }
format.json { head :no_content } end
else else
format.json { head :bad_request } respond_to do |format|
end format.json { head :bad_request }
end end
end end
end end
......
...@@ -42,6 +42,13 @@ describe Projects::Registry::RepositoriesController do ...@@ -42,6 +42,13 @@ describe Projects::Registry::RepositoriesController do
expect { go_to_index }.to change { ContainerRepository.all.count }.by(1) expect { go_to_index }.to change { ContainerRepository.all.count }.by(1)
expect(ContainerRepository.first).to be_root_repository expect(ContainerRepository.first).to be_root_repository
end end
it 'json has a list of projects' do
go_to_index(format: :json)
expect(response).to have_http_status(:ok)
expect(response).to match_response_schema('registry/repositories')
end
end end
context 'when there are no tags for this repository' do context 'when there are no tags for this repository' do
...@@ -58,6 +65,31 @@ describe Projects::Registry::RepositoriesController do ...@@ -58,6 +65,31 @@ describe Projects::Registry::RepositoriesController do
it 'does not ensure root container repository' do it 'does not ensure root container repository' do
expect { go_to_index }.not_to change { ContainerRepository.all.count } expect { go_to_index }.not_to change { ContainerRepository.all.count }
end end
it 'responds with json if asked' do
go_to_index(format: :json)
expect(response).to have_http_status(:ok)
expect(json_response).to be_kind_of(Array)
end
end
end
end
describe 'DELETE destroy' do
context 'when root container repository exists' do
let!(:repository) do
create(:container_repository, :root, project: project)
end
before do
stub_container_registry_tags(repository: :any, tags: [])
end
it 'deletes a repository' do
expect { delete_repository(repository) }.to change { ContainerRepository.all.count }.by(-1)
expect(response).to have_http_status(:no_content)
end end
end end
end end
...@@ -77,8 +109,16 @@ describe Projects::Registry::RepositoriesController do ...@@ -77,8 +109,16 @@ describe Projects::Registry::RepositoriesController do
end end
end end
def go_to_index def go_to_index(format: :html)
get :index, namespace_id: project.namespace, get :index, namespace_id: project.namespace,
project_id: project project_id: project,
format: format
end
def delete_repository(repository)
delete :destroy, namespace_id: project.namespace,
project_id: project,
id: repository,
format: :json
end end
end end
...@@ -4,24 +4,83 @@ describe Projects::Registry::TagsController do ...@@ -4,24 +4,83 @@ describe Projects::Registry::TagsController do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project, :private) } let(:project) { create(:project, :private) }
let(:repository) do
create(:container_repository, name: 'image', project: project)
end
before do before do
sign_in(user) sign_in(user)
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
end end
context 'when user has access to registry' do describe 'GET index' do
let(:tags) do
40.times.map { |i| "tag#{i}" }
end
before do before do
project.add_developer(user) stub_container_registry_tags(repository: /image/, tags: tags)
end
context 'when user can control the registry' do
before do
project.add_developer(user)
end
it 'receive a list of tags' do
get_tags
expect(response).to have_http_status(:ok)
expect(response).to match_response_schema('registry/tags')
expect(response).to include_pagination_headers
end
end
context 'when user can read the registry' do
before do
project.add_reporter(user)
end
it 'receive a list of tags' do
get_tags
expect(response).to have_http_status(:ok)
expect(response).to match_response_schema('registry/tags')
expect(response).to include_pagination_headers
end
end end
describe 'POST destroy' do context 'when user does not have access to registry' do
before do
project.add_guest(user)
end
it 'does not receive a list of tags' do
get_tags
expect(response).to have_http_status(:not_found)
end
end
private
def get_tags
get :index, namespace_id: project.namespace,
project_id: project,
repository_id: repository,
format: :json
end
end
describe 'POST destroy' do
context 'when user has access to registry' do
before do
project.add_developer(user)
end
context 'when there is matching tag present' do context 'when there is matching tag present' do
before do before do
stub_container_registry_tags(repository: /image/, tags: %w[rc1 test.]) stub_container_registry_tags(repository: repository.path, tags: %w[rc1 test.])
end
let(:repository) do
create(:container_repository, name: 'image', project: project)
end end
it 'makes it possible to delete regular tag' do it 'makes it possible to delete regular tag' do
...@@ -37,12 +96,15 @@ describe Projects::Registry::TagsController do ...@@ -37,12 +96,15 @@ describe Projects::Registry::TagsController do
end end
end end
end end
end
def destroy_tag(name) private
post :destroy, namespace_id: project.namespace,
project_id: project, def destroy_tag(name)
repository_id: repository, post :destroy, namespace_id: project.namespace,
id: name project_id: project,
repository_id: repository,
id: name,
format: :json
end
end end
end end
require 'spec_helper' require 'spec_helper'
describe "Container Registry" do describe "Container Registry", js: true do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project) } let(:project) { create(:project) }
......
{
"type": "array",
"items": {
"$ref": "repository.json"
}
}
{
"type": "object",
"required" : [
"id",
"path",
"location",
"tags_path"
],
"properties" : {
"id": {
"type": "integer"
},
"path": {
"type": "string"
},
"location": {
"type": "string"
},
"tags_path": {
"type": "string"
},
"destroy_path": {
"type": "string"
}
},
"additionalProperties": false
}
{
"type": "object",
"required" : [
"name",
"location"
],
"properties" : {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"revision": {
"type": "string"
},
"total_size": {
"type": "integer"
},
"created_at": {
"type": "date"
},
"destroy_path": {
"type": "string"
}
},
"additionalProperties": false
}
{
"type": "array",
"items": {
"$ref": "tag.json"
}
}
require 'spec_helper'
describe ContainerRepositoryEntity do
let(:entity) do
described_class.new(repository, request: request)
end
set(:project) { create(:project) }
set(:user) { create(:user) }
set(:repository) { create(:container_repository, project: project) }
let(:request) { double('request') }
subject { entity.as_json }
before do
stub_container_registry_config(enabled: true)
allow(request).to receive(:project).and_return(project)
allow(request).to receive(:current_user).and_return(user)
end
it 'exposes required informations' do
expect(subject).to include(:id, :path, :location, :tags_path)
end
context 'when user can manage repositories' do
before do
project.add_developer(user)
end
it 'exposes destroy_path' do
expect(subject).to include(:destroy_path)
end
end
context 'when user cannot manage repositories' do
it 'does not expose destroy_path' do
expect(subject).not_to include(:destroy_path)
end
end
end
require 'spec_helper'
describe ContainerTagEntity do
let(:entity) do
described_class.new(tag, request: request)
end
set(:project) { create(:project) }
set(:user) { create(:user) }
set(:repository) { create(:container_repository, name: 'image', project: project) }
let(:request) { double('request') }
let(:tag) { repository.tag('test') }
subject { entity.as_json }
before do
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: /image/, tags: %w[test])
allow(request).to receive(:project).and_return(project)
allow(request).to receive(:current_user).and_return(user)
end
it 'exposes required informations' do
expect(subject).to include(:name, :location, :revision, :total_size, :created_at)
end
context 'when user can manage repositories' do
before do
project.add_developer(user)
end
it 'exposes destroy_path' do
expect(subject).to include(:destroy_path)
end
end
context 'when user cannot manage repositories' do
it 'does not expose destroy_path' do
expect(subject).not_to include(:destroy_path)
end
end
end
...@@ -39,11 +39,11 @@ module StubGitlabCalls ...@@ -39,11 +39,11 @@ module StubGitlabCalls
.and_return({ 'tags' => tags }) .and_return({ 'tags' => tags })
allow_any_instance_of(ContainerRegistry::Client) allow_any_instance_of(ContainerRegistry::Client)
.to receive(:repository_manifest).with(repository) .to receive(:repository_manifest).with(repository, anything)
.and_return(stub_container_registry_tag_manifest) .and_return(stub_container_registry_tag_manifest)
allow_any_instance_of(ContainerRegistry::Client) allow_any_instance_of(ContainerRegistry::Client)
.to receive(:blob).with(repository) .to receive(:blob).with(repository, anything, 'application/octet-stream')
.and_return(stub_container_registry_blob) .and_return(stub_container_registry_blob)
end end
......
require 'spec_helper'
describe 'projects/registry/repositories/index' do
let(:group) { create(:group, path: 'group') }
let(:project) { create(:project, group: group, path: 'test') }
let(:repository) do
create(:container_repository, project: project, name: 'image')
end
before do
stub_container_registry_config(enabled: true,
host_port: 'registry.gitlab',
api_url: 'http://registry.gitlab')
stub_container_registry_tags(repository: :any, tags: [:latest])
assign(:project, project)
assign(:images, [repository])
allow(view).to receive(:can?).and_return(true)
end
it 'contains container repository path' do
render
expect(rendered).to have_content 'group/test/image'
end
it 'contains attribute for copying tag location into clipboard' do
render
expect(rendered).to have_css 'button[data-clipboard-text="docker pull ' \
'registry.gitlab/group/test/image:latest"]'
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment