diff options
Diffstat (limited to 'spec/models/container_repository_spec.rb')
-rw-r--r-- | spec/models/container_repository_spec.rb | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb new file mode 100644 index 00000000000..eff41d85972 --- /dev/null +++ b/spec/models/container_repository_spec.rb @@ -0,0 +1,234 @@ +require 'spec_helper' + +describe ContainerRepository do + let(:group) { create(:group, name: 'group') } + let(:project) { create(:project, path: 'test', group: group) } + + let(:repository) do + create(:container_repository, name: 'my_image', project: project) + end + + before do + stub_container_registry_config(enabled: true, + api_url: 'http://registry.gitlab', + host_port: 'registry.gitlab') + + stub_request(:get, 'http://registry.gitlab/v2/group/test/my_image/tags/list') + .with(headers: { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }) + .to_return( + status: 200, + body: JSON.dump(tags: ['test_tag']), + headers: { 'Content-Type' => 'application/json' }) + end + + describe 'associations' do + it 'belongs to the project' do + expect(repository).to belong_to(:project) + end + end + + describe '#tag' do + it 'has a test tag' do + expect(repository.tag('test')).not_to be_nil + end + end + + describe '#path' do + context 'when project path does not contain uppercase letters' do + it 'returns a full path to the repository' do + expect(repository.path).to eq('group/test/my_image') + end + end + + context 'when path contains uppercase letters' do + let(:project) { create(:project, path: 'MY_PROJECT', group: group) } + + it 'returns a full path without capital letters' do + expect(repository.path).to eq('group/my_project/my_image') + end + end + end + + describe '#manifest' do + it 'returns non-empty manifest' do + expect(repository.manifest).not_to be_nil + end + end + + describe '#valid?' do + it 'is a valid repository' do + expect(repository).to be_valid + end + end + + describe '#tags' do + it 'returns non-empty tags list' do + expect(repository.tags).not_to be_empty + end + end + + describe '#has_tags?' do + it 'has tags' do + expect(repository).to have_tags + end + end + + describe '#delete_tags!' do + let(:repository) do + create(:container_repository, name: 'my_image', + tags: %w[latest rc1], + project: project) + end + + context 'when action succeeds' do + it 'returns status that indicates success' do + expect(repository.client) + .to receive(:delete_repository_tag) + .and_return(true) + + expect(repository.delete_tags!).to be_truthy + end + end + + context 'when action fails' do + it 'returns status that indicates failure' do + expect(repository.client) + .to receive(:delete_repository_tag) + .and_return(false) + + expect(repository.delete_tags!).to be_falsey + end + end + end + + describe '#location' do + context 'when registry is running on a custom port' do + before do + stub_container_registry_config(enabled: true, + api_url: 'http://registry.gitlab:5000', + host_port: 'registry.gitlab:5000') + end + + it 'returns a full location of the repository' do + expect(repository.location) + .to eq 'registry.gitlab:5000/group/test/my_image' + end + end + end + + describe '#root_repository?' do + context 'when repository is a root repository' do + let(:repository) { create(:container_repository, :root) } + + it 'returns true' do + expect(repository).to be_root_repository + end + end + + context 'when repository is not a root repository' do + it 'returns false' do + expect(repository).not_to be_root_repository + end + end + end + + describe '.build_from_path' do + let(:registry_path) do + ContainerRegistry::Path.new(project.full_path + '/some/image') + end + + let(:repository) do + described_class.build_from_path(registry_path) + end + + it 'fabricates repository assigned to a correct project' do + expect(repository.project).to eq project + end + + it 'fabricates repository with a correct name' do + expect(repository.name).to eq 'some/image' + end + + it 'is not persisted' do + expect(repository).not_to be_persisted + end + end + + describe '.create_from_path!' do + let(:repository) do + described_class.create_from_path!(ContainerRegistry::Path.new(path)) + end + + let(:repository_path) { ContainerRegistry::Path.new(path) } + + context 'when received multi-level repository path' do + let(:path) { project.full_path + '/some/image' } + + it 'fabricates repository assigned to a correct project' do + expect(repository.project).to eq project + end + + it 'fabricates repository with a correct name' do + expect(repository.name).to eq 'some/image' + end + end + + context 'when path is too long' do + let(:path) do + project.full_path + '/a/b/c/d/e/f/g/h/i/j/k/l/n/o/p/s/t/u/x/y/z' + end + + it 'does not create repository and raises error' do + expect { repository }.to raise_error( + ContainerRegistry::Path::InvalidRegistryPathError) + end + end + + context 'when received multi-level repository with nested groups' do + let(:group) { create(:group, :nested, name: 'nested') } + let(:path) { project.full_path + '/some/image' } + + it 'fabricates repository assigned to a correct project' do + expect(repository.project).to eq project + end + + it 'fabricates repository with a correct name' do + expect(repository.name).to eq 'some/image' + end + + it 'has path including a nested group' do + expect(repository.path).to include 'nested/test/some/image' + end + end + + context 'when received root repository path' do + let(:path) { project.full_path } + + it 'fabricates repository assigned to a correct project' do + expect(repository.project).to eq project + end + + it 'fabricates repository with an empty name' do + expect(repository.name).to be_empty + end + end + end + + describe '.build_root_repository' do + let(:repository) do + described_class.build_root_repository(project) + end + + it 'fabricates a root repository object' do + expect(repository).to be_root_repository + end + + it 'assignes it to the correct project' do + expect(repository.project).to eq project + end + + it 'does not persist it' do + expect(repository).not_to be_persisted + end + end +end |