// Copyright 2015-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
//	http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 entity

import (
	"errors"
	"fmt"
	"testing"

	"github.com/aws/amazon-ecs-cli/ecs-cli/modules/cli/compose/context"
	"github.com/aws/amazon-ecs-cli/ecs-cli/modules/cli/compose/entity/mock"
	"github.com/aws/amazon-ecs-cli/ecs-cli/modules/clients/aws/ec2/mock"
	"github.com/aws/amazon-ecs-cli/ecs-cli/modules/clients/aws/ecs/mock"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/aws/aws-sdk-go/service/ecs"
	"github.com/golang/mock/gomock"
	"github.com/stretchr/testify/assert"
)

const (
	eniIdentifier    = "eni-123456"
	taskArn          = "arn:123346:task/mytask"
	taskDefArn       = "arn:123456:taskdefinition/mytaskdef"
	privateIPAddress = "10.0.0.1"
	publicIPAddress  = "55.241.196.185"
)

func TestGetContainersForTasks(t *testing.T) {
	containerInstanceArn := "containerInstanceArn"
	ec2InstanceID := "ec2InstanceId"
	ec2Instance := &ec2.Instance{PublicIpAddress: aws.String(publicIPAddress)}

	ecsTasks := []*ecs.Task{
		&ecs.Task{
			Containers: []*ecs.Container{
				&ecs.Container{
					Name: aws.String("containerName"),
				},
			},
			ContainerInstanceArn: aws.String(containerInstanceArn),
		},
	}
	containerInstances := make(map[string]string)
	containerInstances[containerInstanceArn] = ec2InstanceID

	ec2Instances := make(map[string]*ec2.Instance)
	ec2Instances[ec2InstanceID] = ec2Instance

	mockProjectEntity := setupMocks(t, []*string{aws.String(containerInstanceArn)}, containerInstances,
		[]*string{aws.String(ec2InstanceID)}, ec2Instances)

	containers, err := getContainersForTasks(mockProjectEntity, ecsTasks, nil)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasks")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Equal(t, aws.StringValue(ec2Instance.PublicIpAddress), containers[0].EC2IPAddress, "Expects PublicIpAddress to match")
}

func ecsTask(launchType string) *ecs.Task {
	return ecsTaskWithOptions(launchType, ENIStatusAttached, ecs.DesiredStatusRunning)
}

func ecsTaskWithOptions(launchType string, attachmentStatus string, taskStatus string) *ecs.Task {
	return &ecs.Task{
		TaskDefinitionArn: aws.String(taskDefArn),
		TaskArn:           aws.String(taskArn),
		LaunchType:        aws.String(launchType),
		LastStatus:        aws.String(taskStatus),
		Attachments: []*ecs.Attachment{
			&ecs.Attachment{
				Status: aws.String(attachmentStatus),
				Type:   aws.String(ENIAttachmentType),
				Details: []*ecs.KeyValuePair{
					&ecs.KeyValuePair{
						Name:  aws.String(eniIDKey),
						Value: aws.String(eniIdentifier),
					},
				},
			},
		},
		Containers: []*ecs.Container{
			&ecs.Container{
				NetworkInterfaces: []*ecs.NetworkInterface{
					&ecs.NetworkInterface{
						PrivateIpv4Address: aws.String(privateIPAddress),
					},
				},
				Name: aws.String("containerName"),
			},
		},
	}
}

func taskDefinition(networkMode string) *ecs.TaskDefinition {
	return &ecs.TaskDefinition{
		TaskDefinitionArn: aws.String(taskDefArn),
		NetworkMode:       aws.String(networkMode),
		ContainerDefinitions: []*ecs.ContainerDefinition{
			&ecs.ContainerDefinition{
				Name: aws.String("containerName"),
				PortMappings: []*ecs.PortMapping{
					&ecs.PortMapping{
						ContainerPort: aws.Int64(80),
						HostPort:      aws.Int64(80),
						Protocol:      aws.String("tcp"),
					},
				},
			},
		},
	}
}

// Test case ensures that GetContainersForTasksWithTaskNetworking() can be given
// a list of tasks with task networking but without ENIs attached (i.e. task is provisioning) and return correctly.
func TestGetContainersForTasksWithTaskNetworkingENIProvisioning(t *testing.T) {
	ecsTasks := []*ecs.Task{
		&ecs.Task{
			TaskDefinitionArn: aws.String(taskDefArn),
			TaskArn:           aws.String(taskArn),
			Containers: []*ecs.Container{
				&ecs.Container{
					Name: aws.String("containerName"),
				},
			},
		},
	}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}
	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 containers")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
}

// Test case ensures that GetContainersForTasksWithTaskNetworking() can be given
// a list of tasks without task networking and return without error.
func TestGetContainersForTasksWithTaskNetworkingNoNetworkInterfaces(t *testing.T) {
	ecsTasks := []*ecs.Task{
		&ecs.Task{
			TaskDefinitionArn: aws.String(taskDefArn),
			TaskArn:           aws.String(taskArn),
			Containers: []*ecs.Container{
				&ecs.Container{
					Name: aws.String("containerName"),
				},
			},
		},
	}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}
	taskDef := taskDefinition(ecs.NetworkModeHost)

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 0, "Expected to have 0 containers")
	assert.Len(t, tasks, 1, "Expected to have 1 tasks without task networking")
}

