forked from loafle/openapi-generator-original
update test case, minor fix to required property in c#
This commit is contained in:
parent
890b7d17e3
commit
d42f23f829
0
bin/jaxrs-resteasy-petstore-server.sh
Normal file → Executable file
0
bin/jaxrs-resteasy-petstore-server.sh
Normal file → Executable file
@ -22,9 +22,10 @@ namespace {{packageName}}.Model
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
|
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public {{classname}}({{#vars}}{{{dataType}}}{{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}})
|
public {{classname}}({{#vars}}{{{datatype}}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}})
|
||||||
{
|
{
|
||||||
{{#vars}}{{#required}}if ({{name}} == null)
|
{{#vars}}{{#required}}// to ensure "{{name}}" is required (not null)
|
||||||
|
if ({{name}} == null)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException("{{name}} is a required property for {{classname}} and cannot be null");
|
throw new InvalidDataException("{{name}} is a required property for {{classname}} and cannot be null");
|
||||||
}
|
}
|
||||||
@ -32,16 +33,17 @@ namespace {{packageName}}.Model
|
|||||||
{
|
{
|
||||||
this.{{name}} = {{name}};
|
this.{{name}} = {{name}};
|
||||||
}
|
}
|
||||||
{{/required}}{{/vars}}
|
{{/required}}{{/vars}}{{#vars}}{{^required}}{{#defaultValue}}// use default value if no "{{name}}" provided
|
||||||
{{#vars}}{{#defaultValue}}if ({{name}} == null)
|
if ({{name}} == null)
|
||||||
{
|
{
|
||||||
this.{{name}} = {{{defaultValue}}};
|
this.{{name}} = {{{defaultValue}}};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.{{name}} = {{name}};
|
this.{{name}} = {{name}};
|
||||||
}
|
}
|
||||||
{{/defaultValue}}{{/vars}}
|
{{/defaultValue}}{{^defaultValue}}this.{{name}} = {{name}};
|
||||||
|
{{/defaultValue}}{{/required}}{{/vars}}
|
||||||
}
|
}
|
||||||
|
|
||||||
{{#vars}}
|
{{#vars}}
|
||||||
@ -50,7 +52,7 @@ namespace {{packageName}}.Model
|
|||||||
/// </summary>{{#description}}
|
/// </summary>{{#description}}
|
||||||
/// <value>{{{description}}}</value>{{/description}}
|
/// <value>{{{description}}}</value>{{/description}}
|
||||||
[DataMember(Name="{{baseName}}", EmitDefaultValue=false)]
|
[DataMember(Name="{{baseName}}", EmitDefaultValue=false)]
|
||||||
public {{{datatype}}} {{name}} { get; {{^isReadOnly}}set;{{/isReadOnly}} }
|
public {{{datatype}}} {{name}} { get; {{#isReadOnly}}private {{/isReadOnly}}set; }
|
||||||
|
|
||||||
{{/vars}}
|
{{/vars}}
|
||||||
|
|
||||||
|
@ -1304,13 +1304,6 @@ namespace IO.Swagger.Api
|
|||||||
}
|
}
|
||||||
// authentication (petstore_auth) required
|
// authentication (petstore_auth) required
|
||||||
|
|
||||||
// oauth required
|
|
||||||
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
|
||||||
{
|
|
||||||
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
|
||||||
}
|
|
||||||
// authentication (petstore_auth) required
|
|
||||||
|
|
||||||
// oauth required
|
// oauth required
|
||||||
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
||||||
{
|
{
|
||||||
@ -1411,14 +1404,6 @@ namespace IO.Swagger.Api
|
|||||||
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// authentication (petstore_auth) required
|
|
||||||
|
|
||||||
// oauth required
|
|
||||||
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
|
||||||
{
|
|
||||||
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// make the HTTP request
|
// make the HTTP request
|
||||||
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_,
|
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_,
|
||||||
@ -2048,13 +2033,6 @@ namespace IO.Swagger.Api
|
|||||||
}
|
}
|
||||||
// authentication (petstore_auth) required
|
// authentication (petstore_auth) required
|
||||||
|
|
||||||
// oauth required
|
|
||||||
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
|
||||||
{
|
|
||||||
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
|
||||||
}
|
|
||||||
// authentication (petstore_auth) required
|
|
||||||
|
|
||||||
// oauth required
|
// oauth required
|
||||||
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
||||||
{
|
{
|
||||||
@ -2155,14 +2133,6 @@ namespace IO.Swagger.Api
|
|||||||
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// authentication (petstore_auth) required
|
|
||||||
|
|
||||||
// oauth required
|
|
||||||
if (!String.IsNullOrEmpty(Configuration.AccessToken))
|
|
||||||
{
|
|
||||||
headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// make the HTTP request
|
// make the HTTP request
|
||||||
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_,
|
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_,
|
||||||
|
@ -676,6 +676,7 @@ namespace IO.Swagger.Api
|
|||||||
|
|
||||||
|
|
||||||
// authentication (test_api_key_header) required
|
// authentication (test_api_key_header) required
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(Configuration.GetApiKeyWithPrefix("test_api_key_header")))
|
if (!String.IsNullOrEmpty(Configuration.GetApiKeyWithPrefix("test_api_key_header")))
|
||||||
{
|
{
|
||||||
headerParams["test_api_key_header"] = Configuration.GetApiKeyWithPrefix("test_api_key_header");
|
headerParams["test_api_key_header"] = Configuration.GetApiKeyWithPrefix("test_api_key_header");
|
||||||
@ -767,12 +768,14 @@ namespace IO.Swagger.Api
|
|||||||
|
|
||||||
|
|
||||||
// authentication (test_api_key_header) required
|
// authentication (test_api_key_header) required
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(Configuration.GetApiKeyWithPrefix("test_api_key_header")))
|
if (!String.IsNullOrEmpty(Configuration.GetApiKeyWithPrefix("test_api_key_header")))
|
||||||
{
|
{
|
||||||
headerParams["test_api_key_header"] = Configuration.GetApiKeyWithPrefix("test_api_key_header");
|
headerParams["test_api_key_header"] = Configuration.GetApiKeyWithPrefix("test_api_key_header");
|
||||||
}
|
}
|
||||||
|
|
||||||
// authentication (test_api_key_query) required
|
// authentication (test_api_key_query) required
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(Configuration.GetApiKeyWithPrefix("test_api_key_query")))
|
if (!String.IsNullOrEmpty(Configuration.GetApiKeyWithPrefix("test_api_key_query")))
|
||||||
{
|
{
|
||||||
queryParams["test_api_key_query"] = Configuration.GetApiKeyWithPrefix("test_api_key_query");
|
queryParams["test_api_key_query"] = Configuration.GetApiKeyWithPrefix("test_api_key_query");
|
||||||
|
@ -20,9 +20,10 @@ namespace IO.Swagger.Model
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Category" /> class.
|
/// Initializes a new instance of the <see cref="Category" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Category(Id = null, Name = null)
|
public Category(long? Id = null, string Name = null)
|
||||||
{
|
{
|
||||||
|
this.Id = Id;
|
||||||
|
this.Name = Name;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,9 +20,14 @@ namespace IO.Swagger.Model
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Order" /> class.
|
/// Initializes a new instance of the <see cref="Order" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Order(Id = null, PetId = null, Quantity = null, ShipDate = null, Status = null, Complete = null)
|
public Order(long? Id = null, long? PetId = null, int? Quantity = null, DateTime? ShipDate = null, string Status = null, bool? Complete = null)
|
||||||
{
|
{
|
||||||
|
this.Id = Id;
|
||||||
|
this.PetId = PetId;
|
||||||
|
this.Quantity = Quantity;
|
||||||
|
this.ShipDate = ShipDate;
|
||||||
|
this.Status = Status;
|
||||||
|
this.Complete = Complete;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +36,7 @@ namespace IO.Swagger.Model
|
|||||||
/// Gets or Sets Id
|
/// Gets or Sets Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataMember(Name="id", EmitDefaultValue=false)]
|
[DataMember(Name="id", EmitDefaultValue=false)]
|
||||||
public long? Id { get; }
|
public long? Id { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -20,8 +20,9 @@ namespace IO.Swagger.Model
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Pet" /> class.
|
/// Initializes a new instance of the <see cref="Pet" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Pet(Id = null, Category = null, Name = null, PhotoUrls = null, Tags = null, Status = null)
|
public Pet(long? Id = null, Category Category = null, string Name = null, List<string> PhotoUrls = null, List<Tag> Tags = null, string Status = null)
|
||||||
{
|
{
|
||||||
|
// to ensure "Name" is required (not null)
|
||||||
if (Name == null)
|
if (Name == null)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException("Name is a required property for Pet and cannot be null");
|
throw new InvalidDataException("Name is a required property for Pet and cannot be null");
|
||||||
@ -30,6 +31,7 @@ namespace IO.Swagger.Model
|
|||||||
{
|
{
|
||||||
this.Name = Name;
|
this.Name = Name;
|
||||||
}
|
}
|
||||||
|
// to ensure "PhotoUrls" is required (not null)
|
||||||
if (PhotoUrls == null)
|
if (PhotoUrls == null)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException("PhotoUrls is a required property for Pet and cannot be null");
|
throw new InvalidDataException("PhotoUrls is a required property for Pet and cannot be null");
|
||||||
@ -38,7 +40,10 @@ namespace IO.Swagger.Model
|
|||||||
{
|
{
|
||||||
this.PhotoUrls = PhotoUrls;
|
this.PhotoUrls = PhotoUrls;
|
||||||
}
|
}
|
||||||
|
this.Id = Id;
|
||||||
|
this.Category = Category;
|
||||||
|
this.Tags = Tags;
|
||||||
|
this.Status = Status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,9 +20,10 @@ namespace IO.Swagger.Model
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Tag" /> class.
|
/// Initializes a new instance of the <see cref="Tag" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Tag(Id = null, Name = null)
|
public Tag(long? Id = null, string Name = null)
|
||||||
{
|
{
|
||||||
|
this.Id = Id;
|
||||||
|
this.Name = Name;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,9 +20,16 @@ namespace IO.Swagger.Model
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="User" /> class.
|
/// Initializes a new instance of the <see cref="User" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public User(Id = null, Username = null, FirstName = null, LastName = null, Email = null, Password = null, Phone = null, UserStatus = null)
|
public User(long? Id = null, string Username = null, string FirstName = null, string LastName = null, string Email = null, string Password = null, string Phone = null, int? UserStatus = null)
|
||||||
{
|
{
|
||||||
|
this.Id = Id;
|
||||||
|
this.Username = Username;
|
||||||
|
this.FirstName = FirstName;
|
||||||
|
this.LastName = LastName;
|
||||||
|
this.Email = Email;
|
||||||
|
this.Password = Password;
|
||||||
|
this.Phone = Phone;
|
||||||
|
this.UserStatus = UserStatus;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@ namespace SwaggerClientTest.TestPet
|
|||||||
private Pet createPet()
|
private Pet createPet()
|
||||||
{
|
{
|
||||||
// create pet
|
// create pet
|
||||||
Pet p = new Pet();
|
Pet p = new Pet(Name: "Csharp test", PhotoUrls: new List<string> { "http://petstore.com/csharp_test" });
|
||||||
p.Id = petId;
|
p.Id = petId;
|
||||||
p.Name = "Csharp test";
|
//p.Name = "Csharp test";
|
||||||
p.Status = "available";
|
p.Status = "available";
|
||||||
// create Category object
|
// create Category object
|
||||||
Category category = new Category();
|
Category category = new Category();
|
||||||
@ -33,7 +33,7 @@ namespace SwaggerClientTest.TestPet
|
|||||||
// create Tag object
|
// create Tag object
|
||||||
Tag tag = new Tag();
|
Tag tag = new Tag();
|
||||||
tag.Id = petId;
|
tag.Id = petId;
|
||||||
tag.Name = "sample tag name1";
|
tag.Name = "csharp sample tag name1";
|
||||||
List<Tag> tags = new List<Tag>(new Tag[] {tag});
|
List<Tag> tags = new List<Tag>(new Tag[] {tag});
|
||||||
p.Tags = tags;
|
p.Tags = tags;
|
||||||
p.Category = category;
|
p.Category = category;
|
||||||
@ -86,7 +86,7 @@ namespace SwaggerClientTest.TestPet
|
|||||||
|
|
||||||
Assert.IsInstanceOf<List<Tag>> (response.Tags, "Response.Tags is a Array");
|
Assert.IsInstanceOf<List<Tag>> (response.Tags, "Response.Tags is a Array");
|
||||||
Assert.AreEqual (petId, response.Tags [0].Id);
|
Assert.AreEqual (petId, response.Tags [0].Id);
|
||||||
Assert.AreEqual ("sample tag name1", response.Tags [0].Name);
|
Assert.AreEqual ("csharp sample tag name1", response.Tags [0].Name);
|
||||||
|
|
||||||
Assert.IsInstanceOf<List<String>> (response.PhotoUrls, "Response.PhotoUrls is a Array");
|
Assert.IsInstanceOf<List<String>> (response.PhotoUrls, "Response.PhotoUrls is a Array");
|
||||||
Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]);
|
Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]);
|
||||||
@ -118,7 +118,7 @@ namespace SwaggerClientTest.TestPet
|
|||||||
|
|
||||||
Assert.IsInstanceOf<List<Tag>> (response.Tags, "Response.Tags is a Array");
|
Assert.IsInstanceOf<List<Tag>> (response.Tags, "Response.Tags is a Array");
|
||||||
Assert.AreEqual (petId, response.Tags [0].Id);
|
Assert.AreEqual (petId, response.Tags [0].Id);
|
||||||
Assert.AreEqual ("sample tag name1", response.Tags [0].Name);
|
Assert.AreEqual ("csharp sample tag name1", response.Tags [0].Name);
|
||||||
|
|
||||||
Assert.IsInstanceOf<List<String>> (response.PhotoUrls, "Response.PhotoUrls is a Array");
|
Assert.IsInstanceOf<List<String>> (response.PhotoUrls, "Response.PhotoUrls is a Array");
|
||||||
Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]);
|
Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]);
|
||||||
@ -147,7 +147,7 @@ namespace SwaggerClientTest.TestPet
|
|||||||
|
|
||||||
Assert.IsInstanceOf<List<Tag>> (response.Tags, "Response.Tags is a Array");
|
Assert.IsInstanceOf<List<Tag>> (response.Tags, "Response.Tags is a Array");
|
||||||
Assert.AreEqual (petId, response.Tags [0].Id);
|
Assert.AreEqual (petId, response.Tags [0].Id);
|
||||||
Assert.AreEqual ("sample tag name1", response.Tags [0].Name);
|
Assert.AreEqual ("csharp sample tag name1", response.Tags [0].Name);
|
||||||
|
|
||||||
Assert.IsInstanceOf<List<String>> (response.PhotoUrls, "Response.PhotoUrls is a Array");
|
Assert.IsInstanceOf<List<String>> (response.PhotoUrls, "Response.PhotoUrls is a Array");
|
||||||
Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]);
|
Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]);
|
||||||
@ -235,16 +235,16 @@ namespace SwaggerClientTest.TestPet
|
|||||||
/// Test FindPetByStatus
|
/// Test FindPetByStatus
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test ()]
|
[Test ()]
|
||||||
public void TestFindPetByStatus ()
|
public void TestFindPetByTags ()
|
||||||
{
|
{
|
||||||
PetApi petApi = new PetApi ();
|
PetApi petApi = new PetApi ();
|
||||||
List<String> statusList = new List<String>(new String[] {"available"});
|
List<String> tagsList = new List<String>(new String[] {"available"});
|
||||||
|
|
||||||
List<Pet> listPet = petApi.FindPetsByStatus (statusList);
|
List<Pet> listPet = petApi.FindPetsByTags (tagsList);
|
||||||
foreach (Pet pet in listPet) // Loop through List with foreach.
|
foreach (Pet pet in listPet) // Loop through List with foreach.
|
||||||
{
|
{
|
||||||
Assert.IsInstanceOf<Pet> (pet, "Response is a Pet");
|
Assert.IsInstanceOf<Pet> (pet, "Response is a Pet");
|
||||||
Assert.AreEqual ("available", pet.Status);
|
Assert.AreEqual ("csharp sample tag name1", pet.Tags[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -256,9 +256,9 @@ namespace SwaggerClientTest.TestPet
|
|||||||
public void TestEqual()
|
public void TestEqual()
|
||||||
{
|
{
|
||||||
// create pet
|
// create pet
|
||||||
Pet p1 = new Pet();
|
Pet p1 = new Pet(Name: "Csharp test", PhotoUrls: new List<string> { "http://petstore.com/csharp_test"} );
|
||||||
p1.Id = petId;
|
p1.Id = petId;
|
||||||
p1.Name = "Csharp test";
|
//p1.Name = "Csharp test";
|
||||||
p1.Status = "available";
|
p1.Status = "available";
|
||||||
// create Category object
|
// create Category object
|
||||||
Category category1 = new Category();
|
Category category1 = new Category();
|
||||||
@ -268,14 +268,14 @@ namespace SwaggerClientTest.TestPet
|
|||||||
// create Tag object
|
// create Tag object
|
||||||
Tag tag1 = new Tag();
|
Tag tag1 = new Tag();
|
||||||
tag1.Id = petId;
|
tag1.Id = petId;
|
||||||
tag1.Name = "sample tag name1";
|
tag1.Name = "csharp sample tag name1";
|
||||||
List<Tag> tags1 = new List<Tag>(new Tag[] {tag1});
|
List<Tag> tags1 = new List<Tag>(new Tag[] {tag1});
|
||||||
p1.Tags = tags1;
|
p1.Tags = tags1;
|
||||||
p1.Category = category1;
|
p1.Category = category1;
|
||||||
p1.PhotoUrls = photoUrls1;
|
p1.PhotoUrls = photoUrls1;
|
||||||
|
|
||||||
// create pet 2
|
// create pet 2
|
||||||
Pet p2 = new Pet();
|
Pet p2 = new Pet(Name: "Csharp test", PhotoUrls: new List<string> { "http://petstore.com/csharp_test"} );
|
||||||
p2.Id = petId;
|
p2.Id = petId;
|
||||||
p2.Name = "Csharp test";
|
p2.Name = "Csharp test";
|
||||||
p2.Status = "available";
|
p2.Status = "available";
|
||||||
@ -287,7 +287,7 @@ namespace SwaggerClientTest.TestPet
|
|||||||
// create Tag object
|
// create Tag object
|
||||||
Tag tag2 = new Tag();
|
Tag tag2 = new Tag();
|
||||||
tag2.Id = petId;
|
tag2.Id = petId;
|
||||||
tag2.Name = "sample tag name1";
|
tag2.Name = "csharp sample tag name1";
|
||||||
List<Tag> tags2 = new List<Tag>(new Tag[] {tag2});
|
List<Tag> tags2 = new List<Tag>(new Tag[] {tag2});
|
||||||
p2.Tags = tags2;
|
p2.Tags = tags2;
|
||||||
p2.Category = category2;
|
p2.Category = category2;
|
||||||
@ -334,8 +334,9 @@ namespace SwaggerClientTest.TestPet
|
|||||||
public void TestDefaultHeader ()
|
public void TestDefaultHeader ()
|
||||||
{
|
{
|
||||||
PetApi petApi = new PetApi ();
|
PetApi petApi = new PetApi ();
|
||||||
|
// comment out the warning test below as it's confirmed the warning is working as expecteds
|
||||||
// there should be a warning for using AddDefaultHeader (deprecated) below
|
// there should be a warning for using AddDefaultHeader (deprecated) below
|
||||||
petApi.AddDefaultHeader ("header_key", "header_value");
|
//petApi.AddDefaultHeader ("header_key", "header_value");
|
||||||
// the following should be used instead as suggested in the doc
|
// the following should be used instead as suggested in the doc
|
||||||
petApi.Configuration.AddDefaultHeader ("header_key2", "header_value2");
|
petApi.Configuration.AddDefaultHeader ("header_key2", "header_value2");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user