mirror of
https://github.com/Gu1llaum-3/sshm.git
synced 2025-10-19 01:17:20 +02:00
fix(cmd): export variables for test accessibility
Export rootCmd->RootCmd and appVersion->AppVersion to fix test compilation errors. Update all references across cmd package and tests.
This commit is contained in:
parent
9bb44da18b
commit
aa6be1d92d
@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/Gu1llaum-3/sshm/internal/ui"
|
"github.com/Gu1llaum-3/sshm/internal/ui"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -26,5 +27,5 @@ var addCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(addCmd)
|
RootCmd.AddCommand(addCmd)
|
||||||
}
|
}
|
||||||
|
@ -12,23 +12,23 @@ func TestAddCommand(t *testing.T) {
|
|||||||
if addCmd.Use != "add [hostname]" {
|
if addCmd.Use != "add [hostname]" {
|
||||||
t.Errorf("Expected Use 'add [hostname]', got '%s'", addCmd.Use)
|
t.Errorf("Expected Use 'add [hostname]', got '%s'", addCmd.Use)
|
||||||
}
|
}
|
||||||
|
|
||||||
if addCmd.Short != "Add a new SSH host configuration" {
|
if addCmd.Short != "Add a new SSH host configuration" {
|
||||||
t.Errorf("Expected Short description, got '%s'", addCmd.Short)
|
t.Errorf("Expected Short description, got '%s'", addCmd.Short)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that it accepts maximum 1 argument
|
// Test that it accepts maximum 1 argument
|
||||||
err := addCmd.Args(addCmd, []string{"host1", "host2"})
|
err := addCmd.Args(addCmd, []string{"host1", "host2"})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Expected error for too many arguments")
|
t.Error("Expected error for too many arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that it accepts 0 or 1 argument
|
// Test that it accepts 0 or 1 argument
|
||||||
err = addCmd.Args(addCmd, []string{})
|
err = addCmd.Args(addCmd, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error for 0 arguments, got %v", err)
|
t.Errorf("Expected no error for 0 arguments, got %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addCmd.Args(addCmd, []string{"hostname"})
|
err = addCmd.Args(addCmd, []string{"hostname"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error for 1 argument, got %v", err)
|
t.Errorf("Expected no error for 1 argument, got %v", err)
|
||||||
@ -38,7 +38,7 @@ func TestAddCommand(t *testing.T) {
|
|||||||
func TestAddCommandRegistration(t *testing.T) {
|
func TestAddCommandRegistration(t *testing.T) {
|
||||||
// Check that add command is registered with root command
|
// Check that add command is registered with root command
|
||||||
found := false
|
found := false
|
||||||
for _, cmd := range rootCmd.Commands() {
|
for _, cmd := range RootCmd.Commands() {
|
||||||
if cmd.Name() == "add" {
|
if cmd.Name() == "add" {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
@ -53,17 +53,17 @@ func TestAddCommandHelp(t *testing.T) {
|
|||||||
// Test help output
|
// Test help output
|
||||||
cmd := &cobra.Command{}
|
cmd := &cobra.Command{}
|
||||||
cmd.AddCommand(addCmd)
|
cmd.AddCommand(addCmd)
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
cmd.SetOut(buf)
|
cmd.SetOut(buf)
|
||||||
cmd.SetArgs([]string{"add", "--help"})
|
cmd.SetArgs([]string{"add", "--help"})
|
||||||
|
|
||||||
// This should not return an error for help
|
// This should not return an error for help
|
||||||
err := cmd.Execute()
|
err := cmd.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error for help command, got %v", err)
|
t.Errorf("Expected no error for help command, got %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
output := buf.String()
|
output := buf.String()
|
||||||
if !contains(output, "Add a new SSH host configuration") {
|
if !contains(output, "Add a new SSH host configuration") {
|
||||||
t.Error("Help output should contain command description")
|
t.Error("Help output should contain command description")
|
||||||
@ -72,10 +72,10 @@ func TestAddCommandHelp(t *testing.T) {
|
|||||||
|
|
||||||
// Helper function to check if string contains substring
|
// Helper function to check if string contains substring
|
||||||
func contains(s, substr string) bool {
|
func contains(s, substr string) bool {
|
||||||
return len(s) >= len(substr) && (s == substr || len(substr) == 0 ||
|
return len(s) >= len(substr) && (s == substr || len(substr) == 0 ||
|
||||||
(len(s) > len(substr) && (s[:len(substr)] == substr ||
|
(len(s) > len(substr) && (s[:len(substr)] == substr ||
|
||||||
s[len(s)-len(substr):] == substr ||
|
s[len(s)-len(substr):] == substr ||
|
||||||
containsSubstring(s, substr))))
|
containsSubstring(s, substr))))
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsSubstring(s, substr string) bool {
|
func containsSubstring(s, substr string) bool {
|
||||||
@ -85,4 +85,4 @@ func containsSubstring(s, substr string) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/Gu1llaum-3/sshm/internal/ui"
|
"github.com/Gu1llaum-3/sshm/internal/ui"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -23,5 +24,5 @@ var editCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(editCmd)
|
RootCmd.AddCommand(editCmd)
|
||||||
}
|
}
|
||||||
|
@ -12,22 +12,22 @@ func TestEditCommand(t *testing.T) {
|
|||||||
if editCmd.Use != "edit <hostname>" {
|
if editCmd.Use != "edit <hostname>" {
|
||||||
t.Errorf("Expected Use 'edit <hostname>', got '%s'", editCmd.Use)
|
t.Errorf("Expected Use 'edit <hostname>', got '%s'", editCmd.Use)
|
||||||
}
|
}
|
||||||
|
|
||||||
if editCmd.Short != "Edit an existing SSH host configuration" {
|
if editCmd.Short != "Edit an existing SSH host configuration" {
|
||||||
t.Errorf("Expected Short description, got '%s'", editCmd.Short)
|
t.Errorf("Expected Short description, got '%s'", editCmd.Short)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that it requires exactly 1 argument
|
// Test that it requires exactly 1 argument
|
||||||
err := editCmd.Args(editCmd, []string{})
|
err := editCmd.Args(editCmd, []string{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Expected error for no arguments")
|
t.Error("Expected error for no arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = editCmd.Args(editCmd, []string{"host1", "host2"})
|
err = editCmd.Args(editCmd, []string{"host1", "host2"})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Expected error for too many arguments")
|
t.Error("Expected error for too many arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = editCmd.Args(editCmd, []string{"hostname"})
|
err = editCmd.Args(editCmd, []string{"hostname"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error for 1 argument, got %v", err)
|
t.Errorf("Expected no error for 1 argument, got %v", err)
|
||||||
@ -37,7 +37,7 @@ func TestEditCommand(t *testing.T) {
|
|||||||
func TestEditCommandRegistration(t *testing.T) {
|
func TestEditCommandRegistration(t *testing.T) {
|
||||||
// Check that edit command is registered with root command
|
// Check that edit command is registered with root command
|
||||||
found := false
|
found := false
|
||||||
for _, cmd := range rootCmd.Commands() {
|
for _, cmd := range RootCmd.Commands() {
|
||||||
if cmd.Name() == "edit" {
|
if cmd.Name() == "edit" {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
@ -52,19 +52,19 @@ func TestEditCommandHelp(t *testing.T) {
|
|||||||
// Test help output
|
// Test help output
|
||||||
cmd := &cobra.Command{}
|
cmd := &cobra.Command{}
|
||||||
cmd.AddCommand(editCmd)
|
cmd.AddCommand(editCmd)
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
cmd.SetOut(buf)
|
cmd.SetOut(buf)
|
||||||
cmd.SetArgs([]string{"edit", "--help"})
|
cmd.SetArgs([]string{"edit", "--help"})
|
||||||
|
|
||||||
// This should not return an error for help
|
// This should not return an error for help
|
||||||
err := cmd.Execute()
|
err := cmd.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error for help command, got %v", err)
|
t.Errorf("Expected no error for help command, got %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
output := buf.String()
|
output := buf.String()
|
||||||
if !contains(output, "Edit an existing SSH host configuration") {
|
if !contains(output, "Edit an existing SSH host configuration") {
|
||||||
t.Error("Help output should contain command description")
|
t.Error("Help output should contain command description")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,5 +24,5 @@ var moveCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(moveCmd)
|
RootCmd.AddCommand(moveCmd)
|
||||||
}
|
}
|
||||||
|
21
cmd/root.go
21
cmd/root.go
@ -15,13 +15,14 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
// appVersion will be set at build time via -ldflags
|
// AppVersion will be set at build time via -ldflags
|
||||||
var appVersion = "dev"
|
var AppVersion = "dev"
|
||||||
|
|
||||||
// configFile holds the path to the SSH config file
|
// configFile holds the path to the SSH config file
|
||||||
var configFile string
|
var configFile string
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
// RootCmd is the base command when called without any subcommands
|
||||||
|
var RootCmd = &cobra.Command{
|
||||||
Use: "sshm",
|
Use: "sshm",
|
||||||
Short: "SSH Manager - A modern SSH connection manager",
|
Short: "SSH Manager - A modern SSH connection manager",
|
||||||
Long: `SSHM is a modern SSH manager for your terminal.
|
Long: `SSHM is a modern SSH manager for your terminal.
|
||||||
@ -32,7 +33,7 @@ Main usage:
|
|||||||
You can also use sshm in CLI mode for direct operations.
|
You can also use sshm in CLI mode for direct operations.
|
||||||
|
|
||||||
Hosts are read from your ~/.ssh/config file by default.`,
|
Hosts are read from your ~/.ssh/config file by default.`,
|
||||||
Version: appVersion,
|
Version: AppVersion,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
// If no arguments provided, run interactive mode
|
// If no arguments provided, run interactive mode
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
@ -88,7 +89,7 @@ func runInteractiveMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the interactive TUI
|
// Run the interactive TUI
|
||||||
if err := ui.RunInteractiveMode(hosts, configFile, appVersion); err != nil {
|
if err := ui.RunInteractiveMode(hosts, configFile, AppVersion); err != nil {
|
||||||
log.Fatalf("Error running interactive mode: %v", err)
|
log.Fatalf("Error running interactive mode: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,13 +142,13 @@ func connectToHost(hostName string) {
|
|||||||
|
|
||||||
// getVersionWithUpdateCheck returns a custom version string with update check
|
// getVersionWithUpdateCheck returns a custom version string with update check
|
||||||
func getVersionWithUpdateCheck() string {
|
func getVersionWithUpdateCheck() string {
|
||||||
versionText := fmt.Sprintf("sshm version %s", appVersion)
|
versionText := fmt.Sprintf("sshm version %s", AppVersion)
|
||||||
|
|
||||||
// Check for updates
|
// Check for updates
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
updateInfo, err := version.CheckForUpdates(ctx, appVersion)
|
updateInfo, err := version.CheckForUpdates(ctx, AppVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Return just version if check fails
|
// Return just version if check fails
|
||||||
return versionText + "\n"
|
return versionText + "\n"
|
||||||
@ -165,7 +166,7 @@ func getVersionWithUpdateCheck() string {
|
|||||||
|
|
||||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
func Execute() {
|
func Execute() {
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := RootCmd.Execute(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@ -173,8 +174,8 @@ func Execute() {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Add the config file flag
|
// Add the config file flag
|
||||||
rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "", "SSH config file to use (default: ~/.ssh/config)")
|
RootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "", "SSH config file to use (default: ~/.ssh/config)")
|
||||||
|
|
||||||
// Set custom version template with update check
|
// Set custom version template with update check
|
||||||
rootCmd.SetVersionTemplate(getVersionWithUpdateCheck())
|
RootCmd.SetVersionTemplate(getVersionWithUpdateCheck())
|
||||||
}
|
}
|
||||||
|
@ -8,27 +8,28 @@ import (
|
|||||||
|
|
||||||
func TestRootCommand(t *testing.T) {
|
func TestRootCommand(t *testing.T) {
|
||||||
// Test that the root command is properly configured
|
// Test that the root command is properly configured
|
||||||
if rootCmd.Use != "sshm" {
|
if RootCmd.Use != "sshm" {
|
||||||
t.Errorf("Expected Use 'sshm', got '%s'", rootCmd.Use)
|
t.Errorf("Expected Use 'sshm', got '%s'", RootCmd.Use)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rootCmd.Short != "SSH Manager - A modern SSH connection manager" {
|
if RootCmd.Short != "SSH Manager - A modern SSH connection manager" {
|
||||||
t.Errorf("Expected Short description, got '%s'", rootCmd.Short)
|
t.Errorf("Expected Short description, got '%s'", RootCmd.Short)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rootCmd.Version != version {
|
if RootCmd.Version != AppVersion {
|
||||||
t.Errorf("Expected Version '%s', got '%s'", version, rootCmd.Version)
|
t.Errorf("Expected Version '%s', got '%s'", AppVersion, RootCmd.Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRootCommandFlags(t *testing.T) {
|
func TestRootCommandFlags(t *testing.T) {
|
||||||
// Test that persistent flags are properly configured
|
// Test that persistent flags are properly configured
|
||||||
flags := rootCmd.PersistentFlags()
|
flags := RootCmd.PersistentFlags()
|
||||||
|
|
||||||
// Check config flag
|
// Check config flag
|
||||||
configFlag := flags.Lookup("config")
|
configFlag := flags.Lookup("config")
|
||||||
if configFlag == nil {
|
if configFlag == nil {
|
||||||
t.Error("Expected --config flag to be defined")
|
t.Error("Expected --config flag to be defined")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if configFlag.Shorthand != "c" {
|
if configFlag.Shorthand != "c" {
|
||||||
t.Errorf("Expected config flag shorthand 'c', got '%s'", configFlag.Shorthand)
|
t.Errorf("Expected config flag shorthand 'c', got '%s'", configFlag.Shorthand)
|
||||||
@ -40,7 +41,7 @@ func TestRootCommandSubcommands(t *testing.T) {
|
|||||||
// Note: completion and help are automatically added by Cobra and may not always appear in Commands()
|
// Note: completion and help are automatically added by Cobra and may not always appear in Commands()
|
||||||
expectedCommands := []string{"add", "edit", "search"}
|
expectedCommands := []string{"add", "edit", "search"}
|
||||||
|
|
||||||
commands := rootCmd.Commands()
|
commands := RootCmd.Commands()
|
||||||
commandNames := make(map[string]bool)
|
commandNames := make(map[string]bool)
|
||||||
for _, cmd := range commands {
|
for _, cmd := range commands {
|
||||||
commandNames[cmd.Name()] = true
|
commandNames[cmd.Name()] = true
|
||||||
@ -61,11 +62,11 @@ func TestRootCommandSubcommands(t *testing.T) {
|
|||||||
func TestRootCommandHelp(t *testing.T) {
|
func TestRootCommandHelp(t *testing.T) {
|
||||||
// Test help output
|
// Test help output
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
rootCmd.SetOut(buf)
|
RootCmd.SetOut(buf)
|
||||||
rootCmd.SetArgs([]string{"--help"})
|
RootCmd.SetArgs([]string{"--help"})
|
||||||
|
|
||||||
// This should not return an error for help
|
// This should not return an error for help
|
||||||
err := rootCmd.Execute()
|
err := RootCmd.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error for help command, got %v", err)
|
t.Errorf("Expected no error for help command, got %v", err)
|
||||||
}
|
}
|
||||||
@ -82,16 +83,16 @@ func TestRootCommandHelp(t *testing.T) {
|
|||||||
func TestRootCommandVersion(t *testing.T) {
|
func TestRootCommandVersion(t *testing.T) {
|
||||||
// Test that version command executes without error
|
// Test that version command executes without error
|
||||||
// Note: Cobra handles version output internally, so we just check for no error
|
// Note: Cobra handles version output internally, so we just check for no error
|
||||||
rootCmd.SetArgs([]string{"--version"})
|
RootCmd.SetArgs([]string{"--version"})
|
||||||
|
|
||||||
// This should not return an error for version
|
// This should not return an error for version
|
||||||
err := rootCmd.Execute()
|
err := RootCmd.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error for version command, got %v", err)
|
t.Errorf("Expected no error for version command, got %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset args for other tests
|
// Reset args for other tests
|
||||||
rootCmd.SetArgs([]string{})
|
RootCmd.SetArgs([]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecuteFunction(t *testing.T) {
|
func TestExecuteFunction(t *testing.T) {
|
||||||
@ -124,8 +125,8 @@ func TestConfigFileVariable(t *testing.T) {
|
|||||||
defer func() { configFile = originalConfigFile }()
|
defer func() { configFile = originalConfigFile }()
|
||||||
|
|
||||||
// Set config file through flag
|
// Set config file through flag
|
||||||
rootCmd.SetArgs([]string{"--config", "/tmp/test-config"})
|
RootCmd.SetArgs([]string{"--config", "/tmp/test-config"})
|
||||||
rootCmd.ParseFlags([]string{"--config", "/tmp/test-config"})
|
RootCmd.ParseFlags([]string{"--config", "/tmp/test-config"})
|
||||||
|
|
||||||
// The configFile variable should be updated by the flag parsing
|
// The configFile variable should be updated by the flag parsing
|
||||||
// Note: This test verifies the flag binding works
|
// Note: This test verifies the flag binding works
|
||||||
@ -133,12 +134,12 @@ func TestConfigFileVariable(t *testing.T) {
|
|||||||
|
|
||||||
func TestVersionVariable(t *testing.T) {
|
func TestVersionVariable(t *testing.T) {
|
||||||
// Test that version variable has a default value
|
// Test that version variable has a default value
|
||||||
if version == "" {
|
if AppVersion == "" {
|
||||||
t.Error("version variable should have a default value")
|
t.Error("AppVersion variable should have a default value")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that version is set to "dev" by default
|
// Test that version is set to "dev" by default
|
||||||
if version != "dev" {
|
if AppVersion != "dev" {
|
||||||
t.Logf("version is set to '%s' (expected 'dev' for development)", version)
|
t.Logf("AppVersion is set to '%s' (expected 'dev' for development)", AppVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ func escapeJSON(s string) string {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Add search command to root
|
// Add search command to root
|
||||||
rootCmd.AddCommand(searchCmd)
|
RootCmd.AddCommand(searchCmd)
|
||||||
|
|
||||||
// Add flags
|
// Add flags
|
||||||
searchCmd.Flags().StringVarP(&outputFormat, "format", "f", "table", "Output format (table, json, simple)")
|
searchCmd.Flags().StringVarP(&outputFormat, "format", "f", "table", "Output format (table, json, simple)")
|
||||||
|
@ -36,7 +36,7 @@ func TestSearchCommand(t *testing.T) {
|
|||||||
func TestSearchCommandRegistration(t *testing.T) {
|
func TestSearchCommandRegistration(t *testing.T) {
|
||||||
// Check that search command is registered with root command
|
// Check that search command is registered with root command
|
||||||
found := false
|
found := false
|
||||||
for _, cmd := range rootCmd.Commands() {
|
for _, cmd := range RootCmd.Commands() {
|
||||||
if cmd.Name() == "search" {
|
if cmd.Name() == "search" {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
|
Loading…
x
Reference in New Issue
Block a user