func TestGetContainersForTasksWithTaskNetworkingFargateENIDeleted(t *testing.T) {
	ecsTasks := []*ecs.Task{
		ecsTaskWithOptions("FARGATE", "DELETED", ecs.DesiredStatusRunning),
	}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}
	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
	assert.Equal(t, privateIPAddress, containers[0].EC2IPAddress)
	assert.Equal(t, privateIPAddress+":80->80/tcp", containers[0].PortString())
}

func TestGetContainersForTasksWithTaskNetworkingFargateTaskStopped(t *testing.T) {
	ecsTasks := []*ecs.Task{
		ecsTaskWithOptions("FARGATE", "DELETED", ecs.DesiredStatusStopped),
	}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}
	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
	assert.Empty(t, containers[0].EC2IPAddress)
	assert.Equal(t, "80->80/tcp", containers[0].PortString())
}

func TestGetContainersForTasksWithTaskNetworkingEC2TaskStopped(t *testing.T) {
	ecsTasks := []*ecs.Task{
		ecsTaskWithOptions("EC2", "DELETED", ecs.DesiredStatusStopped),
	}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}
	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
	assert.Empty(t, containers[0].EC2IPAddress)
	assert.Equal(t, "80->80/tcp", containers[0].PortString())
}

func TestGetContainersForTasksWithTaskNetworkingEC2(t *testing.T) {
	ecsTasks := []*ecs.Task{
		ecsTask("EC2"),
	}

	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
	assert.Equal(t, privateIPAddress, containers[0].EC2IPAddress)
	assert.Equal(t, privateIPAddress+":80->80/tcp", containers[0].PortString())
}

func TestGetContainersForTasksWithTaskNetworkingFargate(t *testing.T) {
	ecsTasks := []*ecs.Task{
		ecsTask("FARGATE"),
	}

	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	eni := &ec2.NetworkInterface{
		NetworkInterfaceId: aws.String(eniIdentifier),
		Association: &ec2.NetworkInterfaceAssociation{
			PublicIp: aws.String(publicIPAddress),
		},
	}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEc2.EXPECT().DescribeNetworkInterfaces(gomock.Any()).Do(func(x interface{}) {
			eniIDs := x.([]*string)
			assert.Equal(t, eniIdentifier, aws.StringValue(eniIDs[0]))
		}).Return([]*ec2.NetworkInterface{eni}, nil),
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
	assert.Equal(t, publicIPAddress, containers[0].EC2IPAddress)
	assert.Equal(t, publicIPAddress+":80->80/tcp", containers[0].PortString())
}

func TestGetContainersForTasksWithTaskNetworkingFargateENIDescribeFails(t *testing.T) {
	ecsTasks := []*ecs.Task{
		ecsTask("FARGATE"),
	}

	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEc2.EXPECT().DescribeNetworkInterfaces(gomock.Any()).Do(func(x interface{}) {
			eniIDs := x.([]*string)
			assert.Equal(t, eniIdentifier, aws.StringValue(eniIDs[0]))
		}).Return(nil, fmt.Errorf("Some API Error")),
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
	assert.Equal(t, privateIPAddress, containers[0].EC2IPAddress)
	assert.Equal(t, privateIPAddress+":80->80/tcp", containers[0].PortString())
}

func TestGetContainersForTasksWithTaskNetworkingFargateENIWithoutPublicIP(t *testing.T) {
	ecsTasks := []*ecs.Task{
		ecsTask("FARGATE"),
	}

	taskDef := taskDefinition(ecs.NetworkModeAwsvpc)

	eni := &ec2.NetworkInterface{
		NetworkInterfaceId: aws.String(eniIdentifier),
	}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)
	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEc2.EXPECT().DescribeNetworkInterfaces(gomock.Any()).Do(func(x interface{}) {
			eniIDs := x.([]*string)
			assert.Equal(t, eniIdentifier, aws.StringValue(eniIDs[0]))
		}).Return([]*ec2.NetworkInterface{eni}, nil),
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().DescribeTaskDefinition(taskDefArn).Return(taskDef, nil),
	)

	containers, tasks, err := getContainersForTasksWithTaskNetworking(mockProjectEntity, ecsTasks)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasksWithTaskNetworking")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Len(t, tasks, 0, "Expected to have 0 tasks without task networking")
	assert.Equal(t, privateIPAddress, containers[0].EC2IPAddress)
	assert.Equal(t, privateIPAddress+":80->80/tcp", containers[0].PortString())
}

