/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestFindMissingPerms(t *testing.T) {
	// permission is larger than required
	userPerms := map[string]bool{
		"repo": true,
	}
	requiredPerms := []string{"repo:status"}
	missingPerms := findMissingPerms(userPerms, requiredPerms)
	assert.Empty(t, missingPerms)

	// permission equals to required
	userPerms = map[string]bool{
		"repo:status": true,
	}
	requiredPerms = []string{"repo:status"}
	missingPerms = findMissingPerms(userPerms, requiredPerms)
	assert.Empty(t, missingPerms)

	// permissions are missing
	userPerms = map[string]bool{
		"admin:org": true,
	}
	requiredPerms = []string{"repo:status", "read:user"}
	missingPerms = findMissingPerms(userPerms, requiredPerms)
	assert.Equal(t, []string{"repo:status", "read:user"}, missingPerms)
}
