1
+ using Microsoft . AspNetCore . Mvc ;
2
+
3
+ using Moq ;
4
+
5
+ using Nullinside . Api . Common . Docker ;
6
+ using Nullinside . Api . Common . Docker . Support ;
7
+ using Nullinside . Api . Controllers ;
8
+ using Nullinside . Api . Model . Ddl ;
9
+ using Nullinside . Api . Shared . Json ;
10
+
11
+ namespace Nullinside . Api . Tests . Nullinside . Api . Controllers ;
12
+
13
+ /// <summary>
14
+ /// Tests for the <see cref="DockerController" /> class
15
+ /// </summary>
16
+ public class DockerControllerTests : UnitTestBase {
17
+ /// <summary>
18
+ /// The docker proxy.
19
+ /// </summary>
20
+ private Mock < IDockerProxy > _docker ;
21
+
22
+ /// <summary>
23
+ /// Add the docker proxy.
24
+ /// </summary>
25
+ public override void Setup ( ) {
26
+ base . Setup ( ) ;
27
+ _docker = new Mock < IDockerProxy > ( ) ;
28
+ }
29
+
30
+ /// <summary>
31
+ /// Tests that given a list of docker projects from the database we can match it against the actively running
32
+ /// projects on the server.
33
+ /// </summary>
34
+ [ Test ]
35
+ public async Task DatabaseMatchesCommandOutputSuccessfully ( ) {
36
+ // Create three entries in the database for what we allow people to see. All of these should be in the output.
37
+ _db . DockerDeployments . AddRange (
38
+ new DockerDeployments {
39
+ Id = 1 , DisplayName = "Good" , IsDockerComposeProject = true , Name = "Good" , Notes = "Should be in output"
40
+ } ,
41
+ new DockerDeployments {
42
+ Id = 2 , DisplayName = "Good without matching name" , IsDockerComposeProject = true , Name = "NonMatchingName" ,
43
+ Notes = "Should be in output"
44
+ } ,
45
+ new DockerDeployments {
46
+ Id = 3 , DisplayName = "Good non-compose" , IsDockerComposeProject = false , Name = "Stuff" ,
47
+ Notes = "Should be in output"
48
+ }
49
+ ) ;
50
+ await _db . SaveChangesAsync ( ) ;
51
+
52
+ // Create two entries "in the server" for what is actually running. We should only match on the "good" one. The bad
53
+ // one is different enough that it shouldn't match.
54
+ var compose = new List < DockerResource > {
55
+ new ( ) { Id = 1 , IsOnline = true , Name = "Good" , Notes = "Should be in output's IsOnline field" } ,
56
+ new ( ) { Id = 2 , IsOnline = false , Name = "Bad" , Notes = "Should not be in output" }
57
+ } ;
58
+ _docker . Setup ( d => d . GetDockerComposeProjects ( It . IsAny < CancellationToken > ( ) ) )
59
+ . Returns ( ( ) => Task . FromResult ( compose . AsEnumerable ( ) ) ) ;
60
+
61
+ var containers = new List < DockerResource > {
62
+ new ( ) { Id = 3 , IsOnline = true , Name = "doesn't match" , Notes = "Should not be in output" }
63
+ } ;
64
+ _docker . Setup ( d => d . GetContainers ( It . IsAny < CancellationToken > ( ) ) )
65
+ . Returns ( ( ) => Task . FromResult ( containers . AsEnumerable ( ) ) ) ;
66
+
67
+ // Make the call and ensure it's successful.
68
+ var controller = new DockerController ( _db , _docker . Object ) ;
69
+ ObjectResult obj = await controller . GetDockerResources ( ) ;
70
+ Assert . That ( obj . StatusCode , Is . EqualTo ( 200 ) ) ;
71
+
72
+ // There should be three results. One that was actively running "Good" and the others weren't actively running.
73
+ var deployments = obj . Value as List < DockerResource > ;
74
+ Assert . That ( deployments , Is . Not . Null ) ;
75
+ Assert . That ( deployments . Count , Is . EqualTo ( 3 ) ) ;
76
+ Assert . That ( deployments . FirstOrDefault ( d => d . Name == "Good" ) ? . IsOnline , Is . True ) ;
77
+ Assert . That ( deployments . FirstOrDefault ( d => d . Name == "Good without matching name" ) ? . IsOnline , Is . False ) ;
78
+ Assert . That ( deployments . FirstOrDefault ( d => d . Name == "Good non-compose" ) ? . IsOnline , Is . False ) ;
79
+ }
80
+
81
+ /// <summary>
82
+ /// Tests that turning on/off a compose project calls the correct thing.
83
+ /// </summary>
84
+ [ Test ]
85
+ public async Task OnOffComposeProjectsWork ( ) {
86
+ // Create two entries in the database for what we allow people to adjust.
87
+ _db . DockerDeployments . AddRange (
88
+ new DockerDeployments {
89
+ Id = 1 , DisplayName = "Good" , IsDockerComposeProject = true , Name = "Good" , Notes = "Should be in output"
90
+ } ,
91
+ new DockerDeployments {
92
+ Id = 2 , DisplayName = "Bad" , IsDockerComposeProject = true , Name = "Bad" , Notes = "Should not be in output"
93
+ }
94
+ ) ;
95
+ await _db . SaveChangesAsync ( ) ;
96
+
97
+ // Only a call with "Good" will work.
98
+ _docker . Setup ( d =>
99
+ d . TurnOnOffDockerCompose ( "Good" , It . IsAny < bool > ( ) , It . IsAny < CancellationToken > ( ) , It . IsAny < string > ( ) ) )
100
+ . Returns ( ( ) => Task . FromResult ( true ) ) ;
101
+
102
+ // Make the call and ensure it's successful.
103
+ var controller = new DockerController ( _db , _docker . Object ) ;
104
+ ObjectResult obj =
105
+ await controller . TurnOnOrOffDockerResources ( 1 , new TurnOnOrOffDockerResourcesRequest { TurnOn = true } ) ;
106
+ Assert . That ( obj . StatusCode , Is . EqualTo ( 200 ) ) ;
107
+
108
+ // Ensure we called the 3rd party API with a value of "Good" to turn on a compose.
109
+ bool deployments = ( bool ) obj . Value ! ;
110
+ Assert . That ( deployments , Is . True ) ;
111
+ }
112
+
113
+ /// <summary>
114
+ /// Tests that turning on/off a container project calls the correct thing.
115
+ /// </summary>
116
+ [ Test ]
117
+ public async Task OnOffContainerWork ( ) {
118
+ // Create two entries in the database for what we allow people to adjust.
119
+ _db . DockerDeployments . AddRange (
120
+ new DockerDeployments {
121
+ Id = 1 , DisplayName = "Good" , IsDockerComposeProject = false , Name = "Good" , Notes = "Should be in output"
122
+ } ,
123
+ new DockerDeployments {
124
+ Id = 2 , DisplayName = "Bad" , IsDockerComposeProject = false , Name = "Bad" , Notes = "Should not be in output"
125
+ }
126
+ ) ;
127
+ await _db . SaveChangesAsync ( ) ;
128
+
129
+ // Only a call with "Good" will work.
130
+ _docker . Setup ( d => d . TurnOnOffDockerContainer ( "Good" , It . IsAny < bool > ( ) , It . IsAny < CancellationToken > ( ) ) )
131
+ . Returns ( ( ) => Task . FromResult ( true ) ) ;
132
+
133
+ // Make the call and ensure it's successful.
134
+ var controller = new DockerController ( _db , _docker . Object ) ;
135
+ ObjectResult obj =
136
+ await controller . TurnOnOrOffDockerResources ( 1 , new TurnOnOrOffDockerResourcesRequest { TurnOn = true } ) ;
137
+ Assert . That ( obj . StatusCode , Is . EqualTo ( 200 ) ) ;
138
+
139
+ // Ensure we called the 3rd party API with a value of "Good" to turn on a container.
140
+ bool deployments = ( bool ) obj . Value ! ;
141
+ Assert . That ( deployments , Is . True ) ;
142
+ }
143
+
144
+ /// <summary>
145
+ /// Tests providing an invalid id will result in a HTTP bad request.
146
+ /// </summary>
147
+ [ Test ]
148
+ public async Task InvalidIdIsBadRequest ( ) {
149
+ // Create two entries in the database for what we allow people to adjust.
150
+ _db . DockerDeployments . Add (
151
+ new DockerDeployments {
152
+ Id = 2 , DisplayName = "Bad" , IsDockerComposeProject = false , Name = "Bad" , Notes = "Should not be in output"
153
+ }
154
+ ) ;
155
+ await _db . SaveChangesAsync ( ) ;
156
+
157
+ // Only a call with "Good" will get true.
158
+ _docker . Setup ( d => d . TurnOnOffDockerContainer ( "Good" , It . IsAny < bool > ( ) , It . IsAny < CancellationToken > ( ) ) )
159
+ . Returns ( ( ) => Task . FromResult ( true ) ) ;
160
+
161
+ // Make the call and ensure it's successful.
162
+ var controller = new DockerController ( _db , _docker . Object ) ;
163
+ ObjectResult obj =
164
+ await controller . TurnOnOrOffDockerResources ( 1 , new TurnOnOrOffDockerResourcesRequest { TurnOn = true } ) ;
165
+ Assert . That ( obj . StatusCode , Is . EqualTo ( 400 ) ) ;
166
+
167
+ // Bad request is returned to user with a generic error message.
168
+ Assert . That ( obj . Value , Is . TypeOf < BasicServerFailure > ( ) ) ;
169
+ }
170
+ }
0 commit comments