func TestGetContainersForTasksPrivateIP(t *testing.T) {
	containerInstanceArn := "containerInstanceArn"
	ec2InstanceID := "ec2InstanceId"
	ec2Instance := &ec2.Instance{PrivateIpAddress: aws.String(privateIPAddress)}

	ecsTasks := []*ecs.Task{
		&ecs.Task{
			Containers: []*ecs.Container{
				&ecs.Container{
					Name: aws.String("containerName"),
				},
			},
			ContainerInstanceArn: aws.String(containerInstanceArn),
		},
	}
	containerInstances := make(map[string]string)
	containerInstances[containerInstanceArn] = ec2InstanceID

	ec2Instances := make(map[string]*ec2.Instance)
	ec2Instances[ec2InstanceID] = ec2Instance

	mockProjectEntity := setupMocks(t, []*string{aws.String(containerInstanceArn)}, containerInstances,
		[]*string{aws.String(ec2InstanceID)}, ec2Instances)

	containers, err := getContainersForTasks(mockProjectEntity, ecsTasks, nil)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasks")
	assert.Len(t, containers, 1, "Expected to have 1 container")
	assert.Equal(t, aws.StringValue(ec2Instance.PrivateIpAddress), containers[0].EC2IPAddress, "Expects PublicIpAddress to match")
}

func TestGetContainersForTasksWithoutEc2InstanceID(t *testing.T) {
	containerInstanceArn := "containerInstanceArn"
	ec2InstanceID := "ec2InstanceId"

	ecsTasks := []*ecs.Task{
		&ecs.Task{
			Containers: []*ecs.Container{
				&ecs.Container{
					Name: aws.String("containerName"),
				},
			},
			ContainerInstanceArn: aws.String(containerInstanceArn),
		},
	}
	containerInstances := make(map[string]string)
	containerInstances[containerInstanceArn] = ec2InstanceID

	// No ec2InstanceID is found
	ec2Instances := make(map[string]*ec2.Instance)

	projectEntity := setupMocks(t, []*string{aws.String(containerInstanceArn)}, containerInstances,
		[]*string{aws.String(ec2InstanceID)}, ec2Instances)

	containers, err := getContainersForTasks(projectEntity, ecsTasks, nil)
	assert.NoError(t, err, "Unexpected error when calling getContainersForTasks")
	assert.Len(t, containers, 1, "Expects to have 1 containers")
	assert.Empty(t, containers[0].EC2IPAddress, "Expects ec2IpAddress to be empty")
}

func TestGetContainersForTasksErrorCases(t *testing.T) {
	containerInstanceArn := "containerInstanceArn"
	ec2InstanceID := "ec2InstanceId"

	ecsTasks := []*ecs.Task{
		&ecs.Task{
			Containers: []*ecs.Container{
				&ecs.Container{
					Name: aws.String("containerName"),
				},
			},
			ContainerInstanceArn: aws.String(containerInstanceArn),
		},
	}
	containerInstances := make(map[string]string)
	containerInstances[containerInstanceArn] = ec2InstanceID

	mockEc2, mockEcs, mockProjectEntity := setupTest(t)
	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}
	// GetEC2InstanceIDs failed
	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().GetEC2InstanceIDs(gomock.Any()).Return(nil, errors.New("something wrong")),
	)

	_, err := getContainersForTasks(mockProjectEntity, ecsTasks, nil)
	assert.Error(t, err, "Expected error when calling getContainersForTasks")

	// DescribeInstances failed
	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().GetEC2InstanceIDs(gomock.Any()).Return(containerInstances, nil),
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEc2.EXPECT().DescribeInstances(gomock.Any()).Return(nil, errors.New("something wrong")),
	)
	_, err = getContainersForTasks(mockProjectEntity, ecsTasks, nil)
	assert.Error(t, err, "Expected error when calling getContainersForTasks")
}

func setupTest(t *testing.T) (*mock_ec2.MockEC2Client, *mock_ecs.MockECSClient, *mock_entity.MockProjectEntity) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()
	mockEcs := mock_ecs.NewMockECSClient(ctrl)
	mockEc2 := mock_ec2.NewMockEC2Client(ctrl)

	mockProjectEntity := mock_entity.NewMockProjectEntity(ctrl)

	return mockEc2, mockEcs, mockProjectEntity
}

func setupMocks(t *testing.T, getEc2InstanceIDsRequest []*string, getEc2InstanceIDsResult map[string]string,
	describeInstancesRequest []*string, describeInstancesResult map[string]*ec2.Instance) *mock_entity.MockProjectEntity {

	mockEc2, mockEcs, mockProjectEntity := setupTest(t)

	mockContext := &context.ECSContext{
		ECSClient: mockEcs,
		EC2Client: mockEc2,
	}

	gomock.InOrder(
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEcs.EXPECT().GetEC2InstanceIDs(getEc2InstanceIDsRequest).Return(getEc2InstanceIDsResult, nil),
		mockProjectEntity.EXPECT().Context().Return(mockContext),
		mockEc2.EXPECT().DescribeInstances(describeInstancesRequest).Return(describeInstancesResult, nil),
	)
	return mockProjectEntity
}
