1+ namespace Microsoft . Web
2+ {
3+ using System ;
4+ using System . Collections . Generic ;
5+ using System . Net . Http ;
6+ using System . Net . Http . Formatting ;
7+ using System . Net . Http . Headers ;
8+ using System . Threading . Tasks ;
9+ using System . Web . Http ;
10+ using System . Web . Http . Dispatcher ;
11+ using Xunit ;
12+ using static System . Net . Http . HttpMethod ;
13+ using static System . String ;
14+ using static System . Web . Http . IncludeErrorDetailPolicy ;
15+
16+ [ Trait ( "Kind" , "Acceptance" ) ]
17+ public abstract class AcceptanceTest : IDisposable
18+ {
19+ private sealed class FilteredControllerTypeResolver : List < Type > , IHttpControllerTypeResolver
20+ {
21+ public ICollection < Type > GetControllerTypes ( IAssembliesResolver assembliesResolver ) => this ;
22+ }
23+
24+ private const string JsonMediaType = "application/json" ;
25+ private static readonly HttpMethod Patch = new HttpMethod ( "PATCH" ) ;
26+ private readonly FilteredControllerTypeResolver filteredControllerTypes = new FilteredControllerTypeResolver ( ) ;
27+ private bool disposed ;
28+
29+ ~ AcceptanceTest ( )
30+ {
31+ Dispose ( false ) ;
32+ }
33+
34+ protected AcceptanceTest ( )
35+ {
36+ Configuration . IncludeErrorDetailPolicy = Always ;
37+ Configuration . Services . Replace ( typeof ( IHttpControllerTypeResolver ) , FilteredControllerTypes ) ;
38+ Server = new HttpServer ( Configuration ) ;
39+ Client = new HttpClient ( new HttpSimulatorHandler ( Server ) )
40+ {
41+ BaseAddress = new Uri ( "http://localhost" ) ,
42+ DefaultRequestHeaders =
43+ {
44+ { "Host" , "localhost" }
45+ }
46+ } ;
47+ }
48+
49+ protected HttpConfiguration Configuration { get ; } = new HttpConfiguration ( ) ;
50+
51+ protected HttpServer Server { get ; }
52+
53+ protected HttpClient Client { get ; }
54+
55+ protected IList < Type > FilteredControllerTypes => filteredControllerTypes ;
56+
57+ protected virtual void Dispose ( bool disposing )
58+ {
59+ if ( disposed )
60+ {
61+ return ;
62+ }
63+
64+ disposed = true ;
65+
66+ if ( ! disposing )
67+ {
68+ return ;
69+ }
70+
71+ Client . Dispose ( ) ;
72+ Server . Dispose ( ) ;
73+ Configuration . Dispose ( ) ;
74+ }
75+
76+ public void Dispose ( )
77+ {
78+ Dispose ( true ) ;
79+ GC . SuppressFinalize ( this ) ;
80+ }
81+
82+ private HttpRequestMessage CreateRequest < TEntity > ( string requestUri , TEntity entity , HttpMethod method )
83+ {
84+ var request = new HttpRequestMessage ( method , requestUri ) ;
85+
86+ if ( ! Equals ( entity , default ( TEntity ) ) )
87+ {
88+ var formatter = new JsonMediaTypeFormatter ( ) ;
89+ request . Content = new ObjectContent < TEntity > ( entity , formatter , JsonMediaType ) ;
90+ }
91+
92+ Client . DefaultRequestHeaders . Accept . Add ( new MediaTypeWithQualityHeaderValue ( JsonMediaType ) ) ;
93+
94+ return request ;
95+ }
96+
97+ protected void Accept ( string metadata = null )
98+ {
99+ var mediaType = new MediaTypeWithQualityHeaderValue ( JsonMediaType ) ;
100+ var odataMetadata = new NameValueHeaderValue ( "odata.metadata" ) ;
101+
102+ if ( IsNullOrEmpty ( metadata ) )
103+ {
104+ odataMetadata . Value = "none" ;
105+ }
106+ else
107+ {
108+ switch ( metadata . ToUpperInvariant ( ) )
109+ {
110+ case "NONE" :
111+ case "MINIMAL" :
112+ case "FULL" :
113+ break ;
114+ default :
115+ throw new ArgumentOutOfRangeException ( nameof ( metadata ) , "The specified metadata value must be 'none', 'minimal', or 'full'." ) ;
116+ }
117+
118+ odataMetadata . Value = metadata ;
119+ }
120+
121+ mediaType . Parameters . Add ( odataMetadata ) ;
122+ Client . DefaultRequestHeaders . Accept . Clear ( ) ;
123+ Client . DefaultRequestHeaders . Accept . Add ( mediaType ) ;
124+ }
125+
126+ protected void PreferNoReturn ( ) => Client . DefaultRequestHeaders . Add ( "Prefer" , "return=representation" ) ;
127+
128+ protected virtual Task < HttpResponseMessage > GetAsync ( string requestUri ) => Client . SendAsync ( CreateRequest ( requestUri , default ( object ) , Get ) ) ;
129+
130+ protected virtual Task < HttpResponseMessage > PostAsync < TEntity > ( string requestUri , TEntity entity ) => Client . SendAsync ( CreateRequest ( requestUri , entity , Post ) ) ;
131+
132+ protected virtual Task < HttpResponseMessage > PutAsync < TEntity > ( string requestUri , TEntity entity ) => Client . SendAsync ( CreateRequest ( requestUri , entity , Put ) ) ;
133+
134+ protected virtual Task < HttpResponseMessage > PatchAsync < TEntity > ( string requestUri , TEntity entity ) => Client . SendAsync ( CreateRequest ( requestUri , entity , Patch ) ) ;
135+
136+ protected virtual Task < HttpResponseMessage > DeleteAsync ( string requestUri ) => Client . SendAsync ( CreateRequest ( requestUri , default ( object ) , Delete ) ) ;
137+ }
138+ }
0 commit comments